dsn-visualizer/src/dsn/mod.rs

96 lines
2.9 KiB
Rust

use std::collections::HashMap;
use std::convert::TryFrom;
use std::io::BufReader;
use std::time::{SystemTime, UNIX_EPOCH};
use reqwest::blocking::Client;
use xml::reader::XmlEvent;
use xml::EventReader;
use error::ParseError;
use crate::dsn::error::DSNError;
use crate::dsn::models::{Dish, Signal, Station, Target};
pub mod error;
pub mod models;
pub fn dsn_request(client: &Client, dsn_api_url: &str) -> Result<Vec<Station>, DSNError> {
let mut params = HashMap::new();
let timestamp = (SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_millis()
/ 5000) as u64;
params.insert("r", timestamp);
let resp = client.get(dsn_api_url).query(&params).send()?.text()?;
let file = BufReader::new(resp.as_bytes());
Ok(parse_dsn_resp(file)?)
}
pub fn parse_dsn_resp<T>(reader: BufReader<T>) -> Result<Vec<Station>, ParseError>
where
T: std::io::Read,
{
let mut stations = Vec::new();
let mut station: Option<Station> = None;
let mut dish: Option<Dish> = None;
let parser = EventReader::new(reader).into_iter();
for e in parser {
match e {
Ok(XmlEvent::StartElement {
name, attributes, ..
}) => {
if name.local_name.contains("station") {
if let Some(station) = station {
stations.push(station);
}
station = Some(Station::try_from(attributes).unwrap());
} else if name.local_name.contains("dish") {
dish = Some(Dish::try_from(attributes).unwrap());
} else if name.local_name.contains("downSignal") {
dish = Some(
dish.unwrap()
.add_down_signal(Signal::try_from(attributes).unwrap()),
);
} else if name.local_name.contains("upSignal") {
dish = Some(
dish.unwrap()
.add_up_signal(Signal::try_from(attributes).unwrap()),
);
} else if name.local_name.contains("target") {
dish = Some(
dish.unwrap()
.add_target(Target::try_from(attributes).unwrap()),
);
}
}
Ok(XmlEvent::EndElement { name }) => {
if name.local_name.contains("dish") && station.is_some() && dish.is_some() {
station = Some(station.unwrap().add_dish(dish.unwrap()));
dish = None;
}
}
Ok(XmlEvent::EndDocument) => {
if let Some(station) = station {
stations.push(station);
break;
}
}
Err(e) => {
println!("Error: {}", e);
break;
}
_ => {}
}
}
Ok(stations)
}