kenwood_thd75/protocol/
gps.rs1use crate::error::ProtocolError;
10use crate::types::GpsRadioMode;
11
12use super::Response;
13
14pub(crate) fn parse_gps(mnemonic: &str, payload: &str) -> Option<Result<Response, ProtocolError>> {
18 match mnemonic {
19 "GP" => Some(parse_gp(payload)),
20 "GM" => Some(parse_gm(payload)),
21 "GS" => Some(parse_gs(payload)),
22 _ => None,
23 }
24}
25
26fn parse_u8_field(s: &str, cmd: &str, field: &str) -> Result<u8, ProtocolError> {
32 s.parse::<u8>().map_err(|_| ProtocolError::FieldParse {
33 command: cmd.to_owned(),
34 field: field.to_owned(),
35 detail: format!("invalid u8: {s:?}"),
36 })
37}
38
39fn parse_gp(payload: &str) -> Result<Response, ProtocolError> {
47 let parts: Vec<&str> = payload.split(',').collect();
48 if parts.len() != 2 {
49 return Err(ProtocolError::FieldParse {
50 command: "GP".to_owned(),
51 field: "all".to_owned(),
52 detail: format!("expected 2 fields (gps_enabled,pc_output), got {payload:?}"),
53 });
54 }
55 let gps_val = parse_u8_field(parts[0], "GP", "gps_enabled")?;
56 let pc_val = parse_u8_field(parts[1], "GP", "pc_output")?;
57 Ok(Response::GpsConfig {
58 gps_enabled: gps_val != 0,
59 pc_output: pc_val != 0,
60 })
61}
62
63fn parse_gm(payload: &str) -> Result<Response, ProtocolError> {
67 let raw = parse_u8_field(payload, "GM", "mode")?;
68 let mode = GpsRadioMode::try_from(raw).map_err(|e| ProtocolError::FieldParse {
69 command: "GM".into(),
70 field: "mode".into(),
71 detail: e.to_string(),
72 })?;
73 Ok(Response::GpsMode { mode })
74}
75
76#[allow(clippy::similar_names)]
80fn parse_gs(payload: &str) -> Result<Response, ProtocolError> {
81 let parts: Vec<&str> = payload.split(',').collect();
82 if parts.len() != 6 {
83 return Err(ProtocolError::FieldParse {
84 command: "GS".to_owned(),
85 field: "all".to_owned(),
86 detail: format!("expected 6 fields, got {}", parts.len()),
87 });
88 }
89 let gga = parse_u8_field(parts[0], "GS", "gga")? != 0;
90 let gll = parse_u8_field(parts[1], "GS", "gll")? != 0;
91 let gsa = parse_u8_field(parts[2], "GS", "gsa")? != 0;
92 let gsv = parse_u8_field(parts[3], "GS", "gsv")? != 0;
93 let rmc = parse_u8_field(parts[4], "GS", "rmc")? != 0;
94 let vtg = parse_u8_field(parts[5], "GS", "vtg")? != 0;
95 Ok(Response::GpsSentences {
96 gga,
97 gll,
98 gsa,
99 gsv,
100 rmc,
101 vtg,
102 })
103}