Attribute Macro medea_macro::dispatchable
source · #[dispatchable]
Expand description
Generates a *Handler
trait and dispatching function for some event,
represented as enum
.
How to use
1. Declare enum
for event variants and a struct
to handle them.
use medea_macro::dispatchable;
#[dispatchable]
enum Event {
Some { new_bar: i32 },
Another,
UnnamedVariant(i32, i32),
}
struct Foo {
bar: i32,
baz: i32,
}
2. Implement handler for your struct
.
For the given enum
macro generates a unique trait by adding Handler
to the end of its name. Each method of trait is created by snake_case
’ing
enum
variants and adding on_
prefix.
type Output
is a type which will be returned from all functions of
EventHandler
trait.
impl EventHandler for Foo {
type Output = i32;
fn on_some(&mut self, new_bar: i32) -> Self::Output {
self.bar = new_bar;
self.bar
}
fn on_another(&mut self) -> Self::Output {
self.bar = 2;
self.bar
}
fn on_unnamed_variant(&mut self, data: (i32, i32)) -> Self::Output {
self.bar = data.0;
self.baz = data.1;
self.bar
}
}
3. Dispatch event with handler
For the given enum
macro generates dispatch_with()
method to dispatch
enum
with a given handler.
let mut foo = Foo { bar: 0, baz: 0 };
let bar = Event::Some { new_bar: 1 }.dispatch_with(&mut foo);
assert_eq!(foo.bar, 1);
assert_eq!(bar, 1);
let bar = Event::Another.dispatch_with(&mut foo);
assert_eq!(foo.bar, 2);
assert_eq!(bar, 2);
let bar = Event::UnnamedVariant(3, 3).dispatch_with(&mut foo);
assert_eq!(foo.bar, 3);
assert_eq!(foo.baz, 3);
assert_eq!(bar, 3);
Customize self
type in handler functions (optional)
By default, all handler functions take &mut Self
, if this doesn’t suit
your case, then you can specify the method receiver manually:
#[dispatchable(self: Rc<Self>)]
, #[dispatchable(self: &Self)]
.
You can use any type that is a valid self
receiver, e.g. self
, &self
,
&mut self
, self: Box<Self>
, self: Rc<Self>
, self: Arc<Self>
, or
self: Pin<P>
(where P is one of the previous, except Self
).
use medea_macro::dispatchable;
#[dispatchable(self: Rc<Self>)]
enum Event {
Variant,
}
struct Foo;
impl EventHandler for Foo {
type Output = ();
fn on_variant(self: Rc<Self>) {}
}
let foo = Rc::new(Foo);
Event::Variant.dispatch_with(foo);
Async handlers (optional)
It’s possible to make handler methods async
. Rust doesn’t support async
trait methods at the moment, that’s why async_trait
is used.
use async_trait::async_trait;
use medea_macro::dispatchable;
#[dispatchable(async_trait(?Send))]
enum Event {
Variant,
}
struct Foo;
#[async_trait(?Send)]
impl EventHandler for Foo {
type Output = ();
async fn on_variant(&mut self) {}
}
let mut foo = Foo;
Event::Variant.dispatch_with(&mut foo);