1pub use test_try_macros::test_try;
4
5pub mod report {
6 use std::error::Error;
9 use std::fmt::Write;
10 use std::fmt::{self};
11 use std::sync::Arc;
12
13 pub struct Report {
15 error: Arc<dyn std::error::Error>,
16 }
17
18 impl<E: Error + 'static> From<E> for Report {
19 fn from(error: E) -> Self {
20 Report { error: Arc::new(error) }
21 }
22 }
23
24 impl fmt::Display for Report {
25 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
26 let error = &self.error;
27
28 write!(f, "{error}")?;
29
30 if let Some(cause) = error.source() {
31 write!(f, "\n\nCaused by:")?;
32
33 let multiple = cause.source().is_some();
34
35 for (ind, error) in Source::new(cause).enumerate() {
36 writeln!(f)?;
37 let mut indented = Indented { inner: f };
38 if multiple {
39 write!(indented, "{ind: >4}: {error}")?;
40 } else {
41 write!(indented, " {error}")?;
42 }
43 }
44 }
45
46 Ok(())
47 }
48 }
49
50 impl fmt::Debug for Report {
51 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52 fmt::Display::fmt(self, f)
53 }
54 }
55
56 #[derive(Clone, Debug)]
57 struct Source<'a> {
58 current: Option<&'a (dyn Error + 'static)>,
59 }
60
61 impl<'a> Source<'a> {
62 fn new(error: &'a (dyn Error + 'static)) -> Self {
63 Self { current: Some(error) }
64 }
65 }
66
67 impl<'a> Iterator for Source<'a> {
68 type Item = &'a (dyn Error + 'static);
69
70 fn next(&mut self) -> Option<Self::Item> {
71 let current = self.current;
72 self.current = self.current.and_then(Error::source);
73 current
74 }
75
76 fn size_hint(&self) -> (usize, Option<usize>) {
77 if self.current.is_some() { (1, None) } else { (0, Some(0)) }
78 }
79 }
80
81 impl std::iter::FusedIterator for Source<'_> {}
82
83 struct Indented<'a, D> {
84 inner: &'a mut D,
85 }
86
87 impl<T> Write for Indented<'_, T>
88 where
89 T: Write,
90 {
91 fn write_str(&mut self, s: &str) -> fmt::Result {
92 for (i, line) in s.split('\n').enumerate() {
93 if i > 0 {
94 self.inner.write_char('\n')?;
95 self.inner.write_str(" ")?;
96 }
97
98 self.inner.write_str(line)?;
99 }
100
101 Ok(())
102 }
103 }
104}