annotatable_enum/
lib.rs

1#[macro_export]
2macro_rules! implement_annotatable_enum {
3    ($name:ident {
4        $($item: ident = $code: expr,)*
5    }) => {
6        impl $name {
7            pub fn try_from(code: isize) -> ::std::option::Option<$name> {
8                match code {
9                    $($code => ::std::option::Option::Some($name::$item),)*
10                    _ => ::std::option::Option::None
11                }
12            }
13        }
14
15        impl ::std::convert::Into<isize> for $name {
16            fn into(self) -> isize {
17                self as isize
18            }
19        }
20    }
21}
22
23#[macro_export]
24macro_rules! annotatable_enum {
25    ($name:ident {
26        $($item: ident = $code: expr,)*
27    }) => {
28        #[derive(Debug, Copy, Clone, PartialEq, Eq)]
29        enum $name {
30            $($item = $code,)*
31        }
32
33        implement_annotatable_enum!($name {
34            $($item = $code,)*
35        });
36    };
37
38    (pub $name:ident {
39        $($item: ident = $code: expr,)*
40    }) => {
41        #[derive(Debug, Copy, Clone, PartialEq, Eq)]
42        pub enum $name {
43            $($item = $code,)*
44        }
45
46        implement_annotatable_enum!($name {
47            $($item = $code,)*
48        });
49
50    };
51}
52
53#[cfg(test)]
54mod tests {
55    annotatable_enum!(Test {
56        Value = 0,
57        AnotherValue = 1,
58    });
59
60    #[test]
61    fn it_creates_enum_from_valid_code() {
62        assert_eq!(Test::try_from(0), Some(Test::Value));
63        assert_eq!(Test::try_from(1), Some(Test::AnotherValue));
64    }
65
66    #[test]
67    fn it_does_not_create_enum_from_invalid_code() {
68        assert_eq!(Test::try_from(2), None);
69    }
70
71    #[test]
72    fn it_converts_enum_into_isize() {
73        let zero: isize = Test::Value.into();
74        assert_eq!(zero, 0);
75    }
76}