hyperlit-base 0.1.0

A software documentation tool documentation embedded in source files - base crate
Documentation
use error_stack::{Context, Report};
use std::error::Error;
use std::fmt::{Debug, Display, Formatter};

pub struct HyperlitError(pub Report<HyperlitErrorContext>);

pub struct HyperlitErrorContext {
    pub context: Box<dyn Context>,
}

impl Debug for HyperlitError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        std::fmt::Debug::fmt(&self.0, f)
    }
}

impl HyperlitErrorContext {
    #[track_caller]
    pub fn new<T: Context>(context: T) -> HyperlitErrorContext {
        HyperlitErrorContext {
            context: Box::new(context),
        }
    }

    #[track_caller]
    pub fn from_string<T: Into<String>>(message: T) -> HyperlitErrorContext {
        HyperlitErrorContext {
            context: Box::new(GeneralError {
                message: message.into(),
            }),
        }
    }
}

pub struct BoxedErrorContext {
    pub error: BoxedError,
}

pub type BoxedError = Box<dyn Error + Send + Sync + 'static>;

impl BoxedErrorContext {
    #[track_caller]
    pub fn new(error: BoxedError) -> BoxedErrorContext {
        BoxedErrorContext { error }
    }
}

impl Display for BoxedErrorContext {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        std::fmt::Display::fmt(&self.error, f)
    }
}

impl Debug for BoxedErrorContext {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        std::fmt::Debug::fmt(&self.error, f)
    }
}

impl Error for BoxedErrorContext {}

impl HyperlitErrorContext {
    pub fn from_context<T: Context>(context: T) -> HyperlitErrorContext {
        HyperlitErrorContext {
            context: Box::new(context),
        }
    }
}

impl Display for HyperlitErrorContext {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        std::fmt::Display::fmt(&self.context, f)
    }
}

impl Debug for HyperlitErrorContext {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        std::fmt::Debug::fmt(&self.context, f)
    }
}

impl Error for HyperlitErrorContext {}

pub struct GeneralError {
    pub message: String,
}

impl Display for GeneralError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        std::fmt::Display::fmt(&self.message, f)
    }
}

impl Debug for GeneralError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        std::fmt::Debug::fmt(&self.message, f)
    }
}

impl Error for GeneralError {}

impl Display for HyperlitError {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        std::fmt::Display::fmt(&self.0, f)
    }
}

impl HyperlitError {
    #[track_caller]
    pub fn change_context<S: Into<String>>(self, message: S) -> Self {
        Self(
            self.0
                .change_context(HyperlitErrorContext::from_string(message.into())),
        )
    }
}

impl HyperlitError {
    #[track_caller]
    pub fn new<T: Context>(error: T) -> HyperlitError {
        HyperlitError(Report::new(HyperlitErrorContext::from_context(error)))
    }

    #[track_caller]
    pub fn from_string<T: Into<String>>(message: T) -> HyperlitError {
        HyperlitError(Report::new(HyperlitErrorContext::from_string(message)))
    }

    #[track_caller]
    pub fn from_boxed(error: BoxedError) -> HyperlitErrorContext {
        HyperlitErrorContext {
            context: Box::new(BoxedErrorContext::new(error)),
        }
    }
}

impl<T: Context> From<T> for HyperlitError {
    #[track_caller]
    fn from(error: T) -> Self {
        Self::new(error)
    }
}

#[macro_export]
macro_rules! bail {
    ($($args:tt)+) => {
        return Err($crate::err!($($args)+))
    }
}

#[macro_export]
macro_rules! err {
    ($($args:tt)+) => {
        $crate::error::HyperlitError::from_string(format!($($args)+))
    };
}