1use crate::alloc_prelude::*;
2
3#[derive(Clone, PartialEq, Eq)]
5pub struct Error {
6 pub(crate) inner: ErrorInner,
7}
8
9impl Error {
10 pub(crate) fn new(inner: impl core::fmt::Display) -> Self {
11 Self {
12 inner: ErrorInner::Custom(inner.to_string()),
13 }
14 }
15
16 pub(crate) fn unsupported_type(t: Option<&'static str>) -> Self {
17 Self {
18 inner: ErrorInner::UnsupportedType(t),
19 }
20 }
21
22 pub(crate) fn out_of_range(t: Option<&'static str>) -> Self {
23 Self {
24 inner: ErrorInner::OutOfRange(t),
25 }
26 }
27
28 pub(crate) fn unsupported_none() -> Self {
29 Self {
30 inner: ErrorInner::UnsupportedNone,
31 }
32 }
33
34 pub(crate) fn key_not_string() -> Self {
35 Self {
36 inner: ErrorInner::KeyNotString,
37 }
38 }
39
40 #[cfg(feature = "display")]
41 pub(crate) fn date_invalid() -> Self {
42 Self {
43 inner: ErrorInner::DateInvalid,
44 }
45 }
46}
47
48impl From<core::fmt::Error> for Error {
49 fn from(_: core::fmt::Error) -> Self {
50 Self::new("an error occurred when writing a value")
51 }
52}
53
54impl serde::ser::Error for Error {
55 fn custom<T>(msg: T) -> Self
56 where
57 T: core::fmt::Display,
58 {
59 Self::new(msg)
60 }
61}
62
63impl core::fmt::Display for Error {
64 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
65 self.inner.fmt(f)
66 }
67}
68
69impl core::fmt::Debug for Error {
70 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
71 self.inner.fmt(f)
72 }
73}
74
75#[cfg(feature = "std")]
76impl std::error::Error for Error {}
77#[cfg(not(feature = "std"))]
78impl serde::de::StdError for Error {}
79
80#[derive(Debug, Clone, PartialEq, Eq, Hash)]
82#[non_exhaustive]
83pub(crate) enum ErrorInner {
84 UnsupportedType(Option<&'static str>),
86 OutOfRange(Option<&'static str>),
88 UnsupportedNone,
90 KeyNotString,
92 DateInvalid,
94 Custom(String),
96}
97
98impl core::fmt::Display for ErrorInner {
99 fn fmt(&self, formatter: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
100 match self {
101 Self::UnsupportedType(Some(t)) => write!(formatter, "unsupported {t} type"),
102 Self::UnsupportedType(None) => write!(formatter, "unsupported rust type"),
103 Self::OutOfRange(Some(t)) => write!(formatter, "out-of-range value for {t} type"),
104 Self::OutOfRange(None) => write!(formatter, "out-of-range value"),
105 Self::UnsupportedNone => "unsupported None value".fmt(formatter),
106 Self::KeyNotString => "map key was not a string".fmt(formatter),
107 Self::DateInvalid => "a serialized date was invalid".fmt(formatter),
108 Self::Custom(s) => s.fmt(formatter),
109 }
110 }
111}