use crate::types::{Command, Error};
#[derive(Debug, Clone, PartialEq)]
pub struct Satellite {
pub id: Option<usize>,
pub elevation: Option<usize>,
pub azimuth: Option<usize>,
pub snr: Option<usize>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct GSV {
pub total_pages: usize,
pub pages: Vec<GSVPage>,
}
#[derive(Debug, Clone, PartialEq, Default)]
pub struct GSVPage {
pub total_pages: usize,
pub page_id: usize,
pub number_of_known_satellites_in_view: usize,
pub satellites: Vec<Satellite>,
pub signal_id: Option<usize>,
}
impl Command<GSVPage> for GSVPage {
fn parse_command(&self, command: Vec<String>) -> Result<GSVPage, Error> {
if command.len() < 4 {
return Err(Error::ParseError(format!(
"Invalid GSV command len: {}",
command.len()
)));
}
let total_pages: usize = command[0].parse()?;
let page_id: usize = command[1].parse()?;
let number_of_known_satellites_in_view: usize = command[2].parse()?;
let mut satellites = Vec::new();
for i in 0..4 {
let idx = i * 4;
let id: Option<usize> = if command.len() > idx {
match command[idx].parse::<usize>() {
Ok(e) => Some(e),
Err(_) => None,
}
} else {
None
};
let elevation: Option<usize> = if command.len() > idx + 1 {
match command[idx + 1].parse::<usize>() {
Ok(e) => Some(e),
Err(_) => None,
}
} else {
None
};
let azimuth: Option<usize> = if command.len() > idx + 2 {
match command[idx + 2].parse::<usize>() {
Ok(e) => Some(e),
Err(_) => None,
}
} else {
None
};
let snr: Option<usize> = if command.len() > idx + 3 {
match command[idx + 3].parse::<usize>() {
Ok(e) => Some(e),
Err(_) => None,
}
} else {
None
};
satellites.push(Satellite {
id,
elevation,
azimuth,
snr,
});
}
let signal_id = command[command.len() - 1].parse::<usize>().ok();
Ok(GSVPage {
total_pages,
page_id,
number_of_known_satellites_in_view,
satellites,
signal_id,
})
}
}