miette/eyreish/
into_diagnostic.rs

1use thiserror::Error;
2
3use 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)]
9pub(crate) struct DiagnosticError(pub(crate) Box<dyn std::error::Error + Send + Sync + 'static>);
10impl Diagnostic for DiagnosticError {}
11
12/**
13Convenience 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
18Calling 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
20inaccessible. If you have a type implementing [`Diagnostic`] consider simply returning it or using
21[`Into`] or the [`Try`](std::ops::Try) operator (`?`).
22*/
23pub trait IntoDiagnostic<T, E> {
24    /// Converts [`Result`] types that return regular [`std::error::Error`]s
25    /// into a [`Result`] that returns a [`Diagnostic`].
26    fn into_diagnostic(self) -> Result<T, Report>;
27}
28
29impl<T, E: std::error::Error + Send + Sync + 'static> IntoDiagnostic<T, E> for Result<T, E> {
30    fn into_diagnostic(self) -> Result<T, Report> {
31        self.map_err(|e| DiagnosticError(Box::new(e)).into())
32    }
33}