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
use std::collections::VecDeque;
use std::fmt;

use message::{Message, ProtocolMessage};
use System;

/// Actions instructed by Plumtree [Node].
///
/// For running Plumtree nodes, the actions must be handled correctly by upper layers.
///
/// [Node]: ./struct.Node.html
pub enum Action<T: System> {
    /// Send a message.
    ///
    /// If it is failed to send the message (e.g., the destination node does not exist),
    /// the message will be discarded silently.
    Send {
        /// The destination of the message.
        destination: T::NodeId,

        /// The outgoing message.
        message: ProtocolMessage<T>,
    },

    /// Deliver a message to the applications waiting for messages.
    Deliver {
        /// The message to be delivered.
        message: Message<T>,
    },
}
impl<T: System> Action<T> {
    pub(crate) fn send<M>(destination: T::NodeId, message: M) -> Self
    where
        M: Into<ProtocolMessage<T>>,
    {
        Action::Send {
            destination,
            message: message.into(),
        }
    }
}
impl<T: System> fmt::Debug for Action<T>
where
    T::NodeId: fmt::Debug,
    T::MessageId: fmt::Debug,
    T::MessagePayload: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match self {
            Action::Send {
                destination,
                message,
            } => write!(
                f,
                "Send {{ destination: {:?}, message: {:?} }}",
                destination, message
            ),
            Action::Deliver { message } => write!(f, "Deliver {{ message: {:?} }}", message),
        }
    }
}

pub struct ActionQueue<T: System>(VecDeque<Action<T>>);
impl<T: System> ActionQueue<T> {
    pub fn new() -> Self {
        ActionQueue(VecDeque::new())
    }

    pub fn send<M: Into<ProtocolMessage<T>>>(&mut self, destination: T::NodeId, message: M) {
        self.0.push_back(Action::send(destination, message));
    }

    pub fn deliver(&mut self, message: Message<T>) {
        self.0.push_back(Action::Deliver { message });
    }

    pub fn pop(&mut self) -> Option<Action<T>> {
        self.0.pop_front()
    }
}
impl<T: System> fmt::Debug for ActionQueue<T>
where
    T::NodeId: fmt::Debug,
    T::MessageId: fmt::Debug,
    T::MessagePayload: fmt::Debug,
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "ActionQueue({:?})", self.0)
    }
}