ring_channel/
error.rs

1use core::fmt;
2use derivative::Derivative;
3
4#[cfg(test)]
5use test_strategy::Arbitrary;
6
7/// An error that may be returned by [`RingSender::send`].
8///
9/// [`RingSender::send`]: struct.RingSender.html#method.send
10#[derive(Derivative, Copy, Clone, Eq, PartialEq)]
11#[derivative(Debug)]
12#[cfg_attr(test, derive(Arbitrary))]
13pub enum SendError<T> {
14    /// The channel is disconnected.
15    Disconnected(#[derivative(Debug = "ignore")] T),
16}
17
18impl<T> fmt::Display for SendError<T> {
19    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
20        "sending on a disconnected channel".fmt(f)
21    }
22}
23
24/// Requires [feature] `"std"`.
25///
26/// [feature]: index.html#optional-features
27#[cfg(feature = "std")]
28impl<T: Send> std::error::Error for SendError<T> {}
29
30/// An error that may be returned by [`RingReceiver::recv`].
31///
32/// [`RingReceiver::recv`]: struct.RingReceiver.html#method.recv
33#[cfg(feature = "futures_api")]
34#[derive(Debug, Copy, Clone, Eq, PartialEq)]
35#[cfg_attr(test, derive(Arbitrary))]
36pub enum RecvError {
37    /// No messages pending in the internal buffer and the channel is disconnected.
38    Disconnected,
39}
40
41#[cfg(feature = "futures_api")]
42impl fmt::Display for RecvError {
43    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
44        use RecvError::*;
45        match self {
46            Disconnected => "receiving on an empty and disconnected channel".fmt(f),
47        }
48    }
49}
50
51/// Requires [feature] `"std"`.
52///
53/// [feature]: index.html#optional-features
54#[cfg(all(feature = "std", feature = "futures_api"))]
55impl std::error::Error for RecvError {}
56
57/// An error that may be returned by [`RingReceiver::try_recv`].
58///
59/// [`RingReceiver::try_recv`]: struct.RingReceiver.html#method.try_recv
60#[derive(Debug, Copy, Clone, Eq, PartialEq)]
61#[cfg_attr(test, derive(Arbitrary))]
62pub enum TryRecvError {
63    /// No messages pending in the internal buffer.
64    Empty,
65
66    /// No messages pending in the internal buffer and the channel is disconnected.
67    Disconnected,
68}
69
70impl fmt::Display for TryRecvError {
71    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
72        use TryRecvError::*;
73        match self {
74            Empty => "receiving on an empty channel".fmt(f),
75            Disconnected => "receiving on an empty and disconnected channel".fmt(f),
76        }
77    }
78}
79
80/// Requires [feature] `"std"`.
81///
82/// [feature]: index.html#optional-features
83#[cfg(feature = "std")]
84impl std::error::Error for TryRecvError {}
85
86#[cfg(all(feature = "std", test))]
87mod tests {
88    use super::*;
89    use alloc::boxed::Box;
90    use std::error::Error;
91    use test_strategy::proptest;
92
93    #[proptest]
94    fn send_error_implements_error_trait(err: SendError<()>) {
95        assert_eq!(format!("{err}"), format!("{}", Box::<dyn Error>::from(err)));
96    }
97
98    #[cfg(feature = "futures_api")]
99    #[proptest]
100    fn recv_error_implements_error_trait(err: RecvError) {
101        assert_eq!(format!("{err}"), format!("{}", Box::<dyn Error>::from(err)));
102    }
103
104    #[proptest]
105    fn try_recv_error_implements_error_trait(err: TryRecvError) {
106        assert_eq!(format!("{err}"), format!("{}", Box::<dyn Error>::from(err)));
107    }
108}