use crate::nmea::field::{FieldReader, FieldWriter, NmeaEncodable};
#[derive(Debug, Clone, PartialEq)]
pub struct Wpl {
pub lat: Option<f64>,
pub ns: Option<char>,
pub lon: Option<f64>,
pub ew: Option<char>,
pub ident: Option<String>,
}
impl Wpl {
pub fn parse(fields: &[&str]) -> Option<Self> {
let mut r = FieldReader::new(fields);
let lat = r.f64();
let ns = r.char();
let lon = r.f64();
let ew = r.char();
let ident = r.string();
Some(Self {
lat,
ns,
lon,
ew,
ident,
})
}
}
impl NmeaEncodable for Wpl {
const SENTENCE_TYPE: &str = "WPL";
fn encode(&self) -> Vec<String> {
let mut w = FieldWriter::new();
w.f64(self.lat);
w.char(self.ns);
w.f64(self.lon);
w.char(self.ew);
w.string(self.ident.as_deref());
w.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parse_frame;
#[test]
fn wpl_empty() {
let s = Wpl {
lat: None,
ns: None,
lon: None,
ew: None,
ident: None,
}
.to_sentence("II");
let f = parse_frame(s.trim()).expect("valid");
let w = Wpl::parse(&f.fields).expect("parse");
assert!(w.lat.is_none());
assert!(w.ident.is_none());
}
#[test]
fn wpl_encode_roundtrip() {
let original = Wpl {
lat: Some(5503.453),
ns: Some('N'),
lon: Some(1037.2742),
ew: Some('E'),
ident: Some("411".to_string()),
};
let sentence = original.to_sentence("II");
let frame = parse_frame(sentence.trim()).expect("re-parse");
let parsed = Wpl::parse(&frame.fields).expect("parse");
assert_eq!(original, parsed);
}
#[test]
fn wpl_iiwpl_gonmea() {
let frame = parse_frame("$IIWPL,5503.4530,N,01037.2742,E,411*6F").expect("valid");
let w = Wpl::parse(&frame.fields).expect("parse");
assert!((w.lat.expect("lat") - 5503.453).abs() < 0.001);
assert_eq!(w.ns, Some('N'));
assert!((w.lon.expect("lon") - 1037.2742).abs() < 0.001);
assert_eq!(w.ew, Some('E'));
assert_eq!(w.ident.as_deref(), Some("411"));
}
#[test]
fn wpl_southern_hemisphere_gonmea() {
let frame = parse_frame("$IIWPL,3356.4650,S,15124.5567,E,411*73").expect("valid");
let w = Wpl::parse(&frame.fields).expect("parse");
assert!((w.lat.expect("lat") - 3356.465).abs() < 0.001);
assert_eq!(w.ns, Some('S'));
assert!((w.lon.expect("lon") - 15124.5567).abs() < 0.001);
assert_eq!(w.ew, Some('E'));
assert_eq!(w.ident.as_deref(), Some("411"));
}
}