Attribute Macro lunatic_macros::abstract_process
source · #[abstract_process]
Expand description
Add AbstractProcess
behavior to the given struct implementation with
minimum boilerplate code.
- Use
#[init]
,#[terminate]
, and#[handle_link_trapped]
attributes to specify methods for implementingAbstractProcess
. - Use
#[handle_message]
,#[handle_request]
and#[handle_deferred_request]
attributes to specify message and request handlers.
Specifying message types is unnecessary because the macro will create wrapper types for messages on all handlers. Handlers can take an arbitrary number of parameters and invoking them works the same as directly calling the method on the struct without spawning it as a process.
A trait is generated and defaults to private and follows the name of your
type with Handler
added as a suffix. To rename or change the visibility of
the generated trait, you can use the trait_name
and visbility
arguments
with #[abstract_process(trait_name = "MyHandler", visibility = pub)]
.
Examples
ⓘ
use lunatic::ap::{AbstractProcess, Config, DeferredResponse};
use lunatic::{abstract_process, Mailbox, Tag};
struct Counter(u32);
#[abstract_process]
impl Counter {
#[init]
fn init(_: Config<Self>, start: u32) -> Result<Self, ()> {
Ok(Self(start))
}
#[terminate]
fn terminate(self) {
println!("Shutdown process");
}
#[handle_link_death]
fn handle_link_death(&self, _tag: Tag) {
println!("Link trapped");
}
#[handle_message]
fn increment(&mut self) {
self.0 += 1;
}
#[handle_request]
fn count(&self) -> u32 {
self.0
}
#[handle_deferred_request]
fn add_to_count(&self, a: u32, b: u32, dr: DeferredResponse<u32, Self>) {
dr.send_response(self.0 + a + b)
}
}
let counter = Counter::link().start(0).unwrap();
counter.increment();
assert_eq!(counter.count(), 1);
counter.increment();
assert_eq!(
counter
.with_timeout(Duration::from_millis(10))
.add_to_count(1, 1)
.unwrap(),
4
);