| Crates.io | unit-enum |
| lib.rs | unit-enum |
| version | 1.4.3 |
| created_at | 2024-03-17 13:41:45.128105+00 |
| updated_at | 2025-05-20 07:39:02.260844+00 |
| description | A procedural macro for deriving ordinal methods in unit-like enums for Rust. |
| homepage | |
| repository | https://github.com/tylium/unit-enum |
| max_upload_size | |
| id | 1176504 |
| size | 48,002 |
The unit-enum crate provides a procedural macro UnitEnum designed to enhance enums in Rust, particularly those
consisting of unit variants. This macro simplifies working with such enums by providing useful utility methods.
name: Retrieve the name of an enum variant.ordinal: Retrieve the ordinal of an enum variant, starting from 0.from_ordinal: Convert an ordinal back to an enum variant, if possible.discriminant: Retrieve the discriminant of an enum variant.from_discriminant: Convert a discriminant back to an enum variant.len: Get the total number of unit variants in the enum (excluding the "other" variant if present).values: Returns an iterator over all unit variants of the enum.The macro supports two types of enums:
Add the following to your Cargo.toml:
[dependencies]
unit-enum = "1.4.1"
use unit_enum::UnitEnum;
#[derive(Debug, Clone, Copy, PartialEq, UnitEnum)]
#[repr(i16)] // Specify the discriminant type (optional, defaults to i32)
enum Color {
Red = 10,
Green, // 11
Blue = 45654
}
fn main() {
// Get the name of a variant
assert_eq!(Color::Blue.name(), "Blue");
// Get the ordinal (position) of a variant
assert_eq!(Color::Green.ordinal(), 1);
// Convert from ordinal back to variant
assert_eq!(Color::from_ordinal(2), Some(Color::Blue));
assert_eq!(Color::from_ordinal(4), None);
// Get the discriminant value (respects the repr type)
assert_eq!(Color::Blue.discriminant(), 45654);
assert_eq!(Color::Green.discriminant(), 11);
// Convert from discriminant back to variant
assert_eq!(Color::from_discriminant(10), Some(Color::Red));
assert_eq!(Color::from_discriminant(0), None);
// Get the total number of unit variants
assert_eq!(Color::len(), 3);
// Iterate over all variants
assert_eq!(
Color::values().collect::<Vec<_>>(),
vec![Color::Red, Color::Green, Color::Blue]
);
}
use unit_enum::UnitEnum;
#[derive(Debug, Clone, Copy, PartialEq, UnitEnum)]
#[repr(u16)] // repr attribute is required when using an "other" variant
enum Status {
Active = 1,
Inactive = 2,
#[unit_enum(other)]
Unknown(u16), // type must match repr
}
fn main() {
// from_discriminant always returns a value when "other" variant is present
assert_eq!(Status::from_discriminant(1), Status::Active);
assert_eq!(Status::from_discriminant(42), Status::Unknown(42));
// ordinal treats "other" as the last variant
assert_eq!(Status::Active.ordinal(), 0);
assert_eq!(Status::Unknown(42).ordinal(), 2);
// len returns only the number of unit variants
assert_eq!(Status::len(), 2);
// values iterates only over unit variants
assert_eq!(
Status::values().collect::<Vec<_>>(),
vec![Status::Active, Status::Inactive]
);
}
The crate respects the enum's #[repr] attribute to determine the type of discriminant values. Supported types include:
#[repr(i8)], #[repr(i16)], #[repr(i32)], #[repr(i64)], #[repr(i128)]#[repr(u8)], #[repr(u16)], #[repr(u32)], #[repr(u64)], #[repr(u128)]If no #[repr] attribute is specified, the discriminant type defaults to i32. Note that when using an "other" variant, the #[repr] attribute is required and must match the type of the "other" variant's field.
#[derive(UnitEnum)]
#[repr(u8)] // Use u8 for discriminants
enum SmallEnum {
A, // 0u8
B, // 1u8
C // 2u8
}
#[derive(UnitEnum)]
#[repr(i64)] // Use i64 for large discriminants
enum LargeEnum {
A = -1_000_000,
B = 5_000_000,
#[unit_enum(other)]
Other(i64) // type matches repr
}
When using an "other" variant, the following requirements must be met:
#[repr(type)] attribute#[unit_enum(other)]Contributions are welcome! Please feel free to submit pull requests or open issues on our GitHub repository.
This project is licensed under either of MIT or Apache-2.0, at your choice.