use crate::nmea::field::{FieldReader, FieldWriter, NmeaEncodable};
#[derive(Debug, Clone, PartialEq)]
pub struct Pcdin {
pub pgn: Option<String>,
pub timestamp: Option<String>,
pub source: Option<String>,
pub data: Option<String>,
}
impl Pcdin {
pub fn parse(fields: &[&str]) -> Option<Self> {
let mut r = FieldReader::new(fields);
let pgn = r.string();
let timestamp = r.string();
let source = r.string();
let data = r.string();
Some(Self {
pgn,
timestamp,
source,
data,
})
}
}
impl NmeaEncodable for Pcdin {
const SENTENCE_TYPE: &str = "DIN";
const PROPRIETARY_ID: &str = "PCDIN";
fn encode(&self) -> Vec<String> {
let mut w = FieldWriter::new();
w.string(self.pgn.as_deref());
w.string(self.timestamp.as_deref());
w.string(self.source.as_deref());
w.string(self.data.as_deref());
w.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parse_frame;
#[test]
fn pcdin_empty() {
let s = Pcdin {
pgn: None,
timestamp: None,
source: None,
data: None,
}
.to_proprietary_sentence();
let f = parse_frame(s.trim()).expect("valid");
let p = Pcdin::parse(&f.fields).expect("parse");
assert!(p.pgn.is_none());
assert!(p.data.is_none());
}
#[test]
fn pcdin_encode_roundtrip() {
let original = Pcdin {
pgn: Some("01F112".to_string()),
timestamp: Some("000C72EA".to_string()),
source: Some("09".to_string()),
data: Some("28C36A0000B40AFD".to_string()),
};
let sentence = original.to_proprietary_sentence();
let frame = parse_frame(sentence.trim()).expect("re-parse");
let parsed = Pcdin::parse(&frame.fields).expect("parse");
assert_eq!(original, parsed);
}
#[test]
fn pcdin_pcdin_gonmea() {
let frame =
parse_frame("$PCDIN,01F112,000C72EA,09,28C36A0000B40AFD*56").expect("valid");
let p = Pcdin::parse(&frame.fields).expect("parse");
assert_eq!(p.pgn.as_deref(), Some("01F112"));
assert_eq!(p.timestamp.as_deref(), Some("000C72EA"));
assert_eq!(p.source.as_deref(), Some("09"));
assert_eq!(p.data.as_deref(), Some("28C36A0000B40AFD"));
}
}