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