diff --git a/src/lib.rs b/src/lib.rs index 4c1ca43..2e9ef49 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,9 +3,11 @@ pub use error::*; pub use protocol::*; pub use reporter::*; +pub use utils::*; mod chain; mod error; mod protocol; mod reporter; mod source_impls; +mod utils; diff --git a/src/utils.rs b/src/utils.rs new file mode 100644 index 0000000..8320eb7 --- /dev/null +++ b/src/utils.rs @@ -0,0 +1,39 @@ +use std::fmt; + +use thiserror::Error; + +use crate::Diagnostic; + +/// Convenience [Diagnostic] that can be used as an "anonymous" wrapper for +/// Errors. This is intended to be paired with [IntoDiagnostic]. +#[derive(Debug, Error)] +#[error("{}", self.error)] +pub struct DiagnosticError { + #[source] + pub error: Box, + pub code: String, +} + +impl Diagnostic for DiagnosticError { + fn code<'a>(&'a self) -> Box { + Box::new(&self.code) + } +} + +/// Utility Result type for functions that return boxed [Diagnostic]s. +pub type DiagnosticResult = Result>; + +pub trait IntoDiagnostic { + /// Converts [Result]-like types that return regular errors into a + /// `Result` that returns a [Diagnostic]. + fn into_diagnostic(self, code: &(dyn fmt::Display)) -> Result; +} + +impl IntoDiagnostic for Result { + fn into_diagnostic(self, code: &(dyn fmt::Display)) -> Result { + self.map_err(|e| DiagnosticError { + error: Box::new(e), + code: format!("{}", code), + }) + } +}