mm1_core/context/
messaging.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, message};
7
8use super::{Fork, ForkErrorKind};
9use crate::envelope::{Envelope, EnvelopeHeader};
10
11#[derive(Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
12#[message]
13pub enum RecvErrorKind {
14    Closed,
15}
16
17impl_error_kind!(RecvErrorKind);
18
19#[derive(Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
20#[message]
21pub enum SendErrorKind {
22    InternalError,
23    NotFound,
24    Closed,
25    Full,
26}
27
28pub trait Messaging {
29    fn address(&self) -> Address;
30
31    fn recv(&mut self) -> impl Future<Output = Result<Envelope, ErrorOf<RecvErrorKind>>> + Send;
32
33    fn close(&mut self) -> impl Future<Output = ()> + Send;
34
35    fn send(
36        &mut self,
37        envelope: Envelope,
38    ) -> impl Future<Output = Result<(), ErrorOf<SendErrorKind>>> + Send;
39}
40
41impl_error_kind!(SendErrorKind);
42
43#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
44pub enum AskErrorKind {
45    Fork(ForkErrorKind),
46    Tell(SendErrorKind),
47    Recv(RecvErrorKind),
48}
49
50pub trait Ask: Messaging + Fork {
51    fn ask<Req>(
52        &mut self,
53        to: Address,
54        make_request: impl FnOnce(Address) -> Req + Send,
55    ) -> impl Future<Output = Result<Envelope, ErrorOf<AskErrorKind>>> + Send
56    where
57        Req: Message,
58    {
59        async move {
60            let mut forked = self
61                .fork()
62                .await
63                .map_err(|e| e.map_kind(AskErrorKind::Fork))?;
64
65            let reply_to = forked.address();
66            let request = make_request(reply_to);
67            self.tell(to, request)
68                .await
69                .map_err(|e| e.map_kind(AskErrorKind::Tell))?;
70
71            let inbound = forked
72                .recv()
73                .await
74                .map_err(|e| e.map_kind(AskErrorKind::Recv))?;
75
76            Ok(inbound)
77        }
78    }
79}
80
81pub trait Tell: Messaging {
82    fn tell<M>(
83        &mut self,
84        to: Address,
85        message: M,
86    ) -> impl Future<Output = Result<(), ErrorOf<SendErrorKind>>> + Send
87    where
88        M: Message,
89    {
90        let info = EnvelopeHeader::to_address(to);
91        let envelope = Envelope::new(info, message);
92        self.send(envelope.into_erased())
93    }
94}
95
96impl_error_kind!(AskErrorKind);
97
98impl<T> Ask for T where T: Messaging + Fork {}
99impl<T> Tell for T where T: Messaging {}