diff --git a/src/mpsc.rs b/src/mpsc.rs index be467b7..7bda5ad 100644 --- a/src/mpsc.rs +++ b/src/mpsc.rs @@ -20,7 +20,6 @@ use core::{fmt, ops::Index, task::Poll}; /// Error returned by the [`Sender::try_send`] (and [`StaticSender::try_send`]) /// methods. -#[derive(Debug)] #[non_exhaustive] pub enum TrySendError { /// The data could not be sent on the channel because the channel is @@ -33,7 +32,6 @@ pub enum TrySendError { /// Error returned by [`Sender::send`] and [`Sender::send_ref`], if the /// [`Receiver`] half of the channel has been dropped. -#[derive(Debug)] pub struct Closed(T); #[derive(Debug)] @@ -67,7 +65,31 @@ struct SendRefInner<'a, T, N: Notify> { struct NotifyRx<'a, N: Notify>(&'a WaitCell); struct NotifyTx<'a, N: Notify + Unpin>(&'a WaitQueue); -// ==== impl TrySendError === +// === impl Closed === + +impl Closed { + /// Unwraps the inner `T` value held by this error. + /// + /// This method allows recovering the original message when sending to a + /// channel has failed. + pub fn into_inner(self) -> T { + self.0 + } +} + +impl fmt::Debug for Closed { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("Closed(..)") + } +} + +impl fmt::Display for Closed { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("channel closed") + } +} + +// === impl TrySendError === impl TrySendError { fn with_value(self, value: T) -> TrySendError { @@ -78,7 +100,54 @@ impl TrySendError { } } +impl TrySendError { + /// Returns `true` if this error was returned because the channel was at + /// capacity. + pub fn is_full(&self) -> bool { + matches!(self, Self::Full(_)) + } + + /// Returns `true` if this error was returned because the channel has closed + /// (e.g. the `Receiver` end has been dropped). + /// + /// If this returns `true`, no future `try_send` or `send` operation on this + /// channel will succeed. + pub fn is_closed(&self) -> bool { + matches!(self, Self::Full(_)) + } + + /// Unwraps the inner `T` value held by this error. + /// + /// This method allows recovering the original message when sending to a + /// channel has failed. + pub fn into_inner(self) -> T { + match self { + Self::Full(val) => val, + Self::Closed(val) => val, + } + } +} + +impl fmt::Debug for TrySendError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match self { + Self::Full(_) => "TrySendError::Full(..)", + Self::Closed(_) => "TrySendError::Closed(..)", + }) + } +} + +impl fmt::Display for TrySendError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match self { + Self::Full(_) => "no available capacity", + Self::Closed(_) => "channel closed", + }) + } +} + // ==== impl Inner ==== + impl ChannelCore { #[cfg(not(loom))] const fn new(capacity: usize) -> Self {