use std::error::Error;
use std::fmt;
#[derive(Debug)]
pub enum StreamError {
TaskFailed { task_id: u32, reason: String },
ChannelClosed { reason: String },
InnerError { reason: String },
JsonParseError { reason: String },
}
pub type StreamResult<T> = Result<T, StreamError>;
pub fn task_failed(task_id: u32, reason: impl Into<String>) -> StreamError {
StreamError::TaskFailed {
task_id,
reason: reason.into(),
}
}
pub fn remap_task_failed(err: StreamError, task_id: u32) -> StreamError {
match err {
StreamError::TaskFailed { reason, .. } => StreamError::TaskFailed { task_id, reason },
other => other,
}
}
impl fmt::Display for StreamError {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
StreamError::TaskFailed { task_id, reason } => {
write!(f, "Task {} failed: {}", task_id, reason)
}
StreamError::ChannelClosed { reason } => write!(f, "Channel closed: {}", reason),
StreamError::InnerError { reason } => write!(f, "Inner error: {}", reason),
StreamError::JsonParseError { reason } => write!(f, "Json parse error: {}", reason),
}
}
}
impl Error for StreamError {}
impl From<serde_json::Error> for StreamError {
fn from(e: serde_json::Error) -> Self {
StreamError::TaskFailed {
task_id: 0,
reason: format!("config parse: {e}"),
}
}
}
pub trait OptionStreamExt<T> {
fn ok_or_task_failed(self, task_id: u32, reason: impl Into<String>) -> StreamResult<T>;
}
impl<T> OptionStreamExt<T> for Option<T> {
fn ok_or_task_failed(self, task_id: u32, reason: impl Into<String>) -> StreamResult<T> {
self.ok_or_else(|| StreamError::TaskFailed {
task_id,
reason: reason.into(),
})
}
}