1 use std::fmt;
2 
3 /// An error encountered while working with structured data.
4 #[derive(Debug)]
5 pub struct Error {
6     inner: Inner,
7 }
8 
9 #[derive(Debug)]
10 enum Inner {
11     #[cfg(feature = "std")]
12     Boxed(std_support::BoxedError),
13     Msg(&'static str),
14     Fmt,
15 }
16 
17 impl Error {
18     /// Create an error from a message.
msg(msg: &'static str) -> Self19     pub fn msg(msg: &'static str) -> Self {
20         Error {
21             inner: Inner::Msg(msg),
22         }
23     }
24 }
25 
26 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result27     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
28         use self::Inner::*;
29         match &self.inner {
30             #[cfg(feature = "std")]
31             &Boxed(ref err) => err.fmt(f),
32             &Msg(ref msg) => msg.fmt(f),
33             &Fmt => fmt::Error.fmt(f),
34         }
35     }
36 }
37 
38 impl From<fmt::Error> for Error {
from(_: fmt::Error) -> Self39     fn from(_: fmt::Error) -> Self {
40         Error { inner: Inner::Fmt }
41     }
42 }
43 
44 #[cfg(feature = "std")]
45 mod std_support {
46     use super::*;
47     use std::{error, io};
48 
49     pub(super) type BoxedError = Box<dyn error::Error + Send + Sync>;
50 
51     impl Error {
52         /// Create an error from a standard error type.
boxed<E>(err: E) -> Self where E: Into<BoxedError>,53         pub fn boxed<E>(err: E) -> Self
54         where
55             E: Into<BoxedError>,
56         {
57             Error {
58                 inner: Inner::Boxed(err.into()),
59             }
60         }
61     }
62 
63     impl error::Error for Error {}
64 
65     impl From<io::Error> for Error {
from(err: io::Error) -> Self66         fn from(err: io::Error) -> Self {
67             Error::boxed(err)
68         }
69     }
70 }
71