1 use std::error;
2 use std::fmt;
3 
4 /// An error returned from the [`send`] method.
5 ///
6 /// The message could not be sent because the channel is disconnected.
7 ///
8 /// The error contains the message so it can be recovered.
9 ///
10 /// [`send`]: super::Sender::send
11 #[derive(PartialEq, Eq, Clone, Copy)]
12 pub struct SendError<T>(pub T);
13 
14 /// An error returned from the [`try_send`] method.
15 ///
16 /// The error contains the message being sent so it can be recovered.
17 ///
18 /// [`try_send`]: super::Sender::try_send
19 #[derive(PartialEq, Eq, Clone, Copy)]
20 pub enum TrySendError<T> {
21     /// The message could not be sent because the channel is full.
22     ///
23     /// If this is a zero-capacity channel, then the error indicates that there was no receiver
24     /// available to receive the message at the time.
25     Full(T),
26 
27     /// The message could not be sent because the channel is disconnected.
28     Disconnected(T),
29 }
30 
31 /// An error returned from the [`send_timeout`] method.
32 ///
33 /// The error contains the message being sent so it can be recovered.
34 ///
35 /// [`send_timeout`]: super::Sender::send_timeout
36 #[derive(PartialEq, Eq, Clone, Copy)]
37 pub enum SendTimeoutError<T> {
38     /// The message could not be sent because the channel is full and the operation timed out.
39     ///
40     /// If this is a zero-capacity channel, then the error indicates that there was no receiver
41     /// available to receive the message and the operation timed out.
42     Timeout(T),
43 
44     /// The message could not be sent because the channel is disconnected.
45     Disconnected(T),
46 }
47 
48 /// An error returned from the [`recv`] method.
49 ///
50 /// A message could not be received because the channel is empty and disconnected.
51 ///
52 /// [`recv`]: super::Receiver::recv
53 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
54 pub struct RecvError;
55 
56 /// An error returned from the [`try_recv`] method.
57 ///
58 /// [`try_recv`]: super::Receiver::try_recv
59 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
60 pub enum TryRecvError {
61     /// A message could not be received because the channel is empty.
62     ///
63     /// If this is a zero-capacity channel, then the error indicates that there was no sender
64     /// available to send a message at the time.
65     Empty,
66 
67     /// The message could not be received because the channel is empty and disconnected.
68     Disconnected,
69 }
70 
71 /// An error returned from the [`recv_timeout`] method.
72 ///
73 /// [`recv_timeout`]: super::Receiver::recv_timeout
74 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
75 pub enum RecvTimeoutError {
76     /// A message could not be received because the channel is empty and the operation timed out.
77     ///
78     /// If this is a zero-capacity channel, then the error indicates that there was no sender
79     /// available to send a message and the operation timed out.
80     Timeout,
81 
82     /// The message could not be received because the channel is empty and disconnected.
83     Disconnected,
84 }
85 
86 /// An error returned from the [`try_select`] method.
87 ///
88 /// Failed because none of the channel operations were ready.
89 ///
90 /// [`try_select`]: super::Select::try_select
91 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
92 pub struct TrySelectError;
93 
94 /// An error returned from the [`select_timeout`] method.
95 ///
96 /// Failed because none of the channel operations became ready before the timeout.
97 ///
98 /// [`select_timeout`]: super::Select::select_timeout
99 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
100 pub struct SelectTimeoutError;
101 
102 /// An error returned from the [`try_ready`] method.
103 ///
104 /// Failed because none of the channel operations were ready.
105 ///
106 /// [`try_ready`]: super::Select::try_ready
107 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
108 pub struct TryReadyError;
109 
110 /// An error returned from the [`ready_timeout`] method.
111 ///
112 /// Failed because none of the channel operations became ready before the timeout.
113 ///
114 /// [`ready_timeout`]: super::Select::ready_timeout
115 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
116 pub struct ReadyTimeoutError;
117 
118 impl<T> fmt::Debug for SendError<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result119     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
120         "SendError(..)".fmt(f)
121     }
122 }
123 
124 impl<T> fmt::Display for SendError<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result125     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
126         "sending on a disconnected channel".fmt(f)
127     }
128 }
129 
130 impl<T: Send> error::Error for SendError<T> {}
131 
132 impl<T> SendError<T> {
133     /// Unwraps the message.
134     ///
135     /// # Examples
136     ///
137     /// ```
138     /// use crossbeam_channel::unbounded;
139     ///
140     /// let (s, r) = unbounded();
141     /// drop(r);
142     ///
143     /// if let Err(err) = s.send("foo") {
144     ///     assert_eq!(err.into_inner(), "foo");
145     /// }
146     /// ```
into_inner(self) -> T147     pub fn into_inner(self) -> T {
148         self.0
149     }
150 }
151 
152 impl<T> fmt::Debug for TrySendError<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result153     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
154         match *self {
155             TrySendError::Full(..) => "Full(..)".fmt(f),
156             TrySendError::Disconnected(..) => "Disconnected(..)".fmt(f),
157         }
158     }
159 }
160 
161 impl<T> fmt::Display for TrySendError<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result162     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
163         match *self {
164             TrySendError::Full(..) => "sending on a full channel".fmt(f),
165             TrySendError::Disconnected(..) => "sending on a disconnected channel".fmt(f),
166         }
167     }
168 }
169 
170 impl<T: Send> error::Error for TrySendError<T> {}
171 
172 impl<T> From<SendError<T>> for TrySendError<T> {
from(err: SendError<T>) -> TrySendError<T>173     fn from(err: SendError<T>) -> TrySendError<T> {
174         match err {
175             SendError(t) => TrySendError::Disconnected(t),
176         }
177     }
178 }
179 
180 impl<T> TrySendError<T> {
181     /// Unwraps the message.
182     ///
183     /// # Examples
184     ///
185     /// ```
186     /// use crossbeam_channel::bounded;
187     ///
188     /// let (s, r) = bounded(0);
189     ///
190     /// if let Err(err) = s.try_send("foo") {
191     ///     assert_eq!(err.into_inner(), "foo");
192     /// }
193     /// ```
into_inner(self) -> T194     pub fn into_inner(self) -> T {
195         match self {
196             TrySendError::Full(v) => v,
197             TrySendError::Disconnected(v) => v,
198         }
199     }
200 
201     /// Returns `true` if the send operation failed because the channel is full.
is_full(&self) -> bool202     pub fn is_full(&self) -> bool {
203         match self {
204             TrySendError::Full(_) => true,
205             _ => false,
206         }
207     }
208 
209     /// Returns `true` if the send operation failed because the channel is disconnected.
is_disconnected(&self) -> bool210     pub fn is_disconnected(&self) -> bool {
211         match self {
212             TrySendError::Disconnected(_) => true,
213             _ => false,
214         }
215     }
216 }
217 
218 impl<T> fmt::Debug for SendTimeoutError<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result219     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
220         "SendTimeoutError(..)".fmt(f)
221     }
222 }
223 
224 impl<T> fmt::Display for SendTimeoutError<T> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result225     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
226         match *self {
227             SendTimeoutError::Timeout(..) => "timed out waiting on send operation".fmt(f),
228             SendTimeoutError::Disconnected(..) => "sending on a disconnected channel".fmt(f),
229         }
230     }
231 }
232 
233 impl<T: Send> error::Error for SendTimeoutError<T> {}
234 
235 impl<T> From<SendError<T>> for SendTimeoutError<T> {
from(err: SendError<T>) -> SendTimeoutError<T>236     fn from(err: SendError<T>) -> SendTimeoutError<T> {
237         match err {
238             SendError(e) => SendTimeoutError::Disconnected(e),
239         }
240     }
241 }
242 
243 impl<T> SendTimeoutError<T> {
244     /// Unwraps the message.
245     ///
246     /// # Examples
247     ///
248     /// ```
249     /// use std::time::Duration;
250     /// use crossbeam_channel::unbounded;
251     ///
252     /// let (s, r) = unbounded();
253     ///
254     /// if let Err(err) = s.send_timeout("foo", Duration::from_secs(1)) {
255     ///     assert_eq!(err.into_inner(), "foo");
256     /// }
257     /// ```
into_inner(self) -> T258     pub fn into_inner(self) -> T {
259         match self {
260             SendTimeoutError::Timeout(v) => v,
261             SendTimeoutError::Disconnected(v) => v,
262         }
263     }
264 
265     /// Returns `true` if the send operation timed out.
is_timeout(&self) -> bool266     pub fn is_timeout(&self) -> bool {
267         match self {
268             SendTimeoutError::Timeout(_) => true,
269             _ => false,
270         }
271     }
272 
273     /// Returns `true` if the send operation failed because the channel is disconnected.
is_disconnected(&self) -> bool274     pub fn is_disconnected(&self) -> bool {
275         match self {
276             SendTimeoutError::Disconnected(_) => true,
277             _ => false,
278         }
279     }
280 }
281 
282 impl fmt::Display for RecvError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result283     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
284         "receiving on an empty and disconnected channel".fmt(f)
285     }
286 }
287 
288 impl error::Error for RecvError {}
289 
290 impl fmt::Display for TryRecvError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result291     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
292         match *self {
293             TryRecvError::Empty => "receiving on an empty channel".fmt(f),
294             TryRecvError::Disconnected => "receiving on an empty and disconnected channel".fmt(f),
295         }
296     }
297 }
298 
299 impl error::Error for TryRecvError {}
300 
301 impl From<RecvError> for TryRecvError {
from(err: RecvError) -> TryRecvError302     fn from(err: RecvError) -> TryRecvError {
303         match err {
304             RecvError => TryRecvError::Disconnected,
305         }
306     }
307 }
308 
309 impl TryRecvError {
310     /// Returns `true` if the receive operation failed because the channel is empty.
311     #[allow(clippy::trivially_copy_pass_by_ref)]
is_empty(&self) -> bool312     pub fn is_empty(&self) -> bool {
313         match self {
314             TryRecvError::Empty => true,
315             _ => false,
316         }
317     }
318 
319     /// Returns `true` if the receive operation failed because the channel is disconnected.
320     #[allow(clippy::trivially_copy_pass_by_ref)]
is_disconnected(&self) -> bool321     pub fn is_disconnected(&self) -> bool {
322         match self {
323             TryRecvError::Disconnected => true,
324             _ => false,
325         }
326     }
327 }
328 
329 impl fmt::Display for RecvTimeoutError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result330     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331         match *self {
332             RecvTimeoutError::Timeout => "timed out waiting on receive operation".fmt(f),
333             RecvTimeoutError::Disconnected => "channel is empty and disconnected".fmt(f),
334         }
335     }
336 }
337 
338 impl error::Error for RecvTimeoutError {}
339 
340 impl From<RecvError> for RecvTimeoutError {
from(err: RecvError) -> RecvTimeoutError341     fn from(err: RecvError) -> RecvTimeoutError {
342         match err {
343             RecvError => RecvTimeoutError::Disconnected,
344         }
345     }
346 }
347 
348 impl RecvTimeoutError {
349     /// Returns `true` if the receive operation timed out.
350     #[allow(clippy::trivially_copy_pass_by_ref)]
is_timeout(&self) -> bool351     pub fn is_timeout(&self) -> bool {
352         match self {
353             RecvTimeoutError::Timeout => true,
354             _ => false,
355         }
356     }
357 
358     /// Returns `true` if the receive operation failed because the channel is disconnected.
359     #[allow(clippy::trivially_copy_pass_by_ref)]
is_disconnected(&self) -> bool360     pub fn is_disconnected(&self) -> bool {
361         match self {
362             RecvTimeoutError::Disconnected => true,
363             _ => false,
364         }
365     }
366 }
367 
368 impl fmt::Display for TrySelectError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result369     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
370         "all operations in select would block".fmt(f)
371     }
372 }
373 
374 impl error::Error for TrySelectError {}
375 
376 impl fmt::Display for SelectTimeoutError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result377     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
378         "timed out waiting on select".fmt(f)
379     }
380 }
381 
382 impl error::Error for SelectTimeoutError {}
383