mqtt_packet/
macros.rs

1/// Generates a public enum with the following traits implemented:
2/// * `From<T> for u8`
3/// * `TryFrom<u8> for T`
4#[macro_export]
5macro_rules! build_enum {
6  (@accum (1, $name:ident { $([$($doc:expr,)*] $key:ident = $value:expr),* }))
7    => {
8    #[repr(u8)]
9    #[derive(Debug, PartialEq, Eq, Hash, PartialOrd, Ord, Clone, Copy)]
10    pub enum $name {
11      $(
12        /// # Examples
13        /// ```rust
14        /// use std::convert::TryFrom;
15        $(#[doc=$doc])*
16        /// ```
17        $key = $value,
18      )*
19    }
20
21    impl From<$name> for u8 {
22        fn from(t: $name) -> Self {
23            match t {
24                $($name::$key => $value),*
25            }
26        }
27    }
28
29    impl TryFrom<u8> for $name {
30        type Error = crate::Error;
31        fn try_from(v: u8) -> Result<Self, crate::Error> {
32            return match v {
33              $($value => Ok($name::$key),)*
34              _ => Err(crate::Error::GenerateError)
35            };
36        }
37    }
38  };
39
40  ($name:ident {
41      $($key:ident = $value:expr),*
42  }) => {
43    build_enum!(@accum (1, $name {
44        $(
45          [
46            concat!("use mqtt_packet::", stringify!($name), ";"),
47            concat!("let id = ", stringify!($name), "::", stringify!($key), ";"),
48            concat!("assert_eq!(u8::from(id), ", stringify!($value), ");"),
49            concat!("assert_eq!(", stringify!($name), "::try_from(", stringify!($value), ").unwrap(), id);"),
50          ]
51          $key = $value),*
52      })
53    );
54  };
55}