1use std::{error, fmt, sync::Arc};
2
3use crate::{Backtrace, Error, ErrorDiagnostic, ResultKind, ResultType, repr::ErrorRepr};
4
5trait ErrorInformation: fmt::Display + fmt::Debug + 'static {
6 fn tp(&self) -> ResultType;
7
8 fn service(&self) -> Option<&'static str>;
9
10 fn signature(&self) -> &'static str;
11
12 fn backtrace(&self) -> Option<&Backtrace>;
13
14 fn source(&self) -> Option<&(dyn error::Error + 'static)>;
15}
16
17impl<E> ErrorInformation for ErrorRepr<E>
18where
19 E: ErrorDiagnostic,
20{
21 fn tp(&self) -> ResultType {
22 self.kind().tp()
23 }
24
25 fn service(&self) -> Option<&'static str> {
26 ErrorDiagnostic::service(self)
27 }
28
29 fn signature(&self) -> &'static str {
30 self.kind().signature()
31 }
32
33 fn backtrace(&self) -> Option<&Backtrace> {
34 ErrorDiagnostic::backtrace(self)
35 }
36
37 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
38 Some(&self.error)
39 }
40}
41
42#[derive(Clone)]
43pub struct ErrorInfo {
44 inner: Arc<dyn ErrorInformation>,
45}
46
47impl AsRef<dyn ErrorInformation> for ErrorInfo {
48 fn as_ref(&self) -> &dyn ErrorInformation {
49 self.inner.as_ref()
50 }
51}
52
53impl ErrorInfo {
54 pub fn tp(&self) -> ResultType {
55 self.inner.tp()
56 }
57
58 pub fn service(&self) -> Option<&'static str> {
59 self.inner.service()
60 }
61
62 pub fn signature(&self) -> &'static str {
63 self.inner.signature()
64 }
65
66 pub fn backtrace(&self) -> Option<&Backtrace> {
67 self.inner.backtrace()
68 }
69}
70
71impl<E> From<Error<E>> for ErrorInfo
72where
73 E: ErrorDiagnostic,
74{
75 fn from(err: Error<E>) -> Self {
76 Self { inner: err.inner }
77 }
78}
79
80impl<E> From<&Error<E>> for ErrorInfo
81where
82 E: ErrorDiagnostic,
83{
84 fn from(err: &Error<E>) -> Self {
85 Self {
86 inner: err.inner.clone(),
87 }
88 }
89}
90
91impl error::Error for ErrorInfo {
92 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
93 self.inner.source()
94 }
95}
96
97impl fmt::Debug for ErrorInfo {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 fmt::Debug::fmt(&self.inner, f)
100 }
101}
102
103impl fmt::Display for ErrorInfo {
104 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
105 fmt::Display::fmt(&self.inner, f)
106 }
107}
108
109#[derive(Copy, Clone, Debug, PartialEq, Eq)]
110pub struct ErrorInfoType(ResultType, &'static str);
111
112impl ResultKind for ErrorInfoType {
113 fn tp(&self) -> ResultType {
114 self.0
115 }
116
117 fn signature(&self) -> &'static str {
118 self.1
119 }
120}
121
122impl ErrorDiagnostic for ErrorInfo {
123 type Kind = ErrorInfoType;
124
125 fn kind(&self) -> ErrorInfoType {
126 ErrorInfoType(self.tp(), self.inner.signature())
127 }
128
129 fn service(&self) -> Option<&'static str> {
130 self.inner.service()
131 }
132
133 fn backtrace(&self) -> Option<&Backtrace> {
134 self.inner.backtrace()
135 }
136}