crb_superagent/mission/
sync_fn.rs1use 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}