use std::error::Error;
#[derive(Debug, thiserror::Error)]
pub enum StreamError<SourceErr, SinkErr>
where
SourceErr: 'static + Error,
SinkErr: 'static + Error,
{
#[error("Source failed: {0}")]
SourceError(#[source] SourceErr),
#[error("Sink failed: {0}")]
SinkError(#[source] SinkErr),
}
pub use self::StreamError::*;
impl<SourceErr, SinkErr> StreamError<SourceErr, SinkErr>
where
SourceErr: 'static + Error,
SinkErr: 'static + Error,
{
pub fn is_source_error(&self) -> bool {
matches!(self, SourceError(_))
}
pub fn is_sink_error(&self) -> bool {
matches!(self, SinkError(_))
}
pub fn inner_into<Err>(self) -> Err
where
SourceErr: 'static + Error + Into<Err>,
SinkErr: 'static + Error + Into<Err>,
{
match self {
SourceError(err) => err.into(),
SinkError(err) => err.into(),
}
}
pub fn unwrap_source_error(self) -> SourceErr {
match self {
SourceError(err) => err,
SinkError(_) => panic!("this is a SinkError"),
}
}
pub fn unwrap_sink_error(self) -> SinkErr {
match self {
SourceError(_) => panic!("this is a SourceError"),
SinkError(err) => err,
}
}
pub fn reverse(self) -> StreamError<SinkErr, SourceErr> {
match self {
SourceError(e) => SinkError(e),
SinkError(e) => SourceError(e),
}
}
}
pub type StreamResult<T, E1, E2> = Result<T, StreamError<E1, E2>>;
pub trait SourceResult<T, E1, E2>
where
E1: 'static + Error,
E2: 'static + Error,
{
fn source_err(self) -> StreamResult<T, E1, E2>;
}
impl<T, E1, E2> SourceResult<T, E1, E2> for Result<T, E1>
where
E1: 'static + Error,
E2: 'static + Error,
{
fn source_err(self) -> StreamResult<T, E1, E2> {
self.map_err(SourceError)
}
}
pub trait SinkResult<T, E1, E2>
where
E1: 'static + Error,
E2: 'static + Error,
{
fn sink_err(self) -> StreamResult<T, E1, E2>;
}
impl<T, E1, E2> SinkResult<T, E1, E2> for Result<T, E2>
where
E1: 'static + Error,
E2: 'static + Error,
{
fn sink_err(self) -> StreamResult<T, E1, E2> {
self.map_err(SinkError)
}
}