1use crate::prelude::*;
52use crate::prelude::{f64_fract, f64_mul_add};
53
54use crate::prelude::{FxHashMap, FxHashSet};
55use smallvec::SmallVec;
56
57use crate::error::{BudgetBreach, Error, Result, closest_name};
58use crate::parser::budget;
59use crate::parser::meter::{AliasCost, CostTally, Meter};
60use crate::parser::{Event, ParseConfig, Parser, ScalarStyle};
61use crate::value::Value;
62use core::fmt;
63
64const FALLBACK_SENTINEL: &str = "$__noyalib_streaming_fallback";
66
67#[cfg(feature = "wasm-opt")]
69const SMALL_VEC_SIZE: usize = 4;
70#[cfg(not(feature = "wasm-opt"))]
71const SMALL_VEC_SIZE: usize = 16;
72
73#[derive(Debug, Clone)]
74enum BufferedEvent {
75 Scalar { value: String, style: ScalarStyle },
76 SeqStart,
77 SeqEnd,
78 MapStart,
79 MapEnd,
80 Alias { anchor: String },
81}
82
83#[derive(Debug, Clone)]
84pub(crate) enum Scalar<'a> {
85 Null,
86 Bool(bool),
87 Int(i64),
88 #[cfg(feature = "lossless-u64")]
89 Uint(u64),
90 Float(f64),
91 Str(Cow<'a, str>),
92}
93
94pub struct StreamingDeserializer<'a> {
114 parser: Parser<'a>,
115 input: &'a str,
116 config: ParseConfig,
117 tag_registry: Option<Arc<crate::TagRegistry>>,
118 depth: usize,
119 current: Option<Lookahead<'a>>,
123 raw_str_mode: bool,
124 anchor_events: FxHashMap<String, SmallVec<[BufferedEvent; SMALL_VEC_SIZE]>>,
125 anchor_def_spans: FxHashMap<String, usize>,
126 replay_stack: Vec<SmallVec<[BufferedEvent; SMALL_VEC_SIZE]>>,
127 recording: Option<(String, usize, SmallVec<[BufferedEvent; SMALL_VEC_SIZE]>)>,
128 anchor_costs: FxHashMap<String, AliasCost>,
131 meter: Meter,
133 started: bool,
137}
138
139impl fmt::Debug for StreamingDeserializer<'_> {
140 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
141 f.debug_struct("StreamingDeserializer")
142 .field("input_len", &self.input.len())
143 .field("config", &self.config)
144 .field("depth", &self.depth)
145 .field("raw_str_mode", &self.raw_str_mode)
146 .field("anchor_events_len", &self.anchor_events.len())
147 .field("replay_stack_len", &self.replay_stack.len())
148 .field("is_recording", &self.recording.is_some())
149 .finish()
150 }
151}
152
153#[derive(Debug)]
177enum Lookahead<'a> {
178 Raw(Event<'a>),
180 Processed(Event<'a>),
182}
183
184impl<'a> Lookahead<'a> {
185 fn event(&self) -> &Event<'a> {
186 match self {
187 Self::Raw(ev) | Self::Processed(ev) => ev,
188 }
189 }
190
191 fn event_mut(&mut self) -> &mut Event<'a> {
192 match self {
193 Self::Raw(ev) | Self::Processed(ev) => ev,
194 }
195 }
196
197 fn into_inner(self) -> Event<'a> {
210 match self {
211 Self::Raw(ev) | Self::Processed(ev) => ev,
212 }
213 }
214}
215
216impl<'a> StreamingDeserializer<'a> {
217 #[must_use]
220 pub fn new(input: &'a str) -> Self {
221 Self::with_config(input, ParseConfig::default())
222 }
223
224 pub fn with_config<C>(input: &'a str, config: C) -> Self
231 where
232 C: Into<ParseConfig>,
233 {
234 let config: ParseConfig = config.into();
235 let meter = Meter::new(&config);
236 StreamingDeserializer {
237 parser: Parser::with_max_events(input, config.max_events),
238 input,
239 config,
240 tag_registry: None,
241 depth: 0,
242 current: None,
243 raw_str_mode: false,
244 anchor_events: FxHashMap::default(),
245 anchor_def_spans: FxHashMap::default(),
246 replay_stack: Vec::new(),
247 recording: None,
248 anchor_costs: FxHashMap::default(),
249 meter,
250 started: false,
251 }
252 }
253
254 #[must_use]
276 pub fn with_tag_registry(mut self, registry: Arc<crate::TagRegistry>) -> Self {
277 self.tag_registry = Some(registry);
278 self
279 }
280
281 pub fn end(&mut self) -> Result<()> {
307 loop {
310 match self.next_event()? {
311 Event::StreamEnd => return Ok(()),
312 Event::DocumentEnd | Event::StreamStart => {}
313 Event::DocumentStart => return Err(Error::MoreThanOneDocument),
314 _ => return Ok(()),
315 }
316 }
317 }
318
319 fn pull_parser_event(&mut self) -> Result<Event<'a>> {
326 if !self.started {
327 self.started = true;
328 if self.input.len() > self.config.max_document_length {
329 return Err(document_too_long(self.config.max_document_length));
330 }
331 }
332 let ev = self
333 .parser
334 .next_event()
335 .map_err(|e| e.into_error(self.input, self.config.max_events))?;
336 self.charge_event(&ev)?;
337 Ok(ev)
338 }
339
340 fn charge_event(&mut self, ev: &Event<'_>) -> Result<()> {
343 self.meter.charge_event(ev, &self.config)
344 }
345
346 fn peek_parser_event(&mut self) -> Result<&Event<'a>> {
349 if self.current.is_none() {
350 let event = self.pull_parser_event()?;
351 self.current = Some(Lookahead::Raw(event));
352 }
353 Ok(self.current.as_ref().unwrap().event())
354 }
355
356 fn next_parser_event(&mut self) -> Result<Event<'a>> {
357 match self.current.take() {
358 Some(Lookahead::Processed(ev)) => Ok(ev),
361 Some(Lookahead::Raw(mut ev)) => {
362 self.anchor_and_record(&mut ev);
363 Ok(ev)
364 }
365 None => {
366 let mut ev = self.pull_parser_event()?;
367 self.anchor_and_record(&mut ev);
368 Ok(ev)
369 }
370 }
371 }
372
373 fn peek_event(&mut self) -> Result<&Event<'a>> {
374 if self.current.is_none() {
379 let mut ev_opt = None;
383 while let Some(buf) = self.replay_stack.last_mut() {
384 if let Some(be) = buf.pop() {
385 ev_opt = Some(self.buffered_to_event(be));
386 break;
387 }
388 let _ = self.replay_stack.pop();
389 }
390 let raw = if let Some(ev) = ev_opt {
396 ev
397 } else {
398 self.pull_parser_event()?
399 };
400 let ev = self.process_event(raw)?;
401 self.current = Some(Lookahead::Processed(ev));
402 }
403 Ok(self.current.as_ref().unwrap().event())
404 }
405
406 fn anchor_and_record(&mut self, ev: &mut Event<'a>) {
417 self.handle_anchor(ev);
418 self.maybe_record(ev);
419 }
420
421 fn process_event(&mut self, mut ev: Event<'a>) -> Result<Event<'a>> {
425 if let Event::Alias {
426 ref anchor,
427 ref span,
428 } = ev
429 {
430 let start = span.start;
431 ev = self.resolve_alias(anchor, start)?;
432 }
433 self.anchor_and_record(&mut ev);
434 Ok(ev)
435 }
436
437 fn next_event(&mut self) -> Result<Event<'a>> {
438 if let Some(slot) = self.current.take() {
441 return Ok(slot.into_inner());
442 }
443
444 let mut ev_opt = None;
445 while let Some(buf) = self.replay_stack.last_mut() {
446 if let Some(be) = buf.pop() {
447 ev_opt = Some(self.buffered_to_event(be));
448 break;
449 }
450 let _ = self.replay_stack.pop();
451 }
452 if let Some(ev) = ev_opt {
453 return self.process_event(ev);
456 }
457
458 let ev = self.pull_parser_event()?;
459 self.process_event(ev)
460 }
461
462 fn buffered_to_event(&self, be: BufferedEvent) -> Event<'a> {
463 let dummy_span = crate::parser::scanner_span_default();
464 match be {
465 BufferedEvent::Scalar { value, style } => Event::Scalar {
466 value: Cow::Owned(value),
467 style,
468 anchor: None,
469 tag: None,
470 span: dummy_span,
471 },
472 BufferedEvent::SeqStart => Event::SequenceStart {
473 anchor: None,
474 tag: None,
475 span: dummy_span,
476 },
477 BufferedEvent::SeqEnd => Event::SequenceEnd { span: dummy_span },
478 BufferedEvent::MapStart => Event::MappingStart {
479 anchor: None,
480 tag: None,
481 span: dummy_span,
482 },
483 BufferedEvent::MapEnd => Event::MappingEnd { span: dummy_span },
484 BufferedEvent::Alias { anchor } => Event::Alias {
485 anchor,
486 span: dummy_span,
487 },
488 }
489 }
490
491 fn handle_anchor(&mut self, ev: &mut Event<'_>) {
492 if self.recording.is_some() {
493 return;
494 }
495 let def_start = match ev {
496 Event::Scalar { span, .. }
497 | Event::SequenceStart { span, .. }
498 | Event::MappingStart { span, .. } => Some(span.start),
499 _ => None,
500 };
501 let anchor_name = match ev {
502 Event::Scalar { anchor, .. }
503 | Event::SequenceStart { anchor, .. }
504 | Event::MappingStart { anchor, .. } => anchor.take(),
505 _ => None,
506 };
507 if let Some(name) = anchor_name {
508 if let Some(start) = def_start {
509 let _ = self.anchor_def_spans.insert(name.clone(), start);
510 }
511 self.recording = Some((name, 0, SmallVec::new()));
512 }
513 }
514
515 fn maybe_record(&mut self, ev: &Event<'_>) {
516 if let Some((_, ref mut depth, ref mut buf)) = self.recording {
517 match ev {
518 Event::Scalar { value, style, .. } => {
519 buf.push(BufferedEvent::Scalar {
520 value: value.to_string(),
521 style: *style,
522 });
523 if *depth == 0 {
524 self.finish_recording();
525 }
526 }
527 Event::SequenceStart { .. } => {
528 buf.push(BufferedEvent::SeqStart);
529 *depth += 1;
530 }
531 Event::SequenceEnd { .. } => {
532 buf.push(BufferedEvent::SeqEnd);
533 *depth -= 1;
534 if *depth == 0 {
535 self.finish_recording();
536 }
537 }
538 Event::MappingStart { .. } => {
539 buf.push(BufferedEvent::MapStart);
540 *depth += 1;
541 }
542 Event::MappingEnd { .. } => {
543 buf.push(BufferedEvent::MapEnd);
544 *depth -= 1;
545 if *depth == 0 {
546 self.finish_recording();
547 }
548 }
549 Event::Alias { anchor, .. } => {
550 buf.push(BufferedEvent::Alias {
551 anchor: anchor.clone(),
552 });
553 if *depth == 0 {
554 self.finish_recording();
555 }
556 }
557 _ => {}
558 }
559 }
560 }
561
562 fn finish_recording(&mut self) {
564 if let Some((name, _, events)) = self.recording.take() {
565 let _ = self.anchor_costs.insert(name.clone(), buffer_cost(&events));
566 let _ = self.anchor_events.insert(name, events);
567 }
568 }
569
570 fn charge_alias(&mut self, name: &str) -> Result<()> {
575 self.meter.charge_alias(&self.config)?;
576 match self.anchor_costs.get(name) {
577 Some(cost) => self.meter.charge_expansion(cost, self.depth, &self.config),
578 None => Ok(()),
579 }
580 }
581
582 fn resolve_alias(&mut self, name: &str, alias_start: usize) -> Result<Event<'a>> {
583 self.charge_alias(name)?;
584 let buf = self
585 .anchor_events
586 .get(name)
587 .cloned()
588 .ok_or_else(|| self.build_unknown_anchor(name, alias_start))?;
589 if buf.is_empty() {
590 return Err(self.build_unknown_anchor(name, alias_start));
591 }
592 let mut reversed = buf;
593 reversed.reverse();
594 let first = reversed.pop().unwrap();
595 if !reversed.is_empty() {
596 self.replay_stack.push(reversed);
597 }
598 Ok(self.buffered_to_event(first))
599 }
600
601 fn inject_multi_merge_mapping_contents(&mut self, sources: &[(String, usize)]) -> Result<()> {
602 self.meter.charge_merge_key(&self.config)?;
603 let local_buf = self.buffer_rest_of_mapping()?;
604 let mut seen_keys = extract_local_keys(&local_buf);
605 let mut filtered_sources: SmallVec<[SmallVec<[BufferedEvent; SMALL_VEC_SIZE]>; 2]> =
606 SmallVec::new();
607 for (name, start) in sources {
608 let target_buf = self
609 .anchor_events
610 .get(name)
611 .cloned()
612 .ok_or_else(|| self.build_unknown_anchor(name, *start))?;
613 let body = extract_mapping_body(&target_buf).ok_or_else(|| self.fallback())?;
614 let filtered = filter_merge_entries(body, &seen_keys).ok_or_else(|| self.fallback())?;
615 collect_keys(body, &mut seen_keys).ok_or_else(|| self.fallback())?;
616 filtered_sources.push(filtered);
617 }
618 if !local_buf.is_empty() {
619 let mut rev = local_buf;
620 rev.reverse();
621 self.replay_stack.push(rev);
622 }
623 for mut filtered in filtered_sources.into_iter().rev() {
624 if !filtered.is_empty() {
625 filtered.reverse();
626 self.replay_stack.push(filtered);
627 }
628 }
629 Ok(())
630 }
631
632 fn buffer_rest_of_mapping(&mut self) -> Result<SmallVec<[BufferedEvent; SMALL_VEC_SIZE]>> {
633 let mut buf = SmallVec::new();
634 let mut depth: usize = 0;
635 loop {
636 let ev = self.next_parser_event()?;
637 match ev {
638 Event::MappingEnd { .. } => {
639 buf.push(BufferedEvent::MapEnd);
640 if depth == 0 {
641 return Ok(buf);
642 }
643 depth -= 1;
644 }
645 Event::MappingStart { .. } => {
646 buf.push(BufferedEvent::MapStart);
647 depth += 1;
648 }
649 Event::SequenceStart { .. } => {
650 buf.push(BufferedEvent::SeqStart);
651 depth += 1;
652 }
653 Event::SequenceEnd { .. } => {
654 buf.push(BufferedEvent::SeqEnd);
655 depth = depth.saturating_sub(1);
656 }
657 Event::Scalar { value, style, .. } => buf.push(BufferedEvent::Scalar {
658 value: value.into_owned(),
659 style,
660 }),
661 Event::Alias { anchor, .. } => buf.push(BufferedEvent::Alias { anchor }),
662 _ => {}
663 }
664 }
665 }
666
667 fn build_unknown_anchor(&self, name: &str, alias_start: usize) -> Error {
668 let loc = crate::error::Location::from_index(self.input, alias_start);
669 let suggestion = closest_name(name, self.anchor_def_spans.keys().map(|s| s.as_str()))
670 .and_then(|s| {
671 self.anchor_def_spans.get(s).map(|&idx| {
672 (
673 s.to_string(),
674 crate::error::Location::from_index(self.input, idx),
675 )
676 })
677 });
678 Error::UnknownAnchorAt {
679 name: name.to_owned(),
680 location: loc,
681 suggestion,
682 }
683 }
684
685 fn fallback(&self) -> Error {
686 Error::Custom(FALLBACK_SENTINEL.to_owned())
687 }
688
689 fn skip_event(&mut self) -> Result<()> {
690 let _ = self.next_event()?;
691 Ok(())
692 }
693
694 fn skip_to_content(&mut self) -> Result<()> {
695 loop {
696 match self.peek_event()? {
697 Event::StreamStart | Event::DocumentStart => {
698 self.skip_event()?;
699 }
700 _ => return Ok(()),
701 }
702 }
703 }
704
705 fn skip_value(&mut self) -> Result<()> {
714 let base = self.depth;
715 let result = self.skip_value_levels();
716 self.depth = base;
718 result
719 }
720
721 fn skip_value_levels(&mut self) -> Result<()> {
722 let mut levels: Vec<SkipLevel> = Vec::new();
723 loop {
724 let ev = self.next_event()?;
725 let opens = match &ev {
726 Event::Scalar { value, style, .. } => {
727 self.skip_note_node(levels.last_mut(), Some((value, *style)))?;
728 None
729 }
730 Event::SequenceStart { .. } => Some(false),
731 Event::MappingStart { .. } => Some(true),
732 Event::SequenceEnd { .. } | Event::MappingEnd { .. } => {
733 let _ = levels.pop();
734 self.depth = self.depth.saturating_sub(1);
735 None
736 }
737 _ => continue,
738 };
739 if let Some(is_map) = opens {
740 self.skip_note_node(levels.last_mut(), None)?;
741 self.depth += 1;
742 if budget::depth_exceeded(self.depth, self.config.max_depth) {
743 return Err(Error::RecursionLimitExceeded { depth: self.depth });
744 }
745 levels.push(SkipLevel::new(is_map));
746 }
747 if levels.is_empty() {
748 return Ok(());
749 }
750 }
751 }
752
753 fn skip_note_node(
757 &mut self,
758 level: Option<&mut SkipLevel>,
759 scalar: Option<(&Cow<'_, str>, ScalarStyle)>,
760 ) -> Result<()> {
761 let Some(level) = level else {
762 return Ok(());
763 };
764 if !level.is_map {
765 level.entries += 1;
766 if level.entries > self.config.max_sequence_length {
767 return Err(Error::Budget(BudgetBreach::MaxSequenceLength {
768 limit: self.config.max_sequence_length,
769 observed: level.entries,
770 }));
771 }
772 return Ok(());
773 }
774 level.expecting_key = !level.expecting_key;
775 if level.expecting_key {
776 return Ok(());
778 }
779 level.entries += 1;
780 if level.entries > self.config.max_mapping_keys {
781 return Err(Error::Budget(BudgetBreach::MaxMappingKeys {
782 limit: self.config.max_mapping_keys,
783 observed: level.entries,
784 }));
785 }
786 let Some((key, style)) = scalar else {
787 return Ok(());
788 };
789 if style == ScalarStyle::Plain && key == "<<" {
790 self.meter.charge_merge_key(&self.config)?;
791 }
792 if self.config.duplicate_key_policy == crate::parser::InternalDuplicateKeyPolicy::Error
793 && !level.keys.insert(key.to_string())
794 {
795 return Err(Error::DuplicateKey(key.to_string()));
796 }
797 Ok(())
798 }
799
800 fn take_tag_from_current(&mut self) -> Option<(String, String)> {
806 let _ = self.peek_event().ok()?;
807 match self.current.as_mut().map(Lookahead::event_mut) {
808 Some(
809 Event::Scalar { tag, .. }
810 | Event::SequenceStart { tag, .. }
811 | Event::MappingStart { tag, .. },
812 ) => tag.take(),
813 _ => None,
814 }
815 }
816
817 fn tag_in_registry(&self, tag: &(String, String)) -> bool {
828 self.tag_registry
829 .as_ref()
830 .is_some_and(|r| tag_is_registry_stripped(&tag.0, &tag.1, r))
831 }
832
833 fn restore_tag_to_current(&mut self, t: (String, String)) {
837 if let Some(
838 Event::Scalar { tag, .. }
839 | Event::SequenceStart { tag, .. }
840 | Event::MappingStart { tag, .. },
841 ) = self.current.as_mut().map(Lookahead::event_mut)
842 {
843 *tag = Some(t);
844 }
845 }
846
847 fn resolve_scalar<'s>(&self, value: &'s str, style: ScalarStyle) -> Scalar<'s> {
848 if style == ScalarStyle::Plain {
849 resolve_plain_ext(
850 value,
851 self.config.strict_booleans,
852 self.config.legacy_booleans,
853 self.config.no_schema,
854 self.config.legacy_octal_numbers,
855 self.config.legacy_sexagesimal,
856 self.config.lossless_u64_integers(),
857 )
858 } else {
859 Scalar::Str(Cow::Borrowed(value))
860 }
861 }
862}
863
864impl<'de> serde_core::Deserializer<'de> for &mut StreamingDeserializer<'de> {
865 type Error = Error;
866
867 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
868 where
869 V: serde_core::de::Visitor<'de>,
870 {
871 self.skip_to_content()?;
872 if let Some(t) = self.take_tag_from_current() {
877 if !self.tag_in_registry(&t) {
881 self.restore_tag_to_current(t);
882 return Err(self.fallback());
883 }
884 }
885 match self.next_event()? {
886 Event::Scalar { value, style, .. } => match value {
887 Cow::Borrowed(s) => match self.resolve_scalar(s, style) {
888 Scalar::Null => visitor.visit_none(),
889 Scalar::Bool(b) => visitor.visit_bool(b),
890 Scalar::Int(n) => visitor.visit_i64(n),
891 #[cfg(feature = "lossless-u64")]
892 Scalar::Uint(n) => visitor.visit_u64(n),
893 Scalar::Float(f) => visitor.visit_f64(f),
894 Scalar::Str(Cow::Borrowed(b)) => visitor.visit_borrowed_str(b),
895 Scalar::Str(Cow::Owned(o)) => visitor.visit_string(o),
896 },
897 Cow::Owned(s) => match self.resolve_scalar(&s, style) {
898 Scalar::Null => visitor.visit_none(),
899 Scalar::Bool(b) => visitor.visit_bool(b),
900 Scalar::Int(n) => visitor.visit_i64(n),
901 #[cfg(feature = "lossless-u64")]
902 Scalar::Uint(n) => visitor.visit_u64(n),
903 Scalar::Float(f) => visitor.visit_f64(f),
904 Scalar::Str(_) => visitor.visit_string(s),
905 },
906 },
907 Event::SequenceStart { .. } => {
908 self.depth += 1;
909 if budget::depth_exceeded(self.depth, self.config.max_depth) {
910 return Err(Error::RecursionLimitExceeded { depth: self.depth });
911 }
912 let res = visitor.visit_seq(StreamingSeqAccess {
913 de: self,
914 finished: false,
915 count: 0,
916 });
917 self.depth = self.depth.saturating_sub(1);
920 res
921 }
922 Event::MappingStart { .. } => {
923 self.depth += 1;
924 if budget::depth_exceeded(self.depth, self.config.max_depth) {
925 return Err(Error::RecursionLimitExceeded { depth: self.depth });
926 }
927 let res = visitor.visit_map(StreamingMapAccess {
928 de: self,
929 finished: false,
930 has_emitted_key: false,
931 key_count: 0,
932 seen_keys: FxHashSet::default(),
933 seen_typed: FxHashMap::default(),
934 });
935 self.depth = self.depth.saturating_sub(1);
939 res
940 }
941 _ => Err(self.fallback()),
942 }
943 }
944
945 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
946 where
947 V: serde_core::de::Visitor<'de>,
948 {
949 self.skip_to_content()?;
950 if let Event::Scalar { value, style, .. } = self.next_event()?
951 && let Scalar::Bool(b) = self.resolve_scalar(&value, style)
952 {
953 return visitor.visit_bool(b);
954 }
955 Err(Error::TypeMismatch {
956 expected: "bool",
957 found: "other".into(),
958 })
959 }
960
961 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
962 where
963 V: serde_core::de::Visitor<'de>,
964 {
965 self.skip_to_content()?;
966 if let Event::Scalar { value, style, .. } = self.next_event()? {
967 match self.resolve_scalar(&value, style) {
968 Scalar::Int(n) => return visitor.visit_i64(n),
969 Scalar::Float(f)
972 if f.is_finite()
973 && f64_fract(f) == 0.0
974 && f >= i64::MIN as f64
975 && f <= i64::MAX as f64 =>
976 {
977 return visitor.visit_i64(f as i64);
978 }
979 _ => {}
980 }
981 }
982 Err(Error::TypeMismatch {
983 expected: "integer",
984 found: "other".into(),
985 })
986 }
987
988 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
989 where
990 V: serde_core::de::Visitor<'de>,
991 {
992 self.skip_to_content()?;
993 if let Event::Scalar { value, style, .. } = self.next_event()? {
994 match self.resolve_scalar(&value, style) {
995 Scalar::Int(n) if n >= 0 => return visitor.visit_u64(n as u64),
996 #[cfg(feature = "lossless-u64")]
997 Scalar::Uint(n) => return visitor.visit_u64(n),
998 Scalar::Float(f)
999 if f.is_finite() && f64_fract(f) == 0.0 && f >= 0.0 && f <= u64::MAX as f64 =>
1000 {
1001 return visitor.visit_u64(f as u64);
1002 }
1003 _ => {}
1004 }
1005 }
1006 Err(Error::TypeMismatch {
1007 expected: "unsigned integer",
1008 found: "other".into(),
1009 })
1010 }
1011
1012 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
1013 where
1014 V: serde_core::de::Visitor<'de>,
1015 {
1016 self.skip_to_content()?;
1017 if let Event::Scalar { value, style, .. } = self.next_event()? {
1018 match self.resolve_scalar(&value, style) {
1019 Scalar::Float(f) => return visitor.visit_f64(f),
1020 Scalar::Int(n) => return visitor.visit_f64(n as f64),
1021 #[cfg(feature = "lossless-u64")]
1022 Scalar::Uint(n) => return visitor.visit_f64(n as f64),
1023 _ => {}
1024 }
1025 }
1026 Err(Error::TypeMismatch {
1027 expected: "float",
1028 found: "other".into(),
1029 })
1030 }
1031
1032 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
1033 where
1034 V: serde_core::de::Visitor<'de>,
1035 {
1036 self.skip_to_content()?;
1037 if let Some(t) = self.take_tag_from_current()
1040 && !self.tag_in_registry(&t)
1041 {
1042 self.restore_tag_to_current(t);
1043 return Err(self.fallback());
1044 }
1045 match self.peek_event()? {
1046 Event::Scalar { .. } => {
1047 if let Event::Scalar { value, style, .. } = self.next_event()? {
1048 if self.raw_str_mode {
1054 return match value {
1055 Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
1056 Cow::Owned(s) => visitor.visit_string(s),
1057 };
1058 }
1059 if style != ScalarStyle::Plain {
1060 return match value {
1061 Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
1062 Cow::Owned(s) => visitor.visit_string(s),
1063 };
1064 }
1065 if self.config.plain_scalar_strings {
1073 return match value {
1074 Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
1075 Cow::Owned(s) => visitor.visit_string(s),
1076 };
1077 }
1078 match value {
1079 Cow::Borrowed(s) => match self.resolve_scalar(s, style) {
1080 Scalar::Str(Cow::Borrowed(b)) => visitor.visit_borrowed_str(b),
1081 Scalar::Str(Cow::Owned(o)) => visitor.visit_string(o),
1082 _ => Err(Error::TypeMismatch {
1083 expected: "string",
1084 found: "non-string scalar".into(),
1085 }),
1086 },
1087 Cow::Owned(s) => match self.resolve_scalar(&s, style) {
1088 Scalar::Str(_) => visitor.visit_string(s),
1089 _ => Err(Error::TypeMismatch {
1090 expected: "string",
1091 found: "non-string scalar".into(),
1092 }),
1093 },
1094 }
1095 } else {
1096 Err(Error::TypeMismatch {
1097 expected: "string",
1098 found: "other".into(),
1099 })
1100 }
1101 }
1102 _ => Err(self.fallback()),
1107 }
1108 }
1109
1110 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
1111 where
1112 V: serde_core::de::Visitor<'de>,
1113 {
1114 self.deserialize_str(visitor)
1115 }
1116
1117 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
1118 where
1119 V: serde_core::de::Visitor<'de>,
1120 {
1121 if self.config.plain_scalar_strings {
1130 return self.deserialize_str(visitor);
1131 }
1132 self.deserialize_any(visitor)
1133 }
1134
1135 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
1136 where
1137 V: serde_core::de::Visitor<'de>,
1138 {
1139 self.skip_to_content()?;
1140 if let Event::Scalar { value, style, .. } = self.peek_event()?
1141 && *style == ScalarStyle::Plain
1142 {
1143 match &**value {
1144 "" | "~" | "null" | "Null" | "NULL" => {
1145 self.skip_event()?;
1146 return visitor.visit_none();
1147 }
1148 _ => {}
1149 }
1150 }
1151 visitor.visit_some(self)
1152 }
1153
1154 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
1155 where
1156 V: serde_core::de::Visitor<'de>,
1157 {
1158 self.skip_to_content()?;
1159 if let Event::Scalar { value, style, .. } = self.next_event()?
1160 && matches!(self.resolve_scalar(&value, style), Scalar::Null)
1161 {
1162 return visitor.visit_unit();
1163 }
1164 Err(Error::TypeMismatch {
1165 expected: "null",
1166 found: "other".into(),
1167 })
1168 }
1169
1170 fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
1171 where
1172 V: serde_core::de::Visitor<'de>,
1173 {
1174 if name == crate::spanned::SPANNED_TYPE_NAME {
1175 return Err(self.fallback());
1176 }
1177 self.skip_to_content()?;
1178 if let Some(t) = self.take_tag_from_current() {
1179 if let ("!!", "int" | "float" | "str" | "bool" | "null" | "seq" | "map") =
1180 (t.0.as_str(), t.1.as_str())
1181 {
1182 } else {
1183 if self.tag_in_registry(&t) {
1187 return visitor.visit_newtype_struct(self);
1188 }
1189 return visitor.visit_map(StreamingTagMapAccess {
1190 de: self,
1191 tag: t,
1192 done: false,
1193 });
1194 }
1195 }
1196 visitor.visit_newtype_struct(self)
1197 }
1198
1199 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
1200 where
1201 V: serde_core::de::Visitor<'de>,
1202 {
1203 self.skip_to_content()?;
1204 if let Some(t) = self.take_tag_from_current()
1208 && !self.tag_in_registry(&t)
1209 {
1210 self.restore_tag_to_current(t);
1211 return Err(self.fallback());
1212 }
1213 if let Event::SequenceStart { .. } = self.next_event()? {
1214 self.depth += 1;
1215 if budget::depth_exceeded(self.depth, self.config.max_depth) {
1216 return Err(Error::RecursionLimitExceeded { depth: self.depth });
1217 }
1218 let res = visitor.visit_seq(StreamingSeqAccess {
1219 de: self,
1220 finished: false,
1221 count: 0,
1222 });
1223 self.depth = self.depth.saturating_sub(1);
1225 res
1226 } else {
1227 Err(Error::TypeMismatch {
1228 expected: "sequence",
1229 found: "other".into(),
1230 })
1231 }
1232 }
1233
1234 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
1235 where
1236 V: serde_core::de::Visitor<'de>,
1237 {
1238 self.skip_to_content()?;
1239 if matches!(self.peek_event()?, Event::StreamEnd) {
1248 return visitor.visit_map(crate::de::EmptyMapAccess);
1249 }
1250 if let Some(t) = self.take_tag_from_current()
1254 && !self.tag_in_registry(&t)
1255 {
1256 self.restore_tag_to_current(t);
1257 return Err(self.fallback());
1258 }
1259 match self.next_event()? {
1260 Event::MappingStart { .. } => {
1261 self.depth += 1;
1262 if budget::depth_exceeded(self.depth, self.config.max_depth) {
1263 return Err(Error::RecursionLimitExceeded { depth: self.depth });
1264 }
1265 let res = visitor.visit_map(StreamingMapAccess {
1266 de: self,
1267 finished: false,
1268 has_emitted_key: false,
1269 key_count: 0,
1270 seen_keys: FxHashSet::default(),
1271 seen_typed: FxHashMap::default(),
1272 });
1273 self.depth = self.depth.saturating_sub(1);
1275 res
1276 }
1277 Event::Scalar { value, style, .. }
1283 if matches!(self.resolve_scalar(&value, style), Scalar::Null) =>
1284 {
1285 visitor.visit_map(crate::de::EmptyMapAccess)
1286 }
1287 _ => Err(Error::TypeMismatch {
1288 expected: "mapping",
1289 found: "other".into(),
1290 }),
1291 }
1292 }
1293
1294 fn deserialize_enum<V>(
1295 self,
1296 _name: &'static str,
1297 _variants: &'static [&'static str],
1298 visitor: V,
1299 ) -> Result<V::Value>
1300 where
1301 V: serde_core::de::Visitor<'de>,
1302 {
1303 self.skip_to_content()?;
1304 if let Some(t) = self.take_tag_from_current() {
1305 match (t.0.as_str(), t.1.as_str()) {
1306 ("!!", "int" | "float" | "str" | "bool" | "null" | "seq" | "map") => {}
1307 _ => {
1308 return visitor.visit_enum(StreamingTagEnumAccess { de: self, tag: t });
1309 }
1310 }
1311 }
1312 match self.next_event()? {
1313 Event::Scalar { value, .. } => visitor.visit_enum(
1314 serde_core::de::IntoDeserializer::into_deserializer(value.into_owned()),
1315 ),
1316 Event::MappingStart { .. } => {
1317 if let Event::Scalar { value, .. } = self.next_event()? {
1318 visitor.visit_enum(StreamingEnumAccess {
1319 de: self,
1320 variant: value.into_owned(),
1321 })
1322 } else {
1323 Err(Error::TypeMismatch {
1324 expected: "variant name",
1325 found: "non-scalar".into(),
1326 })
1327 }
1328 }
1329 _ => Err(Error::TypeMismatch {
1330 expected: "enum",
1331 found: "other".into(),
1332 }),
1333 }
1334 }
1335
1336 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
1337 where
1338 V: serde_core::de::Visitor<'de>,
1339 {
1340 self.skip_to_content()?;
1341 if let Event::Scalar { value, .. } = self.next_event()? {
1342 return match value {
1343 Cow::Borrowed(s) => visitor.visit_borrowed_str(s),
1344 Cow::Owned(s) => visitor.visit_string(s),
1345 };
1346 }
1347 Err(Error::TypeMismatch {
1348 expected: "identifier",
1349 found: "non-scalar".into(),
1350 })
1351 }
1352
1353 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
1354 where
1355 V: serde_core::de::Visitor<'de>,
1356 {
1357 self.skip_value()?;
1358 visitor.visit_unit()
1359 }
1360
1361 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
1362 where
1363 V: serde_core::de::Visitor<'de>,
1364 {
1365 self.skip_to_content()?;
1366 self.deserialize_unit(visitor)
1368 }
1369
1370 fn deserialize_struct<V>(
1371 self,
1372 name: &'static str,
1373 _fields: &'static [&'static str],
1374 visitor: V,
1375 ) -> Result<V::Value>
1376 where
1377 V: serde_core::de::Visitor<'de>,
1378 {
1379 if name == crate::spanned::SPANNED_TYPE_NAME {
1383 return Err(self.fallback());
1384 }
1385 self.deserialize_map(visitor)
1386 }
1387
1388 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
1389 where
1390 V: serde_core::de::Visitor<'de>,
1391 {
1392 self.skip_to_content()?;
1393 let is_binary = match self.current.as_ref().map(Lookahead::event) {
1398 Some(Event::Scalar { tag: Some(t), .. }) => {
1399 let full = format!("{}{}", t.0, t.1);
1400 crate::de::is_binary_tag(&full)
1401 }
1402 _ => false,
1403 };
1404 if is_binary {
1405 let _ = self.take_tag_from_current();
1406 if let Event::Scalar { value, .. } = self.next_event()? {
1407 return match crate::base64::decode(&value) {
1408 Ok(bytes) => visitor.visit_byte_buf(bytes),
1409 Err(why) => Err(Error::Deserialize(format!("!!binary: {why}"))),
1410 };
1411 }
1412 return Err(Error::TypeMismatch {
1413 expected: "string-shaped !!binary content",
1414 found: "non-scalar".into(),
1415 });
1416 }
1417 if let Event::Scalar { value, style, .. } = self.next_event()? {
1418 return match self.resolve_scalar(&value, style) {
1423 Scalar::Str(s) => visitor.visit_bytes(s.as_bytes()),
1424 Scalar::Null => Err(Error::TypeMismatch {
1425 expected: "bytes",
1426 found: "null".into(),
1427 }),
1428 Scalar::Bool(_) => Err(Error::TypeMismatch {
1429 expected: "bytes",
1430 found: "bool".into(),
1431 }),
1432 Scalar::Int(_) => Err(Error::TypeMismatch {
1433 expected: "bytes",
1434 found: "integer".into(),
1435 }),
1436 #[cfg(feature = "lossless-u64")]
1437 Scalar::Uint(_) => Err(Error::TypeMismatch {
1438 expected: "bytes",
1439 found: "integer".into(),
1440 }),
1441 Scalar::Float(_) => Err(Error::TypeMismatch {
1442 expected: "bytes",
1443 found: "float".into(),
1444 }),
1445 };
1446 }
1447 Err(Error::TypeMismatch {
1448 expected: "bytes",
1449 found: "non-scalar".into(),
1450 })
1451 }
1452
1453 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
1454 where
1455 V: serde_core::de::Visitor<'de>,
1456 {
1457 self.deserialize_bytes(visitor)
1458 }
1459
1460 serde_core::forward_to_deserialize_any! {
1461 i8 i16 i32 u8 u16 u32 f32
1462 tuple tuple_struct
1463 }
1464}
1465
1466struct StreamingSeqAccess<'a, 'de> {
1467 de: &'a mut StreamingDeserializer<'de>,
1468 finished: bool,
1469 count: usize,
1470}
1471
1472impl<'de> serde_core::de::SeqAccess<'de> for StreamingSeqAccess<'_, 'de> {
1473 type Error = Error;
1474 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
1475 where
1476 T: serde_core::de::DeserializeSeed<'de>,
1477 {
1478 if self.finished {
1484 return Ok(None);
1485 }
1486 if matches!(self.de.peek_event()?, Event::SequenceEnd { .. }) {
1487 self.de.skip_event()?;
1488 self.finished = true;
1489 return Ok(None);
1490 }
1491 self.count += 1;
1492 if self.count > self.de.config.max_sequence_length {
1493 return Err(Error::Budget(BudgetBreach::MaxSequenceLength {
1494 limit: self.de.config.max_sequence_length,
1495 observed: self.count,
1496 }));
1497 }
1498 seed.deserialize(&mut *self.de).map(Some)
1499 }
1500}
1501
1502impl Drop for StreamingSeqAccess<'_, '_> {
1503 fn drop(&mut self) {
1504 if !self.finished {
1505 loop {
1506 match self.de.peek_event() {
1507 Ok(Event::SequenceEnd { .. }) => {
1508 let _ = self.de.skip_event();
1509 break;
1510 }
1511 Ok(_) => {
1512 if self.de.skip_value().is_err() {
1513 break;
1514 }
1515 }
1516 Err(_) => break,
1517 }
1518 }
1519 }
1520 }
1521}
1522
1523fn scalar_to_value(s: Scalar<'_>) -> Value {
1527 match s {
1528 Scalar::Null => Value::Null,
1529 Scalar::Bool(b) => Value::Bool(b),
1530 Scalar::Int(n) => Value::Number(crate::value::Number::Integer(n)),
1531 #[cfg(feature = "lossless-u64")]
1532 Scalar::Uint(n) => Value::Number(crate::value::Number::Unsigned(n)),
1533 Scalar::Float(f) => Value::Number(crate::value::Number::Float(f)),
1534 Scalar::Str(s) => Value::String(s.into_owned()),
1535 }
1536}
1537
1538struct StreamingMapAccess<'a, 'de> {
1539 de: &'a mut StreamingDeserializer<'de>,
1540 finished: bool,
1541 has_emitted_key: bool,
1542 key_count: usize,
1543 seen_keys: FxHashSet<String>,
1547 seen_typed: FxHashMap<String, Value>,
1552}
1553
1554impl StreamingMapAccess<'_, '_> {
1555 fn expand_merge_key(&mut self) -> Result<()> {
1558 self.de.skip_event()?;
1559 match self.de.peek_parser_event()? {
1562 Event::Alias { anchor, span } => {
1563 let name = anchor.clone();
1564 let start = span.start;
1565 self.de.current = None;
1566 self.de
1567 .inject_multi_merge_mapping_contents(&[(name, start)])?;
1568 }
1569 Event::SequenceStart { .. } => {
1570 self.de.skip_event()?;
1571 let mut sources = Vec::new();
1572 loop {
1573 match self.de.peek_parser_event()? {
1574 Event::SequenceEnd { .. } => {
1575 self.de.skip_event()?;
1576 break;
1577 }
1578 Event::Alias { anchor, span } => {
1579 sources.push((anchor.clone(), span.start));
1580 self.de.skip_event()?;
1581 }
1582 _ => return Err(self.de.fallback()),
1583 }
1584 }
1585 self.de.inject_multi_merge_mapping_contents(&sources)?;
1586 }
1587 _ => return Err(self.de.fallback()),
1588 }
1589 Ok(())
1590 }
1591
1592 fn admit_key(&mut self, key_info: Option<(String, ScalarStyle, bool)>) -> Result<bool> {
1595 let Some((raw, style, untagged)) = key_info else {
1596 return Ok(true);
1597 };
1598 let mut identity = None;
1609 if untagged {
1610 let typed = scalar_to_value(self.de.resolve_scalar(&raw, style));
1611 if let Some(canon) = crate::parser::value_to_key_string(typed.clone()) {
1612 match self.seen_typed.get(&canon) {
1613 Some(prev) if *prev != typed => {
1614 return Err(Error::KeyCollision(canon));
1615 }
1616 Some(_) => {}
1617 None => {
1618 let _ = self.seen_typed.insert(canon.clone(), typed);
1619 }
1620 }
1621 identity = Some(canon);
1622 }
1623 }
1624 let policy = self.de.config.duplicate_key_policy;
1625 if policy == crate::parser::InternalDuplicateKeyPolicy::Last {
1626 return Ok(true);
1627 }
1628 let identity = identity.unwrap_or_else(|| raw.clone());
1629 if self.seen_keys.insert(identity) {
1630 return Ok(true);
1631 }
1632 match policy {
1633 crate::parser::InternalDuplicateKeyPolicy::Error => Err(Error::DuplicateKey(raw)),
1634 crate::parser::InternalDuplicateKeyPolicy::First => {
1635 self.de.skip_value()?;
1637 self.de.skip_value()?;
1638 Ok(false)
1639 }
1640 _ => Ok(true),
1641 }
1642 }
1643}
1644
1645impl<'de> serde_core::de::MapAccess<'de> for StreamingMapAccess<'_, 'de> {
1646 type Error = Error;
1647 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
1648 where
1649 K: serde_core::de::DeserializeSeed<'de>,
1650 {
1651 if self.finished {
1661 return Ok(None);
1662 }
1663 loop {
1664 let ev = self.de.peek_event()?;
1668 if matches!(ev, Event::MappingEnd { .. }) {
1669 self.de.skip_event()?;
1670 self.finished = true;
1671 return Ok(None);
1672 }
1673 if matches!(ev, Event::Scalar { value, style: ScalarStyle::Plain, .. } if value == "<<")
1674 {
1675 if self.has_emitted_key {
1676 return Err(self.de.fallback());
1677 }
1678 self.expand_merge_key()?;
1679 continue;
1680 }
1681 let key_info = if let Event::Scalar {
1687 value: key_val,
1688 style,
1689 tag,
1690 ..
1691 } = ev
1692 {
1693 Some((key_val.to_string(), *style, tag.is_none()))
1694 } else {
1695 None
1696 };
1697 if !self.admit_key(key_info)? {
1698 continue;
1699 }
1700 self.key_count += 1;
1701 if self.key_count > self.de.config.max_mapping_keys {
1702 return Err(Error::Budget(BudgetBreach::MaxMappingKeys {
1703 limit: self.de.config.max_mapping_keys,
1704 observed: self.key_count,
1705 }));
1706 }
1707 self.de.raw_str_mode = true;
1708 let res = seed.deserialize(&mut *self.de).map(Some);
1709 self.de.raw_str_mode = false;
1710 if res.is_ok() {
1711 self.has_emitted_key = true;
1712 }
1713 return res;
1714 }
1715 }
1716 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
1717 where
1718 V: serde_core::de::DeserializeSeed<'de>,
1719 {
1720 if self.finished {
1726 return Err(Error::Custom(
1727 "next_value_seed called after MapAccess exhausted".into(),
1728 ));
1729 }
1730 seed.deserialize(&mut *self.de)
1731 }
1732}
1733
1734impl Drop for StreamingMapAccess<'_, '_> {
1735 fn drop(&mut self) {
1736 if !self.finished {
1737 loop {
1738 match self.de.peek_event() {
1739 Ok(Event::MappingEnd { .. }) => {
1740 let _ = self.de.skip_event();
1741 break;
1742 }
1743 Ok(_) => {
1744 if self.de.skip_value().is_err() {
1745 break;
1746 }
1747 if self.de.skip_value().is_err() {
1748 break;
1749 }
1750 }
1751 Err(_) => break,
1752 }
1753 }
1754 }
1755 }
1756}
1757
1758struct StreamingEnumAccess<'a, 'de> {
1759 de: &'a mut StreamingDeserializer<'de>,
1760 variant: String,
1761}
1762impl<'a, 'de> serde_core::de::EnumAccess<'de> for StreamingEnumAccess<'a, 'de> {
1763 type Error = Error;
1764 type Variant = StreamingVariantAccess<'a, 'de>;
1765 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
1766 where
1767 V: serde_core::de::DeserializeSeed<'de>,
1768 {
1769 let de = serde_core::de::value::StringDeserializer::<Error>::new(self.variant);
1770 let variant = seed.deserialize(de)?;
1771 Ok((variant, StreamingVariantAccess { de: self.de }))
1772 }
1773}
1774
1775struct StreamingVariantAccess<'a, 'de> {
1776 de: &'a mut StreamingDeserializer<'de>,
1777}
1778impl<'de> serde_core::de::VariantAccess<'de> for StreamingVariantAccess<'_, 'de> {
1779 type Error = Error;
1780 fn unit_variant(self) -> Result<()> {
1781 let ev = self.de.next_event()?;
1782 if !matches!(ev, Event::MappingEnd { .. }) {
1783 self.de.current = Some(Lookahead::Processed(ev));
1784 self.de.skip_value()?;
1785 if !matches!(self.de.next_event()?, Event::MappingEnd { .. }) {
1786 return Err(Error::Invalid("expected mapping end".into()));
1787 }
1788 }
1789 Ok(())
1790 }
1791 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
1792 where
1793 T: serde_core::de::DeserializeSeed<'de>,
1794 {
1795 let res = seed.deserialize(&mut *self.de)?;
1796 if !matches!(self.de.next_event()?, Event::MappingEnd { .. }) {
1797 return Err(Error::Invalid("expected mapping end".into()));
1798 }
1799 Ok(res)
1800 }
1801 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
1802 where
1803 V: serde_core::de::Visitor<'de>,
1804 {
1805 let res = serde_core::Deserializer::deserialize_seq(&mut *self.de, visitor)?;
1806 if !matches!(self.de.next_event()?, Event::MappingEnd { .. }) {
1807 return Err(Error::Invalid("expected mapping end".into()));
1808 }
1809 Ok(res)
1810 }
1811 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
1812 where
1813 V: serde_core::de::Visitor<'de>,
1814 {
1815 let res = serde_core::Deserializer::deserialize_map(&mut *self.de, visitor)?;
1816 if !matches!(self.de.next_event()?, Event::MappingEnd { .. }) {
1817 return Err(Error::Invalid("expected mapping end".into()));
1818 }
1819 Ok(res)
1820 }
1821}
1822
1823#[allow(dead_code)]
1824struct StreamingTagMapAccess<'a, 'de> {
1825 de: &'a mut StreamingDeserializer<'de>,
1826 tag: (String, String),
1827 done: bool,
1828}
1829impl<'de> serde_core::de::MapAccess<'de> for StreamingTagMapAccess<'_, 'de> {
1830 type Error = Error;
1831 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
1832 where
1833 K: serde_core::de::DeserializeSeed<'de>,
1834 {
1835 if self.done {
1836 Ok(None)
1837 } else {
1838 let full = if self.tag.0 == "!" {
1839 format!("!{}", self.tag.1)
1840 } else {
1841 format!("{}{}", self.tag.0, self.tag.1)
1842 };
1843 let de = serde_core::de::value::StringDeserializer::<Error>::new(full);
1844 seed.deserialize(de).map(Some)
1845 }
1846 }
1847 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
1848 where
1849 V: serde_core::de::DeserializeSeed<'de>,
1850 {
1851 self.done = true;
1852 seed.deserialize(&mut *self.de)
1853 }
1854}
1855
1856#[allow(dead_code)]
1857struct StreamingTagEnumAccess<'a, 'de> {
1858 de: &'a mut StreamingDeserializer<'de>,
1859 tag: (String, String),
1860}
1861impl<'a, 'de> serde_core::de::EnumAccess<'de> for StreamingTagEnumAccess<'a, 'de> {
1862 type Error = Error;
1863 type Variant = StreamingTagVariantAccess<'a, 'de>;
1864 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
1865 where
1866 V: serde_core::de::DeserializeSeed<'de>,
1867 {
1868 let full = if self.tag.0 == "!" {
1869 format!("!{}", self.tag.1)
1870 } else {
1871 format!("{}{}", self.tag.0, self.tag.1)
1872 };
1873 let de = serde_core::de::value::StringDeserializer::<Error>::new(full);
1874 let variant = seed.deserialize(de)?;
1875 Ok((variant, StreamingTagVariantAccess { de: self.de }))
1876 }
1877}
1878
1879#[allow(dead_code)]
1880struct StreamingTagVariantAccess<'a, 'de> {
1881 de: &'a mut StreamingDeserializer<'de>,
1882}
1883impl<'de> serde_core::de::VariantAccess<'de> for StreamingTagVariantAccess<'_, 'de> {
1884 type Error = Error;
1885 fn unit_variant(self) -> Result<()> {
1886 self.de.skip_value()
1887 }
1888 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
1889 where
1890 T: serde_core::de::DeserializeSeed<'de>,
1891 {
1892 seed.deserialize(self.de)
1893 }
1894 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
1895 where
1896 V: serde_core::de::Visitor<'de>,
1897 {
1898 serde_core::Deserializer::deserialize_seq(self.de, visitor)
1899 }
1900 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
1901 where
1902 V: serde_core::de::Visitor<'de>,
1903 {
1904 serde_core::Deserializer::deserialize_map(self.de, visitor)
1905 }
1906}
1907
1908pub(crate) fn from_str_streaming<T>(s: &str, config: &crate::de::ParserConfig) -> Option<Result<T>>
1909where
1910 T: for<'de> serde_core::Deserialize<'de>,
1911{
1912 let parse_config = ParseConfig::from(config);
1913 if s.len() > parse_config.max_document_length {
1914 return Some(Err(document_too_long(parse_config.max_document_length)));
1915 }
1916 let mut de = StreamingDeserializer::with_config(s, parse_config);
1917 if let Some(registry) = config.tag_registry.as_ref() {
1918 de = de.with_tag_registry(Arc::clone(registry));
1919 }
1920 let res = T::deserialize(&mut de);
1921 match res {
1922 Ok(val) => {
1923 Some(de.end().map(|()| val))
1939 }
1940 Err(ref e) => {
1941 if is_fallback_error(e) {
1942 None
1943 } else {
1944 Some(res)
1945 }
1946 }
1947 }
1948}
1949
1950fn parse_plain_float(s: &str) -> Option<f64> {
1966 let unsigned = s.strip_prefix(['+', '-']).unwrap_or(s);
1967 if unsigned.eq_ignore_ascii_case("nan")
1968 || unsigned.eq_ignore_ascii_case("inf")
1969 || unsigned.eq_ignore_ascii_case("infinity")
1970 {
1971 return None;
1972 }
1973 s.parse::<f64>().ok()
1974}
1975
1976#[derive(Debug)]
1978struct SkipLevel {
1979 is_map: bool,
1980 entries: usize,
1982 expecting_key: bool,
1984 keys: FxHashSet<String>,
1986}
1987
1988impl SkipLevel {
1989 fn new(is_map: bool) -> Self {
1990 Self {
1991 is_map,
1992 entries: 0,
1993 expecting_key: true,
1994 keys: FxHashSet::default(),
1995 }
1996 }
1997}
1998
1999fn document_too_long(max: usize) -> Error {
2001 Error::Parse(format!("document exceeds maximum length of {max} bytes"))
2002}
2003
2004fn buffer_cost(events: &[BufferedEvent]) -> AliasCost {
2008 let mut tally = CostTally::default();
2009 for ev in events {
2010 match ev {
2011 BufferedEvent::Scalar { value, .. } => tally.scalar(value.len()),
2012 BufferedEvent::SeqStart | BufferedEvent::MapStart => tally.open(),
2013 BufferedEvent::SeqEnd | BufferedEvent::MapEnd => tally.close(),
2014 BufferedEvent::Alias { .. } => {}
2015 }
2016 }
2017 tally.finish()
2018}
2019
2020fn is_fallback_error(e: &Error) -> bool {
2021 match e {
2022 Error::Custom(msg) => msg == FALLBACK_SENTINEL,
2023 _ => false,
2024 }
2025}
2026
2027pub(crate) fn tag_is_registry_stripped(
2035 handle: &str,
2036 suffix: &str,
2037 registry: &crate::TagRegistry,
2038) -> bool {
2039 if matches!(
2040 (handle, suffix),
2041 (
2042 "!!",
2043 "int" | "float" | "str" | "bool" | "null" | "seq" | "map"
2044 )
2045 ) {
2046 return false;
2047 }
2048 registry.contains(&format!("{handle}{suffix}"))
2049}
2050
2051pub(crate) fn resolve_plain_ext(
2070 s: &str,
2071 strict: bool,
2072 legacy: bool,
2073 no_schema: bool,
2074 legacy_octal: bool,
2075 legacy_sexagesimal: bool,
2076 lossless_u64: bool,
2077) -> Scalar<'_> {
2078 if no_schema {
2079 return Scalar::Str(Cow::Borrowed(s));
2082 }
2083 match s {
2084 "" | "~" | "null" | "Null" | "NULL" => Scalar::Null,
2085 "true" => Scalar::Bool(true),
2086 "false" => Scalar::Bool(false),
2087 "True" | "TRUE" if !strict => Scalar::Bool(true),
2088 "False" | "FALSE" if !strict => Scalar::Bool(false),
2089 ".inf" | ".Inf" | ".INF" | "+.inf" | "+.Inf" | "+.INF" => Scalar::Float(f64::INFINITY),
2090 "-.inf" | "-.Inf" | "-.INF" => Scalar::Float(f64::NEG_INFINITY),
2091 ".nan" | ".NaN" | ".NAN" => Scalar::Float(f64::NAN),
2092 "yes" | "Yes" | "YES" | "y" | "Y" if legacy => Scalar::Bool(true),
2093 "no" | "No" | "NO" | "n" | "N" if legacy => Scalar::Bool(false),
2094 "on" | "On" | "ON" if !strict && legacy => Scalar::Bool(true),
2095 "off" | "Off" | "OFF" if !strict && legacy => Scalar::Bool(false),
2096 _ => {
2097 if let Some(n) = parse_integer(s, legacy_octal, lossless_u64) {
2098 match n {
2099 ParsedInteger::Signed(n) => Scalar::Int(n),
2100 #[cfg(feature = "lossless-u64")]
2101 ParsedInteger::Unsigned(n) => Scalar::Uint(n),
2102 }
2103 } else if lossless_u64 && looks_like_integer_literal(s, legacy_octal) {
2104 Scalar::Str(Cow::Borrowed(s))
2105 } else if legacy_sexagesimal {
2106 if let Some(n) = parse_sexagesimal_int(s) {
2107 Scalar::Int(n)
2108 } else if let Some(f) = parse_sexagesimal_float(s) {
2109 Scalar::Float(f)
2110 } else if let Some(f) = parse_plain_float(s) {
2111 Scalar::Float(f)
2112 } else {
2113 Scalar::Str(Cow::Borrowed(s))
2114 }
2115 } else if let Some(f) = parse_plain_float(s) {
2116 Scalar::Float(f)
2117 } else {
2118 Scalar::Str(Cow::Borrowed(s))
2119 }
2120 }
2121 }
2122}
2123
2124fn looks_like_integer_literal(s: &str, legacy_octal: bool) -> bool {
2125 let b = s.as_bytes();
2126 if b.is_empty() {
2127 return false;
2128 }
2129 for (prefix, radix) in [("0x", 16), ("0o", 8)] {
2130 if let Some(digits) = s.strip_prefix(prefix) {
2131 return radix_digits(digits, radix);
2132 }
2133 }
2134 if legacy_octal && b.len() >= 2 && b[0] == b'0' {
2135 return b[1..].iter().all(|c| (b'0'..=b'7').contains(c));
2136 }
2137 let start = usize::from(b[0] == b'+' || b[0] == b'-');
2138 start < b.len() && b[start..].iter().all(u8::is_ascii_digit)
2139}
2140
2141enum ParsedInteger {
2142 Signed(i64),
2143 #[cfg(feature = "lossless-u64")]
2144 Unsigned(u64),
2145}
2146
2147fn parse_sexagesimal_int(s: &str) -> Option<i64> {
2158 let (sign, rest) = match s.as_bytes().first() {
2159 Some(b'-') => (-1i64, &s[1..]),
2160 Some(b'+') => (1i64, &s[1..]),
2161 _ => (1i64, s),
2162 };
2163 if !rest.contains(':') {
2164 return None;
2165 }
2166 let parts: Vec<&str> = rest.split(':').collect();
2167 if parts.len() < 2 {
2168 return None;
2169 }
2170 let mut total: i64 = 0;
2171 for (idx, part) in parts.iter().enumerate() {
2172 if part.is_empty() || !part.bytes().all(|b| b.is_ascii_digit()) {
2173 return None;
2174 }
2175 let n: i64 = part.parse().ok()?;
2176 if idx > 0 && n >= 60 {
2177 return None;
2178 }
2179 total = total.checked_mul(60)?.checked_add(n)?;
2180 }
2181 sign.checked_mul(total)
2182}
2183
2184fn parse_sexagesimal_float(s: &str) -> Option<f64> {
2188 let (sign, rest) = match s.as_bytes().first() {
2189 Some(b'-') => (-1.0f64, &s[1..]),
2190 Some(b'+') => (1.0f64, &s[1..]),
2191 _ => (1.0f64, s),
2192 };
2193 if !rest.contains(':') {
2194 return None;
2195 }
2196 let parts: Vec<&str> = rest.split(':').collect();
2197 if parts.len() < 2 {
2198 return None;
2199 }
2200 let last_idx = parts.len() - 1;
2201 let mut total: f64 = 0.0;
2202 for (idx, part) in parts.iter().enumerate() {
2203 if part.is_empty() {
2204 return None;
2205 }
2206 let last_with_decimal = idx == last_idx && part.contains('.');
2207 if !last_with_decimal && !part.bytes().all(|b| b.is_ascii_digit()) {
2208 return None;
2209 }
2210 let n: f64 = part.parse().ok()?;
2211 if idx > 0 && n >= 60.0 {
2212 return None;
2213 }
2214 total = f64_mul_add(total, 60.0, n);
2215 }
2216 Some(sign * total)
2217}
2218
2219fn parse_integer(s: &str, legacy_octal: bool, lossless_u64: bool) -> Option<ParsedInteger> {
2220 let b = s.as_bytes();
2221 if b.is_empty() {
2222 return None;
2223 }
2224 for (prefix, radix) in [("0x", 16), ("0o", 8)] {
2227 if let Some(digits) = s.strip_prefix(prefix) {
2228 return radix_digits(digits, radix)
2229 .then(|| parse_radix_integer(digits, radix, lossless_u64))
2230 .flatten();
2231 }
2232 }
2233 if legacy_octal
2238 && b.len() >= 2
2239 && b[0] == b'0'
2240 && b[1..].iter().all(|&c| c.is_ascii_digit() && c <= b'7')
2241 {
2242 return parse_radix_integer(&s[1..], 8, lossless_u64);
2243 }
2244 let start = usize::from(b[0] == b'+' || b[0] == b'-');
2245 if start >= b.len() {
2246 return None;
2247 }
2248 if b[start..].iter().all(|&c| c.is_ascii_digit()) {
2249 if let Some(n) = crate::simd::parse_decimal_i64(b) {
2254 return Some(ParsedInteger::Signed(n));
2255 }
2256 #[cfg(feature = "lossless-u64")]
2257 if lossless_u64 && b[0] != b'-' {
2258 let digits = if b[0] == b'+' { &b[1..] } else { b };
2259 return crate::simd::parse_decimal_u64(digits).map(ParsedInteger::Unsigned);
2260 }
2261 None
2262 } else {
2263 None
2264 }
2265}
2266
2267fn radix_digits(s: &str, radix: u32) -> bool {
2270 !s.is_empty() && s.chars().all(|c| c.is_digit(radix))
2271}
2272
2273fn parse_radix_integer(s: &str, radix: u32, lossless_u64: bool) -> Option<ParsedInteger> {
2274 #[cfg(not(feature = "lossless-u64"))]
2275 let _ = lossless_u64;
2276 if let Ok(n) = i64::from_str_radix(s, radix) {
2277 return Some(ParsedInteger::Signed(n));
2278 }
2279 #[cfg(feature = "lossless-u64")]
2280 if lossless_u64 {
2281 return u64::from_str_radix(s, radix)
2282 .ok()
2283 .map(ParsedInteger::Unsigned);
2284 }
2285 #[allow(unreachable_code)]
2286 None
2287}
2288
2289fn extract_mapping_body(buf: &[BufferedEvent]) -> Option<&[BufferedEvent]> {
2290 if buf.len() < 2
2291 || !matches!(buf.first(), Some(BufferedEvent::MapStart))
2292 || !matches!(buf.last(), Some(BufferedEvent::MapEnd))
2293 {
2294 None
2295 } else {
2296 Some(&buf[1..buf.len() - 1])
2297 }
2298}
2299
2300fn collect_keys(body: &[BufferedEvent], seen: &mut FxHashSet<String>) -> Option<()> {
2301 let mut i = 0;
2302 while i < body.len() {
2303 if let BufferedEvent::Scalar { value, .. } = &body[i] {
2304 let _ = seen.insert(value.clone());
2305 } else {
2306 return None;
2307 }
2308 i += 1;
2309 if i < body.len() {
2310 let len = skip_buffered_value(&body[i..]);
2311 if len == 0 {
2312 return None;
2313 }
2314 i += len;
2315 } else {
2316 return None;
2317 }
2318 }
2319 Some(())
2320}
2321
2322fn skip_buffered_value(slice: &[BufferedEvent]) -> usize {
2323 if slice.is_empty() {
2324 return 0;
2325 }
2326 match &slice[0] {
2327 BufferedEvent::Scalar { .. } | BufferedEvent::Alias { .. } => 1,
2328 BufferedEvent::SeqStart => {
2329 let mut d = 1;
2330 let mut i = 1;
2331 while i < slice.len() && d > 0 {
2332 match &slice[i] {
2333 BufferedEvent::SeqStart => d += 1,
2334 BufferedEvent::SeqEnd => d -= 1,
2335 _ => {}
2336 }
2337 i += 1;
2338 }
2339 i
2340 }
2341 BufferedEvent::MapStart => {
2342 let mut d = 1;
2343 let mut i = 1;
2344 while i < slice.len() && d > 0 {
2345 match &slice[i] {
2346 BufferedEvent::MapStart => d += 1,
2347 BufferedEvent::MapEnd => d -= 1,
2348 _ => {}
2349 }
2350 i += 1;
2351 }
2352 i
2353 }
2354 _ => 1,
2355 }
2356}
2357
2358fn extract_local_keys(buf: &[BufferedEvent]) -> FxHashSet<String> {
2359 let mut keys = FxHashSet::default();
2360 let mut d: usize = 0;
2361 let mut key = true;
2362 for ev in buf {
2363 match ev {
2364 BufferedEvent::Scalar { value, .. } => {
2365 if d == 0 {
2366 if key {
2367 let _ = keys.insert(value.clone());
2368 }
2369 key = !key;
2370 }
2371 }
2372 BufferedEvent::Alias { .. } => {
2373 if d == 0 {
2374 key = !key;
2375 }
2376 }
2377 BufferedEvent::MapStart | BufferedEvent::SeqStart => d += 1,
2378 BufferedEvent::MapEnd | BufferedEvent::SeqEnd => {
2379 if d == 1 {
2380 key = true;
2381 }
2382 d = d.saturating_sub(1);
2383 }
2384 }
2385 }
2386 keys
2387}
2388
2389fn filter_merge_entries(
2390 inner: &[BufferedEvent],
2391 local: &FxHashSet<String>,
2392) -> Option<SmallVec<[BufferedEvent; SMALL_VEC_SIZE]>> {
2393 let mut out = SmallVec::with_capacity(inner.len());
2394 let mut i = 0;
2395 while i < inner.len() {
2396 let key = if let BufferedEvent::Scalar { value, .. } = &inner[i] {
2397 value.clone()
2398 } else {
2399 return None;
2400 };
2401 let start = i;
2402 i += 1;
2403 if i >= inner.len() {
2404 return None;
2405 }
2406 let len = skip_buffered_value(&inner[i..]);
2407 if len == 0 {
2408 return None;
2409 }
2410 let end = i + len;
2411 if !local.contains(&key) {
2412 for ev in &inner[start..end] {
2413 out.push(ev.clone());
2414 }
2415 }
2416 i = end;
2417 }
2418 Some(out)
2419}
2420
2421#[cfg(test)]
2422mod lookahead_tests {
2423 use super::{Event, Lookahead, ScalarStyle};
2433 use crate::parser::scanner_span_default;
2434
2435 fn scalar(v: &'static str) -> Event<'static> {
2436 Event::Scalar {
2437 value: std::borrow::Cow::Borrowed(v),
2438 style: ScalarStyle::Plain,
2439 anchor: None,
2440 tag: None,
2441 span: scanner_span_default(),
2442 }
2443 }
2444
2445 fn alias(name: &str) -> Event<'static> {
2446 Event::Alias {
2447 anchor: name.to_string(),
2448 span: scanner_span_default(),
2449 }
2450 }
2451
2452 #[test]
2453 fn event_reads_through_both_states() {
2454 let raw = Lookahead::Raw(scalar("a"));
2455 let done = Lookahead::Processed(scalar("a"));
2456 assert!(matches!(raw.event(), Event::Scalar { .. }));
2457 assert!(matches!(done.event(), Event::Scalar { .. }));
2458 }
2459
2460 #[test]
2461 fn event_mut_reads_through_both_states() {
2462 let mut raw = Lookahead::Raw(scalar("a"));
2463 let mut done = Lookahead::Processed(scalar("a"));
2464 assert!(matches!(raw.event_mut(), Event::Scalar { .. }));
2465 assert!(matches!(done.event_mut(), Event::Scalar { .. }));
2466 }
2467
2468 #[test]
2469 fn event_mut_actually_mutates_in_place() {
2470 let mut slot = Lookahead::Processed(Event::Scalar {
2473 value: std::borrow::Cow::Borrowed("a"),
2474 style: ScalarStyle::Plain,
2475 anchor: None,
2476 tag: Some(("!".into(), "custom".into())),
2477 span: scanner_span_default(),
2478 });
2479 if let Event::Scalar { tag, .. } = slot.event_mut() {
2480 let stolen = tag.take();
2481 assert!(stolen.is_some(), "tag was there to take");
2482 }
2483 match slot.event() {
2484 Event::Scalar { tag, .. } => assert!(tag.is_none(), "the take must stick"),
2485 other => panic!("unexpected event: {other:?}"),
2486 }
2487 }
2488
2489 #[test]
2490 fn the_two_states_are_distinguishable() {
2491 let raw = Lookahead::Raw(alias("n"));
2495 let done = Lookahead::Processed(alias("n"));
2496 assert!(matches!(raw, Lookahead::Raw(_)));
2497 assert!(matches!(done, Lookahead::Processed(_)));
2498 assert!(!matches!(raw, Lookahead::Processed(_)));
2499 assert!(!matches!(done, Lookahead::Raw(_)));
2500 }
2501
2502 #[test]
2503 fn an_alias_can_sit_in_either_state() {
2504 assert!(matches!(
2510 Lookahead::Raw(alias("n")).event(),
2511 Event::Alias { .. }
2512 ));
2513 assert!(matches!(
2514 Lookahead::Processed(alias("n")).event(),
2515 Event::Alias { .. }
2516 ));
2517 }
2518
2519 #[test]
2520 fn into_inner_yields_the_event_from_either_state() {
2521 assert!(matches!(
2522 Lookahead::Raw(alias("n")).into_inner(),
2523 Event::Alias { .. }
2524 ));
2525 assert!(matches!(
2526 Lookahead::Processed(scalar("a")).into_inner(),
2527 Event::Scalar { .. }
2528 ));
2529 }
2530
2531 #[test]
2532 fn debug_is_available_for_tracing_the_slot() {
2533 let s = format!("{:?}", Lookahead::Raw(alias("n")));
2536 assert!(s.contains("Raw"), "state must be visible: {s}");
2537 assert!(s.contains("Alias"), "event must be visible: {s}");
2538 }
2539}