1use core::str::FromStr;
4use core::{fmt, str};
5
6use serde::de::{self, Visitor};
7use serde::Serialize;
8
9use self::enum_::{UnitVariantAccess, VariantAccess};
10use self::map::MapAccess;
11use self::seq::SeqAccess;
12
13mod enum_;
14mod map;
15mod seq;
16
17pub type Result<T> = core::result::Result<T, Error>;
19
20#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
22#[cfg_attr(not(feature = "custom-error-messages"), derive(Copy))]
23#[cfg_attr(feature = "defmt", derive(defmt::Format))]
24#[non_exhaustive]
25pub enum Error {
26 AnyIsUnsupported,
28
29 BytesIsUnsupported,
31
32 EofWhileParsingList,
34
35 EofWhileParsingObject,
37
38 EofWhileParsingString,
40
41 EofWhileParsingNumber,
43
44 EofWhileParsingValue,
46
47 ExpectedColon,
49
50 ExpectedListCommaOrEnd,
52
53 ExpectedObjectCommaOrEnd,
55
56 ExpectedSomeIdent,
58
59 ExpectedSomeValue,
61
62 InvalidNumber,
64
65 InvalidType,
67
68 InvalidUnicodeCodePoint,
70
71 InvalidEscapeSequence,
73
74 EscapedStringIsTooLong,
76
77 KeyMustBeAString,
79
80 TrailingCharacters,
82
83 TrailingComma,
85
86 CustomError,
88
89 #[cfg(feature = "custom-error-messages")]
91 CustomErrorWithMessage(
92 #[cfg_attr(feature = "defmt", defmt(Debug2Format))] heapless::String<64>,
93 ),
94}
95
96impl serde::de::StdError for Error {}
97
98impl From<crate::str::StringUnescapeError> for Error {
99 fn from(error: crate::str::StringUnescapeError) -> Self {
100 match error {
101 crate::str::StringUnescapeError::InvalidEscapeSequence => Self::InvalidEscapeSequence,
102 }
103 }
104}
105
106pub struct Deserializer<'b, 's> {
108 slice: &'b [u8],
109 index: usize,
110 string_unescape_buffer: Option<&'s mut [u8]>,
111}
112
113impl<'a, 's> Deserializer<'a, 's> {
114 pub fn new(
117 slice: &'a [u8],
118 string_unescape_buffer: Option<&'s mut [u8]>,
119 ) -> Deserializer<'a, 's> {
120 Deserializer {
121 slice,
122 index: 0,
123 string_unescape_buffer,
124 }
125 }
126
127 fn eat_char(&mut self) {
128 self.index += 1;
129 }
130
131 pub fn end(&mut self) -> Result<usize> {
134 match self.parse_whitespace() {
135 Some(_) => Err(Error::TrailingCharacters),
136 None => Ok(self.index),
137 }
138 }
139
140 fn end_seq(&mut self) -> Result<()> {
141 match self.parse_whitespace().ok_or(Error::EofWhileParsingList)? {
142 b']' => {
143 self.eat_char();
144 Ok(())
145 }
146 b',' => {
147 self.eat_char();
148 match self.parse_whitespace() {
149 Some(b']') => Err(Error::TrailingComma),
150 _ => Err(Error::TrailingCharacters),
151 }
152 }
153 _ => Err(Error::TrailingCharacters),
154 }
155 }
156
157 fn end_map(&mut self) -> Result<()> {
158 match self
159 .parse_whitespace()
160 .ok_or(Error::EofWhileParsingObject)?
161 {
162 b'}' => {
163 self.eat_char();
164 Ok(())
165 }
166 b',' => Err(Error::TrailingComma),
167 _ => Err(Error::TrailingCharacters),
168 }
169 }
170
171 fn next_char(&mut self) -> Option<u8> {
172 let ch = self.slice.get(self.index);
173
174 if ch.is_some() {
175 self.index += 1;
176 }
177
178 ch.cloned()
179 }
180
181 fn parse_ident(&mut self, ident: &[u8]) -> Result<()> {
182 for c in ident {
183 if Some(*c) != self.next_char() {
184 return Err(Error::ExpectedSomeIdent);
185 }
186 }
187
188 Ok(())
189 }
190
191 fn parse_object_colon(&mut self) -> Result<()> {
192 match self
193 .parse_whitespace()
194 .ok_or(Error::EofWhileParsingObject)?
195 {
196 b':' => {
197 self.eat_char();
198 Ok(())
199 }
200 _ => Err(Error::ExpectedColon),
201 }
202 }
203
204 fn parse_str(&mut self) -> Result<&'a str> {
206 if self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? == b'"' {
207 self.eat_char();
208 } else {
209 return Err(Error::InvalidType);
210 }
211
212 let start = self.index;
213 loop {
214 match self.peek() {
215 Some(b'"') => {
216 let leading_backslashes = |index: usize| -> usize {
228 let mut count = 0;
229 loop {
230 if self.slice[index - count - 1] == b'\\' {
231 count += 1;
232 } else {
233 return count;
234 }
235 }
236 };
237
238 let is_escaped = leading_backslashes(self.index) % 2 == 1;
239 if is_escaped {
240 self.eat_char(); } else {
242 let end = self.index;
243 self.eat_char();
244
245 return str::from_utf8(&self.slice[start..end])
246 .map_err(|_| Error::InvalidUnicodeCodePoint);
247 }
248 }
249 Some(_) => self.eat_char(),
250 None => return Err(Error::EofWhileParsingString),
251 }
252 }
253 }
254
255 fn parse_whitespace(&mut self) -> Option<u8> {
257 loop {
258 match self.peek() {
259 Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') => {
260 self.eat_char();
261 }
262 other => {
263 return other;
264 }
265 }
266 }
267 }
268
269 fn peek(&mut self) -> Option<u8> {
270 self.slice.get(self.index).cloned()
271 }
272}
273
274macro_rules! deserialize_unsigned {
278 ($self:ident, $visitor:ident, $uxx:ident, $visit_uxx:ident) => {{
279 let peek = $self
280 .parse_whitespace()
281 .ok_or(Error::EofWhileParsingValue)?;
282
283 match peek {
284 b'-' => Err(Error::InvalidNumber),
285 b'0' => {
286 $self.eat_char();
287 $visitor.$visit_uxx(0)
288 }
289 b'1'..=b'9' => {
290 $self.eat_char();
291
292 let mut number = (peek - b'0') as $uxx;
293 loop {
294 match $self.peek() {
295 Some(c @ b'0'..=b'9') => {
296 $self.eat_char();
297 number = number
298 .checked_mul(10)
299 .ok_or(Error::InvalidNumber)?
300 .checked_add((c - b'0') as $uxx)
301 .ok_or(Error::InvalidNumber)?;
302 }
303 _ => return $visitor.$visit_uxx(number),
304 }
305 }
306 }
307 _ => Err(Error::InvalidType),
308 }
309 }};
310}
311
312macro_rules! deserialize_signed {
313 ($self:ident, $visitor:ident, $ixx:ident, $visit_ixx:ident) => {{
314 let signed = match $self
315 .parse_whitespace()
316 .ok_or(Error::EofWhileParsingValue)?
317 {
318 b'-' => {
319 $self.eat_char();
320 true
321 }
322 _ => false,
323 };
324
325 match $self.peek().ok_or(Error::EofWhileParsingValue)? {
326 b'0' => {
327 $self.eat_char();
328 $visitor.$visit_ixx(0)
329 }
330 c @ b'1'..=b'9' => {
331 $self.eat_char();
332
333 let mut number = (c - b'0') as $ixx * if signed { -1 } else { 1 };
334 loop {
335 match $self.peek() {
336 Some(c @ b'0'..=b'9') => {
337 $self.eat_char();
338 number = number
339 .checked_mul(10)
340 .ok_or(Error::InvalidNumber)?
341 .checked_add((c - b'0') as $ixx * if signed { -1 } else { 1 })
342 .ok_or(Error::InvalidNumber)?;
343 }
344 _ => return $visitor.$visit_ixx(number),
345 }
346 }
347 }
348 _ => return Err(Error::InvalidType),
349 }
350 }};
351}
352
353macro_rules! deserialize_fromstr {
354 ($self:ident, $visitor:ident, $typ:ident, $visit_fn:ident, $pattern:expr) => {{
355 match $self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
356 b'n' => {
357 $self.eat_char();
358 $self.parse_ident(b"ull")?;
359 $visitor.$visit_fn($typ::NAN)
360 }
361 _ => {
362 let start = $self.index;
363 while $self.peek().is_some() {
364 let c = $self.peek().unwrap();
365 if $pattern.iter().find(|&&d| d == c).is_some() {
366 $self.eat_char();
367 } else {
368 break;
369 }
370 }
371
372 let s = unsafe { str::from_utf8_unchecked(&$self.slice[start..$self.index]) };
375
376 let v = $typ::from_str(s).or(Err(Error::InvalidNumber))?;
377
378 $visitor.$visit_fn(v)
379 }
380 }
381 }};
382}
383
384impl<'a, 'de, 's> de::Deserializer<'de> for &'a mut Deserializer<'de, 's> {
385 type Error = Error;
386
387 fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
389 where
390 V: Visitor<'de>,
391 {
392 Err(Error::AnyIsUnsupported)
393 }
394
395 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
396 where
397 V: Visitor<'de>,
398 {
399 let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
400
401 match peek {
402 b't' => {
403 self.eat_char();
404 self.parse_ident(b"rue")?;
405 visitor.visit_bool(true)
406 }
407 b'f' => {
408 self.eat_char();
409 self.parse_ident(b"alse")?;
410 visitor.visit_bool(false)
411 }
412 _ => Err(Error::InvalidType),
413 }
414 }
415
416 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
417 where
418 V: Visitor<'de>,
419 {
420 deserialize_signed!(self, visitor, i8, visit_i8)
421 }
422
423 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
424 where
425 V: Visitor<'de>,
426 {
427 deserialize_signed!(self, visitor, i16, visit_i16)
428 }
429
430 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
431 where
432 V: Visitor<'de>,
433 {
434 deserialize_signed!(self, visitor, i32, visit_i32)
435 }
436
437 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
438 where
439 V: Visitor<'de>,
440 {
441 deserialize_signed!(self, visitor, i64, visit_i64)
442 }
443
444 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
445 where
446 V: Visitor<'de>,
447 {
448 deserialize_unsigned!(self, visitor, u8, visit_u8)
449 }
450
451 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
452 where
453 V: Visitor<'de>,
454 {
455 deserialize_unsigned!(self, visitor, u16, visit_u16)
456 }
457
458 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
459 where
460 V: Visitor<'de>,
461 {
462 deserialize_unsigned!(self, visitor, u32, visit_u32)
463 }
464
465 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
466 where
467 V: Visitor<'de>,
468 {
469 deserialize_unsigned!(self, visitor, u64, visit_u64)
470 }
471
472 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
473 where
474 V: Visitor<'de>,
475 {
476 deserialize_fromstr!(self, visitor, f32, visit_f32, b"0123456789+-.eE")
477 }
478
479 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
480 where
481 V: Visitor<'de>,
482 {
483 deserialize_fromstr!(self, visitor, f64, visit_f64, b"0123456789+-.eE")
484 }
485
486 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
487 where
488 V: Visitor<'de>,
489 {
490 self.deserialize_str(visitor)
491 }
492
493 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
494 where
495 V: Visitor<'de>,
496 {
497 let escaped_string = self.parse_str()?;
498
499 let Some(string_unescape_buffer) = self.string_unescape_buffer.as_deref_mut() else {
501 return visitor.visit_borrowed_str(escaped_string);
502 };
503
504 if !escaped_string.as_bytes().contains(&b'\\') {
506 return visitor.visit_borrowed_str(escaped_string);
507 }
508
509 let mut string_unescape_buffer_write_position = 0;
510
511 for fragment in crate::str::EscapedStr(escaped_string).fragments() {
512 let char_encode_buffer = &mut [0; 4];
513
514 let unescaped_bytes = match fragment? {
515 crate::str::EscapedStringFragment::NotEscaped(fragment) => fragment.as_bytes(),
516 crate::str::EscapedStringFragment::Escaped(c) => {
517 c.encode_utf8(char_encode_buffer).as_bytes()
518 }
519 };
520
521 string_unescape_buffer[string_unescape_buffer_write_position..]
522 .get_mut(..unescaped_bytes.len())
523 .ok_or(Error::EscapedStringIsTooLong)?
524 .copy_from_slice(unescaped_bytes);
525
526 string_unescape_buffer_write_position += unescaped_bytes.len();
527 }
528
529 visitor.visit_str(
530 str::from_utf8(&string_unescape_buffer[..string_unescape_buffer_write_position])
531 .map_err(|_| Error::InvalidUnicodeCodePoint)?,
532 )
533 }
534
535 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
537 where
538 V: Visitor<'de>,
539 {
540 self.deserialize_str(visitor)
541 }
542
543 fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
545 where
546 V: Visitor<'de>,
547 {
548 Err(Error::BytesIsUnsupported)
549 }
550
551 fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
553 where
554 V: Visitor<'de>,
555 {
556 Err(Error::BytesIsUnsupported)
557 }
558
559 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
560 where
561 V: Visitor<'de>,
562 {
563 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
564 b'n' => {
565 self.eat_char();
566 self.parse_ident(b"ull")?;
567 visitor.visit_none()
568 }
569 _ => visitor.visit_some(self),
570 }
571 }
572
573 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
574 where
575 V: Visitor<'de>,
576 {
577 let peek = match self.parse_whitespace() {
578 Some(b) => b,
579 None => {
580 return Err(Error::EofWhileParsingValue);
581 }
582 };
583
584 match peek {
585 b'n' => {
586 self.eat_char();
587 self.parse_ident(b"ull")?;
588 visitor.visit_unit()
589 }
590 _ => Err(Error::InvalidType),
591 }
592 }
593
594 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
595 where
596 V: Visitor<'de>,
597 {
598 self.deserialize_unit(visitor)
599 }
600
601 fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
602 where
603 V: Visitor<'de>,
604 {
605 if name == crate::str::EscapedStr::NAME {
607 struct EscapedStringDeserializer<'a, 'de, 's>(&'a mut Deserializer<'de, 's>);
610
611 impl<'a, 'de, 's> serde::Deserializer<'de> for EscapedStringDeserializer<'a, 'de, 's> {
612 type Error = Error;
613
614 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
615 where
616 V: Visitor<'de>,
617 {
618 visitor.visit_borrowed_str(self.0.parse_str()?)
622 }
623
624 serde::forward_to_deserialize_any! {
626 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
627 bytes byte_buf option unit unit_struct newtype_struct seq tuple
628 tuple_struct map struct enum identifier ignored_any
629 }
630 }
631
632 visitor.visit_newtype_struct(EscapedStringDeserializer(self))
633 } else {
634 visitor.visit_newtype_struct(self)
635 }
636 }
637
638 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
639 where
640 V: Visitor<'de>,
641 {
642 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
643 b'[' => {
644 self.eat_char();
645 let ret = visitor.visit_seq(SeqAccess::new(self))?;
646
647 self.end_seq()?;
648
649 Ok(ret)
650 }
651 _ => Err(Error::InvalidType),
652 }
653 }
654
655 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
656 where
657 V: Visitor<'de>,
658 {
659 self.deserialize_seq(visitor)
660 }
661
662 fn deserialize_tuple_struct<V>(
663 self,
664 _name: &'static str,
665 _len: usize,
666 visitor: V,
667 ) -> Result<V::Value>
668 where
669 V: Visitor<'de>,
670 {
671 self.deserialize_seq(visitor)
672 }
673
674 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
675 where
676 V: Visitor<'de>,
677 {
678 let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
679
680 if peek == b'{' {
681 self.eat_char();
682
683 let ret = visitor.visit_map(MapAccess::new(self))?;
684
685 self.end_map()?;
686
687 Ok(ret)
688 } else {
689 Err(Error::InvalidType)
690 }
691 }
692
693 fn deserialize_struct<V>(
694 self,
695 _name: &'static str,
696 _fields: &'static [&'static str],
697 visitor: V,
698 ) -> Result<V::Value>
699 where
700 V: Visitor<'de>,
701 {
702 self.deserialize_map(visitor)
703 }
704
705 fn deserialize_enum<V>(
706 self,
707 _name: &'static str,
708 _variants: &'static [&'static str],
709 visitor: V,
710 ) -> Result<V::Value>
711 where
712 V: Visitor<'de>,
713 {
714 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
715 b'"' => visitor.visit_enum(UnitVariantAccess::new(self)),
716 b'{' => {
717 self.eat_char();
718 let value = visitor.visit_enum(VariantAccess::new(self))?;
719 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
720 b'}' => {
721 self.eat_char();
722 Ok(value)
723 }
724 _ => Err(Error::ExpectedSomeValue),
725 }
726 }
727 _ => Err(Error::ExpectedSomeValue),
728 }
729 }
730
731 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
732 where
733 V: Visitor<'de>,
734 {
735 self.deserialize_str(visitor)
736 }
737
738 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
741 where
742 V: Visitor<'de>,
743 {
744 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
745 b'"' => self.deserialize_str(visitor),
746 b'[' => self.deserialize_seq(visitor),
747 b'{' => self.deserialize_struct("ignored", &[], visitor),
748 b',' | b'}' | b']' => Err(Error::ExpectedSomeValue),
749 _ => loop {
753 match self.peek() {
754 Some(b',') | Some(b'}') | Some(b']') => break visitor.visit_unit(),
757 Some(_) => self.eat_char(),
758 None => break Err(Error::EofWhileParsingString),
759 }
760 },
761 }
762 }
763}
764
765impl de::Error for Error {
766 #[cfg_attr(not(feature = "custom-error-messages"), allow(unused_variables))]
767 fn custom<T>(msg: T) -> Self
768 where
769 T: fmt::Display,
770 {
771 #[cfg(not(feature = "custom-error-messages"))]
772 {
773 Error::CustomError
774 }
775 #[cfg(feature = "custom-error-messages")]
776 {
777 use core::fmt::Write;
778
779 let mut string = heapless::String::new();
780 write!(string, "{:.64}", msg).unwrap();
781 Error::CustomErrorWithMessage(string)
782 }
783 }
784}
785
786impl fmt::Display for Error {
787 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
788 write!(
789 f,
790 "{}",
791 match self {
792 Error::EofWhileParsingList => "EOF while parsing a list.",
793 Error::EofWhileParsingObject => "EOF while parsing an object.",
794 Error::EofWhileParsingString => "EOF while parsing a string.",
795 Error::EofWhileParsingValue => "EOF while parsing a JSON value.",
796 Error::ExpectedColon => "Expected this character to be a `':'`.",
797 Error::ExpectedListCommaOrEnd => {
798 "Expected this character to be either a `','` or\
799 a \
800 `']'`."
801 }
802 Error::ExpectedObjectCommaOrEnd => {
803 "Expected this character to be either a `','` \
804 or a \
805 `'}'`."
806 }
807 Error::ExpectedSomeIdent => {
808 "Expected to parse either a `true`, `false`, or a \
809 `null`."
810 }
811 Error::ExpectedSomeValue => "Expected this character to start a JSON value.",
812 Error::InvalidNumber => "Invalid number.",
813 Error::InvalidType => "Invalid type",
814 Error::InvalidUnicodeCodePoint => "Invalid unicode code point.",
815 Error::KeyMustBeAString => "Object key is not a string.",
816 Error::TrailingCharacters => {
817 "JSON has non-whitespace trailing characters after \
818 the \
819 value."
820 }
821 Error::TrailingComma => "JSON has a comma after the last value in an array or map.",
822 Error::CustomError => "JSON does not match deserializer’s expected format.",
823 #[cfg(feature = "custom-error-messages")]
824 Error::CustomErrorWithMessage(msg) => msg.as_str(),
825 _ => "Invalid JSON",
826 }
827 )
828 }
829}
830
831fn from_slice_maybe_escaped<'a, T>(
832 v: &'a [u8],
833 string_unescape_buffer: Option<&mut [u8]>,
834) -> Result<(T, usize)>
835where
836 T: de::Deserialize<'a>,
837{
838 let mut de = Deserializer::new(v, string_unescape_buffer);
839 let value = de::Deserialize::deserialize(&mut de)?;
840 let length = de.end()?;
841
842 Ok((value, length))
843}
844
845pub fn from_slice_escaped<'a, T>(
848 v: &'a [u8],
849 string_unescape_buffer: &mut [u8],
850) -> Result<(T, usize)>
851where
852 T: de::Deserialize<'a>,
853{
854 from_slice_maybe_escaped(v, Some(string_unescape_buffer))
855}
856
857pub fn from_slice<'a, T>(v: &'a [u8]) -> Result<(T, usize)>
860where
861 T: de::Deserialize<'a>,
862{
863 from_slice_maybe_escaped(v, None)
864}
865
866pub fn from_str_escaped<'a, T>(s: &'a str, string_unescape_buffer: &mut [u8]) -> Result<(T, usize)>
868where
869 T: de::Deserialize<'a>,
870{
871 from_slice_escaped(s.as_bytes(), string_unescape_buffer)
872}
873
874pub fn from_str<'a, T>(s: &'a str) -> Result<(T, usize)>
876where
877 T: de::Deserialize<'a>,
878{
879 from_slice(s.as_bytes())
880}
881
882#[cfg(test)]
883mod tests {
884 use serde_derive::Deserialize;
885
886 #[derive(Debug, Deserialize, PartialEq)]
887 enum Type {
888 #[serde(rename = "boolean")]
889 Boolean,
890 #[serde(rename = "number")]
891 Number,
892 #[serde(rename = "thing")]
893 Thing,
894 }
895
896 #[test]
897 fn array() {
898 assert_eq!(crate::from_str::<[i32; 0]>("[]"), Ok(([], 2)));
899 assert_eq!(crate::from_str("[0, 1, 2]"), Ok(([0, 1, 2], 9)));
900
901 assert!(crate::from_str::<[i32; 2]>("[0, 1,]").is_err());
903 }
904
905 #[test]
906 fn bool() {
907 assert_eq!(crate::from_str("true"), Ok((true, 4)));
908 assert_eq!(crate::from_str(" true"), Ok((true, 5)));
909 assert_eq!(crate::from_str("true "), Ok((true, 5)));
910
911 assert_eq!(crate::from_str("false"), Ok((false, 5)));
912 assert_eq!(crate::from_str(" false"), Ok((false, 6)));
913 assert_eq!(crate::from_str("false "), Ok((false, 6)));
914
915 assert!(crate::from_str::<bool>("true false").is_err());
917 assert!(crate::from_str::<bool>("tru").is_err());
918 }
919
920 #[test]
921 fn floating_point() {
922 assert_eq!(crate::from_str("5.0"), Ok((5.0, 3)));
923 assert_eq!(crate::from_str("1"), Ok((1.0, 1)));
924 assert_eq!(crate::from_str("1e5"), Ok((1e5, 3)));
925 assert!(crate::from_str::<f32>("a").is_err());
926 assert!(crate::from_str::<f32>(",").is_err());
927 }
928
929 #[test]
930 fn integer() {
931 assert_eq!(crate::from_str("5"), Ok((5, 1)));
932 assert_eq!(crate::from_str("101"), Ok((101, 3)));
933 assert!(crate::from_str::<u16>("1e5").is_err());
934 assert!(crate::from_str::<u8>("256").is_err());
935 assert!(crate::from_str::<f32>(",").is_err());
936 }
937
938 #[test]
939 fn enum_clike() {
940 assert_eq!(crate::from_str(r#" "boolean" "#), Ok((Type::Boolean, 11)));
941 assert_eq!(crate::from_str(r#" "number" "#), Ok((Type::Number, 10)));
942 assert_eq!(crate::from_str(r#" "thing" "#), Ok((Type::Thing, 9)));
943 }
944
945 #[test]
946 fn char() {
947 fn from_str_test<'de, T: serde::Deserialize<'de>>(
948 s: &'de str,
949 ) -> super::Result<(T, usize)> {
950 crate::from_str_escaped(s, &mut [0; 8])
951 }
952
953 assert_eq!(from_str_test(r#""n""#), Ok(('n', 3)));
954 assert_eq!(from_str_test(r#""\"""#), Ok(('"', 4)));
955 assert_eq!(from_str_test(r#""\\""#), Ok(('\\', 4)));
956 assert_eq!(from_str_test(r#""/""#), Ok(('/', 3)));
957 assert_eq!(from_str_test(r#""\b""#), Ok(('\x08', 4)));
958 assert_eq!(from_str_test(r#""\f""#), Ok(('\x0C', 4)));
959 assert_eq!(from_str_test(r#""\n""#), Ok(('\n', 4)));
960 assert_eq!(from_str_test(r#""\r""#), Ok(('\r', 4)));
961 assert_eq!(from_str_test(r#""\t""#), Ok(('\t', 4)));
962 assert_eq!(from_str_test(r#""\u000b""#), Ok(('\x0B', 8)));
963 assert_eq!(from_str_test(r#""\u000B""#), Ok(('\x0B', 8)));
964 assert_eq!(from_str_test(r#""Σ""#), Ok(('Σ', 4)));
965 }
966
967 #[test]
968 fn str() {
969 assert_eq!(crate::from_str(r#" "hello" "#), Ok(("hello", 9)));
971 assert_eq!(crate::from_str(r#" "" "#), Ok(("", 4)));
972 assert_eq!(crate::from_str(r#" " " "#), Ok((" ", 5)));
973 assert_eq!(crate::from_str(r#" "👏" "#), Ok(("👏", 8)));
974
975 fn s(s: &'static str) -> heapless::String<1024> {
976 s.parse().expect("Failed to create test string")
977 }
978
979 fn from_str_test<'de, T: serde::Deserialize<'de>>(
980 s: &'de str,
981 ) -> super::Result<(T, usize)> {
982 crate::from_str_escaped(s, &mut [0; 16])
983 }
984
985 assert_eq!(from_str_test(r#" "foo\"bar" "#), Ok((s(r#"foo"bar"#), 12)));
987 assert_eq!(
988 from_str_test(r#" "foo\\\"bar" "#),
989 Ok((s(r#"foo\"bar"#), 14))
990 );
991 assert_eq!(
992 from_str_test(r#" "foo\"\"bar" "#),
993 Ok((s(r#"foo""bar"#), 14))
994 );
995 assert_eq!(from_str_test(r#" "\"bar" "#), Ok((s(r#""bar"#), 9)));
996 assert_eq!(from_str_test(r#" "foo\"" "#), Ok((s(r#"foo""#), 9)));
997 assert_eq!(from_str_test(r#" "\"" "#), Ok((s(r#"""#), 6)));
998
999 assert_eq!(
1001 from_str_test(r#" "foo bar\\" "#),
1002 Ok((s(r#"foo bar\"#), 13))
1003 );
1004 assert_eq!(
1005 from_str_test(r#" "foo bar\\\\" "#),
1006 Ok((s(r#"foo bar\\"#), 15))
1007 );
1008 assert_eq!(
1009 from_str_test(r#" "foo bar\\\\\\" "#),
1010 Ok((s(r#"foo bar\\\"#), 17))
1011 );
1012 assert_eq!(
1013 from_str_test(r#" "foo bar\\\\\\\\" "#),
1014 Ok((s(r#"foo bar\\\\"#), 19))
1015 );
1016 assert_eq!(from_str_test(r#" "\\" "#), Ok((s(r#"\"#), 6)));
1017 }
1018
1019 #[test]
1020 fn tuple_of_str() {
1021 fn s(s: &'static str) -> heapless::String<1024> {
1022 s.parse().expect("Failed to create test string")
1023 }
1024
1025 fn from_str_test<'de, T: serde::Deserialize<'de>>(
1026 s: &'de str,
1027 ) -> super::Result<(T, usize)> {
1028 crate::from_str_escaped(s, &mut [0; 16])
1029 }
1030
1031 assert_eq!(
1037 from_str_test(
1038 r#" [ "AAAAAAAAAAAA\n", "BBBBBBBBBBBBBBBBBBBBBBBB", "CCCCCCCCCCCC\n" ] "#
1039 ),
1040 Ok((
1041 (
1042 s("AAAAAAAAAAAA\n"),
1043 "BBBBBBBBBBBBBBBBBBBBBBBB",
1044 s("CCCCCCCCCCCC\n")
1045 ),
1046 68
1047 ))
1048 );
1049 }
1050
1051 #[test]
1052 fn escaped_str() {
1053 assert_eq!(
1054 crate::from_str(r#""Hello\nWorld""#),
1055 Ok((crate::str::EscapedStr(r#"Hello\nWorld"#), 14))
1056 );
1057 }
1058
1059 #[test]
1060 fn struct_bool() {
1061 #[derive(Debug, Deserialize, PartialEq)]
1062 struct Led {
1063 led: bool,
1064 }
1065
1066 assert_eq!(
1067 crate::from_str(r#"{ "led": true }"#),
1068 Ok((Led { led: true }, 15))
1069 );
1070 assert_eq!(
1071 crate::from_str(r#"{ "led": false }"#),
1072 Ok((Led { led: false }, 16))
1073 );
1074 }
1075
1076 #[test]
1077 fn struct_i8() {
1078 #[derive(Debug, Deserialize, PartialEq)]
1079 struct Temperature {
1080 temperature: i8,
1081 }
1082
1083 assert_eq!(
1084 crate::from_str(r#"{ "temperature": -17 }"#),
1085 Ok((Temperature { temperature: -17 }, 22))
1086 );
1087
1088 assert_eq!(
1089 crate::from_str(r#"{ "temperature": -0 }"#),
1090 Ok((Temperature { temperature: -0 }, 21))
1091 );
1092
1093 assert_eq!(
1094 crate::from_str(r#"{ "temperature": 0 }"#),
1095 Ok((Temperature { temperature: 0 }, 20))
1096 );
1097
1098 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 128 }"#).is_err());
1100 assert!(crate::from_str::<Temperature>(r#"{ "temperature": -129 }"#).is_err());
1101 }
1102
1103 #[test]
1104 fn struct_f32() {
1105 #[derive(Debug, Deserialize, PartialEq)]
1106 struct Temperature {
1107 temperature: f32,
1108 }
1109
1110 assert_eq!(
1111 crate::from_str(r#"{ "temperature": -17.2 }"#),
1112 Ok((Temperature { temperature: -17.2 }, 24))
1113 );
1114
1115 assert_eq!(
1116 crate::from_str(r#"{ "temperature": -0.0 }"#),
1117 Ok((Temperature { temperature: -0. }, 23))
1118 );
1119
1120 assert_eq!(
1121 crate::from_str(r#"{ "temperature": -2.1e-3 }"#),
1122 Ok((
1123 Temperature {
1124 temperature: -2.1e-3
1125 },
1126 26
1127 ))
1128 );
1129
1130 assert_eq!(
1131 crate::from_str(r#"{ "temperature": -3 }"#),
1132 Ok((Temperature { temperature: -3. }, 21))
1133 );
1134
1135 use core::f32;
1136
1137 assert_eq!(
1138 crate::from_str(r#"{ "temperature": -1e500 }"#),
1139 Ok((
1140 Temperature {
1141 temperature: f32::NEG_INFINITY
1142 },
1143 25
1144 ))
1145 );
1146
1147 let (r, n): (Temperature, usize) = crate::from_str(r#"{ "temperature": null }"#).unwrap();
1149 assert!(r.temperature.is_nan());
1150 assert_eq!(n, 23);
1151
1152 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 1e1e1 }"#).is_err());
1153 assert!(crate::from_str::<Temperature>(r#"{ "temperature": -2-2 }"#).is_err());
1154 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 1 1 }"#).is_err());
1155 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 0.0. }"#).is_err());
1156 assert!(crate::from_str::<Temperature>(r#"{ "temperature": ä }"#).is_err());
1157 assert!(crate::from_str::<Temperature>(r#"{ "temperature": None }"#).is_err());
1158 }
1159
1160 #[test]
1161 fn struct_option() {
1162 #[derive(Debug, Deserialize, PartialEq)]
1163 struct Property<'a> {
1164 #[serde(borrow)]
1165 description: Option<&'a str>,
1166 }
1167
1168 assert_eq!(
1169 crate::from_str(r#"{ "description": "An ambient temperature sensor" }"#),
1170 Ok((
1171 Property {
1172 description: Some("An ambient temperature sensor"),
1173 },
1174 50
1175 ))
1176 );
1177
1178 assert_eq!(
1179 crate::from_str(r#"{ "description": null }"#),
1180 Ok((Property { description: None }, 23))
1181 );
1182
1183 assert_eq!(
1184 crate::from_str(r#"{}"#),
1185 Ok((Property { description: None }, 2))
1186 );
1187 }
1188
1189 #[test]
1190 fn struct_u8() {
1191 #[derive(Debug, Deserialize, PartialEq)]
1192 struct Temperature {
1193 temperature: u8,
1194 }
1195
1196 assert_eq!(
1197 crate::from_str(r#"{ "temperature": 20 }"#),
1198 Ok((Temperature { temperature: 20 }, 21))
1199 );
1200
1201 assert_eq!(
1202 crate::from_str(r#"{ "temperature": 0 }"#),
1203 Ok((Temperature { temperature: 0 }, 20))
1204 );
1205
1206 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 256 }"#).is_err());
1208 assert!(crate::from_str::<Temperature>(r#"{ "temperature": -1 }"#).is_err());
1209 }
1210
1211 #[test]
1212 fn test_unit() {
1213 assert_eq!(crate::from_str::<()>(r#"null"#), Ok(((), 4)));
1214 }
1215
1216 #[test]
1217 fn newtype_struct() {
1218 #[derive(Deserialize, Debug, PartialEq)]
1219 struct A(pub u32);
1220
1221 assert_eq!(crate::from_str::<A>(r#"54"#), Ok((A(54), 2)));
1222 }
1223
1224 #[test]
1225 fn test_newtype_variant() {
1226 #[derive(Deserialize, Debug, PartialEq)]
1227 enum A {
1228 A(u32),
1229 }
1230 let a = A::A(54);
1231 let x = crate::from_str::<A>(r#"{"A":54}"#);
1232 assert_eq!(x, Ok((a, 8)));
1233 }
1234
1235 #[test]
1236 fn test_struct_variant() {
1237 #[derive(Deserialize, Debug, PartialEq)]
1238 enum A {
1239 A { x: u32, y: u16 },
1240 }
1241 let a = A::A { x: 54, y: 720 };
1242 let x = crate::from_str::<A>(r#"{"A": {"x":54,"y":720 } }"#);
1243 assert_eq!(x, Ok((a, 25)));
1244 }
1245
1246 #[test]
1247 #[cfg(not(feature = "custom-error-messages"))]
1248 fn struct_tuple() {
1249 #[derive(Debug, Deserialize, PartialEq)]
1250 struct Xy(i8, i8);
1251
1252 assert_eq!(crate::from_str(r#"[10, 20]"#), Ok((Xy(10, 20), 8)));
1253 assert_eq!(crate::from_str(r#"[10, -20]"#), Ok((Xy(10, -20), 9)));
1254
1255 assert_eq!(
1257 crate::from_str::<Xy>(r#"[10]"#),
1258 Err(crate::de::Error::CustomError)
1259 );
1260 assert_eq!(
1261 crate::from_str::<Xy>(r#"[10, 20, 30]"#),
1262 Err(crate::de::Error::TrailingCharacters)
1263 );
1264 }
1265
1266 #[test]
1267 #[cfg(feature = "custom-error-messages")]
1268 fn struct_tuple() {
1269 #[derive(Debug, Deserialize, PartialEq)]
1270 struct Xy(i8, i8);
1271
1272 assert_eq!(crate::from_str(r#"[10, 20]"#), Ok((Xy(10, 20), 8)));
1273 assert_eq!(crate::from_str(r#"[10, -20]"#), Ok((Xy(10, -20), 9)));
1274
1275 assert_eq!(
1277 crate::from_str::<Xy>(r#"[10]"#),
1278 Err(crate::de::Error::CustomErrorWithMessage(
1279 "invalid length 1, expected tuple struct Xy with 2 elements"
1280 .parse()
1281 .unwrap()
1282 ))
1283 );
1284 assert_eq!(
1285 crate::from_str::<Xy>(r#"[10, 20, 30]"#),
1286 Err(crate::de::Error::TrailingCharacters)
1287 );
1288 }
1289
1290 #[test]
1291 fn struct_with_array_field() {
1292 #[derive(Debug, Deserialize, PartialEq)]
1293 struct Test {
1294 status: bool,
1295 point: [u32; 3],
1296 }
1297
1298 assert_eq!(
1299 crate::from_str(r#"{ "status": true, "point": [1, 2, 3] }"#),
1300 Ok((
1301 Test {
1302 status: true,
1303 point: [1, 2, 3]
1304 },
1305 38
1306 ))
1307 );
1308 }
1309
1310 #[test]
1311 fn struct_with_tuple_field() {
1312 #[derive(Debug, Deserialize, PartialEq)]
1313 struct Test {
1314 status: bool,
1315 point: (u32, u32, u32),
1316 }
1317
1318 assert_eq!(
1319 crate::from_str(r#"{ "status": true, "point": [1, 2, 3] }"#),
1320 Ok((
1321 Test {
1322 status: true,
1323 point: (1, 2, 3)
1324 },
1325 38
1326 ))
1327 );
1328 }
1329
1330 #[test]
1331 fn ignoring_extra_fields() {
1332 #[derive(Debug, Deserialize, PartialEq)]
1333 struct Temperature {
1334 temperature: u8,
1335 }
1336
1337 assert_eq!(
1338 crate::from_str(r#"{ "temperature": 20, "high": 80, "low": -10, "updated": true }"#),
1339 Ok((Temperature { temperature: 20 }, 62))
1340 );
1341
1342 assert_eq!(
1343 crate::from_str(
1344 r#"{ "temperature": 20, "conditions": "windy", "forecast": "cloudy" }"#
1345 ),
1346 Ok((Temperature { temperature: 20 }, 66))
1347 );
1348
1349 assert_eq!(
1350 crate::from_str(r#"{ "temperature": 20, "hourly_conditions": ["windy", "rainy"] }"#),
1351 Ok((Temperature { temperature: 20 }, 62))
1352 );
1353
1354 assert_eq!(
1355 crate::from_str(
1356 r#"{ "temperature": 20, "source": { "station": "dock", "sensors": ["front", "back"] } }"#
1357 ),
1358 Ok((Temperature { temperature: 20 }, 84))
1359 );
1360
1361 assert_eq!(
1362 crate::from_str(r#"{ "temperature": 20, "invalid": this-is-ignored }"#),
1363 Ok((Temperature { temperature: 20 }, 49))
1364 );
1365
1366 assert_eq!(
1367 crate::from_str::<Temperature>(r#"{ "temperature": 20, "broken": }"#),
1368 Err(crate::de::Error::ExpectedSomeValue)
1369 );
1370
1371 assert_eq!(
1372 crate::from_str::<Temperature>(r#"{ "temperature": 20, "broken": [ }"#),
1373 Err(crate::de::Error::ExpectedSomeValue)
1374 );
1375
1376 assert_eq!(
1377 crate::from_str::<Temperature>(r#"{ "temperature": 20, "broken": ] }"#),
1378 Err(crate::de::Error::ExpectedSomeValue)
1379 );
1380 }
1381
1382 #[test]
1383 #[cfg(feature = "custom-error-messages")]
1384 fn preserve_short_error_message() {
1385 use serde::de::Error;
1386 assert_eq!(
1387 crate::de::Error::custom("something bad happened"),
1388 crate::de::Error::CustomErrorWithMessage("something bad happened".parse().unwrap())
1389 );
1390 }
1391
1392 #[test]
1393 #[cfg(feature = "custom-error-messages")]
1394 fn truncate_error_message() {
1395 use serde::de::Error;
1396 assert_eq!(
1397 crate::de::Error::custom("0123456789012345678901234567890123456789012345678901234567890123 <- after here the message should be truncated"),
1398 crate::de::Error::CustomErrorWithMessage(
1399 "0123456789012345678901234567890123456789012345678901234567890123".parse().unwrap()
1400 )
1401 );
1402 }
1403
1404 #[test]
1406 fn wot() {
1407 #[derive(Debug, Deserialize, PartialEq)]
1408 struct Thing<'a> {
1409 #[serde(borrow)]
1410 properties: Properties<'a>,
1411 #[serde(rename = "type")]
1412 ty: Type,
1413 }
1414
1415 #[derive(Debug, Deserialize, PartialEq)]
1416 struct Properties<'a> {
1417 #[serde(borrow)]
1418 temperature: Property<'a>,
1419 #[serde(borrow)]
1420 humidity: Property<'a>,
1421 #[serde(borrow)]
1422 led: Property<'a>,
1423 }
1424
1425 #[derive(Debug, Deserialize, PartialEq)]
1426 struct Property<'a> {
1427 #[serde(rename = "type")]
1428 ty: Type,
1429 unit: Option<&'a str>,
1430 #[serde(borrow)]
1431 description: Option<&'a str>,
1432 href: &'a str,
1433 }
1434
1435 assert_eq!(
1436 crate::from_str::<Thing<'_>>(
1437 r#"
1438 {
1439 "type": "thing",
1440 "properties": {
1441 "temperature": {
1442 "type": "number",
1443 "unit": "celsius",
1444 "description": "An ambient temperature sensor",
1445 "href": "/properties/temperature"
1446 },
1447 "humidity": {
1448 "type": "number",
1449 "unit": "percent",
1450 "href": "/properties/humidity"
1451 },
1452 "led": {
1453 "type": "boolean",
1454 "description": "A red LED",
1455 "href": "/properties/led"
1456 }
1457 }
1458 }
1459 "#
1460 ),
1461 Ok((
1462 Thing {
1463 properties: Properties {
1464 temperature: Property {
1465 ty: Type::Number,
1466 unit: Some("celsius"),
1467 description: Some("An ambient temperature sensor"),
1468 href: "/properties/temperature",
1469 },
1470 humidity: Property {
1471 ty: Type::Number,
1472 unit: Some("percent"),
1473 description: None,
1474 href: "/properties/humidity",
1475 },
1476 led: Property {
1477 ty: Type::Boolean,
1478 unit: None,
1479 description: Some("A red LED"),
1480 href: "/properties/led",
1481 },
1482 },
1483 ty: Type::Thing,
1484 },
1485 852
1486 ))
1487 )
1488 }
1489}