1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
use std::error::Error as StdError;
use std::fmt;
const DEFAULT_DEPTH_LIMIT: usize = 10;
pub trait StdErrorPP: StdError + Sized {
fn pp<'a>(&'a self) -> ErrorPP<'a> {
let err: &'a dyn StdError = self;
ErrorPP { err, depth_limit: DEFAULT_DEPTH_LIMIT }
}
}
impl<E> StdErrorPP for E where E: StdError + Sized {}
#[derive(Debug, Clone, Copy)]
pub struct ErrorPP<'a> {
err: &'a dyn StdError,
depth_limit: usize,
}
impl ErrorPP<'_> {
pub fn depth_limit(self, depth_limit: usize) -> Self {
Self { depth_limit, ..self }
}
}
impl<'a> fmt::Display for ErrorPP<'a> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let mut depth_left = self.depth_limit;
let mut err = self.err;
write!(f, "{}", err)?;
while let Some(next) = err.source() {
if depth_left == 0 {
write!(f, " << ...")?;
} else {
depth_left -= 1;
err = next;
write!(f, " << {}", err)?;
}
}
Ok(())
}
}