1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#[macro_export]
macro_rules! string_enum {
    ( $enum_name:ident, { $( $name:ident = $val:expr ),+ } ) => {
        #[derive(Eq, PartialEq, Clone, Debug)]
        pub enum $enum_name {
            $( $name, )+
        }
        impl std::str::FromStr for $enum_name {
            type Err = ();
            fn from_str(from_val: &str) -> Result<Self, Self::Err> {
                match from_val {
                    $( $val => Ok($enum_name::$name), )+
                    _ => Err(())
                }
            }
        }
        impl std::fmt::Display for $enum_name {
            fn fmt(&self, f: &mut std::fmt::Formatter) -> Result<(), std::fmt::Error> {
                f.write_str(match self {
                    $( $enum_name::$name => $val, )+
                })
            }
        }
        impl $enum_name {
            
            pub fn enum_values() -> Vec<Self> {
                vec![
                    $($enum_name::$name,)+
                ]
            }
            
            
            pub fn string_values() -> Vec<String> {
                Self::enum_values()
                    .iter()
                    .map(ToString::to_string)
                    .collect()
            }
            
            pub fn name_value_pairs() -> Vec<(Self, String)> {
                Self::enum_values()
                    .into_iter()
                    .zip(Self::string_values())
                    .collect()
            }
        }
    };
}