message-channel 0.0.1

A simple thread-safe message channel implementation
Documentation
//! # message-channel
//!
//! `message-channel` is a simple, thread-safe channel implementation for sending and receiving messages between threads.
//!
//! This crate provides a `Channel` struct that can be used to create a pair of `Sender` and `Receiver` for message passing.
//!
//! ## Examples
//!
//! ```
//! use message_channel::Channel;
//!
//! let (sender, receiver) = Channel::create();
//!
//! sender.send(42);
//! let message = receiver.recv().unwrap();
//! assert_eq!(message, 42);
//! ```
//!

use std::collections::VecDeque;
use std::fmt::{self, Debug, Display};
use std::sync::{Arc, Mutex};

/// Custom error type for the `Channel`.
#[derive(Debug)]
pub enum ChannelError {
    Poisoned,
}

impl Display for ChannelError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "Channel mutex is poisoned")
    }
}

#[derive(Debug)]
pub struct Channel<T: Debug + Send + Sync> {
    queue: Mutex<VecDeque<T>>,
}

impl<T: Debug + Send + Sync> Channel<T> {
    /// Creates a new channel and returns a sender and receiver pair.
    ///
    /// # Errors
    ///
    /// This function will return an error if the mutex is poisoned.
    ///
    /// # Examples
    ///
    /// ```
    /// use message_channel::Channel;
    ///
    /// let (sender, receiver) = Channel::<i32>::create();
    /// ```

    #[must_use]
    pub fn create() -> (Sender<T>, Receiver<T>) {
        let channel = Arc::new(Self {
            queue: Mutex::new(VecDeque::new()),
        });

        let sender = Sender {
            channel: Arc::clone(&channel),
        };
        let receiver = Receiver {
            channel: Arc::clone(&channel),
        };

        (sender, receiver)
    }
}

/// A sender for sending messages to the channel.
#[derive(Debug)]
pub struct Sender<T: Debug + Send + Sync> {
    channel: Arc<Channel<T>>,
}

impl<T: Debug + Send + Sync> Clone for Sender<T> {
    fn clone(&self) -> Self {
        Self {
            channel: self.channel.clone(),
        }
    }
}

impl<T: Debug + Send + Sync> Sender<T> {
    /// Sends a message to the channel.
    ///
    /// # Errors
    ///
    /// This function will return an error if the mutex is poisoned.
    ///
    /// # Examples
    ///
    /// ```
    /// use message_channel::Channel;
    ///
    /// let (sender, receiver) = Channel::create();
    /// sender.send(42).unwrap();
    /// ```
    pub fn send(&self, message: T) -> Result<(), ChannelError> {
        let mut queue = self
            .channel
            .queue
            .lock()
            .map_err(|_| ChannelError::Poisoned)?;
        queue.push_back(message);
        Ok(())
    }
}

/// A receiver for receiving messages from the channel.
#[derive(Debug)]
pub struct Receiver<T: Debug + Send + Sync> {
    channel: Arc<Channel<T>>,
}

impl<T: Debug + Send + Sync> Receiver<T> {
    // Non-blocking `recv` that returns `Some` if there is a message, or `None` if the queue is empty
    pub fn try_recv(&self) -> Option<T> {
        let mut queue = self.channel.queue.lock().unwrap();
        queue.pop_front()
    }

    /// Receives a message from the channel.
    ///
    /// # Errors
    ///
    /// This function will return an error if the mutex is poisoned.
    ///
    /// # Examples
    ///
    /// ```
    /// use message_channel::Channel;
    ///
    /// let (sender, receiver) = Channel::create();
    /// sender.send(42).unwrap();
    /// let message = receiver.recv().unwrap();
    /// assert_eq!(message, 42);
    /// ```
    pub fn recv(&self) -> Result<T, ChannelError> {
        let mut queue = self
            .channel
            .queue
            .lock()
            .map_err(|_| ChannelError::Poisoned)?;
        queue.pop_front().ok_or(ChannelError::Poisoned)
    }
}