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
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use super::source::ErrorSource;
use super::tracer::ErrorMessageTracer;
use core::fmt::{Debug, Display, Formatter};
pub struct ErrorReport<Detail, Trace> {
pub detail: Detail,
pub trace: Trace,
}
impl<Detail, Trace> ErrorSource<Trace> for ErrorReport<Detail, Trace> {
type Source = Self;
type Detail = Detail;
fn error_details(source: Self::Source) -> (Self::Detail, Option<Trace>) {
(source.detail, Some(source.trace))
}
}
impl<Detail, Trace> ErrorReport<Detail, Trace> {
pub fn trace_from<E, Cont>(source: E::Source, cont: Cont) -> Self
where
Detail: Display,
E: ErrorSource<Trace>,
Trace: ErrorMessageTracer,
Cont: FnOnce(E::Detail) -> Detail,
{
let (detail1, m_trace1) = E::error_details(source);
let detail2 = cont(detail1);
match m_trace1 {
Some(trace1) => {
let trace2 = trace1.add_message(&detail2);
ErrorReport {
detail: detail2,
trace: trace2,
}
}
None => {
let trace2 = Trace::new_message(&detail2);
ErrorReport {
detail: detail2,
trace: trace2,
}
}
}
}
}
impl<Detail, Trace> Debug for ErrorReport<Detail, Trace>
where
Trace: Debug,
{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.trace.fmt(f)
}
}
impl<Detail, Trace> Display for ErrorReport<Detail, Trace>
where
Trace: Display,
{
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
self.trace.fmt(f)
}
}
#[cfg(feature = "std")]
impl<Detail, Trace> std::error::Error for ErrorReport<Detail, Trace>
where
Detail: Display,
Trace: Debug + Display,
Trace: ErrorMessageTracer,
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
self.trace.as_error()
}
}