1use super::*;
18
19#[derive(Clone, Debug, PartialEq, Serialize)]
21pub struct VbwData {
22 pub source: NavigationSystem,
24
25 pub lon_water_speed_knots: Option<f64>,
27
28 pub tr_water_speed_knots: Option<f64>,
30
31 pub water_speed_valid: Option<bool>,
33
34 pub lon_ground_speed_knots: Option<f64>,
36
37 pub tr_ground_speed_knots: Option<f64>,
39
40 pub ground_speed_valid: Option<bool>,
42}
43
44pub(crate) fn handle(
48 sentence: &str,
49 nav_system: NavigationSystem,
50) -> Result<ParsedMessage, ParseError> {
51 let split: Vec<&str> = sentence.split(',').collect();
52
53 Ok(ParsedMessage::Vbw(VbwData {
54 source: nav_system,
55 lon_water_speed_knots: pick_number_field(&split, 1)?,
56 tr_water_speed_knots: pick_number_field(&split, 2)?,
57 water_speed_valid: {
58 match *split.get(3).unwrap_or(&"") {
59 "A" => Some(true),
60 "" => None,
61 _ => Some(false),
62 }
63 },
64 lon_ground_speed_knots: pick_number_field(&split, 4)?,
65 tr_ground_speed_knots: pick_number_field(&split, 5)?,
66 ground_speed_valid: {
67 match *split.get(6).unwrap_or(&"") {
68 "A" => Some(true),
69 "" => None,
70 _ => Some(false),
71 }
72 },
73 }))
74}
75
76#[cfg(test)]
79mod test {
80 use super::*;
81
82 #[test]
83 fn test_parse_cpvbw() {
84 match NmeaParser::new().parse_sentence("$GPVBW,2.0,1.5,A,2.1,1.6,X") {
85 Ok(ps) => match ps {
86 ParsedMessage::Vbw(vbw) => {
87 assert_eq!(vbw.source, NavigationSystem::Gps);
88 assert::close(vbw.lon_water_speed_knots.unwrap_or(0.0), 2.0, 0.1);
89 assert::close(vbw.tr_water_speed_knots.unwrap_or(0.0), 1.5, 0.1);
90 assert_eq!(vbw.water_speed_valid, Some(true));
91 assert::close(vbw.lon_ground_speed_knots.unwrap_or(0.0), 2.1, 0.1);
92 assert::close(vbw.tr_ground_speed_knots.unwrap_or(0.0), 1.6, 0.1);
93 assert_eq!(vbw.ground_speed_valid, Some(false));
94 }
95 ParsedMessage::Incomplete => {
96 assert!(false);
97 }
98 _ => {
99 assert!(false);
100 }
101 },
102 Err(e) => {
103 assert_eq!(e.to_string(), "OK");
104 }
105 }
106 }
107}