1 use core::fmt::{self, Debug, Display};
2 
3 use std::error::Error as StdError;
4 
5 use crate::{Diagnostic, LabeledSpan, Report, SourceCode};
6 
7 use crate as miette;
8 
9 #[repr(transparent)]
10 pub(crate) struct DisplayError<M>(pub(crate) M);
11 
12 #[repr(transparent)]
13 pub(crate) struct MessageError<M>(pub(crate) M);
14 
15 pub(crate) struct NoneError;
16 
17 impl<M> Debug for DisplayError<M>
18 where
19     M: Display,
20 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result21     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
22         Display::fmt(&self.0, f)
23     }
24 }
25 
26 impl<M> Display for DisplayError<M>
27 where
28     M: Display,
29 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result30     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31         Display::fmt(&self.0, f)
32     }
33 }
34 
35 impl<M> StdError for DisplayError<M> where M: Display + 'static {}
36 impl<M> Diagnostic for DisplayError<M> where M: Display + 'static {}
37 
38 impl<M> Debug for MessageError<M>
39 where
40     M: Display + Debug,
41 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result42     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
43         Debug::fmt(&self.0, f)
44     }
45 }
46 
47 impl<M> Display for MessageError<M>
48 where
49     M: Display + Debug,
50 {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result51     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
52         Display::fmt(&self.0, f)
53     }
54 }
55 
56 impl<M> StdError for MessageError<M> where M: Display + Debug + 'static {}
57 impl<M> Diagnostic for MessageError<M> where M: Display + Debug + 'static {}
58 
59 impl Debug for NoneError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result60     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61         Debug::fmt("Option was None", f)
62     }
63 }
64 
65 impl Display for NoneError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result66     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
67         Display::fmt("Option was None", f)
68     }
69 }
70 
71 impl StdError for NoneError {}
72 impl Diagnostic for NoneError {}
73 
74 #[repr(transparent)]
75 pub(crate) struct BoxedError(pub(crate) Box<dyn Diagnostic + Send + Sync>);
76 
77 impl Diagnostic for BoxedError {
code<'a>(&'a self) -> Option<Box<dyn Display + 'a>>78     fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
79         self.0.code()
80     }
81 
severity(&self) -> Option<miette::Severity>82     fn severity(&self) -> Option<miette::Severity> {
83         self.0.severity()
84     }
85 
help<'a>(&'a self) -> Option<Box<dyn Display + 'a>>86     fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
87         self.0.help()
88     }
89 
url<'a>(&'a self) -> Option<Box<dyn Display + 'a>>90     fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
91         self.0.url()
92     }
93 
labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>>94     fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> {
95         self.0.labels()
96     }
97 
source_code(&self) -> Option<&dyn miette::SourceCode>98     fn source_code(&self) -> Option<&dyn miette::SourceCode> {
99         self.0.source_code()
100     }
101 
related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>>102     fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
103         self.0.related()
104     }
105 
diagnostic_source(&self) -> Option<&dyn Diagnostic>106     fn diagnostic_source(&self) -> Option<&dyn Diagnostic> {
107         self.0.diagnostic_source()
108     }
109 }
110 
111 impl Debug for BoxedError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result112     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113         Debug::fmt(&self.0, f)
114     }
115 }
116 
117 impl Display for BoxedError {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result118     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
119         Display::fmt(&self.0, f)
120     }
121 }
122 
123 impl StdError for BoxedError {
source(&self) -> Option<&(dyn StdError + 'static)>124     fn source(&self) -> Option<&(dyn StdError + 'static)> {
125         self.0.source()
126     }
127 
description(&self) -> &str128     fn description(&self) -> &str {
129         #[allow(deprecated)]
130         self.0.description()
131     }
132 
cause(&self) -> Option<&dyn StdError>133     fn cause(&self) -> Option<&dyn StdError> {
134         #[allow(deprecated)]
135         self.0.cause()
136     }
137 }
138 
139 pub(crate) struct WithSourceCode<E, C> {
140     pub(crate) error: E,
141     pub(crate) source_code: C,
142 }
143 
144 impl<E: Diagnostic, C: SourceCode> Diagnostic for WithSourceCode<E, C> {
code<'a>(&'a self) -> Option<Box<dyn Display + 'a>>145     fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
146         self.error.code()
147     }
148 
severity(&self) -> Option<miette::Severity>149     fn severity(&self) -> Option<miette::Severity> {
150         self.error.severity()
151     }
152 
help<'a>(&'a self) -> Option<Box<dyn Display + 'a>>153     fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
154         self.error.help()
155     }
156 
url<'a>(&'a self) -> Option<Box<dyn Display + 'a>>157     fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
158         self.error.url()
159     }
160 
labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>>161     fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> {
162         self.error.labels()
163     }
164 
source_code(&self) -> Option<&dyn miette::SourceCode>165     fn source_code(&self) -> Option<&dyn miette::SourceCode> {
166         Some(&self.source_code)
167     }
168 
related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>>169     fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
170         self.error.related()
171     }
172 
diagnostic_source(&self) -> Option<&dyn Diagnostic>173     fn diagnostic_source(&self) -> Option<&dyn Diagnostic> {
174         self.error.diagnostic_source()
175     }
176 }
177 
178 impl<C: SourceCode> Diagnostic for WithSourceCode<Report, C> {
code<'a>(&'a self) -> Option<Box<dyn Display + 'a>>179     fn code<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
180         self.error.code()
181     }
182 
severity(&self) -> Option<miette::Severity>183     fn severity(&self) -> Option<miette::Severity> {
184         self.error.severity()
185     }
186 
help<'a>(&'a self) -> Option<Box<dyn Display + 'a>>187     fn help<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
188         self.error.help()
189     }
190 
url<'a>(&'a self) -> Option<Box<dyn Display + 'a>>191     fn url<'a>(&'a self) -> Option<Box<dyn Display + 'a>> {
192         self.error.url()
193     }
194 
labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>>195     fn labels<'a>(&'a self) -> Option<Box<dyn Iterator<Item = LabeledSpan> + 'a>> {
196         self.error.labels()
197     }
198 
source_code(&self) -> Option<&dyn miette::SourceCode>199     fn source_code(&self) -> Option<&dyn miette::SourceCode> {
200         Some(&self.source_code)
201     }
202 
related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>>203     fn related<'a>(&'a self) -> Option<Box<dyn Iterator<Item = &'a dyn Diagnostic> + 'a>> {
204         self.error.related()
205     }
206 
diagnostic_source(&self) -> Option<&dyn Diagnostic>207     fn diagnostic_source(&self) -> Option<&dyn Diagnostic> {
208         self.error.diagnostic_source()
209     }
210 }
211 
212 impl<E: Debug, C> Debug for WithSourceCode<E, C> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result213     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
214         Debug::fmt(&self.error, f)
215     }
216 }
217 
218 impl<E: Display, C> Display for WithSourceCode<E, C> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result219     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
220         Display::fmt(&self.error, f)
221     }
222 }
223 
224 impl<E: StdError, C> StdError for WithSourceCode<E, C> {
source(&self) -> Option<&(dyn StdError + 'static)>225     fn source(&self) -> Option<&(dyn StdError + 'static)> {
226         self.error.source()
227     }
228 }
229 
230 impl<C> StdError for WithSourceCode<Report, C> {
source(&self) -> Option<&(dyn StdError + 'static)>231     fn source(&self) -> Option<&(dyn StdError + 'static)> {
232         self.error.source()
233     }
234 }
235