1use serde::{de, ser};
4
5#[cfg(all(feature = "alloc", not(feature = "std")))]
6use alloc::{
7 boxed::Box,
8 format,
9 string::{String, ToString},
10};
11#[cfg(feature = "std")]
12use std::{
13 boxed::Box,
14 error, format,
15 string::{String, ToString},
16};
17
18use core::{
19 fmt::{self, Display},
20 result,
21};
22
23pub type Result<T> = result::Result<T, Error>;
25
26pub struct Error {
28 inner: Box<ErrorImpl>,
29}
30
31impl Error {
32 #[must_use]
38 #[inline]
39 pub fn new(kind: ErrorKind, byte_offset: usize) -> Self {
40 Self {
41 inner: Box::new(ErrorImpl { kind, byte_offset }),
42 }
43 }
44
45 #[must_use]
46 #[inline]
47 pub(crate) fn with_kind(kind: ErrorKind) -> Self {
48 Self::new(kind, 0)
49 }
50
51 #[must_use]
53 #[inline]
54 pub fn kind(&self) -> &ErrorKind {
55 &self.inner.kind
56 }
57
58 #[must_use]
64 #[inline]
65 pub fn byte_offset(&self) -> usize {
66 self.inner.byte_offset
67 }
68}
69
70impl Display for Error {
71 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 Display::fmt(&self.inner, f)
73 }
74}
75
76impl fmt::Debug for Error {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 fmt::Debug::fmt(&self.inner, f)
79 }
80}
81
82impl de::StdError for Error {
83 #[cfg(feature = "std")]
84 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
85 self.inner.kind.source()
86 }
87}
88
89impl de::Error for Error {
90 fn custom<T: Display>(msg: T) -> Self {
91 Error::with_kind(ErrorKind::Deserialize(msg.to_string()))
92 }
93
94 fn invalid_type(unexp: de::Unexpected<'_>, exp: &dyn de::Expected) -> Self {
95 Error::with_kind(ErrorKind::Deserialize(format!(
96 "unexpected type error. invalid_type={}, expected_type={}",
97 unexp, exp
98 )))
99 }
100}
101
102impl ser::Error for Error {
103 fn custom<T: Display>(msg: T) -> Self {
104 Error::with_kind(ErrorKind::Serialize(msg.to_string()))
105 }
106}
107
108#[cfg(feature = "std")]
109impl From<Error> for std::io::Error {
110 fn from(error: Error) -> Self {
111 if let ErrorKind::Io(error) = error.inner.kind {
112 return error;
113 }
114 std::io::Error::new(std::io::ErrorKind::Other, error.to_string())
115 }
116}
117
118struct ErrorImpl {
119 kind: ErrorKind,
120 byte_offset: usize,
121}
122
123impl Display for ErrorImpl {
124 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 if self.byte_offset == 0 {
126 Display::fmt(&self.kind, f)
127 } else {
128 write!(f, "{} at byte offset {}", self.kind, self.byte_offset)
129 }
130 }
131}
132
133impl fmt::Debug for ErrorImpl {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 f.debug_struct("Error")
136 .field("kind", &self.kind)
137 .field("byte_offset", &self.byte_offset)
138 .finish()
139 }
140}
141
142#[allow(clippy::module_name_repetitions)]
144pub enum ErrorKind {
147 Deserialize(String),
151 EofWhileParsingValue,
153 ExpectedSomeValue,
155 InvalidByteStrLen,
157 InvalidInteger,
159 InvalidDict,
161 InvalidList,
163 #[cfg(feature = "std")]
164 Io(std::io::Error),
166 KeyMustBeAByteStr,
168 KeyWithoutValue,
171 Serialize(String),
173 TrailingData,
175 UnsupportedType,
182 ValueWithoutKey,
185}
186
187#[cfg(feature = "std")]
188impl error::Error for ErrorKind {
189 fn source(&self) -> Option<&(dyn error::Error + 'static)> {
190 match self {
191 ErrorKind::Deserialize(_)
192 | ErrorKind::EofWhileParsingValue
193 | ErrorKind::ExpectedSomeValue
194 | ErrorKind::InvalidByteStrLen
195 | ErrorKind::InvalidInteger
196 | ErrorKind::InvalidDict
197 | ErrorKind::InvalidList
198 | ErrorKind::KeyMustBeAByteStr
199 | ErrorKind::KeyWithoutValue
200 | ErrorKind::Serialize(_)
201 | ErrorKind::TrailingData
202 | ErrorKind::UnsupportedType
203 | ErrorKind::ValueWithoutKey => None,
204 #[cfg(feature = "std")]
205 ErrorKind::Io(source) => Some(source),
206 }
207 }
208}
209
210impl Display for ErrorKind {
211 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212 match self {
213 ErrorKind::Deserialize(str) | ErrorKind::Serialize(str) => f.write_str(str),
214 ErrorKind::EofWhileParsingValue => f.write_str("eof while parsing value"),
215 ErrorKind::ExpectedSomeValue => f.write_str("expected some value"),
216 ErrorKind::InvalidByteStrLen => f.write_str("invalid byte string length"),
217 ErrorKind::InvalidInteger => f.write_str("invalid integer"),
218 ErrorKind::InvalidDict => f.write_str("invalid dictionary"),
219 ErrorKind::InvalidList => f.write_str("invalid list"),
220 ErrorKind::KeyMustBeAByteStr => f.write_str("key must be a byte string"),
221 ErrorKind::KeyWithoutValue => f.write_str("key without value"),
222 ErrorKind::TrailingData => f.write_str("trailing data error"),
223 ErrorKind::UnsupportedType => f.write_str("unsupported type"),
224 ErrorKind::ValueWithoutKey => f.write_str("value without key"),
225 #[cfg(feature = "std")]
226 ErrorKind::Io(source) => Display::fmt(source, f),
227 }
228 }
229}
230
231impl fmt::Debug for ErrorKind {
232 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
233 match self {
234 ErrorKind::Deserialize(str) | ErrorKind::Serialize(str) => f.write_str(str),
235 ErrorKind::EofWhileParsingValue => f.write_str("eof while parsing value"),
236 ErrorKind::ExpectedSomeValue => f.write_str("expected some value"),
237 ErrorKind::InvalidByteStrLen => f.write_str("invalid byte string length"),
238 ErrorKind::InvalidInteger => f.write_str("invalid integer"),
239 ErrorKind::InvalidDict => f.write_str("invalid dictionary"),
240 ErrorKind::InvalidList => f.write_str("invalid list"),
241 ErrorKind::KeyMustBeAByteStr => f.write_str("key must be a byte string"),
242 ErrorKind::KeyWithoutValue => f.write_str("key without value"),
243 ErrorKind::TrailingData => f.write_str("trailing data error"),
244 ErrorKind::UnsupportedType => f.write_str("unsupported type"),
245 ErrorKind::ValueWithoutKey => f.write_str("value without key"),
246 #[cfg(feature = "std")]
247 ErrorKind::Io(source) => fmt::Debug::fmt(source, f),
248 }
249 }
250}