tinyflow-api 0.1.1

Core traits, types, and abstractions for Tinyflow streaming framework
Documentation
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(),
        })
    }
}