umsh_ulcp/
status.rs

1//! Status codes carried in `PROP_LAST_STATUS`.
2
3/// A status code, encoded on the wire as a packed unsigned integer.
4///
5/// Represented as a newtype rather than an enum so receivers can carry
6/// codes defined by future protocol versions without loss.
7#[derive(Clone, Copy, PartialEq, Eq)]
8pub struct Status(pub u32);
9
10impl Status {
11    pub const OK: Self = Self(0);
12    pub const FAILURE: Self = Self(1);
13    pub const UNIMPLEMENTED: Self = Self(2);
14    pub const INVALID_ARGUMENT: Self = Self(3);
15    pub const INVALID_STATE: Self = Self(4);
16    pub const INVALID_COMMAND: Self = Self(5);
17    pub const INTERNAL_ERROR: Self = Self(7);
18    pub const PARSE_ERROR: Self = Self(9);
19    pub const IN_PROGRESS: Self = Self(10);
20    pub const NOMEM: Self = Self(11);
21    pub const BUSY: Self = Self(12);
22    pub const PROP_NOT_FOUND: Self = Self(13);
23    pub const CCA_FAILURE: Self = Self(18);
24    pub const ALREADY: Self = Self(19);
25    pub const ITEM_NOT_FOUND: Self = Self(20);
26    pub const DUTY_LIMIT: Self = Self(32);
27
28    pub const RESET_POWER_ON: Self = Self(112);
29    pub const RESET_EXTERNAL: Self = Self(113);
30    pub const RESET_SOFTWARE: Self = Self(114);
31    pub const RESET_RESTORED: Self = Self(115);
32    pub const RESET_CRASH: Self = Self(116);
33    pub const RESET_ASSERT: Self = Self(117);
34    pub const RESET_OTHER: Self = Self(118);
35    pub const RESET_UNKNOWN: Self = Self(119);
36    pub const RESET_WATCHDOG: Self = Self(120);
37
38    /// Whether this code falls in the reset-code range (112-127).
39    pub const fn is_reset(self) -> bool {
40        self.0 >= 112 && self.0 <= 127
41    }
42
43    const fn name(self) -> Option<&'static str> {
44        Some(match self {
45            Self::OK => "OK",
46            Self::FAILURE => "FAILURE",
47            Self::UNIMPLEMENTED => "UNIMPLEMENTED",
48            Self::INVALID_ARGUMENT => "INVALID_ARGUMENT",
49            Self::INVALID_STATE => "INVALID_STATE",
50            Self::INVALID_COMMAND => "INVALID_COMMAND",
51            Self::INTERNAL_ERROR => "INTERNAL_ERROR",
52            Self::PARSE_ERROR => "PARSE_ERROR",
53            Self::IN_PROGRESS => "IN_PROGRESS",
54            Self::NOMEM => "NOMEM",
55            Self::BUSY => "BUSY",
56            Self::PROP_NOT_FOUND => "PROP_NOT_FOUND",
57            Self::CCA_FAILURE => "CCA_FAILURE",
58            Self::ALREADY => "ALREADY",
59            Self::ITEM_NOT_FOUND => "ITEM_NOT_FOUND",
60            Self::DUTY_LIMIT => "DUTY_LIMIT",
61            Self::RESET_POWER_ON => "RESET_POWER_ON",
62            Self::RESET_EXTERNAL => "RESET_EXTERNAL",
63            Self::RESET_SOFTWARE => "RESET_SOFTWARE",
64            Self::RESET_RESTORED => "RESET_RESTORED",
65            Self::RESET_CRASH => "RESET_CRASH",
66            Self::RESET_ASSERT => "RESET_ASSERT",
67            Self::RESET_OTHER => "RESET_OTHER",
68            Self::RESET_UNKNOWN => "RESET_UNKNOWN",
69            Self::RESET_WATCHDOG => "RESET_WATCHDOG",
70            _ => return None,
71        })
72    }
73}
74
75impl core::fmt::Debug for Status {
76    fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
77        match self.name() {
78            Some(name) => write!(formatter, "Status::{name}"),
79            None => write!(formatter, "Status({})", self.0),
80        }
81    }
82}
83
84#[cfg(test)]
85mod tests {
86    use super::*;
87
88    #[test]
89    fn reset_range() {
90        assert!(!Status::OK.is_reset());
91        assert!(!Status::DUTY_LIMIT.is_reset());
92        assert!(Status::RESET_POWER_ON.is_reset());
93        assert!(Status::RESET_WATCHDOG.is_reset());
94        assert!(Status(127).is_reset());
95        assert!(!Status(128).is_reset());
96    }
97
98    #[test]
99    fn debug_names() {
100        assert_eq!(std::format!("{:?}", Status::OK), "Status::OK");
101        assert_eq!(std::format!("{:?}", Status(42)), "Status(42)");
102    }
103}