valued_enums/
enums.rs

1pub trait ValuedEnum<T> where Self: Sized {
2    fn equal(&self, other: &T) -> bool;
3
4    fn key(&self) -> &str;
5    fn value(self) -> T;
6    fn ref_value(&self) -> &T;
7
8    fn keys() -> Vec<&'static str>;
9    fn values() -> Vec<T>;
10    fn variants() -> Vec<Self>;
11
12    fn from_key(key: &str) -> Option<Self>;
13    fn from_value(value: &T) -> Option<Self>;
14}
15
16
17#[macro_export]
18macro_rules! py_enum {
19    {
20        $(#[$meta:meta])*
21        $name:ident ( $valtype:ty ):
22            $(
23                $(#[$item_meta:meta])*
24                $id:ident = $val:expr
25            )*
26            $(,)?
27    } => {
28        $crate::valued_enum! {
29            $(#[$meta])*
30            pub enum $name ($valtype) {
31                $(
32                    $(#[$item_meta])*
33                    pub $id = $val,
34                )*
35            }
36        }
37    }
38}
39
40#[macro_export]
41macro_rules! rust_enum {
42    {
43        $(#[$meta:meta])*
44        $e_vis:vis enum $name:ident ( $valtype:ty ) {
45            $(
46                $(#[$item_meta:meta])*
47                $id:ident = $val:expr,
48            )*
49            $(,)?
50        }
51    } => {
52        $crate::valued_enum! {
53            $(#[$meta])*
54            $e_vis enum $name ($valtype) {
55                $(
56                    $(#[$item_meta])*
57                    pub $id = $val,
58                )*
59            }
60        }
61    }
62}
63
64#[macro_export]
65macro_rules! valued_enum {
66    {
67       $(#[$meta:meta])*
68       $e_vis:vis enum $name:ident ( $valtype:ty ) {
69           $(
70               $(#[$item_meta:meta])*
71               $i_vis:vis $id:ident = $val:expr,
72           )*
73           $(,)?
74       }
75    } => {
76        $(#[$meta])*
77        $e_vis struct $name(&'static str, $valtype);
78
79        impl $name {
80            $(
81                $(#[$item_meta])*
82                $i_vis const $id: $name = $name(stringify!($id), $val);
83            )*
84        }
85
86        impl $crate::ValuedEnum<$valtype> for $name {
87            fn equal(&self, other: &$valtype) -> bool {
88                &self.1 == other
89            }
90
91            fn key(&self) -> &str {
92                self.0
93            }
94
95            fn value(self) -> $valtype {
96                self.1
97            }
98
99            fn ref_value(&self) -> &$valtype {
100                &self.1
101            }
102
103            fn keys() -> Vec<&'static str> {
104                vec![
105                    $( $name::$id.key(), )*
106                ]
107            }
108
109            fn values() -> Vec<$valtype> {
110                vec![
111                    $( $name::$id.value(), )*
112                ]
113            }
114
115            fn variants() -> Vec<$name> {
116                vec![
117                    $( $name::$id, )*
118                ]
119            }
120
121            fn from_key(key: &str) -> Option<Self> {
122                $( if $name::$id.key() == key { return Some($name::$id) } )*
123                
124                None
125            }
126
127            fn from_value(value: &$valtype) -> Option<Self> {
128                $( if $name::$id.equal(value) { return Some($name::$id) } )*
129                
130                None
131            }
132        }
133    };
134}