aprs_parser/
compression_type.rs

1#[derive(PartialEq, Eq, Copy, Clone, Debug)]
2pub enum GpsFix {
3    Old,
4    Current,
5}
6
7impl From<bool> for GpsFix {
8    fn from(bit: bool) -> Self {
9        match bit {
10            false => GpsFix::Old,
11            true => GpsFix::Current,
12        }
13    }
14}
15
16impl From<GpsFix> for bool {
17    fn from(fix: GpsFix) -> bool {
18        match fix {
19            GpsFix::Old => false,
20            GpsFix::Current => true,
21        }
22    }
23}
24
25#[derive(PartialEq, Eq, Copy, Clone, Debug)]
26pub enum NmeaSource {
27    Other,
28    Gll,
29    Gga,
30    Rmc,
31}
32
33impl From<(bool, bool)> for NmeaSource {
34    fn from(bits: (bool, bool)) -> Self {
35        match bits {
36            (false, false) => NmeaSource::Other,
37            (false, true) => NmeaSource::Gll,
38            (true, false) => NmeaSource::Gga,
39            (true, true) => NmeaSource::Rmc,
40        }
41    }
42}
43
44impl From<NmeaSource> for (bool, bool) {
45    fn from(source: NmeaSource) -> Self {
46        match source {
47            NmeaSource::Other => (false, false),
48            NmeaSource::Gll => (false, true),
49            NmeaSource::Gga => (true, false),
50            NmeaSource::Rmc => (true, true),
51        }
52    }
53}
54
55#[derive(PartialEq, Eq, Copy, Clone, Debug)]
56pub enum Origin {
57    Compressed,
58    TncBText,
59    Software,
60    Tbd,
61    Kpc3,
62    Pico,
63    Other,
64    Digipeater,
65}
66
67impl From<(bool, bool, bool)> for Origin {
68    fn from(bits: (bool, bool, bool)) -> Self {
69        match bits {
70            (false, false, false) => Origin::Compressed,
71            (false, false, true) => Origin::TncBText,
72            (false, true, false) => Origin::Software,
73            (false, true, true) => Origin::Tbd,
74            (true, false, false) => Origin::Kpc3,
75            (true, false, true) => Origin::Pico,
76            (true, true, false) => Origin::Other,
77            (true, true, true) => Origin::Digipeater,
78        }
79    }
80}
81
82impl From<Origin> for (bool, bool, bool) {
83    fn from(origin: Origin) -> Self {
84        match origin {
85            Origin::Compressed => (false, false, false),
86            Origin::TncBText => (false, false, true),
87            Origin::Software => (false, true, false),
88            Origin::Tbd => (false, true, true),
89            Origin::Kpc3 => (true, false, false),
90            Origin::Pico => (true, false, true),
91            Origin::Other => (true, true, false),
92            Origin::Digipeater => (true, true, true),
93        }
94    }
95}
96
97#[derive(PartialEq, Eq, Copy, Clone, Debug)]
98pub struct AprsCompressionType {
99    pub gps_fix: GpsFix,
100    pub nmea_source: NmeaSource,
101    pub origin: Origin,
102}
103
104impl From<u8> for AprsCompressionType {
105    fn from(byte: u8) -> Self {
106        let gps_fix = (byte & (1 << 5)) != 0;
107        let nmea_source = (byte & (1 << 4) != 0, byte & (1 << 3) != 0);
108        let origin = (
109            byte & (1 << 2) != 0,
110            byte & (1 << 1) != 0,
111            byte & (1 << 0) != 0,
112        );
113
114        Self {
115            gps_fix: gps_fix.into(),
116            nmea_source: nmea_source.into(),
117            origin: origin.into(),
118        }
119    }
120}
121
122impl From<AprsCompressionType> for u8 {
123    fn from(t: AprsCompressionType) -> u8 {
124        let b5: bool = t.gps_fix.into();
125        let (b4, b3) = t.nmea_source.into();
126        let (b2, b1, b0) = t.origin.into();
127
128        (u8::from(b5) << 5)
129            + (u8::from(b4) << 4)
130            + (u8::from(b3) << 3)
131            + (u8::from(b2) << 2)
132            + (u8::from(b1) << 1)
133            + (u8::from(b0))
134    }
135}
136
137#[cfg(test)]
138mod tests {
139    use super::*;
140
141    #[test]
142    fn encode_works() {
143        let byte: u8 = 0b00111010;
144        let expected = AprsCompressionType {
145            gps_fix: GpsFix::Current,
146            nmea_source: NmeaSource::Rmc,
147            origin: Origin::Software,
148        };
149
150        assert_eq!(expected, byte.into());
151    }
152
153    #[test]
154    fn decode_works() {
155        let expected: u8 = 0b00111010;
156        let ctype = AprsCompressionType {
157            gps_fix: GpsFix::Current,
158            nmea_source: NmeaSource::Rmc,
159            origin: Origin::Software,
160        };
161
162        assert_eq!(expected, ctype.into());
163    }
164}