miette/eyreish/
into_diagnostic.rs1use std::{error::Error, fmt::Display};
2
3use crate::{Diagnostic, Report};
4
5#[derive(Debug)]
8pub(crate) struct DiagnosticError(pub(crate) Box<dyn std::error::Error + Send + Sync + 'static>);
9
10impl Display for DiagnosticError {
11 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
12 let msg = &self.0;
13 write!(f, "{msg}")
14 }
15}
16impl Error for DiagnosticError {
17 fn source(&self) -> Option<&(dyn Error + 'static)> {
18 self.0.source()
19 }
20}
21
22impl Diagnostic for DiagnosticError {}
23
24pub trait IntoDiagnostic<T, E> {
36 fn into_diagnostic(self) -> Result<T, Report>;
39}
40
41impl<T, E: std::error::Error + Send + Sync + 'static> IntoDiagnostic<T, E> for Result<T, E> {
42 fn into_diagnostic(self) -> Result<T, Report> {
43 self.map_err(|e| DiagnosticError(Box::new(e)).into())
44 }
45}
46
47#[cfg(test)]
48mod tests {
49 use std::io::{self, ErrorKind};
50
51 use super::*;
52
53 use crate::error::tests::TestError;
54
55 #[test]
56 fn diagnostic_error() {
57 let inner_error = io::Error::new(ErrorKind::Other, "halt and catch fire");
58 let outer_error: Result<(), _> = Err(TestError(inner_error));
59
60 let diagnostic_error = outer_error.into_diagnostic().unwrap_err();
61
62 assert_eq!(diagnostic_error.to_string(), "testing, testing...");
63 assert_eq!(
64 diagnostic_error.source().unwrap().to_string(),
65 "halt and catch fire"
66 );
67 }
68}