1 use thiserror::Error; 2 3 use crate::{Diagnostic, Report}; 4 5 /// Convenience [`Diagnostic`] that can be used as an "anonymous" wrapper for 6 /// Errors. This is intended to be paired with [`IntoDiagnostic`]. 7 #[derive(Debug, Error)] 8 #[error(transparent)] 9 struct DiagnosticError(Box<dyn std::error::Error + Send + Sync + 'static>); 10 impl Diagnostic for DiagnosticError {} 11 12 /** 13 Convenience trait that adds a [`.into_diagnostic()`](IntoDiagnostic::into_diagnostic) method that converts a type implementing 14 [`std::error::Error`] to a [`Result<T, Report>`]. 15 16 ## Warning 17 18 Calling this on a type implementing [`Diagnostic`] will reduce it to the common denominator of 19 [`std::error::Error`]. Meaning all extra information provided by [`Diagnostic`] will be 20 inaccessible. If you have a type implementing [`Diagnostic`] consider simply returning it or using 21 [`Into`] or the [`Try`](std::ops::Try) operator (`?`). 22 */ 23 pub trait IntoDiagnostic<T, E> { 24 /// Converts [`Result`] types that return regular [`std::error::Error`]s 25 /// into a [`Result`] that returns a [`Diagnostic`]. into_diagnostic(self) -> Result<T, Report>26 fn into_diagnostic(self) -> Result<T, Report>; 27 } 28 29 impl<T, E: std::error::Error + Send + Sync + 'static> IntoDiagnostic<T, E> for Result<T, E> { into_diagnostic(self) -> Result<T, Report>30 fn into_diagnostic(self) -> Result<T, Report> { 31 self.map_err(|e| DiagnosticError(Box::new(e)).into()) 32 } 33 } 34