dstar_gateway_core/dprs/
error.rs

1//! DPRS parser/encoder errors.
2
3/// DPRS sentence parser errors.
4#[derive(Debug, Clone, thiserror::Error, PartialEq)]
5#[non_exhaustive]
6pub enum DprsError {
7    /// Sentence does not start with `$$CRC`.
8    #[error("DPRS sentence does not start with $$CRC")]
9    MissingCrcPrefix,
10
11    /// Sentence is shorter than the minimum viable length.
12    #[error("DPRS sentence too short: {got} bytes")]
13    TooShort {
14        /// Observed length.
15        got: usize,
16    },
17
18    /// Lat/lon field couldn't be parsed.
19    #[error("DPRS sentence has malformed lat/lon field")]
20    MalformedCoordinates,
21
22    /// Latitude out of range `-90.0..=90.0` or NaN.
23    #[error("latitude {got} out of range -90..=90")]
24    LatitudeOutOfRange {
25        /// Offending value.
26        got: f64,
27    },
28
29    /// Longitude out of range `-180.0..=180.0` or NaN.
30    #[error("longitude {got} out of range -180..=180")]
31    LongitudeOutOfRange {
32        /// Offending value.
33        got: f64,
34    },
35
36    /// Callsign field fails `Callsign::try_from_str`.
37    #[error("DPRS sentence callsign field is invalid: {reason}")]
38    InvalidCallsign {
39        /// Why the callsign failed.
40        reason: &'static str,
41    },
42
43    /// CRC mismatch — computed vs on-wire disagree.
44    #[error("DPRS $$CRC mismatch: computed 0x{computed:04X}, on-wire 0x{on_wire:04X}")]
45    CrcMismatch {
46        /// Computed CRC.
47        computed: u16,
48        /// On-wire CRC.
49        on_wire: u16,
50    },
51}
52
53#[cfg(test)]
54mod tests {
55    use super::*;
56
57    #[test]
58    fn missing_prefix_display() {
59        let err = DprsError::MissingCrcPrefix;
60        assert!(err.to_string().contains("$$CRC"));
61    }
62
63    #[test]
64    fn latitude_out_of_range_display() {
65        let err = DprsError::LatitudeOutOfRange { got: 91.0 };
66        assert!(err.to_string().contains("91"));
67    }
68
69    #[test]
70    fn longitude_out_of_range_display() {
71        let err = DprsError::LongitudeOutOfRange { got: -181.5 };
72        assert!(err.to_string().contains("-181"));
73    }
74
75    #[test]
76    fn crc_mismatch_display() {
77        let err = DprsError::CrcMismatch {
78            computed: 0x1234,
79            on_wire: 0x5678,
80        };
81        let s = err.to_string();
82        assert!(s.contains("1234"));
83        assert!(s.contains("5678"));
84    }
85}