pub trait Message {
fn message_type(&self) -> &'static str;
}
pub trait MessageEndpoint<M: Message> {
fn send(&mut self, msg: M) -> bool;
fn recv(&mut self) -> Option<M>;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
}
#[cfg(test)]
mod tests {
use super::{Message, MessageEndpoint};
#[derive(Debug, Clone, PartialEq, Eq)]
struct TestMessage {
kind: &'static str,
payload: u32,
}
impl Message for TestMessage {
fn message_type(&self) -> &'static str {
self.kind
}
}
struct FixedChannel<const N: usize> {
buffer: std::collections::VecDeque<TestMessage>,
}
impl<const N: usize> FixedChannel<N> {
fn new() -> Self {
Self {
buffer: std::collections::VecDeque::new(),
}
}
}
impl<const N: usize> MessageEndpoint<TestMessage> for FixedChannel<N> {
fn send(&mut self, msg: TestMessage) -> bool {
if self.buffer.len() >= N {
return false;
}
self.buffer.push_back(msg);
true
}
fn recv(&mut self) -> Option<TestMessage> {
self.buffer.pop_front()
}
fn len(&self) -> usize {
self.buffer.len()
}
}
#[test]
fn fixed_channel_sends_and_receives() {
let mut chan: FixedChannel<2> = FixedChannel::new();
assert!(chan.send(TestMessage {
kind: "ping",
payload: 1,
}));
assert!(chan.send(TestMessage {
kind: "ping",
payload: 2,
}));
assert!(!chan.send(TestMessage {
kind: "ping",
payload: 3,
}));
assert_eq!(
chan.recv(),
Some(TestMessage {
kind: "ping",
payload: 1
})
);
assert_eq!(
chan.recv(),
Some(TestMessage {
kind: "ping",
payload: 2
})
);
assert!(chan.recv().is_none());
}
}