1use std::fmt;
2
3#[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 #[cfg(feature = "value-bag")]
15 Value(crate::kv::value::inner::Error),
16 Fmt,
17}
18
19impl Error {
20 pub fn msg(msg: &'static str) -> Self {
22 Error {
23 inner: Inner::Msg(msg),
24 }
25 }
26
27 #[cfg(feature = "value-bag")]
29 pub(super) fn from_value(err: crate::kv::value::inner::Error) -> Self {
30 Error {
31 inner: Inner::Value(err),
32 }
33 }
34
35 #[cfg(feature = "value-bag")]
37 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
48impl fmt::Display for Error {
49 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
62impl From<fmt::Error> for Error {
63 fn from(_: fmt::Error) -> Self {
64 Error { inner: Inner::Fmt }
65 }
66}
67
68#[cfg(feature = "std")]
69mod 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 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 {
90 fn from(err: io::Error) -> Self {
91 Error::boxed(err)
92 }
93 }
94}