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