use std::fmt;
#[derive(Debug)]
pub struct ErrorWithContext {
context: String,
cause: Box<dyn std::error::Error + Send>,
}
pub type Result<T> = std::result::Result<T, ErrorWithContext>;
impl ErrorWithContext {
pub fn wrap<E: std::error::Error + Send + 'static>(
context: impl Into<String>,
cause: E,
) -> Self {
Self {
context: context.into(),
cause: Box::new(cause),
}
}
}
impl fmt::Display for ErrorWithContext {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}: {}", self.context, self.cause)?;
Ok(())
}
}
impl std::error::Error for ErrorWithContext {
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
Some(self.cause.as_ref())
}
}
pub trait ResultExt<T> {
fn error_context(self, context: impl Into<String>) -> Result<T>;
}
impl<T, E: std::error::Error + Send + 'static> ResultExt<T> for std::result::Result<T, E> {
fn error_context(self, context: impl Into<String>) -> Result<T> {
self.map_err(|error| ErrorWithContext::wrap(context, error))
}
}