1#[macro_use]
2extern crate zestors;
3use zestors::{export::async_trait, prelude::*};
4
5#[derive(Message, Debug)]
7#[request(u32)]
8pub struct PrintString {
9 val: String,
10}
11
12#[protocol]
14#[derive(Debug)]
15pub enum MyProtocol {
16 A(u32),
17 B(PrintString),
18 C(Action<MyHandler>),
19}
20
21#[derive(Debug)]
23pub struct MyHandler {
24 handled: u32,
25}
26
27#[async_trait]
29impl Handler for MyHandler {
30 type State = Inbox<MyProtocol>;
31 type Exception = eyre::Report;
32 type Stop = ();
33 type Exit = u32;
34
35 async fn handle_exit(
36 self,
37 _state: &mut Self::State,
38 reason: Result<Self::Stop, Self::Exception>,
39 ) -> ExitFlow<Self> {
40 match reason {
41 Ok(()) => ExitFlow::Exit(self.handled),
43 Err(exception) => {
45 println!("[ERROR] Actor exited with an exception: {exception}");
46 ExitFlow::Exit(self.handled)
47 }
48 }
49 }
50
51 async fn handle_event(&mut self, state: &mut Self::State, event: Event) -> HandlerResult<Self> {
52 match event {
55 Event::Halted => {
56 state.close();
57 Ok(Flow::Continue)
58 }
59 Event::ClosedAndEmpty => Ok(Flow::Stop(())),
60 Event::Dead => Ok(Flow::Stop(())),
61 }
62 }
63}
64
65#[async_trait]
67impl HandleMessage<u32> for MyHandler {
68 async fn handle_msg(
69 &mut self,
70 _state: &mut Self::State,
71 msg: u32,
72 ) -> Result<Flow<Self>, Self::Exception> {
73 self.handled += msg;
74 Ok(Flow::Continue)
75 }
76}
77
78#[async_trait]
80impl HandleMessage<PrintString> for MyHandler {
81 async fn handle_msg(
82 &mut self,
83 _state: &mut Self::State,
84 (msg, tx): (PrintString, Tx<u32>),
85 ) -> Result<Flow<Self>, Self::Exception> {
86 println!("{}", msg.val);
87 let _ = tx.send(self.handled);
88 self.handled += 1;
89 Ok(Flow::Continue)
90 }
91}
92
93#[tokio::main]
95async fn main() {
96 let (child, address) = MyHandler { handled: 0 }.spawn();
98 address.send(10u32).await.unwrap();
100
101 for i in 0..10 {
103 let response = address
104 .request(PrintString {
105 val: String::from("Printing a message"),
106 })
107 .await
108 .unwrap();
109 println!("Got response {i} = {response}");
110 }
111
112 child
114 .send(action!(|handler: &mut MyHandler, _state| async move {
115 println!("This is now 20: `{}`", handler.handled);
116 Ok(Flow::Continue)
117 }))
118 .await
119 .unwrap();
120
121 child.halt();
123 assert!(matches!(child.await, Ok(20)));
124}