use serde::de;
use crate::de::{ParseError, TokenError};
use crate::fmt::FormatIter;
use crate::syntax::Int;
use crate::types::UnescapeError;
#[derive(Clone, Debug, PartialEq, thiserror::Error)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error {
#[error("{0}")]
Parse(#[from] ParseError),
#[error("unused input at end")]
UnusedInput,
#[error("integer out of range: {0}")]
IntRange(Int),
#[error("unescape buffer full")]
UnescapeBufferFull,
#[cfg(feature = "custom-error-messages")]
#[error("{0}")]
Custom(heapless::String<64>),
#[cfg(not(feature = "custom-error-messages"))]
#[error("serde error")]
Custom,
#[error("invalid type")]
InvalidType,
#[error("invalid value")]
InvalidValue,
#[error("invalid length: {0}")]
InvalidLength(usize),
#[error("unknown variant: expected one of {choices}", choices=FormatIter::new(.0.iter(), ", "))]
UnknownVariant(&'static [&'static str]),
#[error("unknown field: expected one of {choices}", choices=FormatIter::new(.0.iter(), ", "))]
UnknownField(&'static [&'static str]),
#[error("missing field: {0}")]
MissingField(&'static str),
#[error("duplicate field: {0}")]
DuplicateField(&'static str),
}
impl From<UnescapeError> for Error {
fn from(other: UnescapeError) -> Self {
match other {
UnescapeError::UnknownEscape => {
Error::Parse(ParseError::Token(TokenError::UnknownEscape))
}
UnescapeError::BufferFull => Error::UnescapeBufferFull,
}
}
}
impl de::Error for Error {
#[cfg(feature = "custom-error-messages")]
fn custom<T>(msg: T) -> Self
where
T: core::fmt::Display,
{
use core::fmt::Write;
let mut s = heapless::String::new();
if write!(&mut s, "{}", msg).is_err() {
s.clear();
let _ = s.push_str("<too large for buffer>");
}
Self::Custom(s)
}
#[cfg(not(feature = "custom-error-messages"))]
fn custom<T>(_msg: T) -> Self
where
T: core::fmt::Display,
{
Self::Custom
}
fn invalid_type(_unexp: de::Unexpected<'_>, _exp: &dyn de::Expected) -> Self {
Self::InvalidType
}
fn invalid_value(_unexp: de::Unexpected<'_>, _exp: &dyn de::Expected) -> Self {
Self::InvalidValue
}
fn invalid_length(len: usize, _exp: &dyn de::Expected) -> Self {
Self::InvalidLength(len)
}
fn unknown_variant(_variant: &str, expected: &'static [&'static str]) -> Self {
Self::UnknownVariant(expected)
}
fn unknown_field(_field: &str, expected: &'static [&'static str]) -> Self {
Self::UnknownField(expected)
}
fn missing_field(field: &'static str) -> Self {
Self::MissingField(field)
}
fn duplicate_field(field: &'static str) -> Self {
Self::DuplicateField(field)
}
}
#[cfg(test)]
mod test {
#[test]
fn invalid_value() {
use crate::{de::Error, from_slice_escaped, Flavor};
use core::num::NonZero;
let r = from_slice_escaped::<NonZero<u8>>(Flavor::Value, b" 0 ", &mut []).unwrap_err();
assert_eq!(Error::InvalidValue, *r)
}
#[test]
fn invalid_length() {
use crate::{de::Error, from_slice_escaped, Flavor};
let r = from_slice_escaped::<(u8, u8)>(Flavor::Value, b" [0] ", &mut []).unwrap_err();
assert_eq!(Error::InvalidLength(1), *r)
}
#[derive(Debug, PartialEq, Eq, serde::Deserialize)]
enum Enum {
Variant,
}
#[test]
fn unknown_variant() {
use crate::{de::Error, from_slice_escaped, Flavor};
let r = from_slice_escaped::<Enum>(Flavor::Value, b" No ", &mut []).unwrap_err();
assert_eq!(Error::UnknownVariant(&["Variant"]), *r)
}
#[derive(Debug, PartialEq, Eq, serde::Deserialize)]
#[serde(deny_unknown_fields)]
struct Struct {
a: u8,
b: u8,
}
#[test]
fn unknown_field() {
use crate::{de::Error, from_slice_escaped, Flavor};
let r = from_slice_escaped::<Struct>(Flavor::Value, b" {foo=2} ", &mut []).unwrap_err();
assert_eq!(Error::UnknownField(&["a", "b"]), *r)
}
#[test]
fn missing_field() {
use crate::{de::Error, from_slice_escaped, Flavor};
let r = from_slice_escaped::<Struct>(Flavor::Value, b" {a=2} ", &mut []).unwrap_err();
assert_eq!(Error::MissingField("b"), *r)
}
#[test]
fn duplicate_field() {
use crate::{de::Error, from_slice_escaped, Flavor};
let r = from_slice_escaped::<Struct>(Flavor::Value, b" {a=2, a=3} ", &mut []).unwrap_err();
assert_eq!(Error::DuplicateField("a"), *r)
}
}