serde_json_wasm/de/
mod.rs

1//! Deserialize JSON data to a Rust data structure
2
3mod enum_;
4mod errors;
5mod map;
6mod seq;
7mod unescape;
8
9use alloc::string::String;
10
11pub use errors::{Error, Result};
12
13use serde::de::{self, Visitor};
14
15use self::enum_::{StructVariantAccess, UnitVariantAccess};
16use self::map::MapAccess;
17use self::seq::SeqAccess;
18
19/// Deserializer will parse serde-json-wasm flavored JSON into a
20/// serde-annotated struct
21pub struct Deserializer<'b> {
22    slice: &'b [u8],
23    index: usize,
24
25    /// Remaining depth until we hit the recursion limit
26    remaining_depth: u8,
27}
28
29enum StringLike<'a> {
30    Borrowed(&'a str),
31    Owned(String),
32}
33
34impl<'a> Deserializer<'a> {
35    fn new(slice: &'a [u8]) -> Deserializer<'_> {
36        Deserializer {
37            slice,
38            index: 0,
39            remaining_depth: 128,
40        }
41    }
42
43    fn eat_char(&mut self) {
44        self.index += 1;
45    }
46
47    fn end(&mut self) -> Result<()> {
48        match self.parse_whitespace() {
49            Some(_) => Err(Error::TrailingCharacters),
50            None => Ok(()),
51        }
52    }
53
54    fn end_seq(&mut self) -> Result<()> {
55        match self.parse_whitespace().ok_or(Error::EofWhileParsingList)? {
56            b']' => {
57                self.eat_char();
58                Ok(())
59            }
60            b',' => {
61                self.eat_char();
62                match self.parse_whitespace() {
63                    Some(b']') => Err(Error::TrailingComma),
64                    _ => Err(Error::TrailingCharacters),
65                }
66            }
67            _ => Err(Error::TrailingCharacters),
68        }
69    }
70
71    fn end_map(&mut self) -> Result<()> {
72        match self
73            .parse_whitespace()
74            .ok_or(Error::EofWhileParsingObject)?
75        {
76            b'}' => {
77                self.eat_char();
78                Ok(())
79            }
80            b',' => Err(Error::TrailingComma),
81            _ => Err(Error::TrailingCharacters),
82        }
83    }
84
85    fn next_char(&mut self) -> Option<u8> {
86        let ch = self.slice.get(self.index);
87
88        if ch.is_some() {
89            self.index += 1;
90        }
91
92        ch.cloned()
93    }
94
95    fn parse_ident(&mut self, ident: &[u8]) -> Result<()> {
96        for c in ident {
97            if Some(*c) != self.next_char() {
98                return Err(Error::ExpectedSomeIdent);
99            }
100        }
101
102        Ok(())
103    }
104
105    fn parse_object_colon(&mut self) -> Result<()> {
106        match self
107            .parse_whitespace()
108            .ok_or(Error::EofWhileParsingObject)?
109        {
110            b':' => {
111                self.eat_char();
112                Ok(())
113            }
114            _ => Err(Error::ExpectedColon),
115        }
116    }
117
118    fn parse_string(&mut self) -> Result<StringLike<'a>> {
119        let start = self.index;
120        let mut contains_backslash = false;
121        let mut escaped = false;
122        loop {
123            match self.peek() {
124                Some(b'"') => {
125                    if escaped {
126                        escaped = false;
127                        self.eat_char(); // just continue
128                    } else {
129                        let end = self.index;
130                        self.eat_char();
131                        return if contains_backslash {
132                            Ok(StringLike::Owned(unescape::unescape(
133                                &self.slice[start..end],
134                            )?))
135                        } else {
136                            Ok(StringLike::Borrowed(
137                                core::str::from_utf8(&self.slice[start..end])
138                                    .map_err(|_| Error::InvalidUnicodeCodePoint)?,
139                            ))
140                        };
141                    }
142                }
143                Some(b'\\') => {
144                    contains_backslash = true;
145                    escaped = !escaped;
146                    self.eat_char()
147                }
148                Some(_) => {
149                    escaped = false;
150                    self.eat_char()
151                }
152                None => return Err(Error::EofWhileParsingString),
153            }
154        }
155    }
156
157    /// Consumes all the whitespace characters and returns a peek into the next character
158    fn parse_whitespace(&mut self) -> Option<u8> {
159        loop {
160            match self.peek() {
161                Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') => {
162                    self.eat_char();
163                }
164                other => {
165                    return other;
166                }
167            }
168        }
169    }
170
171    fn peek(&mut self) -> Option<u8> {
172        self.slice.get(self.index).cloned()
173    }
174}
175
176// NOTE(deserialize_*signed) we avoid parsing into u64 and then casting to a smaller integer, which
177// is what upstream does, to avoid pulling in 64-bit compiler intrinsics, which waste a few KBs of
178// Flash, when targeting non 64-bit architectures
179macro_rules! deserialize_unsigned {
180    ($self:ident, $visitor:ident, $uxx:ident, $visit_uxx:ident) => {{
181        let peek = $self
182            .parse_whitespace()
183            .ok_or(Error::EofWhileParsingValue)?;
184
185        match peek {
186            b'-' => Err(Error::InvalidNumber),
187            b'0' => {
188                $self.eat_char();
189                $visitor.$visit_uxx(0)
190            }
191            b'1'..=b'9' => {
192                $self.eat_char();
193
194                let mut number = (peek - b'0') as $uxx;
195                loop {
196                    match $self.peek() {
197                        Some(c @ b'0'..=b'9') => {
198                            $self.eat_char();
199                            number = number
200                                .checked_mul(10)
201                                .ok_or(Error::InvalidNumber)?
202                                .checked_add((c - b'0') as $uxx)
203                                .ok_or(Error::InvalidNumber)?;
204                        }
205                        _ => break,
206                    }
207                }
208                $visitor.$visit_uxx(number)
209            }
210            _ => Err(Error::InvalidType),
211        }
212    }};
213}
214pub(crate) use deserialize_unsigned;
215
216macro_rules! deserialize_signed {
217    ($self:ident, $visitor:ident, $ixx:ident, $visit_ixx:ident) => {{
218        let signed = match $self
219            .parse_whitespace()
220            .ok_or(Error::EofWhileParsingValue)?
221        {
222            b'-' => {
223                $self.eat_char();
224                true
225            }
226            _ => false,
227        };
228
229        match $self.peek().ok_or(Error::EofWhileParsingValue)? {
230            b'0' => {
231                $self.eat_char();
232                $visitor.$visit_ixx(0)
233            }
234            c @ b'1'..=b'9' => {
235                $self.eat_char();
236
237                let mut number = (c - b'0') as $ixx * if signed { -1 } else { 1 };
238                loop {
239                    match $self.peek() {
240                        Some(c @ b'0'..=b'9') => {
241                            $self.eat_char();
242                            number = number
243                                .checked_mul(10)
244                                .ok_or(Error::InvalidNumber)?
245                                .checked_add((c - b'0') as $ixx * if signed { -1 } else { 1 })
246                                .ok_or(Error::InvalidNumber)?;
247                        }
248                        _ => break,
249                    }
250                }
251                $visitor.$visit_ixx(number)
252            }
253            _ => return Err(Error::InvalidType),
254        }
255    }};
256}
257pub(crate) use deserialize_signed;
258
259impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> {
260    type Error = Error;
261
262    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
263    where
264        V: Visitor<'de>,
265    {
266        match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
267            b'n' => {
268                self.eat_char();
269                self.parse_ident(b"ull")?;
270                visitor.visit_unit()
271            }
272            b't' => {
273                self.eat_char();
274                self.parse_ident(b"rue")?;
275                visitor.visit_bool(true)
276            }
277            b'f' => {
278                self.eat_char();
279                self.parse_ident(b"alse")?;
280                visitor.visit_bool(false)
281            }
282            b'-' => {
283                deserialize_signed!(self, visitor, i64, visit_i64)
284            }
285            b'0'..=b'9' => {
286                deserialize_unsigned!(self, visitor, u64, visit_u64)
287            }
288            b'"' => {
289                self.eat_char();
290                let str_like = self.parse_string()?;
291                match str_like {
292                    StringLike::Borrowed(str) => visitor.visit_borrowed_str(str),
293                    StringLike::Owned(string) => visitor.visit_string(string),
294                }
295            }
296            b'[' => {
297                check_recursion! {
298                    self.eat_char();
299                    let ret = visitor.visit_seq(SeqAccess::new(self));
300                }
301                let ret = ret?;
302
303                self.end_seq()?;
304
305                Ok(ret)
306            }
307            b'{' => {
308                check_recursion! {
309                    self.eat_char();
310                    let ret = visitor.visit_map(MapAccess::new(self));
311                }
312                let ret = ret?;
313
314                self.end_map()?;
315
316                Ok(ret)
317            }
318            _ => Err(Error::ExpectedSomeValue),
319        }
320    }
321
322    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
323    where
324        V: Visitor<'de>,
325    {
326        let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
327
328        match peek {
329            b't' => {
330                self.eat_char();
331                self.parse_ident(b"rue")?;
332                visitor.visit_bool(true)
333            }
334            b'f' => {
335                self.eat_char();
336                self.parse_ident(b"alse")?;
337                visitor.visit_bool(false)
338            }
339            _ => Err(Error::InvalidType),
340        }
341    }
342
343    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
344    where
345        V: Visitor<'de>,
346    {
347        deserialize_signed!(self, visitor, i8, visit_i8)
348    }
349
350    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
351    where
352        V: Visitor<'de>,
353    {
354        deserialize_signed!(self, visitor, i16, visit_i16)
355    }
356
357    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
358    where
359        V: Visitor<'de>,
360    {
361        deserialize_signed!(self, visitor, i32, visit_i32)
362    }
363
364    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
365    where
366        V: Visitor<'de>,
367    {
368        deserialize_signed!(self, visitor, i64, visit_i64)
369    }
370
371    fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
372    where
373        V: Visitor<'de>,
374    {
375        deserialize_signed!(self, visitor, i128, visit_i128)
376    }
377
378    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
379    where
380        V: Visitor<'de>,
381    {
382        deserialize_unsigned!(self, visitor, u8, visit_u8)
383    }
384
385    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
386    where
387        V: Visitor<'de>,
388    {
389        deserialize_unsigned!(self, visitor, u16, visit_u16)
390    }
391
392    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
393    where
394        V: Visitor<'de>,
395    {
396        deserialize_unsigned!(self, visitor, u32, visit_u32)
397    }
398
399    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
400    where
401        V: Visitor<'de>,
402    {
403        deserialize_unsigned!(self, visitor, u64, visit_u64)
404    }
405
406    fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
407    where
408        V: Visitor<'de>,
409    {
410        deserialize_unsigned!(self, visitor, u128, visit_u128)
411    }
412
413    fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value>
414    where
415        V: Visitor<'de>,
416    {
417        unreachable!()
418    }
419
420    fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value>
421    where
422        V: Visitor<'de>,
423    {
424        unreachable!()
425    }
426
427    fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value>
428    where
429        V: Visitor<'de>,
430    {
431        unreachable!()
432    }
433
434    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
435    where
436        V: Visitor<'de>,
437    {
438        self.deserialize_string(visitor)
439    }
440
441    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
442    where
443        V: Visitor<'de>,
444    {
445        let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
446
447        match peek {
448            b'"' => {
449                self.eat_char();
450                let str_like = self.parse_string()?;
451                match str_like {
452                    StringLike::Borrowed(str) => visitor.visit_borrowed_str(str),
453                    StringLike::Owned(string) => visitor.visit_string(string),
454                }
455            }
456            _ => Err(Error::InvalidType),
457        }
458    }
459
460    /// Unsupported
461    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
462    where
463        V: Visitor<'de>,
464    {
465        unreachable!()
466    }
467
468    /// Unsupported
469    fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
470    where
471        V: Visitor<'de>,
472    {
473        unreachable!()
474    }
475
476    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
477    where
478        V: Visitor<'de>,
479    {
480        match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
481            b'n' => {
482                self.eat_char();
483                self.parse_ident(b"ull")?;
484                visitor.visit_none()
485            }
486            _ => visitor.visit_some(self),
487        }
488    }
489
490    /// Resolves "null" to ()
491    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
492    where
493        V: Visitor<'de>,
494    {
495        let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
496
497        if peek == b'n' {
498            self.eat_char();
499            self.parse_ident(b"ull")?;
500            let ret = visitor.visit_unit()?;
501            Ok(ret)
502        } else {
503            Err(Error::InvalidType)
504        }
505    }
506
507    /// Resolves "null" to requested unit struct
508    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
509    where
510        V: Visitor<'de>,
511    {
512        self.deserialize_unit(visitor)
513    }
514
515    /// Unsupported. We can’t parse newtypes because we don’t know the underlying type.
516    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
517    where
518        V: Visitor<'de>,
519    {
520        visitor.visit_newtype_struct(self)
521    }
522
523    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
524    where
525        V: Visitor<'de>,
526    {
527        match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
528            b'[' => {
529                check_recursion! {
530                    self.eat_char();
531                    let ret = visitor.visit_seq(SeqAccess::new(self));
532                }
533                let ret = ret?;
534
535                self.end_seq()?;
536
537                Ok(ret)
538            }
539            _ => Err(Error::InvalidType),
540        }
541    }
542
543    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
544    where
545        V: Visitor<'de>,
546    {
547        self.deserialize_seq(visitor)
548    }
549
550    fn deserialize_tuple_struct<V>(
551        self,
552        _name: &'static str,
553        _len: usize,
554        visitor: V,
555    ) -> Result<V::Value>
556    where
557        V: Visitor<'de>,
558    {
559        self.deserialize_seq(visitor)
560    }
561
562    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
563    where
564        V: Visitor<'de>,
565    {
566        let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
567
568        if peek == b'{' {
569            check_recursion! {
570                self.eat_char();
571                let ret = visitor.visit_map(MapAccess::new(self));
572            }
573            let ret = ret?;
574
575            self.end_map()?;
576
577            Ok(ret)
578        } else {
579            Err(Error::InvalidType)
580        }
581    }
582
583    fn deserialize_struct<V>(
584        self,
585        _name: &'static str,
586        _fields: &'static [&'static str],
587        visitor: V,
588    ) -> Result<V::Value>
589    where
590        V: Visitor<'de>,
591    {
592        self.deserialize_map(visitor)
593    }
594
595    fn deserialize_enum<V>(
596        self,
597        _name: &'static str,
598        _variants: &'static [&'static str],
599        visitor: V,
600    ) -> Result<V::Value>
601    where
602        V: Visitor<'de>,
603    {
604        match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
605            // if it is a string enum
606            b'"' => visitor.visit_enum(UnitVariantAccess::new(self)),
607            // if it is a struct enum
608            b'{' => {
609                check_recursion! {
610                    self.eat_char();
611                    let value = visitor.visit_enum(StructVariantAccess::new(self));
612                }
613                value
614            }
615            _ => Err(Error::ExpectedSomeIdent),
616        }
617    }
618
619    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
620    where
621        V: Visitor<'de>,
622    {
623        self.deserialize_str(visitor)
624    }
625
626    /// Used to throw out fields from JSON objects that we don’t want to
627    /// keep in our structs.
628    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
629    where
630        V: Visitor<'de>,
631    {
632        match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
633            b'"' => self.deserialize_str(visitor),
634            b'[' => self.deserialize_seq(visitor),
635            b'{' => self.deserialize_struct("ignored", &[], visitor),
636            b',' | b'}' | b']' => Err(Error::ExpectedSomeValue),
637            // If it’s something else then we chomp until we get to an end delimiter.
638            // This does technically allow for illegal JSON since we’re just ignoring
639            // characters rather than parsing them.
640            _ => loop {
641                match self.peek() {
642                    // The visitor is expected to be UnknownAny’s visitor, which
643                    // implements visit_unit to return its unit Ok result.
644                    Some(b',') | Some(b'}') | Some(b']') => break visitor.visit_unit(),
645                    Some(_) => self.eat_char(),
646                    None => break Err(Error::EofWhileParsingString),
647                }
648            },
649        }
650    }
651}
652
653/// Deserializes an instance of type `T` from bytes of JSON text
654pub fn from_slice<T>(v: &[u8]) -> Result<T>
655where
656    T: de::DeserializeOwned,
657{
658    let mut de = Deserializer::new(v);
659    let value = de::Deserialize::deserialize(&mut de)?;
660    de.end()?;
661
662    Ok(value)
663}
664
665/// Deserializes an instance of type T from a string of JSON text
666pub fn from_str<T>(s: &str) -> Result<T>
667where
668    T: de::DeserializeOwned,
669{
670    from_slice(s.as_bytes())
671}
672
673macro_rules! check_recursion {
674    ($this:ident $($body:tt)*) => {
675        $this.remaining_depth -= 1;
676        if $this.remaining_depth == 0 {
677            return Err($crate::de::Error::RecursionLimitExceeded);
678        }
679
680        $this $($body)*
681
682        $this.remaining_depth += 1;
683    };
684}
685pub(crate) use check_recursion;
686
687#[cfg(test)]
688mod tests {
689    use super::from_str;
690
691    use alloc::string::{String, ToString};
692    use alloc::vec;
693    use alloc::vec::Vec;
694
695    use serde_derive::{Deserialize, Serialize};
696
697    #[derive(Debug, Deserialize, PartialEq)]
698    enum Type {
699        #[serde(rename = "boolean")]
700        Boolean,
701        #[serde(rename = "number")]
702        Number,
703        #[serde(rename = "thing")]
704        Thing,
705    }
706
707    #[test]
708    fn parse_whitespace() {
709        assert_eq!(from_str(" true"), Ok(true));
710        assert_eq!(from_str("\ttrue"), Ok(true));
711        assert_eq!(from_str("\ntrue"), Ok(true));
712        assert_eq!(from_str("\rtrue"), Ok(true));
713        assert_eq!(from_str("\n\rtrue"), Ok(true));
714        assert_eq!(from_str("\r\ntrue"), Ok(true));
715        assert_eq!(from_str("true "), Ok(true));
716        assert_eq!(from_str("true\t"), Ok(true));
717        assert_eq!(from_str("true\n"), Ok(true));
718        assert_eq!(from_str("true\r"), Ok(true));
719        assert_eq!(from_str("true\n\r"), Ok(true));
720        assert_eq!(from_str("true\r\n"), Ok(true));
721
722        assert_eq!(from_str("[4,5]"), Ok([4, 5]));
723        assert_eq!(from_str(" [4,5]"), Ok([4, 5]));
724        assert_eq!(from_str("\t[4,5]"), Ok([4, 5]));
725        assert_eq!(from_str("\n[4,5]"), Ok([4, 5]));
726        assert_eq!(from_str("\r[4,5]"), Ok([4, 5]));
727        assert_eq!(from_str("\n\r[4,5]"), Ok([4, 5]));
728        assert_eq!(from_str("\r\n[4,5]"), Ok([4, 5]));
729        assert_eq!(from_str("[ 4,5]"), Ok([4, 5]));
730        assert_eq!(from_str("[\t4,5]"), Ok([4, 5]));
731        assert_eq!(from_str("[\n4,5]"), Ok([4, 5]));
732        assert_eq!(from_str("[\r4,5]"), Ok([4, 5]));
733        assert_eq!(from_str("[\n\r4,5]"), Ok([4, 5]));
734        assert_eq!(from_str("[\r\n4,5]"), Ok([4, 5]));
735        assert_eq!(from_str("[4 ,5]"), Ok([4, 5]));
736        assert_eq!(from_str("[4\t,5]"), Ok([4, 5]));
737        assert_eq!(from_str("[4\n,5]"), Ok([4, 5]));
738        assert_eq!(from_str("[4\r,5]"), Ok([4, 5]));
739        assert_eq!(from_str("[4\n\r,5]"), Ok([4, 5]));
740        assert_eq!(from_str("[4\r\n,5]"), Ok([4, 5]));
741        assert_eq!(from_str("[4, 5]"), Ok([4, 5]));
742        assert_eq!(from_str("[4,\t5]"), Ok([4, 5]));
743        assert_eq!(from_str("[4,\n5]"), Ok([4, 5]));
744        assert_eq!(from_str("[4,\r5]"), Ok([4, 5]));
745        assert_eq!(from_str("[4,\n\r5]"), Ok([4, 5]));
746        assert_eq!(from_str("[4,\r\n5]"), Ok([4, 5]));
747        assert_eq!(from_str("[4,5 ]"), Ok([4, 5]));
748        assert_eq!(from_str("[4,5\t]"), Ok([4, 5]));
749        assert_eq!(from_str("[4,5\n]"), Ok([4, 5]));
750        assert_eq!(from_str("[4,5\r]"), Ok([4, 5]));
751        assert_eq!(from_str("[4,5\n\r]"), Ok([4, 5]));
752        assert_eq!(from_str("[4,5\r\n]"), Ok([4, 5]));
753        assert_eq!(from_str("[4,5] "), Ok([4, 5]));
754        assert_eq!(from_str("[4,5]\t"), Ok([4, 5]));
755        assert_eq!(from_str("[4,5]\n"), Ok([4, 5]));
756        assert_eq!(from_str("[4,5]\r"), Ok([4, 5]));
757        assert_eq!(from_str("[4,5]\n\r"), Ok([4, 5]));
758        assert_eq!(from_str("[4,5]\r\n"), Ok([4, 5]));
759    }
760
761    #[test]
762    fn integer128() {
763        assert_eq!(
764            from_str::<i128>(r#""0""#),
765            Err(crate::de::Error::InvalidType)
766        );
767        assert_eq!(from_str::<i128>(r#"0"#), Ok(0));
768        assert_eq!(from_str::<i128>(r#"1"#), Ok(1));
769        assert_eq!(from_str::<i128>(r#"-1"#), Ok(-1));
770        // max i128
771        assert_eq!(
772            from_str::<i128>(r#"170141183460469231731687303715884105727"#),
773            Ok(170141183460469231731687303715884105727)
774        );
775        assert_eq!(
776            from_str::<i128>(r#"170141183460469231731687303715884105728"#),
777            Err(crate::de::Error::InvalidNumber)
778        );
779        // min i128
780        assert_eq!(
781            from_str::<i128>(r#"-170141183460469231731687303715884105728"#),
782            Ok(-170141183460469231731687303715884105728)
783        );
784        assert_eq!(
785            from_str::<i128>(r#"-170141183460469231731687303715884105729"#),
786            Err(crate::de::Error::InvalidNumber)
787        );
788
789        assert_eq!(
790            from_str::<u128>(r#""0""#),
791            Err(crate::de::Error::InvalidType)
792        );
793        assert_eq!(from_str::<u128>(r#"0"#), Ok(0));
794        assert_eq!(from_str::<u128>(r#"1"#), Ok(1));
795        assert_eq!(
796            from_str::<u128>(r#"-1"#),
797            Err(crate::de::Error::InvalidNumber)
798        );
799        // max u128
800        assert_eq!(
801            from_str::<u128>(r#"340282366920938463463374607431768211455"#),
802            Ok(340282366920938463463374607431768211455)
803        );
804        assert_eq!(
805            from_str::<u128>(r#"340282366920938463463374607431768211456"#),
806            Err(crate::de::Error::InvalidNumber)
807        )
808    }
809
810    #[test]
811    fn array() {
812        assert_eq!(from_str::<[i32; 0]>("[]"), Ok([]));
813        assert_eq!(from_str("[0, 1, 2]"), Ok([0, 1, 2]));
814
815        // errors
816        assert!(from_str::<[i32; 2]>("[0, 1,]").is_err());
817    }
818
819    #[allow(clippy::let_unit_value)]
820    #[allow(clippy::unit_cmp)]
821    #[test]
822    fn tuple() {
823        type Pair = (i64, i64);
824        type Wrapped = (i64,); // Comma differentiates one element tuple from a primary type surrounded by parentheses
825        type Unit = ();
826
827        let pair: Pair = (1, 2);
828        assert_eq!(from_str("[1,2]"), Ok(pair));
829        assert_eq!(serde_json::from_str::<Pair>("[1,2]").unwrap(), pair);
830
831        let wrapped: Wrapped = (5,);
832        assert_eq!(from_str("[5]"), Ok(wrapped));
833        assert_eq!(serde_json::from_str::<Wrapped>("[5]").unwrap(), wrapped);
834
835        let unit: Unit = ();
836        assert_eq!(from_str("null"), Ok(unit));
837        assert_eq!(serde_json::from_str::<()>("null").unwrap(), unit);
838    }
839
840    #[test]
841    fn tuple_variant() {
842        #[derive(Debug, Deserialize, PartialEq)]
843        enum Ops {
844            Exit(),
845            Square(i32),
846            Add(i64, i64),
847        }
848        assert_eq!(from_str(r#"{"Exit":[]}"#), Ok(Ops::Exit()));
849        assert_eq!(
850            serde_json::from_str::<Ops>(r#"{"Exit":[]}"#).unwrap(),
851            Ops::Exit()
852        );
853        assert_eq!(from_str(r#"{"Square":1}"#), Ok(Ops::Square(1)));
854        assert_eq!(
855            serde_json::from_str::<Ops>(r#"{"Square":1}"#).unwrap(),
856            Ops::Square(1)
857        );
858        assert_eq!(from_str(r#"{"Add":[2,3]}"#), Ok(Ops::Add(2, 3)));
859        assert_eq!(
860            serde_json::from_str::<Ops>(r#"{"Add":[2,3]}"#).unwrap(),
861            Ops::Add(2, 3)
862        );
863    }
864
865    #[test]
866    fn bool() {
867        assert_eq!(from_str("true"), Ok(true));
868        assert_eq!(from_str(" true"), Ok(true));
869        assert_eq!(from_str("true "), Ok(true));
870
871        assert_eq!(from_str("false"), Ok(false));
872        assert_eq!(from_str(" false"), Ok(false));
873        assert_eq!(from_str("false "), Ok(false));
874
875        // errors
876        assert!(from_str::<bool>("true false").is_err());
877        assert!(from_str::<bool>("tru").is_err());
878    }
879
880    #[test]
881    fn enum_clike() {
882        assert_eq!(from_str(r#" "boolean" "#), Ok(Type::Boolean));
883        assert_eq!(from_str(r#" "number" "#), Ok(Type::Number));
884        assert_eq!(from_str(r#" "thing" "#), Ok(Type::Thing));
885    }
886
887    #[test]
888    fn string() {
889        assert_eq!(from_str(r#" "hello" "#), Ok("hello".to_string()));
890        assert_eq!(from_str(r#" "" "#), Ok("".to_string()));
891        assert_eq!(from_str(r#" " " "#), Ok(" ".to_string()));
892        assert_eq!(from_str(r#" "👏" "#), Ok("👏".to_string()));
893
894        // Unescapes things
895        assert_eq!(from_str(r#" "hel\tlo" "#), Ok("hel\tlo".to_string()));
896        assert_eq!(from_str(r#" "hel\\lo" "#), Ok("hel\\lo".to_string()));
897
898        // escaped " in the string content
899        assert_eq!(from_str(r#" "foo\"bar" "#), Ok(r#"foo"bar"#.to_string()));
900        assert_eq!(from_str(r#" "foo\\\"ba" "#), Ok(r#"foo\"ba"#.to_string()));
901        assert_eq!(from_str(r#" "foo\"\"ba" "#), Ok(r#"foo""ba"#.to_string()));
902        assert_eq!(from_str(r#" "\"bar" "#), Ok(r#""bar"#.to_string()));
903        assert_eq!(from_str(r#" "foo\"" "#), Ok(r#"foo""#.to_string()));
904        assert_eq!(from_str(r#" "\"" "#), Ok(r#"""#.to_string()));
905
906        // non-escaped " preceded by backslashes
907        assert_eq!(from_str(r#" "fooooo\\" "#), Ok(r#"fooooo\"#.to_string()));
908        assert_eq!(from_str(r#" "fooo\\\\" "#), Ok(r#"fooo\\"#.to_string()));
909        assert_eq!(from_str(r#" "fo\\\\\\" "#), Ok(r#"fo\\\"#.to_string()));
910        assert_eq!(from_str(r#" "\\\\\\\\" "#), Ok(r#"\\\\"#.to_string()));
911    }
912
913    #[test]
914    fn struct_bool() {
915        #[derive(Debug, Deserialize, PartialEq)]
916        struct Led {
917            led: bool,
918        }
919
920        assert_eq!(from_str(r#"{ "led": true }"#), Ok(Led { led: true }));
921        assert_eq!(from_str(r#"{ "led": false }"#), Ok(Led { led: false }));
922    }
923
924    #[test]
925    fn struct_i8() {
926        #[derive(Debug, Deserialize, PartialEq)]
927        struct Temperature {
928            temperature: i8,
929        }
930
931        assert_eq!(
932            from_str(r#"{ "temperature": -17 }"#),
933            Ok(Temperature { temperature: -17 })
934        );
935
936        assert_eq!(
937            from_str(r#"{ "temperature": -0 }"#),
938            Ok(Temperature { temperature: -0 })
939        );
940
941        assert_eq!(
942            from_str(r#"{ "temperature": 0 }"#),
943            Ok(Temperature { temperature: 0 })
944        );
945
946        // out of range
947        assert!(from_str::<Temperature>(r#"{ "temperature": 128 }"#).is_err());
948        assert!(from_str::<Temperature>(r#"{ "temperature": -129 }"#).is_err());
949    }
950
951    #[test]
952    fn struct_option() {
953        #[derive(Debug, Deserialize, PartialEq)]
954        struct Property {
955            description: Option<String>,
956        }
957
958        assert_eq!(
959            from_str(r#"{ "description": "An ambient temperature sensor" }"#),
960            Ok(Property {
961                description: Some("An ambient temperature sensor".to_string()),
962            })
963        );
964
965        assert_eq!(
966            from_str(r#"{ "description": null }"#),
967            Ok(Property { description: None })
968        );
969
970        assert_eq!(from_str(r#"{}"#), Ok(Property { description: None }));
971    }
972
973    #[test]
974    fn struct_u8() {
975        #[derive(Debug, Deserialize, PartialEq)]
976        struct Temperature {
977            temperature: u8,
978        }
979
980        assert_eq!(
981            from_str(r#"{ "temperature": 20 }"#),
982            Ok(Temperature { temperature: 20 })
983        );
984
985        assert_eq!(
986            from_str(r#"{ "temperature": 0 }"#),
987            Ok(Temperature { temperature: 0 })
988        );
989
990        // out of range
991        assert!(from_str::<Temperature>(r#"{ "temperature": 256 }"#).is_err());
992        assert!(from_str::<Temperature>(r#"{ "temperature": -1 }"#).is_err());
993    }
994
995    #[test]
996    fn struct_tuple() {
997        #[derive(Debug, Deserialize, PartialEq)]
998        struct Xy(i8, i8);
999
1000        assert_eq!(from_str(r#"[10, 20]"#), Ok(Xy(10, 20)));
1001        assert_eq!(from_str(r#"[10, -20]"#), Ok(Xy(10, -20)));
1002
1003        // wrong number of args
1004        match from_str::<Xy>(r#"[10]"#) {
1005            Err(super::Error::Custom(_)) => {}
1006            _ => panic!("expect custom error"),
1007        }
1008        assert_eq!(
1009            from_str::<Xy>(r#"[10, 20, 30]"#),
1010            Err(crate::de::Error::TrailingCharacters)
1011        );
1012    }
1013
1014    #[test]
1015    fn struct_empty() {
1016        #[derive(Debug, Deserialize, PartialEq)]
1017        struct Empty {}
1018
1019        assert_eq!(from_str(r#"{}"#), Ok(Empty {}));
1020        assert_eq!(serde_json::from_str::<Empty>(r#"{}"#).unwrap(), Empty {});
1021    }
1022
1023    #[test]
1024    fn struct_nothing() {
1025        #[derive(Debug, Deserialize, PartialEq)]
1026        struct Nothing;
1027
1028        assert_eq!(from_str(r#"null"#), Ok(Nothing));
1029        assert_eq!(serde_json::from_str::<Nothing>(r#"null"#).unwrap(), Nothing);
1030    }
1031
1032    #[test]
1033    fn struct_with_flatten() {
1034        #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
1035        struct Pagination {
1036            limit: u64,
1037            offset: u64,
1038            total: u64,
1039        }
1040
1041        #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
1042        struct Users {
1043            users: Vec<String>,
1044
1045            #[serde(flatten)]
1046            pagination: Pagination,
1047        }
1048
1049        let expected = Users {
1050            users: vec!["joe".to_string(), "alice".to_string()],
1051            pagination: Pagination {
1052                offset: 100,
1053                limit: 20,
1054                total: 102,
1055            },
1056        };
1057
1058        assert_eq!(
1059            from_str::<Users>(r#"{"users":["joe","alice"],"limit":20,"offset":100,"total":102}"#)
1060                .unwrap(),
1061            expected,
1062        );
1063    }
1064
1065    #[test]
1066    fn ignoring_extra_fields() {
1067        #[derive(Debug, Deserialize, PartialEq)]
1068        struct Temperature {
1069            temperature: u8,
1070        }
1071
1072        assert_eq!(
1073            from_str(r#"{ "temperature": 20, "high": 80, "low": -10, "updated": true }"#),
1074            Ok(Temperature { temperature: 20 })
1075        );
1076
1077        assert_eq!(
1078            from_str(r#"{ "temperature": 20, "conditions": "windy", "forecast": "cloudy" }"#),
1079            Ok(Temperature { temperature: 20 })
1080        );
1081
1082        assert_eq!(
1083            from_str(r#"{ "temperature": 20, "hourly_conditions": ["windy", "rainy"] }"#),
1084            Ok(Temperature { temperature: 20 })
1085        );
1086
1087        assert_eq!(
1088            from_str(
1089                r#"{ "temperature": 20, "source": { "station": "dock", "sensors": ["front", "back"] } }"#
1090            ),
1091            Ok(Temperature { temperature: 20 })
1092        );
1093
1094        assert_eq!(
1095            from_str(r#"{ "temperature": 20, "invalid": this-is-ignored }"#),
1096            Ok(Temperature { temperature: 20 })
1097        );
1098
1099        assert_eq!(
1100            from_str::<Temperature>(r#"{ "temperature": 20, "broken": }"#),
1101            Err(crate::de::Error::ExpectedSomeValue)
1102        );
1103
1104        assert_eq!(
1105            from_str::<Temperature>(r#"{ "temperature": 20, "broken": [ }"#),
1106            Err(crate::de::Error::ExpectedSomeValue)
1107        );
1108
1109        assert_eq!(
1110            from_str::<Temperature>(r#"{ "temperature": 20, "broken": ] }"#),
1111            Err(crate::de::Error::ExpectedSomeValue)
1112        );
1113    }
1114
1115    #[test]
1116    fn newtypes() {
1117        #[derive(Deserialize, Debug, PartialEq)]
1118        struct Address(String);
1119
1120        #[derive(Deserialize, Debug, PartialEq)]
1121        struct CommentId(u32);
1122
1123        #[derive(Deserialize, Debug, PartialEq)]
1124        struct NewtypeDemo {
1125            address: Address,
1126            comment: CommentId,
1127        }
1128
1129        let element: Address = from_str(r#""johnny""#).unwrap();
1130        assert_eq!(element, Address("johnny".to_string()));
1131
1132        let element: CommentId = from_str(r#"5464813"#).unwrap();
1133        assert_eq!(element, CommentId(5464813));
1134
1135        let element: NewtypeDemo = from_str(r#"{"address": "johnny", "comment": 9897}"#).unwrap();
1136        assert_eq!(
1137            element,
1138            NewtypeDemo {
1139                address: Address("johnny".to_string()),
1140                comment: CommentId(9897),
1141            }
1142        );
1143    }
1144
1145    #[test]
1146    fn numbered_key_maps() {
1147        use alloc::collections::BTreeMap;
1148
1149        // u8
1150        let mut ranking: BTreeMap<u8, String> = BTreeMap::new();
1151        ranking.insert(1, "Elon".to_string());
1152        ranking.insert(2, "Bazos".to_string());
1153        assert_eq!(
1154            from_str::<BTreeMap<u8, String>>(r#"{"1": "Elon", "2": "Bazos"}"#).unwrap(),
1155            ranking
1156        );
1157
1158        // u16
1159        let mut ranking: BTreeMap<u16, String> = BTreeMap::new();
1160        ranking.insert(1, "Elon".to_string());
1161        ranking.insert(2, "Bazos".to_string());
1162        assert_eq!(
1163            from_str::<BTreeMap<u16, String>>(r#"{"1": "Elon", "2": "Bazos"}"#).unwrap(),
1164            ranking
1165        );
1166
1167        // u32
1168        let mut ranking: BTreeMap<u32, String> = BTreeMap::new();
1169        ranking.insert(1, "Elon".to_string());
1170        ranking.insert(2, "Bazos".to_string());
1171        assert_eq!(
1172            from_str::<BTreeMap<u32, String>>(r#"{"1": "Elon", "2": "Bazos"}"#).unwrap(),
1173            ranking
1174        );
1175
1176        // u64
1177        let mut ranking: BTreeMap<u64, String> = BTreeMap::new();
1178        ranking.insert(1, "Elon".to_string());
1179        ranking.insert(2, "Bazos".to_string());
1180        assert_eq!(
1181            from_str::<BTreeMap<u64, String>>(r#"{"1": "Elon", "2": "Bazos"}"#).unwrap(),
1182            ranking
1183        );
1184
1185        // u128
1186        let mut ranking: BTreeMap<u128, String> = BTreeMap::new();
1187        ranking.insert(1, "Elon".to_string());
1188        ranking.insert(2, "Bazos".to_string());
1189        assert_eq!(
1190            from_str::<BTreeMap<u128, String>>(r#"{"1": "Elon", "2": "Bazos"}"#).unwrap(),
1191            ranking
1192        );
1193
1194        // i8
1195        let mut ranking: BTreeMap<i8, String> = BTreeMap::new();
1196        ranking.insert(1, "Elon".to_string());
1197        ranking.insert(2, "Bazos".to_string());
1198        assert_eq!(
1199            from_str::<BTreeMap<i8, String>>(r#"{"1": "Elon", "2": "Bazos"}"#).unwrap(),
1200            ranking
1201        );
1202
1203        // i16
1204        let mut ranking: BTreeMap<i16, String> = BTreeMap::new();
1205        ranking.insert(1, "Elon".to_string());
1206        ranking.insert(2, "Bazos".to_string());
1207        assert_eq!(
1208            from_str::<BTreeMap<i16, String>>(r#"{"1": "Elon", "2": "Bazos"}"#).unwrap(),
1209            ranking
1210        );
1211
1212        // i32
1213        let mut ranking: BTreeMap<i32, String> = BTreeMap::new();
1214        ranking.insert(1, "Elon".to_string());
1215        ranking.insert(2, "Bazos".to_string());
1216        assert_eq!(
1217            from_str::<BTreeMap<i32, String>>(r#"{"1": "Elon", "2": "Bazos"}"#).unwrap(),
1218            ranking
1219        );
1220
1221        // i64
1222        let mut ranking: BTreeMap<i64, String> = BTreeMap::new();
1223        ranking.insert(1, "Elon".to_string());
1224        ranking.insert(2, "Bazos".to_string());
1225        assert_eq!(
1226            from_str::<BTreeMap<i64, String>>(r#"{"1": "Elon", "2": "Bazos"}"#).unwrap(),
1227            ranking
1228        );
1229
1230        // i128
1231        let mut ranking: BTreeMap<i128, String> = BTreeMap::new();
1232        ranking.insert(1, "Elon".to_string());
1233        ranking.insert(2, "Bazos".to_string());
1234        assert_eq!(
1235            from_str::<BTreeMap<i128, String>>(r#"{"1": "Elon", "2": "Bazos"}"#).unwrap(),
1236            ranking
1237        );
1238    }
1239
1240    #[test]
1241    fn deserialize_optional_vector() {
1242        #[derive(Debug, Deserialize, PartialEq, Eq)]
1243        pub struct Response {
1244            pub log: Option<String>,
1245            pub messages: Vec<Msg>,
1246        }
1247
1248        #[derive(Debug, Deserialize, PartialEq, Eq, serde_derive::Serialize)]
1249        pub struct Msg {
1250            pub name: String,
1251        }
1252
1253        #[derive(Debug, Deserialize, PartialEq, Eq)]
1254        pub struct OptIn {
1255            pub name: Option<String>,
1256        }
1257
1258        let m: Msg = from_str(
1259            r#"{
1260          "name": "one"
1261        }"#,
1262        )
1263        .expect("simple");
1264        assert_eq!(
1265            m,
1266            Msg {
1267                name: "one".to_string()
1268            }
1269        );
1270
1271        let o: OptIn = from_str(
1272            r#"{
1273          "name": "two"
1274        }"#,
1275        )
1276        .expect("opt");
1277        assert_eq!(
1278            o,
1279            OptIn {
1280                name: Some("two".to_string())
1281            }
1282        );
1283
1284        let res: Response = from_str(
1285            r#"{
1286          "log": "my log",
1287          "messages": [{"name": "one"}]
1288        }"#,
1289        )
1290        .expect("fud");
1291        assert_eq!(
1292            res,
1293            Response {
1294                log: Some("my log".to_string()),
1295                messages: vec![Msg {
1296                    name: "one".to_string()
1297                }],
1298            }
1299        );
1300
1301        let res: Response = from_str(r#"{"log": null,"messages": []}"#).expect("fud");
1302        assert_eq!(
1303            res,
1304            Response {
1305                log: None,
1306                messages: Vec::new()
1307            }
1308        );
1309    }
1310
1311    #[test]
1312    fn deserialize_embedded_enum() {
1313        #[derive(Debug, Deserialize, PartialEq, Eq)]
1314        #[serde(rename_all = "lowercase")]
1315        pub enum MyResult {
1316            Ok(Response),
1317            Err(String),
1318        }
1319
1320        #[derive(Debug, Deserialize, PartialEq, Eq)]
1321        pub struct Response {
1322            pub log: Option<String>,
1323            pub messages: Vec<Msg>,
1324        }
1325
1326        #[derive(Debug, Deserialize, PartialEq, Eq)]
1327        pub struct Msg {
1328            pub name: String,
1329            pub amount: Option<String>,
1330        }
1331
1332        let res: MyResult = from_str(
1333            r#"{
1334          "ok": {
1335            "log": "hello",
1336            "messages": [{
1337                "name": "fred",
1338                "amount": "15"
1339            }]
1340          }
1341        }"#,
1342        )
1343        .expect("goo");
1344        assert_eq!(
1345            res,
1346            MyResult::Ok(Response {
1347                log: Some("hello".to_string()),
1348                messages: vec![Msg {
1349                    name: "fred".to_string(),
1350                    amount: Some("15".to_string())
1351                }]
1352            })
1353        );
1354
1355        let res: MyResult = from_str(
1356            r#"{
1357          "ok": {
1358            "log": "hello",
1359            "messages": []
1360          }
1361        }"#,
1362        )
1363        .expect("goo");
1364        assert_eq!(
1365            res,
1366            MyResult::Ok(Response {
1367                log: Some("hello".to_string()),
1368                messages: Vec::new()
1369            })
1370        );
1371
1372        let res: MyResult = from_str(
1373            r#"{
1374          "ok": {
1375            "log": null,
1376            "messages": []
1377          }
1378        }"#,
1379        )
1380        .expect("goo");
1381        assert_eq!(
1382            res,
1383            MyResult::Ok(Response {
1384                log: None,
1385                messages: Vec::new()
1386            })
1387        );
1388    }
1389
1390    // See https://iot.mozilla.org/wot/#thing-resource
1391    #[test]
1392    fn wot() {
1393        #[derive(Debug, Deserialize, PartialEq)]
1394        struct Thing {
1395            properties: Properties,
1396            #[serde(rename = "type")]
1397            ty: Type,
1398        }
1399
1400        #[derive(Debug, Deserialize, PartialEq)]
1401        struct Properties {
1402            temperature: Property,
1403            humidity: Property,
1404            led: Property,
1405        }
1406
1407        #[derive(Debug, Deserialize, PartialEq)]
1408        struct Property {
1409            #[serde(rename = "type")]
1410            ty: Type,
1411            unit: Option<String>,
1412            description: Option<String>,
1413            href: String,
1414        }
1415
1416        assert_eq!(
1417            from_str::<Thing>(
1418                r#"
1419{
1420  "type": "thing",
1421  "properties": {
1422    "temperature": {
1423      "type": "number",
1424      "unit": "celsius",
1425      "description": "An ambient temperature sensor",
1426      "href": "/properties/temperature"
1427    },
1428    "humidity": {
1429      "type": "number",
1430      "unit": "percent",
1431      "href": "/properties/humidity"
1432    },
1433    "led": {
1434      "type": "boolean",
1435      "unit": null,
1436      "description": "A red LED",
1437      "href": "/properties/led"
1438    }
1439  }
1440}
1441"#
1442            ),
1443            Ok(Thing {
1444                properties: Properties {
1445                    temperature: Property {
1446                        ty: Type::Number,
1447                        unit: Some("celsius".to_string()),
1448                        description: Some("An ambient temperature sensor".to_string()),
1449                        href: "/properties/temperature".to_string(),
1450                    },
1451                    humidity: Property {
1452                        ty: Type::Number,
1453                        unit: Some("percent".to_string()),
1454                        description: None,
1455                        href: "/properties/humidity".to_string(),
1456                    },
1457                    led: Property {
1458                        ty: Type::Boolean,
1459                        unit: None,
1460                        description: Some("A red LED".to_string()),
1461                        href: "/properties/led".to_string(),
1462                    },
1463                },
1464                ty: Type::Thing,
1465            })
1466        )
1467    }
1468}