Skip to main content

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(all(feature = "alloc", feature = "error-core"))]
12    Boxed(alloc_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(all(feature = "alloc", feature = "error-core"))]
28        {
29            Error::boxed(format!("{msg}: {e}"))
30        }
31        #[cfg(not(all(feature = "alloc", feature = "error-core")))]
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(all(feature = "alloc", feature = "error-core"))]
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 = "error-core")]
58mod error_support {
59    use super::*;
60    use crate::std::error;
61
62    impl error::Error for Error {}
63}
64
65#[cfg(all(feature = "alloc", feature = "error-core"))]
66mod alloc_support {
67    use super::*;
68    use crate::std::{boxed::Box, error};
69
70    pub(crate) type BoxedError = Box<dyn error::Error + Send + Sync>;
71
72    impl Error {
73        /// Create an error from a standard error type.
74        pub fn boxed<E>(err: E) -> Self
75        where
76            E: Into<BoxedError>,
77        {
78            Error {
79                inner: Inner::Boxed(err.into()),
80            }
81        }
82    }
83}
84
85#[cfg(all(feature = "std", feature = "error-core"))]
86mod std_support {
87    use super::*;
88    use crate::std::io;
89
90    impl From<io::Error> for Error {
91        fn from(err: io::Error) -> Self {
92            Error::boxed(err)
93        }
94    }
95}