Attribute Macro medea_macro::dispatchable [−][src]
#[dispatchable]
Generates *Handler
trait and displatching 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);