#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum ErrorCode {
EParam,
ELength,
ENotConfigured,
EModulation,
EUnknownCmd,
EBusy,
ERadio,
EFrame,
EInternal,
Unknown(u16),
}
impl ErrorCode {
pub const fn as_u16(self) -> u16 {
match self {
Self::EParam => 0x0001,
Self::ELength => 0x0002,
Self::ENotConfigured => 0x0003,
Self::EModulation => 0x0004,
Self::EUnknownCmd => 0x0005,
Self::EBusy => 0x0006,
Self::ERadio => 0x0101,
Self::EFrame => 0x0102,
Self::EInternal => 0x0103,
Self::Unknown(raw) => raw,
}
}
pub const fn from_u16(v: u16) -> Self {
match v {
0x0001 => Self::EParam,
0x0002 => Self::ELength,
0x0003 => Self::ENotConfigured,
0x0004 => Self::EModulation,
0x0005 => Self::EUnknownCmd,
0x0006 => Self::EBusy,
0x0101 => Self::ERadio,
0x0102 => Self::EFrame,
0x0103 => Self::EInternal,
other => Self::Unknown(other),
}
}
pub const fn is_async_range(self) -> bool {
let v = self.as_u16();
v >= 0x0100 && v <= 0x01FF
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn canonical_sync_values() {
assert_eq!(ErrorCode::EParam.as_u16(), 0x0001);
assert_eq!(ErrorCode::ELength.as_u16(), 0x0002);
assert_eq!(ErrorCode::ENotConfigured.as_u16(), 0x0003);
assert_eq!(ErrorCode::EModulation.as_u16(), 0x0004);
assert_eq!(ErrorCode::EUnknownCmd.as_u16(), 0x0005);
assert_eq!(ErrorCode::EBusy.as_u16(), 0x0006);
}
#[test]
fn canonical_async_values() {
assert_eq!(ErrorCode::ERadio.as_u16(), 0x0101);
assert_eq!(ErrorCode::EFrame.as_u16(), 0x0102);
assert_eq!(ErrorCode::EInternal.as_u16(), 0x0103);
}
#[test]
fn assigned_roundtrip() {
let all = [
ErrorCode::EParam,
ErrorCode::ELength,
ErrorCode::ENotConfigured,
ErrorCode::EModulation,
ErrorCode::EUnknownCmd,
ErrorCode::EBusy,
ErrorCode::ERadio,
ErrorCode::EFrame,
ErrorCode::EInternal,
];
for code in all {
assert_eq!(ErrorCode::from_u16(code.as_u16()), code);
}
}
#[test]
fn unknown_preserves_raw() {
let unusual = [0x0000u16, 0x0007, 0x0100, 0x0200, 0xFFFF];
for raw in unusual {
let c = ErrorCode::from_u16(raw);
assert_eq!(c.as_u16(), raw);
assert!(matches!(c, ErrorCode::Unknown(_)));
}
}
#[test]
fn is_async_range_boundaries() {
assert!(!ErrorCode::EParam.is_async_range());
assert!(!ErrorCode::EBusy.is_async_range());
assert!(ErrorCode::ERadio.is_async_range());
assert!(ErrorCode::EInternal.is_async_range());
assert!(!ErrorCode::Unknown(0x00FF).is_async_range());
assert!(!ErrorCode::Unknown(0x0200).is_async_range());
assert!(ErrorCode::Unknown(0x01FF).is_async_range());
}
}