mm1_core/
envelope.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use std::fmt;
use std::sync::atomic::{AtomicU64, Ordering};

use mm1_address::address::Address;

use crate::message::AnyMessage;

static ENVELOPE_SEQ_NO: AtomicU64 = AtomicU64::new(0);

#[derive(Debug)]
pub struct EnvelopeInfo {
    #[allow(dead_code)]
    no: u64,
    #[allow(dead_code)]
    to: Address,
}

pub struct Envelope<M = AnyMessage> {
    info:    EnvelopeInfo,
    message: M,
}

impl EnvelopeInfo {
    pub fn new(to: Address) -> Self {
        Self {
            no: ENVELOPE_SEQ_NO.fetch_add(1, Ordering::Relaxed),
            to,
        }
    }
}

impl<M> Envelope<M>
where
    M: Send + 'static,
{
    pub fn into_erased(self) -> Envelope<AnyMessage> {
        let Self { info, message } = self;
        let message = AnyMessage::new(message);
        Envelope { info, message }
    }
}

impl<M> Envelope<M> {
    pub fn new(info: EnvelopeInfo, message: M) -> Self {
        Self { info, message }
    }

    pub fn info(&self) -> &EnvelopeInfo {
        &self.info
    }
}

impl Envelope<AnyMessage> {
    pub fn cast<M>(self) -> Result<Envelope<M>, Self>
    where
        M: Send + 'static,
    {
        let Self { info, message } = self;
        match message.cast() {
            Ok(message) => Ok(Envelope { info, message }),
            Err(message) => Err(Self { info, message }),
        }
    }

    pub fn peek<M>(&self) -> Option<&M>
    where
        M: Send + 'static,
    {
        self.message.peek()
    }
}
impl<M> Envelope<M> {
    pub fn take_message(self) -> (M, Envelope<()>) {
        (
            self.message,
            Envelope {
                info:    self.info,
                message: (),
            },
        )
    }
}

impl<M> fmt::Debug for Envelope<M>
where
    M: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        f.debug_struct("Envelope")
            .field("info", &self.info)
            .field("message", &self.message)
            .finish()
    }
}