message_channel/
lib.rs

1//! # message-channel
2//!
3//! `message-channel` is a simple, thread-safe channel implementation for sending and receiving messages between threads.
4//!
5//! This crate provides a `Channel` struct that can be used to create a pair of `Sender` and `Receiver` for message passing.
6//!
7//! ## Examples
8//!
9//! ```
10//! use message_channel::Channel;
11//!
12//! let (sender, receiver) = Channel::create();
13//!
14//! sender.send(42);
15//! let message = receiver.recv().unwrap();
16//! assert_eq!(message, 42);
17//! ```
18//!
19
20use std::collections::VecDeque;
21use std::fmt::{self, Debug, Display};
22use std::sync::{Arc, Mutex};
23
24/// Custom error type for the `Channel`.
25#[derive(Debug)]
26pub enum ChannelError {
27    Poisoned,
28}
29
30impl Display for ChannelError {
31    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32        write!(f, "Channel mutex is poisoned")
33    }
34}
35
36#[derive(Debug)]
37pub struct Channel<T: Debug + Send + Sync> {
38    queue: Mutex<VecDeque<T>>,
39}
40
41impl<T: Debug + Send + Sync> Channel<T> {
42    /// Creates a new channel and returns a sender and receiver pair.
43    ///
44    /// # Errors
45    ///
46    /// This function will return an error if the mutex is poisoned.
47    ///
48    /// # Examples
49    ///
50    /// ```
51    /// use message_channel::Channel;
52    ///
53    /// let (sender, receiver) = Channel::<i32>::create();
54    /// ```
55
56    #[must_use]
57    pub fn create() -> (Sender<T>, Receiver<T>) {
58        let channel = Arc::new(Self {
59            queue: Mutex::new(VecDeque::new()),
60        });
61
62        let sender = Sender {
63            channel: Arc::clone(&channel),
64        };
65        let receiver = Receiver {
66            channel: Arc::clone(&channel),
67        };
68
69        (sender, receiver)
70    }
71}
72
73/// A sender for sending messages to the channel.
74#[derive(Debug)]
75pub struct Sender<T: Debug + Send + Sync> {
76    channel: Arc<Channel<T>>,
77}
78
79impl<T: Debug + Send + Sync> Clone for Sender<T> {
80    fn clone(&self) -> Self {
81        Self {
82            channel: self.channel.clone(),
83        }
84    }
85}
86
87impl<T: Debug + Send + Sync> Sender<T> {
88    /// Sends a message to the channel.
89    ///
90    /// # Errors
91    ///
92    /// This function will return an error if the mutex is poisoned.
93    ///
94    /// # Examples
95    ///
96    /// ```
97    /// use message_channel::Channel;
98    ///
99    /// let (sender, receiver) = Channel::create();
100    /// sender.send(42).unwrap();
101    /// ```
102    pub fn send(&self, message: T) -> Result<(), ChannelError> {
103        let mut queue = self
104            .channel
105            .queue
106            .lock()
107            .map_err(|_| ChannelError::Poisoned)?;
108        queue.push_back(message);
109        Ok(())
110    }
111}
112
113/// A receiver for receiving messages from the channel.
114#[derive(Debug)]
115pub struct Receiver<T: Debug + Send + Sync> {
116    channel: Arc<Channel<T>>,
117}
118
119impl<T: Debug + Send + Sync> Receiver<T> {
120    // Non-blocking `recv` that returns `Some` if there is a message, or `None` if the queue is empty
121    pub fn try_recv(&self) -> Option<T> {
122        let mut queue = self.channel.queue.lock().unwrap();
123        queue.pop_front()
124    }
125
126    /// Receives a message from the channel.
127    ///
128    /// # Errors
129    ///
130    /// This function will return an error if the mutex is poisoned.
131    ///
132    /// # Examples
133    ///
134    /// ```
135    /// use message_channel::Channel;
136    ///
137    /// let (sender, receiver) = Channel::create();
138    /// sender.send(42).unwrap();
139    /// let message = receiver.recv().unwrap();
140    /// assert_eq!(message, 42);
141    /// ```
142    pub fn recv(&self) -> Result<T, ChannelError> {
143        let mut queue = self
144            .channel
145            .queue
146            .lock()
147            .map_err(|_| ChannelError::Poisoned)?;
148        queue.pop_front().ok_or(ChannelError::Poisoned)
149    }
150}