1个不稳定版本
新 0.1.0 | 2024年8月21日 |
---|
#443在Rust模式
每月102次下载
45KB
1K SLoC
Rust枚举处理器派生宏
本项目提供了一种方便且高效的宏,用于处理Rust枚举。
#[derive(EnumHandler)]
宏简化了匹配和处理不同枚举变体的过程,使得代码更简洁易读。
它生成了一个具有对枚举每个变体进行match语句的公共处理方法特征的特质,允许你轻松地单独处理每个案例。
// You declare the CounterEvent enum:
use enum_handler::EnumHandler;
#[derive(EnumHandler)]
pub enum CounterEvent {
Increment,
Decrement,
Reset,
Set(i32),
}
// and the enum_handler macro will generate the following code for you behind the scenes:
pub trait CounterEventHandler {
fn on(&self, e: CounterEvent) -> () {
match (e) {
CounterEvent::Increment => self.on_increment(),
CounterEvent::Decrement => self.on_decrement(),
CounterEvent::Reset => self.on_reset(),
CounterEvent::Set(arg) => self.on_set(arg),
}
}
fn on_increment(&self) -> ();
fn on_decrement(&self) -> ();
fn on_reset(&self) -> ();
fn on_set(&self, set: i32) -> ();
}
生成的代码可以高度自定义以满足你的特定需求。
例如,你可以指定
- 生成的特质和方法名称
- 异步或同步方法
- 按值(默认,改变所有权)或按引用传递参数
- 为方法生成默认实现
- 指定返回值
- 为每个方法指定公共返回类型
- 指定生成的特质和方法的可见性
- 将生成的代码输出到文件以进行调试
- 模拟所有支持
项目结构
项目结构如下
包 | 描述 |
---|---|
enum_handler |
暴露#[enum_handler()] 属性宏的库包。这是你将在项目中包含的包! |
enum_handler_derive |
实现#[derive(EnumHandler)] 宏的过程宏包。 |
enum_handler_core |
包含宏几乎所有逻辑的核心包。这个包在库和派生包之间共享。你可以在测试目录和enum_handler_core包中的tests.rs文件中看到示例。 |
配置
使用 #[enum_handler()]
属性宏,您可以通过指定以下选项来自定义生成的代码:
选项 | 类型 | 默认值 | 描述 |
---|---|---|---|
trait_suffix |
String |
"Handler" |
指定要附加到枚举名称上的生成特质的后缀。 |
trait_name |
String |
"" |
如果指定,生成的特质将使用此名称而不是默认名称。 |
handler_name |
String |
on |
指定通用处理方法的名称。这也会用作生成方法名称的前缀(分隔符为 _ )。 |
return_type |
String |
() |
指定每个方法的通用返回类型。 |
default_return_value |
String |
() |
指定如果生成默认实现,每个方法的通用返回值。 |
is_async |
bool |
false |
指定生成的函数应该是异步(true )还是同步(false )。 |
default_implementation |
bool |
true |
指定是否应该为方法生成默认实现(true )或不是(false )。 |
visibility |
String |
"" |
指定生成的特质的可见性和方法的可见性。如果没有指定,则使用枚举的可见性。 |
no_async_trait_macro |
bool |
false |
指定是否使用 #[async_trait::async_trait] 宏(false )或不使用(true )。这仅当 is_async 为 true 时相关。必须将 async_trait 包包含在 [dependencies] 中。 |
mock_name |
String |
"" |
如果指定,将使用此名称生成一个 mockall 特质。必须将 mockall 包包含在 [dev-dependencies] 中。 |
pass_args_by_ref |
bool |
false |
指定是否应该通过引用(true )或通过值(false )传递参数。 |
示例
以下是一些使用 #[derive(EnumHandler)]
宏的示例:
异步方法
use enum_handler::EnumHandler;
#[derive(EnumHandler)]
#[enum_handler(is_async = true)]
pub enum CounterEvent {
Increment,
Decrement,
Reset,
Set(i32),
}
自定义特质名称
use enum_handler::EnumHandler;
#[derive(EnumHandler)]
#[enum_handler(trait_name = "CounterHandler")]
pub enum CounterEvent {
Increment,
Decrement,
Reset,
Set(i32),
}
自定义处理方法名称
use enum_handler::EnumHandler;
#[derive(EnumHandler)]
#[enum_handler(handler_name = "handle")]
pub enum CounterEvent {
Increment,
Decrement,
Reset,
Set(i32),
}
自定义返回类型
use enum_handler::EnumHandler;
#[derive(EnumHandler)]
#[enum_handler(return_type = "i32")]
pub enum CounterEvent {
Increment,
Decrement,
Reset,
Set(i32),
}
Mockall 支持
use enum_handler::EnumHandler;
#[derive(EnumHandler)]
#[enum_handler(mock_name = "MockCounterHandler")]
pub enum CounterEvent {
Increment,
Decrement,
Reset,
Set(i32),
}
将生成的代码写入文件
您可以将环境变量 ENUM_HANDLER_DEBUG
设置为将生成的代码写入文件。
ENUM_HANDLER_DEBUG=/tmp/enum_handler.rs cargo build
- 如果文件大于 128kB,它将被截断。
- 这仅适用于调试目的,不应在生产代码中使用。
如果您想使用 rustfmt
格式化生成的代码,可以将环境变量 ENUM_HANDLER_DEBUG_FORMAT
设置为 1
。
ENUM_HANDLER_DEBUG=/tmp/enum_handler.rs ENUM_HANDLER_DEBUG_FORMAT=1 cargo build
- 如果可用,文件将使用
rustfmt
进行格式化。
您还可以使用 cargo-expand 来查看生成的代码
cargo install cargo-expand
cargo expand --help
已知问题
- 此包正在积极开发中,未来可能会有破坏性更改。
- 在未来的版本中,将对
#[async_trait::async_trait]
宏的使用进行改进。 - 在未来的版本中,
rustfmt
格式化将可定制。 - 在未来的版本中,元组变体参数的名称将被更改。
- 当前支持的最小Rust版本(MSRV)设置为1.80.1。这将在未来的版本中进行审查。
贡献
欢迎贡献!如果您有任何想法、建议或错误报告,请在 GitHub 仓库 上创建一个问题或提交一个拉取请求。
许可证
根据您的选择,许可方式为以下之一:
- Apache License,版本 2.0,(LICENSE-APACHE 或 https://apache.ac.cn/licenses/LICENSE-2.0)
- MIT 许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
。
贡献
除非您明确表示,否则根据 Apache-2.0 许可证定义的,您有意提交以包含在工作中的任何贡献,都将按上述方式双许可,而不附加任何额外条款或条件。
依赖项
~0.7–1.1MB
~26K SLoC