• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     Value(value_bag::Error),
15     Fmt,
16 }
17 
18 impl Error {
19     /// Create an error from a message.
msg(msg: &'static str) -> Self20     pub fn msg(msg: &'static str) -> Self {
21         Error {
22             inner: Inner::Msg(msg),
23         }
24     }
25 
26     // Not public so we don't leak the `value_bag` API
from_value(err: value_bag::Error) -> Self27     pub(super) fn from_value(err: value_bag::Error) -> Self {
28         Error {
29             inner: Inner::Value(err),
30         }
31     }
32 
33     // Not public so we don't leak the `value_bag` API
into_value(self) -> value_bag::Error34     pub(super) fn into_value(self) -> value_bag::Error {
35         match self.inner {
36             Inner::Value(err) => err,
37             #[cfg(feature = "kv_unstable_std")]
38             _ => value_bag::Error::boxed(self),
39             #[cfg(not(feature = "kv_unstable_std"))]
40             _ => value_bag::Error::msg("error inspecting a value"),
41         }
42     }
43 }
44 
45 impl fmt::Display for Error {
fmt(&self, f: &mut fmt::Formatter) -> fmt::Result46     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
47         use self::Inner::*;
48         match &self.inner {
49             #[cfg(feature = "std")]
50             &Boxed(ref err) => err.fmt(f),
51             &Value(ref err) => err.fmt(f),
52             &Msg(ref msg) => msg.fmt(f),
53             &Fmt => fmt::Error.fmt(f),
54         }
55     }
56 }
57 
58 impl From<fmt::Error> for Error {
from(_: fmt::Error) -> Self59     fn from(_: fmt::Error) -> Self {
60         Error { inner: Inner::Fmt }
61     }
62 }
63 
64 #[cfg(feature = "std")]
65 mod std_support {
66     use super::*;
67     use std::{error, io};
68 
69     pub(super) type BoxedError = Box<dyn error::Error + Send + Sync>;
70 
71     impl Error {
72         /// Create an error from a standard error type.
boxed<E>(err: E) -> Self where E: Into<BoxedError>,73         pub fn boxed<E>(err: E) -> Self
74         where
75             E: Into<BoxedError>,
76         {
77             Error {
78                 inner: Inner::Boxed(err.into()),
79             }
80         }
81     }
82 
83     impl error::Error for Error {}
84 
85     impl From<io::Error> for Error {
from(err: io::Error) -> Self86         fn from(err: io::Error) -> Self {
87             Error::boxed(err)
88         }
89     }
90 }
91