use crate::types::{CardinalDirection, Command, Error, ModeIndicator, Time};
#[derive(Debug, Clone, PartialEq, Default)]
pub struct GNS {
pub time: Time,
pub latitude: Option<f64>,
pub latitude_direction: Option<CardinalDirection>,
pub longitude: Option<f64>,
pub longitude_direction: Option<CardinalDirection>,
pub gps_mode_indicator: Option<ModeIndicator>,
pub glonass_mode_indicator: Option<ModeIndicator>,
pub galileo_mode_indicator: Option<ModeIndicator>,
pub beidou_mode_indicator: Option<ModeIndicator>,
pub qzss_mode_indicator: Option<ModeIndicator>,
pub number_of_satellites_in_use: u8,
pub horizontal_dilution_of_precision: Option<f64>,
pub orthometric_height: Option<f64>,
pub geodial_separation: Option<f64>,
pub age_of_differential_gps_data: f64,
pub reference_station_id: Option<String>,
}
impl Command<GNS> for GNS {
fn parse_command(&self, command: Vec<String>) -> Result<GNS, Error> {
let time_split: Vec<&str> = if command[0].contains('.') {
command[0].split('.').collect()
} else {
vec![&command[0], "0"]
};
let hour = time_split[0][..2].parse()?;
let minute = time_split[0][2..4].parse()?;
let second = time_split[0][4..6].parse()?;
let decimal_seconds = time_split[1].parse()?;
let time = Time {
hour,
minute,
second,
decimal_seconds,
};
let latitude = match command[1].parse() {
Ok(latitude) => Some(latitude),
Err(_) => None,
};
let latitude_direction = match command[2].parse::<char>() {
Ok(direction) => CardinalDirection::from_char(direction),
Err(_) => None,
};
let longitude = match command[3].parse() {
Ok(longitude) => Some(longitude),
Err(_) => None,
};
let longitude_direction = match command[4].parse::<char>() {
Ok(direction) => CardinalDirection::from_char(direction),
Err(_) => None,
};
let mode_indicator = command[5].chars();
let gps_mode_indicator = match mode_indicator.clone().nth(0) {
Some(mode) => ModeIndicator::from_char(mode),
None => None,
};
let glonass_mode_indicator = match mode_indicator.clone().nth(1) {
Some(mode) => ModeIndicator::from_char(mode),
None => None,
};
let galileo_mode_indicator = match mode_indicator.clone().nth(2) {
Some(mode) => ModeIndicator::from_char(mode),
None => None,
};
let beidou_mode_indicator = match mode_indicator.clone().nth(3) {
Some(mode) => ModeIndicator::from_char(mode),
None => None,
};
let qzss_mode_indicator = match mode_indicator.clone().nth(4) {
Some(mode) => ModeIndicator::from_char(mode),
None => None,
};
let number_of_satellites_in_use = command[6].parse()?;
let horizontal_dilution_of_precision = match command[7].parse::<f64>() {
Ok(dilution) => Some(dilution),
Err(_) => None,
};
let orthometric_height = match command[8].parse::<f64>() {
Ok(height) => Some(height),
Err(_) => None,
};
let geodial_separation = match command[9].parse::<f64>() {
Ok(separation) => Some(separation),
Err(_) => None,
};
let age_of_differential_gps_data = command[10].parse()?;
let reference_station_id = match command[11].parse::<u16>() {
Ok(id) => Some(id.to_string()),
Err(_) => None,
};
Ok(GNS {
time,
latitude,
latitude_direction,
longitude,
longitude_direction,
gps_mode_indicator,
glonass_mode_indicator,
galileo_mode_indicator,
beidou_mode_indicator,
qzss_mode_indicator,
number_of_satellites_in_use,
horizontal_dilution_of_precision,
orthometric_height,
geodial_separation,
age_of_differential_gps_data,
reference_station_id,
})
}
}