use crate::types::*;
mod gga;
mod gll;
mod gns;
mod gsa;
mod gsv;
mod rmc;
mod vtg;
pub use gga::GgaData;
pub use gll::GllData;
pub use gns::GnsData;
pub use gsa::GsaData;
pub use gsv::{GsvData, SatelliteInfo};
pub use rmc::RmcData;
pub use vtg::VtgData;
pub(crate) const MAX_FIELDS: usize = 20;
#[derive(Debug, Clone)]
pub(crate) struct ParsedSentence {
pub message_type: MessageType,
pub talker_id: TalkerId,
pub fields: [Option<Field>; MAX_FIELDS],
pub field_count: usize,
}
impl ParsedSentence {
pub(crate) fn get_field_str(&self, index: usize) -> Option<&str> {
if index < self.field_count {
self.fields[index].as_ref()?.as_str()
} else {
None
}
}
pub(crate) fn parse_field<T>(&self, index: usize) -> Option<T>
where
T: core::str::FromStr,
{
self.get_field_str(index)?.parse().ok()
}
pub(crate) fn parse_field_char(&self, index: usize) -> Option<char> {
self.get_field_str(index)?.chars().next()
}
}
#[derive(Debug, Clone, Copy)]
pub struct Field {
data: [u8; 16], len: u8, }
impl Field {
pub(crate) fn from_bytes(bytes: &[u8]) -> Self {
let copy_len = bytes.len().min(16);
let mut data = [0; 16];
data[..copy_len].copy_from_slice(&bytes[..copy_len]);
Field {
data,
len: copy_len as u8,
}
}
pub fn as_str(&self) -> Option<&str> {
core::str::from_utf8(&self.data[..self.len as usize]).ok()
}
pub fn as_bytes(&self) -> &[u8] {
&self.data[..self.len as usize]
}
}