mm1_core/context/
ask.rs

1use std::future::Future;
2
3use mm1_address::address::Address;
4use mm1_common::errors::error_of::ErrorOf;
5use mm1_common::impl_error_kind;
6use mm1_proto::Message;
7
8use crate::context::{Fork, ForkErrorKind, Recv, RecvErrorKind, Tell, TellErrorKind};
9use crate::envelope::Envelope;
10
11#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub enum AskErrorKind {
13    Fork(ForkErrorKind),
14    Tell(TellErrorKind),
15    Recv(RecvErrorKind),
16}
17
18pub trait Ask: Tell + Fork + Recv {
19    fn ask<Req>(
20        &mut self,
21        to: Address,
22        make_request: impl FnOnce(Address) -> Req + Send,
23    ) -> impl Future<Output = Result<Envelope, ErrorOf<AskErrorKind>>> + Send
24    where
25        Req: Message,
26    {
27        async move {
28            let mut forked = self
29                .fork()
30                .await
31                .map_err(|e| e.map_kind(AskErrorKind::Fork))?;
32
33            let reply_to = forked.address();
34            let request = make_request(reply_to);
35            self.tell(to, request)
36                .await
37                .map_err(|e| e.map_kind(AskErrorKind::Tell))?;
38
39            let inbound = forked
40                .recv()
41                .await
42                .map_err(|e| e.map_kind(AskErrorKind::Recv))?;
43
44            Ok(inbound)
45        }
46    }
47}
48
49impl_error_kind!(AskErrorKind);
50
51impl<T> Ask for T where T: Tell + Fork + Recv {}