Crates.io | enum_handler |
lib.rs | enum_handler |
version | 0.1.0 |
source | src |
created_at | 2024-08-21 06:30:53.457548 |
updated_at | 2024-08-21 06:30:53.457548 |
description | A macro to generate a handler trait for enums variants. |
homepage | |
repository | https://github.com/oxiui/enum_handler |
max_upload_size | |
id | 1346182 |
size | 22,090 |
This project provides a macro for handling Rust enums in a convenient and efficient way.
The #[derive(EnumHandler)]
macro simplifies the process of matching and handling different enum variants,
allowing for cleaner and more readable code.
It generates a trait with a common handler method with match statements for each variant of the enum, allowing you to easily handle each case separately.
// 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) -> ();
}
The generated code can be highly customized to suit your specific needs.
Eg. you can specify:
The project is structured as follows:
Crate | Description |
---|---|
enum_handler |
The library crate that exposes the #[enum_handler()] attribute macro. This is the crate that you will include in your project! |
enum_handler_derive |
The procedural macro crate that implements the #[derive(EnumHandler)] macro. |
enum_handler_core |
The core crate that contains almost all the logic for the macro. This crate is shared between the library and the derive crate. You can see examples is the tests directory and the tests.rs file in the enum_handler_core crate. |
With the #[enum_handler()]
attribute macro, you can customize the generated code by specifying the following options:
Option | Type | Default | Description |
---|---|---|---|
trait_suffix |
String |
"Handler" |
Specifies the suffix for the generated trait name which will be appended to the enum name. |
trait_name |
String |
"" |
If specified, the generated trait will have this name instead of the default one. |
handler_name |
String |
on |
Specifies the name of the common handler method. This is also used as a prefix for the generated method names (separator is _ ). |
return_type |
String |
() |
Specifies the common return type for each method. |
default_return_value |
String |
() |
Specifies the common return value for each method if the default implementations are generated. |
is_async |
bool |
false |
Specifies whether the generated methods should be asynchronous (true ) or synchronous (false ). |
default_implementation |
bool |
true |
Specifies whether default implementations should be generated for the methods (true ) or not (false ). |
visibility |
String |
"" |
Specifies the visibility for the generated trait and methods. If not specified, the visibility of the enum is used. |
no_async_trait_macro |
bool |
false |
Specifies whether to use the #[async_trait::async_trait] macro (false ) or not (true ). This is only relevant if is_async is true . The async_trait crate must be included in the [dependencies]. |
mock_name |
String |
"" |
If specified, a mockall trait will be generated with this name. The mockall crate must be included in the [dev-dependencies]. |
pass_args_by_ref |
bool |
false |
Specifies whether the arguments should be passed by reference (true ) or by value (false ). |
Here are a few examples to demonstrate the usage of the #[derive(EnumHandler)]
macro:
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),
}
use enum_handler::EnumHandler;
#[derive(EnumHandler)]
#[enum_handler(mock_name = "MockCounterHandler")]
pub enum CounterEvent {
Increment,
Decrement,
Reset,
Set(i32),
}
You can set the environment variable ENUM_HANDLER_DEBUG
to write the generated code to a file.
ENUM_HANDLER_DEBUG=/tmp/enum_handler.rs cargo build
If you want to format the generated code with rustfmt
, you can set the environment variable ENUM_HANDLER_DEBUG_FORMAT
to 1
.
ENUM_HANDLER_DEBUG=/tmp/enum_handler.rs ENUM_HANDLER_DEBUG_FORMAT=1 cargo build
rustfmt
if it is available.You can also use cargo-expand to see the generated code:
cargo install cargo-expand
cargo expand --help
#[async_trait::async_trait]
macro usage will be improved in a future release.rustfmt
formatting will be customizable in a future release.Contributions are welcome! If you have any ideas, suggestions, or bug reports, please open an issue or submit a pull request on the GitHub repository.
Licensed under either of
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.