mm1_common/errors/
chain.rs1use std::error::Error as StdError;
2use std::fmt;
3
4use crate::types::AnyError;
5
6pub trait ExactTypeDisplayChainExt {
7 fn as_display_chain(&self) -> impl fmt::Display + fmt::Debug;
8}
9
10pub trait StdErrorDisplayChainExt: StdError + Sized {
11 fn as_display_chain(&self) -> impl fmt::Display + fmt::Debug {
12 let e: &dyn StdError = self;
13 D(e)
14 }
15}
16
17impl<E> StdErrorDisplayChainExt for E where E: StdError {}
18
19impl<T> ExactTypeDisplayChainExt for T
20where
21 for<'a> D<&'a T>: fmt::Display + fmt::Debug,
22{
23 fn as_display_chain(&self) -> impl fmt::Display + fmt::Debug {
24 D(self)
25 }
26}
27
28struct D<T>(T);
29
30impl fmt::Display for D<&dyn StdError> {
31 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
32 let mut e = self.0;
33 write!(f, "{}", e)?;
34 while let Some(source) = e.source() {
35 write!(f, " << {}", source)?;
36 e = source;
37 }
38 Ok(())
39 }
40}
41impl fmt::Debug for D<&dyn StdError> {
42 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43 fmt::Display::fmt(self, f)
44 }
45}
46
47impl fmt::Display for D<&AnyError> {
48 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
49 let mut chain = self.0.chain();
50 if let Some(e) = chain.next() {
51 write!(f, "{}", e)?;
52 }
53 for source in chain {
54 write!(f, "<< {}", source)?;
55 }
56
57 Ok(())
58 }
59}
60
61impl fmt::Debug for D<&AnyError> {
62 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63 fmt::Display::fmt(self, f)
64 }
65}