1use std::collections::{HashSet, VecDeque};
2use std::{borrow::Cow, fmt};
3
4use granit_parser::ScalarStyle;
5use serde_core::de::{self, Deserializer as _, IntoDeserializer, Visitor};
6
7use super::base64::decode_base64_yaml;
8use super::cfg::Cfg;
9#[cfg(feature = "comments")]
10use super::commented_deser;
11use super::error::{Error, MissingFieldLocationGuard, TransformReason};
12use super::events::{
13 Ev, Events, RecordedEvents, ReplayEvents, attach_alias_locations_if_missing, eof_with_loc,
14 with_deferred_recursive_aliases,
15};
16use super::key_nodes::{
17 KeyFingerprint, KeyNode, PendingEntry, apply_duplicate_key_policy_to_entries,
18 capture_node_with_legacy_octal, capture_simple_tagged_node_as_map_events,
19 is_empty_mapping_key_fingerprint, is_merge_key, pending_entries_from_live_events,
20 simple_tagged_enum_name, validate_no_merge_keys_in_node_events,
21};
22#[cfg(feature = "properties")]
23use super::options::PropertySyntax;
24use super::options::{DuplicateKeyPolicy, MergeKeyPolicy, NonFiniteFloatPolicy};
25#[cfg(any(feature = "garde", feature = "validator"))]
26use super::path_map::PathRecorder;
27#[cfg(feature = "properties")]
28use super::properties::{interpolate_compose_style_with_limits, is_sole_unset_reference};
29use super::properties_redaction::{
30 ScalarRedactionCtx, ScalarRedactionGuard, with_interp_redaction_scope,
31};
32use super::spanned_deser;
33use super::tagged_deser;
34use super::tags::SfTag;
35use crate::anchor_store::{self, AnchorKind};
36#[cfg(feature = "properties")]
37use crate::budget::BudgetBreach;
38#[cfg(feature = "properties")]
39use crate::de_error::budget_error;
40use crate::location::Location;
41#[cfg(any(feature = "garde", feature = "validator"))]
42use crate::location::Locations;
43use crate::parse_scalars::{
44 leading_zero_decimal, maybe_not_string, parse_int_signed, parse_int_unsigned,
45 parse_yaml11_bool, parse_yaml12_bool, parse_yaml12_float, scalar_is_null, scalar_is_nullish,
46 try_parse_float_incl_overflow, yaml_trim,
47};
48
49struct TupleLenExpected {
50 len: usize,
51}
52
53impl fmt::Display for TupleLenExpected {
54 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
55 write!(formatter, "a tuple of size {}", self.len)
56 }
57}
58
59impl de::Expected for TupleLenExpected {
60 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
61 fmt::Display::fmt(self, formatter)
62 }
63}
64
65struct TupleLenVisitor<V> {
66 inner: V,
67 len: usize,
68}
69
70impl<'de, V> Visitor<'de> for TupleLenVisitor<V>
71where
72 V: Visitor<'de>,
73{
74 type Value = V::Value;
75
76 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
77 self.inner.expecting(formatter)
78 }
79
80 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
81 where
82 A: de::SeqAccess<'de>,
83 {
84 let mut consumed = 0usize;
85 let value = self.inner.visit_seq(CountingSeqAccess {
86 inner: &mut seq,
87 consumed: &mut consumed,
88 })?;
89
90 if seq.next_element::<de::IgnoredAny>()?.is_some() {
91 return Err(<A::Error as de::Error>::invalid_length(
92 consumed + 1,
93 &TupleLenExpected { len: self.len },
94 ));
95 }
96
97 Ok(value)
98 }
99}
100
101struct CountingSeqAccess<'a, A> {
102 inner: &'a mut A,
103 consumed: &'a mut usize,
104}
105
106impl<'de, A> de::SeqAccess<'de> for CountingSeqAccess<'_, A>
107where
108 A: de::SeqAccess<'de>,
109{
110 type Error = A::Error;
111
112 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
113 where
114 T: de::DeserializeSeed<'de>,
115 {
116 let value = self.inner.next_element_seed(seed)?;
117 if value.is_some() {
118 *self.consumed += 1;
119 }
120 Ok(value)
121 }
122
123 fn size_hint(&self) -> Option<usize> {
124 self.inner.size_hint()
125 }
126}
127
128fn skip_one_node_from_events(ev: &mut dyn Events<'_>) -> Result<(), Error> {
129 let mut depth;
130 match ev.next()? {
131 Some(Ev::RecursiveAlias { location, .. }) => {
132 return Err(Error::RecursiveReferencesRequireWeakTypes { location });
133 }
134 Some(Ev::Scalar { .. }) => return Ok(()),
135 Some(Ev::SeqStart { .. } | Ev::MapStart { .. }) => depth = 1usize,
136 Some(Ev::SeqEnd { location } | Ev::MapEnd { location }) => {
137 return Err(Error::UnexpectedContainerEndWhileSkippingNode { location });
138 }
139 Some(Ev::Taken { location }) => {
140 return Err(Error::unexpected("consumed event").with_location(location));
141 }
142 None => return Err(eof_with_loc(ev)),
143 }
144
145 while depth != 0 {
146 match ev.next()? {
147 Some(Ev::RecursiveAlias { location, .. }) => {
148 return Err(Error::RecursiveReferencesRequireWeakTypes { location });
149 }
150 Some(Ev::SeqStart { .. } | Ev::MapStart { .. }) => depth += 1,
151 Some(Ev::SeqEnd { .. } | Ev::MapEnd { .. }) => depth -= 1,
152 Some(Ev::Scalar { .. }) => {}
153 Some(Ev::Taken { location }) => {
154 return Err(Error::unexpected("consumed event").with_location(location));
155 }
156 None => return Err(eof_with_loc(ev)),
157 }
158 }
159
160 Ok(())
161}
162
163fn drain_remaining_sequence(ev: &mut dyn Events<'_>) -> Result<(), Error> {
164 loop {
165 match ev.peek()? {
166 Some(Ev::SeqEnd { .. }) => {
167 let _ = ev.next()?;
168 return Ok(());
169 }
170 Some(_) => skip_one_node_from_events(ev)?,
171 None => return Err(eof_with_loc(ev)),
172 }
173 }
174}
175
176fn remembers_seen_keys(cfg: &Cfg) -> bool {
179 !matches!(cfg.dup_policy, DuplicateKeyPolicy::PassThrough)
180 || cfg.merge_keys == MergeKeyPolicy::Merge
181}
182
183fn is_serde_content_buffer<V>() -> bool {
190 let name = std::any::type_name::<V>();
191 let bare_name = name
194 .split_once('<')
195 .map_or(name, |(bare_name, _)| bare_name);
196 name.contains("::private::de::") && bare_name.ends_with("::ContentVisitor")
197}
198
199pub struct YamlDeserializer<'de, 'e> {
241 pub(super) ev: &'e mut dyn Events<'de>,
242 pub(super) cfg: Cfg,
243 in_key: bool,
245 struct_mode: bool,
250 key_empty_map_node: bool,
252 pub(super) pending_comments: Vec<Cow<'de, str>>,
254 pub(super) pending_value_separator_comments: Vec<Cow<'de, str>>,
256 pub(super) pending_value_comments: Vec<Cow<'de, str>>,
258
259 #[cfg(any(feature = "garde", feature = "validator"))]
260 pub(super) garde: Option<&'e mut PathRecorder>,
261}
262
263#[derive(Clone)]
264struct ScalarView<'de> {
265 raw: Cow<'de, str>,
266 effective: Cow<'de, str>,
267 tag: SfTag,
268 style: ScalarStyle,
269 location: Location,
270 interpolated: bool,
271}
272
273type EffectiveScalar<'de> = (Cow<'de, str>, SfTag, ScalarStyle, Location);
274
275impl ScalarView<'_> {
276 fn redaction_ctx(&self) -> Option<ScalarRedactionCtx> {
277 self.interpolated.then(|| ScalarRedactionCtx {
278 raw: self.raw.as_ref().to_owned(),
279 effective: self.effective.as_ref().to_owned(),
280 })
281 }
282}
283
284fn with_scalar_redaction<T>(
285 ctx: Option<ScalarRedactionCtx>,
286 f: impl FnOnce() -> Result<T, Error>,
287) -> Result<T, Error> {
288 let _guard = ctx.map(ScalarRedactionGuard::new);
289 f()
290}
291
292fn with_subtree_redaction<T>(
299 ctx: Option<ScalarRedactionCtx>,
300 f: impl FnOnce() -> Result<T, Error>,
301) -> Result<T, Error> {
302 with_interp_redaction_scope(|| with_scalar_redaction(ctx, f))
303}
304
305#[cfg(feature = "properties")]
306pub(crate) fn with_root_redaction<'de, 'e, T>(
307 mut de: YamlDeserializer<'de, 'e>,
308 f: impl FnOnce(YamlDeserializer<'de, 'e>) -> Result<T, Error>,
309) -> Result<T, Error> {
310 let redaction_ctx = de.peek_scalar_redaction_ctx()?;
311 with_subtree_redaction(redaction_ctx, || f(de))
312}
313
314#[cfg(not(feature = "properties"))]
315pub(crate) fn with_root_redaction<'de, 'e, T>(
316 de: YamlDeserializer<'de, 'e>,
317 f: impl FnOnce(YamlDeserializer<'de, 'e>) -> Result<T, Error>,
318) -> Result<T, Error> {
319 f(de)
320}
321
322#[cfg_attr(not(feature = "properties"), allow(unused_mut))]
327pub(crate) fn with_root_redaction_unless_null<'de, 'e, T>(
328 mut de: YamlDeserializer<'de, 'e>,
329 f: impl FnOnce(YamlDeserializer<'de, 'e>) -> Result<T, Error>,
330) -> Result<Option<T>, Error> {
331 if let Some(Ev::Scalar {
332 value, tag, style, ..
333 }) = de.ev.peek()?
334 {
335 let keep_tagged = *tag == SfTag::Other;
336 if !keep_tagged && scalar_is_null(tag, value, style) {
337 let _ = de.ev.next()?;
338 return Ok(None);
339 }
340
341 #[cfg(feature = "properties")]
342 {
343 let (tag, style) = (*tag, *style);
344 if de.interpolation_possible(tag, style) {
345 let Some(view) = de.peek_scalar_view()? else {
346 return Err(eof_with_loc(de.ev));
347 };
348 if !keep_tagged
349 && de.ev.property_interpolation().syntax()
350 == PropertySyntax::DockerComposeWithNulls
351 && view.tag == SfTag::Null
352 {
353 let _ = de.ev.next()?;
354 return Ok(None);
355 }
356 return with_subtree_redaction(view.redaction_ctx(), || f(de)).map(Some);
357 }
358 }
359 }
360
361 with_root_redaction(de, f).map(Some)
362}
363
364struct EnumScalarId<'de> {
365 raw: Cow<'de, str>,
366 effective: Cow<'de, str>,
367 interpolated: bool,
368 location: Location,
369}
370
371impl<'de> EnumScalarId<'de> {
372 fn from_view(view: ScalarView<'de>) -> Self {
373 Self {
374 raw: view.raw,
375 effective: view.effective,
376 interpolated: view.interpolated,
377 location: view.location,
378 }
379 }
380
381 fn redaction_ctx(&self) -> Option<ScalarRedactionCtx> {
382 self.interpolated.then(|| ScalarRedactionCtx {
383 raw: self.raw.as_ref().to_owned(),
384 effective: self.effective.as_ref().to_owned(),
385 })
386 }
387}
388
389impl<'de> IntoDeserializer<'de, Error> for EnumScalarId<'de> {
390 type Deserializer = Self;
391
392 fn into_deserializer(self) -> Self::Deserializer {
393 self
394 }
395}
396
397impl<'de> de::Deserializer<'de> for EnumScalarId<'de> {
398 type Error = Error;
399
400 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
401 where
402 V: Visitor<'de>,
403 {
404 self.deserialize_identifier(visitor)
405 }
406
407 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
408 where
409 V: Visitor<'de>,
410 {
411 let ctx = self.redaction_ctx();
412 let location = self.location;
413 let effective = self.effective;
414 with_scalar_redaction(ctx, move || match effective {
415 Cow::Borrowed(value) => visitor.visit_borrowed_str(value),
416 Cow::Owned(value) => visitor.visit_string(value),
417 })
418 .map_err(|err| err.with_location(location))
419 }
420
421 serde_core::forward_to_deserialize_any! {
422 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf
423 option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum
424 ignored_any
425 }
426}
427
428impl<'de, 'e> YamlDeserializer<'de, 'e> {
429 fn validate_scalar_tag(
435 &self,
436 tag: SfTag,
437 expected: SfTag,
438 ty: &'static str,
439 location: Location,
440 ) -> Result<(), Error> {
441 let compatible = tag == expected
442 || match tag {
443 SfTag::None
444 | SfTag::Other
445 | SfTag::Include
446 | SfTag::Merge
447 | SfTag::Value
448 | SfTag::NonSpecific => true,
449 tag if tag.is_robotics() => {
450 expected == SfTag::Float
451 && cfg!(feature = "robotics")
452 && self.cfg.angle_conversions
453 }
454 _ => false,
455 };
456 if compatible {
457 Ok(())
458 } else {
459 Err(Error::InvalidScalar { ty, location })
460 }
461 }
462
463 pub(crate) fn new(ev: &'e mut dyn Events<'de>, cfg: Cfg) -> Self {
475 Self {
476 ev,
477 cfg,
478 in_key: false,
479 struct_mode: false,
480 key_empty_map_node: false,
481 pending_comments: Vec::new(),
482 pending_value_separator_comments: Vec::new(),
483 pending_value_comments: Vec::new(),
484
485 #[cfg(any(feature = "garde", feature = "validator"))]
486 garde: None,
487 }
488 }
489
490 fn quoting_required_for_scalar(view: &ScalarView<'de>) -> Error {
491 Error::quoting_required(view.raw.as_ref(), view.interpolated).with_location(view.location)
492 }
493
494 #[cfg(feature = "properties")]
495 fn interpolation_possible(&self, tag: SfTag, style: ScalarStyle) -> bool {
496 if self.in_key || tag == SfTag::Binary {
497 return false;
498 }
499
500 let properties = self.ev.property_interpolation();
501 if properties.property_map().is_none() {
502 return false;
503 }
504
505 match properties.syntax() {
506 syntax if syntax.is_docker_compose() => tag.can_parse_into_string(),
507 _ => style == ScalarStyle::Plain,
508 }
509 }
510
511 #[cfg(not(feature = "properties"))]
512 fn interpolation_possible(&self, _tag: SfTag, _style: ScalarStyle) -> bool {
513 false
514 }
515
516 #[cfg(feature = "properties")]
517 fn peek_scalar_redaction_ctx(&mut self) -> Result<Option<ScalarRedactionCtx>, Error> {
518 let Some((tag, style)) = (match self.ev.peek()? {
519 Some(Ev::Scalar { tag, style, .. }) => Some((*tag, *style)),
520 _ => None,
521 }) else {
522 return Ok(None);
523 };
524
525 if !self.interpolation_possible(tag, style) {
526 return Ok(None);
527 }
528
529 Ok(self
530 .peek_scalar_view()?
531 .and_then(|view| view.redaction_ctx()))
532 }
533
534 #[cfg(not(feature = "properties"))]
535 fn peek_scalar_redaction_ctx(&mut self) -> Result<Option<ScalarRedactionCtx>, Error> {
536 Ok(None)
537 }
538
539 #[cfg(any(feature = "garde", feature = "validator"))]
540 pub(crate) fn new_with_path_recorder(
541 ev: &'e mut dyn Events<'de>,
542 cfg: Cfg,
543 garde: &'e mut PathRecorder,
544 ) -> Self {
545 Self {
546 ev,
547 cfg,
548 in_key: false,
549 struct_mode: false,
550 key_empty_map_node: false,
551 pending_comments: Vec::new(),
552 pending_value_separator_comments: Vec::new(),
553 pending_value_comments: Vec::new(),
554 garde: Some(garde),
555 }
556 }
557
558 fn take_scalar_event(&mut self) -> Result<(String, SfTag, Location), Error> {
567 let view = self.take_scalar_view()?;
568 Ok((view.effective.into_owned(), view.tag, view.location))
569 }
570
571 fn take_scalar_cow_event(&mut self) -> Result<(Cow<'de, str>, SfTag, Location), Error> {
576 let view = self.take_scalar_view()?;
577 Ok((view.effective, view.tag, view.location))
578 }
579
580 fn take_scalar_view(&mut self) -> Result<ScalarView<'de>, Error> {
581 match self.ev.next()? {
582 Some(Ev::Scalar {
583 value,
584 tag,
585 style,
586 location,
587 ..
588 }) => self.scalar_view_from_parts(value, tag, style, location),
589 Some(other) => Err(Error::unexpected("string scalar").with_location(other.location())),
590 None => Err(eof_with_loc(self.ev)),
591 }
592 }
593
594 fn take_peeked_scalar_view(&mut self, view: ScalarView<'de>) -> Result<ScalarView<'de>, Error> {
595 match self.ev.next()? {
596 Some(Ev::Scalar { .. }) => Ok(view),
597 Some(other) => Err(Error::unexpected("string scalar").with_location(other.location())),
598 None => Err(eof_with_loc(self.ev)),
599 }
600 }
601
602 fn take_string_scalar(&mut self) -> Result<String, Error> {
607 let (value, tag, location) = self.take_scalar_event()?;
608
609 if tag == SfTag::Binary && !self.cfg.ignore_binary_tag_for_string {
611 let data = decode_base64_yaml(&value).map_err(|err| err.with_location(location))?;
612 let text = String::from_utf8(data).map_err(|_| Error::BinaryNotUtf8 { location })?;
613 return Ok(text);
614 }
615
616 if !(tag.can_parse_into_string()
618 || self.cfg.ignore_binary_tag_for_string && tag == SfTag::Binary)
619 {
620 return Err(Error::TaggedScalarCannotDeserializeIntoString { location });
621 }
622
623 Ok(value)
624 }
625
626 fn visit_typeless_float<V: Visitor<'de>>(
628 &self,
629 value: f64,
630 raw: String,
631 location: Location,
632 visitor: V,
633 ) -> Result<V::Value, Error> {
634 if value.is_finite() {
635 return visitor.visit_f64(value);
636 }
637 match self.cfg.non_finite_float_policy {
638 NonFiniteFloatPolicy::PassThrough => visitor.visit_f64(value),
639 NonFiniteFloatPolicy::Default | NonFiniteFloatPolicy::Reject => {
642 Err(Error::NonFiniteFloat {
643 value: raw,
644 location,
645 })
646 }
647 NonFiniteFloatPolicy::AsString => {
648 let canonical = if value.is_nan() {
649 ".nan"
650 } else if value.is_sign_negative() {
651 "-.inf"
652 } else {
653 ".inf"
654 };
655 visitor.visit_string(canonical.to_owned())
656 }
657 }
658 }
659
660 fn expect_seq_start(&mut self) -> Result<(), Error> {
662 match self.ev.next()? {
663 Some(Ev::SeqStart { .. }) => Ok(()),
664 Some(other) => Err(Error::unexpected("sequence start").with_location(other.location())),
665 None => Err(eof_with_loc(self.ev)),
666 }
667 }
668
669 fn expect_map_start(&mut self) -> Result<(), Error> {
671 match self.ev.next()? {
672 Some(Ev::MapStart { .. }) => Ok(()),
673 Some(other) => Err(Error::unexpected("mapping start").with_location(other.location())),
674 None => Err(eof_with_loc(self.ev)),
675 }
676 }
677
678 fn peek_effective_scalar(&mut self) -> Result<Option<EffectiveScalar<'de>>, Error> {
679 let Some(view) = self.peek_scalar_view()? else {
680 return Ok(None);
681 };
682 Ok(Some((view.effective, view.tag, view.style, view.location)))
683 }
684
685 pub(super) fn peek_null_value(&mut self) -> Result<bool, Error> {
690 match self.ev.peek()? {
691 Some(Ev::Scalar {
692 value, tag, style, ..
693 }) => {
694 if scalar_is_null(tag, value, style) {
695 return Ok(true);
696 }
697
698 #[cfg(feature = "properties")]
699 {
700 let (tag, style) = (*tag, *style);
701 if self.ev.property_interpolation().syntax()
702 == PropertySyntax::DockerComposeWithNulls
703 && !tag.forces_string()
704 && self.interpolation_possible(tag, style)
705 {
706 return Ok(self
707 .peek_scalar_view()?
708 .is_some_and(|view| view.tag == SfTag::Null));
709 }
710 }
711
712 Ok(false)
713 }
714 _ => Ok(false),
715 }
716 }
717
718 fn peek_scalar_view(&mut self) -> Result<Option<ScalarView<'de>>, Error> {
719 let (value, tag, style, location) = match self.ev.peek()? {
720 Some(Ev::Scalar {
721 value,
722 tag,
723 style,
724 location,
725 ..
726 }) => (value.clone(), *tag, *style, *location),
727 _ => return Ok(None),
728 };
729
730 Ok(Some(
731 self.scalar_view_from_parts(value, tag, style, location)?,
732 ))
733 }
734
735 fn scalar_view_from_parts(
736 &self,
737 raw: Cow<'de, str>,
738 tag: SfTag,
739 style: ScalarStyle,
740 location: Location,
741 ) -> Result<ScalarView<'de>, Error> {
742 let can_interpolate = self.interpolation_possible(tag, style);
743 let effective = if can_interpolate {
744 self.effective_scalar_value(raw.clone(), location)?
745 } else {
746 raw.clone()
747 };
748 let interpolated = can_interpolate && raw.as_ref() != effective.as_ref();
749 #[cfg(feature = "properties")]
750 let tag = if interpolated {
751 self.compose_expansion_tag(&raw, &effective, tag)
752 } else {
753 tag
754 };
755 Ok(ScalarView {
756 raw,
757 effective,
758 tag,
759 style,
760 location,
761 interpolated,
762 })
763 }
764
765 #[cfg(feature = "properties")]
776 fn compose_expansion_tag(&self, raw: &str, effective: &str, tag: SfTag) -> SfTag {
777 let properties = self.ev.property_interpolation();
778 let syntax = properties.syntax();
779 if !syntax.is_docker_compose() || !tag.can_parse_into_string() || tag.forces_string() {
780 return tag;
781 }
782 let becomes_null = syntax == PropertySyntax::DockerComposeWithNulls
783 && (matches!(effective, "~" | "null" | "Null" | "NULL")
784 || properties
785 .property_map()
786 .is_some_and(|vars| is_sole_unset_reference(raw, vars, syntax)));
787 if becomes_null {
788 SfTag::Null
789 } else {
790 SfTag::NonSpecific
791 }
792 }
793
794 #[cfg(feature = "properties")]
796 fn effective_scalar_value(
797 &self,
798 value: Cow<'de, str>,
799 location: Location,
800 ) -> Result<Cow<'de, str>, Error> {
801 let properties = self.ev.property_interpolation();
802 let Some(vars) = properties.property_map() else {
803 return Ok(value);
804 };
805 let vars = vars.as_ref();
806 let syntax = properties.syntax();
807
808 match interpolate_compose_style_with_limits(
809 value,
810 vars,
811 syntax,
812 properties.max_expansion_depth(),
813 properties.max_total_work(),
814 properties.total_work(),
815 ) {
816 Ok(value) => Ok(value),
817 Err(crate::properties::PropertyError::Unresolved(name)) => {
818 Err(Error::UnresolvedProperty { name, location })
819 }
820 Err(crate::properties::PropertyError::InvalidName(name)) => {
821 Err(Error::InvalidPropertyName { name, location })
822 }
823 Err(crate::properties::PropertyError::RequiredButUnset { name, message }) => {
824 Err(Error::PropertyRequiredButUnset {
825 name,
826 message,
827 location,
828 })
829 }
830 Err(crate::properties::PropertyError::RequiredButEmpty { name, message }) => {
831 Err(Error::PropertyRequiredButEmpty {
832 name,
833 message,
834 location,
835 })
836 }
837 Err(crate::properties::PropertyError::ExpansionDepthLimitExceeded {
838 depth,
839 max_depth,
840 }) => {
841 let breach = BudgetBreach::PropertyExpansionDepth { depth, max_depth };
842 properties.record_breach(breach.clone());
843 Err(budget_error(breach).with_location(location))
844 }
845 Err(crate::properties::PropertyError::ExpansionWorkLimitExceeded {
846 work,
847 max_work,
848 }) => {
849 let breach = BudgetBreach::PropertyInterpolationWork { work, max_work };
850 properties.record_breach(breach.clone());
851 Err(budget_error(breach).with_location(location))
852 }
853 }
854 }
855
856 #[cfg(not(feature = "properties"))]
857 fn effective_scalar_value(
858 &self,
859 value: Cow<'de, str>,
860 _location: Location,
861 ) -> Result<Cow<'de, str>, Error> {
862 Ok(value)
863 }
864
865 fn peek_anchor_id(&mut self) -> Result<Option<usize>, Error> {
867 match self.ev.peek()? {
868 Some(
869 Ev::Scalar { anchor, .. }
870 | Ev::SeqStart { anchor, .. }
871 | Ev::MapStart { anchor, .. },
872 ) => {
873 if *anchor == 0 {
874 Ok(None)
875 } else {
876 Ok(Some(*anchor))
877 }
878 }
879 _ => Ok(None),
880 }
881 }
882}
883
884impl<'de> de::Deserializer<'de> for YamlDeserializer<'de, '_> {
885 type Error = Error;
886
887 fn deserialize_any<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
918 if is_serde_content_buffer::<V>()
922 && let Some(events) = capture_simple_tagged_node_as_map_events(self.ev)?
923 {
924 let mut replay = ReplayEvents::new(
925 events,
926 #[cfg(feature = "properties")]
927 self.ev.property_interpolation().clone(),
928 );
929 return YamlDeserializer::new(&mut replay, self.cfg).deserialize_map(visitor);
930 }
931
932 if let Some((value, tag, style, location)) = self.peek_effective_scalar()? {
933 match tag {
936 SfTag::Null => {
937 let _ = self.take_scalar_event()?;
938 return visitor.visit_unit();
939 }
940 SfTag::Bool => return self.deserialize_bool(visitor),
941 SfTag::Int if yaml_trim(&value).starts_with('-') => {
942 return self.deserialize_i64(visitor);
943 }
944 SfTag::Int => return self.deserialize_u64(visitor),
945 SfTag::Float | SfTag::Time | SfTag::Degrees | SfTag::Radians => {
946 self.validate_scalar_tag(tag, SfTag::Float, "floating point", location)?;
947 let view = self.take_scalar_view()?;
948 let value = try_parse_float_incl_overflow(
949 &view.effective,
950 view.location,
951 view.tag,
952 self.cfg.angle_conversions,
953 )
954 .ok_or(Error::InvalidScalar {
955 ty: "floating point",
956 location: view.location,
957 })?;
958 return self.visit_typeless_float(
959 value,
960 view.raw.into_owned(),
961 view.location,
962 visitor,
963 );
964 }
965 _ => {}
966 }
967 let is_plain = matches!(style, ScalarStyle::Plain);
968 if scalar_is_null(&tag, &value, &style) {
970 let _ = self.ev.next()?; return visitor.visit_unit();
972 }
973 if !is_plain
974 || !tag.can_parse_into_string()
975 || tag == SfTag::Binary
976 || tag.forces_string()
977 {
978 if tag == SfTag::Binary && !self.cfg.ignore_binary_tag_for_string {
982 return visitor.visit_string(self.take_string_scalar()?);
983 }
984 if !(tag.can_parse_into_string()
985 || self.cfg.ignore_binary_tag_for_string && tag == SfTag::Binary)
986 {
987 return Err(Error::TaggedScalarCannotDeserializeIntoString { location });
988 }
989
990 let (cow, _tag2, _location) = self.take_scalar_cow_event()?;
991 return match cow {
992 Cow::Borrowed(b) => visitor.visit_borrowed_str(b),
993 Cow::Owned(s) => visitor.visit_string(s),
994 };
995 }
996
997 let view = self.take_scalar_view()?;
1000 let effective = view.effective;
1001 let location = view.location;
1002
1003 if self.cfg.strict_booleans {
1005 if let Some(b) = parse_yaml12_bool(&effective) {
1006 return visitor.visit_bool(b);
1007 }
1008 } else if let Some(b) = parse_yaml11_bool(&effective) {
1009 return visitor.visit_bool(b);
1010 }
1011
1012 let t = yaml_trim(&effective);
1013 if (self.cfg.leading_zero_numbers_as_strings && leading_zero_decimal(t))
1016 || (self.cfg.underscored_numbers_as_strings && t.contains('_'))
1017 {
1018 return match effective {
1019 Cow::Borrowed(b) => visitor.visit_borrowed_str(b),
1020 Cow::Owned(s) => visitor.visit_string(s),
1021 };
1022 }
1023
1024 if t.starts_with('-') {
1026 if (!leading_zero_decimal(t) || self.cfg.legacy_octal_numbers)
1027 && let Ok(v) =
1028 parse_int_signed::<i64>(t, "i64", location, self.cfg.legacy_octal_numbers)
1029 {
1030 return visitor.visit_i64(v);
1031 }
1032 } else {
1033 if let Ok(v) =
1034 parse_int_unsigned::<u64>(t, "u64", location, self.cfg.legacy_octal_numbers)
1035 {
1036 return visitor.visit_u64(v);
1037 }
1038 }
1039
1040 if let Some(v) = try_parse_float_incl_overflow(
1043 &effective,
1044 location,
1045 view.tag,
1046 self.cfg.angle_conversions,
1047 ) {
1048 return self.visit_typeless_float(v, view.raw.into_owned(), location, visitor);
1049 }
1050
1051 return match effective {
1054 Cow::Borrowed(b) => visitor.visit_borrowed_str(b),
1055 Cow::Owned(s) => visitor.visit_string(s),
1056 };
1057 }
1058
1059 match self.ev.peek()? {
1060 Some(Ev::SeqStart { .. }) => self.deserialize_seq(visitor),
1061 Some(Ev::MapStart { .. }) => self.deserialize_map(visitor),
1062 Some(Ev::RecursiveAlias { location, .. }) => {
1063 Err(Error::RecursiveReferencesRequireWeakTypes {
1064 location: *location,
1065 })
1066 }
1067 Some(Ev::SeqEnd { location }) => Err(Error::UnexpectedSequenceEnd {
1068 location: *location,
1069 }),
1070 Some(Ev::MapEnd { location }) => Err(Error::UnexpectedMappingEnd {
1071 location: *location,
1072 }),
1073 None => {
1074 visitor.visit_unit()
1077 }
1078 Some(Ev::Taken { location }) => {
1079 Err(Error::unexpected("consumed event").with_location(*location))
1080 }
1081 Some(Ev::Scalar { location, .. }) => {
1082 Err(Error::unexpected("scalar").with_location(*location))
1083 }
1084 }
1085 }
1086
1087 fn deserialize_bool<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1092 let (s, tag, location) = self.take_scalar_cow_event()?;
1093 self.validate_scalar_tag(tag, SfTag::Bool, "boolean", location)?;
1094 let s = s.as_ref();
1095 let b: bool = if self.cfg.strict_booleans {
1096 parse_yaml12_bool(s).ok_or(Error::InvalidBooleanStrict { location })?
1097 } else {
1098 parse_yaml11_bool(s).ok_or(Error::InvalidScalar {
1099 ty: "boolean",
1100 location,
1101 })?
1102 };
1103 visitor.visit_bool(b)
1104 }
1105
1106 fn deserialize_i8<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1108 let (s, tag, location) = self.take_scalar_cow_event()?;
1109 self.validate_scalar_tag(tag, SfTag::Int, "i8", location)?;
1110 let v: i8 = parse_int_signed(s.as_ref(), "i8", location, self.cfg.legacy_octal_numbers)?;
1111 visitor.visit_i8(v)
1112 }
1113 fn deserialize_i16<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1115 let (s, tag, location) = self.take_scalar_cow_event()?;
1116 self.validate_scalar_tag(tag, SfTag::Int, "i16", location)?;
1117 let v: i16 = parse_int_signed(s.as_ref(), "i16", location, self.cfg.legacy_octal_numbers)?;
1118 visitor.visit_i16(v)
1119 }
1120 fn deserialize_i32<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1122 let (s, tag, location) = self.take_scalar_cow_event()?;
1123 self.validate_scalar_tag(tag, SfTag::Int, "i32", location)?;
1124 let v: i32 = parse_int_signed(s.as_ref(), "i32", location, self.cfg.legacy_octal_numbers)?;
1125 visitor.visit_i32(v)
1126 }
1127 fn deserialize_i64<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1129 let (s, tag, location) = self.take_scalar_cow_event()?;
1130 self.validate_scalar_tag(tag, SfTag::Int, "i64", location)?;
1131 let v: i64 = parse_int_signed(s.as_ref(), "i64", location, self.cfg.legacy_octal_numbers)?;
1132 visitor.visit_i64(v)
1133 }
1134 fn deserialize_i128<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1136 let (s, tag, location) = self.take_scalar_cow_event()?;
1137 self.validate_scalar_tag(tag, SfTag::Int, "i128", location)?;
1138 let v: i128 =
1139 parse_int_signed(s.as_ref(), "i128", location, self.cfg.legacy_octal_numbers)?;
1140 visitor.visit_i128(v)
1141 }
1142
1143 fn deserialize_u8<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1145 let (s, tag, location) = self.take_scalar_cow_event()?;
1146 self.validate_scalar_tag(tag, SfTag::Int, "u8", location)?;
1147 let v: u8 = parse_int_unsigned(s.as_ref(), "u8", location, self.cfg.legacy_octal_numbers)?;
1148 visitor.visit_u8(v)
1149 }
1150 fn deserialize_u16<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1152 let (s, tag, location) = self.take_scalar_cow_event()?;
1153 self.validate_scalar_tag(tag, SfTag::Int, "u16", location)?;
1154 let v: u16 =
1155 parse_int_unsigned(s.as_ref(), "u16", location, self.cfg.legacy_octal_numbers)?;
1156 visitor.visit_u16(v)
1157 }
1158 fn deserialize_u32<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1160 let (s, tag, location) = self.take_scalar_cow_event()?;
1161 self.validate_scalar_tag(tag, SfTag::Int, "u32", location)?;
1162 let v: u32 =
1163 parse_int_unsigned(s.as_ref(), "u32", location, self.cfg.legacy_octal_numbers)?;
1164 visitor.visit_u32(v)
1165 }
1166 fn deserialize_u64<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1168 let (s, tag, location) = self.take_scalar_cow_event()?;
1169 self.validate_scalar_tag(tag, SfTag::Int, "u64", location)?;
1170 let v: u64 =
1171 parse_int_unsigned(s.as_ref(), "u64", location, self.cfg.legacy_octal_numbers)?;
1172 visitor.visit_u64(v)
1173 }
1174 fn deserialize_u128<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1176 let (s, tag, location) = self.take_scalar_cow_event()?;
1177 self.validate_scalar_tag(tag, SfTag::Int, "u128", location)?;
1178 let v: u128 =
1179 parse_int_unsigned(s.as_ref(), "u128", location, self.cfg.legacy_octal_numbers)?;
1180 visitor.visit_u128(v)
1181 }
1182
1183 fn deserialize_f32<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1185 let (s, tag, location) = self.take_scalar_cow_event()?;
1186 self.validate_scalar_tag(tag, SfTag::Float, "floating point", location)?;
1187 let v: f32 = parse_yaml12_float(s.as_ref(), location, tag, self.cfg.angle_conversions)?;
1188 visitor.visit_f32(v)
1189 }
1190 fn deserialize_f64<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1192 let (s, tag, location) = self.take_scalar_cow_event()?;
1193 self.validate_scalar_tag(tag, SfTag::Float, "floating point", location)?;
1194 let v: f64 = parse_yaml12_float(s.as_ref(), location, tag, self.cfg.angle_conversions)?;
1195 visitor.visit_f64(v)
1196 }
1197
1198 fn deserialize_char<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1206 if let Some(view) = self.peek_scalar_view()?
1208 && !view.tag.forces_string()
1209 {
1210 if view.tag == SfTag::Null || scalar_is_nullish(&view.effective, &view.style) {
1212 let (_value, _tag, location) = self.take_scalar_event()?;
1213 return Err(Error::InvalidCharNull { location });
1214 } else if self.cfg.no_schema
1215 && maybe_not_string(&view.effective, &view.style, self.cfg.strict_booleans)
1216 {
1217 let view = self.take_scalar_view()?;
1219 return Err(Self::quoting_required_for_scalar(&view));
1220 }
1221 }
1222
1223 let (s, tag, location) = self.take_scalar_cow_event()?;
1225 self.validate_scalar_tag(tag, SfTag::String, "char", location)?;
1226 let mut it = s.as_ref().chars();
1227 match (it.next(), it.next()) {
1228 (Some(c), None) => visitor.visit_char(c),
1229 _ => Err(Error::InvalidCharNotSingleScalar { location }),
1230 }
1231 }
1232
1233 fn deserialize_str<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1246 let view = match self.peek_scalar_view()? {
1247 Some(view) => {
1248 if (view.tag == SfTag::Null
1251 || (!view.interpolated && scalar_is_nullish(&view.effective, &view.style)))
1252 && !view.tag.forces_string()
1253 {
1254 let loc = view.location;
1255 let _ = self.ev.next()?;
1256 return Err(Error::NullIntoString { location: loc });
1257 } else if self.cfg.no_schema
1258 && maybe_not_string(&view.effective, &view.style, self.cfg.strict_booleans)
1259 && !view.tag.forces_string()
1260 {
1261 let view = self.take_scalar_view()?;
1262 return Err(Self::quoting_required_for_scalar(&view));
1263 }
1264
1265 if view.tag == SfTag::Binary && !self.cfg.ignore_binary_tag_for_string {
1266 let res: Result<V::Value, Self::Error> =
1267 visitor.visit_string(self.take_string_scalar()?);
1268 return match res {
1269 Ok(v) => Ok(v),
1270 Err(err) if err.to_string().contains("expected a borrowed string") => Err(
1271 Error::cannot_borrow_transformed(TransformReason::ParserReturnedOwned)
1272 .with_location(view.location),
1273 ),
1274 Err(err) => Err(err),
1275 };
1276 }
1277 if !(view.tag.can_parse_into_string()
1278 || self.cfg.ignore_binary_tag_for_string && view.tag == SfTag::Binary)
1279 {
1280 return Err(Error::TaggedScalarCannotDeserializeIntoString {
1281 location: view.location,
1282 });
1283 }
1284
1285 view
1286 }
1287 None => {
1289 return Err(self
1290 .take_scalar_view()
1291 .err()
1292 .unwrap_or_else(|| eof_with_loc(self.ev)));
1293 }
1294 };
1295
1296 let location = view.location;
1297 let redaction_ctx = view.redaction_ctx();
1298 let cannot_borrow_reason = if view.interpolated {
1299 TransformReason::VariableInterpolation
1300 } else if self.ev.input_for_borrowing().is_none() {
1301 TransformReason::InputNotBorrowable
1302 } else {
1303 TransformReason::ParserReturnedOwned
1304 };
1305
1306 let view = self.take_peeked_scalar_view(view)?;
1307 if let Cow::Borrowed(b) = view.effective {
1308 return visitor.visit_borrowed_str(b);
1309 }
1310
1311 let res: Result<V::Value, Self::Error> = with_scalar_redaction(redaction_ctx, || {
1312 visitor.visit_string(view.effective.into_owned())
1313 });
1314 match res {
1315 Ok(v) => Ok(v),
1316 Err(err) => {
1317 let msg = err.to_string();
1318 if msg.contains("expected a borrowed string") {
1319 return Err(Error::cannot_borrow_transformed(cannot_borrow_reason)
1320 .with_location(location));
1321 }
1322 Err(err)
1323 }
1324 }
1325 }
1326
1327 fn deserialize_string<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1336 let view = if let Some(view) = self.peek_scalar_view()? {
1338 if (view.tag == SfTag::Null
1341 || (!view.interpolated && scalar_is_nullish(&view.effective, &view.style)))
1342 && !view.tag.forces_string()
1343 {
1344 let (_value, _tag, location) = self.take_scalar_event()?;
1346 return Err(Error::NullIntoString { location });
1347 } else if self.cfg.no_schema
1348 && maybe_not_string(&view.effective, &view.style, self.cfg.strict_booleans)
1349 && !view.tag.forces_string()
1350 {
1351 let view = self.take_scalar_view()?;
1353 return Err(Self::quoting_required_for_scalar(&view));
1354 }
1355 if view.tag == SfTag::Binary && !self.cfg.ignore_binary_tag_for_string {
1356 return visitor.visit_string(self.take_string_scalar()?);
1357 }
1358 if !(view.tag.can_parse_into_string()
1359 || self.cfg.ignore_binary_tag_for_string && view.tag == SfTag::Binary)
1360 {
1361 return Err(Error::TaggedScalarCannotDeserializeIntoString {
1362 location: view.location,
1363 });
1364 }
1365
1366 view
1367 } else {
1368 return visitor.visit_string(self.take_string_scalar()?);
1370 };
1371
1372 let redaction_ctx = view.redaction_ctx();
1373 let view = self.take_peeked_scalar_view(view)?;
1374 match view.effective {
1375 Cow::Borrowed(b) => {
1376 with_scalar_redaction(redaction_ctx, || visitor.visit_borrowed_str(b))
1377 }
1378 Cow::Owned(s) => with_scalar_redaction(redaction_ctx, || visitor.visit_string(s)),
1379 }
1380 }
1381
1382 fn deserialize_bytes<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1388 if let Some((_value, tag, _style, location)) = self.peek_effective_scalar()? {
1389 if tag == SfTag::Binary {
1390 let (value, data_location) = match self.ev.next()? {
1391 Some(Ev::Scalar {
1392 value, location, ..
1393 }) => (value, location),
1394 Some(other) => {
1395 return Err(
1396 Error::unexpected("binary scalar").with_location(other.location())
1397 );
1398 }
1399 None => return Err(eof_with_loc(self.ev)),
1400 };
1401 let data =
1402 decode_base64_yaml(&value).map_err(|err| err.with_location(data_location))?;
1403 return visitor.visit_byte_buf(data);
1404 }
1405 return Err(Error::BytesNotSupportedMissingBinaryTag { location });
1406 }
1407
1408 match self.ev.peek()? {
1409 Some(Ev::SeqStart { .. }) => {
1411 self.expect_seq_start()?;
1412 let mut out = Vec::new();
1413 loop {
1414 match self.ev.peek()? {
1415 Some(Ev::SeqEnd { .. }) => {
1416 let _ = self.ev.next()?; break;
1418 }
1419 Some(_) => {
1420 let b: u8 = <u8 as serde_core::Deserialize>::deserialize(
1422 YamlDeserializer::new(&mut *self.ev, self.cfg),
1423 )?;
1424 out.push(b);
1425 }
1426 None => return Err(eof_with_loc(self.ev)),
1427 }
1428 }
1429 visitor.visit_byte_buf(out)
1430 }
1431
1432 Some(other) => Err(
1434 Error::unexpected("scalar (!!binary) or sequence of 0..=255")
1435 .with_location(other.location()),
1436 ),
1437 None => Err(eof_with_loc(self.ev)),
1438 }
1439 }
1440
1441 fn deserialize_byte_buf<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
1443 self.deserialize_bytes(visitor)
1444 }
1445
1446 fn deserialize_option<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1453 if self.in_key && self.key_empty_map_node {
1458 match self.ev.next()? {
1460 Some(Ev::MapStart { .. }) => {}
1461 Some(other) => {
1462 return Err(
1463 Error::unexpected("empty mapping start").with_location(other.location())
1464 );
1465 }
1466 None => return Err(eof_with_loc(self.ev)),
1467 }
1468 match self.ev.next()? {
1469 Some(Ev::MapEnd { .. }) => {}
1470 Some(other) => {
1471 return Err(
1472 Error::unexpected("empty mapping end").with_location(other.location())
1473 );
1474 }
1475 None => return Err(eof_with_loc(self.ev)),
1476 }
1477 return visitor.visit_none();
1478 }
1479
1480 if let Some((value, tag, style, _location)) = self.peek_effective_scalar()?
1481 && scalar_is_null(&tag, &value, &style)
1482 {
1483 let _ = self.ev.next()?; return visitor.visit_none();
1485 }
1486
1487 match self.ev.peek()? {
1488 None | Some(Ev::MapEnd { .. } | Ev::SeqEnd { .. }) => visitor.visit_none(),
1490
1491 Some(_) => visitor.visit_some(self),
1493 }
1494 }
1495
1496 fn deserialize_unit<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1504 if let Some((value, tag, style, _location)) = self.peek_effective_scalar()?
1505 && scalar_is_null(&tag, &value, &style)
1506 {
1507 let _ = self.ev.next()?; return visitor.visit_unit();
1509 }
1510
1511 match self.ev.peek()? {
1512 None | Some(Ev::MapEnd { .. } | Ev::SeqEnd { .. }) => visitor.visit_unit(),
1514 Some(other) => Err(Error::UnexpectedValueForUnit {
1516 location: other.location(),
1517 }),
1518 }
1519 }
1520
1521 fn deserialize_unit_struct<V: Visitor<'de>>(
1530 self,
1531 _name: &'static str,
1532 visitor: V,
1533 ) -> Result<V::Value, Self::Error> {
1534 match self.ev.peek()? {
1535 Some(Ev::MapStart { .. }) => {
1537 let _ = self.ev.next()?; match self.ev.peek()? {
1539 Some(Ev::MapEnd { .. }) => {
1540 let _ = self.ev.next()?; visitor.visit_unit()
1542 }
1543 Some(other) => Err(Error::ExpectedEmptyMappingForUnitStruct {
1544 location: other.location(),
1545 }),
1546 None => Err(eof_with_loc(self.ev)),
1547 }
1548 }
1549 _ => self.deserialize_unit(visitor),
1551 }
1552 }
1553
1554 fn deserialize_newtype_struct<V: Visitor<'de>>(
1564 mut self,
1565 n: &'static str,
1566 visitor: V,
1567 ) -> Result<V::Value, Self::Error> {
1568 match n {
1569 "__yaml_spanned" => spanned_deser::deserialize_yaml_spanned(self, visitor),
1571 #[cfg(feature = "comments")]
1572 "__yaml_commented" => commented_deser::deserialize_yaml_commented(self, visitor),
1573 "__yaml_tagged" => tagged_deser::deserialize_yaml_tagged(self, visitor),
1574 "__yaml_rc_anchor" => {
1575 let anchor = self.peek_anchor_id()?;
1576 anchor_store::with_anchor_context(AnchorKind::Rc, anchor, || {
1577 visitor.visit_newtype_struct(self)
1578 })
1579 }
1580 "__yaml_arc_anchor" => {
1581 let anchor = self.peek_anchor_id()?;
1582 anchor_store::with_anchor_context(AnchorKind::Arc, anchor, || {
1583 visitor.visit_newtype_struct(self)
1584 })
1585 }
1586 "__yaml_rc_recursive" => {
1587 let anchor = self.peek_anchor_id()?;
1588 anchor_store::with_anchor_context(AnchorKind::RcRecursive, anchor, || {
1589 visitor.visit_newtype_struct(self)
1590 })
1591 }
1592 "__yaml_arc_recursive" => {
1593 let anchor = self.peek_anchor_id()?;
1594 anchor_store::with_anchor_context(AnchorKind::ArcRecursive, anchor, || {
1595 visitor.visit_newtype_struct(self)
1596 })
1597 }
1598 "__yaml_rc_weak_anchor" => {
1599 let anchor = self.peek_anchor_id()?;
1600 anchor_store::with_anchor_context(AnchorKind::Rc, anchor, || {
1601 visitor.visit_newtype_struct(self)
1602 })
1603 }
1604 "__yaml_arc_weak_anchor" => {
1605 let anchor = self.peek_anchor_id()?;
1606 anchor_store::with_anchor_context(AnchorKind::Arc, anchor, || {
1607 visitor.visit_newtype_struct(self)
1608 })
1609 }
1610 "__yaml_rc_recursion" => {
1611 let anchor = self.peek_anchor_id()?;
1612 anchor_store::with_anchor_context(AnchorKind::RcRecursive, anchor, || {
1613 visitor.visit_newtype_struct(self)
1614 })
1615 }
1616 "__yaml_arc_recursion" => {
1617 let anchor = self.peek_anchor_id()?;
1618 anchor_store::with_anchor_context(AnchorKind::ArcRecursive, anchor, || {
1619 visitor.visit_newtype_struct(self)
1620 })
1621 }
1622 _ => visitor.visit_newtype_struct(self),
1623 }
1624 }
1625
1626 fn deserialize_seq<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1633 if self.ev.take_empty_stream()? {
1634 return visitor.visit_seq(de::value::SeqDeserializer::<_, Error>::new(
1635 std::iter::empty::<()>(),
1636 ));
1637 }
1638 if let Some((_, SfTag::Binary, _, _)) = self.peek_effective_scalar()? {
1639 let (scalar, data_location) = match self.ev.next()? {
1640 Some(Ev::Scalar {
1641 value, location, ..
1642 }) => (value, location),
1643 Some(other) => {
1644 return Err(Error::unexpected("binary scalar").with_location(other.location()));
1645 }
1646 None => return Err(eof_with_loc(self.ev)),
1647 };
1648 let data =
1649 decode_base64_yaml(&scalar).map_err(|err| err.with_location(data_location))?;
1650 struct ByteSeq {
1652 data: Vec<u8>,
1653 idx: usize,
1654 }
1655 impl<'de> de::SeqAccess<'de> for ByteSeq {
1656 type Error = Error;
1657 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
1658 where
1659 T: de::DeserializeSeed<'de>,
1660 {
1661 if self.idx >= self.data.len() {
1662 return Ok(None);
1663 }
1664 let b = self.data[self.idx];
1665 self.idx += 1;
1666 let deser = serde_core::de::value::U8Deserializer::<Error>::new(b);
1667 seed.deserialize(deser).map(Some)
1668 }
1669 }
1670 return visitor.visit_seq(ByteSeq { data, idx: 0 });
1671 }
1672 let mut seq_start_comments = std::mem::take(&mut self.pending_value_comments);
1677 seq_start_comments.extend(self.ev.take_leading_comments_for_next_node()?);
1678 let seq_location = match self.ev.peek()? {
1679 Some(ev) => ev.location(),
1680 None => self.ev.last_location(),
1681 };
1682 let child_cfg = self.cfg.enter_container(seq_location)?;
1683 self.expect_seq_start()?;
1684 struct SA<'de, 'e> {
1686 ev: &'e mut dyn Events<'de>,
1687 cfg: Cfg,
1688 pending_first_element_comments: Vec<Cow<'de, str>>,
1689
1690 #[cfg(any(feature = "garde", feature = "validator"))]
1691 garde: Option<&'e mut PathRecorder>,
1692 #[cfg(any(feature = "garde", feature = "validator"))]
1693 idx: usize,
1694 }
1695 impl<'de> de::SeqAccess<'de> for SA<'de, '_> {
1696 type Error = Error;
1697 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
1699 where
1700 T: de::DeserializeSeed<'de>,
1701 {
1702 let (is_end, defined_location) = {
1703 let peeked = self.ev.peek()?;
1704 match peeked {
1705 Some(Ev::SeqEnd { .. }) => (true, Location::UNKNOWN),
1706 Some(ev) => (false, ev.location()),
1707 None => return Err(eof_with_loc(self.ev)),
1708 }
1709 };
1710
1711 if is_end {
1712 return Ok(None);
1713 }
1714
1715 let reference_location = self.ev.reference_location();
1717 let alias_reference_location = self.ev.alias_reference_location();
1718 let _missing_field_guard = MissingFieldLocationGuard::new(reference_location);
1719 let mut item_comments = std::mem::take(&mut self.pending_first_element_comments);
1720 item_comments.extend(self.ev.take_leading_comments_for_next_node()?);
1721 let value_separator_comments = self
1722 .ev
1723 .take_separator_comments_before_sequence_item_value()?;
1724
1725 #[cfg(any(feature = "garde", feature = "validator"))]
1726 {
1727 if let Some(garde_ref) = self.garde.as_mut() {
1728 let recorder: &mut PathRecorder = garde_ref;
1729
1730 let prev = recorder.current.take();
1731 let now = prev.clone().join(self.idx);
1732 recorder.current = now.clone();
1733 recorder.map.insert(
1734 now,
1735 Locations {
1736 reference_location,
1737 defined_location,
1738 },
1739 );
1740
1741 let mut de =
1742 YamlDeserializer::new_with_path_recorder(self.ev, self.cfg, recorder);
1743 de.pending_comments = item_comments;
1744 de.pending_value_separator_comments = value_separator_comments;
1745 let redaction_ctx = de.peek_scalar_redaction_ctx()?;
1746 let res = with_subtree_redaction(redaction_ctx, || seed.deserialize(de))
1747 .map(Some)
1748 .map_err(|e| {
1749 attach_alias_locations_if_missing(
1750 e,
1751 alias_reference_location,
1752 defined_location,
1753 )
1754 });
1755
1756 recorder.current = prev;
1757 self.idx += 1;
1758 return res;
1759 }
1760 }
1761
1762 let mut de = YamlDeserializer::new(self.ev, self.cfg);
1763 de.pending_comments = item_comments;
1764 de.pending_value_separator_comments = value_separator_comments;
1765 let redaction_ctx = de.peek_scalar_redaction_ctx()?;
1766 with_subtree_redaction(redaction_ctx, || seed.deserialize(de))
1767 .map(Some)
1768 .map_err(|e| {
1769 attach_alias_locations_if_missing(
1770 e,
1771 alias_reference_location,
1772 defined_location,
1773 )
1774 })
1775 }
1776 }
1777
1778 #[cfg(any(feature = "garde", feature = "validator"))]
1779 let garde = self.garde;
1780
1781 let result = visitor.visit_seq(SA {
1782 ev: self.ev,
1783 cfg: child_cfg,
1784 pending_first_element_comments: seq_start_comments,
1785
1786 #[cfg(any(feature = "garde", feature = "validator"))]
1787 garde,
1788 #[cfg(any(feature = "garde", feature = "validator"))]
1789 idx: 0,
1790 })?;
1791 drain_remaining_sequence(self.ev)?;
1792 Ok(result)
1793 }
1794
1795 fn deserialize_tuple<V: Visitor<'de>>(
1797 self,
1798 len: usize,
1799 visitor: V,
1800 ) -> Result<V::Value, Self::Error> {
1801 self.deserialize_seq(TupleLenVisitor {
1802 inner: visitor,
1803 len,
1804 })
1805 }
1806
1807 fn deserialize_tuple_struct<V: Visitor<'de>>(
1809 self,
1810 _name: &'static str,
1811 len: usize,
1812 visitor: V,
1813 ) -> Result<V::Value, Self::Error> {
1814 self.deserialize_seq(TupleLenVisitor {
1815 inner: visitor,
1816 len,
1817 })
1818 }
1819
1820 fn deserialize_map<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
1830 if self.ev.take_empty_stream()? {
1831 struct EmptyMap {
1832 location: Location,
1833 }
1834 impl<'de> de::MapAccess<'de> for EmptyMap {
1835 type Error = Error;
1836
1837 fn next_key_seed<K>(&mut self, _seed: K) -> Result<Option<K::Value>, Error>
1838 where
1839 K: de::DeserializeSeed<'de>,
1840 {
1841 Ok(None)
1842 }
1843
1844 fn next_value_seed<V>(&mut self, _seed: V) -> Result<V::Value, Error>
1845 where
1846 V: de::DeserializeSeed<'de>,
1847 {
1848 Err(Error::ValueRequestedBeforeKey {
1849 location: self.location,
1850 })
1851 }
1852 }
1853 return visitor.visit_map(EmptyMap {
1854 location: self.ev.last_location(),
1855 });
1856 }
1857 let _map_node_comments = std::mem::take(&mut self.pending_value_separator_comments);
1861 let mut map_start_comments = std::mem::take(&mut self.pending_value_comments);
1866 map_start_comments.extend(self.ev.take_leading_comments_for_next_node()?);
1867 let map_location = match self.ev.peek()? {
1868 Some(ev) => ev.location(),
1869 None => self.ev.last_location(),
1870 };
1871 let map_reference_location = self.ev.reference_location();
1872 let child_cfg = self.cfg.enter_container(map_location)?;
1873 self.expect_map_start()?;
1874
1875 let _missing_field_guard = MissingFieldLocationGuard::new(map_reference_location);
1878
1879 #[cfg(any(feature = "garde", feature = "validator"))]
1880 if let Some(recorder) = self.garde.as_mut() {
1881 let path = recorder.current.clone();
1884 recorder.map.insert(
1885 path,
1886 Locations {
1887 reference_location: map_reference_location,
1888 defined_location: map_location,
1889 },
1890 );
1891 }
1892
1893 fn collect_last_wins_entries<'de>(
1894 ev: &mut dyn Events<'de>,
1895 mut first_key_comments: Vec<Cow<'de, str>>,
1896 cfg: Cfg,
1897 mut first_key: Option<KeyNode<'de>>,
1898 prior_seen: &HashSet<KeyFingerprint<'de>>,
1899 mut merge_batches: VecDeque<Vec<PendingEntry<'de>>>,
1900 ) -> Result<VecDeque<PendingEntry<'de>>, Error> {
1901 with_deferred_recursive_aliases(ev, |ev| {
1902 let mut explicit_entries = Vec::new();
1903
1904 loop {
1905 let (key, field_comments) = if let Some(key) = first_key.take() {
1906 (key, std::mem::take(&mut first_key_comments))
1907 } else {
1908 match ev.peek()? {
1909 Some(Ev::MapEnd { .. }) => {
1910 let _ = ev.next()?;
1911 break;
1912 }
1913 Some(_) => {
1914 let mut key_comments = std::mem::take(&mut first_key_comments);
1915 key_comments.extend(ev.take_leading_comments_for_next_node()?);
1916 let key =
1917 capture_node_with_legacy_octal(ev, cfg.legacy_octal_numbers)?;
1918 (key, key_comments)
1919 }
1920 None => return Err(eof_with_loc(ev)),
1921 }
1922 };
1923
1924 if is_merge_key(&key) {
1925 match cfg.merge_keys {
1926 MergeKeyPolicy::Merge => {
1927 let _ = ev.peek()?;
1928 let merge_ref_loc = ev.reference_location();
1929 let entries =
1930 pending_entries_from_live_events(ev, merge_ref_loc, cfg)?;
1931 if !entries.is_empty() {
1932 merge_batches.push_back(entries);
1933 }
1934 continue;
1935 }
1936 MergeKeyPolicy::AsOrdinary => {}
1937 MergeKeyPolicy::Error => {
1938 return Err(Error::MergeKeyNotAllowed {
1939 location: key.location(),
1940 });
1941 }
1942 }
1943 }
1944
1945 if cfg.reject_tagged_field_names {
1946 key.validate_field_name_tag()?;
1947 }
1948 let value_separator_comments =
1949 ev.take_separator_comments_before_mapping_value()?;
1950 let value_comments = ev.take_leading_comments_for_next_node()?;
1951 let _ = ev.peek()?;
1954 let reference_location = ev.reference_location();
1955 let value = capture_node_with_legacy_octal(ev, cfg.legacy_octal_numbers)?;
1956 explicit_entries.push(PendingEntry {
1957 key,
1958 value,
1959 reference_location,
1960 field_comments,
1961 value_separator_comments,
1962 value_comments,
1963 });
1964 }
1965
1966 let mut explicit_entries = apply_duplicate_key_policy_to_entries(
1967 explicit_entries,
1968 cfg.dup_policy,
1969 cfg.merge_keys,
1970 )?;
1971 let mut seen = prior_seen.clone();
1972 seen.reserve(explicit_entries.len());
1973 for entry in &explicit_entries {
1974 seen.insert(entry.key.fingerprint().into_owned());
1975 }
1976
1977 let mut merge_entries = Vec::new();
1978 for batch in merge_batches {
1979 for entry in batch {
1980 let fingerprint = entry.key.fingerprint().into_owned();
1981 if seen.insert(fingerprint) {
1982 merge_entries.push(entry);
1983 }
1984 }
1985 }
1986
1987 explicit_entries.extend(merge_entries);
1988 Ok(explicit_entries.into_iter().collect())
1989 })
1990 }
1991
1992 struct MA<'de, 'e> {
1994 ev: &'e mut dyn Events<'de>,
1995 cfg: Cfg,
1996 struct_mode: bool,
1997 have_key: bool,
1998
1999 fallback_guard: Option<MissingFieldLocationGuard>,
2003
2004 #[cfg(any(feature = "garde", feature = "validator"))]
2005 garde: Option<&'e mut PathRecorder>,
2006 #[cfg(any(feature = "garde", feature = "validator"))]
2007 pending_path_segment: Option<String>,
2008
2009 seen: HashSet<KeyFingerprint<'de>>,
2011 pending: VecDeque<PendingEntry<'de>>,
2012 merge_stack: VecDeque<Vec<PendingEntry<'de>>>,
2013 flushing_merges: bool,
2014 live_done: bool,
2015 pending_value: Option<Box<(RecordedEvents<'de>, Location)>>,
2016 pending_field_comments: Vec<Cow<'de, str>>,
2017 pending_value_separator_comments: Vec<Cow<'de, str>>,
2018 pending_value_comments: Vec<Cow<'de, str>>,
2019 pending_first_key_comments: Vec<Cow<'de, str>>,
2020 }
2021
2022 impl<'de> MA<'de, '_> {
2023 fn skip_one_node(&mut self) -> Result<(), Error> {
2028 if self.cfg.merge_keys == MergeKeyPolicy::Error {
2029 let node =
2030 capture_node_with_legacy_octal(self.ev, self.cfg.legacy_octal_numbers)?;
2031 return validate_no_merge_keys_in_node_events(node.events());
2032 }
2033
2034 let mut depth; match self.ev.next()? {
2036 Some(Ev::RecursiveAlias { location, .. }) => {
2037 return Err(Error::RecursiveReferencesRequireWeakTypes { location });
2038 }
2039 Some(Ev::Scalar { .. }) => return Ok(()),
2040 Some(Ev::SeqStart { .. } | Ev::MapStart { .. }) => depth = 1,
2041 Some(Ev::SeqEnd { location } | Ev::MapEnd { location }) => {
2042 return Err(Error::UnexpectedContainerEndWhileSkippingNode { location });
2043 }
2044 Some(Ev::Taken { location }) => {
2045 return Err(Error::unexpected("consumed event").with_location(location));
2046 }
2047 None => return Err(eof_with_loc(self.ev)),
2048 }
2049 while depth != 0 {
2050 match self.ev.next()? {
2051 Some(Ev::RecursiveAlias { location, .. }) => {
2052 return Err(Error::RecursiveReferencesRequireWeakTypes { location });
2053 }
2054 Some(Ev::SeqStart { .. } | Ev::MapStart { .. }) => depth += 1,
2055 Some(Ev::SeqEnd { .. } | Ev::MapEnd { .. }) => depth -= 1,
2056 Some(Ev::Scalar { .. }) => {}
2057 Some(Ev::Taken { location }) => {
2058 return Err(Error::unexpected("consumed event").with_location(location));
2059 }
2060 None => return Err(eof_with_loc(self.ev)),
2061 }
2062 }
2063 Ok(())
2064 }
2065
2066 fn validate_skipped_node(&self, node: &KeyNode<'_>) -> Result<(), Error> {
2067 if self.cfg.merge_keys == MergeKeyPolicy::Error {
2068 validate_no_merge_keys_in_node_events(node.events())?;
2069 }
2070 Ok(())
2071 }
2072
2073 fn deserialize_recorded_key<'de2, K>(
2079 &mut self,
2080 seed: K,
2081 events: RecordedEvents<'de2>,
2082 kemn: bool,
2083 ) -> Result<K::Value, Error>
2084 where
2085 K: de::DeserializeSeed<'de2>,
2086 {
2087 let mut replay = ReplayEvents::new(
2088 events,
2089 #[cfg(feature = "properties")]
2090 self.ev.property_interpolation().for_key(),
2091 );
2092
2093 let location = replay.reference_location();
2095
2096 let de = YamlDeserializer::<'de2, '_> {
2097 ev: &mut replay,
2098 cfg: self.cfg,
2099 in_key: true,
2100 struct_mode: false,
2101 key_empty_map_node: kemn,
2102 pending_comments: Vec::new(),
2103 pending_value_separator_comments: Vec::new(),
2104 pending_value_comments: Vec::new(),
2105
2106 #[cfg(any(feature = "garde", feature = "validator"))]
2107 garde: None,
2108 };
2109 seed.deserialize(de).map_err(|e| {
2110 if e.location().is_none() {
2111 e.with_location(location)
2112 } else {
2113 e
2114 }
2115 })
2116 }
2117
2118 fn enqueue_entries(&mut self, entries: Vec<PendingEntry<'de>>) {
2120 self.pending.reserve(entries.len());
2121 for entry in entries.into_iter().rev() {
2122 self.pending.push_front(entry);
2123 }
2124 }
2125
2126 fn enqueue_next_merge_batch(&mut self) -> bool {
2128 while let Some(entries) = self.merge_stack.pop_front() {
2129 if entries.is_empty() {
2130 continue;
2131 }
2132 self.enqueue_entries(entries);
2133 return true;
2134 }
2135 false
2136 }
2137
2138 fn finish(&mut self) -> Result<(), Error> {
2144 if self.have_key {
2145 return Err(
2146 Error::unexpected("mapping end").with_location(self.ev.last_location())
2147 );
2148 }
2149
2150 if de::MapAccess::next_key::<de::IgnoredAny>(self)?.is_some() {
2151 return Err(
2152 Error::unexpected("mapping end").with_location(self.ev.last_location())
2153 );
2154 }
2155
2156 Ok(())
2157 }
2158 }
2159
2160 impl<'de> de::MapAccess<'de> for MA<'de, '_> {
2161 type Error = Error;
2162
2163 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
2165 where
2166 K: de::DeserializeSeed<'de>,
2167 {
2168 let mut seed = Some(seed);
2169
2170 loop {
2171 if let Some(entry) = self.pending.pop_front() {
2172 let PendingEntry {
2173 mut key,
2174 mut value,
2175 reference_location,
2176 field_comments,
2177 value_separator_comments,
2178 value_comments,
2179 } = entry;
2180 let fingerprint = key.take_fingerprint();
2181 let location = key.location();
2182
2183 let is_duplicate = self.seen.contains(&fingerprint);
2184 if self.flushing_merges {
2185 if is_duplicate {
2186 self.validate_skipped_node(&value)?;
2187 continue;
2188 }
2189 } else {
2190 match self.cfg.dup_policy {
2191 DuplicateKeyPolicy::Error => {
2192 if is_duplicate {
2193 let key = key.stringy_scalar_value().map(|s| s.to_owned());
2194 return Err(Error::DuplicateMappingKey { key, location });
2195 }
2196 }
2197 DuplicateKeyPolicy::FirstWins => {
2198 if is_duplicate {
2199 self.validate_skipped_node(&value)?;
2200 continue;
2201 }
2202 }
2203 DuplicateKeyPolicy::LastWins | DuplicateKeyPolicy::PassThrough => {}
2204 }
2205 }
2206
2207 #[cfg(any(feature = "garde", feature = "validator"))]
2208 let key_path_segment = key.stringy_scalar_value().map(ToOwned::to_owned);
2209 let events = key.take_events();
2210 let value_events = value.take_events();
2211 let kemn = is_empty_mapping_key_fingerprint(&fingerprint);
2212 let Some(key_seed) = seed.take() else {
2213 return Err(Error::InternalSeedReusedForMapKey { location });
2214 };
2215
2216 match &mut self.fallback_guard {
2221 Some(guard) => guard.replace_location(location),
2222 None => {
2223 self.fallback_guard =
2224 Some(MissingFieldLocationGuard::new(location));
2225 }
2226 }
2227
2228 let key_value = self.deserialize_recorded_key(key_seed, events, kemn)?;
2229 self.have_key = true;
2230 self.pending_field_comments = field_comments;
2231 self.pending_value_separator_comments = value_separator_comments;
2232 self.pending_value_comments = value_comments;
2233 self.pending_value = Some(Box::new((value_events, reference_location)));
2234
2235 #[cfg(any(feature = "garde", feature = "validator"))]
2236 {
2237 self.pending_path_segment = key_path_segment;
2238 }
2239
2240 if remembers_seen_keys(&self.cfg) {
2241 self.seen.insert(fingerprint);
2242 }
2243 return Ok(Some(key_value));
2244 }
2245
2246 if self.live_done {
2247 return Ok(None);
2248 }
2249
2250 if self.flushing_merges {
2251 if self.enqueue_next_merge_batch() {
2252 continue;
2253 }
2254 self.flushing_merges = false;
2255 self.live_done = true;
2256 return Ok(None);
2257 }
2258
2259 match self.ev.peek()? {
2260 Some(Ev::MapEnd { .. }) => {
2261 let _ = self.ev.next()?; if self.merge_stack.is_empty() {
2263 self.live_done = true;
2264 return Ok(None);
2265 }
2266 self.flushing_merges = true;
2267 if self.enqueue_next_merge_batch() {
2268 continue;
2269 }
2270 self.flushing_merges = false;
2271 self.live_done = true;
2272 return Ok(None);
2273 }
2274 Some(_) => {
2275 let mut key_comments =
2276 std::mem::take(&mut self.pending_first_key_comments);
2277 key_comments.extend(self.ev.take_leading_comments_for_next_node()?);
2278 let mut key_node = capture_node_with_legacy_octal(
2279 self.ev,
2280 self.cfg.legacy_octal_numbers,
2281 )?;
2282 if is_merge_key(&key_node) {
2283 match self.cfg.merge_keys {
2284 MergeKeyPolicy::Merge => {
2285 let _ = self.ev.peek()?;
2290 let merge_ref_loc = self.ev.reference_location();
2291 let entries = pending_entries_from_live_events(
2292 self.ev,
2293 merge_ref_loc,
2294 Cfg {
2295 reject_tagged_field_names: self.struct_mode
2296 && self.cfg.reject_tagged_field_names,
2297 ..self.cfg
2298 },
2299 )?;
2300 if !entries.is_empty() {
2301 self.merge_stack.push_back(entries);
2302 }
2303 continue;
2304 }
2305 MergeKeyPolicy::AsOrdinary => {}
2306 MergeKeyPolicy::Error => {
2307 return Err(Error::MergeKeyNotAllowed {
2308 location: key_node.location(),
2309 });
2310 }
2311 }
2312 }
2313
2314 if self.struct_mode && self.cfg.reject_tagged_field_names {
2315 key_node.validate_field_name_tag()?;
2316 }
2317
2318 if matches!(self.cfg.dup_policy, DuplicateKeyPolicy::LastWins)
2319 && key_node.fingerprint().contains_integer()
2320 {
2321 self.pending = collect_last_wins_entries(
2324 self.ev,
2325 key_comments,
2326 Cfg {
2327 reject_tagged_field_names: self.struct_mode
2328 && self.cfg.reject_tagged_field_names,
2329 ..self.cfg
2330 },
2331 Some(key_node),
2332 &self.seen,
2333 std::mem::take(&mut self.merge_stack),
2334 )?;
2335 self.live_done = true;
2336 continue;
2337 }
2338
2339 let fingerprint = key_node.fingerprint();
2340 let is_duplicate = self.seen.contains(&fingerprint);
2341 match self.cfg.dup_policy {
2342 DuplicateKeyPolicy::Error => {
2343 if is_duplicate {
2344 let location = key_node.location();
2345 let key =
2346 key_node.stringy_scalar_value().map(|s| s.to_owned());
2347 return Err(Error::DuplicateMappingKey { key, location });
2348 }
2349 }
2350 DuplicateKeyPolicy::FirstWins => {
2351 if is_duplicate {
2352 self.skip_one_node()?;
2353 continue;
2354 }
2355 }
2356 DuplicateKeyPolicy::LastWins | DuplicateKeyPolicy::PassThrough => {}
2357 }
2358
2359 let kemn_direct =
2360 is_empty_mapping_key_fingerprint(fingerprint.as_ref());
2361 let fingerprint =
2363 remembers_seen_keys(&self.cfg).then(|| fingerprint.into_owned());
2364 let location = key_node.location();
2365 #[cfg(any(feature = "garde", feature = "validator"))]
2366 let key_path_segment =
2367 key_node.stringy_scalar_value().map(ToOwned::to_owned);
2368 let events = key_node.take_events();
2369 let Some(key_seed) = seed.take() else {
2370 return Err(Error::InternalSeedReusedForMapKey { location });
2371 };
2372
2373 match &mut self.fallback_guard {
2377 Some(guard) => guard.replace_location(location),
2378 None => {
2379 self.fallback_guard =
2380 Some(MissingFieldLocationGuard::new(location));
2381 }
2382 }
2383
2384 let key_value =
2385 self.deserialize_recorded_key(key_seed, events, kemn_direct)?;
2386 self.have_key = true;
2387 self.pending_field_comments = key_comments;
2388 self.pending_value = None; #[cfg(any(feature = "garde", feature = "validator"))]
2391 {
2392 self.pending_path_segment = key_path_segment;
2393 }
2394
2395 if let Some(fingerprint) = fingerprint {
2396 self.seen.insert(fingerprint);
2397 }
2398 return Ok(Some(key_value));
2399 }
2400 None => return Err(eof_with_loc(self.ev)),
2401 }
2402 }
2403 }
2404
2405 fn next_value_seed<Vv>(&mut self, seed: Vv) -> Result<Vv::Value, Error>
2407 where
2408 Vv: de::DeserializeSeed<'de>,
2409 {
2410 if !self.have_key {
2411 return Err(Error::ValueRequestedBeforeKey {
2412 location: self.ev.last_location(),
2413 });
2414 }
2415 self.have_key = false;
2416
2417 #[cfg(any(feature = "garde", feature = "validator"))]
2418 let pending_segment = self.pending_path_segment.take();
2419
2420 let field_comments = std::mem::take(&mut self.pending_field_comments);
2421 let mut value_separator_comments =
2422 std::mem::take(&mut self.pending_value_separator_comments);
2423 let mut value_comments = std::mem::take(&mut self.pending_value_comments);
2424
2425 if let Some(events) = self.pending_value.take() {
2426 let (events, fallback_reference_location) = *events;
2427 let mut replay = ReplayEvents::new(
2430 events,
2431 #[cfg(feature = "properties")]
2432 self.ev.property_interpolation().clone(),
2433 );
2434
2435 let defined_location = match replay.peek()? {
2438 Some(ev) => ev.location(),
2439 None => replay.last_location(),
2440 };
2441 let alias_reference_location = replay.alias_reference_location();
2442 #[cfg(any(feature = "garde", feature = "validator"))]
2443 let reference_location = if defined_location == Location::UNKNOWN {
2444 fallback_reference_location
2445 } else {
2446 replay.reference_location()
2447 };
2448 #[cfg(not(any(feature = "garde", feature = "validator")))]
2449 let _ = fallback_reference_location;
2450
2451 #[cfg(any(feature = "garde", feature = "validator"))]
2452 {
2453 if let (Some(seg), Some(garde_ref)) = (pending_segment, self.garde.as_mut())
2454 {
2455 let recorder: &mut PathRecorder = garde_ref;
2456
2457 let prev = recorder.current.take();
2458 let now = prev.clone().join(seg.as_str());
2459 recorder.current = now.clone();
2460 recorder.map.insert(
2461 now,
2462 Locations {
2463 reference_location,
2464 defined_location,
2465 },
2466 );
2467
2468 let mut de = YamlDeserializer::new_with_path_recorder(
2469 &mut replay,
2470 self.cfg,
2471 recorder,
2472 );
2473 de.pending_comments = field_comments;
2474 de.pending_value_separator_comments = value_separator_comments;
2475 de.pending_value_comments = value_comments;
2476 let redaction_ctx = de.peek_scalar_redaction_ctx()?;
2477 let res =
2478 with_subtree_redaction(redaction_ctx, || seed.deserialize(de))
2479 .map_err(|e| {
2480 attach_alias_locations_if_missing(
2481 e,
2482 alias_reference_location,
2483 defined_location,
2484 )
2485 });
2486 recorder.current = prev;
2487 return res;
2488 }
2489 }
2490
2491 let mut de = YamlDeserializer::new(&mut replay, self.cfg);
2492 de.pending_comments = field_comments;
2493 de.pending_value_separator_comments = value_separator_comments;
2494 de.pending_value_comments = value_comments;
2495 let redaction_ctx = de.peek_scalar_redaction_ctx()?;
2496 with_subtree_redaction(redaction_ctx, || seed.deserialize(de)).map_err(|e| {
2497 attach_alias_locations_if_missing(
2498 e,
2499 alias_reference_location,
2500 defined_location,
2501 )
2502 })
2503 } else {
2504 value_separator_comments
2505 .extend(self.ev.take_separator_comments_before_mapping_value()?);
2506 value_comments.extend(self.ev.take_leading_comments_for_next_node()?);
2507
2508 let defined_location = match self.ev.peek()? {
2510 Some(ev) => ev.location(),
2511 None => self.ev.last_location(),
2512 };
2513
2514 #[cfg(any(feature = "garde", feature = "validator"))]
2515 let reference_location = self.ev.reference_location();
2516 let alias_reference_location = self.ev.alias_reference_location();
2517
2518 #[cfg(any(feature = "garde", feature = "validator"))]
2519 {
2520 if let (Some(seg), Some(garde_ref)) = (pending_segment, self.garde.as_mut())
2521 {
2522 let recorder: &mut PathRecorder = garde_ref;
2523 let prev = recorder.current.take();
2524 let now = prev.clone().join(seg.as_str());
2525 recorder.current = now.clone();
2526 recorder.map.insert(
2527 now,
2528 Locations {
2529 reference_location,
2530 defined_location,
2531 },
2532 );
2533
2534 let mut de = YamlDeserializer::new_with_path_recorder(
2535 self.ev, self.cfg, recorder,
2536 );
2537 de.pending_comments = field_comments;
2538 de.pending_value_separator_comments = value_separator_comments;
2539 de.pending_value_comments = value_comments;
2540 let redaction_ctx = de.peek_scalar_redaction_ctx()?;
2541 let res =
2542 with_subtree_redaction(redaction_ctx, || seed.deserialize(de))
2543 .map_err(|e| {
2544 attach_alias_locations_if_missing(
2545 e,
2546 alias_reference_location,
2547 defined_location,
2548 )
2549 });
2550 recorder.current = prev;
2551 return res;
2552 }
2553 }
2554
2555 let mut de = YamlDeserializer::new(self.ev, self.cfg);
2556 de.pending_comments = field_comments;
2557 de.pending_value_separator_comments = value_separator_comments;
2558 de.pending_value_comments = value_comments;
2559 let redaction_ctx = de.peek_scalar_redaction_ctx()?;
2560 with_scalar_redaction(redaction_ctx, || seed.deserialize(de)).map_err(|e| {
2561 attach_alias_locations_if_missing(
2562 e,
2563 alias_reference_location,
2564 defined_location,
2565 )
2566 })
2567 }
2568 }
2569 }
2570
2571 let (pending, pending_first_key_comments, live_done) =
2572 if self.struct_mode && matches!(self.cfg.dup_policy, DuplicateKeyPolicy::LastWins) {
2573 (
2574 collect_last_wins_entries(
2575 self.ev,
2576 map_start_comments,
2577 self.cfg,
2578 None,
2579 &HashSet::new(),
2580 VecDeque::new(),
2581 )?,
2582 Vec::new(),
2583 true,
2584 )
2585 } else {
2586 (VecDeque::new(), map_start_comments, false)
2587 };
2588
2589 #[cfg(any(feature = "garde", feature = "validator"))]
2590 let garde = self.garde;
2591
2592 let mut access = MA {
2593 ev: self.ev,
2594 cfg: child_cfg,
2595 struct_mode: self.struct_mode,
2596 have_key: false,
2597
2598 fallback_guard: None,
2599
2600 #[cfg(any(feature = "garde", feature = "validator"))]
2601 garde,
2602 #[cfg(any(feature = "garde", feature = "validator"))]
2603 pending_path_segment: None,
2604
2605 seen: if remembers_seen_keys(&child_cfg) {
2606 HashSet::with_capacity(8)
2607 } else {
2608 HashSet::new()
2609 },
2610 pending,
2611 merge_stack: VecDeque::new(),
2612 flushing_merges: false,
2613 live_done,
2614 pending_value: None,
2615 pending_field_comments: Vec::new(),
2616 pending_value_separator_comments: Vec::new(),
2617 pending_value_comments: Vec::new(),
2618 pending_first_key_comments,
2619 };
2620 let result = visitor.visit_map(&mut access)?;
2621 access.finish()?;
2622 Ok(result)
2623 }
2624
2625 fn deserialize_struct<V: Visitor<'de>>(
2633 self,
2634 _name: &'static str,
2635 _fields: &'static [&'static str],
2636 visitor: V,
2637 ) -> Result<V::Value, Self::Error> {
2638 let mut de = self;
2639 de.struct_mode = true;
2640 de.deserialize_map(visitor)
2641 }
2642
2643 fn deserialize_enum<V: Visitor<'de>>(
2649 mut self,
2650 name: &'static str,
2651 variants: &'static [&'static str],
2652 visitor: V,
2653 ) -> Result<V::Value, Self::Error> {
2654 enum Mode<'de, 'a> {
2655 Unit(EnumScalarId<'de>),
2656 Map(String, Location),
2657 TaggedNewtype(EnumScalarId<'de>, RecordedEvents<'a>),
2659 }
2660
2661 let mut tagged_enum = None;
2662
2663 let peeked_ev = self.ev.peek()?.cloned();
2664 let mode = match peeked_ev {
2665 Some(Ev::RecursiveAlias { location, .. }) => {
2666 return Err(Error::RecursiveReferencesRequireWeakTypes { location });
2667 }
2668 Some(Ev::Scalar {
2669 tag,
2670 style,
2671 value: _,
2672 raw_tag,
2673 location,
2674 ..
2675 }) => {
2676 if let Some(tag_name) = simple_tagged_enum_name(&raw_tag, &tag) {
2677 tagged_enum = Some((tag_name, location));
2678 }
2679 if let Some((ref tag_name, tag_loc)) = tagged_enum
2682 && variants.contains(&tag_name.as_str())
2683 {
2684 let variant_name = EnumScalarId {
2685 raw: Cow::Owned(tag_name.clone()),
2686 effective: Cow::Owned(tag_name.clone()),
2687 interpolated: false,
2688 location: tag_loc,
2689 };
2690 let origin = self.ev.node_origin();
2692 let Some(mut ev) = self.ev.next()? else {
2693 return Err(eof_with_loc(self.ev));
2694 };
2695 ev.strip_node_tag();
2696 let replay = RecordedEvents::from_event(ev, origin);
2697 tagged_enum = None; Mode::TaggedNewtype(variant_name, replay)
2699 } else {
2700 let Some(view) = self.peek_scalar_view()? else {
2701 return Err(eof_with_loc(self.ev));
2702 };
2703 self.validate_scalar_tag(
2704 view.tag,
2705 SfTag::String,
2706 "enum variant",
2707 view.location,
2708 )?;
2709 if self.cfg.no_schema
2710 && !view.tag.forces_string()
2711 && maybe_not_string(&view.effective, &style, self.cfg.strict_booleans)
2712 {
2713 let view = self.take_scalar_view()?;
2714 return Err(Self::quoting_required_for_scalar(&view));
2715 }
2716 let view = self.take_scalar_view()?;
2717 Mode::Unit(EnumScalarId::from_view(view))
2718 }
2719 }
2720 Some(Ev::MapStart {
2721 tag,
2722 raw_tag,
2723 location,
2724 ..
2725 }) => {
2726 let tag_name = simple_tagged_enum_name(&raw_tag, &tag).or_else(|| {
2732 (tag == SfTag::Map && raw_tag.as_deref() == Some("!map"))
2733 .then(|| "map".to_owned())
2734 });
2735 if let Some(tag_name) = tag_name
2736 && variants.contains(&tag_name.as_str())
2737 {
2738 self.ev.strip_peeked_node_tag()?;
2739 return visitor.visit_enum(EA {
2740 ev: self.ev,
2741 cfg: self.cfg,
2742 variant: EnumScalarId {
2743 raw: Cow::Owned(tag_name.clone()),
2744 effective: Cow::Owned(tag_name),
2745 interpolated: false,
2746 location,
2747 },
2748 map_mode: false,
2749 tagged_payload: true,
2750 });
2751 }
2752
2753 self.expect_map_start()?;
2754 let mut key_de = YamlDeserializer::new(&mut *self.ev, self.cfg);
2755 key_de.in_key = true;
2756 if let Some(view) = key_de.peek_scalar_view()? {
2757 key_de.validate_scalar_tag(
2758 view.tag,
2759 SfTag::String,
2760 "enum variant",
2761 view.location,
2762 )?;
2763 if self.cfg.no_schema
2764 && !view.tag.forces_string()
2765 && maybe_not_string(&view.raw, &view.style, self.cfg.strict_booleans)
2766 {
2767 let view = key_de.take_scalar_view()?;
2768 return Err(Self::quoting_required_for_scalar(&view));
2769 }
2770 let view = key_de.take_scalar_view()?;
2771 Mode::Map(view.raw.into_owned(), view.location)
2772 } else {
2773 match self.ev.next()? {
2774 Some(other) => {
2775 return Err(Error::ExpectedStringKeyForExternallyTaggedEnum {
2776 location: other.location(),
2777 });
2778 }
2779 None => return Err(eof_with_loc(self.ev)),
2780 }
2781 }
2782 }
2783 Some(Ev::SeqStart {
2784 tag,
2785 raw_tag,
2786 location,
2787 ..
2788 }) => {
2789 if let Some(tag_name) = simple_tagged_enum_name(&raw_tag, &tag)
2790 && variants.contains(&tag_name.as_str())
2791 {
2792 let origin = self.ev.node_origin();
2794 let Some(seq_start) = self.ev.next()? else {
2795 return Err(eof_with_loc(self.ev));
2796 };
2797 let start_loc = seq_start.location();
2798 let mut replay_events = RecordedEvents::new();
2799 if let Ev::SeqStart {
2801 anchor, location, ..
2802 } = seq_start
2803 {
2804 replay_events.push(
2805 Ev::SeqStart {
2806 anchor,
2807 tag: SfTag::None,
2808 raw_tag: None,
2809 location,
2810 },
2811 origin,
2812 );
2813 }
2814 let mut depth = 1usize;
2815 while depth > 0 {
2816 let _ = self.ev.peek()?;
2817 let origin = self.ev.node_origin();
2818 match self.ev.next()? {
2819 Some(ev @ (Ev::SeqStart { .. } | Ev::MapStart { .. })) => {
2820 depth += 1;
2821 replay_events.push(ev, origin);
2822 }
2823 Some(ev @ (Ev::SeqEnd { .. } | Ev::MapEnd { .. })) => {
2824 depth -= 1;
2825 replay_events.push(ev, origin);
2826 }
2827 Some(ev) => {
2828 replay_events.push(ev, origin);
2829 }
2830 None => return Err(eof_with_loc(self.ev)),
2831 }
2832 }
2833 let replay = Box::new(ReplayEvents::new(
2834 replay_events,
2835 #[cfg(feature = "properties")]
2836 self.ev.property_interpolation().clone(),
2837 ));
2838 return visitor.visit_enum(TaggedEA {
2839 replay,
2840 cfg: self.cfg,
2841 variant: EnumScalarId {
2842 raw: Cow::Owned(tag_name.clone()),
2843 effective: Cow::Owned(tag_name),
2844 interpolated: false,
2845 location: start_loc,
2846 },
2847 });
2848 }
2849 return Err(Error::ExternallyTaggedEnumExpectedScalarOrMapping { location });
2850 }
2851 Some(Ev::SeqEnd { location }) => {
2852 return Err(Error::UnexpectedSequenceEnd { location });
2853 }
2854 Some(Ev::MapEnd { location }) => {
2855 return Err(Error::UnexpectedMappingEnd { location });
2856 }
2857 Some(Ev::Taken { location }) => {
2858 return Err(Error::unexpected("consumed event").with_location(location));
2859 }
2860 None => return Err(eof_with_loc(self.ev)),
2861 };
2862
2863 if let Some((tag_name, location)) = tagged_enum
2864 && tag_name != name
2865 {
2866 return Err(Error::TaggedEnumMismatch {
2867 tagged: tag_name,
2868 target: name,
2869 location,
2870 });
2871 }
2872
2873 struct EA<'de, 'e> {
2874 ev: &'e mut dyn Events<'de>,
2875 cfg: Cfg,
2876 variant: EnumScalarId<'de>,
2877 map_mode: bool,
2878 tagged_payload: bool,
2879 }
2880
2881 impl<'de, 'e> de::EnumAccess<'de> for EA<'de, 'e> {
2882 type Error = Error;
2883 type Variant = VA<'de, 'e>;
2884
2885 fn variant_seed<Vv>(self, seed: Vv) -> Result<(Vv::Value, Self::Variant), Error>
2887 where
2888 Vv: de::DeserializeSeed<'de>,
2889 {
2890 let EA {
2891 ev,
2892 cfg,
2893 variant,
2894 map_mode,
2895 tagged_payload,
2896 } = self;
2897 let v = seed.deserialize(variant.into_deserializer())?;
2898 Ok((
2899 v,
2900 VA {
2901 ev,
2902 cfg,
2903 map_mode,
2904 tagged_payload,
2905 },
2906 ))
2907 }
2908 }
2909
2910 struct VA<'de, 'e> {
2911 ev: &'e mut dyn Events<'de>,
2912 cfg: Cfg,
2913 map_mode: bool,
2914 tagged_payload: bool,
2915 }
2916
2917 impl VA<'_, '_> {
2918 fn expect_map_end(&mut self) -> Result<(), Error> {
2920 match self.ev.next()? {
2921 Some(Ev::MapEnd { .. }) => Ok(()),
2922 Some(other) => Err(Error::ExpectedMappingEndAfterEnumVariantValue {
2923 location: other.location(),
2924 }),
2925 None => Err(eof_with_loc(self.ev)),
2926 }
2927 }
2928 }
2929
2930 impl<'de> de::VariantAccess<'de> for VA<'de, '_> {
2931 type Error = Error;
2932
2933 fn unit_variant(mut self) -> Result<(), Error> {
2935 if self.map_mode {
2936 if YamlDeserializer::new(self.ev, self.cfg).peek_null_value()? {
2937 let _ = self.ev.next()?; return self.expect_map_end();
2939 }
2940 match self.ev.peek()? {
2941 Some(Ev::MapEnd { .. }) => {
2942 let _ = self.ev.next()?;
2943 Ok(())
2944 }
2945 Some(other) => Err(Error::UnexpectedValueForUnitEnumVariant {
2946 location: other.location(),
2947 }),
2948 None => Err(eof_with_loc(self.ev)),
2949 }
2950 } else if self.tagged_payload {
2951 de::Deserialize::deserialize(YamlDeserializer::new(self.ev, self.cfg))
2952 } else {
2953 Ok(())
2954 }
2955 }
2956
2957 fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Error>
2959 where
2960 T: de::DeserializeSeed<'de>,
2961 {
2962 let defined_location = match self.ev.peek()? {
2964 Some(ev) => ev.location(),
2965 None => self.ev.last_location(),
2966 };
2967 let alias_reference_location = self.ev.alias_reference_location();
2968
2969 let mut de = YamlDeserializer::new(self.ev, self.cfg);
2970 let redaction_ctx = de.peek_scalar_redaction_ctx()?;
2971 let value = with_subtree_redaction(redaction_ctx, || seed.deserialize(de))
2972 .map_err(|e| {
2973 attach_alias_locations_if_missing(
2974 e,
2975 alias_reference_location,
2976 defined_location,
2977 )
2978 })?;
2979 if self.map_mode {
2980 self.expect_map_end()?;
2981 }
2982 Ok(value)
2983 }
2984
2985 fn tuple_variant<Vv>(mut self, len: usize, visitor: Vv) -> Result<Vv::Value, Error>
2987 where
2988 Vv: Visitor<'de>,
2989 {
2990 let result =
2991 YamlDeserializer::new(self.ev, self.cfg).deserialize_tuple(len, visitor)?;
2992 if self.map_mode {
2993 self.expect_map_end()?;
2994 }
2995 Ok(result)
2996 }
2997
2998 fn struct_variant<Vv>(
3000 mut self,
3001 fields: &'static [&'static str],
3002 visitor: Vv,
3003 ) -> Result<Vv::Value, Error>
3004 where
3005 Vv: Visitor<'de>,
3006 {
3007 let result = YamlDeserializer::new(self.ev, self.cfg)
3008 .deserialize_struct("", fields, visitor)?;
3009 if self.map_mode {
3010 self.expect_map_end()?;
3011 }
3012 Ok(result)
3013 }
3014 }
3015
3016 struct TaggedEA<'de> {
3017 replay: Box<ReplayEvents<'de>>,
3018 cfg: Cfg,
3019 variant: EnumScalarId<'de>,
3020 }
3021
3022 impl<'de> de::EnumAccess<'de> for TaggedEA<'de> {
3023 type Error = Error;
3024 type Variant = TaggedVA<'de>;
3025
3026 fn variant_seed<Vv>(self, seed: Vv) -> Result<(Vv::Value, Self::Variant), Error>
3027 where
3028 Vv: de::DeserializeSeed<'de>,
3029 {
3030 let v = seed.deserialize(self.variant.into_deserializer())?;
3031 Ok((
3032 v,
3033 TaggedVA {
3034 replay: self.replay,
3035 cfg: self.cfg,
3036 },
3037 ))
3038 }
3039 }
3040
3041 struct TaggedVA<'de> {
3042 replay: Box<ReplayEvents<'de>>,
3043 cfg: Cfg,
3044 }
3045
3046 impl<'de> de::VariantAccess<'de> for TaggedVA<'de> {
3047 type Error = Error;
3048
3049 fn unit_variant(mut self) -> Result<(), Error> {
3050 de::Deserialize::deserialize(YamlDeserializer::new(&mut *self.replay, self.cfg))
3051 }
3052
3053 fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Error>
3054 where
3055 T: de::DeserializeSeed<'de>,
3056 {
3057 let mut de = YamlDeserializer::new(&mut *self.replay, self.cfg);
3058 let redaction_ctx = de.peek_scalar_redaction_ctx()?;
3059 with_subtree_redaction(redaction_ctx, || seed.deserialize(de))
3060 }
3061
3062 fn tuple_variant<Vv>(mut self, len: usize, visitor: Vv) -> Result<Vv::Value, Error>
3063 where
3064 Vv: Visitor<'de>,
3065 {
3066 YamlDeserializer::new(&mut *self.replay, self.cfg).deserialize_tuple(len, visitor)
3067 }
3068
3069 fn struct_variant<Vv>(
3070 mut self,
3071 fields: &'static [&'static str],
3072 visitor: Vv,
3073 ) -> Result<Vv::Value, Error>
3074 where
3075 Vv: Visitor<'de>,
3076 {
3077 YamlDeserializer::new(&mut *self.replay, self.cfg)
3078 .deserialize_struct("", fields, visitor)
3079 }
3080 }
3081
3082 let access = match mode {
3083 Mode::Unit(variant) => EA {
3084 ev: self.ev,
3085 cfg: self.cfg,
3086 variant,
3087 map_mode: false,
3088 tagged_payload: false,
3089 },
3090 Mode::Map(variant, variant_location) => EA {
3091 ev: self.ev,
3092 cfg: self.cfg,
3093 variant: EnumScalarId {
3094 raw: Cow::Owned(variant.clone()),
3095 effective: Cow::Owned(variant),
3096 interpolated: false,
3097 location: variant_location,
3098 },
3099 map_mode: true,
3100 tagged_payload: false,
3101 },
3102 Mode::TaggedNewtype(variant, replay_buf) => {
3103 let replay = Box::new(ReplayEvents::new(
3104 replay_buf,
3105 #[cfg(feature = "properties")]
3106 self.ev.property_interpolation().clone(),
3107 ));
3108 return visitor.visit_enum(TaggedEA {
3110 replay,
3111 cfg: self.cfg,
3112 variant,
3113 });
3114 }
3115 };
3116
3117 visitor.visit_enum(access)
3118 }
3119
3120 fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
3122 self.deserialize_str(visitor)
3123 }
3124
3125 fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
3129 self.deserialize_any(visitor)
3130 }
3131}
3132
3133#[cfg(all(test, feature = "properties"))]
3134mod tests {
3135 use super::super::events::PropertyInterpolation;
3136 use super::super::options::{Options, PropertySyntax};
3137 use super::*;
3138
3139 #[test]
3140 fn effective_scalar_value_without_property_map_returns_original_scalar() {
3141 let budget = crate::Budget::default();
3142 let mut events = ReplayEvents::new(
3143 Vec::new(),
3144 PropertyInterpolation::new(None, PropertySyntax::Braced, Some(&budget)),
3145 );
3146 let de = YamlDeserializer::new(&mut events, Cfg::from_options(&Options::default()));
3147
3148 let value = de
3149 .effective_scalar_value(Cow::Borrowed("${MISSING}"), Location::new(1, 1))
3150 .expect("missing property map should not be treated as interpolation");
3151
3152 assert_eq!(value, Cow::Borrowed("${MISSING}"));
3153 }
3154}