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}