Rust枚举变体检测库derive_is_enum_variant的使用:通过过程宏自动生成enum变体验证方法
Rust枚举变体检测库derive_is_enum_variant的使用:通过过程宏自动生成enum变体验证方法
derive_is_enum_variant
不再需要手动为你的enum
编写pub is_whatever(&self) -> bool
方法了!只需使用#[derive(is_enum_variant)]
宏即可自动生成这些方法。
使用方法
首先在Cargo.toml
中添加依赖:
[dependencies]
derive_is_enum_variant = "0.1.1" # 请使用最新版本
然后在枚举定义上使用派生宏:
#[macro_use]
extern crate derive_is_enum_variant;
#[derive(is_enum_variant)]
pub enum Animal {
Dog,
Cat,
}
fn main() {
let animal = Animal::Dog;
// 自动生成的方法
assert!(animal.is_dog());
assert!(!animal.is_cat());
}
自定义方法名称
可以为枚举变体指定自定义的检测方法名称:
#[derive(is_enum_variant)]
pub enum Animal {
#[is_enum_variant(name = "is_doggy")]
Dog,
Cat,
}
let animal = Animal::Dog;
assert!(animal.is_doggy()); // 使用自定义的方法名
跳过特定变体
对于不需要生成检测方法的变体,可以使用skip
属性:
#[derive(is_enum_variant)]
pub enum Error {
Io(std::io::Error),
#[is_enum_variant(skip)]
InternalError,
}
完整示例代码
// 1. 在Cargo.toml中添加依赖
// [dependencies]
// derive_is_enum_variant = "0.1.1"
// 2. 实际使用示例
#[macro_use]
extern crate derive_is_enum_variant;
#[derive(Debug, is_enum_variant)]
enum NetworkStatus {
// 默认生成is_connected方法
Connected,
// 自定义方法名
#[is_enum_variant(name = "is_disconnected_status")]
Disconnected,
// 带数据的变体
Error(String),
// 跳过生成方法
#[is_enum_variant(skip)]
Unknown,
}
fn main() {
let connected = NetworkStatus::Connected;
let disconnected = NetworkStatus::Disconnected;
let error = NetworkStatus::Error("Timeout".to_string());
let unknown = NetworkStatus::Unknown;
// 测试生成的方法
assert!(connected.is_connected());
assert!(!connected.is_disconnected_status());
assert!(!connected.is_error());
assert!(disconnected.is_disconnected_status());
assert!(error.is_error());
assert_eq!(error.is_connected(), false);
// 跳过的变体不会有对应方法
// unknown.is_unknown(); // 这会编译错误
}
许可证
此库采用以下许可证之一:
- Apache License, Version 2.0
- MIT license
可根据需要选择使用。
1 回复
Rust枚举变体检测库derive_is_enum_variant使用指南
derive_is_enum_variant
是一个方便的Rust过程宏库,它能够自动为枚举类型生成检测变体的方法,避免了手动编写大量match
语句或if let
表达式的麻烦。
安装
在Cargo.toml
中添加依赖:
[dependencies]
derive_is_enum_variant = "0.1"
基本用法
使用#[derive(IsEnumVariant)]
宏来自动生成is_
前缀的变体检测方法:
use derive_is_enum_variant::IsEnumVariant;
#[derive(IsEnumVariant)]
enum MyEnum {
VariantA,
VariantB(i32),
VariantC { x: f64, y: f64 },
}
这将自动生成以下方法:
is_variant_a()
is_variant_b()
is_variant_c()
示例代码
use derive_is_enum_variant::IsEnumVariant;
#[derive(Debug, IsEnumVariant)]
enum NetworkEvent {
Connect,
Message(String),
Disconnect { reason: String },
}
fn handle_event(event: NetworkEvent) {
if event.is_connect() {
println!("Connection established");
} else if event.is_message() {
println!("Received message");
} else if event.is_disconnect() {
println!("Disconnected: {:?}", event);
}
}
fn main() {
let events = vec![
NetworkEvent::Connect,
NetworkEvent::Message("Hello".to_string()),
NetworkEvent::Disconnect { reason: "Timeout".to_string() },
];
for event in events {
handle_event(event);
}
}
高级特性
自定义方法名前缀
默认生成的方法以is_
为前缀,但你可以自定义:
#[derive(IsEnumVariant)]
#[is_enum_variant(prefix = "check_")]
enum CustomEnum {
First,
Second,
}
// 生成 check_first() 和 check_second() 方法
忽略特定变体
可以忽略某些变体不生成检测方法:
#[derive(IsEnumVariant)]
#[is_enum_variant(skip(VariantB, VariantC))]
enum SkipEnum {
VariantA,
VariantB,
VariantC,
}
// 只生成 is_variant_a() 方法
完整示例代码
// 导入必要的库
use derive_is_enum_variant::IsEnumVariant;
use std::fmt;
// 定义一个带有派生宏的枚举
#[derive(Debug, IsEnumVariant)]
enum UserAction {
Login { username: String, password: String },
Logout,
SendMessage { recipient: String, content: String },
ChangePassword(String),
}
// 实现Display trait以便更好地打印
impl fmt::Display for UserAction {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
UserAction::Login { username, password: _ } =>
write!(f, "Login attempt by {}", username),
UserAction::Logout =>
write!(f, "User logged out"),
UserAction::SendMessage { recipient, content } =>
write!(f, "Message to {}: {}", recipient, content),
UserAction::ChangePassword(_) =>
write!(f, "Password change requested"),
}
}
}
fn process_action(action: UserAction) {
// 使用自动生成的检测方法
if action.is_login() {
println!("处理登录: {}", action);
} else if action.is_logout() {
println!("处理登出: {}", action);
} else if action.is_send_message() {
println!("处理消息发送: {}", action);
} else if action.is_change_password() {
println!("处理密码修改: {}", action);
}
}
fn main() {
// 创建各种用户操作
let actions = vec![
UserAction::Login {
username: "alice".to_string(),
password: "secret".to_string()
},
UserAction::Logout,
UserAction::SendMessage {
recipient: "bob".to_string(),
content: "Hello!".to_string()
},
UserAction::ChangePassword("newpassword".to_string()),
];
// 处理每个操作
for action in actions {
process_action(action);
}
}
适用场景
- 当需要频繁检查枚举当前是哪个变体时
- 当枚举有很多变体,手动实现检测方法很繁琐时
- 需要更简洁的代码表达变体检查逻辑时
注意事项
- 生成的检测方法返回
bool
类型 - 方法名由变体名转换而来,遵循Rust的命名约定(小写下划线风格)
- 对于元组变体或结构体变体,检测方法只检查变体类型,不检查内部值
这个库可以显著简化枚举变体的检测代码,使代码更加清晰易读。