Derive Macro strum::EnumDiscriminants

source ·
#[derive(EnumDiscriminants)]
{
    // Attributes available to this derive:
    #[strum]
    #[strum_discriminants]
}
Expand description

Generate a new type with only the discriminant names.

Given an enum named MyEnum, generates another enum called MyEnumDiscriminants with the same variants but without any data fields. This is useful when you wish to determine the variant of an enum but one or more of the variants contains a non-Default field. From implementations are generated so that you can easily convert from MyEnum to MyEnumDiscriminants.

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.

Note, the variant attributes passed to the discriminant enum are filtered to avoid compilation errors due to the derives mismatches, thus only #[doc], #[cfg], #[allow], and #[deny] are passed through by default. If you want to specify a custom attribute on the discriminant variant, wrap it with #[strum_discriminants(...)] attribute.

// Bring trait into scope
use std::str::FromStr;
use strum::{IntoEnumIterator, EnumMessage};
use strum_macros::{EnumDiscriminants, EnumIter, EnumString, EnumMessage};

#[derive(Debug)]
struct NonDefault;

// simple example
#[derive(Debug, EnumDiscriminants)]
#[strum_discriminants(derive(EnumString, EnumMessage))]
enum MyEnum {
    #[strum_discriminants(strum(message = "Variant zero"))]
    Variant0(NonDefault),
    Variant1 { a: NonDefault },
}

// You can rename the generated enum using the `#[strum_discriminants(name(OtherName))]` attribute:
#[derive(Debug, EnumDiscriminants)]
#[strum_discriminants(derive(EnumIter))]
#[strum_discriminants(name(MyVariants))]
enum MyEnumR {
    Variant0(bool),
    Variant1 { a: bool },
}

// test simple example
assert_eq!(
    MyEnumDiscriminants::Variant0,
    MyEnumDiscriminants::from_str("Variant0").unwrap()
);
// test rename example combined with EnumIter
assert_eq!(
    vec![MyVariants::Variant0, MyVariants::Variant1],
    MyVariants::iter().collect::<Vec<_>>()
);

// Make use of the auto-From conversion to check whether an instance of `MyEnum` matches a
// `MyEnumDiscriminants` discriminant.
assert_eq!(
    MyEnumDiscriminants::Variant0,
    MyEnum::Variant0(NonDefault).into()
);
assert_eq!(
    MyEnumDiscriminants::Variant0,
    MyEnumDiscriminants::from(MyEnum::Variant0(NonDefault))
);

// Make use of the EnumMessage on the `MyEnumDiscriminants` discriminant.
assert_eq!(
    MyEnumDiscriminants::Variant0.get_message(),
    Some("Variant zero")
);

It is also possible to specify the visibility (e.g. pub/pub(crate)/etc.) of the generated enum. By default, the generated enum inherits the visibility of the parent enum it was generated from.

use strum_macros::EnumDiscriminants;

// You can set the visibility of the generated enum using the `#[strum_discriminants(vis(..))]` attribute:
mod inner {
    use strum_macros::EnumDiscriminants;

    # #[allow(dead_code)]
    #[derive(Debug, EnumDiscriminants)]
    #[strum_discriminants(vis(pub))]
    #[strum_discriminants(name(PubDiscriminants))]
    enum PrivateEnum {
        Variant0(bool),
        Variant1 { a: bool },
    }
}

// test visibility example, `PrivateEnum` should not be accessible here
assert_ne!(
    inner::PubDiscriminants::Variant0,
    inner::PubDiscriminants::Variant1,
);