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