mm1_core/
envelope.rs

1use std::any::TypeId;
2use std::fmt;
3use std::sync::atomic::{AtomicU64, Ordering};
4
5use mm1_address::address::Address;
6pub use mm1_proc_macros::dispatch;
7use mm1_proto::Message;
8
9use crate::message::AnyMessage;
10
11static ENVELOPE_SEQ_NO: AtomicU64 = AtomicU64::new(0);
12
13#[derive(Debug)]
14pub struct EnvelopeHeader {
15    pub to:         Address,
16    #[allow(dead_code)]
17    no:             u64,
18    #[allow(dead_code)]
19    trace_id:       Option<u64>,
20    #[allow(dead_code)]
21    correlation_id: Option<u64>,
22}
23
24pub struct Envelope<M = AnyMessage> {
25    header:  EnvelopeHeader,
26    message: M,
27}
28
29impl EnvelopeHeader {
30    pub fn to_address(to: Address) -> Self {
31        Self {
32            to,
33            no: ENVELOPE_SEQ_NO.fetch_add(1, Ordering::Relaxed),
34            trace_id: None,
35            correlation_id: None,
36        }
37    }
38}
39
40impl<M> Envelope<M>
41where
42    M: Message,
43{
44    pub fn into_erased(self) -> Envelope<AnyMessage> {
45        let Self {
46            header: info,
47            message,
48        } = self;
49        let message = AnyMessage::new(message);
50        Envelope {
51            header: info,
52            message,
53        }
54    }
55}
56
57impl<M> Envelope<M> {
58    pub fn new(header: EnvelopeHeader, message: M) -> Self {
59        Self { header, message }
60    }
61
62    pub fn header(&self) -> &EnvelopeHeader {
63        &self.header
64    }
65}
66
67impl Envelope<AnyMessage> {
68    pub fn cast<M>(self) -> Result<Envelope<M>, Self>
69    where
70        M: Message,
71    {
72        let Self {
73            header: info,
74            message,
75        } = self;
76        match message.cast() {
77            Ok(message) => {
78                Ok(Envelope {
79                    header: info,
80                    message,
81                })
82            },
83            Err(message) => {
84                Err(Self {
85                    header: info,
86                    message,
87                })
88            },
89        }
90    }
91
92    pub fn peek<M>(&self) -> Option<&M>
93    where
94        M: Message,
95    {
96        self.message.peek()
97    }
98
99    pub fn is<M>(&self) -> bool
100    where
101        M: Message,
102    {
103        self.message.is::<M>()
104    }
105
106    pub fn tid(&self) -> TypeId {
107        self.message.tid()
108    }
109
110    pub fn message_name(&self) -> &'static str {
111        self.message.type_name()
112    }
113}
114impl<M> Envelope<M> {
115    pub fn take(self) -> (M, Envelope<()>) {
116        (
117            self.message,
118            Envelope {
119                header:  self.header,
120                message: (),
121            },
122        )
123    }
124}
125
126impl<M> fmt::Debug for Envelope<M>
127where
128    M: fmt::Debug,
129{
130    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
131        f.debug_struct("Envelope")
132            .field("info", &self.header)
133            .field("message", &self.message)
134            .finish()
135    }
136}