macro_bits/serializable_enum.rs
1#[macro_export]
2/// Generate a serializable enum.
3///
4/// An Unknown field is always generated, which contains a variable, which type is the enum representation.
5/// ```
6/// use macro_bits::serializable_enum;
7///
8/// serializable_enum! {
9/// #[derive(Debug, PartialEq)]
10/// pub enum ABC: u8 {
11/// /// This is a doc comment too.
12/// A => 0,
13/// B => 1,
14/// C => 2
15/// }
16/// }
17/// assert_eq!(ABC::from_bits(2), ABC::C);
18/// assert_eq!(ABC::from_bits(3), ABC::Unknown(3));
19/// assert_eq!((ABC::C).into_bits(), 2);
20/// ```
21macro_rules! serializable_enum {
22 (
23 $(#[$enum_attr:meta])*
24 $enum_visibility:vis enum $enum_name:ident : $representation:ty {
25 $(
26 $(#[$field_attr:meta])*
27 $field_name:ident => $field_value:expr
28 ),*
29 }
30 ) => {
31 ::macro_bits::defile::defile!{
32 $(#[$enum_attr])*
33 $enum_visibility enum $enum_name {
34 $(
35 $(#[$field_attr])*
36 $field_name,
37 )*
38 Unknown($representation)
39 }
40 #[allow(ineffective_bit_mask)]
41 impl $enum_name {
42 pub const fn from_bits(value: $representation) -> Self {
43 use $enum_name::*;
44 match value {
45 $(
46 $field_value => $field_name,
47 )*
48 x => Self::Unknown(x)
49 }
50 }
51 pub const fn into_bits(self) -> $representation {
52 use $enum_name::*;
53 match self {
54 $(
55 $field_name => $field_value,
56 )*
57 Self::Unknown(x) => x
58 }
59 }
60 }
61 ::macro_bits::generate_conversions!($representation, $representation, $enum_name);
62 }
63 };
64}