value_bag/
error.rs

1use crate::std::fmt;
2
3/// An error encountered while working with structured data.
4#[derive(Debug)]
5pub struct Error {
6    inner: Inner,
7}
8
9#[derive(Debug)]
10enum Inner {
11    #[cfg(feature = "std")]
12    Boxed(std_support::BoxedError),
13    Msg(&'static str),
14    Fmt,
15}
16
17impl 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
39impl 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) => msg.fmt(f),
46            Fmt => fmt::Error.fmt(f),
47        }
48    }
49}
50
51impl From<fmt::Error> for Error {
52    fn from(_: fmt::Error) -> Self {
53        Error { inner: Inner::Fmt }
54    }
55}
56
57#[cfg(feature = "std")]
58mod 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}