strum

Derive Macro EnumString

Source
#[derive(EnumString)]
{
    // Attributes available to this derive:
    #[strum]
}
Expand description

Converts strings to enum variants based on their name.

auto-derives std::str::FromStr on the enum (for Rust 1.34 and above, std::convert::TryFrom<&str> will be derived as well). Each variant of the enum will match on it’s own name. This can be overridden using serialize="DifferentName" or to_string="DifferentName" on the attribute as shown below. Multiple deserializations can be added to the same variant. If the variant contains additional data, they will be set to their default values upon deserialization.

The default attribute can be applied to a tuple variant with a single data parameter. When a match isn’t found, the given variant will be returned and the input string will be captured in the parameter.

Note that the implementation of FromStr by default only matches on the name of the variant. There is an option to match on different case conversions through the #[strum(serialize_all = "snake_case")] type attribute.

See the Additional Attributes Section for more information on using this feature.

If you have a large enum, you may want to consider using the use_phf attribute here. It leverages perfect hash functions to parse much quicker than a standard match. (MSRV 1.46)

§Example howto use EnumString

use std::str::FromStr;
use strum_macros::EnumString;

#[derive(Debug, PartialEq, EnumString)]
enum Color {
    Red,
    // The Default value will be inserted into range if we match "Green".
    Green {
        range: usize,
    },

    // We can match on multiple different patterns.
    #[strum(serialize = "blue", serialize = "b")]
    Blue(usize),

    // Notice that we can disable certain variants from being found
    #[strum(disabled)]
    Yellow,

    // We can make the comparison case insensitive (however Unicode is not supported at the moment)
    #[strum(ascii_case_insensitive)]
    Black,
}

/*
//The generated code will look like:
impl std::str::FromStr for Color {
    type Err = ::strum::ParseError;

    fn from_str(s: &str) -> ::core::result::Result<Color, Self::Err> {
        match s {
            "Red" => ::core::result::Result::Ok(Color::Red),
            "Green" => ::core::result::Result::Ok(Color::Green { range:Default::default() }),
            "blue" => ::core::result::Result::Ok(Color::Blue(Default::default())),
            "b" => ::core::result::Result::Ok(Color::Blue(Default::default())),
            s if s.eq_ignore_ascii_case("Black") => ::core::result::Result::Ok(Color::Black),
            _ => ::core::result::Result::Err(::strum::ParseError::VariantNotFound),
        }
    }
}
*/

// simple from string
let color_variant = Color::from_str("Red").unwrap();
assert_eq!(Color::Red, color_variant);
// short version works too
let color_variant = Color::from_str("b").unwrap();
assert_eq!(Color::Blue(0), color_variant);
// was disabled for parsing = returns parse-error
let color_variant = Color::from_str("Yellow");
assert!(color_variant.is_err());
// however the variant is still normally usable
println!("{:?}", Color::Yellow);
let color_variant = Color::from_str("bLACk").unwrap();
assert_eq!(Color::Black, color_variant);