Skip to main content

crb_superagent/interplay/
interaction.rs

1use super::{Fetcher, Interplay};
2use anyhow::{Result, anyhow};
3use async_trait::async_trait;
4use crb_agent::{Address, Agent, Context, MessageFor};
5
6pub trait InteractExt<R: Request> {
7    fn interact(&self, request: R) -> Fetcher<R::Response>;
8}
9
10impl<A, R> InteractExt<R> for Address<A>
11where
12    A: OnRequest<R>,
13    R: Request,
14{
15    fn interact(&self, request: R) -> Fetcher<R::Response> {
16        let (interplay, fetcher) = Interplay::new_pair(request);
17        let msg = Interaction { interplay };
18        let res = self.send(msg);
19        fetcher.grasp(res)
20    }
21}
22
23impl<A, R> InteractExt<R> for Context<A>
24where
25    A: OnRequest<R>,
26    R: Request,
27{
28    fn interact(&self, request: R) -> Fetcher<R::Response> {
29        self.address().interact(request)
30    }
31}
32
33pub trait Request: Send + 'static {
34    type Response: Send + 'static;
35}
36
37pub struct Interaction<R: Request> {
38    pub interplay: Interplay<R, R::Response>,
39}
40
41#[async_trait]
42impl<A, R> MessageFor<A> for Interaction<R>
43where
44    A: OnRequest<R>,
45    R: Request,
46{
47    async fn handle(self: Box<Self>, agent: &mut A, ctx: &mut Context<A>) -> Result<()> {
48        agent.handle(*self, ctx).await
49    }
50}
51
52#[async_trait]
53pub trait OnRequest<R: Request>: Agent {
54    async fn handle(&mut self, msg: Interaction<R>, ctx: &mut Context<Self>) -> Result<()> {
55        let resp = self.on_request(msg.interplay.request, ctx).await;
56        msg.interplay.responder.send_result(resp)
57    }
58
59    async fn on_request(&mut self, _request: R, _ctx: &mut Context<Self>) -> Result<R::Response> {
60        Err(anyhow!("The on_request method in not implemented."))
61    }
62}