1use core::{fmt, str};
4
5#[cfg(feature = "custom-error-messages")]
6use alloc::string::String;
7use serde::de::{self, Visitor};
8
9use self::enum_::{UnitVariantAccess, VariantAccess};
10use self::map::MapAccess;
11use self::read::Reference;
12use self::read::{Read, SliceRead};
13use self::seq::SeqAccess;
14
15use alloc::vec::Vec;
16
17mod enum_;
18mod map;
19mod read;
20mod seq;
21
22pub type Result<T> = core::result::Result<T, Error>;
24
25#[derive(Debug, PartialEq)]
27#[non_exhaustive]
28pub enum Error {
29 EofWhileParsingList,
31
32 EofWhileParsingObject,
34
35 EofWhileParsingString,
37
38 EofWhileParsingNumber,
40
41 EofWhileParsingValue,
43
44 ExpectedColon,
46
47 ExpectedListCommaOrEnd,
49
50 ExpectedObjectCommaOrEnd,
52
53 ExpectedSomeIdent,
55
56 ExpectedSomeValue,
58
59 InvalidNumber,
61
62 InvalidType,
64
65 InvalidUnicodeCodePoint,
67
68 KeyMustBeAString,
70
71 TrailingCharacters,
73
74 TrailingComma,
76
77 CustomError,
79
80 InvalidEscape,
82
83 ControlCharacterWhileParsingString,
85
86 #[cfg(feature = "custom-error-messages")]
88 CustomErrorWithMessage(String),
89}
90
91#[cfg(feature = "std")]
92impl ::std::error::Error for Error {
93 fn description(&self) -> &str {
94 ""
95 }
96}
97
98pub(crate) struct Deserializer<'b> {
99 read: SliceRead<'b>,
100 scratch: Vec<u8>,
101}
102
103impl<'a> Deserializer<'a> {
104 fn new(slice: &'a [u8]) -> Deserializer<'_> {
105 Deserializer {
106 read: SliceRead::new(slice),
107 scratch: Vec::new(),
108 }
109 }
110
111 fn eat_char(&mut self) {
112 self.read.discard();
113 }
114
115 fn end(&mut self) -> Result<()> {
116 match self.parse_whitespace() {
117 Some(_) => Err(Error::TrailingCharacters),
118 None => Ok(()),
119 }
120 }
121
122 fn end_seq(&mut self) -> Result<()> {
123 match self.parse_whitespace().ok_or(Error::EofWhileParsingList)? {
124 b']' => {
125 self.eat_char();
126 Ok(())
127 }
128 b',' => {
129 self.eat_char();
130 match self.parse_whitespace() {
131 Some(b']') => Err(Error::TrailingComma),
132 _ => Err(Error::TrailingCharacters),
133 }
134 }
135 _ => Err(Error::TrailingCharacters),
136 }
137 }
138
139 fn end_map(&mut self) -> Result<()> {
140 match self
141 .parse_whitespace()
142 .ok_or(Error::EofWhileParsingObject)?
143 {
144 b'}' => {
145 self.eat_char();
146 Ok(())
147 }
148 b',' => Err(Error::TrailingComma),
149 _ => Err(Error::TrailingCharacters),
150 }
151 }
152
153 fn next_char(&mut self) -> Option<u8> {
154 self.read.next_byte()
155 }
156
157 fn parse_ident(&mut self, ident: &[u8]) -> Result<()> {
158 for c in ident {
159 if Some(*c) != self.next_char() {
160 return Err(Error::ExpectedSomeIdent);
161 }
162 }
163
164 Ok(())
165 }
166
167 fn parse_object_colon(&mut self) -> Result<()> {
168 match self
169 .parse_whitespace()
170 .ok_or(Error::EofWhileParsingObject)?
171 {
172 b':' => {
173 self.eat_char();
174 Ok(())
175 }
176 _ => Err(Error::ExpectedColon),
177 }
178 }
179
180 fn parse_whitespace(&mut self) -> Option<u8> {
182 loop {
183 match self.peek() {
184 Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') => {
185 self.eat_char();
186 }
187 other => {
188 return other;
189 }
190 }
191 }
192 }
193
194 fn peek(&mut self) -> Option<u8> {
195 self.read.peek_byte()
196 }
197}
198
199macro_rules! deserialize_unsigned {
203 ($self:ident, $visitor:ident, $uxx:ident, $visit_uxx:ident) => {{
204 let peek = $self
205 .parse_whitespace()
206 .ok_or(Error::EofWhileParsingValue)?;
207
208 match peek {
209 b'-' => Err(Error::InvalidNumber),
210 b'0' => {
211 $self.eat_char();
212 $visitor.$visit_uxx(0)
213 }
214 b'1'..=b'9' => {
215 $self.eat_char();
216
217 let mut number = (peek - b'0') as $uxx;
218 loop {
219 match $self.peek() {
220 Some(c @ b'0'..=b'9') => {
221 $self.eat_char();
222 number = number
223 .checked_mul(10)
224 .ok_or(Error::InvalidNumber)?
225 .checked_add((c - b'0') as $uxx)
226 .ok_or(Error::InvalidNumber)?;
227 }
228 _ => return $visitor.$visit_uxx(number),
229 }
230 }
231 }
232 _ => Err(Error::InvalidType),
233 }
234 }};
235}
236
237macro_rules! deserialize_signed {
238 ($self:ident, $visitor:ident, $ixx:ident, $visit_ixx:ident) => {{
239 let signed = match $self
240 .parse_whitespace()
241 .ok_or(Error::EofWhileParsingValue)?
242 {
243 b'-' => {
244 $self.eat_char();
245 true
246 }
247 _ => false,
248 };
249
250 match $self.peek().ok_or(Error::EofWhileParsingValue)? {
251 b'0' => {
252 $self.eat_char();
253 $visitor.$visit_ixx(0)
254 }
255 c @ b'1'..=b'9' => {
256 $self.eat_char();
257
258 let mut number = (c - b'0') as $ixx * if signed { -1 } else { 1 };
259 loop {
260 match $self.peek() {
261 Some(c @ b'0'..=b'9') => {
262 $self.eat_char();
263 number = number
264 .checked_mul(10)
265 .ok_or(Error::InvalidNumber)?
266 .checked_add((c - b'0') as $ixx * if signed { -1 } else { 1 })
267 .ok_or(Error::InvalidNumber)?;
268 }
269 _ => return $visitor.$visit_ixx(number),
270 }
271 }
272 }
273 _ => return Err(Error::InvalidType),
274 }
275 }};
276}
277
278impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> {
279 type Error = Error;
280
281 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
282 where
283 V: Visitor<'de>,
284 {
285 let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
286 match peek {
287 b'n' => {
288 self.eat_char();
289 self.parse_ident(b"ull")?;
290 visitor.visit_unit()
291 }
292 b't' => {
293 self.eat_char();
294 self.parse_ident(b"rue")?;
295 visitor.visit_bool(true)
296 }
297 b'f' => {
298 self.eat_char();
299 self.parse_ident(b"alse")?;
300 visitor.visit_bool(false)
301 }
302 b'"' => {
303 self.eat_char();
304 self.scratch.clear();
305 match self.read.parse_str(&mut self.scratch)? {
306 Reference::Borrowed(s) => visitor.visit_borrowed_str(s),
307 Reference::Copied(s) => visitor.visit_str(s),
308 }
309 }
310 b'[' => {
311 self.eat_char();
312 let ret = visitor.visit_seq(SeqAccess::new(self));
313
314 match (ret, self.end_seq()) {
315 (Ok(ret), Ok(())) => Ok(ret),
316 (Err(err), _) | (_, Err(err)) => Err(err),
317 }
318 }
319 b'{' => {
320 self.eat_char();
321 let ret = visitor.visit_map(MapAccess::new(self));
322
323 match (ret, self.end_map()) {
324 (Ok(ret), Ok(())) => Ok(ret),
325 (Err(err), _) | (_, Err(err)) => Err(err),
326 }
327 }
328 _ => Err(Error::InvalidType),
329 }
330 }
331
332 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
333 where
334 V: Visitor<'de>,
335 {
336 let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
337
338 match peek {
339 b't' => {
340 self.eat_char();
341 self.parse_ident(b"rue")?;
342 visitor.visit_bool(true)
343 }
344 b'f' => {
345 self.eat_char();
346 self.parse_ident(b"alse")?;
347 visitor.visit_bool(false)
348 }
349 _ => Err(Error::InvalidType),
350 }
351 }
352
353 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
354 where
355 V: Visitor<'de>,
356 {
357 deserialize_signed!(self, visitor, i8, visit_i8)
358 }
359
360 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
361 where
362 V: Visitor<'de>,
363 {
364 deserialize_signed!(self, visitor, i16, visit_i16)
365 }
366
367 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
368 where
369 V: Visitor<'de>,
370 {
371 deserialize_signed!(self, visitor, i32, visit_i32)
372 }
373
374 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
375 where
376 V: Visitor<'de>,
377 {
378 deserialize_signed!(self, visitor, i64, visit_i64)
379 }
380
381 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
382 where
383 V: Visitor<'de>,
384 {
385 deserialize_unsigned!(self, visitor, u8, visit_u8)
386 }
387
388 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
389 where
390 V: Visitor<'de>,
391 {
392 deserialize_unsigned!(self, visitor, u16, visit_u16)
393 }
394
395 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
396 where
397 V: Visitor<'de>,
398 {
399 deserialize_unsigned!(self, visitor, u32, visit_u32)
400 }
401
402 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
403 where
404 V: Visitor<'de>,
405 {
406 deserialize_unsigned!(self, visitor, u64, visit_u64)
407 }
408
409 fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value>
410 where
411 V: Visitor<'de>,
412 {
413 Err(Error::InvalidNumber)
414 }
415
416 fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value>
417 where
418 V: Visitor<'de>,
419 {
420 Err(Error::InvalidNumber)
421 }
422
423 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
424 where
425 V: Visitor<'de>,
426 {
427 self.deserialize_str(visitor)
428 }
429
430 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
431 where
432 V: Visitor<'de>,
433 {
434 let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
435
436 match peek {
437 b'"' => {
438 self.eat_char();
439 self.scratch.clear();
440 match self.read.parse_str(&mut self.scratch)? {
441 Reference::Borrowed(s) => visitor.visit_borrowed_str(s),
442 Reference::Copied(s) => visitor.visit_str(s),
443 }
444 }
445 _ => Err(Error::InvalidType),
446 }
447 }
448
449 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
450 where
451 V: Visitor<'de>,
452 {
453 self.deserialize_str(visitor)
454 }
455
456 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
457 where
458 V: Visitor<'de>,
459 {
460 let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
461
462 match peek {
463 b'"' => {
464 self.eat_char();
465 self.scratch.clear();
466 match self.read.parse_str_raw(&mut self.scratch)? {
467 Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b),
468 Reference::Copied(b) => visitor.visit_bytes(b),
469 }
470 }
471 b'[' => self.deserialize_seq(visitor),
472 _ => Err(Error::InvalidType),
473 }
474 }
475
476 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
477 where
478 V: Visitor<'de>,
479 {
480 self.deserialize_bytes(visitor)
481 }
482
483 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
484 where
485 V: Visitor<'de>,
486 {
487 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
488 b'n' => {
489 self.eat_char();
490 self.parse_ident(b"ull")?;
491 visitor.visit_none()
492 }
493 _ => visitor.visit_some(self),
494 }
495 }
496
497 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
498 where
499 V: Visitor<'de>,
500 {
501 let peek = match self.parse_whitespace() {
502 Some(b) => b,
503 None => {
504 return Err(Error::EofWhileParsingValue);
505 }
506 };
507
508 match peek {
509 b'n' => {
510 self.eat_char();
511 self.parse_ident(b"ull")?;
512 visitor.visit_unit()
513 }
514 _ => Err(Error::InvalidType),
515 }
516 }
517
518 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
519 where
520 V: Visitor<'de>,
521 {
522 self.deserialize_unit(visitor)
523 }
524
525 fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
527 where
528 V: Visitor<'de>,
529 {
530 visitor.visit_newtype_struct(self)
531 }
532
533 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
534 where
535 V: Visitor<'de>,
536 {
537 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
538 b'[' => {
539 self.eat_char();
540 let ret = visitor.visit_seq(SeqAccess::new(self))?;
541
542 self.end_seq()?;
543
544 Ok(ret)
545 }
546 _ => Err(Error::InvalidType),
547 }
548 }
549
550 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
551 where
552 V: Visitor<'de>,
553 {
554 self.deserialize_seq(visitor)
555 }
556
557 fn deserialize_tuple_struct<V>(
558 self,
559 _name: &'static str,
560 _len: usize,
561 visitor: V,
562 ) -> Result<V::Value>
563 where
564 V: Visitor<'de>,
565 {
566 self.deserialize_seq(visitor)
567 }
568
569 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
570 where
571 V: Visitor<'de>,
572 {
573 let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
574
575 if peek == b'{' {
576 self.eat_char();
577
578 let ret = visitor.visit_map(MapAccess::new(self))?;
579
580 self.end_map()?;
581
582 Ok(ret)
583 } else {
584 Err(Error::InvalidType)
585 }
586 }
587
588 fn deserialize_struct<V>(
589 self,
590 _name: &'static str,
591 _fields: &'static [&'static str],
592 visitor: V,
593 ) -> Result<V::Value>
594 where
595 V: Visitor<'de>,
596 {
597 self.deserialize_map(visitor)
598 }
599
600 fn deserialize_enum<V>(
601 self,
602 _name: &'static str,
603 _variants: &'static [&'static str],
604 visitor: V,
605 ) -> Result<V::Value>
606 where
607 V: Visitor<'de>,
608 {
609 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
610 b'"' => visitor.visit_enum(UnitVariantAccess::new(self)),
611 b'{' => {
612 self.eat_char();
613 let value = visitor.visit_enum(VariantAccess::new(self))?;
614 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
615 b'}' => {
616 self.eat_char();
617 Ok(value)
618 }
619 _ => Err(Error::ExpectedSomeValue),
620 }
621 }
622 _ => Err(Error::ExpectedSomeValue),
623 }
624 }
625
626 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
627 where
628 V: Visitor<'de>,
629 {
630 self.deserialize_str(visitor)
631 }
632
633 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
636 where
637 V: Visitor<'de>,
638 {
639 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
640 b'"' => self.deserialize_str(visitor),
641 b'[' => self.deserialize_seq(visitor),
642 b'{' => self.deserialize_struct("ignored", &[], visitor),
643 b',' | b'}' | b']' => Err(Error::ExpectedSomeValue),
644 _ => loop {
648 match self.peek() {
649 Some(b',') | Some(b'}') | Some(b']') => break visitor.visit_unit(),
652 Some(_) => self.eat_char(),
653 None => break Err(Error::EofWhileParsingString),
654 }
655 },
656 }
657 }
658}
659
660impl de::Error for Error {
661 #[cfg_attr(not(feature = "custom-error-messages"), allow(unused_variables))]
662 fn custom<T>(msg: T) -> Self
663 where
664 T: fmt::Display,
665 {
666 #[cfg(not(feature = "custom-error-messages"))]
667 {
668 Error::CustomError
669 }
670 #[cfg(feature = "custom-error-messages")]
671 {
672 use core::fmt::Write;
673
674 let mut string = String::new();
675 write!(string, "{:.64}", msg).unwrap();
676 Error::CustomErrorWithMessage(string)
677 }
678 }
679}
680
681impl fmt::Display for Error {
682 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
683 write!(
684 f,
685 "{}",
686 match self {
687 Error::EofWhileParsingList => "EOF while parsing a list.",
688 Error::EofWhileParsingObject => "EOF while parsing an object.",
689 Error::EofWhileParsingString => "EOF while parsing a string.",
690 Error::EofWhileParsingValue => "EOF while parsing a JSON value.",
691 Error::ExpectedColon => "Expected this character to be a `':'`.",
692 Error::ExpectedListCommaOrEnd => {
693 "Expected this character to be either a `','` or\
694 a \
695 `']'`."
696 }
697 Error::ExpectedObjectCommaOrEnd => {
698 "Expected this character to be either a `','` \
699 or a \
700 `'}'`."
701 }
702 Error::ExpectedSomeIdent => {
703 "Expected to parse either a `true`, `false`, or a \
704 `null`."
705 }
706 Error::ExpectedSomeValue => "Expected this character to start a JSON value.",
707 Error::InvalidNumber => "Invalid number.",
708 Error::InvalidType => "Invalid type",
709 Error::InvalidUnicodeCodePoint => "Invalid unicode code point.",
710 Error::KeyMustBeAString => "Object key is not a string.",
711 Error::TrailingCharacters => {
712 "JSON has non-whitespace trailing characters after \
713 the \
714 value."
715 }
716 Error::TrailingComma => "JSON has a comma after the last value in an array or map.",
717 Error::CustomError => "JSON does not match deserializer’s expected format.",
718 #[cfg(feature = "custom-error-messages")]
719 Error::CustomErrorWithMessage(msg) => msg.as_str(),
720 _ => "Invalid JSON",
721 }
722 )
723 }
724}
725
726pub fn from_slice<'a, T>(v: &'a [u8]) -> Result<T>
729where
730 T: de::Deserialize<'a>,
731{
732 let mut de = Deserializer::new(v);
733 let value = de::Deserialize::deserialize(&mut de)?;
734 de.end()?;
735
736 Ok(value)
737}
738
739pub fn from_str<'a, T>(s: &'a str) -> Result<T>
741where
742 T: de::Deserialize<'a>,
743{
744 from_slice(s.as_bytes())
745}
746
747#[cfg(test)]
748mod tests {
749 use alloc::borrow::ToOwned;
750 use serde_derive::Deserialize;
751
752 #[derive(Debug, Deserialize, PartialEq)]
753 enum Type {
754 #[serde(rename = "boolean")]
755 Boolean,
756 #[serde(rename = "number")]
757 Number,
758 #[serde(rename = "thing")]
759 Thing,
760 }
761
762 #[test]
763 fn array() {
764 assert_eq!(crate::from_str::<[i32; 0]>("[]"), Ok([]));
765 assert_eq!(crate::from_str("[0, 1, 2]"), Ok([0, 1, 2]));
766
767 assert!(crate::from_str::<[i32; 2]>("[0, 1,]").is_err());
769 }
770
771 #[test]
772 fn bool() {
773 assert_eq!(crate::from_str("true"), Ok(true));
774 assert_eq!(crate::from_str(" true"), Ok(true));
775 assert_eq!(crate::from_str("true "), Ok(true));
776
777 assert_eq!(crate::from_str("false"), Ok(false));
778 assert_eq!(crate::from_str(" false"), Ok(false));
779 assert_eq!(crate::from_str("false "), Ok(false));
780
781 assert!(crate::from_str::<bool>("true false").is_err());
783 assert!(crate::from_str::<bool>("tru").is_err());
784 }
785
786 #[test]
787 fn floating_point() {
788 assert_eq!(crate::from_str("5.0"), Ok(5.0));
789 assert_eq!(crate::from_str("1"), Ok(1.0));
790 assert_eq!(crate::from_str("1e5"), Ok(1e5));
791 assert!(crate::from_str::<f32>("a").is_err());
792 assert!(crate::from_str::<f32>(",").is_err());
793 }
794
795 #[test]
796 fn integer() {
797 assert_eq!(crate::from_str("5"), Ok(5));
798 assert_eq!(crate::from_str("101"), Ok(101));
799 assert!(crate::from_str::<u16>("1e5").is_err());
800 assert!(crate::from_str::<u8>("256").is_err());
801 assert!(crate::from_str::<f32>(",").is_err());
802 }
803
804 #[test]
805 fn enum_clike() {
806 assert_eq!(crate::from_str(r#" "boolean" "#), Ok(Type::Boolean));
807 assert_eq!(crate::from_str(r#" "number" "#), Ok(Type::Number));
808 assert_eq!(crate::from_str(r#" "thing" "#), Ok(Type::Thing));
809 }
810
811 #[test]
812 fn str() {
813 assert_eq!(crate::from_str(r#" "hello" "#), Ok("hello"));
814 assert_eq!(crate::from_str(r#" "" "#), Ok(""));
815 assert_eq!(crate::from_str(r#" " " "#), Ok(" "));
816 assert_eq!(crate::from_str(r#" "👏" "#), Ok("👏"));
817
818 assert_eq!(crate::from_str(r#" "hel\tlo" "#), Ok("hel\tlo".to_owned()));
820 assert_eq!(crate::from_str(r#" "hello \\" "#), Ok("hello \\".to_owned()));
821
822 assert_eq!(crate::from_str(r#" "foo\"bar" "#), Ok("foo\"bar".to_owned()));
824 assert_eq!(crate::from_str(r#" "foo\\\"bar" "#), Ok("foo\\\"bar".to_owned()));
825 assert_eq!(crate::from_str(r#" "foo\"\"bar" "#), Ok("foo\"\"bar".to_owned()));
826 assert_eq!(crate::from_str(r#" "\"bar" "#), Ok("\"bar".to_owned()));
827 assert_eq!(crate::from_str(r#" "foo\"" "#), Ok("foo\"".to_owned()));
828 assert_eq!(crate::from_str(r#" "\"" "#), Ok("\"".to_owned()));
829
830 assert_eq!(crate::from_str(r#" "foo bar\\" "#), Ok("foo bar\\".to_owned()));
832 assert_eq!(crate::from_str(r#" "foo bar\\\\" "#), Ok("foo bar\\\\".to_owned()));
833 assert_eq!(
834 crate::from_str(r#" "foo bar\\\\\\" "#),
835 Ok("foo bar\\\\\\".to_owned())
836 );
837 assert_eq!(
838 crate::from_str(r#" "foo bar\\\\\\\\" "#),
839 Ok("foo bar\\\\\\\\".to_owned())
840 );
841 assert_eq!(crate::from_str(r#" "\\" "#), Ok("\\".to_owned()));
842 }
843
844 #[test]
845 fn struct_bool() {
846 #[derive(Debug, Deserialize, PartialEq)]
847 struct Led {
848 led: bool,
849 }
850
851 assert_eq!(crate::from_str(r#"{ "led": true }"#), Ok(Led { led: true }));
852 assert_eq!(
853 crate::from_str(r#"{ "led": false }"#),
854 Ok(Led { led: false })
855 );
856 }
857
858 #[test]
859 fn struct_i8() {
860 #[derive(Debug, Deserialize, PartialEq)]
861 struct Temperature {
862 temperature: i8,
863 }
864
865 assert_eq!(
866 crate::from_str(r#"{ "temperature": -17 }"#),
867 Ok(Temperature { temperature: -17 })
868 );
869
870 assert_eq!(
871 crate::from_str(r#"{ "temperature": -0 }"#),
872 Ok(Temperature { temperature: -0 })
873 );
874
875 assert_eq!(
876 crate::from_str(r#"{ "temperature": 0 }"#),
877 Ok(Temperature { temperature: 0 })
878 );
879
880 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 128 }"#).is_err());
882 assert!(crate::from_str::<Temperature>(r#"{ "temperature": -129 }"#).is_err());
883 }
884
885 #[test]
886 fn struct_f32() {
887 #[derive(Debug, Deserialize, PartialEq)]
888 struct Temperature {
889 temperature: f32,
890 }
891
892 assert_eq!(
893 crate::from_str(r#"{ "temperature": -17.2 }"#),
894 Ok(Temperature { temperature: -17.2 })
895 );
896
897 assert_eq!(
898 crate::from_str(r#"{ "temperature": -0.0 }"#),
899 Ok(Temperature { temperature: -0. })
900 );
901
902 assert_eq!(
903 crate::from_str(r#"{ "temperature": -2.1e-3 }"#),
904 Ok(Temperature {
905 temperature: -2.1e-3
906 })
907 );
908
909 assert_eq!(
910 crate::from_str(r#"{ "temperature": -3 }"#),
911 Ok(Temperature { temperature: -3. })
912 );
913
914 use core::f32;
915
916 assert_eq!(
917 crate::from_str(r#"{ "temperature": -1e500 }"#),
918 Ok(Temperature {
919 temperature: f32::NEG_INFINITY
920 })
921 );
922
923 let r: Temperature = crate::from_str(r#"{ "temperature": null }"#).unwrap();
925 assert!(r.temperature.is_nan());
926
927 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 1e1e1 }"#).is_err());
928 assert!(crate::from_str::<Temperature>(r#"{ "temperature": -2-2 }"#).is_err());
929 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 1 1 }"#).is_err());
930 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 0.0. }"#).is_err());
931 assert!(crate::from_str::<Temperature>(r#"{ "temperature": ä }"#).is_err());
932 assert!(crate::from_str::<Temperature>(r#"{ "temperature": None }"#).is_err());
933 }
934
935 #[test]
936 fn struct_option() {
937 #[derive(Debug, Deserialize, PartialEq)]
938 struct Property<'a> {
939 #[serde(borrow)]
940 description: Option<&'a str>,
941 }
942
943 assert_eq!(
944 crate::from_str(r#"{ "description": "An ambient temperature sensor" }"#),
945 Ok(Property {
946 description: Some("An ambient temperature sensor"),
947 })
948 );
949
950 assert_eq!(
951 crate::from_str(r#"{ "description": null }"#),
952 Ok(Property { description: None })
953 );
954
955 assert_eq!(crate::from_str(r#"{}"#), Ok(Property { description: None }));
956 }
957
958 #[test]
959 fn struct_u8() {
960 #[derive(Debug, Deserialize, PartialEq)]
961 struct Temperature {
962 temperature: u8,
963 }
964
965 assert_eq!(
966 crate::from_str(r#"{ "temperature": 20 }"#),
967 Ok(Temperature { temperature: 20 })
968 );
969
970 assert_eq!(
971 crate::from_str(r#"{ "temperature": 0 }"#),
972 Ok(Temperature { temperature: 0 })
973 );
974
975 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 256 }"#).is_err());
977 assert!(crate::from_str::<Temperature>(r#"{ "temperature": -1 }"#).is_err());
978 }
979
980 #[test]
981 fn test_unit() {
982 assert_eq!(crate::from_str::<()>(r#"null"#), Ok(()));
983 }
984
985 #[test]
986 fn newtype_struct() {
987 #[derive(Deserialize, Debug, PartialEq)]
988 struct A(pub u32);
989
990 assert_eq!(crate::from_str::<A>(r#"54"#), Ok(A(54)));
991 }
992
993 #[test]
994 fn test_newtype_variant() {
995 #[derive(Deserialize, Debug, PartialEq)]
996 enum A {
997 A(u32),
998 }
999 let a = A::A(54);
1000 let x = crate::from_str::<A>(r#"{"A":54}"#);
1001 assert_eq!(x, Ok(a));
1002 }
1003
1004 #[test]
1005 fn test_struct_variant() {
1006 #[derive(Deserialize, Debug, PartialEq)]
1007 enum A {
1008 A { x: u32, y: u16 },
1009 }
1010 let a = A::A { x: 54, y: 720 };
1011 let x = crate::from_str::<A>(r#"{"A": {"x":54,"y":720 } }"#);
1012 assert_eq!(x, Ok(a));
1013 }
1014
1015 #[test]
1016 #[cfg(not(feature = "custom-error-messages"))]
1017 fn struct_tuple() {
1018 #[derive(Debug, Deserialize, PartialEq)]
1019 struct Xy(i8, i8);
1020
1021 assert_eq!(crate::from_str(r#"[10, 20]"#), Ok(Xy(10, 8)));
1022 assert_eq!(crate::from_str(r#"[10, -20]"#), Ok(Xy(10, 9)));
1023
1024 assert_eq!(
1026 crate::from_str::<Xy>(r#"[10]"#),
1027 Err(crate::de::Error::CustomError)
1028 );
1029 assert_eq!(
1030 crate::from_str::<Xy>(r#"[10, 20, 30]"#),
1031 Err(crate::de::Error::TrailingCharacters)
1032 );
1033 }
1034
1035 #[test]
1036 #[cfg(feature = "custom-error-messages")]
1037 fn struct_tuple() {
1038 #[derive(Debug, Deserialize, PartialEq)]
1039 struct Xy(i8, i8);
1040
1041 assert_eq!(crate::from_str(r#"[10, 20]"#), Ok(Xy(10, 20)));
1042 assert_eq!(crate::from_str(r#"[10, -20]"#), Ok(Xy(10, -20)));
1043
1044 assert_eq!(
1046 crate::from_str::<Xy>(r#"[10]"#),
1047 Err(crate::de::Error::CustomErrorWithMessage(
1048 "invalid length 1, expected tuple struct Xy with 2 elements".into()
1049 ))
1050 );
1051 assert_eq!(
1052 crate::from_str::<Xy>(r#"[10, 20, 30]"#),
1053 Err(crate::de::Error::TrailingCharacters)
1054 );
1055 }
1056
1057 #[test]
1058 fn ignoring_extra_fields() {
1059 #[derive(Debug, Deserialize, PartialEq)]
1060 struct Temperature {
1061 temperature: u8,
1062 }
1063
1064 assert_eq!(
1065 crate::from_str(r#"{ "temperature": 20, "high": 80, "low": -10, "updated": true }"#),
1066 Ok(Temperature { temperature: 20 })
1067 );
1068
1069 assert_eq!(
1070 crate::from_str(
1071 r#"{ "temperature": 20, "conditions": "windy", "forecast": "cloudy" }"#
1072 ),
1073 Ok(Temperature { temperature: 20 })
1074 );
1075
1076 assert_eq!(
1077 crate::from_str(r#"{ "temperature": 20, "hourly_conditions": ["windy", "rainy"] }"#),
1078 Ok(Temperature { temperature: 20 })
1079 );
1080
1081 assert_eq!(
1082 crate::from_str(
1083 r#"{ "temperature": 20, "source": { "station": "dock", "sensors": ["front", "back"] } }"#
1084 ),
1085 Ok(Temperature { temperature: 20 })
1086 );
1087
1088 assert_eq!(
1089 crate::from_str(r#"{ "temperature": 20, "invalid": this-is-ignored }"#),
1090 Ok(Temperature { temperature: 20 })
1091 );
1092
1093 assert_eq!(
1094 crate::from_str::<Temperature>(r#"{ "temperature": 20, "broken": }"#),
1095 Err(crate::de::Error::ExpectedSomeValue)
1096 );
1097
1098 assert_eq!(
1099 crate::from_str::<Temperature>(r#"{ "temperature": 20, "broken": [ }"#),
1100 Err(crate::de::Error::ExpectedSomeValue)
1101 );
1102
1103 assert_eq!(
1104 crate::from_str::<Temperature>(r#"{ "temperature": 20, "broken": ] }"#),
1105 Err(crate::de::Error::ExpectedSomeValue)
1106 );
1107 }
1108
1109 #[test]
1110 #[cfg(feature = "custom-error-messages")]
1111 fn preserve_short_error_message() {
1112 use serde::de::Error;
1113 assert_eq!(
1114 crate::de::Error::custom("something bad happened"),
1115 crate::de::Error::CustomErrorWithMessage("something bad happened".into())
1116 );
1117 }
1118
1119 #[test]
1120 #[cfg(feature = "custom-error-messages")]
1121 fn truncate_error_message() {
1122 use serde::de::Error;
1123 assert_eq!(
1124 crate::de::Error::custom("0123456789012345678901234567890123456789012345678901234567890123 <- after here the message should be truncated"),
1125 crate::de::Error::CustomErrorWithMessage(
1126 "0123456789012345678901234567890123456789012345678901234567890123".into()
1127 )
1128 );
1129 }
1130
1131 #[test]
1133 fn wot() {
1134 #[derive(Debug, Deserialize, PartialEq)]
1135 struct Thing<'a> {
1136 #[serde(borrow)]
1137 properties: Properties<'a>,
1138 #[serde(rename = "type")]
1139 ty: Type,
1140 }
1141
1142 #[derive(Debug, Deserialize, PartialEq)]
1143 struct Properties<'a> {
1144 #[serde(borrow)]
1145 temperature: Property<'a>,
1146 #[serde(borrow)]
1147 humidity: Property<'a>,
1148 #[serde(borrow)]
1149 led: Property<'a>,
1150 }
1151
1152 #[derive(Debug, Deserialize, PartialEq)]
1153 struct Property<'a> {
1154 #[serde(rename = "type")]
1155 ty: Type,
1156 unit: Option<&'a str>,
1157 #[serde(borrow)]
1158 description: Option<&'a str>,
1159 href: &'a str,
1160 }
1161
1162 assert_eq!(
1163 crate::from_str::<Thing<'_>>(
1164 r#"
1165 {
1166 "type": "thing",
1167 "properties": {
1168 "temperature": {
1169 "type": "number",
1170 "unit": "celsius",
1171 "description": "An ambient temperature sensor",
1172 "href": "/properties/temperature"
1173 },
1174 "humidity": {
1175 "type": "number",
1176 "unit": "percent",
1177 "href": "/properties/humidity"
1178 },
1179 "led": {
1180 "type": "boolean",
1181 "description": "A red LED",
1182 "href": "/properties/led"
1183 }
1184 }
1185 }
1186 "#
1187 ),
1188 Ok(Thing {
1189 properties: Properties {
1190 temperature: Property {
1191 ty: Type::Number,
1192 unit: Some("celsius"),
1193 description: Some("An ambient temperature sensor"),
1194 href: "/properties/temperature",
1195 },
1196 humidity: Property {
1197 ty: Type::Number,
1198 unit: Some("percent"),
1199 description: None,
1200 href: "/properties/humidity",
1201 },
1202 led: Property {
1203 ty: Type::Boolean,
1204 unit: None,
1205 description: Some("A red LED"),
1206 href: "/properties/led",
1207 },
1208 },
1209 ty: Type::Thing,
1210 })
1211 )
1212 }
1213}