1use core::fmt::Debug;
2
3#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)]
6#[deprecated(
7 note = "The `auto_uds` crate has been renamed to `automotive_diag`. Update your Cargo.toml, and use this enum from the `uds` namespace."
8)]
9pub enum ByteWrapper<T> {
10 Standard(T),
11 Extended(u8),
12}
13
14impl<T: Debug> Debug for ByteWrapper<T> {
15 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
16 match self {
17 Self::Standard(v) => Debug::fmt(v, f),
19 Self::Extended(v) => write!(f, "Extended({v:#02X})"),
20 }
21 }
22}
23
24impl<T: Into<u8>> From<ByteWrapper<T>> for u8 {
25 fn from(value: ByteWrapper<T>) -> Self {
26 match value {
27 ByteWrapper::Standard(v) => v.into(),
28 ByteWrapper::Extended(v) => v,
29 }
30 }
31}
32
33impl<T: TryFrom<u8>> From<u8> for ByteWrapper<T> {
34 fn from(value: u8) -> Self {
35 match T::try_from(value) {
36 Ok(v) => ByteWrapper::Standard(v),
37 Err(_) => ByteWrapper::Extended(value),
38 }
39 }
40}
41
42#[macro_export]
43macro_rules! enum_wrapper {
44 ($enum_name:tt, $enum_wrapper:tt) => {
45 #[doc = concat!("Store a single byte, either as a `Standard(", stringify!($enum_name), ")`, or as an `Extended(u8)`.")]
46 pub type $enum_wrapper = $crate::ByteWrapper<$enum_name>;
47
48 impl From<$crate::$enum_name> for $crate::$enum_wrapper {
49 fn from(value: $crate::$enum_name) -> Self {
50 Self::Standard(value)
51 }
52 }
53
54 #[cfg(test)]
55 mod tests {
56 #[test]
57 #[allow(non_snake_case)]
58 fn test_try_from() {
59 for value in 0x00_u8..=0xFF {
60 if let Ok(v) = $crate::$enum_name::try_from(value) {
61 let enc: u8 = v.into();
62 assert_eq!(value, enc, "{value:#02X} → {v:?} → {enc:#02X}");
63 }
64 }
65 }
66 #[test]
67 #[allow(non_snake_case)]
68 fn test_from() {
69 for value in 0x00_u8..=0xFF {
70 let v = $crate::$enum_wrapper::from(value);
71 let enc: u8 = v.into();
72 assert_eq!(value, enc, "Wrapped {value:#02X} → {v:?} → {enc:#02X}");
73 }
74 }
75 }
76 };
77}