use crate::types::{Command, Error, ModeIndicator, VTGUnit};
#[derive(Debug, Clone, PartialEq)]
pub struct VTG {
pub course_over_ground_true: Option<f32>,
pub course_over_ground_unit: char,
pub course_over_ground_magnetic: Option<f32>,
pub course_over_ground_magnetic_unit: char,
pub speed_over_ground_first: Option<f32>,
pub speed_over_ground_first_unit: VTGUnit,
pub speed_over_ground_second: Option<f32>,
pub speed_over_ground_second_unit: VTGUnit,
pub mode_indicator: ModeIndicator,
}
impl Default for VTG {
fn default() -> Self {
Self {
course_over_ground_true: Default::default(),
course_over_ground_unit: Default::default(),
course_over_ground_magnetic: Default::default(),
course_over_ground_magnetic_unit: Default::default(),
speed_over_ground_first: Default::default(),
speed_over_ground_first_unit: VTGUnit::Knots,
speed_over_ground_second: Default::default(),
speed_over_ground_second_unit: VTGUnit::Kmh,
mode_indicator: ModeIndicator::Autonomous,
}
}
}
impl Command<VTG> for VTG {
fn parse_command(&self, command: Vec<String>) -> Result<VTG, crate::types::Error> {
if command.len() != 9 {
Err(Error::ParseError(format!(
"Invalid VTG command length: {}",
command.join(" ")
)))
} else {
let course_over_ground_true = command[0].parse::<f32>().ok();
let course_over_ground_unit = match command[1].chars().next() {
Some(e) => e,
None => {
return Err(Error::ParseError(
"Invalid course over ground unit".to_string(),
))
}
};
let course_over_ground_magnetic = command[2].parse::<f32>().ok();
let course_over_ground_magnetic_unit = match command[3].chars().next() {
Some(e) => e,
None => {
return Err(Error::ParseError(
"Invalid course over ground magnetic unit".to_string(),
))
}
};
let speed_over_ground_first = command[4].parse::<f32>().ok();
let speed_over_ground_first_unit = match VTGUnit::from_str(&command[5]) {
Ok(e) => e,
Err(_) => {
return Err(Error::ParseError(
"Invalid speed over ground first unit".to_string(),
))
}
};
let speed_over_ground_second = command[6].parse::<f32>().ok();
let speed_over_ground_second_unit = match VTGUnit::from_str(&command[7]) {
Ok(e) => e,
Err(_) => {
return Err(Error::ParseError(
"Invalid speed over ground second unit".to_string(),
))
}
};
let mode_indicator = match ModeIndicator::from_str(&command[8]) {
Ok(e) => e,
Err(_) => return Err(Error::ParseError("Invalid mode indicator".to_string())),
};
Ok(VTG {
course_over_ground_true,
course_over_ground_unit,
course_over_ground_magnetic,
course_over_ground_magnetic_unit,
speed_over_ground_first,
speed_over_ground_first_unit,
speed_over_ground_second,
speed_over_ground_second_unit,
mode_indicator,
})
}
}
}