Attribute Macro lunatic::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]
and#[handle_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 arbitrary number of parameters and invocating 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::{
abstract_process,
process::{Message, ProcessRef, Request, StartProcess},
Tag,
};
struct Counter(u32);
#[abstract_process]
impl Counter {
#[init]
fn init(_: ProcessRef<Self>, start: u32) -> Self {
Self(start)
}
#[terminate]
fn terminate(self) {
println!("Shutdown process");
}
#[handle_link_trapped]
fn handle_link_trapped(&self, tag: Tag) {
println!("Link trapped");
}
#[handle_message]
fn increment(&mut self) {
self.0 += 1;
}
#[handle_request]
fn count(&self) -> u32 {
self.0
}
}
let counter = Counter::start(5, None);
counter.increment();
assert_eq!(counter.count(), 6);
A more complicated example
ⓘ
use lunatic::{
abstract_process,
process::{Message, ProcessRef, Request, StartProcess},
}
struct A;
#[derive(serde::Serialize, serde::Deserialize)]
struct Person {
name: String,
age: u16,
}
#[abstract_process(trait_name = "AHandler", visibility = pub)]
impl A {
#[init]
fn init(_: ProcessRef<Self>, _: ()) -> A {
A
}
#[hanlde_message]
fn multiple_arguments(&self, a: u8, (b, c): (bool, char)) {
assert_eq!(a, 5);
assert_eq!(b, false);
assert_eq!(c, 'a');
}
#[handle_request]
fn unpack_struct(&self, Person { name, age }: Person) -> String {
assert_eq!(name, "Mark");
assert_eq!(age, 5);
self.create_greeting(name)
}
fn create_greeting(&self, name: String) {
format!("Hi {}!", name)
}
}
let a = A::start_link((), None);
a.multiple_arguments(5, (false, 'a'));
let person = Person {
name: "Mark".to_owned(),
age: 4,
};
let greeting = a.unpack_struct(person);
assert_eq!(greeting, "Hi Mark!");