Skip to main content

ironsbe_channel/
lib.rs

1//! # IronSBE Channel
2//!
3//! High-performance channel abstractions for messaging.
4//!
5//! This crate provides:
6//! - [`spsc`] - Ultra-low-latency single-producer single-consumer channels (~20ns)
7//! - [`mpsc`] - Multi-producer single-consumer channels (~100ns)
8//! - [`broadcast`] - One-to-many broadcast channels
9//! - [`async_bridge`] - Async/sync bridging utilities
10
11pub mod async_bridge;
12pub mod broadcast;
13pub mod mpsc;
14pub mod spsc;
15
16pub use mpsc::{MpscChannel, MpscReceiver, MpscSender};
17pub use spsc::{SpscChannel, SpscReceiver, SpscSender};
18
19/// Error type for channel operations.
20#[derive(Debug, Clone, PartialEq, Eq)]
21pub enum ChannelError<T> {
22    /// Channel is full, item returned.
23    Full(T),
24    /// Channel is disconnected, item returned.
25    Disconnected(T),
26    /// Channel is empty.
27    Empty,
28    /// Operation timed out.
29    Timeout,
30}
31
32impl<T> std::fmt::Display for ChannelError<T> {
33    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34        match self {
35            Self::Full(_) => write!(f, "channel full"),
36            Self::Disconnected(_) => write!(f, "channel disconnected"),
37            Self::Empty => write!(f, "channel empty"),
38            Self::Timeout => write!(f, "operation timed out"),
39        }
40    }
41}
42
43impl<T: std::fmt::Debug> std::error::Error for ChannelError<T> {}
44
45/// Trait for channel senders.
46pub trait ChannelSender<T>: Clone + Send + Sync {
47    /// Non-blocking send attempt.
48    ///
49    /// # Errors
50    /// Returns the item if the channel is full or disconnected.
51    fn try_send(&self, item: T) -> Result<(), ChannelError<T>>;
52
53    /// Blocking send with timeout.
54    ///
55    /// # Errors
56    /// Returns the item if the operation times out or channel is disconnected.
57    fn send_timeout(&self, item: T, timeout: std::time::Duration) -> Result<(), ChannelError<T>>;
58}
59
60/// Trait for channel receivers.
61pub trait ChannelReceiver<T>: Send {
62    /// Non-blocking receive attempt.
63    fn try_recv(&self) -> Option<T>;
64
65    /// Blocking receive with timeout.
66    fn recv_timeout(&self, timeout: std::time::Duration) -> Option<T>;
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72
73    #[test]
74    fn test_channel_error_display_full() {
75        let err: ChannelError<u32> = ChannelError::Full(42);
76        assert_eq!(err.to_string(), "channel full");
77    }
78
79    #[test]
80    fn test_channel_error_display_disconnected() {
81        let err: ChannelError<u32> = ChannelError::Disconnected(42);
82        assert_eq!(err.to_string(), "channel disconnected");
83    }
84
85    #[test]
86    fn test_channel_error_display_empty() {
87        let err: ChannelError<u32> = ChannelError::Empty;
88        assert_eq!(err.to_string(), "channel empty");
89    }
90
91    #[test]
92    fn test_channel_error_display_timeout() {
93        let err: ChannelError<u32> = ChannelError::Timeout;
94        assert_eq!(err.to_string(), "operation timed out");
95    }
96
97    #[test]
98    fn test_channel_error_equality() {
99        let err1: ChannelError<u32> = ChannelError::Empty;
100        let err2: ChannelError<u32> = ChannelError::Empty;
101        assert_eq!(err1, err2);
102
103        let err3: ChannelError<u32> = ChannelError::Timeout;
104        assert_ne!(err1, err3);
105    }
106
107    #[test]
108    fn test_channel_error_clone() {
109        let err: ChannelError<u32> = ChannelError::Full(42);
110        let cloned = err.clone();
111        assert_eq!(err, cloned);
112    }
113
114    #[test]
115    fn test_channel_error_debug() {
116        let err: ChannelError<u32> = ChannelError::Full(42);
117        let debug_str = format!("{:?}", err);
118        assert!(debug_str.contains("Full"));
119        assert!(debug_str.contains("42"));
120    }
121}