communicator 0.1.0

Generic communication traits
Documentation
use std::sync::mpsc::{
    Receiver as MpscReceiver, SendError as MpscSendError, Sender as MpscSender,
    TryRecvError as MpscReceiveError,
};

#[derive(Debug)]
pub struct SendError;
#[derive(Debug)]
pub enum ReceiveError {
    Empty,
    Disconnected,
}

pub trait Sender<M> {
    fn send(&mut self, message: M) -> Result<(), SendError>;
}

pub trait Receiver<M> {
    fn receive(&mut self) -> Result<M, ReceiveError>;
}

pub trait Communicator<SendMessage, ReceiveMessage>:
    Sender<SendMessage> + Receiver<ReceiveMessage>
{
}

impl<T, SendMessage, ReceiveMessage> Communicator<SendMessage, ReceiveMessage> for T where
    T: Sender<SendMessage> + Receiver<ReceiveMessage>
{
}

pub struct SimpleCommunicator<S, R> {
    sender: S,
    receiver: R,
}

impl<S, R> SimpleCommunicator<S, R> {
    pub fn new(sender: S, receiver: R) -> Self {
        Self { sender, receiver }
    }

    #[inline]
    fn send<M>(&mut self, message: M) -> Result<(), SendError>
    where
        S: Sender<M>,
    {
        self.sender.send(message)
    }

    #[inline]
    fn receive<M>(&mut self) -> Result<M, ReceiveError>
    where
        R: Receiver<M>,
    {
        self.receiver.receive()
    }
}

impl<S, R, M> Sender<M> for SimpleCommunicator<S, R>
where
    S: Sender<M>,
{
    #[inline]
    fn send(&mut self, message: M) -> Result<(), SendError> {
        Self::send(self, message)
    }
}

impl<S, R, M> Receiver<M> for SimpleCommunicator<S, R>
where
    R: Receiver<M>,
{
    #[inline]
    fn receive(&mut self) -> Result<M, ReceiveError> {
        Self::receive(self)
    }
}

impl<M> Sender<M> for MpscSender<M> {
    #[inline]
    fn send(&mut self, message: M) -> Result<(), SendError> {
        Ok(MpscSender::send(self, message)?)
    }
}

impl<M> Receiver<M> for MpscReceiver<M> {
    #[inline]
    fn receive(&mut self) -> Result<M, ReceiveError> {
        Ok(self.try_recv()?)
    }
}

impl<T> From<MpscSendError<T>> for SendError {
    fn from(_err: MpscSendError<T>) -> SendError {
        SendError
    }
}

impl From<MpscReceiveError> for ReceiveError {
    fn from(err: MpscReceiveError) -> ReceiveError {
        match err {
            MpscReceiveError::Empty => ReceiveError::Empty,
            MpscReceiveError::Disconnected => ReceiveError::Disconnected,
        }
    }
}

#[cfg(feature = "data-stream")]
mod general {
    use super::{ReceiveError, Receiver, SendError, Sender};

    use data_stream::{from_stream, to_stream, FromStream, ReadError, ToStream};

    use std::{
        io::{Read, Write},
        marker::PhantomData,
    };

    pub struct StreamCommunicator<S, T> {
        stream: T,
        settings: PhantomData<S>,
    }

    impl<S, T> StreamCommunicator<S, T> {
        pub fn new(stream: T) -> Self {
            Self {
                stream,
                settings: PhantomData,
            }
        }
    }

    impl<S, M: ToStream<S>, W: Write> Sender<M> for StreamCommunicator<S, W> {
        #[inline]
        fn send(&mut self, message: M) -> Result<(), SendError> {
            match to_stream(&message, &mut self.stream) {
                Ok(value) => Ok(value),
                Err(_) => Err(SendError),
            }
        }
    }

    impl<S, M: FromStream<S>, R: Read> Receiver<M> for StreamCommunicator<S, R> {
        #[inline]
        fn receive(&mut self) -> Result<M, ReceiveError> {
            match from_stream::<_, M, _>(&mut self.stream) {
                Ok(value) => Ok(value),
                Err(err) => Err(match err {
                    ReadError::Stream => ReceiveError::Disconnected,
                    ReadError::Invalid => ReceiveError::Empty,
                }),
            }
        }
    }
}

#[cfg(feature = "data-stream")]
pub use general::*;