Skip to main content

simd_json/
serde.rs

1/// simd-json integrates with serde, this module holds this integration.
2/// note that when parsing to a dom you should use the functions in
3/// `to_owned_value` or `to_borrowed_value` as they provide much
4/// better performance.
5///
6/// However if have to use serde for other reasons or are parsing
7/// directly to structs this is the place to go.
8///
9mod de;
10mod se;
11mod value;
12pub use self::se::*;
13pub use self::value::*;
14use crate::{BorrowedValue, OwnedValue};
15use crate::{Buffers, Deserializer, Error, ErrorType, Node, Result, macros::stry};
16use serde::de::DeserializeOwned;
17use serde_ext::Deserialize;
18use std::fmt;
19use std::io;
20use value_trait::prelude::*;
21type ConvertResult<T> = std::result::Result<T, SerdeConversionError>;
22
23/// Error while converting from or to serde values
24#[derive(Debug)]
25pub enum SerdeConversionError {
26    /// Serde can not reflect NAN or Infinity
27    NanOrInfinity,
28    /// The number is out of the 64 bit bound
29    NumberOutOfBounds,
30    /// Something horrible went wrong, please open a ticket at <https://simd-json.rs>
31    Oops,
32}
33impl std::fmt::Display for SerdeConversionError {
34    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
35        use SerdeConversionError::{NanOrInfinity, NumberOutOfBounds, Oops};
36        match self {
37            NanOrInfinity => write!(f, "JSON can not represent NAN or Infinity values"),
38            NumberOutOfBounds => write!(f, "Serde can not represent 128 bit values"),
39            Oops => write!(
40                f,
41                "Unreachable code is reachable, oops - please open a bug with simd-json"
42            ),
43        }
44    }
45}
46
47impl std::error::Error for SerdeConversionError {}
48
49/// Parses an integer map key. A key is an integer only when written as a JSON integer
50/// (`-?(0|[1-9][0-9]*)`), so `+1` and `01` (which `str::parse` alone accepts) are not; `-0` is
51/// rejected too, since it would be the same number as the key `0` but a different string.
52/// The leading characters are checked here, the rest by `str::parse`.
53pub(crate) fn parse_integer_key<T: std::str::FromStr>(key: &str) -> Option<T> {
54    match key.as_bytes() {
55        [b'0'] | [b'1'..=b'9', ..] | [b'-', b'1'..=b'9', ..] => key.parse().ok(),
56        _ => None,
57    }
58}
59
60/// parses a byte slice using a serde deserializer.
61/// note that the slice will be rewritten in the process.
62///
63/// # Errors
64///
65/// Will return `Err` if `s` is invalid JSON.
66#[cfg_attr(not(feature = "no-inline"), inline)]
67pub fn from_slice<'a, T>(s: &'a mut [u8]) -> Result<T>
68where
69    T: Deserialize<'a>,
70{
71    let mut deserializer = stry!(Deserializer::from_slice(s));
72    T::deserialize(&mut deserializer)
73}
74
75/// Parses a byte slice using a serde deserializer.
76/// note that the slice will be rewritten in the process.
77///
78/// Passes in reusable buffers to reduce allocations
79///
80/// # Errors
81///
82/// Will return `Err` if `s` is invalid JSON.
83#[cfg_attr(not(feature = "no-inline"), inline)]
84pub fn from_slice_with_buffers<'a, T>(s: &'a mut [u8], buffers: &mut Buffers) -> Result<T>
85where
86    T: Deserialize<'a>,
87{
88    let mut deserializer = stry!(Deserializer::from_slice_with_buffers(s, buffers));
89    T::deserialize(&mut deserializer)
90}
91
92/// Parses a str using a serde deserializer.
93/// note that the slice will be rewritten in the process and
94/// might not remain a valid utf8 string in its entirety.
95///
96/// It is recommended to use `from_slice` instead.
97///
98/// # Errors
99///
100/// Will return `Err` if `s` is invalid JSON.
101///
102/// # Safety
103///
104/// This function mutates the string passed into it, it's a convenience wrapper around `from_slice`,
105/// holding the same guarantees as `str::as_bytes_mut` in that after the call &str might include
106/// invalid utf8 bytes.
107#[cfg_attr(not(feature = "no-inline"), inline)]
108pub unsafe fn from_str<'a, T>(s: &'a mut str) -> Result<T>
109where
110    T: Deserialize<'a>,
111{
112    let mut deserializer = stry!(Deserializer::from_slice(unsafe { s.as_bytes_mut() }));
113
114    T::deserialize(&mut deserializer)
115}
116
117/// Parses a str using a serde deserializer.
118/// note that the slice will be rewritten in the process and
119/// might not remain a valid utf8 string in its entirety.
120///
121/// It is recommended to use `from_slice_with_buffers` instead.
122///
123/// Passes in reusable buffers to reduce allocations.
124///
125/// # Errors
126///
127/// Will return `Err` if `s` is invalid JSON.
128///
129/// # Safety
130///
131/// This function mutates the string passed into it, it's a convinience wrapper around `from_slice`,
132/// holding the same guarantees as `str::as_bytes_mut` in that after the call &str might include
133/// invalid utf8 bytes.
134#[cfg_attr(not(feature = "no-inline"), inline)]
135pub unsafe fn from_str_with_buffers<'a, T>(s: &'a mut str, buffers: &mut Buffers) -> Result<T>
136where
137    T: Deserialize<'a>,
138{
139    let mut deserializer = stry!(Deserializer::from_slice_with_buffers(
140        unsafe { s.as_bytes_mut() },
141        buffers
142    ));
143
144    T::deserialize(&mut deserializer)
145}
146
147/// parses a Reader using a serde deserializer.
148///
149/// # Warning
150///
151/// Since simd-json does not support streaming and requires mutability of the data, this function
152/// will read the entire reader into memory before parsing it.
153///
154/// You might do better using `from_slice` and managing the read buffer yourself.
155///
156/// # Errors
157///
158/// Will return `Err` if an IO error is encountered while reading
159/// rdr or if the readers content is invalid JSON.
160#[cfg_attr(not(feature = "no-inline"), inline)]
161pub fn from_reader<R, T>(mut rdr: R) -> Result<T>
162where
163    R: io::Read,
164    T: DeserializeOwned,
165{
166    let mut data = Vec::new();
167    if let Err(e) = rdr.read_to_end(&mut data) {
168        return Err(Error::generic(ErrorType::Io(e)));
169    }
170    let mut deserializer = stry!(Deserializer::from_slice(&mut data));
171    T::deserialize(&mut deserializer)
172}
173
174/// Parses a Reader using a serde deserializer.
175///
176/// Passes in reusable buffers to reduce allocations.
177///
178/// # Errors
179///
180/// Will return `Err` if an IO error is encountered while reading
181/// rdr or if the readers content is invalid JSON.
182#[cfg_attr(not(feature = "no-inline"), inline)]
183pub fn from_reader_with_buffers<R, T>(mut rdr: R, buffers: &mut Buffers) -> Result<T>
184where
185    R: io::Read,
186    T: DeserializeOwned,
187{
188    let mut data = Vec::new();
189    if let Err(e) = rdr.read_to_end(&mut data) {
190        return Err(Error::generic(ErrorType::Io(e)));
191    }
192    let mut deserializer = stry!(Deserializer::from_slice_with_buffers(&mut data, buffers));
193    T::deserialize(&mut deserializer)
194}
195
196impl serde::de::Error for Error {
197    fn custom<T: fmt::Display>(msg: T) -> Self {
198        Self::generic(ErrorType::Serde(msg.to_string()))
199    }
200}
201
202impl serde_ext::ser::Error for Error {
203    fn custom<T: fmt::Display>(msg: T) -> Self {
204        Self::generic(ErrorType::Serde(msg.to_string()))
205    }
206}
207
208// Functions purely used by serde
209impl<'de> Deserializer<'de> {
210    #[cfg_attr(not(feature = "no-inline"), inline)]
211    fn next(&mut self) -> Result<Node<'de>> {
212        let r = self
213            .tape
214            .get(self.idx)
215            .copied()
216            .ok_or_else(|| Self::error(ErrorType::Syntax));
217        self.idx += 1;
218        r
219    }
220
221    #[cfg_attr(not(feature = "no-inline"), inline)]
222    fn peek(&self) -> Result<Node<'de>> {
223        self.tape
224            .get(self.idx)
225            .copied()
226            .ok_or_else(|| Self::error(ErrorType::Eof))
227    }
228
229    #[cfg_attr(not(feature = "no-inline"), inline)]
230    #[allow(clippy::cast_sign_loss)]
231    fn parse_u8(&mut self) -> Result<u8> {
232        match stry!(self.next()) {
233            Node::Static(s) => s
234                .as_u8()
235                .ok_or_else(|| Self::error(ErrorType::ExpectedUnsigned)),
236            _ => Err(Self::error(ErrorType::ExpectedUnsigned)),
237        }
238    }
239
240    #[cfg_attr(not(feature = "no-inline"), inline)]
241    #[allow(clippy::cast_sign_loss)]
242    fn parse_u16(&mut self) -> Result<u16> {
243        let next = stry!(self.next());
244        match next {
245            Node::Static(s) => s
246                .as_u16()
247                .ok_or_else(|| Self::error(ErrorType::ExpectedUnsigned)),
248            _ => Err(Self::error(ErrorType::ExpectedUnsigned)),
249        }
250    }
251
252    #[cfg_attr(not(feature = "no-inline"), inline)]
253    #[allow(clippy::cast_sign_loss)]
254    fn parse_u32(&mut self) -> Result<u32> {
255        match stry!(self.next()) {
256            Node::Static(s) => s
257                .as_u32()
258                .ok_or_else(|| Self::error(ErrorType::ExpectedUnsigned)),
259            _ => Err(Self::error(ErrorType::ExpectedUnsigned)),
260        }
261    }
262
263    #[cfg_attr(not(feature = "no-inline"), inline)]
264    #[allow(clippy::cast_sign_loss)]
265    fn parse_u64(&mut self) -> Result<u64> {
266        match stry!(self.next()) {
267            Node::Static(s) => s
268                .as_u64()
269                .ok_or_else(|| Self::error(ErrorType::ExpectedUnsigned)),
270            _ => Err(Self::error(ErrorType::ExpectedUnsigned)),
271        }
272    }
273
274    #[cfg_attr(not(feature = "no-inline"), inline)]
275    #[allow(clippy::cast_sign_loss)]
276    fn parse_u128(&mut self) -> Result<u128> {
277        match stry!(self.next()) {
278            Node::Static(s) => s
279                .as_u128()
280                .ok_or_else(|| Self::error(ErrorType::ExpectedUnsigned)),
281            _ => Err(Self::error(ErrorType::ExpectedUnsigned)),
282        }
283    }
284
285    #[cfg_attr(not(feature = "no-inline"), inline)]
286    #[allow(clippy::cast_sign_loss)]
287    fn parse_i8(&mut self) -> Result<i8> {
288        match stry!(self.next()) {
289            Node::Static(s) => s
290                .as_i8()
291                .ok_or_else(|| Self::error(ErrorType::ExpectedSigned)),
292            _ => Err(Self::error(ErrorType::ExpectedSigned)),
293        }
294    }
295
296    #[cfg_attr(not(feature = "no-inline"), inline)]
297    #[allow(clippy::cast_sign_loss)]
298    fn parse_i16(&mut self) -> Result<i16> {
299        match stry!(self.next()) {
300            Node::Static(s) => s
301                .as_i16()
302                .ok_or_else(|| Self::error(ErrorType::ExpectedSigned)),
303            _ => Err(Self::error(ErrorType::ExpectedSigned)),
304        }
305    }
306
307    #[cfg_attr(not(feature = "no-inline"), inline)]
308    #[allow(clippy::cast_sign_loss)]
309    fn parse_i32(&mut self) -> Result<i32> {
310        match stry!(self.next()) {
311            Node::Static(s) => s
312                .as_i32()
313                .ok_or_else(|| Self::error(ErrorType::ExpectedSigned)),
314            _ => Err(Self::error(ErrorType::ExpectedSigned)),
315        }
316    }
317
318    #[cfg_attr(not(feature = "no-inline"), inline)]
319    #[allow(clippy::cast_sign_loss)]
320    fn parse_i64(&mut self) -> Result<i64> {
321        match stry!(self.next()) {
322            Node::Static(s) => s
323                .as_i64()
324                .ok_or_else(|| Self::error(ErrorType::ExpectedSigned)),
325            _ => Err(Self::error(ErrorType::ExpectedSigned)),
326        }
327    }
328
329    #[cfg_attr(not(feature = "no-inline"), inline)]
330    #[allow(clippy::cast_sign_loss)]
331    fn parse_i128(&mut self) -> Result<i128> {
332        match stry!(self.next()) {
333            Node::Static(s) => s
334                .as_i128()
335                .ok_or_else(|| Self::error(ErrorType::ExpectedSigned)),
336            _ => Err(Self::error(ErrorType::ExpectedSigned)),
337        }
338    }
339
340    #[cfg_attr(not(feature = "no-inline"), inline)]
341    #[allow(clippy::cast_possible_wrap, clippy::cast_precision_loss)]
342    fn parse_double(&mut self) -> Result<f64> {
343        match stry!(self.next()) {
344            #[allow(clippy::useless_conversion)] // .into() required by ordered-float
345            Node::Static(StaticNode::F64(n)) => Ok(n.into()),
346            Node::Static(StaticNode::I64(n)) => Ok(n as f64),
347            Node::Static(StaticNode::U64(n)) => Ok(n as f64),
348            _ => Err(Self::error(ErrorType::ExpectedFloat)),
349        }
350    }
351}
352
353impl TryFrom<serde_json::Value> for OwnedValue {
354    type Error = SerdeConversionError;
355    fn try_from(item: serde_json::Value) -> ConvertResult<Self> {
356        use serde_json::Value;
357        Ok(match item {
358            Value::Null => Self::Static(StaticNode::Null),
359            Value::Bool(b) => Self::Static(StaticNode::Bool(b)),
360            Value::Number(b) => {
361                if let Some(n) = b.as_i64() {
362                    Self::Static(StaticNode::I64(n))
363                } else if let Some(n) = b.as_u64() {
364                    Self::Static(StaticNode::U64(n))
365                } else if let Some(n) = b.as_f64() {
366                    Self::Static(StaticNode::from(n))
367                } else {
368                    return Err(SerdeConversionError::Oops);
369                }
370            }
371            Value::String(b) => Self::String(b),
372            Value::Array(a) => a
373                .into_iter()
374                .map(Self::try_from)
375                .collect::<ConvertResult<Self>>()?,
376            Value::Object(o) => o
377                .into_iter()
378                .map(|(k, v)| Ok((k, Self::try_from(v)?)))
379                .collect::<ConvertResult<Self>>()?,
380        })
381    }
382}
383
384impl TryInto<serde_json::Value> for OwnedValue {
385    type Error = SerdeConversionError;
386    fn try_into(self) -> ConvertResult<serde_json::Value> {
387        use serde_json::Value;
388        Ok(match self {
389            Self::Static(StaticNode::Null) => Value::Null,
390            Self::Static(StaticNode::Bool(b)) => Value::Bool(b),
391            Self::Static(StaticNode::I64(n)) => Value::Number(n.into()),
392            #[cfg(feature = "128bit")] // FIXME error for too large numbers
393            Self::Static(StaticNode::I128(n)) => Value::Number(
394                i64::try_from(n)
395                    .map_err(|_| SerdeConversionError::NumberOutOfBounds)?
396                    .into(),
397            ),
398            Self::Static(StaticNode::U64(n)) => Value::Number(n.into()),
399            #[cfg(feature = "128bit")] // FIXME error for too large numbers
400            Self::Static(StaticNode::U128(n)) => Value::Number(
401                u64::try_from(n)
402                    .map_err(|_| SerdeConversionError::NumberOutOfBounds)?
403                    .into(),
404            ),
405            Self::Static(StaticNode::F64(n)) => {
406                #[allow(clippy::useless_conversion)] // .into() required by ordered-float
407                if let Some(n) = serde_json::Number::from_f64(n.into()) {
408                    Value::Number(n)
409                } else {
410                    return Err(SerdeConversionError::NanOrInfinity);
411                }
412            }
413            Self::String(b) => Value::String(b),
414            Self::Array(a) => Value::Array(
415                a.into_iter()
416                    .map(TryInto::try_into)
417                    .collect::<ConvertResult<Vec<Value>>>()?,
418            ),
419            Self::Object(o) => Value::Object(
420                o.into_iter()
421                    .map(|(k, v)| Ok((k, v.try_into()?)))
422                    .collect::<ConvertResult<serde_json::map::Map<String, Value>>>()?,
423            ),
424        })
425    }
426}
427
428impl TryFrom<serde_json::Value> for BorrowedValue<'_> {
429    type Error = SerdeConversionError;
430    fn try_from(item: serde_json::Value) -> ConvertResult<Self> {
431        use serde_json::Value;
432        match item {
433            Value::Null => Ok(BorrowedValue::from(())),
434            Value::Bool(b) => Ok(BorrowedValue::from(b)),
435            Value::Number(b) => match (b.as_i64(), b.as_u64(), b.as_f64()) {
436                (Some(n), _, _) => Ok(Self::from(n)),
437                (_, Some(n), _) => Ok(Self::from(n)),
438                (_, _, Some(n)) => Ok(Self::from(n)),
439                _ => Err(SerdeConversionError::Oops),
440            },
441            Value::String(b) => Ok(Self::String(b.into())),
442            Value::Array(a) => a.into_iter().map(Self::try_from).collect(),
443            Value::Object(o) => o
444                .into_iter()
445                .map(|(k, v)| Ok((k, Self::try_from(v)?)))
446                .collect(),
447        }
448    }
449}
450
451impl TryInto<serde_json::Value> for BorrowedValue<'_> {
452    type Error = SerdeConversionError;
453    fn try_into(self) -> ConvertResult<serde_json::Value> {
454        use serde_json::Value;
455        Ok(match self {
456            BorrowedValue::Static(StaticNode::Null) => Value::Null,
457            BorrowedValue::Static(StaticNode::Bool(b)) => Value::Bool(b),
458            BorrowedValue::Static(StaticNode::I64(n)) => Value::Number(n.into()),
459            #[cfg(feature = "128bit")] // FIXME error for too large numbers
460            BorrowedValue::Static(StaticNode::I128(n)) => Value::Number(
461                i64::try_from(n)
462                    .map_err(|_| SerdeConversionError::NumberOutOfBounds)?
463                    .into(),
464            ),
465            BorrowedValue::Static(StaticNode::U64(n)) => Value::Number(n.into()),
466            #[cfg(feature = "128bit")] // FIXME error for too large numbers
467            BorrowedValue::Static(StaticNode::U128(n)) => Value::Number(
468                u64::try_from(n)
469                    .map_err(|_| SerdeConversionError::NumberOutOfBounds)?
470                    .into(),
471            ),
472            BorrowedValue::Static(StaticNode::F64(n)) => {
473                #[allow(clippy::useless_conversion)] // .into() required by ordered-float
474                if let Some(n) = serde_json::Number::from_f64(n.into()) {
475                    Value::Number(n)
476                } else {
477                    return Err(SerdeConversionError::NanOrInfinity);
478                }
479            }
480            BorrowedValue::String(b) => Value::String(b.to_string()),
481            BorrowedValue::Array(a) => Value::Array(
482                a.into_iter()
483                    .map(TryInto::try_into)
484                    .collect::<ConvertResult<Vec<Value>>>()?,
485            ),
486            BorrowedValue::Object(o) => Value::Object(
487                o.into_iter()
488                    .map(|(k, v)| Ok((k.to_string(), v.try_into()?)))
489                    .collect::<ConvertResult<serde_json::map::Map<String, Value>>>()?,
490            ),
491        })
492    }
493}
494
495#[cfg(test)]
496mod test {
497    #![allow(clippy::unwrap_used)]
498    use crate::{
499        BorrowedValue, Deserializer as SimdDeserializer, ErrorType, OwnedValue, error::Error, json,
500    };
501    use float_cmp::assert_approx_eq;
502    use halfbrown::{HashMap, hashmap};
503    use serde::{Deserialize, Serialize};
504    use serde_json::{Value as SerdeValue, json as sjson, to_string as sto_string};
505    use std::collections::BTreeMap;
506
507    #[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
508    struct UnitStruct;
509    #[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
510    struct NewTypeStruct(u8);
511    #[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
512    struct TupleStruct(u8, u8);
513    #[derive(Debug, Serialize, Deserialize)]
514    struct TestStruct {
515        value: String,
516    }
517    #[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
518    struct TestStruct2 {
519        value: u8,
520    }
521    #[derive(Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
522    enum E {
523        NewTypeVariant(u8),
524        UnitVariant,
525        StructVariant { r: u8, g: u8, b: u8 },
526        StructVariant2 { r: u8, g: u8, b: u8 },
527        TupleVariant(u8, u8, u8),
528    }
529    #[derive(Debug, Serialize, Deserialize)]
530    struct TestPoint(f64, f64);
531
532    #[test]
533    fn convert_owned_value() {
534        let v: OwnedValue = json!({
535            "int": 42,
536            "int2": i64::MAX as u64 + 1,
537            "float": 7.2,
538            "neg-int": -23,
539            "string": "string",
540            "bytes": b"bytes",
541            "bool": true,
542            "null": null,
543            "array": [42, 7, -23, false, null, {"key": "value"}],
544            "object": {
545            "array": [42, 7, -23, false, null, {"key": "value"}],
546            },
547            "tuple": (122, -14, true, 13_i8, -14_i16, 'c', 22_u8, 23_u16, 24_u32, 25_u64, (), None as Option<i32>, Some(3.25_f32), b"bytes"),
548            "struct": TestStruct{value: "value".to_string()},
549            "test_struct": TestStruct2{value: 3},
550            "point": TestPoint(3., 4.),
551            "unit_variant": E::UnitVariant,
552            "new_type_variant": E::NewTypeVariant(3),
553            "struct_variant": E::StructVariant{r:0, g:0, b:0},
554            "tuple_variant": E::TupleVariant(3, 4, 5),
555        });
556
557        let s: SerdeValue = sjson!({
558            "int": 42,
559            "int2": i64::MAX as u64 + 1,
560            "float": 7.2,
561            "neg-int": -23,
562            "string": "string",
563            "bytes": b"bytes",
564            "bool": true,
565            "null": null,
566            "array": [42, 7, -23, false, null, {"key": "value"}],
567            "object": {
568            "array": [42, 7, -23, false, null, {"key": "value"}],
569            },
570            "tuple": (122, -14, true, 13_i8, -14_i16, 'c', 22_u8, 23_u16, 24_u32, 25_u64, (), None as Option<i32>, Some(3.25_f32), b"bytes"),
571            "struct": TestStruct{value: "value".to_string()},
572            "test_struct": TestStruct2{value: 3},
573            "point": TestPoint(3., 4.),
574            "unit_variant": E::UnitVariant,
575            "new_type_variant": E::NewTypeVariant(3),
576            "struct_variant": E::StructVariant{r:0, g:0, b:0},
577            "tuple_variant": E::TupleVariant(3, 4, 5),
578        });
579        let s_c: SerdeValue = v.clone().try_into().unwrap();
580        assert_eq!(s, s_c);
581        let v_c: OwnedValue = s.try_into().unwrap();
582        assert_eq!(v, v_c);
583
584        let mut v_ser = crate::serde::to_string(&v).unwrap();
585        let s_ser = serde_json::to_string(&v).unwrap();
586        assert_eq!(s_ser, v_ser);
587
588        let s_deser: OwnedValue = serde_json::from_str(&v_ser).unwrap();
589        assert_eq!(v, s_deser);
590
591        let v_deser: OwnedValue = unsafe { crate::serde::from_str(&mut v_ser).unwrap() };
592        assert_eq!(v, v_deser);
593    }
594
595    #[test]
596    fn convert_borrowed_value() {
597        let v: BorrowedValue = json!({
598            "int": 42,
599            "int2": i64::MAX as u64 + 1,
600            "float": 7.2,
601            "neg-int": -23,
602            "string": "string",
603            "bool": true,
604            "null": null,
605            "object": {
606            "array": [42, 7, -23, false, null, {"key": "value"}],
607            },
608            "tuple": (122, -14, true, 13_i8, -14_i16, 'c', 22_u8, 23_u16, 24_u32, 25_u64, (), None as Option<i32>, Some(3.25_f32), b"bytes"),
609            "unit_struct": UnitStruct,
610            "new_type_struct": NewTypeStruct(3),
611            "tuple_struct": TupleStruct(3, 4),
612            "struct": TestStruct{value: "value".to_string()},
613            "test_struct": TestStruct2{value: 3},
614            "point": TestPoint(3., 4.),
615            "unit_variant": E::UnitVariant,
616            "new_type_variant": E::NewTypeVariant(3),
617            "struct_variant": E::StructVariant{r:0, g:0, b:0},
618            "tuple_variant": E::TupleVariant(3, 4, 5),
619        })
620        .into();
621
622        let s: SerdeValue = sjson!({
623            "int": 42,
624            "int2": i64::MAX as u64 + 1,
625            "float": 7.2,
626            "neg-int": -23,
627            "string": "string",
628            "bool": true,
629            "null": null,
630            "object": {
631            "array": [42, 7, -23, false, null, {"key": "value"}],
632            },
633            "tuple": (122, -14, true, 13_i8, -14_i16, 'c', 22_u8, 23_u16, 24_u32, 25_u64, (), None as Option<i32>, Some(3.25_f32), b"bytes"),
634            "unit_struct": UnitStruct,
635            "new_type_struct": NewTypeStruct(3),
636            "tuple_struct": TupleStruct(3, 4),
637            "struct": TestStruct{value: "value".to_string()},
638            "test_struct": TestStruct2{value: 3},
639            "point": TestPoint(3., 4.),
640            "unit_variant": E::UnitVariant,
641            "new_type_variant": E::NewTypeVariant(3),
642            "struct_variant": E::StructVariant{r:0, g:0, b:0},
643            "tuple_variant": E::TupleVariant(3, 4, 5),
644        });
645        let s_c: SerdeValue = v.clone().try_into().unwrap();
646        assert_eq!(s, s_c);
647        let v_c: BorrowedValue = s.try_into().unwrap();
648        assert_eq!(v, v_c);
649    }
650
651    #[test]
652    fn option_field_absent() {
653        #[derive(serde::Deserialize, Debug, PartialEq, Eq)]
654        pub struct Person {
655            pub name: String,
656            pub middle_name: Option<String>,
657            pub friends: Vec<String>,
658        }
659        let mut raw_json = r#"{"name":"bob","friends":[]}"#.to_string();
660        let result: Result<Person, _> = super::from_slice(unsafe { raw_json.as_bytes_mut() });
661        assert_eq!(
662            result,
663            Ok(Person {
664                name: "bob".to_string(),
665                middle_name: None,
666                friends: vec![],
667            })
668        );
669    }
670    #[test]
671    fn option_field_present() {
672        #[derive(serde::Deserialize, Debug, PartialEq, Eq)]
673        pub struct Person {
674            pub name: String,
675            pub middle_name: Option<String>,
676            pub friends: Vec<String>,
677        }
678        let mut raw_json = r#"{"name":"bob","middle_name": "frank", "friends":[]}"#.to_string();
679        let result: Result<Person, _> = super::from_slice(unsafe { raw_json.as_bytes_mut() });
680        assert_eq!(
681            result,
682            Ok(Person {
683                name: "bob".to_string(),
684                middle_name: Some("frank".to_string()),
685                friends: vec![],
686            })
687        );
688    }
689
690    #[test]
691    fn convert_enum() {
692        #[allow(dead_code)]
693        #[derive(serde::Deserialize, Debug, PartialEq, Eq)]
694        #[serde(tag = "type")]
695        enum Message {
696            Request { id: usize, method: String },
697            Response { id: String, result: String },
698        }
699
700        #[derive(serde::Deserialize, Debug, PartialEq, Eq)]
701        #[serde(tag = "type", content = "v")]
702        pub enum Color {
703            Red(String), // TODO: If `content` flag is present, `Red` works and `Green` doesn't
704            Green { v: bool },
705            Blue,
706        }
707
708        #[derive(serde::Deserialize, Debug, PartialEq, Eq)]
709        #[serde(tag = "type")]
710        pub enum Color1 {
711            Red(String),
712            Green { v: bool }, // TODO: If `content` flag is absent, `Green` works and `Red` doesn't
713            Blue,
714        }
715
716        let mut raw_json = r#"{"type": "Request", "id": 1, "method": "..."}"#.to_string();
717        let result: Result<Message, _> = super::from_slice(unsafe { raw_json.as_bytes_mut() });
718        assert_eq!(
719            result,
720            Ok(Message::Request {
721                id: 1,
722                method: "...".to_string()
723            })
724        );
725
726        let mut raw_json = r#"{"type": "Response", "id": "1", "result": "..."}"#.to_string();
727        let result: Result<Message, _> = super::from_slice(unsafe { raw_json.as_bytes_mut() });
728        assert_eq!(
729            result,
730            Ok(Message::Response {
731                id: "1".to_string(),
732                result: "...".to_string()
733            })
734        );
735
736        let mut raw_json = r#"{"type": "Red", "v": "1"}"#.to_string();
737        let result: Result<Color, _> = super::from_slice(unsafe { raw_json.as_bytes_mut() });
738        assert_eq!(result, Ok(Color::Red("1".to_string())));
739
740        let mut raw_json = r#"{"type": "Blue"}"#.to_string();
741        let result: Result<Color, _> = super::from_slice(unsafe { raw_json.as_bytes_mut() });
742        assert_eq!(result, Ok(Color::Blue));
743
744        let mut raw_json = r#"{"type": "Green", "v": false}"#.to_string();
745        let result: Result<Color1, _> = super::from_slice(unsafe { raw_json.as_bytes_mut() });
746        assert_eq!(result, Ok(Color1::Green { v: false }));
747
748        let mut raw_json = r#"{"type": "Blue"}"#.to_string();
749        let result: Result<Color1, _> = super::from_slice(unsafe { raw_json.as_bytes_mut() });
750        assert_eq!(result, Ok(Color1::Blue));
751    }
752
753    #[derive(serde_ext::Deserialize)]
754    pub struct Foo {
755        #[allow(unused)]
756        bar: Bar,
757    }
758
759    #[derive(serde_ext::Deserialize)]
760    pub enum Bar {
761        A,
762    }
763
764    #[test]
765    fn object_simd_json() {
766        let mut json = br#"{"bar":"A"}"#.to_vec();
767
768        crate::from_slice::<Foo>(&mut json).unwrap();
769    }
770
771    #[test]
772    fn simple_simd_json() {
773        let mut json = br#""A""#.to_vec();
774
775        assert!(crate::from_slice::<Bar>(&mut json).is_ok());
776    }
777
778    #[test]
779    fn array_as_struct() {
780        #[derive(serde_ext::Deserialize)]
781        struct Point {
782            x: u64,
783            y: u64,
784        }
785
786        let mut json = b"[1,2]".to_vec();
787
788        let p: Point = serde_json::from_slice(&json).unwrap();
789        assert_eq!(p.x, 1);
790        assert_eq!(p.y, 2);
791
792        let p: Point = crate::from_slice(&mut json).unwrap();
793        assert_eq!(p.x, 1);
794        assert_eq!(p.y, 2);
795    }
796
797    #[test]
798    #[allow(clippy::cast_precision_loss)]
799    fn floats() {
800        #[derive(serde_ext::Deserialize)]
801        struct Point {
802            x: f64,
803            y: f64,
804        }
805
806        let mut json = br#"{"x":1.0,"y":2.0}"#.to_vec();
807
808        let p: Point = crate::from_slice(&mut json).unwrap();
809        assert_approx_eq!(f64, p.x, 1_f64);
810        assert_approx_eq!(f64, p.y, 2_f64);
811
812        let json = json!({"x":-1,"y":i64::MAX as u64 + 1});
813
814        let p: Point = unsafe { crate::from_str(&mut crate::to_string(&json).unwrap()).unwrap() };
815        assert_approx_eq!(f64, p.x, -1_f64);
816        assert_approx_eq!(f64, p.y, i64::MAX as f64 + 1.0);
817    }
818
819    #[test]
820    fn vectors() {
821        let input: Vec<UnitStruct> = vec![UnitStruct];
822        let mut v_str = crate::to_string(&input).unwrap();
823        assert_eq!(input, unsafe {
824            crate::from_str::<Vec<UnitStruct>>(&mut v_str).unwrap()
825        });
826        let input: Vec<()> = Vec::new();
827        let mut v_str = crate::to_string(&input).unwrap();
828        assert_eq!(input, unsafe {
829            crate::from_str::<Vec<()>>(&mut v_str).unwrap()
830        });
831        let input: Vec<Option<u8>> = vec![None, Some(3_u8)];
832        let mut v_str = crate::to_string(&input).unwrap();
833        dbg!(&v_str);
834        assert_eq!(input, unsafe {
835            crate::from_str::<Vec<Option<u8>>>(&mut v_str).unwrap()
836        });
837        let input: Vec<(i32, f32)> = vec![(3, 3.)];
838        let mut v_str = crate::to_string(&input).unwrap();
839        assert_eq!(input, unsafe {
840            crate::from_str::<Vec<(i32, f32)>>(&mut v_str).unwrap()
841        });
842        let input = vec![vec![3_u8]];
843        let mut v_str = crate::to_string(&input).unwrap();
844        assert_eq!(input, unsafe {
845            crate::from_str::<Vec<Vec<u8>>>(&mut v_str).unwrap()
846        });
847        let input: Vec<NewTypeStruct> = vec![NewTypeStruct(3_u8)];
848        let mut v_str = crate::to_string(&input).unwrap();
849        assert_eq!(input, unsafe {
850            crate::from_str::<Vec<NewTypeStruct>>(&mut v_str).unwrap()
851        });
852        let input: Vec<TupleStruct> = Vec::new();
853        let mut v_str = crate::to_string(&input).unwrap();
854        assert_eq!(input, unsafe {
855            crate::from_str::<Vec<TupleStruct>>(&mut v_str).unwrap()
856        });
857        let input = vec![TupleStruct(3, 3)];
858        let mut v_str = crate::to_string(&input).unwrap();
859        assert_eq!(input, unsafe {
860            crate::from_str::<Vec<TupleStruct>>(&mut v_str).unwrap()
861        });
862        let input = vec![E::NewTypeVariant(3)];
863        let mut _v_str = crate::to_string(&input).unwrap();
864        // Enums are not handled yet
865        // assert_eq!(input, crate::from_str::<Vec<E>>(&mut v_str).unwrap());
866        let input = vec![E::UnitVariant, E::UnitVariant];
867        let mut _v_str = crate::to_string(&input).unwrap();
868        // Enums are not handled yet
869        // assert_eq!(input, crate::from_str::<Vec<E>>(&mut v_str).unwrap());
870        let input = vec![
871            E::StructVariant { r: 0, g: 0, b: 0 },
872            E::StructVariant { r: 0, g: 0, b: 1 },
873        ];
874        let mut _v_str = crate::to_string(&input).unwrap();
875        // Enums are not handled yet
876        // assert_eq!(input, crate::from_str::<Vec<E>>(&mut v_str).unwrap());
877        let input = vec![E::TupleVariant(0, 0, 0), E::TupleVariant(1, 1, 1)];
878        let mut _v_str = crate::to_string(&input).unwrap();
879        // Enums are not handled yet
880        // assert_eq!(input, crate::from_str::<Vec<E>>(&mut v_str).unwrap());
881    }
882
883    macro_rules! parsing_error {
884        ($input:expr_2021; $type:ty => $err:ident) => {{
885            let mut json_str = $input.to_string();
886            assert_eq!(
887                unsafe { crate::from_str::<$type>(&mut json_str) },
888                Err(SimdDeserializer::error(ErrorType::$err))
889            );
890        }};
891    }
892
893    #[test]
894    fn test_parsing_errors() {
895        parsing_error!(r#""3""#; i8 => ExpectedSigned);
896        parsing_error!(r#""3""#; i16 => ExpectedSigned);
897        parsing_error!(r#""3""#; i32 => ExpectedSigned);
898        parsing_error!(r#""3""#; i64 => ExpectedSigned);
899        parsing_error!(r#""3""#; u8 => ExpectedUnsigned);
900        parsing_error!(r#""3""#; u16 => ExpectedUnsigned);
901        parsing_error!(r#""3""#; u32 => ExpectedUnsigned);
902        parsing_error!(r#""3""#; u64 => ExpectedUnsigned);
903
904        parsing_error!("null"; i8 => ExpectedSigned);
905        parsing_error!("null"; i16 => ExpectedSigned);
906        parsing_error!("null"; i32 => ExpectedSigned);
907        parsing_error!("null"; i64 => ExpectedSigned);
908        parsing_error!("-3"; u8 => ExpectedUnsigned);
909        parsing_error!("-3"; u16 => ExpectedUnsigned);
910        parsing_error!("-3"; u32 => ExpectedUnsigned);
911        parsing_error!("-3"; u64 => ExpectedUnsigned);
912        parsing_error!("-3"; String => ExpectedString);
913
914        #[cfg(feature = "128bit")]
915        {
916            parsing_error!(r#""3""#; i128 => ExpectedSigned);
917            parsing_error!(r#""3""#; u128 => ExpectedUnsigned);
918            parsing_error!("null"; i128 => ExpectedSigned);
919            parsing_error!("-3"; u128 => ExpectedUnsigned);
920        }
921
922        parsing_error!("null"; f64 => ExpectedFloat);
923    }
924
925    macro_rules! ser_deser_map {
926        ($key:expr_2021 => $value:expr_2021, $type:ty) => {
927            let input = hashmap! {$key => $value};
928            let mut m_str = crate::to_string(&input).unwrap();
929            assert_eq!(m_str, sto_string(&input).unwrap());
930            assert_eq!(input, unsafe {
931                crate::from_str::<$type>(&mut m_str).unwrap()
932            });
933        };
934    }
935
936    #[test]
937    fn maps() {
938        let key_error = Err(Error::generic(ErrorType::KeyMustBeAString));
939        assert_eq!(crate::to_string(&hashmap! {b"1234" => 3_i8}), key_error);
940        assert_eq!(crate::to_string(&hashmap! {true => 3_i8}), key_error);
941        assert_eq!(
942            crate::to_string(&hashmap! {[3_u8, 4_u8] => 3_i8}),
943            key_error
944        );
945        assert_eq!(
946            crate::to_string(&hashmap! {None as Option<u8> => 3_i8}),
947            key_error
948        );
949        assert_eq!(crate::to_string(&hashmap! {Some(3_u8) => 3_i8}), key_error);
950        assert_eq!(crate::to_string(&hashmap! {() => 3_i8}), key_error);
951        assert_eq!(crate::to_string(&hashmap! {(3, 4) => 3_i8}), key_error);
952        assert_eq!(crate::to_string(&hashmap! {[3, 4] => 3_i8}), key_error);
953        assert_eq!(crate::to_string(&hashmap! {UnitStruct => 3_i8}), key_error);
954        assert_eq!(
955            crate::to_string(&hashmap! {TupleStruct(3, 3) => 3_i8}),
956            key_error
957        );
958        assert_eq!(
959            crate::to_string(&hashmap! {TestStruct2{value:3} => 3_i8}),
960            key_error
961        );
962        assert_eq!(
963            crate::to_string(&hashmap! {E::NewTypeVariant(0) => 3_i8}),
964            key_error
965        );
966        assert_eq!(
967            crate::to_string(&hashmap! {E::StructVariant{r:0, g:0, b:0} => 3_i8}),
968            key_error
969        );
970        assert_eq!(
971            crate::to_string(&hashmap! {E::StructVariant2{r:0, g:0, b:0} => 3_i8}),
972            key_error
973        );
974        assert_eq!(
975            crate::to_string(&hashmap! {E::TupleVariant(0, 0, 0) => 3_i8}),
976            key_error
977        );
978        assert_eq!(
979            crate::to_string(&hashmap! {vec![0, 0, 0] => 3_i8}),
980            key_error
981        );
982        let mut m = BTreeMap::new();
983        m.insert("value", 3_u8);
984        assert_eq!(crate::to_string(&hashmap! {m => 3_i8}), key_error);
985
986        // f32 and f64 do not implement std::cmp:Eq nor Hash traits
987        // assert_eq!(crate::to_string(&hashmap! {3f32 => 3i8}), key_error);
988        // assert_eq!(crate::to_string(&hashmap! {3f64 => 3i8}), key_error);
989
990        let mut input = std::collections::HashMap::new();
991        input.insert(128_u8, "3");
992        let mut input_str = crate::to_string(&input).unwrap();
993        assert_eq!(input_str, sto_string(&input).unwrap());
994        assert_eq!(
995            unsafe { crate::from_str::<std::collections::HashMap<u8, i8>>(&mut input_str) },
996            Err(Error::new(0, None, ErrorType::ExpectedSigned))
997        );
998        assert_eq!(
999            unsafe { crate::from_str::<std::collections::HashMap<i8, String>>(&mut input_str) },
1000            Err(Error::new(0, None, ErrorType::InvalidNumber))
1001        );
1002        assert_eq!(
1003            unsafe { crate::from_str::<HashMap<Option<u8>, String>>(&mut input_str) },
1004            Ok(hashmap! {Some(128_u8) => "3".to_string()})
1005        );
1006
1007        ser_deser_map!('c' => 3_i8, HashMap<char, i8>);
1008        ser_deser_map!(3_i8 => 3_i8, HashMap<i8, i8>);
1009        ser_deser_map!(3_i16 => 3_i8, HashMap<i16, i8>);
1010        ser_deser_map!(3_i32 => 3_i8, HashMap<i32, i8>);
1011        ser_deser_map!(3_i64 => 3_i8, HashMap<i64, i8>);
1012        ser_deser_map!(3_u8 => 3_i8, HashMap<u8, i8>);
1013        ser_deser_map!(3_u16 => 3_i8, HashMap<u16, i8>);
1014        ser_deser_map!(3_u32 => 3_i8, HashMap<u32, i8>);
1015        ser_deser_map!(3_u64 => 3_i8, HashMap<u64, i8>);
1016        ser_deser_map!(3_i128 => 3_i8, HashMap<i128, i8>);
1017        ser_deser_map!(3_u128 => 3_i8, HashMap<u128, i8>);
1018        ser_deser_map!(NewTypeStruct(1) => 3_i8, HashMap<NewTypeStruct, i8>);
1019        ser_deser_map!(E::UnitVariant => 3_i8, HashMap<E, i8>);
1020    }
1021}