1macro_rules! numerical_enum {
5 (
6 $(#[$attr:meta])*
7 $vis:vis enum $enum_name:ident as $repr:tt {
8 $(
9 $(#[$id_attr:meta])*
10 $identifier:ident = $value:expr,
11 )+
12 }
13 ) => {
14 $(#[$attr])*
15 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
16 #[repr($repr)]
17 $vis enum $enum_name {
18 $(
19 $(#[$id_attr])*
20 $identifier = $value,
21 )+
22 }
23
24 impl TryFrom<$repr> for $enum_name {
25 type Error = std::io::Error;
26
27 fn try_from(val: $repr) -> std::io::Result<Self> {
28 match val {
29 $(x if x == $value => Ok($enum_name::$identifier),)*
30 _ => Err(std::io::Error::new(
31 std::io::ErrorKind::InvalidData,
32 format!(
33 "Invalid value for {}: {val:x}",
34 stringify!($enum_name),
35 ),
36 )),
37 }
38 }
39 }
40 }
41}
42
43pub(crate) use numerical_enum;
44
45macro_rules! passthrough_trait_fn {
53 { fn $name:ident($($param:ident: $type:ty),*) -> $ret:ty; } => {
54 fn $name($($param: $type),*) -> $ret {
55 Self::$name($($param),*)
56 }
57 };
58
59 { fn $name:ident(self$(, $param:ident: $type:ty)*) -> $ret:ty; } => {
60 passthrough_trait_fn! { fn $name(self: Self$(, $param: $type)*) -> $ret; }
61 };
62
63 { fn $name:ident(&self$(, $param:ident: $type:ty)*) -> $ret:ty; } => {
64 passthrough_trait_fn! { fn $name(self: &Self$(, $param: $type)*) -> $ret; }
65 };
66
67 { fn $name:ident(&mut self$(, $param:ident: $type:ty)*) -> $ret:ty; } => {
68 passthrough_trait_fn! { fn $name(self: &mut Self$(, $param: $type)*) -> $ret; }
69 };
70
71 { fn $name:ident(self$(, $param:ident: $type:ty)*); } => {
72 passthrough_trait_fn! { fn $name(self$(, $param: $type)*) -> (); }
73 };
74
75 { fn $name:ident(&self$(, $param:ident: $type:ty)*); } => {
76 passthrough_trait_fn! { fn $name(&self$(, $param: $type)*) -> (); }
77 };
78
79 { fn $name:ident(&mut self$(, $param:ident: $type:ty)*); } => {
80 passthrough_trait_fn! { fn $name(&mut self$(, $param: $type)*) -> (); }
81 };
82}
83
84pub(crate) use passthrough_trait_fn;