Skip to main content

crb_superagent/
routine.rs

1use 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
26// Async Routine
27
28impl 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
47// Sync Routine
48
49impl 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}