use core::fmt;
#[derive(Clone, Copy, PartialEq, Eq)]
pub struct SendError<T>(pub T);
impl<T> SendError<T> {
#[inline]
pub fn into_inner(self) -> T {
self.0
}
}
impl<T: fmt::Debug> fmt::Debug for SendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("SendError").field("value", &self.0).finish()
}
}
impl<T> fmt::Display for SendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "sending on a closed channel")
}
}
impl<T: fmt::Debug> std::error::Error for SendError<T> {}
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum TrySendError<T> {
Full(T),
Disconnected(T),
}
impl<T> TrySendError<T> {
#[inline]
pub fn is_full(&self) -> bool {
matches!(self, TrySendError::Full(_))
}
#[inline]
pub fn is_disconnected(&self) -> bool {
matches!(self, TrySendError::Disconnected(_))
}
#[inline]
pub fn into_inner(self) -> T {
match self {
TrySendError::Full(v) | TrySendError::Disconnected(v) => v,
}
}
}
impl<T: fmt::Debug> fmt::Debug for TrySendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TrySendError::Full(v) => f.debug_tuple("Full").field(v).finish(),
TrySendError::Disconnected(v) => f.debug_tuple("Disconnected").field(v).finish(),
}
}
}
impl<T> fmt::Display for TrySendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TrySendError::Full(_) => write!(f, "sending on a full channel"),
TrySendError::Disconnected(_) => write!(f, "sending on a closed channel"),
}
}
}
impl<T: fmt::Debug> std::error::Error for TrySendError<T> {}
impl<T> From<SendError<T>> for TrySendError<T> {
fn from(err: SendError<T>) -> Self {
TrySendError::Disconnected(err.0)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct RecvError;
impl fmt::Display for RecvError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "receiving on a closed channel")
}
}
impl std::error::Error for RecvError {}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum TryRecvError {
Empty,
Disconnected,
}
impl TryRecvError {
#[inline]
pub fn is_empty(&self) -> bool {
matches!(self, TryRecvError::Empty)
}
#[inline]
pub fn is_disconnected(&self) -> bool {
matches!(self, TryRecvError::Disconnected)
}
}
impl fmt::Display for TryRecvError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TryRecvError::Empty => write!(f, "receiving on an empty channel"),
TryRecvError::Disconnected => write!(f, "receiving on a closed channel"),
}
}
}
impl std::error::Error for TryRecvError {}
impl From<RecvError> for TryRecvError {
fn from(_: RecvError) -> Self {
TryRecvError::Disconnected
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_send_error() {
let err = SendError(42);
assert_eq!(err.into_inner(), 42);
}
#[test]
fn test_send_error_display() {
let err: SendError<i32> = SendError(0);
assert_eq!(format!("{}", err), "sending on a closed channel");
}
#[test]
fn test_try_send_error_full() {
let err: TrySendError<i32> = TrySendError::Full(42);
assert!(err.is_full());
assert!(!err.is_disconnected());
assert_eq!(err.into_inner(), 42);
}
#[test]
fn test_try_send_error_disconnected() {
let err: TrySendError<i32> = TrySendError::Disconnected(42);
assert!(!err.is_full());
assert!(err.is_disconnected());
assert_eq!(err.into_inner(), 42);
}
#[test]
fn test_try_send_error_display() {
let full: TrySendError<i32> = TrySendError::Full(0);
assert_eq!(format!("{}", full), "sending on a full channel");
let disc: TrySendError<i32> = TrySendError::Disconnected(0);
assert_eq!(format!("{}", disc), "sending on a closed channel");
}
#[test]
fn test_recv_error() {
let err = RecvError;
assert_eq!(format!("{}", err), "receiving on a closed channel");
}
#[test]
fn test_try_recv_error_empty() {
let err = TryRecvError::Empty;
assert!(err.is_empty());
assert!(!err.is_disconnected());
}
#[test]
fn test_try_recv_error_disconnected() {
let err = TryRecvError::Disconnected;
assert!(!err.is_empty());
assert!(err.is_disconnected());
}
#[test]
fn test_try_recv_error_display() {
assert_eq!(
format!("{}", TryRecvError::Empty),
"receiving on an empty channel"
);
assert_eq!(
format!("{}", TryRecvError::Disconnected),
"receiving on a closed channel"
);
}
#[test]
fn test_send_error_into_try_send() {
let send_err = SendError(42);
let try_err: TrySendError<i32> = send_err.into();
assert!(try_err.is_disconnected());
assert_eq!(try_err.into_inner(), 42);
}
#[test]
fn test_recv_error_into_try_recv() {
let recv_err = RecvError;
let try_err: TryRecvError = recv_err.into();
assert!(try_err.is_disconnected());
}
}