use sift_error::prelude::{Error as SiftError, ErrorKind};
use std::fmt;
#[derive(Debug)]
pub struct SendError<T>(pub T);
impl<T> SendError<T> {
pub fn into_inner(self) -> T {
self.0
}
}
impl<T> fmt::Display for SendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "channel closed: failed to send message")
}
}
impl<T: fmt::Debug> std::error::Error for SendError<T> {}
#[derive(Debug)]
pub enum TrySendError<T> {
Closed(T),
Full(T),
}
impl<T> TrySendError<T> {
pub fn into_inner(self) -> T {
match self {
TrySendError::Closed(v) | TrySendError::Full(v) => v,
}
}
pub fn is_closed(&self) -> bool {
matches!(self, TrySendError::Closed(_))
}
pub fn is_full(&self) -> bool {
matches!(self, TrySendError::Full(_))
}
}
impl<T> fmt::Display for TrySendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TrySendError::Closed(_) => write!(f, "channel closed: failed to send message"),
TrySendError::Full(_) => write!(f, "channel full: failed to send message"),
}
}
}
impl<T: fmt::Debug> std::error::Error for TrySendError<T> {}
#[derive(Debug)]
pub enum SiftStreamSendError<T> {
EncodeError(SiftError),
ChannelClosed(T),
}
impl<T: fmt::Debug> fmt::Display for SiftStreamSendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SiftStreamSendError::EncodeError(e) => write!(f, "encode error: {e}"),
SiftStreamSendError::ChannelClosed(_) => {
write!(f, "channel closed: failed to send message")
}
}
}
}
impl<T: fmt::Debug> std::error::Error for SiftStreamSendError<T> {}
impl<T> SiftStreamSendError<T> {
pub(crate) fn encode_error(msg: &str) -> Self {
SiftStreamSendError::EncodeError(SiftError::new_msg(ErrorKind::EncodeMessageError, msg))
}
}
#[derive(Debug)]
pub enum SiftStreamTrySendError<T> {
EncodeError(SiftError),
Channel(TrySendError<T>),
}
impl<T: fmt::Debug> fmt::Display for SiftStreamTrySendError<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SiftStreamTrySendError::EncodeError(e) => write!(f, "encode error: {e}"),
SiftStreamTrySendError::Channel(e) => write!(f, "{e}"),
}
}
}
impl<T: fmt::Debug> std::error::Error for SiftStreamTrySendError<T> {}
impl<T> SiftStreamTrySendError<T> {
pub(crate) fn encode_error(msg: &str) -> Self {
SiftStreamTrySendError::EncodeError(SiftError::new_msg(ErrorKind::EncodeMessageError, msg))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn send_error_into_inner() {
let err = SendError(42u32);
assert_eq!(err.into_inner(), 42u32);
}
#[test]
fn send_error_display() {
let err = SendError("msg");
assert!(err.to_string().contains("channel closed"));
}
#[test]
fn send_error_is_error() {
fn assert_error<E: std::error::Error>(_: &E) {}
let err = SendError(0u8);
assert_error(&err);
}
#[test]
fn try_send_error_into_inner_closed() {
let err: TrySendError<u32> = TrySendError::Closed(7);
assert_eq!(err.into_inner(), 7);
}
#[test]
fn try_send_error_into_inner_full() {
let err: TrySendError<u32> = TrySendError::Full(9);
assert_eq!(err.into_inner(), 9);
}
#[test]
fn try_send_error_is_closed() {
assert!(TrySendError::<u8>::Closed(0).is_closed());
assert!(!TrySendError::<u8>::Full(0).is_closed());
}
#[test]
fn try_send_error_is_full() {
assert!(TrySendError::<u8>::Full(0).is_full());
assert!(!TrySendError::<u8>::Closed(0).is_full());
}
#[test]
fn try_send_error_display() {
assert!(
TrySendError::<u8>::Closed(0)
.to_string()
.contains("channel closed")
);
assert!(
TrySendError::<u8>::Full(0)
.to_string()
.contains("channel full")
);
}
#[test]
fn try_send_error_is_error() {
fn assert_error<E: std::error::Error>(_: &E) {}
let err = TrySendError::Closed(0u8);
assert_error(&err);
}
#[test]
fn try_send_error_debug() {
let closed = TrySendError::Closed(42u32);
let full = TrySendError::Full(42u32);
assert!(format!("{:?}", closed).contains("Closed"));
assert!(format!("{:?}", full).contains("Full"));
}
#[test]
fn sift_stream_send_error_encode_error_display() {
let err = SiftStreamSendError::<u32>::encode_error("bad encoding");
assert!(err.to_string().contains("encode error"));
}
#[test]
fn sift_stream_send_error_channel_closed_display() {
let err = SiftStreamSendError::ChannelClosed(42u32);
assert!(err.to_string().contains("channel closed"));
}
#[test]
fn sift_stream_send_error_is_error() {
fn assert_error<E: std::error::Error>(_: &E) {}
let err = SiftStreamSendError::ChannelClosed(0u8);
assert_error(&err);
}
#[test]
fn sift_stream_send_error_debug() {
let err = SiftStreamSendError::ChannelClosed(42u32);
assert!(format!("{:?}", err).contains("ChannelClosed"));
let err2 = SiftStreamSendError::<u32>::encode_error("oops");
assert!(format!("{:?}", err2).contains("EncodeError"));
}
#[test]
fn sift_stream_try_send_error_encode_error_display() {
let err = SiftStreamTrySendError::<u32>::encode_error("bad");
assert!(err.to_string().contains("encode error"));
}
#[test]
fn sift_stream_try_send_error_channel_full_display() {
let err = SiftStreamTrySendError::Channel(TrySendError::Full(42u32));
assert!(err.to_string().contains("channel full"));
}
#[test]
fn sift_stream_try_send_error_channel_closed_display() {
let err = SiftStreamTrySendError::Channel(TrySendError::Closed(42u32));
assert!(err.to_string().contains("channel closed"));
}
#[test]
fn sift_stream_try_send_error_is_error() {
fn assert_error<E: std::error::Error>(_: &E) {}
let err = SiftStreamTrySendError::Channel(TrySendError::Closed(0u8));
assert_error(&err);
}
#[test]
fn sift_stream_try_send_error_debug() {
let err = SiftStreamTrySendError::Channel(TrySendError::Full(42u32));
assert!(format!("{:?}", err).contains("Full"));
let err2 = SiftStreamTrySendError::<u32>::encode_error("oops");
assert!(format!("{:?}", err2).contains("EncodeError"));
}
}