41 个稳定版本 (3 个主要版本)
4.3.0 | 2023 年 12 月 15 日 |
---|---|
4.2.0 | 2023 年 11 月 27 日 |
3.1.15 | 2023 年 10 月 1 日 |
3.1.13 | 2023 年 5 月 10 日 |
1.0.1 | 2018 年 9 月 2 日 |
106 在 Rust 模式 中排名
752,513 每月下载量
用于 683 个包 (直接使用 17 个)
19KB
Enum Ordinalize
此库允许枚举不仅能够获取其变体的序号值,还可以从序号值构造枚举。
用法
使用 #[derive(Ordinalize)]
以使枚举(只能有单元变体)实现 Ordinalize
特性。
use enum_ordinalize::Ordinalize;
#[derive(Debug, PartialEq, Eq, Ordinalize)]
enum MyEnum {
Zero,
One,
Two,
}
assert_eq!(3, MyEnum::VARIANT_COUNT);
assert_eq!([MyEnum::Zero, MyEnum::One, MyEnum::Two], MyEnum::VARIANTS);
assert_eq!([0i8, 1i8, 2i8], MyEnum::VALUES);
assert_eq!(0i8, MyEnum::Zero.ordinal());
assert_eq!(1i8, MyEnum::One.ordinal());
assert_eq!(2i8, MyEnum::Two.ordinal());
assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0i8));
assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1i8));
assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2i8));
assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0i8) });
assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1i8) });
assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2i8) });
枚举的大小
序号值是一个整数,其大小由枚举本身决定。枚举的大小随着变体值的幅度增加而增加,无论大小(或负值时更小)。
例如,
use enum_ordinalize::Ordinalize;
#[derive(Debug, PartialEq, Eq, Ordinalize)]
enum MyEnum {
Zero,
One,
Two,
Thousand = 1000,
}
assert_eq!(4, MyEnum::VARIANT_COUNT);
assert_eq!([MyEnum::Zero, MyEnum::One, MyEnum::Two, MyEnum::Thousand], MyEnum::VARIANTS);
assert_eq!([0i16, 1i16, 2i16, 1000i16], MyEnum::VALUES);
assert_eq!(0i16, MyEnum::Zero.ordinal());
assert_eq!(1i16, MyEnum::One.ordinal());
assert_eq!(2i16, MyEnum::Two.ordinal());
assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0i16));
assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1i16));
assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2i16));
assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0i16) });
assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1i16) });
assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2i16) });
为了适应值 1000
,MyEnum
的大小会增加。因此,序号用 i16
而不是 i8
表示。
您可以使用 #[repr(type)]
属性来显式控制大小。例如,
use enum_ordinalize::Ordinalize;
#[derive(Debug, PartialEq, Eq, Ordinalize)]
#[repr(usize)]
enum MyEnum {
Zero,
One,
Two,
Thousand = 1000,
}
assert_eq!(4, MyEnum::VARIANT_COUNT);
assert_eq!([MyEnum::Zero, MyEnum::One, MyEnum::Two, MyEnum::Thousand], MyEnum::VARIANTS);
assert_eq!([0usize, 1usize, 2usize, 1000usize], MyEnum::VALUES);
assert_eq!(0usize, MyEnum::Zero.ordinal());
assert_eq!(1usize, MyEnum::One.ordinal());
assert_eq!(2usize, MyEnum::Two.ordinal());
assert_eq!(Some(MyEnum::Zero), MyEnum::from_ordinal(0usize));
assert_eq!(Some(MyEnum::One), MyEnum::from_ordinal(1usize));
assert_eq!(Some(MyEnum::Two), MyEnum::from_ordinal(2usize));
assert_eq!(MyEnum::Zero, unsafe { MyEnum::from_ordinal_unsafe(0usize) });
assert_eq!(MyEnum::One, unsafe { MyEnum::from_ordinal_unsafe(1usize) });
assert_eq!(MyEnum::Two, unsafe { MyEnum::from_ordinal_unsafe(2usize) });
有用的增量
变体表示的整数可以按顺序增加,并从任何值显式设置。
use enum_ordinalize::Ordinalize;
#[derive(Debug, PartialEq, Eq, Ordinalize)]
enum MyEnum {
Two = 2,
Three,
Four,
Eight = 8,
Nine,
NegativeTen = -10,
NegativeNine,
}
assert_eq!(7, MyEnum::VARIANT_COUNT);
assert_eq!([MyEnum::Two, MyEnum::Three, MyEnum::Four, MyEnum::Eight, MyEnum::Nine, MyEnum::NegativeTen, MyEnum::NegativeNine], MyEnum::VARIANTS);
assert_eq!([2i8, 3i8, 4i8, 8i8, 9i8, -10i8, -9i8], MyEnum::VALUES);
assert_eq!(4i8, MyEnum::Four.ordinal());
assert_eq!(9i8, MyEnum::Nine.ordinal());
assert_eq!(-9i8, MyEnum::NegativeNine.ordinal());
assert_eq!(Some(MyEnum::Four), MyEnum::from_ordinal(4i8));
assert_eq!(Some(MyEnum::Nine), MyEnum::from_ordinal(9i8));
assert_eq!(Some(MyEnum::NegativeNine), MyEnum::from_ordinal(-9i8));
assert_eq!(MyEnum::Four, unsafe { MyEnum::from_ordinal_unsafe(4i8) });
assert_eq!(MyEnum::Nine, unsafe { MyEnum::from_ordinal_unsafe(9i8) });
assert_eq!(MyEnum::NegativeNine, unsafe { MyEnum::from_ordinal_unsafe(-9i8) });
为枚举实现自身上的功能
出于某种原因,如果您不想为您的枚举实现 Ordinalize
特性,您可以选择禁用特性实现并逐个启用常量/函数。函数是 const fn
。名称和可见性也可以由您定义。
use enum_ordinalize::Ordinalize;
#[derive(Debug, PartialEq, Eq, Ordinalize)]
#[ordinalize(impl_trait = false)]
#[ordinalize(variant_count(pub const VARIANT_COUNT, doc = "The count of variants."))]
#[ordinalize(variants(pub const VARIANTS, doc = "List of this enum's variants."))]
#[ordinalize(values(pub const VALUES, doc = "List of values for all variants of this enum."))]
#[ordinalize(ordinal(pub const fn ordinal, doc = "Retrieve the integer number of this variant."))]
#[ordinalize(from_ordinal(pub const fn from_ordinal, doc = "Obtain a variant based on an integer number."))]
#[ordinalize(from_ordinal_unsafe(
pub const fn from_ordinal_unsafe,
doc = "Obtain a variant based on an integer number.",
doc = "# Safety",
doc = "You have to ensure that the input integer number can correspond to a variant on your own.",
))]
enum MyEnum {
A,
B,
}
assert_eq!(2, MyEnum::VARIANT_COUNT);
assert_eq!([MyEnum::A, MyEnum::B], MyEnum::VARIANTS);
assert_eq!([0i8, 1i8], MyEnum::VALUES);
assert_eq!(0i8, MyEnum::A.ordinal());
assert_eq!(1i8, MyEnum::B.ordinal());
assert_eq!(Some(MyEnum::A), MyEnum::from_ordinal(0i8));
assert_eq!(Some(MyEnum::B), MyEnum::from_ordinal(1i8));
assert_eq!(MyEnum::A, unsafe { MyEnum::from_ordinal_unsafe(0i8) });
assert_eq!(MyEnum::B, unsafe { MyEnum::from_ordinal_unsafe(1i8) });
Crates.io
https://crates.io/crates/enum-ordinalize
文档
https://docs.rs/enum-ordinalize
许可证
依赖项
~110KB