1#[doc(hidden)]
102#[macro_export]
103macro_rules! error_type_as_item {
104 ($i:item) => {$i};
105}
106
107#[doc(hidden)]
108#[macro_export]
109macro_rules! error_type_var_body_emit {
110 (
114 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident
115 ) => {
116 };
118
119 (
123 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
124 disp ()
125 $($tail:tt)*
126 ) => {
127 impl<'a> $edi_tr for (&'a $err_name, &'a $var_ty) {
128 fn error_fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> {
129 ::std::fmt::Display::fmt(self.1, fmt)
130 }
131 }
132
133 error_type_var_body_emit! {
134 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr $($tail)*
135 }
136 };
137
138 (
142 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
143 disp (($disp_arg:ident, $disp_fmt:ident) $disp_expr:expr)
144 $($tail:tt)*
145 ) => {
146 impl<'a> $edi_tr for (&'a $err_name, &'a $var_ty) {
147 fn error_fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> {
148 let $disp_arg = self.1;
149 let $disp_fmt = fmt;
150 $disp_expr
151 }
152 }
153
154 error_type_var_body_emit! {
155 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr $($tail)*
156 }
157 };
158
159 (
163 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
164 desc ()
165 $($tail:tt)*
166 ) => {
167 impl<'a> $ede_tr<'a> for (&'a $err_name, &'a $var_ty) {
168 fn error_desc(&self) -> &'a str {
169 ::std::error::Error::description(self.1)
170 }
171 }
172
173 error_type_var_body_emit! {
174 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr $($tail)*
175 }
176 };
177
178 (
182 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
183 desc (($desc_arg:ident) $desc_expr:expr)
184 $($tail:tt)*
185 ) => {
186 impl<'a> $ede_tr<'a> for (&'a $err_name, &'a $var_ty) {
187 fn error_desc(&self) -> &'a str {
188 let $desc_arg = self.1;
189 $desc_expr
190 }
191 }
192
193 error_type_var_body_emit! {
194 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr $($tail)*
195 }
196 };
197
198 (
202 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
203 cause ()
204 $($tail:tt)*
205 ) => {
206 impl<'a> $ec_tr<'a> for (&'a $err_name, &'a $var_ty) {
207 fn error_cause(&self) -> ::std::option::Option<&'a ::std::error::Error> {
208 None
209 }
210 }
211
212 error_type_var_body_emit! {
213 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr $($tail)*
214 }
215 };
216
217 (
221 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
222 cause (($cl_arg:ident) $cl_expr:expr)
223 $($tail:tt)*
224 ) => {
225 impl<'a> $ec_tr<'a> for (&'a $err_name, &'a $var_ty) {
226 fn error_cause(&self) -> ::std::option::Option<&'a ::std::error::Error> {
227 let $cl_arg = self.1;
228 $cl_expr
229 }
230 }
231
232 error_type_var_body_emit! {
233 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr $($tail)*
234 }
235 };
236
237 (
241 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
242 from ($(($cl_arg:ident: $cl_ty:ty) $cl_expr:expr);*)
243 $($tail:tt)*
244 ) => {
245 $(
246 impl ::std::convert::From<$cl_ty> for $err_name {
247 fn from($cl_arg: $cl_ty) -> $err_name {
248 $err_name::$var_name($cl_expr)
249 }
250 }
251 )*
252
253 error_type_var_body_emit! {
254 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr $($tail)*
255 }
256 };
257}
258
259#[doc(hidden)]
260#[macro_export]
261macro_rules! error_type_var_body {
262 (
266 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
267 $disp:tt, $desc:tt, $cause:tt, $from:tt; {}
268 ) => {
269 error_type_var_body_emit! {
270 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr,
271 disp $disp, desc $desc, cause $cause, from $from
272 }
273 };
274
275 (
279 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
280 $disp:tt, $desc:tt, $cause:tt, $from:tt; {
281 disp ($cl_arg:ident, $cl_fmt:ident) $cl_body:expr;
282 $($tail:tt)*
283 }
284 ) => {
285 error_type_var_body! {
286 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr,
287 (($cl_arg, $cl_fmt) $cl_body), $desc, $cause, $from;
288 {$($tail)*}
289 }
290 };
291
292 (
296 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
297 $disp:tt, $desc:tt, $cause:tt, $from:tt; {
298 desc ($cl_arg:ident) $cl_body:expr;
299 $($tail:tt)*
300 }
301 ) => {
302 error_type_var_body! {
303 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr,
304 $disp, (($cl_arg) $cl_body), $cause, $from;
305 {$($tail)*}
306 }
307 };
308
309 (
313 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
314 $disp:tt, $desc:tt, $cause:tt, $from:tt; {
315 cause ($cl_arg:ident) $cl_body:expr;
316 $($tail:tt)*
317 }
318 ) => {
319 error_type_var_body! {
320 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr,
321 $disp, $desc, (($cl_arg) $cl_body), $from;
322 {$($tail)*}
323 }
324 };
325
326 (
330 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
331 $disp:tt, $desc:tt, $cause:tt, $from:tt; {
332 cause;
333 $($tail:tt)*
334 }
335 ) => {
336 error_type_var_body! {
337 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr,
338 $disp, $desc, ((e) ::std::error::Error::cause(e)), $from;
339 {$($tail)*}
340 }
341 };
342
343 (
347 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
348 $disp:tt, $desc:tt, $cause:tt, (); {
349 from ($cl_arg:ident: $cl_ty:ty) $cl_body:expr;
350 $($tail:tt)*
351 }
352 ) => {
353 error_type_var_body! {
354 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr,
355 $disp, $desc, $cause, (($cl_arg: $cl_ty) $cl_body);
356 {$($tail)*}
357 }
358 };
359
360 (
364 $err_name:ident, $var_name:ident, $var_ty:ty, $edi_tr:ident, $ede_tr:ident, $ec_tr:ident,
365 $disp:tt, $desc:tt, $cause:tt, ($($from:tt)*); {
366 from ($cl_arg:ident: $cl_ty:ty) $cl_body:expr;
367 $($tail:tt)*
368 }
369 ) => {
370 error_type_var_body! {
371 $err_name, $var_name, $var_ty, $edi_tr, $ede_tr, $ec_tr,
372 $disp, $desc, $cause, (($cl_arg: $cl_ty) $cl_body; $($from)*);
373 {$($tail)*}
374 }
375 };
376}
377
378#[doc(hidden)]
379#[macro_export]
380macro_rules! error_type_impl {
381 (
382 $(#[$($derive_tts:tt)*])*
383 enum $err_name:ident {
384 $($var_name:ident($var_ty:ty) $var_body:tt),+
385 $(,)*
386 }
387 ) => {
388 $(
389 impl ::std::convert::From<$var_ty> for $err_name {
390 fn from(value: $var_ty) -> $err_name {
391 $err_name::$var_name(value)
392 }
393 }
394 )+
395
396 impl ::std::fmt::Display for $err_name {
397 fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error> {
398 match *self {
399 $(
400 $err_name::$var_name(ref v) => (self, v).error_fmt(fmt)
401 ),+
402 }
403 }
404 }
405
406 pub trait ErrorDisplay {
407 fn error_fmt(&self, &mut ::std::fmt::Formatter) -> ::std::result::Result<(), ::std::fmt::Error>;
408 }
409
410 pub trait ErrorDescription<'a> {
411 fn error_desc(&self) -> &'a str;
412 }
413
414 pub trait ErrorCause<'a> {
415 fn error_cause(&self) -> ::std::option::Option<&'a ::std::error::Error>;
416 }
417
418 impl ::std::error::Error for $err_name {
419 fn description(&self) -> &str {
420 use self::ErrorDescription;
421 match *self {
422 $(
423 $err_name::$var_name(ref v) => (self, v).error_desc()
424 ),+
425 }
426 }
427
428 fn cause(&self) -> ::std::option::Option<&::std::error::Error> {
429 use self::ErrorCause;
430 match *self {
431 $(
432 $err_name::$var_name(ref v) => (self, v).error_cause()
433 ),+
434 }
435 }
436 }
437
438 $(
439 error_type_var_body! {
440 $err_name, $var_name, $var_ty,
441 ErrorDisplay, ErrorDescription, ErrorCause,
442 (), (), (), ();
443 $var_body
444 }
445 )+
446 };
447}
448
449#[macro_export]
455macro_rules! error_type {
456 (
457 $(#[$($derive_tts:tt)*])*
458 pub enum $err_name:ident {
459 $($var_name:ident($var_ty:ty) $var_body:tt),+
460 $(,)*
461 }
462 ) => {
463 error_type_as_item! {
464 $(#[$($derive_tts)*])*
465 pub enum $err_name {
466 $($var_name($var_ty)),+
467 }
468 }
469
470 error_type_impl! {
471 $(#[$($derive_tts)*])*
472 enum $err_name {
473 $($var_name($var_ty) $var_body),+
474 }
475 }
476 };
477
478 (
479 $(#[$($derive_tts:tt)*])*
480 enum $err_name:ident {
481 $($var_name:ident($var_ty:ty) $var_body:tt),+
482 $(,)*
483 }
484 ) => {
485 error_type_as_item! {
486 $(#[$($derive_tts)*])*
487 enum $err_name {
488 $($var_name($var_ty)),+
489 }
490 }
491
492 error_type_impl! {
493 $(#[$($derive_tts)*])*
494 enum $err_name {
495 $($var_name($var_ty) $var_body),+
496 }
497 }
498 };
499}