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 #[cfg(feature = "value-bag")] 15 Value(crate::kv::value::inner::Error), 16 Fmt, 17 } 18 19 impl Error { 20 /// Create an error from a message. msg(msg: &'static str) -> Self21 pub fn msg(msg: &'static str) -> Self { 22 Error { 23 inner: Inner::Msg(msg), 24 } 25 } 26 27 // Not public so we don't leak the `crate::kv::value::inner` API 28 #[cfg(feature = "value-bag")] from_value(err: crate::kv::value::inner::Error) -> Self29 pub(super) fn from_value(err: crate::kv::value::inner::Error) -> Self { 30 Error { 31 inner: Inner::Value(err), 32 } 33 } 34 35 // Not public so we don't leak the `crate::kv::value::inner` API 36 #[cfg(feature = "value-bag")] into_value(self) -> crate::kv::value::inner::Error37 pub(super) fn into_value(self) -> crate::kv::value::inner::Error { 38 match self.inner { 39 Inner::Value(err) => err, 40 #[cfg(feature = "kv_std")] 41 _ => crate::kv::value::inner::Error::boxed(self), 42 #[cfg(not(feature = "kv_std"))] 43 _ => crate::kv::value::inner::Error::msg("error inspecting a value"), 44 } 45 } 46 } 47 48 impl fmt::Display for Error { fmt(&self, f: &mut fmt::Formatter) -> fmt::Result49 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { 50 use self::Inner::*; 51 match &self.inner { 52 #[cfg(feature = "std")] 53 Boxed(err) => err.fmt(f), 54 #[cfg(feature = "value-bag")] 55 Value(err) => err.fmt(f), 56 Msg(msg) => msg.fmt(f), 57 Fmt => fmt::Error.fmt(f), 58 } 59 } 60 } 61 62 impl From<fmt::Error> for Error { from(_: fmt::Error) -> Self63 fn from(_: fmt::Error) -> Self { 64 Error { inner: Inner::Fmt } 65 } 66 } 67 68 #[cfg(feature = "std")] 69 mod std_support { 70 use super::*; 71 use std::{error, io}; 72 73 pub(super) type BoxedError = Box<dyn error::Error + Send + Sync>; 74 75 impl Error { 76 /// Create an error from a standard error type. boxed<E>(err: E) -> Self where E: Into<BoxedError>,77 pub fn boxed<E>(err: E) -> Self 78 where 79 E: Into<BoxedError>, 80 { 81 Error { 82 inner: Inner::Boxed(err.into()), 83 } 84 } 85 } 86 87 impl error::Error for Error {} 88 89 impl From<io::Error> for Error { from(err: io::Error) -> Self90 fn from(err: io::Error) -> Self { 91 Error::boxed(err) 92 } 93 } 94 } 95