1 | /// A macro which defines an enum type. |
2 | macro_rules! enum_builder { |
3 | ( |
4 | $(#[$comment:meta])* |
5 | @U8 |
6 | $enum_vis:vis enum $enum_name:ident |
7 | { $( $enum_var: ident => $enum_val: expr ),* } |
8 | ) => { |
9 | $(#[$comment])* |
10 | #[non_exhaustive] |
11 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
12 | $enum_vis enum $enum_name { |
13 | $( $enum_var),* |
14 | ,Unknown(u8) |
15 | } |
16 | impl $enum_name { |
17 | $enum_vis fn get_u8(&self) -> u8 { |
18 | let x = self.clone(); |
19 | match x { |
20 | $( $enum_name::$enum_var => $enum_val),* |
21 | ,$enum_name::Unknown(x) => x |
22 | } |
23 | } |
24 | } |
25 | impl Codec for $enum_name { |
26 | // NOTE(allow) fully qualified Vec is only needed in no-std mode |
27 | #[allow(unused_qualifications)] |
28 | fn encode(&self, bytes: &mut alloc::vec::Vec<u8>) { |
29 | self.get_u8().encode(bytes); |
30 | } |
31 | |
32 | fn read(r: &mut Reader) -> Result<Self, crate::error::InvalidMessage> { |
33 | match u8::read(r) { |
34 | Ok(x) => Ok($enum_name::from(x)), |
35 | Err(_) => Err(crate::error::InvalidMessage::MissingData(stringify!($enum_name))), |
36 | } |
37 | } |
38 | } |
39 | impl From<u8> for $enum_name { |
40 | fn from(x: u8) -> Self { |
41 | match x { |
42 | $($enum_val => $enum_name::$enum_var),* |
43 | , x => $enum_name::Unknown(x), |
44 | } |
45 | } |
46 | } |
47 | }; |
48 | ( |
49 | $(#[$comment:meta])* |
50 | @U16 |
51 | $enum_vis:vis enum $enum_name:ident |
52 | { $( $enum_var: ident => $enum_val: expr ),* } |
53 | ) => { |
54 | $(#[$comment])* |
55 | #[non_exhaustive] |
56 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
57 | $enum_vis enum $enum_name { |
58 | $( $enum_var),* |
59 | ,Unknown(u16) |
60 | } |
61 | impl $enum_name { |
62 | $enum_vis fn get_u16(&self) -> u16 { |
63 | let x = self.clone(); |
64 | match x { |
65 | $( $enum_name::$enum_var => $enum_val),* |
66 | ,$enum_name::Unknown(x) => x |
67 | } |
68 | } |
69 | |
70 | #[allow(dead_code)] // generated irrespective if there are callers |
71 | $enum_vis fn as_str(&self) -> Option<&'static str> { |
72 | match self { |
73 | $( $enum_name::$enum_var => Some(stringify!($enum_var))),* |
74 | ,$enum_name::Unknown(_) => None, |
75 | } |
76 | } |
77 | } |
78 | impl Codec for $enum_name { |
79 | // NOTE(allow) fully qualified Vec is only needed in no-std mode |
80 | #[allow(unused_qualifications)] |
81 | fn encode(&self, bytes: &mut alloc::vec::Vec<u8>) { |
82 | self.get_u16().encode(bytes); |
83 | } |
84 | |
85 | fn read(r: &mut Reader) -> Result<Self, crate::error::InvalidMessage> { |
86 | match u16::read(r) { |
87 | Ok(x) => Ok($enum_name::from(x)), |
88 | Err(_) => Err(crate::error::InvalidMessage::MissingData(stringify!($enum_name))), |
89 | } |
90 | } |
91 | } |
92 | impl From<u16> for $enum_name { |
93 | fn from(x: u16) -> Self { |
94 | match x { |
95 | $($enum_val => $enum_name::$enum_var),* |
96 | , x => $enum_name::Unknown(x), |
97 | } |
98 | } |
99 | } |
100 | }; |
101 | } |
102 | |