12d8ae3abSopenharmony_ciuse std::fmt;
22d8ae3abSopenharmony_ci
32d8ae3abSopenharmony_ci/// An error encountered while working with structured data.
42d8ae3abSopenharmony_ci#[derive(Debug)]
52d8ae3abSopenharmony_cipub struct Error {
62d8ae3abSopenharmony_ci    inner: Inner,
72d8ae3abSopenharmony_ci}
82d8ae3abSopenharmony_ci
92d8ae3abSopenharmony_ci#[derive(Debug)]
102d8ae3abSopenharmony_cienum Inner {
112d8ae3abSopenharmony_ci    #[cfg(feature = "std")]
122d8ae3abSopenharmony_ci    Boxed(std_support::BoxedError),
132d8ae3abSopenharmony_ci    Msg(&'static str),
142d8ae3abSopenharmony_ci    Value(value_bag::Error),
152d8ae3abSopenharmony_ci    Fmt,
162d8ae3abSopenharmony_ci}
172d8ae3abSopenharmony_ci
182d8ae3abSopenharmony_ciimpl Error {
192d8ae3abSopenharmony_ci    /// Create an error from a message.
202d8ae3abSopenharmony_ci    pub fn msg(msg: &'static str) -> Self {
212d8ae3abSopenharmony_ci        Error {
222d8ae3abSopenharmony_ci            inner: Inner::Msg(msg),
232d8ae3abSopenharmony_ci        }
242d8ae3abSopenharmony_ci    }
252d8ae3abSopenharmony_ci
262d8ae3abSopenharmony_ci    // Not public so we don't leak the `value_bag` API
272d8ae3abSopenharmony_ci    pub(super) fn from_value(err: value_bag::Error) -> Self {
282d8ae3abSopenharmony_ci        Error {
292d8ae3abSopenharmony_ci            inner: Inner::Value(err),
302d8ae3abSopenharmony_ci        }
312d8ae3abSopenharmony_ci    }
322d8ae3abSopenharmony_ci
332d8ae3abSopenharmony_ci    // Not public so we don't leak the `value_bag` API
342d8ae3abSopenharmony_ci    pub(super) fn into_value(self) -> value_bag::Error {
352d8ae3abSopenharmony_ci        match self.inner {
362d8ae3abSopenharmony_ci            Inner::Value(err) => err,
372d8ae3abSopenharmony_ci            #[cfg(feature = "kv_unstable_std")]
382d8ae3abSopenharmony_ci            _ => value_bag::Error::boxed(self),
392d8ae3abSopenharmony_ci            #[cfg(not(feature = "kv_unstable_std"))]
402d8ae3abSopenharmony_ci            _ => value_bag::Error::msg("error inspecting a value"),
412d8ae3abSopenharmony_ci        }
422d8ae3abSopenharmony_ci    }
432d8ae3abSopenharmony_ci}
442d8ae3abSopenharmony_ci
452d8ae3abSopenharmony_ciimpl fmt::Display for Error {
462d8ae3abSopenharmony_ci    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
472d8ae3abSopenharmony_ci        use self::Inner::*;
482d8ae3abSopenharmony_ci        match &self.inner {
492d8ae3abSopenharmony_ci            #[cfg(feature = "std")]
502d8ae3abSopenharmony_ci            &Boxed(ref err) => err.fmt(f),
512d8ae3abSopenharmony_ci            &Value(ref err) => err.fmt(f),
522d8ae3abSopenharmony_ci            &Msg(ref msg) => msg.fmt(f),
532d8ae3abSopenharmony_ci            &Fmt => fmt::Error.fmt(f),
542d8ae3abSopenharmony_ci        }
552d8ae3abSopenharmony_ci    }
562d8ae3abSopenharmony_ci}
572d8ae3abSopenharmony_ci
582d8ae3abSopenharmony_ciimpl From<fmt::Error> for Error {
592d8ae3abSopenharmony_ci    fn from(_: fmt::Error) -> Self {
602d8ae3abSopenharmony_ci        Error { inner: Inner::Fmt }
612d8ae3abSopenharmony_ci    }
622d8ae3abSopenharmony_ci}
632d8ae3abSopenharmony_ci
642d8ae3abSopenharmony_ci#[cfg(feature = "std")]
652d8ae3abSopenharmony_cimod std_support {
662d8ae3abSopenharmony_ci    use super::*;
672d8ae3abSopenharmony_ci    use std::{error, io};
682d8ae3abSopenharmony_ci
692d8ae3abSopenharmony_ci    pub(super) type BoxedError = Box<dyn error::Error + Send + Sync>;
702d8ae3abSopenharmony_ci
712d8ae3abSopenharmony_ci    impl Error {
722d8ae3abSopenharmony_ci        /// Create an error from a standard error type.
732d8ae3abSopenharmony_ci        pub fn boxed<E>(err: E) -> Self
742d8ae3abSopenharmony_ci        where
752d8ae3abSopenharmony_ci            E: Into<BoxedError>,
762d8ae3abSopenharmony_ci        {
772d8ae3abSopenharmony_ci            Error {
782d8ae3abSopenharmony_ci                inner: Inner::Boxed(err.into()),
792d8ae3abSopenharmony_ci            }
802d8ae3abSopenharmony_ci        }
812d8ae3abSopenharmony_ci    }
822d8ae3abSopenharmony_ci
832d8ae3abSopenharmony_ci    impl error::Error for Error {}
842d8ae3abSopenharmony_ci
852d8ae3abSopenharmony_ci    impl From<io::Error> for Error {
862d8ae3abSopenharmony_ci        fn from(err: io::Error) -> Self {
872d8ae3abSopenharmony_ci            Error::boxed(err)
882d8ae3abSopenharmony_ci        }
892d8ae3abSopenharmony_ci    }
902d8ae3abSopenharmony_ci}
91