#group #enums #macro-derive #derive #macro

enum-group

一个简单的 derive 宏包,帮助枚举类型对它们的变体进行分组。

3 个版本

0.1.2 2022年7月25日
0.1.1 2022年7月22日
0.1.0 2022年7月21日

1036开发工具

Download history 1228/week @ 2024-04-09 1982/week @ 2024-04-16 1381/week @ 2024-04-23 1407/week @ 2024-04-30 1207/week @ 2024-05-07 1756/week @ 2024-05-14 2085/week @ 2024-05-21 1616/week @ 2024-05-28 1851/week @ 2024-06-04 1604/week @ 2024-06-11 1846/week @ 2024-06-18 2118/week @ 2024-06-25 1671/week @ 2024-07-02 2468/week @ 2024-07-09 1703/week @ 2024-07-16 2011/week @ 2024-07-23

每月 8,256 次下载

MIT/Apache

17KB
273

Enum Group

enum-group 是一个简单的 derive 宏包,帮助枚举类型对它们的变体进行分组。使用 #[derive(EnumGroup)] 注释枚举,并使用 #[groups(label1, label2)] 标记一些变体的分组标签名称,将自动生成函数 is_label1is_label2。这些函数将告诉您枚举的某个变体是否属于此分组。

示例

分组您的变体

use enum_group::EnumGroup;

#[derive(EnumGroup)]
enum Number {
    #[groups(odd)]
    One,

    #[groups(even, prime)]
    Two,

    #[groups(odd, prime)]
    Three,

    Unknown(usize)
}

// Will auto generate function `fn is_odd(&self) -> bool`
assert!(Number::One.is_odd());
assert!(!Number::Two.is_odd());
assert!(Number::Three.is_odd());
assert!(!Number::Unknown(0).is_odd());

// Will auto generate function `fn is_even(&self) -> bool`
assert!(!Number::One.is_even());
assert!(Number::Two.is_even());
assert!(!Number::Three.is_even());
assert!(!Number::Unknown(0).is_even());

// Will auto generate function `fn is_prime(&self) -> bool`
assert!(!Number::One.is_prime());
assert!(Number::Two.is_prime());
assert!(Number::Three.is_prime());
assert!(!Number::Unknown(0).is_prime());

标签名称带有前缀

有时,您可能有大量带有相同前缀的分组标签名称,您可以使用嵌套分组来减少代码重复。它支持多层嵌套。

use enum_group::EnumGroup;

#[derive(EnumGroup)]
enum Typing {
    
    #[groups(accept(eq, ne, gt, gte, lt, lte), number)]
    I8,

    #[groups(accept(not, eq, ne))]
    Bool,
}

assert!(!Typing::I8.is_accept_not());
assert!(Typing::I8.is_accept_eq());
assert!(Typing::I8.is_accept_ne());
assert!(Typing::I8.is_accept_gt());
assert!(Typing::I8.is_accept_gte());
assert!(Typing::I8.is_accept_lt());
assert!(Typing::I8.is_accept_lte());
assert!(Typing::I8.is_number());

assert!(Typing::Bool.is_accept_not());
assert!(Typing::Bool.is_accept_eq());
assert!(Typing::Bool.is_accept_ne());
assert!(!Typing::Bool.is_accept_gt());
assert!(!Typing::Bool.is_accept_gte());
assert!(!Typing::Bool.is_accept_lt());
assert!(!Typing::Bool.is_accept_lte());
assert!(!Typing::Bool.is_number());

变体判断函数

如果您只想确定当前变体是哪个,并且不想编写太多繁琐的 match 表达式,您可以使用以下函数来快速获得帮助。每个变体提供了一个小写判断函数。

use enum_group::EnumGroup;

#[derive(EnumGroup)]
enum Pet {
    
    Cat,

    Dog,
}

assert!(Pet::Cat.is_cat());
assert!(!Pet::Dog.is_cat());
assert!(!Pet::Cat.is_dog());
assert!(Pet::Dog.is_dog());

其他帮助函数

有时您可能想打印每个变体的名称字符串,您可以使用 variant_name() 来获取 &str

use enum_group::EnumGroup;

#[derive(EnumGroup)]
enum FooBar {
    
    Foo = 1,

    BAR = 2,
}

assert_eq!(FooBar::Foo.variant_name(), "Foo");
assert_eq!(FooBar::BAR.variant_name(), "BAR");

使用限制

每个变体的分组标签名称的每个字符必须是小写字母数字或 _

恐慌

use enum_group::EnumGroup;

#[derive(EnumGroup)]
enum Number {
    // #[groups(one)] // conflict group label name and viriant name. group name cannot equal to variant name
    // #[groups(Odd_&)] // groups attribute ident can only contain the characters a-z0-9_
    // #[groups(_odd)] // groups attribute ident must starts wtih characters a-z
    // #[groups(odd_)] // groups attribute ident must ends wtih characters a-z
    // #[groups()] // must have group ident in groups attribute
    One,
}

依赖项

~1.5MB
~35K SLoC