simd_json_derive/
de.rs

1use std::num::TryFromIntError;
2
3use simd_json::Buffers;
4
5use crate::Tape;
6
7fn expected(fields: &[&str]) -> String {
8    fields
9        .iter()
10        .map(|f| format!("`{f}`"))
11        .collect::<Vec<_>>()
12        .join(", ")
13}
14/// Deserialisation error
15#[derive(Debug, thiserror::Error, PartialEq)]
16pub enum Error {
17    /// Error from simd-json
18    #[error("json error: {0:?}")]
19    Json(simd_json::ErrorType),
20
21    /// Error from simd-json
22    #[error(transparent)]
23    Simd(#[from] simd_json::Error),
24
25    /// Missing field
26    #[error("missing field: `{0}`")]
27    MissingField(&'static str),
28    /// Unexpected field
29    #[error(
30        "unknown field `{unknown_field}`, expected one of {}",
31        expected(possible_field_names)
32    )]
33    UnknownField {
34        /// Unknown field that was encountered
35        unknown_field: String,
36        /// Possible fields that are expected
37        possible_field_names: &'static [&'static str],
38    },
39    /// unnamed enum field is not an array
40    #[error("unnamed enum field `{0}` is not an array")]
41    FieldNotAnArray(&'static str),
42    /// unknwon enum variant
43    #[error("unknwon enum variant `{0}`")]
44    UnknownEnumVariant(String),
45    /// invalid enum representation, needs to be either a string or an object
46    #[error("invalid enum representation, needs to be either a string or an object")]
47    InvalidEnumRepresentation,
48    /// invalid struct representation, needs to be an object
49    #[error("invalid struct representation, needs to be an object")]
50    InvalidStructRepresentation,
51    /// Unexpected e,nd of input
52    #[error("Unexpected e,nd of input")]
53    EOF,
54    /// Invalid integer number
55    #[error("Invalid integer number")]
56    InvalidNumber(#[from] TryFromIntError),
57    /// Custom error
58    #[error("Custom error: {0}")]
59    Custom(String),
60    /// The universe is broken
61    #[error("The universe is broken: {0}")]
62    BrokenUniverse(#[from] std::convert::Infallible),
63}
64
65impl Error {
66    /// Create a custom error
67    pub fn custom<T: std::fmt::Display>(msg: T) -> Self {
68        Error::Custom(msg.to_string())
69    }
70    /// Expected String error
71    #[must_use]
72    pub const fn expected_string() -> Self {
73        Error::Json(simd_json::ErrorType::ExpectedString)
74    }
75    /// Expected Map error
76    #[must_use]
77    pub const fn expected_map() -> Self {
78        Error::Json(simd_json::ErrorType::ExpectedMap)
79    }
80    /// Expected Array error
81    #[must_use]
82    pub const fn expected_array() -> Self {
83        Error::Json(simd_json::ErrorType::ExpectedArray)
84    }
85    /// Expected Float error
86    #[must_use]
87    pub const fn expected_float() -> Self {
88        Error::Json(simd_json::ErrorType::ExpectedFloat)
89    }
90    /// Expected Null error
91    #[must_use]
92    pub fn expected_null() -> Self {
93        Error::Json(simd_json::ErrorType::ExpectedNull)
94    }
95    /// Expected Integer error
96    #[must_use]
97    pub fn expected_integer() -> Self {
98        Error::Json(simd_json::ErrorType::ExpectedInteger)
99    }
100    /// Expected Boolean error
101    #[must_use]
102    pub fn expected_boolean() -> Self {
103        Error::Json(simd_json::ErrorType::ExpectedBoolean)
104    }
105}
106
107// Deserialisation result
108/// Deserializer result
109pub type Result<T> = std::result::Result<T, Error>;
110
111/// Deserialisation trait for simd-json
112pub trait Deserialize<'input> {
113    /// Deserializes from a tape
114    /// # Errors
115    /// if deserialisation fails
116    fn from_tape(tape: &mut Tape<'input>) -> Result<Self>
117    where
118        Self: Sized + 'input;
119
120    /// Deserializes from a u8 slice
121    /// # Errors
122    /// if deserialisation fails
123    #[inline]
124    fn from_slice(json: &'input mut [u8]) -> Result<Self>
125    where
126        Self: Sized + 'input,
127    {
128        let tape = simd_json::to_tape(json)?;
129        let mut itr = tape.0.into_iter().peekable();
130        Self::from_tape(&mut itr)
131    }
132
133    /// Deserializes from a u8 slice using pre-allocated buffers
134    /// # Errors
135    /// if deserialisation fails
136    #[inline]
137    fn from_slice_with_buffers(json: &'input mut [u8], buffers: &mut Buffers) -> Result<Self>
138    where
139        Self: Sized + 'input,
140    {
141        let tape = simd_json::Deserializer::from_slice_with_buffers(json, buffers)?.into_tape();
142        let mut itr = tape.0.into_iter().peekable();
143        Self::from_tape(&mut itr)
144    }
145
146    #[inline]
147    /// # Errors
148    /// if deserialisation fails
149    /// # Safety
150    ///
151    /// user must not use the string afterwards
152    /// as it most likely will no longer contain valid utf-8
153    unsafe fn from_str(json: &'input mut str) -> Result<Self>
154    where
155        Self: Sized + 'input,
156    {
157        Self::from_slice(json.as_bytes_mut())
158    }
159}