ts_error_stack/
lib.rs

1//! Simple error stacks for better reporting. Adapted from the unstable std `::std::error::Report`
2
3#![no_std]
4
5extern crate alloc;
6
7use core::{error::Error, fmt};
8
9use alloc::boxed::Box;
10
11/// An error report that prints an error and its sources.
12pub struct Report<E = Box<dyn Error>>(E);
13
14impl<E> Report<E>
15where
16    Self: From<E>,
17{
18    /// Creates a new `Report` from an input error.
19    pub fn new(error: E) -> Self {
20        Self::from(error)
21    }
22}
23
24impl<E> From<E> for Report<E>
25where
26    E: Error,
27{
28    fn from(error: E) -> Self {
29        Self(error)
30    }
31}
32
33// Debug links to display for when the report is returned from `main()`
34impl<E> fmt::Debug for Report<E>
35where
36    Self: fmt::Display,
37{
38    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
39        fmt::Display::fmt(self, f)
40    }
41}
42
43impl<E> fmt::Display for Report<E>
44where
45    E: Error,
46{
47    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
48        let mut error: &dyn Error = &self.0;
49
50        write!(f, "{error}")?;
51
52        if error.source().is_some() {
53            write!(f, "\n\nCaused by:")?;
54
55            let mut index = 0;
56            while let Some(cause) = error.source() {
57                write!(f, "\n{index: >4}: {cause}")?;
58                error = cause;
59                index += 1;
60            }
61        }
62
63        Ok(())
64    }
65}