aprs_decode/
third_party.rs1use crate::error::AprsError;
2use crate::packet::AprsPacket;
3
4#[derive(Debug, Clone, PartialEq)]
12#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
13pub struct AprsThirdParty {
14 pub inner: Box<AprsPacket>,
16}
17
18impl AprsThirdParty {
19 pub(crate) fn parse(info: &[u8]) -> Result<Self, AprsError> {
21 let inner_bytes = info.get(1..).unwrap_or_default();
22 let inner = AprsPacket::decode_textual(inner_bytes)?;
23 Ok(Self {
24 inner: Box::new(inner),
25 })
26 }
27
28 pub fn encode(&self) -> Result<Vec<u8>, AprsError> {
29 let mut out = vec![b'}'];
30 out.extend_from_slice(&self.inner.encode_textual()?);
31 Ok(out)
32 }
33}
34
35#[cfg(test)]
36mod tests {
37 use super::*;
38 use crate::AprsData;
39
40 #[test]
41 fn decode_third_party_position() {
42 let tp = AprsThirdParty::parse(b"}WB0VGI-7>APOT30,W0RO-11*,WIDE2-1:!4228.35N/09101.45Wk")
43 .unwrap();
44 assert_eq!(tp.inner.from.to_string(), "WB0VGI-7");
45 assert!(matches!(tp.inner.data, AprsData::Position(_)));
46 }
47
48 #[test]
49 fn decode_third_party_message() {
50 let tp =
51 AprsThirdParty::parse(b"}W1ABC>APRS,WIDE1-1::DEST :Hello from third party{123")
52 .unwrap();
53 assert_eq!(tp.inner.from.to_string(), "W1ABC");
54 assert!(matches!(tp.inner.data, AprsData::Message(_)));
55 }
56
57 #[test]
58 fn encode_round_trip() {
59 let inner = b"}W1ABC>APRS::DEST :Hello{001";
60 let tp = AprsThirdParty::parse(inner).unwrap();
61 let encoded = tp.encode().unwrap();
62 assert_eq!(encoded.as_slice(), inner.as_slice());
63 }
64}