53 lines
1.3 KiB
Rust
53 lines
1.3 KiB
Rust
//! Error handling niceties.
|
|
|
|
// Because who needs anyhow anyways.
|
|
|
|
/// Provide context for an existing error.
|
|
pub trait Context<T> {
|
|
fn context(self, fmt: std::fmt::Arguments<'_>) -> Result<T, CtxError>;
|
|
}
|
|
|
|
impl<T, E> Context<T> for std::result::Result<T, E>
|
|
where
|
|
E: std::error::Error + 'static,
|
|
{
|
|
fn context(self, fmt: std::fmt::Arguments<'_>) -> Result<T, CtxError> {
|
|
match self {
|
|
Ok(o) => Ok(o),
|
|
Err(e) => Err(CtxError {
|
|
context: fmt.to_string(),
|
|
inner: Box::new(e),
|
|
}),
|
|
}
|
|
}
|
|
}
|
|
|
|
/// An error with context attached.
|
|
///
|
|
/// The context is provided as format arguments, but will be constructed into a string if the value
|
|
/// is an error.
|
|
#[derive(Debug)]
|
|
pub struct CtxError {
|
|
context: String,
|
|
inner: Box<dyn std::error::Error>,
|
|
}
|
|
|
|
impl std::fmt::Display for CtxError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
f.write_str(self.context.as_str())
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for CtxError {
|
|
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
|
|
Some(self.inner.as_ref())
|
|
}
|
|
}
|
|
|
|
pub type Result<T, E = CtxError> = std::result::Result<T, E>;
|
|
|
|
pub fn ctx_os_error(args: std::fmt::Arguments<'_>) -> Result<(), CtxError> {
|
|
Err(std::io::Error::last_os_error()).context(args)
|
|
}
|
|
|