1mod 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
19pub struct Deserializer<'b> {
22 slice: &'b [u8],
23 index: usize,
24
25 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(); } 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 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
176macro_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 fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
462 where
463 V: Visitor<'de>,
464 {
465 unreachable!()
466 }
467
468 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 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 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 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 b'"' => visitor.visit_enum(UnitVariantAccess::new(self)),
607 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 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 _ => loop {
641 match self.peek() {
642 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
653pub 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
665pub 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 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 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 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 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,); 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 #[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}