use core::fmt;
macro_rules! impl_error_with_inner {
($name:ident, $inner_ty_param:ident, $inner_concrete_ty:ty, $($variant:ident($message:expr)),+ $(,)?) => {
impl<$inner_ty_param> $name<$inner_ty_param> {
#[inline]
pub fn into_inner(self) -> $inner_ty_param { match self {
$( $name::$variant(v) => v, )+
}
}
}
impl<$inner_ty_param> fmt::Display for $name<$inner_ty_param> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
$( $name::$variant(_) => f.write_str($message), )+
}
}
}
impl<$inner_ty_param: fmt::Debug> std::error::Error for $name<$inner_ty_param> {}
};
}
#[derive(PartialEq, Eq, Clone)]
pub enum TrySendError<T> {
Full(T),
Closed(T),
Sent(T),
}
impl<T> fmt::Debug for TrySendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TrySendError::Full(_) => write!(f, "TrySendError::Full(..)"),
TrySendError::Closed(_) => write!(f, "TrySendError::Closed(..)"),
TrySendError::Sent(_) => write!(f, "TrySendError::Sent(..)"),
}
}
}
macro_rules! impl_error_for_enum_with_inner {
(
$enum_name:ident < $generic_param:ident >, // e.g., TrySendError<T>
$($variant:ident ( $message:expr ) ),+ $(,)?
) => {
impl<$generic_param> $enum_name<$generic_param> {
#[inline]
pub fn into_inner(self) -> $generic_param {
match self {
$( $enum_name::$variant(v) => v, )+
}
}
}
impl<$generic_param> fmt::Display for $enum_name<$generic_param> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
$( $enum_name::$variant(_) => f.write_str($message), )+
}
}
}
impl<$generic_param: fmt::Debug> std::error::Error for $enum_name<$generic_param> {}
};
}
impl_error_for_enum_with_inner!(
TrySendError<T>, Full("channel full"),
Closed("channel closed"),
Sent("channel already sent a value")
);
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum SendError {
Closed,
Sent,
}
impl std::error::Error for SendError {}
impl fmt::Display for SendError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SendError::Closed => write!(f, "channel closed"),
SendError::Sent => write!(f, "channel already sent a value"),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum TryRecvError {
Empty,
Disconnected,
}
impl std::error::Error for TryRecvError {}
impl fmt::Display for TryRecvError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TryRecvError::Empty => write!(f, "channel empty"),
TryRecvError::Disconnected => write!(f, "channel disconnected (empty and all senders dropped)"),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum RecvError {
Disconnected,
}
impl std::error::Error for RecvError {}
impl fmt::Display for RecvError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RecvError::Disconnected => write!(f, "channel disconnected (empty and all senders dropped)"),
}
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub struct CloseError;
impl std::error::Error for CloseError {}
impl fmt::Display for CloseError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "channel is already closed")
}
}
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum RecvErrorTimeout {
Disconnected,
Timeout,
}
impl std::error::Error for RecvErrorTimeout {}
impl fmt::Display for RecvErrorTimeout {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
RecvErrorTimeout::Disconnected => write!(f, "channel disconnected"),
RecvErrorTimeout::Timeout => write!(f, "receive operation timed out"),
}
}
}