Skip to content

Derive EnumDiscriminants

Peter Glotfelty edited this page Aug 18, 2019 · 1 revision

Given an enum named MyEnum, generates another enum called MyEnumDiscriminants with the same variants, without any data fields. This is useful when you wish to determine the variant of an enum from a String, but the variants contain any non-Default fields. By default, the generated enum has the following derives: Clone, Copy, Debug, PartialEq, Eq. You can add additional derives using the #[strum_discriminants(derive(AdditionalDerive))] attribute.

Here's an example:

extern crate strum;
#[macro_use] extern crate strum_macros;

// Bring trait into scope
use std::str::FromStr;

#[derive(Debug)]
struct NonDefault;

#[allow(dead_code)]
#[derive(Debug, EnumDiscriminants)]
#[strum_discriminants(derive(EnumString))]
enum MyEnum {
    Variant0(NonDefault),
    Variant1 { a: NonDefault },
}

fn main() {
    assert_eq!(
        MyEnumDiscriminants::Variant0,
        MyEnumDiscriminants::from_str("Variant0").unwrap()
    );
}

You can also rename the generated enum using the #[strum_discriminants(name(OtherName))] attribute:

extern crate strum;
#[macro_use] extern crate strum_macros;
// You need to bring the type into scope to use it!!!
use strum::IntoEnumIterator;

#[allow(dead_code)]
#[derive(Debug, EnumDiscriminants)]
#[strum_discriminants(derive(EnumIter))]
#[strum_discriminants(name(MyVariants))]
enum MyEnum {
    Variant0(bool),
    Variant1 { a: bool },
}

fn main() {
    assert_eq!(
        vec![MyVariants::Variant0, MyVariants::Variant1],
        MyVariants::iter().collect::<Vec<_>>()
    );
}

When using #[strum_discriminants()], the derive parameter may be followed by additional attributes and these will be expanded as attributes on the generated enum e.g. #[strum_discriminants(name(SomeOtherName), derive(Serialize), serde(rename_all = "SCREAMING_SNAKE_CASE"))]`

The derived enum also has the following trait implementations:

  • impl From<MyEnum> for MyEnumDiscriminants
  • impl<'_enum> From<&'_enum MyEnum> for MyEnumDiscriminants

These allow you to get the Discriminants enum variant from the original enum:

extern crate strum;
#[macro_use] extern crate strum_macros;

#[derive(Debug, EnumDiscriminants)]
#[strum_discriminants(name(MyVariants))]
enum MyEnum {
    Variant0(bool),
    Variant1 { a: bool },
}

fn main() {
    assert_eq!(MyVariants::Variant0, MyEnum::Variant0(true).into());
}