use crate::nmea::field::{FieldReader, FieldWriter, NmeaEncodable};
#[derive(Debug, Clone, PartialEq)]
pub struct Pskpdpt {
pub depth: Option<f32>,
pub offset: Option<f32>,
pub range_scale: Option<u32>,
pub echo_strength: Option<u8>,
pub channel: Option<u8>,
pub transducer_location: Option<String>,
}
impl Pskpdpt {
pub fn parse(fields: &[&str]) -> Option<Self> {
let mut r = FieldReader::new(fields);
let depth = r.f32();
let offset = r.f32();
let range_scale = r.u32();
let echo_strength = r.u8();
let channel = r.u8();
let transducer_location = r.string();
Some(Self {
depth,
offset,
range_scale,
echo_strength,
channel,
transducer_location,
})
}
}
impl NmeaEncodable for Pskpdpt {
const SENTENCE_TYPE: &str = "DPT";
const PROPRIETARY_ID: &str = "PSKPDPT";
fn encode(&self) -> Vec<String> {
let mut w = FieldWriter::new();
w.f32(self.depth);
w.f32(self.offset);
w.u32(self.range_scale);
w.u8(self.echo_strength);
w.u8(self.channel);
w.string(self.transducer_location.as_deref());
w.finish()
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::parse_frame;
#[test]
fn pskpdpt_empty() {
let s = Pskpdpt {
depth: None,
offset: None,
range_scale: None,
echo_strength: None,
channel: None,
transducer_location: None,
}
.to_proprietary_sentence();
let f = parse_frame(s.trim()).expect("valid");
let p = Pskpdpt::parse(&f.fields).expect("parse");
assert!(p.depth.is_none());
assert!(p.transducer_location.is_none());
}
#[test]
fn pskpdpt_encode_roundtrip() {
let original = Pskpdpt {
depth: Some(2.5),
offset: Some(0.0),
range_scale: Some(10),
echo_strength: Some(10),
channel: Some(3),
transducer_location: None,
};
let sentence = original.to_proprietary_sentence();
let frame = parse_frame(sentence.trim()).expect("re-parse");
let parsed = Pskpdpt::parse(&frame.fields).expect("parse");
assert_eq!(original, parsed);
}
#[test]
fn pskpdpt_pskpdpt_gonmea() {
let frame = parse_frame("$PSKPDPT,0002.5,+00.0,0010,10,03,*77").expect("valid");
let p = Pskpdpt::parse(&frame.fields).expect("parse");
assert!((p.depth.expect("depth") - 2.5).abs() < 0.01);
assert!((p.offset.expect("offset") - 0.0).abs() < 0.01);
assert_eq!(p.range_scale, Some(10));
assert_eq!(p.echo_strength, Some(10));
assert_eq!(p.channel, Some(3));
assert!(p.transducer_location.is_none());
}
#[test]
fn pskpdpt_with_location_gonmea() {
let frame = parse_frame("$PSKPDPT,0002.5,-01.1,0010,10,03,AFT*22").expect("valid");
let p = Pskpdpt::parse(&frame.fields).expect("parse");
assert!((p.depth.expect("depth") - 2.5).abs() < 0.01);
assert!((p.offset.expect("offset") - (-1.1)).abs() < 0.01);
assert_eq!(p.range_scale, Some(10));
assert_eq!(p.echo_strength, Some(10));
assert_eq!(p.channel, Some(3));
assert_eq!(p.transducer_location.as_deref(), Some("AFT"));
}
}