1use serde::{
23 Deserialize,
24 de::{self, DeserializeSeed, EnumAccess, MapAccess, SeqAccess, VariantAccess, Visitor},
25};
26use snafu::prelude::*;
27
28use crate::{
29 dom::Parser,
30 tape::{self, TapeRef, TapeType},
31};
32
33#[derive(Debug, Snafu)]
35#[snafu(visibility(pub(crate)))]
36pub enum Error {
37 #[snafu(display("serde error: {message}"))]
38 Custom { message: String },
39
40 #[snafu(transparent)]
44 Tape {
45 #[snafu(backtrace)]
46 source: tape::Error,
47 },
48
49 #[snafu(display("dom error: {source}"))]
50 Dom {
51 #[snafu(backtrace)]
52 source: crate::dom::Error,
53 },
54}
55
56pub type Result<T, E = Error> = std::result::Result<T, E>;
57
58impl From<crate::dom::Error> for Error {
59 fn from(source: crate::dom::Error) -> Self {
60 Error::Dom { source }
61 }
62}
63
64impl de::Error for Error {
65 fn custom<T: std::fmt::Display>(msg: T) -> Self {
66 Error::Custom {
67 message: msg.to_string(),
68 }
69 }
70}
71
72pub fn from_str<T: for<'de> Deserialize<'de>>(json: &str) -> Result<T> {
74 let mut parser = Parser::default();
75 let tape = parser.parse_str(json)?;
76 let mut de = TapeDeserializer { tape };
77 T::deserialize(&mut de)
78}
79
80pub fn from_bytes<T: for<'de> Deserialize<'de>>(json: &[u8]) -> Result<T> {
82 let mut parser = Parser::default();
83 let tape = parser.parse_bytes(json)?;
84 let mut de = TapeDeserializer { tape };
85 T::deserialize(&mut de)
86}
87
88pub fn from_tape<'de, T: Deserialize<'de>>(tape: TapeRef<'de>) -> Result<T> {
93 let mut de = TapeDeserializer { tape };
94 T::deserialize(&mut de)
95}
96
97pub struct TapeDeserializer<'de> {
102 tape: TapeRef<'de>,
103}
104
105#[inline]
114fn deserialize_value<'de, V: Visitor<'de>>(
115 tape: &mut TapeRef<'de>,
116 visitor: V,
117) -> Result<V::Value> {
118 if tape.pos >= tape.tape.len() {
119 return Err(tape::OutOfBoundsSnafu {
120 pos: tape.pos,
121 len: tape.tape.len(),
122 }
123 .build()
124 .into());
125 }
126 let word = tape.current_word_public();
127 let tag = (word >> 56) as u8;
128 match tag {
129 b'r' => {
130 tape.skip(1);
131 deserialize_value(tape, visitor)
132 }
133 b'n' => {
134 tape.skip(1);
135 visitor.visit_unit()
136 }
137 b't' => {
138 tape.skip(1);
139 visitor.visit_bool(true)
140 }
141 b'f' => {
142 tape.skip(1);
143 visitor.visit_bool(false)
144 }
145 b'l' => {
146 let v = tape.get_int64()?;
147 tape.skip(2);
148 visitor.visit_i64(v)
149 }
150 b'u' => {
151 let v = tape.get_uint64()?;
152 tape.skip(2);
153 visitor.visit_u64(v)
154 }
155 b'd' => {
156 let v = tape.get_double()?;
157 tape.skip(2);
158 visitor.visit_f64(v)
159 }
160 b'"' => {
161 let s: &'de str = tape.get_string()?;
162 tape.skip(1);
163 visitor.visit_borrowed_str(s)
164 }
165 b'[' => {
166 let end_idx = tape.scope_close_idx();
167 let count = tape.scope_count();
168 tape.skip(1); let result = visitor.visit_seq(TapeSeqAccess {
170 tape,
171 end_idx,
172 count,
173 })?;
174 tape.skip(1); Ok(result)
176 }
177 b'{' => {
178 let end_idx = tape.scope_close_idx();
179 tape.skip(1); let result = visitor.visit_map(TapeMapAccess { tape, end_idx })?;
181 tape.skip(1); Ok(result)
183 }
184 _ => match TapeType::from_tape_word(word) {
185 Some(_) => Err(tape::UnexpectedTapeTypeSnafu {
188 found: tag,
189 pos: tape.pos(),
190 }
191 .build()
192 .into()),
193 None => Err(tape::UnknownTapeTypeSnafu {
194 tag,
195 pos: tape.pos(),
196 }
197 .build()
198 .into()),
199 },
200 }
201}
202
203fn skip_value(tape: &mut TapeRef<'_>) -> Result<()> {
205 match tape.tape_type() {
206 Some(TapeType::Null) | Some(TapeType::True) | Some(TapeType::False) => {
207 tape.skip(1);
208 }
209 Some(TapeType::Int64) | Some(TapeType::Uint64) | Some(TapeType::Double) => {
210 tape.skip(2);
211 }
212 Some(TapeType::String) => {
213 tape.skip(1);
214 }
215 Some(TapeType::StartArray) | Some(TapeType::StartObject) => {
216 let end_idx = tape.scope_close_idx();
218 tape.seek_public(end_idx);
219 tape.skip(1); }
221 Some(t) => {
222 return Err(tape::UnexpectedTapeTypeSnafu {
223 found: t as u8,
224 pos: tape.pos(),
225 }
226 .build()
227 .into());
228 }
229 None => {
230 return Err(tape::UnknownTapeTypeSnafu {
231 tag: (tape.current_word_public() >> 56) as u8,
232 pos: tape.pos(),
233 }
234 .build()
235 .into());
236 }
237 }
238 Ok(())
239}
240
241struct TapeSeqAccess<'a, 'de: 'a> {
246 tape: &'a mut TapeRef<'de>,
247 end_idx: usize,
248 count: usize,
251}
252
253impl<'a, 'de> SeqAccess<'de> for TapeSeqAccess<'a, 'de> {
254 type Error = Error;
255
256 fn next_element_seed<T: DeserializeSeed<'de>>(&mut self, seed: T) -> Result<Option<T::Value>> {
257 if self.tape.pos() >= self.end_idx {
258 return Ok(None);
259 }
260 seed.deserialize(&mut TapeRefDeserializer { tape: self.tape })
261 .map(Some)
262 }
263
264 fn size_hint(&self) -> Option<usize> {
265 Some(self.count)
266 }
267}
268
269struct TapeMapAccess<'a, 'de: 'a> {
274 tape: &'a mut TapeRef<'de>,
275 end_idx: usize,
276}
277
278impl<'a, 'de> MapAccess<'de> for TapeMapAccess<'a, 'de> {
279 type Error = Error;
280
281 fn next_key_seed<K: DeserializeSeed<'de>>(&mut self, seed: K) -> Result<Option<K::Value>> {
282 if self.tape.pos() >= self.end_idx {
283 return Ok(None);
284 }
285 let word = self.tape.current_word_public();
287 let tag = (word >> 56) as u8;
288 if tag != b'"' {
289 return Err(tape::UnexpectedTapeTypeSnafu {
290 found: tag,
291 pos: self.tape.pos(),
292 }
293 .build()
294 .into());
295 }
296 let key: &'de str = self.tape.get_string()?;
297 self.tape.skip(1);
298 let key_deserializer = de::value::BorrowedStrDeserializer::<Error>::new(key);
299 seed.deserialize(key_deserializer).map(Some)
300 }
301
302 fn next_value_seed<V: DeserializeSeed<'de>>(&mut self, seed: V) -> Result<V::Value> {
303 seed.deserialize(&mut TapeRefDeserializer { tape: self.tape })
304 }
305}
306
307struct TapeEnumAccess<'a, 'de: 'a> {
312 tape: &'a mut TapeRef<'de>,
313 end_idx: usize,
314}
315
316impl<'a, 'de> EnumAccess<'de> for TapeEnumAccess<'a, 'de> {
317 type Error = Error;
318 type Variant = TapeVariantAccess<'a, 'de>;
319
320 fn variant_seed<V: DeserializeSeed<'de>>(self, seed: V) -> Result<(V::Value, Self::Variant)> {
321 let word = self.tape.current_word_public();
322 let tag = (word >> 56) as u8;
323 if tag != b'"' {
324 return Err(tape::UnexpectedTapeTypeSnafu {
325 found: tag,
326 pos: self.tape.pos(),
327 }
328 .build()
329 .into());
330 }
331 let name: &'de str = self.tape.get_string()?;
332 self.tape.skip(1);
333 let name_deserializer = de::value::BorrowedStrDeserializer::<Error>::new(name);
334 let val = seed.deserialize(name_deserializer)?;
335 Ok((
336 val,
337 TapeVariantAccess {
338 tape: self.tape,
339 end_idx: self.end_idx,
340 },
341 ))
342 }
343}
344
345struct TapeVariantAccess<'a, 'de: 'a> {
346 tape: &'a mut TapeRef<'de>,
347 #[allow(dead_code)]
348 end_idx: usize,
349}
350
351impl<'a, 'de> VariantAccess<'de> for TapeVariantAccess<'a, 'de> {
352 type Error = Error;
353
354 fn unit_variant(self) -> Result<()> {
355 Ok(())
356 }
357
358 fn newtype_variant_seed<T: DeserializeSeed<'de>>(self, seed: T) -> Result<T::Value> {
359 seed.deserialize(&mut TapeRefDeserializer { tape: self.tape })
360 }
361
362 fn tuple_variant<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value> {
363 deserialize_value(self.tape, visitor)
364 }
365
366 fn struct_variant<V: Visitor<'de>>(
367 self,
368 _fields: &'static [&'static str],
369 visitor: V,
370 ) -> Result<V::Value> {
371 deserialize_value(self.tape, visitor)
372 }
373}
374
375struct TapeRefDeserializer<'a, 'de: 'a> {
384 tape: &'a mut TapeRef<'de>,
385}
386
387macro_rules! forward_to_deserialize_value {
388 ($($fn:ident)*) => {
389 $(
390 fn $fn<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
391 deserialize_value(self.tape, visitor)
392 }
393 )*
394 };
395}
396
397impl<'a, 'de> de::Deserializer<'de> for &mut TapeRefDeserializer<'a, 'de> {
398 type Error = Error;
399
400 forward_to_deserialize_value! {
402 deserialize_bool
403 deserialize_i8 deserialize_i16 deserialize_i32 deserialize_i64
404 deserialize_u8 deserialize_u16 deserialize_u32 deserialize_u64
405 deserialize_f32 deserialize_f64
406 deserialize_char deserialize_str deserialize_string
407 deserialize_bytes deserialize_byte_buf
408 deserialize_unit
409 deserialize_seq deserialize_map
410 deserialize_identifier
411 }
412
413 fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
414 deserialize_value(self.tape, visitor)
415 }
416
417 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
418 if self.tape.tape_type() == Some(TapeType::Null) {
419 self.tape.skip(1);
420 visitor.visit_none()
421 } else {
422 visitor.visit_some(self)
423 }
424 }
425
426 fn deserialize_newtype_struct<V: Visitor<'de>>(
427 self,
428 _name: &'static str,
429 visitor: V,
430 ) -> Result<V::Value> {
431 visitor.visit_newtype_struct(self)
432 }
433
434 fn deserialize_enum<V: Visitor<'de>>(
435 self,
436 _name: &'static str,
437 _variants: &'static [&'static str],
438 visitor: V,
439 ) -> Result<V::Value> {
440 match self.tape.tape_type() {
441 Some(TapeType::String) => {
442 let s: &'de str = self.tape.get_string()?;
443 self.tape.skip(1);
444 let enum_deserializer = de::value::StrDeserializer::<Error>::new(s);
445 visitor.visit_enum(enum_deserializer)
446 }
447 Some(TapeType::StartObject) => {
448 let end_idx = self.tape.scope_close_idx();
449 self.tape.skip(1); let result = visitor.visit_enum(TapeEnumAccess {
451 tape: self.tape,
452 end_idx,
453 })?;
454 self.tape.skip(1); Ok(result)
456 }
457 _ => deserialize_value(self.tape, visitor),
458 }
459 }
460
461 fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
462 skip_value(self.tape)?;
463 visitor.visit_unit()
464 }
465
466 fn deserialize_unit_struct<V: Visitor<'de>>(
467 self,
468 _name: &'static str,
469 visitor: V,
470 ) -> Result<V::Value> {
471 deserialize_value(self.tape, visitor)
472 }
473
474 fn deserialize_tuple<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value> {
475 deserialize_value(self.tape, visitor)
476 }
477
478 fn deserialize_tuple_struct<V: Visitor<'de>>(
479 self,
480 _name: &'static str,
481 _len: usize,
482 visitor: V,
483 ) -> Result<V::Value> {
484 deserialize_value(self.tape, visitor)
485 }
486
487 fn deserialize_struct<V: Visitor<'de>>(
488 self,
489 _name: &'static str,
490 _fields: &'static [&'static str],
491 visitor: V,
492 ) -> Result<V::Value> {
493 deserialize_value(self.tape, visitor)
494 }
495}
496
497impl<'de> de::Deserializer<'de> for &mut TapeDeserializer<'de> {
502 type Error = Error;
503
504 fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
505 if self.tape.tape_type() == Some(TapeType::Root) {
507 self.tape.skip(1);
508 }
509 deserialize_value(&mut self.tape, visitor)
510 }
511
512 fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
513 if self.tape.tape_type() == Some(TapeType::Root) {
514 self.tape.skip(1);
515 }
516 if self.tape.tape_type() == Some(TapeType::Null) {
517 self.tape.skip(1);
518 visitor.visit_none()
519 } else {
520 visitor.visit_some(self)
521 }
522 }
523
524 fn deserialize_newtype_struct<V: Visitor<'de>>(
525 self,
526 _name: &'static str,
527 visitor: V,
528 ) -> Result<V::Value> {
529 visitor.visit_newtype_struct(self)
530 }
531
532 fn deserialize_enum<V: Visitor<'de>>(
533 self,
534 _name: &'static str,
535 _variants: &'static [&'static str],
536 visitor: V,
537 ) -> Result<V::Value> {
538 if self.tape.tape_type() == Some(TapeType::Root) {
539 self.tape.skip(1);
540 }
541 match self.tape.tape_type() {
542 Some(TapeType::String) => {
543 let s: &'de str = self.tape.get_string()?;
544 self.tape.skip(1);
545 let enum_deserializer = de::value::StrDeserializer::<Error>::new(s);
546 visitor.visit_enum(enum_deserializer)
547 }
548 Some(TapeType::StartObject) => {
549 let end_idx = self.tape.scope_close_idx();
550 self.tape.skip(1);
551 let result = visitor.visit_enum(TapeEnumAccess {
552 tape: &mut self.tape,
553 end_idx,
554 })?;
555 self.tape.skip(1); Ok(result)
557 }
558 _ => {
559 let t = &mut self.tape;
560 deserialize_value(t, visitor)
561 }
562 }
563 }
564
565 fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
566 if self.tape.tape_type() == Some(TapeType::Root) {
567 self.tape.skip(1);
568 }
569 skip_value(&mut self.tape)?;
570 visitor.visit_unit()
571 }
572
573 fn deserialize_bool<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
574 self.deserialize_any(visitor)
575 }
576
577 fn deserialize_i8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
578 self.deserialize_any(visitor)
579 }
580
581 fn deserialize_i16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
582 self.deserialize_any(visitor)
583 }
584
585 fn deserialize_i32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
586 self.deserialize_any(visitor)
587 }
588
589 fn deserialize_i64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
590 self.deserialize_any(visitor)
591 }
592
593 fn deserialize_u8<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
594 self.deserialize_any(visitor)
595 }
596
597 fn deserialize_u16<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
598 self.deserialize_any(visitor)
599 }
600
601 fn deserialize_u32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
602 self.deserialize_any(visitor)
603 }
604
605 fn deserialize_u64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
606 self.deserialize_any(visitor)
607 }
608
609 fn deserialize_f32<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
610 self.deserialize_any(visitor)
611 }
612
613 fn deserialize_f64<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
614 self.deserialize_any(visitor)
615 }
616
617 fn deserialize_char<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
618 self.deserialize_any(visitor)
619 }
620
621 fn deserialize_str<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
622 self.deserialize_any(visitor)
623 }
624
625 fn deserialize_string<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
626 self.deserialize_any(visitor)
627 }
628
629 fn deserialize_bytes<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
630 self.deserialize_any(visitor)
631 }
632
633 fn deserialize_byte_buf<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
634 self.deserialize_any(visitor)
635 }
636
637 fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
638 self.deserialize_any(visitor)
639 }
640
641 fn deserialize_unit_struct<V: Visitor<'de>>(
642 self,
643 _name: &'static str,
644 visitor: V,
645 ) -> Result<V::Value> {
646 self.deserialize_any(visitor)
647 }
648
649 fn deserialize_seq<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
650 self.deserialize_any(visitor)
651 }
652
653 fn deserialize_tuple<V: Visitor<'de>>(self, _len: usize, visitor: V) -> Result<V::Value> {
654 self.deserialize_any(visitor)
655 }
656
657 fn deserialize_tuple_struct<V: Visitor<'de>>(
658 self,
659 _name: &'static str,
660 _len: usize,
661 visitor: V,
662 ) -> Result<V::Value> {
663 self.deserialize_any(visitor)
664 }
665
666 fn deserialize_map<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
667 self.deserialize_any(visitor)
668 }
669
670 fn deserialize_struct<V: Visitor<'de>>(
671 self,
672 _name: &'static str,
673 _fields: &'static [&'static str],
674 visitor: V,
675 ) -> Result<V::Value> {
676 self.deserialize_any(visitor)
677 }
678
679 fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value> {
680 self.deserialize_any(visitor)
681 }
682}
683
684#[cfg(test)]
689mod tests {
690 use serde::Deserialize;
691
692 use super::*;
693
694 #[derive(Debug, Deserialize, PartialEq)]
695 struct Point {
696 x: f64,
697 y: f64,
698 }
699
700 #[derive(Debug, Deserialize, PartialEq)]
701 struct Nested {
702 name: String,
703 value: i64,
704 tags: Vec<String>,
705 }
706
707 #[derive(Debug, Deserialize, PartialEq)]
708 #[serde(rename_all = "snake_case")]
709 enum Color {
710 Red,
711 Green,
712 Blue,
713 Custom { r: u8, g: u8, b: u8 },
714 }
715
716 #[test]
717 fn deserialize_struct() {
718 let p: Point = from_str(r#"{"x": 1.5, "y": -2.0}"#).unwrap();
719 assert_eq!(p, Point { x: 1.5, y: -2.0 });
720 }
721
722 #[test]
723 fn deserialize_nested() {
724 let n: Nested = from_str(r#"{"name":"hello","value":42,"tags":["a","b","c"]}"#).unwrap();
725 assert_eq!(n.name, "hello");
726 assert_eq!(n.value, 42);
727 assert_eq!(n.tags, vec!["a", "b", "c"]);
728 }
729
730 #[test]
731 fn deserialize_vec_of_ints() {
732 let v: Vec<i64> = from_str("[1, 2, 3, -4]").unwrap();
733 assert_eq!(v, vec![1, 2, 3, -4]);
734 }
735
736 #[test]
737 fn deserialize_option_some() {
738 let v: Option<i64> = from_str("42").unwrap();
739 assert_eq!(v, Some(42));
740 }
741
742 #[test]
743 fn deserialize_option_none() {
744 let v: Option<i64> = from_str("null").unwrap();
745 assert_eq!(v, None);
746 }
747
748 #[test]
749 fn deserialize_bool_true() {
750 assert!(from_str::<bool>("true").unwrap());
751 }
752
753 #[test]
754 fn deserialize_bool_false() {
755 assert!(!from_str::<bool>("false").unwrap());
756 }
757
758 #[test]
759 fn deserialize_unit_enum() {
760 let c: Color = from_str(r#""red""#).unwrap();
761 assert_eq!(c, Color::Red);
762 }
763
764 #[test]
765 fn deserialize_struct_enum() {
766 let c: Color = from_str(r#"{"custom": {"r": 10, "g": 20, "b": 30}}"#).unwrap();
767 assert_eq!(
768 c,
769 Color::Custom {
770 r: 10,
771 g: 20,
772 b: 30
773 }
774 );
775 }
776
777 #[test]
778 fn deserialize_f64() {
779 let v: f64 = from_str("1.5").unwrap();
780 assert_eq!(v, 1.5_f64);
781 }
782
783 #[test]
784 fn deserialize_string() {
785 let s: String = from_str(r#""hello world""#).unwrap();
786 assert_eq!(s, "hello world");
787 }
788
789 #[test]
790 fn deserialize_nested_arrays() {
791 let v: Vec<Vec<i64>> = from_str("[[1,2],[3,4],[5]]").unwrap();
792 assert_eq!(v, vec![vec![1, 2], vec![3, 4], vec![5]]);
793 }
794
795 #[derive(Debug, Deserialize, PartialEq)]
796 struct LargeObject {
797 id: u64,
798 name: String,
799 active: bool,
800 score: f64,
801 tags: Vec<String>,
802 meta: Option<String>,
803 }
804
805 #[test]
806 fn deserialize_large_object() {
807 let json = r#"{
808 "id": 12345,
809 "name": "simdjson",
810 "active": true,
811 "score": 9.99,
812 "tags": ["fast", "safe", "rust"],
813 "meta": null
814 }"#;
815 let v: LargeObject = from_str(json).unwrap();
816 assert_eq!(v.id, 12345);
817 assert_eq!(v.name, "simdjson");
818 assert!(v.active);
819 assert!((v.score - 9.99).abs() < 1e-6);
820 assert_eq!(v.tags[0], "fast");
821 assert!(v.meta.is_none());
822 }
823}