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 或 https://open-source.org.cn/licenses/MIT)
。
贡献
除非您明确表示,否则根据 Apache-2.0 许可证定义的,您有意提交以包含在工作中的任何贡献,都将按上述方式双许可,而不附加任何额外条款或条件。
依赖项
~0.7–1.1MB
~26K SLoC