serde_content/
error.rs

1use crate::DataType;
2use crate::Number;
3use alloc::boxed::Box;
4use alloc::format;
5use alloc::string::String;
6use alloc::string::ToString;
7use alloc::vec::Vec;
8use core::fmt;
9
10/// Alias for [core::result::Result] with [crate::Error] as the error type.
11pub type Result<T> = core::result::Result<T, Error>;
12
13/// The error type returned by this crate.
14#[derive(Debug, Clone, PartialEq, PartialOrd)]
15#[cfg_attr(feature = "derive", derive(serde::Serialize, serde::Deserialize))]
16pub struct Error {
17    kind: Box<ErrorKind>,
18}
19
20impl Error {
21    /// Creates a new unexpected error
22    pub fn unexpected(found: Found, expected: Expected) -> Self {
23        Self {
24            kind: Box::new(ErrorKind::Unexpected { found, expected }),
25        }
26    }
27
28    /// Borrows the underlying error kind
29    pub fn kind(&self) -> &ErrorKind {
30        &self.kind
31    }
32
33    /// Consumes the error and returns the error kind
34    pub fn into_kind(self) -> ErrorKind {
35        *self.kind
36    }
37}
38
39/// The kind of error returned by [`Error::kind`]
40#[derive(Debug, Clone, PartialEq, PartialOrd)]
41#[cfg_attr(feature = "derive", derive(serde::Serialize, serde::Deserialize))]
42#[non_exhaustive] // In case we add new error variants in future.
43pub enum ErrorKind {
44    /// Found an unexpected type when deserialising.
45    Unexpected {
46        /// The type we found (and data where applicable).
47        found: Found,
48        /// The type we expected.
49        expected: Expected,
50    },
51    /// A custom error message from `serde`.
52    Custom(String),
53}
54
55impl fmt::Display for Error {
56    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57        match &*self.kind {
58            ErrorKind::Custom(msg) => write!(f, "{msg}"),
59            ErrorKind::Unexpected { found, expected } => write!(
60                f,
61                "failed to deserialize; expected {expected}, found {found}"
62            ),
63        }
64    }
65}
66
67#[cfg(feature = "std")]
68impl std::error::Error for Error {}
69
70#[cfg(feature = "serde")]
71impl serde::ser::Error for Error {
72    fn custom<T>(msg: T) -> Self
73    where
74        T: fmt::Display,
75    {
76        Self {
77            kind: Box::new(ErrorKind::Custom(msg.to_string())),
78        }
79    }
80}
81
82#[cfg(feature = "serde")]
83impl serde::de::Error for Error {
84    fn custom<T>(msg: T) -> Self
85    where
86        T: fmt::Display,
87    {
88        Self {
89            kind: Box::new(ErrorKind::Custom(msg.to_string())),
90        }
91    }
92}
93
94/// The type that was expected.
95#[derive(Debug, Clone, PartialEq, PartialOrd)]
96#[cfg_attr(feature = "derive", derive(serde::Serialize, serde::Deserialize))]
97#[non_exhaustive] // In case we add new number variants in future.
98pub enum Expected {
99    /// Expected the Rust unit type, `()`.
100    Unit,
101    /// Expected a Rust boolean.
102    Bool,
103    /// Expected a Rust character.
104    Char,
105    /// Expected a Rust string.
106    String,
107    /// Expected a static string slice.
108    StaticStr,
109    /// Expected a Rust byte array.
110    Bytes,
111    /// Expected an array of Rust values.
112    Seq,
113    /// Expected a map of Rust values.
114    Map,
115    /// Expected a Rust struct.
116    Struct {
117        /// The name of the struct.
118        name: Option<String>,
119        /// The type of the struct
120        typ: Option<DataType>,
121    },
122    /// Expected a Rust enum.
123    Enum {
124        /// The name of the enum.
125        name: Option<String>,
126        /// The type of the enum.
127        typ: Option<DataType>,
128    },
129    /// Expected a Rust tuple.
130    Tuple(usize),
131    /// Expected a struct field or an enum variant.
132    Identifier,
133    /// Expected an 8-bit signed integer type.
134    I8,
135    /// Expected an 8-bit unsigned integer type.
136    U8,
137    /// Expected a 16-bit signed integer type.
138    I16,
139    /// Expected a 16-bit unsigned integer type.
140    U16,
141    /// Expected a 32-bit signed integer type.
142    I32,
143    /// Expected a 32-bit unsigned integer type.
144    U32,
145    /// Expected a 32-bit floating point type.
146    F32,
147    /// Expected a 64-bit signed integer type.
148    I64,
149    /// Expected a 64-bit unsigned integer type.
150    U64,
151    /// Expected a 32-bit floating point type.
152    F64,
153    /// Expected a 128-bit signed integer type.
154    I128,
155    /// Expected a 128-bit unsigned integer type.
156    U128,
157}
158
159#[doc(hidden)] // Not public API.
160impl fmt::Display for Expected {
161    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
162        match self {
163            Expected::Unit => write!(f, "a unit"),
164            Expected::Bool => write!(f, "a boolean"),
165            Expected::I8 => write!(f, "an 8-bit signed integer"),
166            Expected::U8 => write!(f, "an 8-bit unsigned integer"),
167            Expected::I16 => write!(f, "a 16-bit signed integer"),
168            Expected::U16 => write!(f, "a 16-bit unsigned integer"),
169            Expected::I32 => write!(f, "a 32-bit signed integer"),
170            Expected::U32 => write!(f, "a 32-bit unsigned integer"),
171            Expected::F32 => write!(f, "a 32-bit floating point"),
172            Expected::I64 => write!(f, "a 64-bit signed integer"),
173            Expected::U64 => write!(f, "a 64-bit unsigned integer"),
174            Expected::F64 => write!(f, "a 64-bit floating point"),
175            Expected::I128 => write!(f, "a 128-bit signed integer"),
176            Expected::U128 => write!(f, "a 128-bit unsigned integer"),
177            Expected::Char => write!(f, "a single character"),
178            Expected::String => write!(f, "a string"),
179            Expected::StaticStr => write!(f, "a static string slice"),
180            Expected::Bytes => write!(f, "a byte array"),
181            Expected::Seq => write!(f, "a sequence"),
182            Expected::Map => write!(f, "a map"),
183            Expected::Struct { name, typ } => match (name.as_deref(), typ) {
184                (None, None) => write!(f, "a struct"),
185                (None, Some(typ)) => write!(f, "{typ} struct"),
186                (Some(name), None) => write!(f, "a struct named {name}"),
187                (Some(name), Some(typ)) => write!(f, "{typ} struct named {name}"),
188            },
189            Expected::Enum { name, typ } => match (name.as_deref(), typ) {
190                (None, None) => write!(f, "an enum variant"),
191                (None, Some(typ)) => write!(f, "{typ} enum variant"),
192                (Some(name), None) => write!(f, "an enum variant of {name}"),
193                (Some(name), Some(typ)) => write!(f, "{typ} enum variant of {name}"),
194            },
195            Expected::Tuple(len) => write!(f, "a tuple with {len} elements"),
196            Expected::Identifier => write!(f, "a struct field name or an enum variant"),
197        }
198    }
199}
200
201#[doc(hidden)] // Not public API.
202impl fmt::Display for DataType {
203    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204        match self {
205            DataType::Unit => write!(f, "a unit"),
206            DataType::NewType => write!(f, "a newtype"),
207            DataType::Tuple => write!(f, "a tuple"),
208            DataType::Struct => write!(f, "an object-like"),
209        }
210    }
211}
212
213/// Struct and enum data type for error messages.
214#[derive(Debug, Clone, PartialEq, PartialOrd)]
215#[cfg_attr(feature = "derive", derive(serde::Serialize, serde::Deserialize))]
216pub enum Data {
217    /// Unit struct or unit enum variant.
218    Unit,
219    /// Newtype struct or enum variant.
220    NewType(Found),
221    /// Tuple struct or enum variant.
222    Tuple(Vec<Found>),
223    /// Object-like struct or enum variant.
224    Struct(Vec<(String, Found)>),
225}
226
227/// The type that was found.
228#[derive(Debug, Clone, PartialEq, PartialOrd)]
229#[cfg_attr(feature = "derive", derive(serde::Serialize, serde::Deserialize))]
230pub enum Found {
231    /// Found the Rust unit type, `()`.
232    Unit,
233    /// Found a Rust boolean.
234    Bool(bool),
235    /// Found any Rust number.
236    Number(Number),
237    /// Found a Rust character.
238    Char(char),
239    /// Found a Rust string.
240    String(String),
241    /// Found a Rust byte array.
242    Bytes(Vec<u8>),
243    /// Found an array of Rust values.
244    Seq(Vec<Found>),
245    /// Found a map of Rust values.
246    Map(Vec<(Found, Found)>),
247    /// Found optional Rust values.
248    Option(Option<Box<Found>>),
249    /// Found a Rust struct.
250    Struct {
251        /// The name of the struct.
252        name: String,
253        /// The data of the struct
254        data: Box<Data>,
255    },
256    /// Found a Rust enum.
257    Enum {
258        /// The name of the enum.
259        name: String,
260        /// The variant of the enum.
261        variant: String,
262        /// The data of the enum.
263        data: Box<Data>,
264    },
265    /// Found a Rust tuple.
266    Tuple(Vec<Found>),
267    /// Found a struct field or an enum variant.
268    Identifier(String),
269}
270
271#[doc(hidden)] // Not public API.
272impl fmt::Display for Found {
273    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
274        match self {
275            Found::Unit => write!(f, "()"),
276            Found::Bool(v) => write!(f, "{v}"),
277            Found::Number(v) => match v {
278                Number::I8(v) => write!(f, "{v}i8"),
279                Number::U8(v) => write!(f, "{v}u8"),
280                Number::I16(v) => write!(f, "{v}i16"),
281                Number::U16(v) => write!(f, "{v}u16"),
282                Number::I32(v) => write!(f, "{v}i32"),
283                Number::U32(v) => write!(f, "{v}u32"),
284                Number::F32(v) => write!(f, "{v}f32"),
285                Number::I64(v) => write!(f, "{v}i64"),
286                Number::U64(v) => write!(f, "{v}u64"),
287                Number::F64(v) => write!(f, "{v}f64"),
288                Number::I128(v) => write!(f, "{v}i128"),
289                Number::U128(v) => write!(f, "{v}u128"),
290            },
291            Found::Char(v) => write!(f, "'{v}'"),
292            Found::String(v) => write!(f, "{v:?}"),
293            Found::Bytes(v) => write!(f, "&{v:?}"),
294            Found::Seq(v) => {
295                f.write_str("[")?;
296                let data = v.iter().map(Self::to_string).collect::<Vec<_>>();
297                f.write_str(&data.join(", "))?;
298                f.write_str("]")
299            }
300            Found::Map(v) => {
301                f.write_str("{ ")?;
302                let data = v
303                    .iter()
304                    .map(|(k, v)| format!("{k}: {v}"))
305                    .collect::<Vec<_>>();
306                f.write_str(&data.join(", "))?;
307                f.write_str(" }")
308            }
309            Found::Option(v) => match v {
310                Some(v) => write!(f, "Some({v})"),
311                None => write!(f, "None"),
312            },
313            Found::Struct { name, data } => match data.as_ref() {
314                Data::Unit => write!(f, "{name}"),
315                Data::NewType(v) => write!(f, "{name}({v})"),
316                Data::Tuple(v) => {
317                    write!(f, "{name}(")?;
318                    let data = v.iter().map(Self::to_string).collect::<Vec<_>>();
319                    f.write_str(&data.join(", "))?;
320                    f.write_str(")")
321                }
322                Data::Struct(v) => {
323                    write!(f, "{name} {{ ")?;
324                    let data = v
325                        .iter()
326                        .map(|(k, v)| format!("{k}: {v}"))
327                        .collect::<Vec<_>>();
328                    f.write_str(&data.join(", "))?;
329                    f.write_str(" }")
330                }
331            },
332            Found::Enum {
333                name,
334                variant,
335                data,
336            } => match data.as_ref() {
337                Data::Unit => write!(f, "{name}::{variant}"),
338                Data::NewType(v) => write!(f, "{name}::{variant}({v})"),
339                Data::Tuple(v) => {
340                    write!(f, "{name}::{variant}(")?;
341                    let data = v.iter().map(Self::to_string).collect::<Vec<_>>();
342                    f.write_str(&data.join(", "))?;
343                    f.write_str(")")
344                }
345                Data::Struct(v) => {
346                    write!(f, "{name}::{variant} {{ ")?;
347                    let data = v
348                        .iter()
349                        .map(|(k, v)| format!("{k}: {v}"))
350                        .collect::<Vec<_>>();
351                    f.write_str(&data.join(", "))?;
352                    f.write_str(" }")
353                }
354            },
355            Found::Tuple(v) => {
356                f.write_str("(")?;
357                let data = v.iter().map(Self::to_string).collect::<Vec<_>>();
358                f.write_str(&data.join(", "))?;
359                f.write_str(")")
360            }
361            Found::Identifier(v) => write!(f, "{v}"),
362        }
363    }
364}