Derive Macro EnumTools

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

Derive Macro for enums

§Requirements

This derive macro only works on enum

§Example

#[derive(Clone, Copy, EnumTools, PartialEq)]
#[enum_tools(as_str, Debug, next, next_back(name = "pred"))]
#[repr(usize)]
pub enum MyEnum { A, #[enum_tools(rename = "B*")] B, C }

assert_eq!(MyEnum::B.as_str(), "B*");
assert_eq!(MyEnum::A.next(), MyEnum::C.pred());

§Intro

Many features have different modes (built in or to chose) based on the type of the enum: whether it has holes or not.

Examples for “gapless” (i.e. without holes)

  • enum Name { A, B, C }
  • enum Name { A=5, B=7, C=6 }

Examples for “with holes”

  • enum Name { A=0, B=1, C=9 }
  • enum Name { A=0, B=5, C=1 }

The modes “with holes” are not as performant and/or small as the “gapless” version, but functionally identical.

Also please note that all functions which have an order do order based on values (and not the order of there occurrence, and thus identical to derived Ord and PartialOrd).

§Common parameter

All features which create a function (or constant) have the two optional parameters:

  • name: the name of the function (the default is shown in the description below)
  • vis: the visibility, either "", "pub(crate)" or "pub", defaults to the same as the enum itself

§Dependencies

Some features depend on others. When the other feature is not enabled by the user then it will be automatically enabled. The vis is "" (inherent/private), the name starts with two underscores (this may change at any time and is not considered a breaking change as no other code should depend on it).

§Auto modes

Some features have an "auto" mode (which is always default). What implementation is chosen by "auto" may change at any time, this will not change the function but probably the size or speed of the code. This is not considered a breaking change.

If you want a specific mode, specify it.

§Compile time features

§sorted

Ensure that the enum is sorted by name and/or value.

It is a compile-error when the enum is not in order.

Parameter:

  • name (optional)
  • value (optional)

Example: #[enum_tools(sorted(name, value))]

§Value attributes

The only supported value attribute is rename (see example above). This will affect all from/to str(ing) functions including the names iterator.

§Function/Constant Features

The name of the function is identical to the feature, but can be changed.

§as_str

$vis fn as_str(self) -> &'static str {..}

Parameter:

  • mode:
    • "auto": (default)
    • "match": match statement
    • "table": a table with all names, will be shared with FromStr, from_str and names if they also use a table.
  • name, vis: see common parameter

§from_str

$vis fn from_str(s: &str) -> Option<Self> {..}

Parameter:

  • mode:
    • "auto": (default)
    • "match": match statement
    • "table": a table with all names, will be shared with as_str, FromStr and names if they also use a table. And possibly a second table with all values if the enum has holes, will be shared with FromStr and iter if they also use a table.
  • name, vis: see common parameter

§into

$vis const fn into(self) -> $repr

Converts the enum into the primitive.

§MAX

$vis const MAX : Self = ..

The enum with the maximum value.

§MIN

$vis const MIN : Self = ..

The enum with the minimum value.

§next

$vis fn next(self) -> Option<Self> {..}

The next value after this, or None if Self::MAX.

§next_back

$vis fn next_back(self) -> Option<Self> {..}

The value before this, or None if Self::MIN.

§try_from

$vis fn try_from(value: $repr) -> Option<Self>

Converts the primitive type into the enum.

§Trait Features

The features are similar to the function above and/or the trait.

The error type is always () since this crate can’t create one and it’s not known if the user does provide one or one should be created. In the future there may be options to fine tune this.

§Debug

Implement Debug by calling as_str (see above).

§Display

Implement Display by calling as_str (see above).

§FromStr

Implement FromStr.

Parameter:

  • mode:
    • "auto": (default)
    • "match": match statement
    • "table": a table with all names, will be shared with as_str, from_str and names if they also use a table. And possibly a second table with all values if the enum has holes, will be shared with from_str and iter if they also use a table.

The error is ().

§Into

Implement From<Self> for $repr.

Converts the enum into the primitive.

§IntoStr

Implement From<Self> for &'static str.

Converts the enum into a str by calling as_str (see above).

§TryFrom

Implement TryFrom<$repr> for Self.

Converts the primitive type into the enum.

Error: ()

§Iterator Features

These features implement a function for the enum and a struct for the iterator.

Example:

#[derive(Clone, Copy, EnumTools, PartialEq)]
#[enum_tools(iter, Debug)]
#[repr(usize)]
pub enum MyEnum { A, B, C }

let mut it : MyEnumIter = MyEnum::iter();
assert_eq!(it.next(), Some(MyEnum::A));
assert_eq!(it.next_back(), Some(MyEnum::C));
assert_eq!(it.next(), Some(MyEnum::B));
assert_eq!(it.next_back(), None);
assert_eq!(it.next(), None);

§iter

$vis fn iter() -> SelfIter {..}

An iterator over the values of the enum (in value order).

The struct implements: Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator.

Parameter:

  • struct_name: name of the generated struct, defaults to the name of the enum and ‘Iter’.
  • mode:
    • "auto": (default) will pick range for gapless and something appropriate otherwise
    • "range": only available on gapless enums, simply iterate over a range with a conversion (as a no-op) to the enum-value
    • "next_and_back": use next and next_back (see below) for the iteration
    • "match": match statement
    • "table": a table with all enums, will be shared with FromStr and from_str if they use a table.
    • "table_inline": use an array (not a reference) of all enums to generate an iterator. Similar to [Self::A, Self::B, ...].into_iter(). Since the table is loaded every time into ram this is only a good pick for enums with few values.
  • name, vis: see common parameter

§names

$vis fn names() -> SelfNames {..}

An iterator over the names of the enum (in value order).

The struct implements: Iterator, DoubleEndedIterator, ExactSizeIterator, FusedIterator.

Parameter:

  • struct_name: name of the generated struct, defaults to the name of the enum and ‘Names’.
  • name, vis: see common parameter

This always generates a table, will be shared with as_str, FromStr and from_str if they also use a table.

§range

$vis fn range(start: Self, end: Self) -> SelfIter {..}

An Iterator over a inclusive range of the enum, in value order, similar to ..=.

This feature requires that the feature iter is activated and the mode "table_inline" is not used.

For enums with holes the function to create the range may be not very performant.