1 | use crate::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. |
19 | pub fn msg(msg: &'static str) -> Self { |
20 | Error { |
21 | inner: Inner::Msg(msg), |
22 | } |
23 | } |
24 | |
25 | #[cfg (feature = "serde1" )] |
26 | pub(crate) fn try_boxed(msg: &'static str, e: impl fmt::Display) -> Self { |
27 | #[cfg (feature = "std" )] |
28 | { |
29 | Error::boxed(format!("{msg}: {e}" )) |
30 | } |
31 | #[cfg (not(feature = "std" ))] |
32 | { |
33 | let _ = e; |
34 | Error::msg(msg) |
35 | } |
36 | } |
37 | } |
38 | |
39 | impl fmt::Display for Error { |
40 | fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { |
41 | use self::Inner::*; |
42 | match self.inner { |
43 | #[cfg (feature = "std" )] |
44 | Boxed(ref err) => err.fmt(f), |
45 | Msg(ref msg: &&'static str) => msg.fmt(f), |
46 | Fmt => fmt::Error.fmt(f), |
47 | } |
48 | } |
49 | } |
50 | |
51 | impl From<fmt::Error> for Error { |
52 | fn from(_: fmt::Error) -> Self { |
53 | Error { inner: Inner::Fmt } |
54 | } |
55 | } |
56 | |
57 | #[cfg (feature = "std" )] |
58 | mod std_support { |
59 | use super::*; |
60 | use crate::std::{boxed::Box, error, io}; |
61 | |
62 | pub(crate) type BoxedError = Box<dyn error::Error + Send + Sync>; |
63 | |
64 | impl Error { |
65 | /// Create an error from a standard error type. |
66 | pub fn boxed<E>(err: E) -> Self |
67 | where |
68 | E: Into<BoxedError>, |
69 | { |
70 | Error { |
71 | inner: Inner::Boxed(err.into()), |
72 | } |
73 | } |
74 | } |
75 | |
76 | impl error::Error for Error {} |
77 | |
78 | impl From<io::Error> for Error { |
79 | fn from(err: io::Error) -> Self { |
80 | Error::boxed(err) |
81 | } |
82 | } |
83 | } |
84 | |