A simple way to define integer-like enums.
This macro implements bunch of traits that are usually implemented via looooong derive(..)
attribute.
By default [IntegralEnum
] assumes that you want all trait implementations: PartialOrd
, Ord
, PartialEq
, Eq
, Debug
, Clone
, Copy
, TryFrom
```rust use integral_enum::IntegralEnum;
pub enum Sex { Male, Female, }
assertne!(Sex::Male, Sex::Female); assert!(Sex::Female > Sex::Male); asserteq!(Sex::tryfrom(0), Ok(Sex::Male)); asserteq!(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):
```rust compile_fail
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):
```rust compilefail use integralenum::IntegralEnum; use thiserror::Error;
pub enum SendError { #[error("The remote side is closed connection")] Closed,
#[error("Client with specified id was not found")]
NotFound,
} ```
On the other hand you may want to enable certain implementations, here the [StrictIntegralEnum
] serves you:
```rust use integral_enum::StrictIntegralEnum;
pub enum Sex { Male, Female }
asserteq!(Sex::tryfrom(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.
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 on Copy
Eq
depends on PartialEq
PartialOrd
depends on Eq
, Copy
Ord
depends on PartialOrd
IntegralEnum
tries to determine the discriminant exact type based on the following conditions:
- #[repr(..)]
attribute
- deducing by the number of variants
So, macro will generate wrong code if there is no #[repr(..)]
or discriminant type will deduced wrongly. It is quite impossible to infer exact discriminant type with the only AST data, consider the following examples:
```rust // Complete type inference is impossible const A: u8 = 0;
pub enum TryToDetermineMyTag { Tag = A, } ```
rust
// 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,
}
And the macro will only get the enum definition, so exact type inference is impossible.