How do I get an enum as a string?

前端 未结 2 633
悲哀的现实
悲哀的现实 2020-12-18 17:41

I have an enum with many values and I\'d like to write the name of one of its values to a stream:

enum Foo {
    Bar = 0x00,
    Baz = 0x01,
    Qux = 0x02,
         


        
2条回答
  •  别那么骄傲
    2020-12-18 18:27

    Since the names of enum variants are fixed, you don't need to allocate a String, a &'static str will suffice. A macro can remove the boilerplate:

    macro_rules! enum_str {
        (enum $name:ident {
            $($variant:ident = $val:expr),*,
        }) => {
            enum $name {
                $($variant = $val),*
            }
    
            impl $name {
                fn name(&self) -> &'static str {
                    match self {
                        $($name::$variant => stringify!($variant)),*
                    }
                }
            }
        };
    }
    
    enum_str! {
        enum Foo {
            Bar = 0x00,
            Baz = 0x01,
            Qux = 0x02,
            //...
            Quux = 0xFF,
        }
    }
    
    fn main() {
        assert_eq!(Foo::Baz.name(), "Baz");
    }
    

    Even better, you can derive these with a crate like strum_macros.

    In strum 0.10, you can use AsStaticRef / AsStaticStr to do the exact same code:

    extern crate strum; // 0.10.0
    #[macro_use]
    extern crate strum_macros; // 0.10.0
    
    use strum::AsStaticRef;
    
    #[derive(AsStaticStr)]
    enum Foo {
        Bar = 0x00,
        Baz = 0x01,
        Qux = 0x02,
        //...
        Quux = 0xFF,
    }
    
    fn main() {
        assert_eq!(Foo::Baz.as_static(), "Baz");
    }
    

    In strum 0.9, the string slice's lifetime is not 'static in this case:

    #[macro_use]
    extern crate strum_macros; // 0.9.0
    
    #[derive(AsRefStr)]
    enum Foo {
        Bar = 0x00,
        Baz = 0x01,
        Qux = 0x02,
        //...
        Quux = 0xFF,
    }
    
    fn main() {
        assert_eq!(Foo::Baz.as_ref(), "Baz");
    }
    

提交回复
热议问题