donglora_protocol/
errors.rs1#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
24pub enum ErrorCode {
25 EParam,
27 ELength,
29 ENotConfigured,
31 EModulation,
33 EUnknownCmd,
35 EBusy,
37
38 ERadio,
40 EFrame,
42 EInternal,
44
45 Unknown(u16),
48}
49
50impl ErrorCode {
51 pub const fn as_u16(self) -> u16 {
53 match self {
54 Self::EParam => 0x0001,
55 Self::ELength => 0x0002,
56 Self::ENotConfigured => 0x0003,
57 Self::EModulation => 0x0004,
58 Self::EUnknownCmd => 0x0005,
59 Self::EBusy => 0x0006,
60 Self::ERadio => 0x0101,
61 Self::EFrame => 0x0102,
62 Self::EInternal => 0x0103,
63 Self::Unknown(raw) => raw,
64 }
65 }
66
67 pub const fn from_u16(v: u16) -> Self {
70 match v {
71 0x0001 => Self::EParam,
72 0x0002 => Self::ELength,
73 0x0003 => Self::ENotConfigured,
74 0x0004 => Self::EModulation,
75 0x0005 => Self::EUnknownCmd,
76 0x0006 => Self::EBusy,
77 0x0101 => Self::ERadio,
78 0x0102 => Self::EFrame,
79 0x0103 => Self::EInternal,
80 other => Self::Unknown(other),
81 }
82 }
83
84 pub const fn is_async_range(self) -> bool {
88 let v = self.as_u16();
89 v >= 0x0100 && v <= 0x01FF
90 }
91}
92
93#[cfg(test)]
94mod tests {
95 use super::*;
96
97 #[test]
98 fn canonical_sync_values() {
99 assert_eq!(ErrorCode::EParam.as_u16(), 0x0001);
100 assert_eq!(ErrorCode::ELength.as_u16(), 0x0002);
101 assert_eq!(ErrorCode::ENotConfigured.as_u16(), 0x0003);
102 assert_eq!(ErrorCode::EModulation.as_u16(), 0x0004);
103 assert_eq!(ErrorCode::EUnknownCmd.as_u16(), 0x0005);
104 assert_eq!(ErrorCode::EBusy.as_u16(), 0x0006);
105 }
106
107 #[test]
108 fn canonical_async_values() {
109 assert_eq!(ErrorCode::ERadio.as_u16(), 0x0101);
110 assert_eq!(ErrorCode::EFrame.as_u16(), 0x0102);
111 assert_eq!(ErrorCode::EInternal.as_u16(), 0x0103);
112 }
113
114 #[test]
115 fn assigned_roundtrip() {
116 let all = [
117 ErrorCode::EParam,
118 ErrorCode::ELength,
119 ErrorCode::ENotConfigured,
120 ErrorCode::EModulation,
121 ErrorCode::EUnknownCmd,
122 ErrorCode::EBusy,
123 ErrorCode::ERadio,
124 ErrorCode::EFrame,
125 ErrorCode::EInternal,
126 ];
127 for code in all {
128 assert_eq!(ErrorCode::from_u16(code.as_u16()), code);
129 }
130 }
131
132 #[test]
133 fn unknown_preserves_raw() {
134 let unusual = [0x0000u16, 0x0007, 0x0100, 0x0200, 0xFFFF];
135 for raw in unusual {
136 let c = ErrorCode::from_u16(raw);
137 assert_eq!(c.as_u16(), raw);
138 assert!(matches!(c, ErrorCode::Unknown(_)));
139 }
140 }
141
142 #[test]
143 fn is_async_range_boundaries() {
144 assert!(!ErrorCode::EParam.is_async_range());
145 assert!(!ErrorCode::EBusy.is_async_range());
146 assert!(ErrorCode::ERadio.is_async_range());
147 assert!(ErrorCode::EInternal.is_async_range());
148 assert!(!ErrorCode::Unknown(0x00FF).is_async_range());
150 assert!(!ErrorCode::Unknown(0x0200).is_async_range());
151 assert!(ErrorCode::Unknown(0x01FF).is_async_range());
152 }
153}