1use actor_helper::{Actor, Handle, act_ok, act};
2use anyhow::{anyhow, Result};
3use tokio::sync::mpsc;
4
5pub struct Counter {
7 handle: Handle<CounterActor>,
8}
9
10impl Counter {
11 pub fn new() -> Self {
12 let (handle, rx) = Handle::channel(128);
13 let actor = CounterActor { value: 0, rx };
14
15 tokio::spawn(async move {
16 let mut actor = actor;
17 let _ = actor.run().await;
18 });
19
20 Self { handle }
21 }
22
23 pub async fn increment(&self, by: i32) -> Result<()> {
24 self.handle.call(act_ok!(actor => async move {
25 actor.value += by;
26 })).await
27 }
28
29 pub async fn get(&self) -> Result<i32> {
30 self.handle.call(act_ok!(actor => async move {
31 actor.value
32 })).await
33 }
34
35 pub async fn set_positive(&self, value: i32) -> Result<()> {
36 self.handle.call(act!(actor => async move {
37 if value <= 0 {
38 Err(anyhow!("Value must be positive"))
39 } else {
40 actor.value = value;
41 Ok(())
42 }
43 })).await
44 }
45}
46
47struct CounterActor {
49 value: i32,
50 rx: mpsc::Receiver<actor_helper::Action<CounterActor>>,
51}
52
53impl Actor for CounterActor {
54 async fn run(&mut self) -> Result<()> {
55 loop {
56 tokio::select! {
57 Some(action) = self.rx.recv() => {
58 action(self).await;
59 }
60 }
62 }
63 }
64}
65
66#[tokio::main]
67async fn main() -> Result<()> {
68 let counter = Counter::new();
69
70 counter.increment(5).await?;
71 println!("Value: {}", counter.get().await?);
72
73 counter.set_positive(10).await?;
74 println!("Value: {}", counter.get().await?);
75
76 Ok(())
77}