pub use crate::budget::Budget;
pub use crate::de_error::Error;
pub use crate::location::Location;
use crate::anchor_store::{self, AnchorKind};
use crate::base64::decode_base64_yaml;
use crate::de_error::{MissingFieldLocationGuard, TransformReason};
use crate::parse_scalars::{
leading_zero_decimal, maybe_not_string, parse_int_signed, parse_int_unsigned,
parse_yaml11_bool, parse_yaml12_float, scalar_is_nullish, scalar_is_nullish_for_option,
};
use ahash::{HashSetExt, RandomState};
use saphyr_parser::ScalarStyle;
use serde::de::{self, Deserializer as _, IntoDeserializer, Visitor};
use std::borrow::Cow;
use std::collections::{HashSet, VecDeque};
use std::mem;
pub mod with_deserializer;
pub use with_deserializer::{
with_deserializer_from_reader, with_deserializer_from_reader_with_options,
with_deserializer_from_slice, with_deserializer_from_slice_with_options,
with_deserializer_from_str, with_deserializer_from_str_with_options,
};
type FastHashSet<T> = HashSet<T, RandomState>;
use crate::location::Locations;
#[inline]
fn attach_alias_locations_if_missing(
err: Error,
reference_location: Location,
defined_location: Location,
) -> Error {
if reference_location != Location::UNKNOWN
&& defined_location != Location::UNKNOWN
&& reference_location != defined_location
{
Error::AliasError {
msg: err.to_string(),
locations: Locations {
reference_location,
defined_location,
},
}
} else if err.location().is_some() {
err
} else {
let loc = if reference_location != Location::UNKNOWN {
reference_location
} else {
defined_location
};
err.with_location(loc)
}
}
mod spanned_deser;
pub use crate::options::{AliasLimits, DuplicateKeyPolicy, Options};
use crate::tags::SfTag;
#[cfg(any(feature = "garde", feature = "validator"))]
use crate::path_map::PathRecorder;
#[derive(Clone, Copy)]
pub(crate) struct Cfg {
pub(crate) dup_policy: DuplicateKeyPolicy,
pub(crate) legacy_octal_numbers: bool,
pub(crate) strict_booleans: bool,
pub(crate) angle_conversions: bool,
pub(crate) ignore_binary_tag_for_string: bool,
pub(crate) no_schema: bool,
}
impl Cfg {
#[inline]
#[allow(deprecated)]
pub(crate) fn from_options(options: &Options) -> Self {
Self {
dup_policy: options.duplicate_keys,
legacy_octal_numbers: options.legacy_octal_numbers,
strict_booleans: options.strict_booleans,
angle_conversions: options.angle_conversions,
ignore_binary_tag_for_string: options.ignore_binary_tag_for_string,
no_schema: options.no_schema,
}
}
}
#[derive(Clone, Debug)]
pub(crate) enum Ev<'a> {
Scalar {
value: Cow<'a, str>,
tag: SfTag,
raw_tag: Option<Cow<'a, str>>,
style: ScalarStyle,
anchor: usize,
location: Location,
},
SeqStart { anchor: usize, location: Location },
SeqEnd { location: Location },
MapStart { anchor: usize, location: Location },
MapEnd { location: Location },
Taken { location: Location },
}
impl Default for Ev<'_> {
fn default() -> Self {
Ev::Taken {
location: Location::UNKNOWN,
}
}
}
impl Ev<'_> {
pub(crate) fn location(&self) -> Location {
match self {
Ev::Scalar { location, .. }
| Ev::SeqStart { location, .. }
| Ev::SeqEnd { location }
| Ev::MapStart { location, .. }
| Ev::MapEnd { location }
| Ev::Taken { location } => *location,
}
}
}
fn simple_tagged_enum_name(raw_tag: &Option<Cow<'_, str>>, tag: &SfTag) -> Option<String> {
if !matches!(tag, SfTag::Other) {
return None;
}
let raw = raw_tag.as_deref()?;
let mut candidate =
if let Some(inner) = raw.strip_prefix("!<").and_then(|s| s.strip_suffix('>')) {
inner
} else {
raw
};
if let Some(stripped) = candidate.strip_prefix("tag:yaml.org,2002:") {
candidate = stripped;
}
candidate = candidate.trim_start_matches('!');
if candidate.is_empty() || candidate.contains([':', '!']) {
return None;
}
Some(candidate.to_owned())
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Default)]
enum KeyFingerprint {
Scalar { value: String, tag: SfTag },
Sequence(Vec<KeyFingerprint>),
Mapping(Vec<(KeyFingerprint, KeyFingerprint)>),
#[default]
Default,
}
impl KeyFingerprint {
fn stringy_scalar_value(&self) -> Option<&str> {
match self {
KeyFingerprint::Scalar { value, tag } => {
if tag.can_parse_into_string() && tag != &SfTag::Binary {
Some(value.as_str())
} else {
None
}
}
_ => None,
}
}
}
enum KeyNode<'a> {
Fingerprinted {
fingerprint: KeyFingerprint,
events: Vec<Ev<'a>>,
location: Location,
},
Scalar {
events: Vec<Ev<'a>>,
location: Location,
},
}
impl<'a> KeyNode<'a> {
fn fingerprint(&self) -> Cow<'_, KeyFingerprint> {
match self {
KeyNode::Fingerprinted { fingerprint, .. } => Cow::Borrowed(fingerprint),
KeyNode::Scalar { events, .. } => {
if let Some(Ev::Scalar { tag, value, .. }) = events.first() {
Cow::Owned(KeyFingerprint::Scalar {
tag: *tag,
value: value.to_string(),
})
} else {
unreachable!()
}
}
}
}
fn events(&self) -> &[Ev<'a>] {
match self {
KeyNode::Fingerprinted { events, .. } => events,
KeyNode::Scalar { events, .. } => events,
}
}
fn take_events(&mut self) -> Vec<Ev<'a>> {
match self {
KeyNode::Fingerprinted { events, .. } => mem::take(events),
KeyNode::Scalar { events, .. } => mem::take(events),
}
}
fn take_fingerprint(&mut self) -> KeyFingerprint {
match self {
KeyNode::Fingerprinted { fingerprint, .. } => mem::take(fingerprint),
KeyNode::Scalar { .. } => self.fingerprint().into_owned(),
}
}
fn location(&self) -> Location {
let location = match self {
KeyNode::Fingerprinted { location, .. } => location,
KeyNode::Scalar { location, .. } => location,
};
*location
}
}
struct PendingEntry<'a> {
key: KeyNode<'a>,
value: KeyNode<'a>,
reference_location: Location,
}
fn one_entry_map_spans<'a>(events: &[Ev<'a>]) -> Option<(usize, usize, usize, usize)> {
if events.len() < 4 {
return None;
}
match events.first()? {
Ev::MapStart { .. } => {}
_ => return None,
}
match events.last()? {
Ev::MapEnd { .. } => {}
_ => return None,
}
let mut i = 1; let key_start = i;
i += skip_one_node_len(events, i)?;
let key_end = i;
let val_start = i;
i += skip_one_node_len(events, i)?;
let val_end = i;
if i != events.len() - 1 {
return None;
}
Some((key_start, key_end, val_start, val_end))
}
fn skip_one_node_len<'a>(events: &[Ev<'a>], mut i: usize) -> Option<usize> {
match events.get(i)? {
Ev::Scalar { .. } => Some(1),
Ev::SeqStart { .. } => {
let start = i;
let mut depth = 1i32;
i += 1;
while i < events.len() {
match events.get(i)? {
Ev::SeqStart { .. } => depth += 1,
Ev::SeqEnd { .. } => {
depth -= 1;
if depth == 0 {
return Some(i - start + 1);
}
}
Ev::MapStart { .. } => depth += 1,
Ev::MapEnd { .. } => {
depth -= 1;
}
Ev::Scalar { .. } => {}
Ev::Taken { .. } => return None,
}
i += 1;
}
None
}
Ev::MapStart { .. } => {
let start = i;
let mut depth = 1i32;
i += 1;
while i < events.len() {
match events.get(i)? {
Ev::MapStart { .. } => depth += 1,
Ev::MapEnd { .. } => {
depth -= 1;
if depth == 0 {
return Some(i - start + 1);
}
}
Ev::SeqStart { .. } => depth += 1,
Ev::SeqEnd { .. } => {
depth -= 1;
}
Ev::Scalar { .. } => {}
Ev::Taken { .. } => return None,
}
i += 1;
}
None
}
Ev::SeqEnd { .. } | Ev::MapEnd { .. } => None,
Ev::Taken { .. } => None,
}
}
fn capture_node<'a>(ev: &mut dyn Events<'a>) -> Result<KeyNode<'a>, Error> {
let Some(event) = ev.next()? else {
return Err(Error::eof().with_location(ev.last_location()));
};
match event {
Ev::Scalar {
value,
tag,
raw_tag,
style,
anchor,
location,
} => {
let scalar_ev = Ev::Scalar {
value,
tag,
raw_tag,
style,
anchor,
location,
};
Ok(KeyNode::Scalar {
events: vec![scalar_ev],
location,
})
}
Ev::SeqStart { anchor, location } => {
let mut events = vec![Ev::SeqStart { anchor, location }];
let mut elements = Vec::new();
loop {
match ev.peek()? {
Some(Ev::SeqEnd { location: end_loc }) => {
let end_loc = *end_loc;
let _ = ev.next()?;
events.push(Ev::SeqEnd { location: end_loc });
break;
}
Some(_) => {
let mut child = capture_node(ev)?; let fp = child.take_fingerprint();
let child_events = child.take_events();
elements.push(fp);
events.reserve(child_events.len());
events.extend(child_events);
}
None => {
return Err(Error::eof().with_location(ev.last_location()));
}
}
}
Ok(KeyNode::Fingerprinted {
fingerprint: KeyFingerprint::Sequence(elements),
events,
location,
})
}
Ev::MapStart { anchor, location } => {
let mut events = vec![Ev::MapStart { anchor, location }];
let mut entries = Vec::new();
loop {
match ev.peek()? {
Some(Ev::MapEnd { location: end_loc }) => {
let end_loc = *end_loc;
let _ = ev.next()?;
events.push(Ev::MapEnd { location: end_loc });
break;
}
Some(_) => {
let mut key = capture_node(ev)?; let key_fp = key.take_fingerprint();
let mut value = capture_node(ev)?; let value_fp = value.take_fingerprint();
entries.push((key_fp, value_fp));
let key_events = key.take_events();
let value_events = value.take_events();
events.reserve(key_events.len() + value_events.len());
events.extend(key_events);
events.extend(value_events);
}
None => {
return Err(Error::eof().with_location(ev.last_location()));
}
}
}
Ok(KeyNode::Fingerprinted {
fingerprint: KeyFingerprint::Mapping(entries),
events,
location,
})
}
Ev::SeqEnd { location } | Ev::MapEnd { location } => {
Err(Error::UnexpectedContainerEndWhileReadingKeyNode { location })
}
Ev::Taken { location } => Err(Error::unexpected("consumed event").with_location(location)),
}
}
#[inline]
fn is_merge_key(node: &KeyNode) -> bool {
let events = node.events();
if events.len() != 1 {
return false;
}
matches!(
events.first(),
Some(Ev::Scalar {
value,
tag,
style: ScalarStyle::Plain,
..
}) if tag == &SfTag::None && value.as_ref() == "<<"
)
}
fn pending_entries_from_events<'a>(
events: Vec<Ev<'a>>,
location: Location,
reference_location: Location,
) -> Result<Vec<PendingEntry<'a>>, Error> {
let mut replay = ReplayEvents::with_reference(events, reference_location);
match replay.peek()? {
Some(Ev::Scalar { value, style, .. }) if scalar_is_nullish(value.as_ref(), style) => {
Ok(Vec::new())
}
Some(Ev::Scalar { location, .. }) => Err(Error::MergeValueNotMapOrSeqOfMaps {
location: *location,
}),
Some(Ev::MapStart { .. }) => collect_entries_from_map(&mut replay, reference_location),
Some(Ev::SeqStart { .. }) => {
let mut batches = Vec::new();
let _ = replay.next()?; loop {
match replay.peek()? {
Some(Ev::SeqEnd { .. }) => {
let _ = replay.next()?;
break;
}
Some(_) => {
let _ = replay.peek()?;
let element_ref_loc = replay.reference_location();
let mut element = capture_node(&mut replay)?;
batches.push(pending_entries_from_events(
element.take_events(),
element.location(),
element_ref_loc,
)?); }
None => {
return Err(Error::eof().with_location(replay.last_location()));
}
}
}
let mut merged = Vec::new();
while let Some(mut nested) = batches.pop() {
merged.append(&mut nested);
}
Ok(merged)
}
Some(other) => Err(Error::MergeValueNotMapOrSeqOfMaps {
location: other.location(),
}),
None => Err(Error::eof().with_location(location)),
}
}
fn pending_entries_from_live_events<'a>(
ev: &mut dyn Events<'a>,
merge_reference_location: Location,
) -> Result<Vec<PendingEntry<'a>>, Error> {
match ev.peek()? {
Some(Ev::Scalar { value, style, .. }) if scalar_is_nullish(value.as_ref(), style) => {
let _ = ev.next()?;
Ok(Vec::new())
}
Some(Ev::Scalar { location, .. }) => Err(Error::MergeValueNotMapOrSeqOfMaps {
location: *location,
}),
Some(Ev::MapStart { .. }) => {
let mut node = capture_node(ev)?;
pending_entries_from_events(
node.take_events(),
node.location(),
merge_reference_location,
)
}
Some(Ev::SeqStart { .. }) => {
let _ = ev.next()?; let mut batches = Vec::new();
loop {
match ev.peek()? {
Some(Ev::SeqEnd { .. }) => {
let _ = ev.next()?;
break;
}
Some(_) => {
let _ = ev.peek()?;
let element_ref_loc = ev.reference_location();
let mut element = capture_node(ev)?;
batches.push(pending_entries_from_events(
element.take_events(),
element.location(),
element_ref_loc,
)?);
}
None => return Err(Error::eof().with_location(ev.last_location())),
}
}
let mut merged = Vec::new();
while let Some(mut nested) = batches.pop() {
merged.append(&mut nested);
}
Ok(merged)
}
Some(other) => Err(Error::MergeValueNotMapOrSeqOfMaps {
location: other.location(),
}),
None => Err(Error::eof().with_location(ev.last_location())),
}
}
fn collect_entries_from_map<'a>(
ev: &mut dyn Events<'a>,
reference_location: Location,
) -> Result<Vec<PendingEntry<'a>>, Error> {
let Some(Ev::MapStart { .. }) = ev.next()? else {
return Err(Error::MergeValueNotMapOrSeqOfMaps {
location: ev.last_location(),
});
};
let mut fields = Vec::new();
let mut merges = Vec::new();
loop {
match ev.peek()? {
Some(Ev::MapEnd { .. }) => {
let _ = ev.next()?;
break;
}
Some(_) => {
let key = capture_node(ev)?;
if is_merge_key(&key) {
let _ = ev.peek()?;
let merge_ref_loc = ev.reference_location();
merges.push(pending_entries_from_live_events(ev, merge_ref_loc)?);
} else {
let value = capture_node(ev)?;
fields.push(PendingEntry {
key,
value,
reference_location,
});
}
}
None => {
return Err(Error::eof().with_location(ev.last_location()));
}
}
}
let mut entries = fields;
while let Some(mut nested) = merges.pop() {
entries.append(&mut nested);
}
Ok(entries)
}
pub(crate) trait Events<'de> {
fn next(&mut self) -> Result<Option<Ev<'de>>, Error>;
fn peek(&mut self) -> Result<Option<&Ev<'de>>, Error>;
fn last_location(&self) -> Location;
fn reference_location(&self) -> Location;
#[allow(dead_code)]
fn input_for_borrowing(&self) -> Option<&'de str> {
None }
}
struct ReplayEvents<'a> {
buf: Vec<Ev<'a>>,
idx: usize,
ref_override: Option<Location>,
}
impl<'a> ReplayEvents<'a> {
fn new(buf: Vec<Ev<'a>>) -> Self {
Self {
buf,
idx: 0,
ref_override: None,
}
}
fn with_reference(buf: Vec<Ev<'a>>, reference: Location) -> Self {
Self {
buf,
idx: 0,
ref_override: Some(reference),
}
}
}
impl<'a> Events<'a> for ReplayEvents<'a> {
fn next(&mut self) -> Result<Option<Ev<'a>>, Error> {
if self.idx >= self.buf.len() {
return Ok(None);
}
let location = self.buf[self.idx].location();
let ev = mem::replace(&mut self.buf[self.idx], Ev::Taken { location });
self.idx += 1;
Ok(Some(ev))
}
fn peek(&mut self) -> Result<Option<&Ev<'a>>, Error> {
Ok(self.buf.get(self.idx))
}
fn last_location(&self) -> Location {
let last = self.idx.saturating_sub(1);
self.buf
.get(last)
.map(|e| e.location())
.unwrap_or(Location::UNKNOWN)
}
fn reference_location(&self) -> Location {
if let Some(loc) = self.ref_override {
return loc;
}
self.buf
.get(self.idx)
.map(|e| e.location())
.unwrap_or_else(|| self.last_location())
}
}
pub struct YamlDeserializer<'de, 'e> {
ev: &'e mut dyn Events<'de>,
cfg: Cfg,
in_key: bool,
key_empty_map_node: bool,
#[cfg(any(feature = "garde", feature = "validator"))]
garde: Option<&'e mut PathRecorder>,
}
impl<'de, 'e> YamlDeserializer<'de, 'e> {
pub(crate) fn new(ev: &'e mut dyn Events<'de>, cfg: Cfg) -> Self {
Self {
ev,
cfg,
in_key: false,
key_empty_map_node: false,
#[cfg(any(feature = "garde", feature = "validator"))]
garde: None,
}
}
#[cfg(any(feature = "garde", feature = "validator"))]
pub(crate) fn new_with_path_recorder(
ev: &'e mut dyn Events<'de>,
cfg: Cfg,
garde: &'e mut PathRecorder,
) -> Self {
Self {
ev,
cfg,
in_key: false,
key_empty_map_node: false,
garde: Some(garde),
}
}
fn take_scalar_event(&mut self) -> Result<(String, SfTag, Location), Error> {
match self.ev.next()? {
Some(Ev::Scalar {
value,
tag,
location,
..
}) => Ok((value.into_owned(), tag, location)),
Some(other) => Err(Error::unexpected("string scalar").with_location(other.location())),
None => Err(Error::eof().with_location(self.ev.last_location())),
}
}
fn take_scalar_cow_event(&mut self) -> Result<(Cow<'de, str>, SfTag, Location), Error> {
match self.ev.next()? {
Some(Ev::Scalar {
value,
tag,
location,
..
}) => Ok((value, tag, location)),
Some(other) => Err(Error::unexpected("string scalar").with_location(other.location())),
None => Err(Error::eof().with_location(self.ev.last_location())),
}
}
fn take_scalar_cow_with_location(&mut self) -> Result<(Cow<'de, str>, SfTag, Location), Error> {
let (value, tag, location) = self.take_scalar_cow_event()?;
Ok((value, tag, location))
}
fn take_string_scalar(&mut self) -> Result<String, Error> {
let (value, tag, location) = self.take_scalar_event()?;
if tag == SfTag::Binary && !self.cfg.ignore_binary_tag_for_string {
let data = decode_base64_yaml(&value).map_err(|err| err.with_location(location))?;
let text = String::from_utf8(data)
.map_err(|_| Error::BinaryNotUtf8 { location })?;
return Ok(text);
}
if !tag.can_parse_into_string()
&& tag != SfTag::NonSpecific
&& !(self.cfg.ignore_binary_tag_for_string && tag == SfTag::Binary)
{
return Err(Error::TaggedScalarCannotDeserializeIntoString { location });
}
Ok(value)
}
fn expect_seq_start(&mut self) -> Result<(), Error> {
match self.ev.next()? {
Some(Ev::SeqStart { .. }) => Ok(()),
Some(other) => Err(Error::unexpected("sequence start").with_location(other.location())),
None => Err(Error::eof().with_location(self.ev.last_location())),
}
}
fn expect_map_start(&mut self) -> Result<(), Error> {
match self.ev.next()? {
Some(Ev::MapStart { .. }) => Ok(()),
Some(other) => Err(Error::unexpected("mapping start").with_location(other.location())),
None => Err(Error::eof().with_location(self.ev.last_location())),
}
}
fn peek_anchor_id(&mut self) -> Result<Option<usize>, Error> {
match self.ev.peek()? {
Some(Ev::Scalar { anchor, .. })
| Some(Ev::SeqStart { anchor, .. })
| Some(Ev::MapStart { anchor, .. }) => {
if *anchor == 0 {
Ok(None)
} else {
Ok(Some(*anchor))
}
}
_ => Ok(None),
}
}
}
impl<'de, 'e> de::Deserializer<'de> for YamlDeserializer<'de, 'e> {
type Error = Error;
fn deserialize_any<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
match self.ev.peek()? {
Some(Ev::Scalar {
tag,
style,
value,
location,
..
}) => {
if tag == &SfTag::Null {
let _ = self.take_scalar_event()?; return visitor.visit_unit();
}
let is_plain = matches!(style, ScalarStyle::Plain);
if scalar_is_nullish(value, style) {
let _ = self.ev.next()?; return visitor.visit_unit();
}
if !is_plain || !tag.can_parse_into_string() || tag == &SfTag::Binary {
if *tag == SfTag::Binary && !self.cfg.ignore_binary_tag_for_string {
return visitor.visit_string(self.take_string_scalar()?);
}
if !tag.can_parse_into_string()
&& *tag != SfTag::NonSpecific
&& !(self.cfg.ignore_binary_tag_for_string && *tag == SfTag::Binary)
{
return Err(Error::TaggedScalarCannotDeserializeIntoString {
location: *location,
});
}
let (cow, _tag2, _location) = self.take_scalar_cow_event()?;
return match cow {
Cow::Borrowed(b) => visitor.visit_borrowed_str(b),
Cow::Owned(s) => visitor.visit_string(s),
};
}
let (s, tag, location) = self.take_scalar_event()?;
if self.cfg.strict_booleans {
let tt = s.trim();
if tt.eq_ignore_ascii_case("true") {
return visitor.visit_bool(true);
} else if tt.eq_ignore_ascii_case("false") {
return visitor.visit_bool(false);
}
} else if let Ok(b) = parse_yaml11_bool(&s) {
return visitor.visit_bool(b);
}
let t = s.trim();
if t.starts_with('-') && !leading_zero_decimal(t) {
if let Ok(v) =
parse_int_signed::<i64>(t, "i64", location, self.cfg.legacy_octal_numbers)
{
return visitor.visit_i64(v);
}
} else {
if let Ok(v) =
parse_int_unsigned::<u64>(t, "u64", location, self.cfg.legacy_octal_numbers)
{
return visitor.visit_u64(v);
}
if let Ok(v) =
parse_int_signed::<i64>(t, "i64", location, self.cfg.legacy_octal_numbers)
{
return visitor.visit_i64(v);
}
}
if let Ok(v) =
parse_yaml12_float::<f64>(&s, location, tag, self.cfg.angle_conversions)
{
if v.is_finite() {
return visitor.visit_f64(v);
} else {
let canon = if v.is_nan() {
".nan".to_string()
} else if v.is_sign_negative() {
"-.inf".to_string()
} else {
".inf".to_string()
};
return visitor.visit_string(canon);
}
}
visitor.visit_string(s)
}
Some(Ev::SeqStart { .. }) => self.deserialize_seq(visitor),
Some(Ev::MapStart { .. }) => self.deserialize_map(visitor),
Some(Ev::SeqEnd { location }) => {
Err(Error::UnexpectedSequenceEnd { location: *location })
}
Some(Ev::MapEnd { location }) => {
Err(Error::UnexpectedMappingEnd { location: *location })
}
None => {
visitor.visit_unit()
}
Some(Ev::Taken { location }) => {
Err(Error::unexpected("consumed event").with_location(*location))
}
}
}
fn deserialize_bool<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let s = s.as_ref();
let t = s.trim();
let b: bool = if self.cfg.strict_booleans {
if t.eq_ignore_ascii_case("true") {
true
} else if t.eq_ignore_ascii_case("false") {
false
} else {
return Err(Error::InvalidBooleanStrict { location });
}
} else {
parse_yaml11_bool(s)
.map_err(|_| Error::InvalidScalar { ty: "boolean", location })?
};
visitor.visit_bool(b)
}
fn deserialize_i8<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let v: i8 = parse_int_signed(s.as_ref(), "i8", location, self.cfg.legacy_octal_numbers)?;
visitor.visit_i8(v)
}
fn deserialize_i16<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let v: i16 = parse_int_signed(s.as_ref(), "i16", location, self.cfg.legacy_octal_numbers)?;
visitor.visit_i16(v)
}
fn deserialize_i32<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let v: i32 = parse_int_signed(s.as_ref(), "i32", location, self.cfg.legacy_octal_numbers)?;
visitor.visit_i32(v)
}
fn deserialize_i64<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let v: i64 = parse_int_signed(s.as_ref(), "i64", location, self.cfg.legacy_octal_numbers)?;
visitor.visit_i64(v)
}
fn deserialize_i128<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let v: i128 = parse_int_signed(s.as_ref(), "i128", location, self.cfg.legacy_octal_numbers)?;
visitor.visit_i128(v)
}
fn deserialize_u8<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let v: u8 = parse_int_unsigned(s.as_ref(), "u8", location, self.cfg.legacy_octal_numbers)?;
visitor.visit_u8(v)
}
fn deserialize_u16<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let v: u16 = parse_int_unsigned(s.as_ref(), "u16", location, self.cfg.legacy_octal_numbers)?;
visitor.visit_u16(v)
}
fn deserialize_u32<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let v: u32 = parse_int_unsigned(s.as_ref(), "u32", location, self.cfg.legacy_octal_numbers)?;
visitor.visit_u32(v)
}
fn deserialize_u64<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let v: u64 = parse_int_unsigned(s.as_ref(), "u64", location, self.cfg.legacy_octal_numbers)?;
visitor.visit_u64(v)
}
fn deserialize_u128<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let v: u128 = parse_int_unsigned(s.as_ref(), "u128", location, self.cfg.legacy_octal_numbers)?;
visitor.visit_u128(v)
}
fn deserialize_f32<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, tag, location) = self.take_scalar_cow_with_location()?;
let v: f32 = parse_yaml12_float(s.as_ref(), location, tag, self.cfg.angle_conversions)?;
visitor.visit_f32(v)
}
fn deserialize_f64<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let (s, tag, location) = self.take_scalar_cow_with_location()?;
let v: f64 = parse_yaml12_float(s.as_ref(), location, tag, self.cfg.angle_conversions)?;
visitor.visit_f64(v)
}
fn deserialize_char<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
if let Some(Ev::Scalar {
tag, style, value, ..
}) = self.ev.peek()?
&& tag != &SfTag::String
{
if tag == &SfTag::Null || scalar_is_nullish(value, style) {
let (_value, _tag, location) = self.take_scalar_event()?;
return Err(Error::InvalidCharNull { location });
} else if self.cfg.no_schema && maybe_not_string(value, style) {
let (value, _tag, location) = self.take_scalar_event()?;
return Err(Error::quoting_required(&value).with_location(location));
}
}
let (s, _tag, location) = self.take_scalar_cow_with_location()?;
let mut it = s.as_ref().chars();
match (it.next(), it.next()) {
(Some(c), None) => visitor.visit_char(c),
_ => Err(Error::InvalidCharNotSingleScalar { location }),
}
}
fn deserialize_str<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let location = match self.ev.peek()? {
Some(Ev::Scalar {
location,
tag,
style,
value,
..
}) => {
if tag == &SfTag::Null || scalar_is_nullish(value, style) {
let loc = *location;
let _ = self.ev.next()?;
return Err(Error::NullIntoString { location: loc });
}
*location
}
Some(other) => {
return Err(Error::unexpected("string scalar").with_location(other.location()));
}
None => return Err(Error::eof().with_location(self.ev.last_location())),
};
let (cow, _tag, _loc) = self.take_scalar_cow_with_location()?;
if let Cow::Borrowed(b) = cow {
return visitor.visit_borrowed_str(b);
}
let cannot_borrow_reason = if self.ev.input_for_borrowing().is_none() {
TransformReason::InputNotBorrowable
} else {
TransformReason::ParserReturnedOwned
};
let res: Result<V::Value, Self::Error> = visitor.visit_string(cow.into_owned());
match res {
Ok(v) => Ok(v),
Err(err) => {
let msg = err.to_string();
if msg.contains("expected a borrowed string") {
return Err(
Error::cannot_borrow_transformed(cannot_borrow_reason)
.with_location(location),
);
}
Err(err)
}
}
}
fn deserialize_string<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
let _location = if let Some(Ev::Scalar {
tag,
style,
value,
location,
..
}) = self.ev.peek()?
{
if (tag == &SfTag::Null || scalar_is_nullish(value, style)) && tag != &SfTag::String {
let (_value, _tag, location) = self.take_scalar_event()?;
return Err(Error::NullIntoString { location });
} else if self.cfg.no_schema && maybe_not_string(value, style) && tag != &SfTag::String {
let (value, _tag, location) = self.take_scalar_event()?;
return Err(Error::quoting_required(&value).with_location(location));
}
*location
} else {
return visitor.visit_string(self.take_string_scalar()?);
};
if let Some(Ev::Scalar { tag, .. }) = self.ev.peek()?
{
if *tag == SfTag::Binary && !self.cfg.ignore_binary_tag_for_string {
return visitor.visit_string(self.take_string_scalar()?);
}
if !tag.can_parse_into_string()
&& *tag != SfTag::NonSpecific
&& !(self.cfg.ignore_binary_tag_for_string && *tag == SfTag::Binary)
{
let location = self.ev.peek()?.unwrap().location();
return Err(Error::TaggedScalarCannotDeserializeIntoString { location });
}
}
let (cow, _tag, _loc) = self.take_scalar_cow_with_location()?;
match cow {
Cow::Borrowed(b) => visitor.visit_borrowed_str(b),
Cow::Owned(s) => visitor.visit_string(s),
}
}
fn deserialize_bytes<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
match self.ev.peek()? {
Some(Ev::Scalar { tag, .. }) if tag == &SfTag::Binary => {
let (value, data_location) = match self.ev.next()? {
Some(Ev::Scalar {
value, location, ..
}) => (value, location),
_ => unreachable!(),
};
let data =
decode_base64_yaml(&value).map_err(|err| err.with_location(data_location))?;
visitor.visit_byte_buf(data)
}
Some(Ev::SeqStart { .. }) => {
self.expect_seq_start()?;
let mut out = Vec::new();
loop {
match self.ev.peek()? {
Some(Ev::SeqEnd { .. }) => {
let _ = self.ev.next()?; break;
}
Some(_) => {
let b: u8 = <u8 as serde::Deserialize>::deserialize(
YamlDeserializer::new(self.ev, self.cfg),
)?;
out.push(b);
}
None => return Err(Error::eof().with_location(self.ev.last_location())),
}
}
visitor.visit_byte_buf(out)
}
Some(Ev::Scalar { location, .. }) => {
Err(Error::BytesNotSupportedMissingBinaryTag {
location: *location,
})
}
Some(other) => Err(
Error::unexpected("scalar (!!binary) or sequence of 0..=255")
.with_location(other.location()),
),
None => Err(Error::eof().with_location(self.ev.last_location())),
}
}
fn deserialize_byte_buf<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
self.deserialize_bytes(visitor)
}
fn deserialize_option<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
if self.in_key && self.key_empty_map_node {
match self.ev.next()? {
Some(Ev::MapStart { .. }) => {}
Some(other) => {
return Err(
Error::unexpected("empty mapping start").with_location(other.location())
);
}
None => return Err(Error::eof().with_location(self.ev.last_location())),
}
match self.ev.next()? {
Some(Ev::MapEnd { .. }) => {}
Some(other) => {
return Err(
Error::unexpected("empty mapping end").with_location(other.location())
);
}
None => return Err(Error::eof().with_location(self.ev.last_location())),
}
return visitor.visit_none();
}
match self.ev.peek()? {
None => visitor.visit_none(),
Some(Ev::Scalar { tag, .. }) if tag == &SfTag::Null => {
let _ = self.ev.next()?; visitor.visit_none()
}
Some(Ev::Scalar {
value: s, style, ..
}) if scalar_is_nullish_for_option(s, style) => {
let _ = self.ev.next()?; visitor.visit_none()
}
Some(Ev::MapEnd { .. }) | Some(Ev::SeqEnd { .. }) => visitor.visit_none(),
Some(_) => visitor.visit_some(self),
}
}
fn deserialize_unit<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
match self.ev.peek()? {
None => visitor.visit_unit(),
Some(Ev::Scalar {
value: s, style, ..
}) if scalar_is_nullish(s, style) => {
let _ = self.ev.next()?; visitor.visit_unit()
}
Some(Ev::MapEnd { .. }) | Some(Ev::SeqEnd { .. }) => visitor.visit_unit(),
Some(other) => {
Err(Error::UnexpectedValueForUnit {
location: other.location(),
})
}
}
}
fn deserialize_unit_struct<V: Visitor<'de>>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error> {
match self.ev.peek()? {
Some(Ev::MapStart { .. }) => {
let _ = self.ev.next()?; match self.ev.peek()? {
Some(Ev::MapEnd { .. }) => {
let _ = self.ev.next()?; visitor.visit_unit()
}
Some(other) => Err(Error::ExpectedEmptyMappingForUnitStruct {
location: other.location(),
}),
None => Err(Error::eof().with_location(self.ev.last_location())),
}
}
_ => self.deserialize_unit(visitor),
}
}
fn deserialize_newtype_struct<V: Visitor<'de>>(
mut self,
n: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error> {
match n {
"__yaml_spanned" => spanned_deser::deserialize_yaml_spanned(self, visitor),
"__yaml_rc_anchor" => {
let anchor = self.peek_anchor_id()?;
anchor_store::with_anchor_context(AnchorKind::Rc, anchor, || {
visitor.visit_newtype_struct(self)
})
}
"__yaml_arc_anchor" => {
let anchor = self.peek_anchor_id()?;
anchor_store::with_anchor_context(AnchorKind::Arc, anchor, || {
visitor.visit_newtype_struct(self)
})
}
"__yaml_rc_recursive" => {
let anchor = self.peek_anchor_id()?;
anchor_store::with_anchor_context(AnchorKind::RcRecursive, anchor, || {
visitor.visit_newtype_struct(self)
})
}
"__yaml_arc_recursive" => {
let anchor = self.peek_anchor_id()?;
anchor_store::with_anchor_context(AnchorKind::ArcRecursive, anchor, || {
visitor.visit_newtype_struct(self)
})
}
"__yaml_rc_weak_anchor" => {
let anchor = self.peek_anchor_id()?;
anchor_store::with_anchor_context(AnchorKind::Rc, anchor, || {
visitor.visit_newtype_struct(self)
})
}
"__yaml_arc_weak_anchor" => {
let anchor = self.peek_anchor_id()?;
anchor_store::with_anchor_context(AnchorKind::Arc, anchor, || {
visitor.visit_newtype_struct(self)
})
}
"__yaml_rc_recursion" => {
let anchor = self.peek_anchor_id()?;
anchor_store::with_anchor_context(AnchorKind::RcRecursive, anchor, || {
visitor.visit_newtype_struct(self)
})
}
"__yaml_arc_recursion" => {
let anchor = self.peek_anchor_id()?;
anchor_store::with_anchor_context(AnchorKind::ArcRecursive, anchor, || {
visitor.visit_newtype_struct(self)
})
}
_ => visitor.visit_newtype_struct(self),
}
}
fn deserialize_seq<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
if let Some(Ev::Scalar {
value: s,
tag,
style,
..
}) = self.ev.peek()?
{
if tag == &SfTag::Null || scalar_is_nullish(s, style) {
let _ = self.ev.next()?; struct EmptySeq;
impl<'de> de::SeqAccess<'de> for EmptySeq {
type Error = Error;
fn next_element_seed<T>(&mut self, _seed: T) -> Result<Option<T::Value>, Error>
where
T: de::DeserializeSeed<'de>,
{
Ok(None)
}
}
return visitor.visit_seq(EmptySeq);
}
if tag == &SfTag::Binary {
let (scalar, data_location) = match self.ev.next()? {
Some(Ev::Scalar {
value, location, ..
}) => (value, location),
_ => unreachable!(),
};
let data =
decode_base64_yaml(&scalar).map_err(|err| err.with_location(data_location))?;
struct ByteSeq {
data: Vec<u8>,
idx: usize,
}
impl<'de> de::SeqAccess<'de> for ByteSeq {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
where
T: de::DeserializeSeed<'de>,
{
if self.idx >= self.data.len() {
return Ok(None);
}
let b = self.data[self.idx];
self.idx += 1;
let deser = serde::de::value::U8Deserializer::<Error>::new(b);
seed.deserialize(deser).map(Some)
}
}
return visitor.visit_seq(ByteSeq { data, idx: 0 });
}
}
self.expect_seq_start()?;
struct SA<'de, 'e> {
ev: &'e mut dyn Events<'de>,
cfg: Cfg,
#[cfg(any(feature = "garde", feature = "validator"))]
garde: Option<&'e mut PathRecorder>,
#[cfg(any(feature = "garde", feature = "validator"))]
idx: usize,
}
impl<'de, 'e> de::SeqAccess<'de> for SA<'de, 'e> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
where
T: de::DeserializeSeed<'de>,
{
let (is_end, defined_location) = {
let peeked = self.ev.peek()?;
match peeked {
Some(Ev::SeqEnd { .. }) => (true, Location::UNKNOWN),
Some(ev) => (false, ev.location()),
None => return Err(Error::eof().with_location(self.ev.last_location())),
}
};
if is_end {
return Ok(None);
}
let reference_location = self.ev.reference_location();
let _missing_field_guard = MissingFieldLocationGuard::new(reference_location);
#[cfg(any(feature = "garde", feature = "validator"))]
{
if let Some(garde_ref) = self.garde.as_mut() {
let recorder: &mut PathRecorder = garde_ref;
let prev = recorder.current.take();
let now = prev.clone().join(self.idx);
recorder.current = now.clone();
recorder.map.insert(
now,
Locations {
reference_location,
defined_location,
},
);
let de =
YamlDeserializer::new_with_path_recorder(self.ev, self.cfg, recorder);
let res = seed
.deserialize(de)
.map(Some)
.map_err(|e| attach_alias_locations_if_missing(e, reference_location, defined_location));
recorder.current = prev;
self.idx += 1;
return res;
}
}
let de = YamlDeserializer::new(self.ev, self.cfg);
seed.deserialize(de)
.map(Some)
.map_err(|e| attach_alias_locations_if_missing(e, reference_location, defined_location))
}
}
#[cfg(any(feature = "garde", feature = "validator"))]
let garde = self.garde;
let result = visitor.visit_seq(SA {
ev: self.ev,
cfg: self.cfg,
#[cfg(any(feature = "garde", feature = "validator"))]
garde,
#[cfg(any(feature = "garde", feature = "validator"))]
idx: 0,
})?;
if let Some(Ev::SeqEnd { .. }) = self.ev.peek()? {
let _ = self.ev.next()?;
}
Ok(result)
}
fn deserialize_tuple<V: Visitor<'de>>(
self,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error> {
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V: Visitor<'de>>(
self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error> {
self.deserialize_seq(visitor)
}
fn deserialize_map<V: Visitor<'de>>(mut self, visitor: V) -> Result<V::Value, Self::Error> {
if let Some(Ev::Scalar {
value: s,
tag,
style,
..
}) = self.ev.peek()?
&& (tag == &SfTag::Null || scalar_is_nullish(s, style))
{
let _ = self.ev.next()?; struct EmptyMap;
impl<'de> de::MapAccess<'de> for EmptyMap {
type Error = Error;
fn next_key_seed<K>(&mut self, _seed: K) -> Result<Option<K::Value>, Error>
where
K: de::DeserializeSeed<'de>,
{
Ok(None)
}
fn next_value_seed<Vv>(&mut self, _seed: Vv) -> Result<Vv::Value, Error>
where
Vv: de::DeserializeSeed<'de>,
{
unreachable!("no values in empty map")
}
}
return visitor.visit_map(EmptyMap);
}
self.expect_map_start()?;
let _missing_field_guard = MissingFieldLocationGuard::new(self.ev.reference_location());
#[cfg(any(feature = "garde", feature = "validator"))]
if let Some(recorder) = self.garde.as_mut() {
let path = recorder.current.clone();
recorder.map.insert(
path,
Locations {
reference_location: self.ev.reference_location(),
defined_location: self.ev.last_location(),
},
);
}
struct MA<'de, 'e> {
ev: &'e mut dyn Events<'de>,
cfg: Cfg,
have_key: bool,
fallback_guard: Option<MissingFieldLocationGuard>,
#[cfg(any(feature = "garde", feature = "validator"))]
garde: Option<&'e mut PathRecorder>,
#[cfg(any(feature = "garde", feature = "validator"))]
pending_path_segment: Option<String>,
seen: FastHashSet<KeyFingerprint>,
pending: VecDeque<PendingEntry<'de>>,
merge_stack: Vec<Vec<PendingEntry<'de>>>,
flushing_merges: bool,
pending_value: Option<(Vec<Ev<'de>>, Location)>,
}
impl<'de, 'e> MA<'de, 'e> {
fn skip_one_node(&mut self) -> Result<(), Error> {
let mut depth; match self.ev.next()? {
Some(Ev::Scalar { .. }) => return Ok(()),
Some(Ev::SeqStart { .. }) | Some(Ev::MapStart { .. }) => depth = 1,
Some(Ev::SeqEnd { location }) | Some(Ev::MapEnd { location }) => {
return Err(Error::UnexpectedContainerEndWhileSkippingNode { location });
}
Some(Ev::Taken { location }) => {
return Err(Error::unexpected("consumed event").with_location(location));
}
None => return Err(Error::eof().with_location(self.ev.last_location())),
}
while depth != 0 {
match self.ev.next()? {
Some(Ev::SeqStart { .. }) | Some(Ev::MapStart { .. }) => depth += 1,
Some(Ev::SeqEnd { .. }) | Some(Ev::MapEnd { .. }) => depth -= 1,
Some(Ev::Scalar { .. }) => {}
Some(Ev::Taken { location }) => {
return Err(Error::unexpected("consumed event").with_location(location));
}
None => return Err(Error::eof().with_location(self.ev.last_location())),
}
}
Ok(())
}
fn deserialize_recorded_key<'de2, K>(
&mut self,
seed: K,
events: Vec<Ev<'de2>>,
kemn: bool,
) -> Result<K::Value, Error>
where
K: de::DeserializeSeed<'de2>,
{
let mut replay = ReplayEvents::new(events);
let location = replay.reference_location();
let de = YamlDeserializer::<'de2, '_> {
ev: &mut replay,
cfg: self.cfg,
in_key: true,
key_empty_map_node: kemn,
#[cfg(any(feature = "garde", feature = "validator"))]
garde: None,
};
seed.deserialize(de)
.map_err(|e| if e.location().is_none() { e.with_location(location) } else { e })
}
fn enqueue_entries(&mut self, entries: Vec<PendingEntry<'de>>) {
self.pending.reserve(entries.len());
for entry in entries.into_iter().rev() {
self.pending.push_front(entry);
}
}
fn enqueue_next_merge_batch(&mut self) -> bool {
while let Some(entries) = self.merge_stack.pop() {
if entries.is_empty() {
continue;
}
self.enqueue_entries(entries);
return true;
}
false
}
}
impl<'de, 'e> de::MapAccess<'de> for MA<'de, 'e> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
where
K: de::DeserializeSeed<'de>,
{
let mut seed = Some(seed);
loop {
if let Some(entry) = self.pending.pop_front() {
let PendingEntry {
mut key,
mut value,
reference_location,
} = entry;
let fingerprint = key.take_fingerprint();
let location = key.location();
let mut events = key.take_events();
let is_duplicate = self.seen.contains(&fingerprint);
if self.flushing_merges {
if is_duplicate {
continue;
}
} else {
match self.cfg.dup_policy {
DuplicateKeyPolicy::Error => {
if is_duplicate {
let key = fingerprint
.stringy_scalar_value()
.map(|s| s.to_owned());
return Err(Error::DuplicateMappingKey { key, location });
}
}
DuplicateKeyPolicy::FirstWins => {
if is_duplicate {
continue;
}
}
DuplicateKeyPolicy::LastWins => {}
}
}
let mut value_events = value.take_events();
let kemn_direct =
matches!(fingerprint, KeyFingerprint::Mapping(ref v) if v.is_empty());
let mut kemn = kemn_direct;
if !kemn
&& let KeyFingerprint::Mapping(ref pairs) = fingerprint
&& pairs.len() == 1
&& let (
KeyFingerprint::Scalar {
value: sv,
tag: stag,
},
_,
) = &pairs[0]
{
let is_nullish = *stag == SfTag::Null
|| sv.is_empty()
|| sv == "~"
|| sv.eq_ignore_ascii_case("null");
if is_nullish {
if let Some((_ks, _ke, vs, ve)) = one_entry_map_spans(&events) {
value_events = events.drain(vs..ve).collect();
let start = match events.first() {
Some(Ev::MapStart { anchor, location }) => Ev::MapStart {
anchor: *anchor,
location: *location,
},
Some(other) => other.clone(),
None => {
return Err(Error::unexpected("mapping start")
.with_location(location));
}
};
let end = match events.last() {
Some(Ev::MapEnd { location }) => Ev::MapEnd {
location: *location,
},
Some(other) => other.clone(),
None => {
return Err(Error::unexpected("mapping end")
.with_location(location));
}
};
events = vec![start, end];
kemn = true;
}
}
}
let key_seed = match seed.take() {
Some(s) => s,
None => {
return Err(Error::InternalSeedReusedForMapKey { location });
}
};
match &mut self.fallback_guard {
Some(guard) => guard.replace_location(location),
None => self.fallback_guard = Some(MissingFieldLocationGuard::new(location)),
}
let key_value = self.deserialize_recorded_key(key_seed, events, kemn)?;
self.have_key = true;
self.pending_value = Some((value_events, reference_location));
#[cfg(any(feature = "garde", feature = "validator"))]
{
self.pending_path_segment =
fingerprint.stringy_scalar_value().map(|s| s.to_owned());
}
self.seen.insert(fingerprint);
return Ok(Some(key_value));
}
if self.flushing_merges {
if self.enqueue_next_merge_batch() {
continue;
}
self.flushing_merges = false;
return Ok(None);
}
match self.ev.peek()? {
Some(Ev::MapEnd { .. }) => {
let _ = self.ev.next()?; if self.merge_stack.is_empty() {
return Ok(None);
}
self.flushing_merges = true;
if self.enqueue_next_merge_batch() {
continue;
}
self.flushing_merges = false;
return Ok(None);
}
Some(_) => {
let mut key_node = capture_node(self.ev)?;
if is_merge_key(&key_node) {
let _ = self.ev.peek()?;
let merge_ref_loc = self.ev.reference_location();
let entries =
pending_entries_from_live_events(self.ev, merge_ref_loc)?;
if !entries.is_empty() {
self.merge_stack.push(entries);
}
continue;
}
let fingerprint = key_node.fingerprint();
let is_duplicate = self.seen.contains(&fingerprint);
match self.cfg.dup_policy {
DuplicateKeyPolicy::Error => {
if is_duplicate {
let location = key_node.location();
let key = key_node
.fingerprint()
.stringy_scalar_value()
.map(|s| s.to_owned());
return Err(Error::DuplicateMappingKey { key, location });
}
}
DuplicateKeyPolicy::FirstWins => {
if is_duplicate {
self.skip_one_node()?;
continue;
}
}
DuplicateKeyPolicy::LastWins => {}
}
let kemn_direct = matches!(*fingerprint, KeyFingerprint::Mapping(ref v) if v.is_empty());
let kemn_one_entry_nullish = match &*fingerprint {
KeyFingerprint::Mapping(pairs) if pairs.len() == 1 => {
if let (
KeyFingerprint::Scalar {
value: sv,
tag: stag,
},
_,
) = &pairs[0]
{
*stag == SfTag::Null
|| sv.is_empty()
|| sv == "~"
|| sv.eq_ignore_ascii_case("null")
} else {
false
}
}
_ => false,
};
if kemn_one_entry_nullish {
let _ = self.ev.peek()?;
let reference_location = self.ev.reference_location();
let value_node = capture_node(self.ev)?;
self.enqueue_entries(vec![PendingEntry {
key: key_node,
value: value_node,
reference_location,
}]);
continue;
} else {
let fingerprint = fingerprint.into_owned();
let location = key_node.location();
let events = key_node.take_events();
let key_seed = match seed.take() {
Some(s) => s,
None => {
return Err(Error::InternalSeedReusedForMapKey { location });
}
};
match &mut self.fallback_guard {
Some(guard) => guard.replace_location(location),
None => self.fallback_guard = Some(MissingFieldLocationGuard::new(location)),
}
let key_value =
self.deserialize_recorded_key(key_seed, events, kemn_direct)?;
self.have_key = true;
self.pending_value = None;
#[cfg(any(feature = "garde", feature = "validator"))]
{
self.pending_path_segment =
fingerprint.stringy_scalar_value().map(|s| s.to_owned());
}
self.seen.insert(fingerprint);
return Ok(Some(key_value));
}
}
None => return Err(Error::eof().with_location(self.ev.last_location())),
}
}
}
fn next_value_seed<Vv>(&mut self, seed: Vv) -> Result<Vv::Value, Error>
where
Vv: de::DeserializeSeed<'de>,
{
if !self.have_key {
return Err(Error::ValueRequestedBeforeKey {
location: self.ev.last_location(),
});
}
self.have_key = false;
#[cfg(any(feature = "garde", feature = "validator"))]
let pending_segment = self.pending_path_segment.take();
if let Some(events) = self.pending_value.take() {
let (events, reference_location) = events;
let mut replay = ReplayEvents::with_reference(events, reference_location);
let defined_location = replay
.peek()?
.map(|ev| ev.location())
.unwrap_or_else(|| replay.last_location());
#[cfg(any(feature = "garde", feature = "validator"))]
{
if let (Some(seg), Some(garde_ref)) = (pending_segment, self.garde.as_mut())
{
let recorder: &mut PathRecorder = garde_ref;
let prev = recorder.current.take();
let now = prev.clone().join(seg.as_str());
recorder.current = now.clone();
recorder.map.insert(
now,
Locations {
reference_location,
defined_location,
},
);
let de = YamlDeserializer::new_with_path_recorder(
&mut replay,
self.cfg,
recorder,
);
let res = seed
.deserialize(de)
.map_err(|e| attach_alias_locations_if_missing(e, reference_location, defined_location));
recorder.current = prev;
return res;
}
}
let de = YamlDeserializer::new(&mut replay, self.cfg);
seed.deserialize(de)
.map_err(|e| attach_alias_locations_if_missing(e, reference_location, defined_location))
} else {
let defined_location = self
.ev
.peek()?
.map(|ev: &Ev| ev.location())
.unwrap_or_else(|| self.ev.last_location());
let reference_location = self.ev.reference_location();
#[cfg(any(feature = "garde", feature = "validator"))]
{
if let (Some(seg), Some(garde_ref)) = (pending_segment, self.garde.as_mut())
{
let recorder: &mut PathRecorder = garde_ref;
let prev = recorder.current.take();
let now = prev.clone().join(seg.as_str());
recorder.current = now.clone();
recorder.map.insert(
now,
Locations {
reference_location,
defined_location,
},
);
let de = YamlDeserializer::new_with_path_recorder(
self.ev, self.cfg, recorder,
);
let res = seed
.deserialize(de)
.map_err(|e| attach_alias_locations_if_missing(e, reference_location, defined_location));
recorder.current = prev;
return res;
}
}
let de = YamlDeserializer::new(self.ev, self.cfg);
seed.deserialize(de)
.map_err(|e| attach_alias_locations_if_missing(e, reference_location, defined_location))
}
}
}
#[cfg(any(feature = "garde", feature = "validator"))]
let garde = self.garde;
visitor.visit_map(MA {
ev: self.ev,
cfg: self.cfg,
have_key: false,
fallback_guard: None,
#[cfg(any(feature = "garde", feature = "validator"))]
garde,
#[cfg(any(feature = "garde", feature = "validator"))]
pending_path_segment: None,
seen: FastHashSet::with_capacity(8),
pending: VecDeque::new(),
merge_stack: Vec::new(),
flushing_merges: false,
pending_value: None,
})
}
fn deserialize_struct<V: Visitor<'de>>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> {
self.deserialize_map(visitor)
}
fn deserialize_enum<V: Visitor<'de>>(
mut self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error> {
enum Mode {
Unit(String, Location),
Map(String, Location),
}
let mut tagged_enum = None;
let mode = match self.ev.peek()? {
Some(Ev::Scalar {
tag,
style,
value,
raw_tag,
location,
..
}) => {
if let Some(tag_name) = simple_tagged_enum_name(raw_tag, tag) {
tagged_enum = Some((tag_name, *location));
}
if self.cfg.no_schema && *tag != SfTag::String && maybe_not_string(value, style) {
let (v, _t, loc) = self.take_scalar_event()?;
return Err(Error::quoting_required(&v).with_location(loc));
}
let (value, _tag, loc) = self.take_scalar_event()?;
Mode::Unit(value, loc)
}
Some(Ev::MapStart { .. }) => {
self.expect_map_start()?;
match self.ev.next()? {
Some(Ev::Scalar {
value,
tag,
style,
location,
..
}) => {
if self.cfg.no_schema
&& tag != SfTag::String
&& maybe_not_string(&value, &style)
{
return Err(Error::quoting_required(&value).with_location(location));
}
Mode::Map(value.to_string(), location)
}
Some(other) => {
return Err(Error::ExpectedStringKeyForExternallyTaggedEnum {
location: other.location(),
});
}
None => return Err(Error::eof().with_location(self.ev.last_location())),
}
}
Some(Ev::SeqStart { location, .. }) => {
return Err(
Error::ExternallyTaggedEnumExpectedScalarOrMapping { location: *location },
);
}
Some(Ev::SeqEnd { location }) => {
return Err(Error::UnexpectedSequenceEnd { location: *location });
}
Some(Ev::MapEnd { location }) => {
return Err(Error::UnexpectedMappingEnd { location: *location });
}
Some(Ev::Taken { location }) => {
return Err(Error::unexpected("consumed event").with_location(*location));
}
None => return Err(Error::eof().with_location(self.ev.last_location())),
};
if let Some((tag_name, location)) = tagged_enum
&& tag_name != _name
{
return Err(Error::TaggedEnumMismatch {
tagged: tag_name,
target: _name,
location,
});
}
struct EA<'de, 'e> {
ev: &'e mut dyn Events<'de>,
cfg: Cfg,
variant: String,
map_mode: bool,
variant_location: Location,
}
impl<'de, 'e> de::EnumAccess<'de> for EA<'de, 'e> {
type Error = Error;
type Variant = VA<'de, 'e>;
fn variant_seed<Vv>(self, seed: Vv) -> Result<(Vv::Value, Self::Variant), Error>
where
Vv: de::DeserializeSeed<'de>,
{
let EA {
ev,
cfg,
variant,
map_mode,
variant_location,
} = self;
let v = seed.deserialize(variant.into_deserializer()).map_err(
|err: serde::de::value::Error| {
Error::SerdeVariantId {
msg: err.to_string(),
location: variant_location,
}
},
)?;
Ok((v, VA { ev, cfg, map_mode }))
}
}
struct VA<'de, 'e> {
ev: &'e mut dyn Events<'de>,
cfg: Cfg,
map_mode: bool,
}
impl<'de, 'e> VA<'de, 'e> {
fn expect_map_end(&mut self) -> Result<(), Error> {
match self.ev.next()? {
Some(Ev::MapEnd { .. }) => Ok(()),
Some(other) => Err(Error::ExpectedMappingEndAfterEnumVariantValue {
location: other.location(),
}),
None => Err(Error::eof().with_location(self.ev.last_location())),
}
}
}
impl<'de, 'e> de::VariantAccess<'de> for VA<'de, 'e> {
type Error = Error;
fn unit_variant(mut self) -> Result<(), Error> {
if self.map_mode {
match self.ev.peek()? {
Some(Ev::MapEnd { .. }) => {
let _ = self.ev.next()?;
Ok(())
}
Some(Ev::Scalar { value: s, style, .. }) if scalar_is_nullish(s, style) => {
let _ = self.ev.next()?; self.expect_map_end()
}
Some(other) => Err(Error::UnexpectedValueForUnitEnumVariant {
location: other.location(),
}),
None => Err(Error::eof().with_location(self.ev.last_location())),
}
} else {
Ok(())
}
}
fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Error>
where
T: de::DeserializeSeed<'de>,
{
let defined_location = self
.ev
.peek()?
.map(|ev: &Ev| ev.location())
.unwrap_or_else(|| self.ev.last_location());
let reference_location = self.ev.reference_location();
let value = seed
.deserialize(YamlDeserializer::new(self.ev, self.cfg))
.map_err(|e| attach_alias_locations_if_missing(e, reference_location, defined_location))?;
if self.map_mode {
self.expect_map_end()?;
}
Ok(value)
}
fn tuple_variant<Vv>(mut self, len: usize, visitor: Vv) -> Result<Vv::Value, Error>
where
Vv: Visitor<'de>,
{
let result =
YamlDeserializer::new(self.ev, self.cfg).deserialize_tuple(len, visitor)?;
if self.map_mode {
self.expect_map_end()?;
}
Ok(result)
}
fn struct_variant<Vv>(
mut self,
fields: &'static [&'static str],
visitor: Vv,
) -> Result<Vv::Value, Error>
where
Vv: Visitor<'de>,
{
let result = YamlDeserializer::new(self.ev, self.cfg)
.deserialize_struct("", fields, visitor)?;
if self.map_mode {
self.expect_map_end()?;
}
Ok(result)
}
}
let access = match mode {
Mode::Unit(variant, variant_location) => EA {
ev: self.ev,
cfg: self.cfg,
variant,
map_mode: false,
variant_location,
},
Mode::Map(variant, variant_location) => EA {
ev: self.ev,
cfg: self.cfg,
variant,
map_mode: true,
variant_location,
},
};
visitor.visit_enum(access)
}
fn deserialize_identifier<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
self.deserialize_str(visitor)
}
fn deserialize_ignored_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
self.deserialize_any(visitor)
}
}