Crates.io | event_bridge |
lib.rs | event_bridge |
version | 0.3.1 |
source | src |
created_at | 2024-12-06 18:22:02.891846 |
updated_at | 2024-12-06 23:24:45.706211 |
description | A procedural macro library for generating event handlers |
homepage | |
repository | https://github.com/mat-kie/event_bridge |
max_upload_size | |
id | 1474511 |
size | 19,304 |
A procedural macro that generates asynchronous event handlers from enum definitions, automatically dispatching enum variants to associated trait methods. This reduces boilerplate and simplifies the integration between synchronous UI events and asynchronous backend logic.
In many applications, especially those with graphical user interfaces (GUIs),
input from the UI thread must be forwarded to asynchronous backend services or
controllers. Writing repetitive match
expressions to route each event to its
corresponding async API method can be tedious and error-prone.
event_bridge
streamlines this process. By annotating your event enum
with a
custom procedural macro, you automatically get an async event handler method
that matches each variant and calls the appropriately named method on your
specified API trait.
When you apply the #[derive(EventBridge)]
macro to your event enum,
it generates a forward_to
method that:
This significantly reduces the boilerplate involved in writing match
arms and
manually forwarding arguments for each new event added to your application.
Add event_bridge
and async-trait
to your Cargo.toml
:
[dependencies]
event_bridge = "0.1.0"
async-trait = "0.1"
use async_trait::async_trait;
use event_bridge::EventBridge;
use std::sync::Arc;
use tokio::sync::Mutex;
// Define a custom error type for demonstration
type MyReturnType = Result<(), String>;
// Define an event enum and associate it with a trait and error type
#[derive(EventBridge)]
#[forward_to_trait(MyApiTrait)]
#[trait_returned_type(MyReturnType)]
pub enum Event {
SetValue(i32),
SetName(String),
Initialize,
}
// Define the API trait that corresponds to the event variants
#[async_trait]
pub trait MyApiTrait {
async fn set_value(&mut self, value: i32) -> MyReturnType;
async fn set_name(&mut self, name: String) -> MyReturnType;
async fn initialize(&mut self) -> MyReturnType;
}
// Example usage
#[tokio::main]
async fn main() {
// Assume `MyApiImpl` implements `MyApiTrait`
let mut api_impl = MyApiImpl::new();
// Example event to dispatch to the API implementation
let some_event = Event::SetValue(42);
// Dispatching an event becomes straightforward:
let result = some_event.forward_to(&mut api_impl).await;
}
The macro supports two attributes on the enum:
#[forward_to_trait(TraitName)]
(required)
Specifies the trait that defines the async methods corresponding to each enum variant.
#[trait_returned_type(ReturnType)]
(optional)
Specifies the return type returned by the generated event handler. If omitted,
the handler defaults to ()
.
The macro handles various enum variants:
#[derive(EventBridge)]
#[forward_to_trait(Handler)]
enum Event {
NoArgs, // Unit variant
SingleArg(String), // Single argument
MultipleArgs(i32, String), // Multiple arguments
NamedFields { id: i32 }, // Named fields
}
Each variant must correspond to a method in the specified trait. The method name
is derived from the variant name converted to snake_case
, and the method
arguments match the variant’s fields in order and type.
Ensure that your trait methods return the appropriate type to maintain consistency.
This project is licensed under the MIT license.
Contributions, issues, and pull requests are welcome. Feel free to open a discussion on GitHub if you have any questions or suggestions.