use crate::nmea::field::{FieldReader, FieldWriter, NmeaEncodable};
#[derive(Debug, Clone, PartialEq)]
pub struct Pgrme {
pub horizontal: Option<f32>,
pub vertical: Option<f32>,
pub spherical: Option<f32>,
}
impl Pgrme {
pub fn parse(fields: &[&str]) -> Option<Self> {
let mut r = FieldReader::new(fields);
let horizontal = r.f32();
r.skip(); let vertical = r.f32();
r.skip(); let spherical = r.f32();
r.skip(); Some(Self {
horizontal,
vertical,
spherical,
})
}
}
impl NmeaEncodable for Pgrme {
const SENTENCE_TYPE: &str = "RME";
const PROPRIETARY_ID: &str = "PGRME";
fn encode(&self) -> Vec<String> {
let mut w = FieldWriter::new();
w.f32(self.horizontal);
w.fixed('M');
w.f32(self.vertical);
w.fixed('M');
w.f32(self.spherical);
w.fixed('M');
w.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parse_frame;
#[test]
fn pgrme_empty() {
let s = Pgrme {
horizontal: None,
vertical: None,
spherical: None,
}
.to_proprietary_sentence();
let f = parse_frame(s.trim()).expect("valid");
let p = Pgrme::parse(&f.fields).expect("parse");
assert!(p.horizontal.is_none());
assert!(p.vertical.is_none());
assert!(p.spherical.is_none());
}
#[test]
fn pgrme_encode_roundtrip() {
let original = Pgrme {
horizontal: Some(3.3),
vertical: Some(4.9),
spherical: Some(6.0),
};
let sentence = original.to_proprietary_sentence();
let frame = parse_frame(sentence.trim()).expect("re-parse");
let parsed = Pgrme::parse(&frame.fields).expect("parse");
assert_eq!(original, parsed);
}
#[test]
fn pgrme_pgrme_gonmea() {
let frame = parse_frame("$PGRME,3.3,M,4.9,M,6.0,M*25").expect("valid");
let p = Pgrme::parse(&frame.fields).expect("parse");
assert!((p.horizontal.expect("horizontal") - 3.3).abs() < 0.01);
assert!((p.vertical.expect("vertical") - 4.9).abs() < 0.01);
assert!((p.spherical.expect("spherical") - 6.0).abs() < 0.01);
}
}