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