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