use crate::nmea::field::{FieldReader, FieldWriter, NmeaEncodable};
#[derive(Debug, Clone, PartialEq)]
pub struct TlbTarget {
pub number: Option<u8>,
pub label: Option<String>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct Tlb {
pub targets: Vec<TlbTarget>,
}
impl Tlb {
pub fn parse(fields: &[&str]) -> Option<Self> {
let mut r = FieldReader::new(fields);
let mut targets = Vec::new();
loop {
let number = r.u8();
if number.is_none() {
break;
}
targets.push(TlbTarget {
number,
label: r.string(),
});
}
Some(Self { targets })
}
}
impl NmeaEncodable for Tlb {
const SENTENCE_TYPE: &str = "TLB";
fn encode(&self) -> Vec<String> {
let mut w = FieldWriter::new();
for t in &self.targets {
w.u8(t.number);
w.string(t.label.as_deref());
}
w.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parse_frame;
#[test]
fn tlb_empty() {
let s = Tlb { targets: vec![] }.to_sentence("RA");
let f = parse_frame(s.trim()).expect("valid");
let t = Tlb::parse(&f.fields).expect("parse");
assert!(t.targets.is_empty());
}
#[test]
fn tlb_encode_roundtrip() {
let original = Tlb {
targets: vec![
TlbTarget {
number: Some(1),
label: Some("ALPHA".to_string()),
},
TlbTarget {
number: Some(2),
label: Some("BETA".to_string()),
},
],
};
let sentence = original.to_sentence("RA");
let frame = parse_frame(sentence.trim()).expect("re-parse");
let parsed = Tlb::parse(&frame.fields).expect("parse");
assert_eq!(original, parsed);
}
#[test]
fn tlb_ratlb_gonmea() {
let f = parse_frame("$RATLB,1,XXX*20").expect("valid TLB");
let t = Tlb::parse(&f.fields).expect("parse TLB");
assert_eq!(t.targets.len(), 1);
assert_eq!(t.targets[0].number, Some(1));
assert_eq!(t.targets[0].label, Some("XXX".to_string()));
}
}