crb_superagent/mission/
async_fn.rs1use super::{Goal, Mission, runtime::RunMission};
2use anyhow::Result;
3use async_trait::async_trait;
4use crb_agent::{Address, Agent, AgentSession, Context, DoAsync, Next};
5use futures::Future;
6
7impl<T: Goal> RunMission<AsyncFn<T>> {
8 pub fn new_async<F: AnyAsyncFut<T>>(fut: F) -> Self {
9 let task = AsyncFn::<T> {
10 fut: Some(Box::new(fut)),
11 output: None,
12 };
13 Self::new(task)
14 }
15}
16
17pub trait AnyAsyncFut<T = ()>: Future<Output = T> + Send + 'static {}
18
19impl<F, T> AnyAsyncFut<T> for F where F: Future<Output = T> + Send + 'static {}
20
21pub struct AsyncFn<T> {
22 fut: Option<Box<dyn AnyAsyncFut<T>>>,
23 output: Option<T>,
24}
25
26impl<T: Goal> Agent for AsyncFn<T> {
27 type Context = AgentSession<Self>;
28 type Link = Address<Self>;
29
30 fn initialize(&mut self, _ctx: &mut Context<Self>) -> Next<Self> {
31 Next::do_async(AwaitFut)
32 }
33}
34
35#[async_trait]
36impl<T: Goal> Mission for AsyncFn<T> {
37 type Goal = T;
38
39 async fn deliver(self, _ctx: &mut Context<Self>) -> Option<Self::Goal> {
40 self.output
41 }
42}
43
44struct AwaitFut;
45
46#[async_trait]
47impl<T: Goal> DoAsync<AwaitFut> for AsyncFn<T> {
48 async fn once(&mut self, _state: &mut AwaitFut) -> Result<Next<Self>> {
49 let fut = self.fut.take().unwrap();
50 let pinned_fut = Box::into_pin(fut);
51 let output = pinned_fut.await;
52 self.output = Some(output);
53 Ok(Next::done())
54 }
55}