Skip to content

Commit

Permalink
feat(mpsc): add methods to errors
Browse files Browse the repository at this point in the history
Signed-off-by: Eliza Weisman <[email protected]>
  • Loading branch information
hawkw committed Mar 15, 2022
1 parent 1423186 commit d5bf3db
Showing 1 changed file with 72 additions and 3 deletions.
75 changes: 72 additions & 3 deletions src/mpsc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<T = ()> {
/// The data could not be sent on the channel because the channel is
Expand All @@ -33,7 +32,6 @@ pub enum TrySendError<T = ()> {

/// 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 = ()>(T);

#[derive(Debug)]
Expand Down Expand Up @@ -67,7 +65,31 @@ struct SendRefInner<'a, T, N: Notify> {
struct NotifyRx<'a, N: Notify>(&'a WaitCell<N>);
struct NotifyTx<'a, N: Notify + Unpin>(&'a WaitQueue<N>);

// ==== impl TrySendError ===
// === impl Closed ===

impl<T> Closed<T> {
/// 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<T> fmt::Debug for Closed<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("Closed(..)")
}
}

impl<T> fmt::Display for Closed<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("channel closed")
}
}

// === impl TrySendError ===

impl TrySendError {
fn with_value<T>(self, value: T) -> TrySendError<T> {
Expand All @@ -78,7 +100,54 @@ impl TrySendError {
}
}

impl<T> TrySendError<T> {
/// 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<T> fmt::Debug for TrySendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(match self {
Self::Full(_) => "TrySendError::Full(..)",
Self::Closed(_) => "TrySendError::Closed(..)",
})
}
}

impl<T> fmt::Display for TrySendError<T> {
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<N> ChannelCore<N> {
#[cfg(not(loom))]
const fn new(capacity: usize) -> Self {
Expand Down

0 comments on commit d5bf3db

Please sign in to comment.