handler_pattern/
handler_pattern.rs1use actor12::{Actor, Call, Handler, Init, MpscChannel, Multi, spawn};
2use futures::future;
3use std::future::Future;
4
5pub struct MultiHandlerActor {
7 counter: i32,
8 name: String,
9}
10
11#[derive(Debug)]
13pub struct IncrementMsg;
14
15#[derive(Debug)]
16pub struct GetCountMsg;
17
18#[derive(Debug)]
19pub struct SetNameMsg(pub String);
20
21#[derive(Debug)]
22pub struct GetNameMsg;
23
24impl Actor for MultiHandlerActor {
25 type Spec = String; type Message = Multi<Self>;
27 type Channel = MpscChannel<Self::Message>;
28 type Cancel = ();
29 type State = ();
30
31 fn state(_spec: &Self::Spec) -> Self::State {}
32
33 fn init(ctx: Init<'_, Self>) -> impl Future<Output = Result<Self, Self::Cancel>> + Send + 'static {
34 let name = ctx.spec;
35 println!("MultiHandlerActor '{}' initialized", name);
36 future::ready(Ok(MultiHandlerActor {
37 counter: 0,
38 name,
39 }))
40 }
41}
42
43impl Handler<IncrementMsg> for MultiHandlerActor {
45 type Reply = Result<i32, anyhow::Error>;
46
47 async fn handle(&mut self, _ctx: Call<'_, Self, Self::Reply>, _msg: IncrementMsg) -> Self::Reply {
48 self.counter += 1;
49 println!("Actor '{}': Counter incremented to {}", self.name, self.counter);
50 Ok(self.counter)
51 }
52}
53
54impl Handler<GetCountMsg> for MultiHandlerActor {
55 type Reply = Result<i32, anyhow::Error>;
56
57 async fn handle(&mut self, _ctx: Call<'_, Self, Self::Reply>, _msg: GetCountMsg) -> Self::Reply {
58 println!("Actor '{}': Current counter is {}", self.name, self.counter);
59 Ok(self.counter)
60 }
61}
62
63impl Handler<SetNameMsg> for MultiHandlerActor {
64 type Reply = Result<String, anyhow::Error>;
65
66 async fn handle(&mut self, _ctx: Call<'_, Self, Self::Reply>, msg: SetNameMsg) -> Self::Reply {
67 let old_name = self.name.clone();
68 self.name = msg.0;
69 println!("Actor name changed from '{}' to '{}'", old_name, self.name);
70 Ok(old_name)
71 }
72}
73
74impl Handler<GetNameMsg> for MultiHandlerActor {
75 type Reply = Result<String, anyhow::Error>;
76
77 async fn handle(&mut self, _ctx: Call<'_, Self, Self::Reply>, _msg: GetNameMsg) -> Self::Reply {
78 println!("Actor '{}': Returning current name", self.name);
79 Ok(self.name.clone())
80 }
81}
82
83impl Handler<String> for MultiHandlerActor {
85 type Reply = Result<String, anyhow::Error>;
86
87 async fn handle(&mut self, _ctx: Call<'_, Self, Self::Reply>, msg: String) -> Self::Reply {
88 let response = format!("Actor '{}' received string: '{}'", self.name, msg);
89 println!("{}", response);
90 Ok(response)
91 }
92}
93
94#[tokio::main]
95async fn main() -> anyhow::Result<()> {
96 println!("=== Handler Pattern Example ===\n");
97
98 let actor = spawn::<MultiHandlerActor>("CounterBot".to_string());
100
101 println!("1. Testing typed messages:");
103
104 let count1: Result<i32, anyhow::Error> = actor.ask_dyn(IncrementMsg).await;
106 println!("Result: {:?}", count1);
107
108 let count2: Result<i32, anyhow::Error> = actor.ask_dyn(IncrementMsg).await;
109 println!("Result: {:?}", count2);
110
111 let current: Result<i32, anyhow::Error> = actor.ask_dyn(GetCountMsg).await;
113 println!("Current count: {:?}", current);
114
115 println!("\n2. Testing name operations:");
116
117 let old_name: Result<String, anyhow::Error> = actor.ask_dyn(SetNameMsg("SuperBot".to_string())).await;
119 println!("Previous name: {:?}", old_name);
120
121 let name: Result<String, anyhow::Error> = actor.ask_dyn(GetNameMsg).await;
123 println!("Current name: {:?}", name);
124
125 println!("\n3. Testing dynamic string messages:");
126
127 let response1: Result<String, anyhow::Error> = actor.ask_dyn("Hello there!".to_string()).await;
129 println!("Response: {:?}", response1);
130
131 let response2: Result<String, anyhow::Error> = actor.ask_dyn("How are you doing?".to_string()).await;
132 println!("Response: {:?}", response2);
133
134 println!("\n4. Final state check:");
135 let final_count: Result<i32, anyhow::Error> = actor.ask_dyn(GetCountMsg).await;
136 let final_name: Result<String, anyhow::Error> = actor.ask_dyn(GetNameMsg).await;
137 println!("Final count: {:?}, Final name: {:?}", final_count, final_name);
138
139 Ok(())
140}