crb_superagent/
routine.rs1use anyhow::{Result, anyhow};
2use async_trait::async_trait;
3use crb_agent::{Address, Agent, AgentSession, DoAsync, DoSync, Next};
4
5pub enum Routine {
6 AsyncRoutine(Box<dyn AsyncRoutine>),
7 SyncRoutine(Box<dyn SyncRoutine>),
8 Detached,
9}
10
11impl Agent for Routine {
12 type Context = AgentSession<Self>;
13 type Link = Address<Self>;
14
15 fn begin(&mut self) -> Next<Self> {
16 let mut detached = Self::Detached;
17 std::mem::swap(self, &mut detached);
18 match detached {
19 Self::AsyncRoutine(routine) => Next::do_async(routine),
20 Self::SyncRoutine(routine) => Next::do_sync(routine),
21 Self::Detached => Next::fail(anyhow!("Detached routine")),
22 }
23 }
24}
25
26impl Routine {
29 pub fn new_async<R: AsyncRoutine>(routine: R) -> Self {
30 Self::AsyncRoutine(Box::new(routine))
31 }
32}
33
34#[async_trait]
35pub trait AsyncRoutine: Send + 'static {
36 async fn routine(&mut self) -> Result<()>;
37}
38
39#[async_trait]
40impl DoAsync<Box<dyn AsyncRoutine>> for Routine {
41 async fn repeat(&mut self, boxed: &mut Box<dyn AsyncRoutine>) -> Result<Option<Next<Self>>> {
42 boxed.routine().await?;
43 Ok(None)
44 }
45}
46
47impl Routine {
50 pub fn new_sync<R: SyncRoutine>(routine: R) -> Self {
51 Self::SyncRoutine(Box::new(routine))
52 }
53}
54
55pub trait SyncRoutine: Send + 'static {
56 fn routine(&mut self) -> Result<()>;
57}
58
59#[async_trait]
60impl DoSync<Box<dyn SyncRoutine>> for Routine {
61 fn repeat(&mut self, boxed: &mut Box<dyn SyncRoutine>) -> Result<Option<Next<Self>>> {
62 boxed.routine()?;
63 Ok(None)
64 }
65}