Integral enum
A simple way to define integer-like enums. This macro implements bunch of traits that are usually implemented via looooong derive(..)
attribute.
Tour
IntegralEnum
By default [IntegralEnum
] assumes that you want all trait implementations: PartialOrd
, Ord
, PartialEq
, Eq
, Debug
, Clone
, Copy
, TryFrom
use integral_enum::IntegralEnum;
#[derive(IntegralEnum)]
pub enum Sex {
Male,
Female,
}
assert_ne!(Sex::Male, Sex::Female);
assert!(Sex::Female > Sex::Male);
assert_eq!(Sex::try_from(0), Ok(Sex::Male));
assert_eq!(format!("{:?}", Sex::Male), "Male");
assert_eq!(Sex::Female.clone(), Sex::Female);
But you may disable some implementations by applying the #[enum_disable(..)]
attribute (this will fail to compile due to disabled Debug
trait implementation):
#[derive(IntegralEnum)]
#[enum_disable(debug)]
pub enum Sex {
Male,
Female,
}
assert_eq!(format!("{:?}", Sex::Male), "Male");
This is useful if you want to compose [IntegralEnum
] with some other macro or your own trait implementations, consider example with the thiserror::Error
macro (IT IS MARKED AS COMPILE FAIL ONLY DUE TO LACK OF thiserror
DEPENDENCY):
use integral_enum::IntegralEnum;
use thiserror::Error;
#[derive(IntegralEnum, Error)]
pub enum SendError {
#[error("The remote side is closed connection")]
Closed,
#[error("Client with specified id was not found")]
NotFound,
}
StrictIntegralEnum
On the other hand you may want to enable certain implementations, here the [StrictIntegralEnum
] serves you:
use integral_enum::StrictIntegralEnum;
#[derive(StrictIntegralEnum)]
#[enum_impl(debug, partial_eq, try_from)]
pub enum Sex {
Male,
Female
}
assert_eq!(Sex::try_from(0), Ok(Sex::Male));
There's no other real use-case other than implementing the try_from
, but I left possibility to autoimplement other traits for convenience.
Dependencies
Some traits are depending on others, for example Copy
depends on Clone
, so, if you disable Clone
implementation, then Copy
implementation will be disabled too. For strict enums rules are the same, but differs in details: if you enable Clone
implementation it will not enable the Copy
. So, here the dependencies:
Clone
depends onCopy
Eq
depends onPartialEq
PartialOrd
depends onEq
,Copy
Ord
depends onPartialOrd
Limitations
IntegralEnum
tries to determine the discriminant exact type based on the following conditions:
#[repr(..)]
attribute- deducing by the number of variants
And there's no type inference, wontfix.
So, macro will generate wrong code if there is no #[repr(..)]
or discriminant type will deduced wrongly. It is quite hard to infer exact discriminant type with the only AST data, consider the following examples:
// Deduction is not watching to the enum tag's values
// (it is quite hard or even impossible to do it the correct way as stated above,
// since tags are just expressions, whose types we can't precisely infer and it just,
// overcomplicated? This crate is not a all-in solution, just simple pattern implementation,
// own type-inference will be overkill)
pub enum U16Tag {
Tag = 0xFF_FF,
}