use core::marker::PhantomData;
use crate::Pipe;
pub trait MessageFamily {
type Message<'message>;
}
pub struct PipeIn<Selected: Pipe>(PhantomData<fn() -> Selected>);
impl<Selected: Pipe> MessageFamily for PipeIn<Selected> {
type Message<'message> = Selected::In<'message>;
}
pub struct PipeOut<Selected: Pipe>(PhantomData<fn() -> Selected>);
impl<Selected: Pipe> MessageFamily for PipeOut<Selected> {
type Message<'message> = Selected::Out<'message>;
}
pub struct OwnedMessage<Message>(PhantomData<fn() -> Message>);
impl<Message> MessageFamily for OwnedMessage<Message> {
type Message<'message> = Message;
}
#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
pub struct EncodedByteCount(usize);
impl EncodedByteCount {
pub const fn new(value: usize) -> Self {
Self(value)
}
pub const fn get(self) -> usize {
self.0
}
}
pub trait MessageEncoder {
type Message<'message>: ?Sized;
type Error;
fn encode<'message>(
&self,
message: &Self::Message<'message>,
destination: &mut [u8],
) -> Result<EncodedByteCount, Self::Error>;
}
pub trait MessageDecoder {
type Message<'frame>;
type Error;
fn decode<'frame>(&self, frame: &'frame mut [u8])
-> Result<Self::Message<'frame>, Self::Error>;
}
#[cfg(test)]
mod tests {
use super::*;
use crate::{NoInput, NoOutput};
struct Duplex;
impl Pipe for Duplex {
type In<'message> = &'message str;
type Out<'message> = &'message [u8];
}
struct Source;
impl Pipe for Source {
type In<'message> = NoInput;
type Out<'message> = &'message str;
}
struct Sink;
impl Pipe for Sink {
type In<'message> = &'message str;
type Out<'message> = NoOutput;
}
#[test]
fn participant_message_families_include_uninhabited_directions() {
fn assert_message_families<Selected>()
where
Selected: Pipe,
for<'message> PipeIn<Selected>:
MessageFamily<Message<'message> = Selected::In<'message>>,
for<'message> PipeOut<Selected>:
MessageFamily<Message<'message> = Selected::Out<'message>>,
{
}
assert_message_families::<Duplex>();
assert_message_families::<Source>();
assert_message_families::<Sink>();
}
#[test]
fn encoded_byte_counts_preserve_their_value() {
assert_eq!(EncodedByteCount::new(7).get(), 7);
}
}