Derive Macro strum_macros::FromRepr
source · #[derive(FromRepr)]
{
// Attributes available to this derive:
#[strum]
}
Expand description
Add a function to enum that allows accessing variants by its discriminant
This macro adds a standalone function to obtain an enum variant by its discriminant. The macro adds
from_repr(discriminant: usize) -> Option<YourEnum>
as a standalone function on the enum. For
variants with additional data, the returned variant will use the Default
trait to fill the
data. The discriminant follows the same rules as rustc
. The first discriminant is zero and each
successive variant has a discriminant of one greater than the previous variant, expect where an
explicit discriminant is specified. The type of the discriminant will match the repr
type if
it is specifed.
When the macro is applied using rustc >= 1.46 and when there is no additional data on any of
the variants, the from_repr
function is marked const
. rustc >= 1.46 is required
to allow match
statements in const fn
. The no additional data requirement is due to the
inability to use Default::default()
in a const fn
.
You cannot derive FromRepr
on any type with a lifetime bound (<'a>
) because the function would surely
create unbounded lifetimes.
use strum_macros::FromRepr;
#[derive(FromRepr, Debug, PartialEq)]
enum Color {
Red,
Green { range: usize },
Blue(usize),
Yellow,
}
assert_eq!(Some(Color::Red), Color::from_repr(0));
assert_eq!(Some(Color::Green {range: 0}), Color::from_repr(1));
assert_eq!(Some(Color::Blue(0)), Color::from_repr(2));
assert_eq!(Some(Color::Yellow), Color::from_repr(3));
assert_eq!(None, Color::from_repr(4));
// Custom discriminant tests
#[derive(FromRepr, Debug, PartialEq)]
#[repr(u8)]
enum Vehicle {
Car = 1,
Truck = 3,
}
assert_eq!(None, Vehicle::from_repr(0));
On versions of rust >= 1.46, the from_repr
function is marked const
.
use strum_macros::FromRepr;
#[derive(FromRepr, Debug, PartialEq)]
#[repr(u8)]
enum Number {
One = 1,
Three = 3,
}
const fn number_from_repr(d: u8) -> Option<Number> {
Number::from_repr(d)
}
assert_eq!(None, number_from_repr(0));
assert_eq!(Some(Number::One), number_from_repr(1));
assert_eq!(None, number_from_repr(2));
assert_eq!(Some(Number::Three), number_from_repr(3));
assert_eq!(None, number_from_repr(4));