crb_superagent/mission/
sync_fn.rs

1use super::{Goal, Mission, runtime::RunMission};
2use anyhow::Result;
3use async_trait::async_trait;
4use crb_agent::{Address, Agent, AgentSession, Context, DoSync, Next};
5
6impl<T: Goal> RunMission<SyncFn<T>> {
7    pub fn new_sync<F: AnySyncFn<T>>(func: F) -> Self {
8        let task = SyncFn::<T> {
9            func: Some(Box::new(func)),
10            output: None,
11        };
12        Self::new(task)
13    }
14}
15
16pub trait AnySyncFn<T = ()>: FnOnce() -> T + Send + 'static {}
17
18impl<F, T> AnySyncFn<T> for F where F: FnOnce() -> T + Send + 'static {}
19
20pub struct SyncFn<T> {
21    func: Option<Box<dyn AnySyncFn<T>>>,
22    output: Option<T>,
23}
24
25impl<T: Goal> Agent for SyncFn<T> {
26    type Context = AgentSession<Self>;
27    type Link = Address<Self>;
28
29    fn initialize(&mut self, _ctx: &mut Context<Self>) -> Next<Self> {
30        Next::do_sync(CallFn)
31    }
32}
33
34#[async_trait]
35impl<T: Goal> Mission for SyncFn<T> {
36    type Goal = T;
37
38    async fn deliver(self, _ctx: &mut Context<Self>) -> Option<Self::Goal> {
39        self.output
40    }
41}
42
43struct CallFn;
44
45impl<T: Goal> DoSync<CallFn> for SyncFn<T> {
46    fn once(&mut self, _state: &mut CallFn) -> Result<Next<Self>> {
47        let func = self.func.take().unwrap();
48        let output = func();
49        self.output = Some(output);
50        Ok(Next::done())
51    }
52}