1use core::{fmt, str};
4
5use serde::de::{self, Visitor};
6
7use self::enum_::UnitVariantAccess;
8use self::map::MapAccess;
9use self::seq::SeqAccess;
10
11mod enum_;
12mod map;
13mod seq;
14
15pub type Result<T> = core::result::Result<T, Error>;
17
18#[derive(Debug, PartialEq)]
20pub enum Error {
21 EofWhileParsingList,
23
24 EofWhileParsingObject,
26
27 EofWhileParsingString,
29
30 EofWhileParsingValue,
32
33 ExpectedColon,
35
36 ExpectedListCommaOrEnd,
38
39 ExpectedObjectCommaOrEnd,
41
42 ExpectedSomeIdent,
44
45 ExpectedSomeValue,
47
48 InvalidNumber,
50
51 InvalidType,
53
54 InvalidUnicodeCodePoint,
56
57 KeyMustBeAString,
59
60 TrailingCharacters,
62
63 TrailingComma,
65
66 #[doc(hidden)]
67 __Extensible,
68}
69
70#[cfg(feature = "std")]
71impl ::std::error::Error for Error {
72 fn description(&self) -> &str {
73 ""
74 }
75}
76
77pub(crate) struct Deserializer<'b> {
78 slice: &'b [u8],
79 index: usize,
80}
81
82impl<'a> Deserializer<'a> {
83 fn new(slice: &'a [u8]) -> Deserializer<'_> {
84 Deserializer { slice, index: 0 }
85 }
86
87 fn eat_char(&mut self) {
88 self.index += 1;
89 }
90
91 fn end(&mut self) -> Result<()> {
92 match self.parse_whitespace() {
93 Some(_) => Err(Error::TrailingCharacters),
94 None => Ok(()),
95 }
96 }
97
98 fn end_seq(&mut self) -> Result<()> {
99 match self.parse_whitespace().ok_or(Error::EofWhileParsingList)? {
100 b']' => {
101 self.eat_char();
102 Ok(())
103 }
104 b',' => {
105 self.eat_char();
106 match self.parse_whitespace() {
107 Some(b']') => Err(Error::TrailingComma),
108 _ => Err(Error::TrailingCharacters),
109 }
110 }
111 _ => Err(Error::TrailingCharacters),
112 }
113 }
114
115 fn end_map(&mut self) -> Result<()> {
116 match self
117 .parse_whitespace()
118 .ok_or(Error::EofWhileParsingObject)?
119 {
120 b'}' => {
121 self.eat_char();
122 Ok(())
123 }
124 b',' => Err(Error::TrailingComma),
125 _ => Err(Error::TrailingCharacters),
126 }
127 }
128
129 fn next_char(&mut self) -> Option<u8> {
130 let ch = self.slice.get(self.index);
131
132 if ch.is_some() {
133 self.index += 1;
134 }
135
136 ch.cloned()
137 }
138
139 fn parse_ident(&mut self, ident: &[u8]) -> Result<()> {
140 for c in ident {
141 if Some(*c) != self.next_char() {
142 return Err(Error::ExpectedSomeIdent);
143 }
144 }
145
146 Ok(())
147 }
148
149 fn parse_object_colon(&mut self) -> Result<()> {
150 match self
151 .parse_whitespace()
152 .ok_or(Error::EofWhileParsingObject)?
153 {
154 b':' => {
155 self.eat_char();
156 Ok(())
157 }
158 _ => Err(Error::ExpectedColon),
159 }
160 }
161
162 fn parse_str(&mut self) -> Result<&'a str> {
163 let start = self.index;
164 loop {
165 match self.peek() {
166 Some(b'"') => {
167 let end = self.index;
168 self.eat_char();
169 return str::from_utf8(&self.slice[start..end])
170 .map_err(|_| Error::InvalidUnicodeCodePoint);
171 }
172 Some(_) => self.eat_char(),
173 None => return Err(Error::EofWhileParsingString),
174 }
175 }
176 }
177
178 fn parse_whitespace(&mut self) -> Option<u8> {
180 loop {
181 match self.peek() {
182 Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') => {
183 self.eat_char();
184 }
185 other => {
186 return other;
187 }
188 }
189 }
190 }
191
192 fn peek(&mut self) -> Option<u8> {
193 self.slice.get(self.index).cloned()
194 }
195}
196
197macro_rules! deserialize_unsigned {
201 ($self:ident, $visitor:ident, $uxx:ident, $visit_uxx:ident) => {{
202 let peek = $self
203 .parse_whitespace()
204 .ok_or(Error::EofWhileParsingValue)?;
205
206 match peek {
207 b'-' => Err(Error::InvalidNumber),
208 b'0' => {
209 $self.eat_char();
210 $visitor.$visit_uxx(0)
211 }
212 b'1'..=b'9' => {
213 $self.eat_char();
214
215 let mut number = (peek - b'0') as $uxx;
216 loop {
217 match $self.peek() {
218 Some(c @ b'0'..=b'9') => {
219 $self.eat_char();
220 number = number
221 .checked_mul(10)
222 .ok_or(Error::InvalidNumber)?
223 .checked_add((c - b'0') as $uxx)
224 .ok_or(Error::InvalidNumber)?;
225 }
226 _ => return $visitor.$visit_uxx(number),
227 }
228 }
229 }
230 _ => Err(Error::InvalidType),
231 }
232 }};
233}
234
235macro_rules! deserialize_signed {
236 ($self:ident, $visitor:ident, $ixx:ident, $visit_ixx:ident) => {{
237 let signed = match $self
238 .parse_whitespace()
239 .ok_or(Error::EofWhileParsingValue)?
240 {
241 b'-' => {
242 $self.eat_char();
243 true
244 }
245 _ => false,
246 };
247
248 match $self.peek().ok_or(Error::EofWhileParsingValue)? {
249 b'0' => {
250 $self.eat_char();
251 $visitor.$visit_ixx(0)
252 }
253 c @ b'1'..=b'9' => {
254 $self.eat_char();
255
256 let mut number = (c - b'0') as $ixx * if signed { -1 } else { 1 };
257 loop {
258 match $self.peek() {
259 Some(c @ b'0'..=b'9') => {
260 $self.eat_char();
261 number = number
262 .checked_mul(10)
263 .ok_or(Error::InvalidNumber)?
264 .checked_add((c - b'0') as $ixx * if signed { -1 } else { 1 })
265 .ok_or(Error::InvalidNumber)?;
266 }
267 _ => return $visitor.$visit_ixx(number),
268 }
269 }
270 }
271 _ => return Err(Error::InvalidType),
272 }
273 }};
274}
275
276impl<'a, 'de> de::Deserializer<'de> for &'a mut Deserializer<'de> {
277 type Error = Error;
278
279 fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value>
280 where
281 V: Visitor<'de>,
282 {
283 unreachable!()
284 }
285
286 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
287 where
288 V: Visitor<'de>,
289 {
290 let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
291
292 match peek {
293 b't' => {
294 self.eat_char();
295 self.parse_ident(b"rue")?;
296 visitor.visit_bool(true)
297 }
298 b'f' => {
299 self.eat_char();
300 self.parse_ident(b"alse")?;
301 visitor.visit_bool(false)
302 }
303 _ => Err(Error::InvalidType),
304 }
305 }
306
307 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
308 where
309 V: Visitor<'de>,
310 {
311 deserialize_signed!(self, visitor, i8, visit_i8)
312 }
313
314 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
315 where
316 V: Visitor<'de>,
317 {
318 deserialize_signed!(self, visitor, i16, visit_i16)
319 }
320
321 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
322 where
323 V: Visitor<'de>,
324 {
325 deserialize_signed!(self, visitor, i32, visit_i32)
326 }
327
328 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
329 where
330 V: Visitor<'de>,
331 {
332 deserialize_signed!(self, visitor, i64, visit_i64)
333 }
334
335 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
336 where
337 V: Visitor<'de>,
338 {
339 deserialize_unsigned!(self, visitor, u8, visit_u8)
340 }
341
342 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
343 where
344 V: Visitor<'de>,
345 {
346 deserialize_unsigned!(self, visitor, u16, visit_u16)
347 }
348
349 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
350 where
351 V: Visitor<'de>,
352 {
353 deserialize_unsigned!(self, visitor, u32, visit_u32)
354 }
355
356 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
357 where
358 V: Visitor<'de>,
359 {
360 deserialize_unsigned!(self, visitor, u64, visit_u64)
361 }
362
363 fn deserialize_f32<V>(self, _visitor: V) -> Result<V::Value>
364 where
365 V: Visitor<'de>,
366 {
367 unreachable!()
368 }
369
370 fn deserialize_f64<V>(self, _visitor: V) -> Result<V::Value>
371 where
372 V: Visitor<'de>,
373 {
374 unreachable!()
375 }
376
377 fn deserialize_char<V>(self, _visitor: V) -> Result<V::Value>
378 where
379 V: Visitor<'de>,
380 {
381 unreachable!()
382 }
383
384 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
385 where
386 V: Visitor<'de>,
387 {
388 let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
389
390 match peek {
391 b'"' => {
392 self.eat_char();
393 visitor.visit_borrowed_str(self.parse_str()?)
394 }
395 _ => Err(Error::InvalidType),
396 }
397 }
398
399 fn deserialize_string<V>(self, _visitor: V) -> Result<V::Value>
400 where
401 V: Visitor<'de>,
402 {
403 unreachable!()
404 }
405
406 fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
407 where
408 V: Visitor<'de>,
409 {
410 unreachable!()
411 }
412
413 fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
414 where
415 V: Visitor<'de>,
416 {
417 unreachable!()
418 }
419
420 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
421 where
422 V: Visitor<'de>,
423 {
424 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
425 b'n' => {
426 self.eat_char();
427 self.parse_ident(b"ull")?;
428 visitor.visit_none()
429 }
430 _ => visitor.visit_some(self),
431 }
432 }
433
434 fn deserialize_unit<V>(self, _visitor: V) -> Result<V::Value>
435 where
436 V: Visitor<'de>,
437 {
438 unreachable!()
439 }
440
441 fn deserialize_unit_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
442 where
443 V: Visitor<'de>,
444 {
445 unreachable!()
446 }
447
448 fn deserialize_newtype_struct<V>(self, _name: &'static str, _visitor: V) -> Result<V::Value>
449 where
450 V: Visitor<'de>,
451 {
452 unreachable!()
453 }
454
455 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
456 where
457 V: Visitor<'de>,
458 {
459 match self.peek().ok_or(Error::EofWhileParsingValue)? {
460 b'[' => {
461 self.eat_char();
462 let ret = visitor.visit_seq(SeqAccess::new(self))?;
463
464 self.end_seq()?;
465
466 Ok(ret)
467 }
468 _ => Err(Error::InvalidType),
469 }
470 }
471
472 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
473 where
474 V: Visitor<'de>,
475 {
476 self.deserialize_seq(visitor)
477 }
478
479 fn deserialize_tuple_struct<V>(
480 self,
481 _name: &'static str,
482 _len: usize,
483 _visitor: V,
484 ) -> Result<V::Value>
485 where
486 V: Visitor<'de>,
487 {
488 unreachable!()
489 }
490
491 fn deserialize_map<V>(self, _visitor: V) -> Result<V::Value>
492 where
493 V: Visitor<'de>,
494 {
495 unreachable!()
496 }
497
498 fn deserialize_struct<V>(
499 self,
500 _name: &'static str,
501 _fields: &'static [&'static str],
502 visitor: V,
503 ) -> Result<V::Value>
504 where
505 V: Visitor<'de>,
506 {
507 let peek = self.parse_whitespace().ok_or(Error::EofWhileParsingValue)?;
508
509 if peek == b'{' {
510 self.eat_char();
511
512 let ret = visitor.visit_map(MapAccess::new(self))?;
513
514 self.end_map()?;
515
516 Ok(ret)
517 } else {
518 Err(Error::InvalidType)
519 }
520 }
521
522 fn deserialize_enum<V>(
523 self,
524 _name: &'static str,
525 _variants: &'static [&'static str],
526 visitor: V,
527 ) -> Result<V::Value>
528 where
529 V: Visitor<'de>,
530 {
531 match self.parse_whitespace().ok_or(Error::EofWhileParsingValue)? {
532 b'"' => visitor.visit_enum(UnitVariantAccess::new(self)),
533 _ => Err(Error::ExpectedSomeValue),
534 }
535 }
536
537 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
538 where
539 V: Visitor<'de>,
540 {
541 self.deserialize_str(visitor)
542 }
543
544 fn deserialize_ignored_any<V>(self, _visitor: V) -> Result<V::Value>
545 where
546 V: Visitor<'de>,
547 {
548 unreachable!()
549 }
550}
551
552impl de::Error for Error {
553 fn custom<T>(_msg: T) -> Self
554 where
555 T: fmt::Display,
556 {
557 unreachable!()
558 }
559}
560
561impl fmt::Display for Error {
562 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
563 write!(
564 f,
565 "{}",
566 match self {
567 Error::EofWhileParsingList => "EOF while parsing a list.",
568 Error::EofWhileParsingObject => "EOF while parsing an object.",
569 Error::EofWhileParsingString => "EOF while parsing a string.",
570 Error::EofWhileParsingValue => "EOF while parsing a JSON value.",
571 Error::ExpectedColon => "Expected this character to be a `':'`.",
572 Error::ExpectedListCommaOrEnd => {
573 "Expected this character to be either a `','` or\
574 a \
575 `']'`."
576 }
577 Error::ExpectedObjectCommaOrEnd => {
578 "Expected this character to be either a `','` \
579 or a \
580 `'}'`."
581 }
582 Error::ExpectedSomeIdent => {
583 "Expected to parse either a `true`, `false`, or a \
584 `null`."
585 }
586 Error::ExpectedSomeValue => "Expected this character to start a JSON value.",
587 Error::InvalidNumber => "Invalid number.",
588 Error::InvalidType => "Invalid type",
589 Error::InvalidUnicodeCodePoint => "Invalid unicode code point.",
590 Error::KeyMustBeAString => "Object key is not a string.",
591 Error::TrailingCharacters => {
592 "JSON has non-whitespace trailing characters after \
593 the \
594 value."
595 }
596 Error::TrailingComma => "JSON has a comma after the last value in an array or map.",
597 _ => "Invalid JSON",
598 }
599 )
600 }
601}
602
603pub fn from_slice<'a, T>(v: &'a [u8]) -> Result<T>
605where
606 T: de::Deserialize<'a>,
607{
608 let mut de = Deserializer::new(v);
609 let value = de::Deserialize::deserialize(&mut de)?;
610 de.end()?;
611
612 Ok(value)
613}
614
615pub fn from_str<'a, T>(s: &'a str) -> Result<T>
617where
618 T: de::Deserialize<'a>,
619{
620 from_slice(s.as_bytes())
621}
622
623#[cfg(test)]
624mod tests {
625 use serde_derive::Deserialize;
626
627 #[derive(Debug, Deserialize, PartialEq)]
628 enum Type {
629 #[serde(rename = "boolean")]
630 Boolean,
631 #[serde(rename = "number")]
632 Number,
633 #[serde(rename = "thing")]
634 Thing,
635 }
636
637 #[test]
638 fn array() {
639 assert_eq!(crate::from_str::<[i32; 0]>("[]"), Ok([]));
640 assert_eq!(crate::from_str("[0, 1, 2]"), Ok([0, 1, 2]));
641
642 assert!(crate::from_str::<[i32; 2]>("[0, 1,]").is_err());
644 }
645
646 #[test]
647 fn bool() {
648 assert_eq!(crate::from_str("true"), Ok(true));
649 assert_eq!(crate::from_str(" true"), Ok(true));
650 assert_eq!(crate::from_str("true "), Ok(true));
651
652 assert_eq!(crate::from_str("false"), Ok(false));
653 assert_eq!(crate::from_str(" false"), Ok(false));
654 assert_eq!(crate::from_str("false "), Ok(false));
655
656 assert!(crate::from_str::<bool>("true false").is_err());
658 assert!(crate::from_str::<bool>("tru").is_err());
659 }
660
661 #[test]
662 fn enum_clike() {
663 assert_eq!(crate::from_str(r#" "boolean" "#), Ok(Type::Boolean));
664 assert_eq!(crate::from_str(r#" "number" "#), Ok(Type::Number));
665 assert_eq!(crate::from_str(r#" "thing" "#), Ok(Type::Thing));
666 }
667
668 #[test]
669 fn str() {
670 assert_eq!(crate::from_str(r#" "hello" "#), Ok("hello"));
671 }
672
673 #[test]
674 fn struct_bool() {
675 #[derive(Debug, Deserialize, PartialEq)]
676 struct Led {
677 led: bool,
678 }
679
680 assert_eq!(crate::from_str(r#"{ "led": true }"#), Ok(Led { led: true }));
681 assert_eq!(
682 crate::from_str(r#"{ "led": false }"#),
683 Ok(Led { led: false })
684 );
685 }
686
687 #[test]
688 fn struct_i8() {
689 #[derive(Debug, Deserialize, PartialEq)]
690 struct Temperature {
691 temperature: i8,
692 }
693
694 assert_eq!(
695 crate::from_str(r#"{ "temperature": -17 }"#),
696 Ok(Temperature { temperature: -17 })
697 );
698
699 assert_eq!(
700 crate::from_str(r#"{ "temperature": -0 }"#),
701 Ok(Temperature { temperature: -0 })
702 );
703
704 assert_eq!(
705 crate::from_str(r#"{ "temperature": 0 }"#),
706 Ok(Temperature { temperature: 0 })
707 );
708
709 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 128 }"#).is_err());
711 assert!(crate::from_str::<Temperature>(r#"{ "temperature": -129 }"#).is_err());
712 }
713
714 #[test]
715 fn struct_option() {
716 #[derive(Debug, Deserialize, PartialEq)]
717 struct Property<'a> {
718 #[serde(borrow)]
719 description: Option<&'a str>,
720 }
721
722 assert_eq!(
723 crate::from_str(r#"{ "description": "An ambient temperature sensor" }"#),
724 Ok(Property {
725 description: Some("An ambient temperature sensor"),
726 })
727 );
728
729 assert_eq!(
730 crate::from_str(r#"{ "description": null }"#),
731 Ok(Property { description: None })
732 );
733
734 assert_eq!(crate::from_str(r#"{}"#), Ok(Property { description: None }));
735 }
736
737 #[test]
738 fn struct_u8() {
739 #[derive(Debug, Deserialize, PartialEq)]
740 struct Temperature {
741 temperature: u8,
742 }
743
744 assert_eq!(
745 crate::from_str(r#"{ "temperature": 20 }"#),
746 Ok(Temperature { temperature: 20 })
747 );
748
749 assert_eq!(
750 crate::from_str(r#"{ "temperature": 0 }"#),
751 Ok(Temperature { temperature: 0 })
752 );
753
754 assert!(crate::from_str::<Temperature>(r#"{ "temperature": 256 }"#).is_err());
756 assert!(crate::from_str::<Temperature>(r#"{ "temperature": -1 }"#).is_err());
757 }
758
759 #[test]
761 #[ignore]
762 fn wot() {
763 #[derive(Debug, Deserialize, PartialEq)]
764 struct Thing<'a> {
765 #[serde(borrow)]
766 properties: Properties<'a>,
767 #[serde(rename = "type")]
768 ty: Type,
769 }
770
771 #[derive(Debug, Deserialize, PartialEq)]
772 struct Properties<'a> {
773 #[serde(borrow)]
774 temperature: Property<'a>,
775 #[serde(borrow)]
776 humidity: Property<'a>,
777 #[serde(borrow)]
778 led: Property<'a>,
779 }
780
781 #[derive(Debug, Deserialize, PartialEq)]
782 struct Property<'a> {
783 #[serde(rename = "type")]
784 ty: Type,
785 unit: Option<&'a str>,
786 #[serde(borrow)]
787 description: Option<&'a str>,
788 href: &'a str,
789 }
790
791 assert_eq!(
792 crate::from_str::<Thing<'_>>(
793 r#"
794{
795 "type": "thing",
796 "properties": {
797 "temperature": {
798 "type": "number",
799 "unit": "celsius",
800 "description": "An ambient temperature sensor",
801 "href": "/properties/temperature"
802 },
803 "humidity": {
804 "type": "number",
805 "unit": "percent",
806 "href": "/properties/humidity"
807 },
808 "led": {
809 "type": "boolean",
810 "description": "A red LED",
811 "href": "/properties/led"
812 }
813 }
814}
815"#
816 ),
817 Ok(Thing {
818 properties: Properties {
819 temperature: Property {
820 ty: Type::Number,
821 unit: Some("celcius"),
822 description: Some("An ambient temperature sensor"),
823 href: "/properties/temperature",
824 },
825 humidity: Property {
826 ty: Type::Number,
827 unit: Some("percent"),
828 description: None,
829 href: "/properties/humidity",
830 },
831 led: Property {
832 ty: Type::Boolean,
833 unit: None,
834 description: Some("A red LED"),
835 href: "/properties/led",
836 },
837 },
838 ty: Type::Thing,
839 })
840 )
841 }
842}