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