1#![no_std]
3
4pub use self::wrapper::*;
5
6use core::error::Error;
7use core::fmt::Formatter;
8
9extern crate alloc;
10
11mod wrapper;
12
13pub trait ErrorDisplay {
17 fn display(&self) -> Display<'_>;
19}
20
21impl<T: Error> ErrorDisplay for T {
22 #[inline(always)]
23 fn display(&self) -> Display<'_> {
24 Display(self)
25 }
26}
27
28impl ErrorDisplay for dyn Error {
29 #[inline(always)]
30 fn display(&self) -> Display<'_> {
31 Display(self)
32 }
33}
34
35pub struct Display<'a>(&'a dyn Error);
37
38impl<'a> core::fmt::Display for Display<'a> {
39 fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
40 core::fmt::Display::fmt(self.0, f)?;
42
43 let mut next = self.0.source();
45
46 while let Some(e) = next {
47 f.write_str(" -> ")?;
48 core::fmt::Display::fmt(e, f)?;
49 next = e.source();
50 }
51
52 Ok(())
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use super::*;
59 use std::prelude::rust_2024::*;
60 use thiserror::Error;
61
62 extern crate std;
63
64 #[test]
65 fn single() {
66 let e = TestError::Single;
67
68 assert_eq!(e.display().to_string(), "an error without nested errors");
69 }
70
71 #[test]
72 fn nested() {
73 let e = std::io::Error::from(std::io::ErrorKind::NotFound);
74 let e = TestError::Nested(e);
75
76 assert_eq!(e.display().to_string(), "nested error -> entity not found");
77 }
78
79 #[test]
80 fn trait_object() {
81 let e: Box<dyn Error> = Box::new(TestError::Single);
82
83 assert_eq!(e.display().to_string(), "an error without nested errors");
84 }
85
86 #[derive(Debug, Error)]
87 enum TestError {
88 #[error("an error without nested errors")]
89 Single,
90
91 #[error("nested error")]
92 Nested(#[source] std::io::Error),
93 }
94}