use crate::error::{self, Error, ErrorImpl, Result}; use crate::path::Path; use serde::de::{ self, Deserialize, DeserializeOwned, DeserializeSeed, Expected, IgnoredAny as Ignore, IntoDeserializer, Unexpected, Visitor, }; use std::collections::BTreeMap; use std::f64; use std::fmt; use std::io; use std::marker::PhantomData; use std::mem; use std::str; use std::sync::atomic::{AtomicUsize, Ordering}; use std::sync::Arc; use yaml_rust::parser::{Event as YamlEvent, MarkedEventReceiver, Parser}; use yaml_rust::scanner::{Marker, TScalarStyle, TokenType}; /// A structure that deserializes YAML into Rust values. /// /// # Examples /// /// Deserializing a single document: /// /// ``` /// use anyhow::Result; /// use serde::Deserialize; /// use serde_yaml::Value; /// /// fn main() -> Result<()> { /// let input = "---\nk: 107\n"; /// let de = serde_yaml::Deserializer::from_str(input); /// let value = Value::deserialize(de)?; /// println!("{:?}", value); /// Ok(()) /// } /// ``` /// /// Deserializing multi-doc YAML: /// /// ``` /// use anyhow::Result; /// use serde::Deserialize; /// use serde_yaml::Value; /// /// fn main() -> Result<()> { /// let input = "---\nk: 107\n...\n---\nj: 106\n"; /// /// for document in serde_yaml::Deserializer::from_str(input) { /// let value = Value::deserialize(document)?; /// println!("{:?}", value); /// } /// /// Ok(()) /// } /// ``` pub struct Deserializer<'a> { input: Input<'a>, } enum Input<'a> { Str(&'a str), Slice(&'a [u8]), Read(Box), Multidoc(Arc), Fail(Arc), } impl<'a> Deserializer<'a> { /// Creates a YAML deserializer from a `&str`. pub fn from_str(s: &'a str) -> Self { let input = Input::Str(s); Deserializer { input } } /// Creates a YAML deserializer from a `&[u8]`. pub fn from_slice(v: &'a [u8]) -> Self { let input = Input::Slice(v); Deserializer { input } } /// Creates a YAML deserializer from an `io::Read`. /// /// Reader-based deserializers do not support deserializing borrowed types /// like `&str`, since the `std::io::Read` trait has no non-copying methods /// -- everything it does involves copying bytes out of the data source. pub fn from_reader(rdr: R) -> Self where R: io::Read + 'a, { let input = Input::Read(Box::new(rdr)); Deserializer { input } } fn de(self, f: impl FnOnce(&mut DeserializerFromEvents) -> Result) -> Result { if let Input::Multidoc(multidoc) = &self.input { let mut pos = multidoc.pos.load(Ordering::Relaxed); let t = f(&mut DeserializerFromEvents { events: &multidoc.loader.events, aliases: &multidoc.loader.aliases, pos: &mut pos, path: Path::Root, remaining_depth: 128, })?; multidoc.pos.store(pos, Ordering::Relaxed); return Ok(t); } let loader = loader(self.input)?; if loader.events.is_empty() { return Err(error::end_of_stream()); } let mut pos = 0; let t = f(&mut DeserializerFromEvents { events: &loader.events, aliases: &loader.aliases, pos: &mut pos, path: Path::Root, remaining_depth: 128, })?; if pos == loader.events.len() { Ok(t) } else { Err(error::more_than_one_document()) } } } fn loader(input: Input) -> Result { enum Input2<'a> { Str(&'a str), Slice(&'a [u8]), } let mut buffer; let input = match input { Input::Str(s) => Input2::Str(s), Input::Slice(bytes) => Input2::Slice(bytes), Input::Read(mut rdr) => { buffer = Vec::new(); rdr.read_to_end(&mut buffer).map_err(error::io)?; Input2::Slice(&buffer) } Input::Multidoc(_) => unreachable!(), Input::Fail(err) => return Err(error::shared(err)), }; let input = match input { Input2::Str(s) => s, Input2::Slice(bytes) => str::from_utf8(bytes).map_err(error::str_utf8)?, }; let mut parser = Parser::new(input.chars()); let mut loader = Loader { events: Vec::new(), aliases: BTreeMap::new(), }; parser.load(&mut loader, true).map_err(error::scanner)?; Ok(loader) } struct Multidoc { loader: Loader, pos: AtomicUsize, } impl<'de> Iterator for Deserializer<'de> { type Item = Self; fn next(&mut self) -> Option { match &self.input { Input::Multidoc(multidoc) => { let pos = multidoc.pos.load(Ordering::Relaxed); return if pos < multidoc.loader.events.len() { Some(Deserializer { input: Input::Multidoc(Arc::clone(multidoc)), }) } else { None }; } Input::Fail(err) => { return Some(Deserializer { input: Input::Fail(Arc::clone(err)), }); } _ => {} } let dummy = Input::Str(""); let input = mem::replace(&mut self.input, dummy); match loader(input) { Ok(loader) => { let multidoc = Arc::new(Multidoc { loader, pos: AtomicUsize::new(0), }); self.input = Input::Multidoc(Arc::clone(&multidoc)); if multidoc.loader.events.is_empty() { None } else { Some(Deserializer { input: Input::Multidoc(multidoc), }) } } Err(err) => { let fail = err.shared(); self.input = Input::Fail(Arc::clone(&fail)); Some(Deserializer { input: Input::Fail(fail), }) } } } } impl<'de> de::Deserializer<'de> for Deserializer<'de> { type Error = Error; fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_any(visitor)) } fn deserialize_bool(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_bool(visitor)) } fn deserialize_i8(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_i8(visitor)) } fn deserialize_i16(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_i16(visitor)) } fn deserialize_i32(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_i32(visitor)) } fn deserialize_i64(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_i64(visitor)) } fn deserialize_i128(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_i128(visitor)) } fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_u8(visitor)) } fn deserialize_u16(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_u16(visitor)) } fn deserialize_u32(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_u32(visitor)) } fn deserialize_u64(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_u64(visitor)) } fn deserialize_u128(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_u128(visitor)) } fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_f32(visitor)) } fn deserialize_f64(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_f64(visitor)) } fn deserialize_char(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_char(visitor)) } fn deserialize_str(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_str(visitor)) } fn deserialize_string(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_string(visitor)) } fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_bytes(visitor)) } fn deserialize_byte_buf(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_byte_buf(visitor)) } fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_option(visitor)) } fn deserialize_unit(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_unit(visitor)) } fn deserialize_unit_struct(self, name: &'static str, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_unit_struct(name, visitor)) } fn deserialize_newtype_struct(self, name: &'static str, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_newtype_struct(name, visitor)) } fn deserialize_seq(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_seq(visitor)) } fn deserialize_tuple(self, len: usize, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_tuple(len, visitor)) } fn deserialize_tuple_struct( self, name: &'static str, len: usize, visitor: V, ) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_tuple_struct(name, len, visitor)) } fn deserialize_map(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_map(visitor)) } fn deserialize_struct( self, name: &'static str, fields: &'static [&'static str], visitor: V, ) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_struct(name, fields, visitor)) } fn deserialize_enum( self, name: &'static str, variants: &'static [&'static str], visitor: V, ) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_enum(name, variants, visitor)) } fn deserialize_identifier(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_identifier(visitor)) } fn deserialize_ignored_any(self, visitor: V) -> Result where V: Visitor<'de>, { self.de(|state| state.deserialize_ignored_any(visitor)) } } pub struct Loader { events: Vec<(Event, Marker)>, /// Map from alias id to index in events. aliases: BTreeMap, } impl MarkedEventReceiver for Loader { fn on_event(&mut self, event: YamlEvent, marker: Marker) { let event = match event { YamlEvent::Nothing | YamlEvent::StreamStart | YamlEvent::StreamEnd | YamlEvent::DocumentStart | YamlEvent::DocumentEnd => return, YamlEvent::Alias(id) => Event::Alias(id), YamlEvent::Scalar(value, style, id, tag) => { self.aliases.insert(id, self.events.len()); Event::Scalar(value, style, tag) } YamlEvent::SequenceStart(id) => { self.aliases.insert(id, self.events.len()); Event::SequenceStart } YamlEvent::SequenceEnd => Event::SequenceEnd, YamlEvent::MappingStart(id) => { self.aliases.insert(id, self.events.len()); Event::MappingStart } YamlEvent::MappingEnd => Event::MappingEnd, }; self.events.push((event, marker)); } } #[derive(Debug, PartialEq)] enum Event { Alias(usize), Scalar(String, TScalarStyle, Option), SequenceStart, SequenceEnd, MappingStart, MappingEnd, } struct DeserializerFromEvents<'a> { events: &'a [(Event, Marker)], /// Map from alias id to index in events. aliases: &'a BTreeMap, pos: &'a mut usize, path: Path<'a>, remaining_depth: u8, } impl<'a> DeserializerFromEvents<'a> { fn peek(&self) -> Result<(&'a Event, Marker)> { match self.events.get(*self.pos) { Some(event) => Ok((&event.0, event.1)), None => Err(error::end_of_stream()), } } fn next(&mut self) -> Result<(&'a Event, Marker)> { self.opt_next().ok_or_else(error::end_of_stream) } fn opt_next(&mut self) -> Option<(&'a Event, Marker)> { self.events.get(*self.pos).map(|event| { *self.pos += 1; (&event.0, event.1) }) } fn jump(&'a self, pos: &'a mut usize) -> Result> { match self.aliases.get(pos) { Some(&found) => { *pos = found; Ok(DeserializerFromEvents { events: self.events, aliases: self.aliases, pos, path: Path::Alias { parent: &self.path }, remaining_depth: self.remaining_depth, }) } None => panic!("unresolved alias: {}", *pos), } } fn ignore_any(&mut self) { enum Nest { Sequence, Mapping, } let mut stack = Vec::new(); while let Some((event, _)) = self.opt_next() { match event { Event::Alias(_) | Event::Scalar(_, _, _) => {} Event::SequenceStart => { stack.push(Nest::Sequence); } Event::MappingStart => { stack.push(Nest::Mapping); } Event::SequenceEnd => match stack.pop() { Some(Nest::Sequence) => {} None | Some(Nest::Mapping) => { panic!("unexpected end of sequence"); } }, Event::MappingEnd => match stack.pop() { Some(Nest::Mapping) => {} None | Some(Nest::Sequence) => { panic!("unexpected end of mapping"); } }, } if stack.is_empty() { return; } } if !stack.is_empty() { panic!("missing end event"); } } fn visit_sequence<'de, V>(&mut self, visitor: V) -> Result where V: Visitor<'de>, { let (value, len) = self.recursion_check(|de| { let mut seq = SeqAccess { de, len: 0 }; let value = visitor.visit_seq(&mut seq)?; Ok((value, seq.len)) })?; self.end_sequence(len)?; Ok(value) } fn visit_mapping<'de, V>(&mut self, visitor: V) -> Result where V: Visitor<'de>, { let (value, len) = self.recursion_check(|de| { let mut map = MapAccess { de, len: 0, key: None, }; let value = visitor.visit_map(&mut map)?; Ok((value, map.len)) })?; self.end_mapping(len)?; Ok(value) } fn end_sequence(&mut self, len: usize) -> Result<()> { let total = { let mut seq = SeqAccess { de: self, len }; while de::SeqAccess::next_element::(&mut seq)?.is_some() {} seq.len }; assert_eq!(Event::SequenceEnd, *self.next()?.0); if total == len { Ok(()) } else { struct ExpectedSeq(usize); impl Expected for ExpectedSeq { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { if self.0 == 1 { write!(formatter, "sequence of 1 element") } else { write!(formatter, "sequence of {} elements", self.0) } } } Err(de::Error::invalid_length(total, &ExpectedSeq(len))) } } fn end_mapping(&mut self, len: usize) -> Result<()> { let total = { let mut map = MapAccess { de: self, len, key: None, }; while de::MapAccess::next_entry::(&mut map)?.is_some() {} map.len }; assert_eq!(Event::MappingEnd, *self.next()?.0); if total == len { Ok(()) } else { struct ExpectedMap(usize); impl Expected for ExpectedMap { fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result { if self.0 == 1 { write!(formatter, "map containing 1 entry") } else { write!(formatter, "map containing {} entries", self.0) } } } Err(de::Error::invalid_length(total, &ExpectedMap(len))) } } fn recursion_check Result, T>(&mut self, f: F) -> Result { let previous_depth = self.remaining_depth; self.remaining_depth = previous_depth .checked_sub(1) .ok_or_else(error::recursion_limit_exceeded)?; let result = f(self); self.remaining_depth = previous_depth; result } } fn visit_scalar<'de, V>( v: &str, style: TScalarStyle, tag: &Option, visitor: V, ) -> Result where V: Visitor<'de>, { if let Some(TokenType::Tag(handle, suffix)) = tag { if handle == "!!" { match suffix.as_ref() { "bool" => match v.parse::() { Ok(v) => visitor.visit_bool(v), Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &"a boolean")), }, "int" => match v.parse::() { Ok(v) => visitor.visit_i64(v), Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &"an integer")), }, "float" => match v.parse::() { Ok(v) => visitor.visit_f64(v), Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &"a float")), }, "null" => match v { "~" | "null" => visitor.visit_unit(), _ => Err(de::Error::invalid_value(Unexpected::Str(v), &"null")), }, _ => visitor.visit_str(v), } } else { visitor.visit_str(v) } } else if style == TScalarStyle::Plain { visit_untagged_str(visitor, v) } else { visitor.visit_str(v) } } struct SeqAccess<'a: 'r, 'r> { de: &'r mut DeserializerFromEvents<'a>, len: usize, } impl<'de, 'a, 'r> de::SeqAccess<'de> for SeqAccess<'a, 'r> { type Error = Error; fn next_element_seed(&mut self, seed: T) -> Result> where T: DeserializeSeed<'de>, { match self.de.peek()?.0 { Event::SequenceEnd => Ok(None), _ => { let mut element_de = DeserializerFromEvents { events: self.de.events, aliases: self.de.aliases, pos: self.de.pos, path: Path::Seq { parent: &self.de.path, index: self.len, }, remaining_depth: self.de.remaining_depth, }; self.len += 1; seed.deserialize(&mut element_de).map(Some) } } } } struct MapAccess<'a: 'r, 'r> { de: &'r mut DeserializerFromEvents<'a>, len: usize, key: Option<&'a str>, } impl<'de, 'a, 'r> de::MapAccess<'de> for MapAccess<'a, 'r> { type Error = Error; fn next_key_seed(&mut self, seed: K) -> Result> where K: DeserializeSeed<'de>, { match self.de.peek()?.0 { Event::MappingEnd => Ok(None), Event::Scalar(key, _, _) => { self.len += 1; self.key = Some(key); seed.deserialize(&mut *self.de).map(Some) } _ => { self.len += 1; self.key = None; seed.deserialize(&mut *self.de).map(Some) } } } fn next_value_seed(&mut self, seed: V) -> Result where V: DeserializeSeed<'de>, { let mut value_de = DeserializerFromEvents { events: self.de.events, aliases: self.de.aliases, pos: self.de.pos, path: if let Some(key) = self.key { Path::Map { parent: &self.de.path, key, } } else { Path::Unknown { parent: &self.de.path, } }, remaining_depth: self.de.remaining_depth, }; seed.deserialize(&mut value_de) } } struct EnumAccess<'a: 'r, 'r> { de: &'r mut DeserializerFromEvents<'a>, name: &'static str, tag: Option<&'static str>, } impl<'de, 'a, 'r> de::EnumAccess<'de> for EnumAccess<'a, 'r> { type Error = Error; type Variant = DeserializerFromEvents<'r>; fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>, { #[derive(Debug)] enum Nope {} struct BadKey { name: &'static str, } impl<'de> Visitor<'de> for BadKey { type Value = Nope; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { write!(formatter, "variant of enum `{}`", self.name) } } let variant = if let Some(tag) = self.tag { tag } else { match self.de.next()?.0 { Event::Scalar(s, _, _) => &**s, _ => { *self.de.pos -= 1; let bad = BadKey { name: self.name }; return Err(de::Deserializer::deserialize_any(&mut *self.de, bad).unwrap_err()); } } }; let str_de = IntoDeserializer::::into_deserializer(variant); let ret = seed.deserialize(str_de)?; let variant_visitor = DeserializerFromEvents { events: self.de.events, aliases: self.de.aliases, pos: self.de.pos, path: Path::Map { parent: &self.de.path, key: variant, }, remaining_depth: self.de.remaining_depth, }; Ok((ret, variant_visitor)) } } impl<'de, 'a> de::VariantAccess<'de> for DeserializerFromEvents<'a> { type Error = Error; fn unit_variant(mut self) -> Result<()> { Deserialize::deserialize(&mut self) } fn newtype_variant_seed(mut self, seed: T) -> Result where T: DeserializeSeed<'de>, { seed.deserialize(&mut self) } fn tuple_variant(mut self, _len: usize, visitor: V) -> Result where V: Visitor<'de>, { de::Deserializer::deserialize_seq(&mut self, visitor) } fn struct_variant(mut self, fields: &'static [&'static str], visitor: V) -> Result where V: Visitor<'de>, { de::Deserializer::deserialize_struct(&mut self, "", fields, visitor) } } struct UnitVariantAccess<'a: 'r, 'r> { de: &'r mut DeserializerFromEvents<'a>, } impl<'de, 'a, 'r> de::EnumAccess<'de> for UnitVariantAccess<'a, 'r> { type Error = Error; type Variant = Self; fn variant_seed(self, seed: V) -> Result<(V::Value, Self::Variant)> where V: DeserializeSeed<'de>, { Ok((seed.deserialize(&mut *self.de)?, self)) } } impl<'de, 'a, 'r> de::VariantAccess<'de> for UnitVariantAccess<'a, 'r> { type Error = Error; fn unit_variant(self) -> Result<()> { Ok(()) } fn newtype_variant_seed(self, _seed: T) -> Result where T: DeserializeSeed<'de>, { Err(de::Error::invalid_type( Unexpected::UnitVariant, &"newtype variant", )) } fn tuple_variant(self, _len: usize, _visitor: V) -> Result where V: Visitor<'de>, { Err(de::Error::invalid_type( Unexpected::UnitVariant, &"tuple variant", )) } fn struct_variant(self, _fields: &'static [&'static str], _visitor: V) -> Result where V: Visitor<'de>, { Err(de::Error::invalid_type( Unexpected::UnitVariant, &"struct variant", )) } } fn visit_untagged_str<'de, V>(visitor: V, v: &str) -> Result where V: Visitor<'de>, { if v == "~" || v == "null" { return visitor.visit_unit(); } if v == "true" { return visitor.visit_bool(true); } if v == "false" { return visitor.visit_bool(false); } if let Some(rest) = Option::or(v.strip_prefix("0x"), v.strip_prefix("+0x")) { if let Ok(n) = u64::from_str_radix(rest, 16) { return visitor.visit_u64(n); } } if let Some(rest) = v.strip_prefix("-0x") { let negative = format!("-{}", rest); if let Ok(n) = i64::from_str_radix(&negative, 16) { return visitor.visit_i64(n); } } if let Some(rest) = Option::or(v.strip_prefix("0o"), v.strip_prefix("+0o")) { if let Ok(n) = u64::from_str_radix(rest, 8) { return visitor.visit_u64(n); } } if let Some(rest) = v.strip_prefix("-0o") { let negative = format!("-{}", rest); if let Ok(n) = i64::from_str_radix(&negative, 8) { return visitor.visit_i64(n); } } if let Some(rest) = Option::or(v.strip_prefix("0b"), v.strip_prefix("+0b")) { if let Ok(n) = u64::from_str_radix(rest, 2) { return visitor.visit_u64(n); } } if let Some(rest) = v.strip_prefix("-0b") { let negative = format!("-{}", rest); if let Ok(n) = i64::from_str_radix(&negative, 2) { return visitor.visit_i64(n); } } if { let v = v.trim_start_matches(&['-', '+'][..]); v.len() > 1 && v.starts_with('0') && v[1..].bytes().all(|b| b.is_ascii_digit()) } { // After handling the different number encodings above if we are left // with leading zero(s) followed by numeric characters this is in fact a // string according to the YAML 1.2 spec. // https://yaml.org/spec/1.2/spec.html#id2761292 return visitor.visit_str(v); } if let Ok(n) = v.parse() { return visitor.visit_u64(n); } if let Ok(n) = v.parse() { return visitor.visit_u128(n); } if let Ok(n) = v.parse() { return visitor.visit_i64(n); } if let Ok(n) = v.parse() { return visitor.visit_i128(n); } match v.trim_start_matches('+') { ".inf" | ".Inf" | ".INF" => return visitor.visit_f64(f64::INFINITY), _ => (), } if v == "-.inf" || v == "-.Inf" || v == "-.INF" { return visitor.visit_f64(f64::NEG_INFINITY); } if v == ".nan" || v == ".NaN" || v == ".NAN" { return visitor.visit_f64(f64::NAN); } if let Ok(n) = v.parse::() { if n.is_finite() { return visitor.visit_f64(n); } } visitor.visit_str(v) } fn invalid_type(event: &Event, exp: &dyn Expected) -> Error { enum Void {} struct InvalidType<'a> { exp: &'a dyn Expected, } impl<'de, 'a> Visitor<'de> for InvalidType<'a> { type Value = Void; fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result { self.exp.fmt(formatter) } } match event { Event::Alias(_) => unreachable!(), Event::Scalar(v, style, tag) => { let get_type = InvalidType { exp }; match visit_scalar(v, *style, tag, get_type) { Ok(void) => match void {}, Err(invalid_type) => invalid_type, } } Event::SequenceStart => de::Error::invalid_type(Unexpected::Seq, exp), Event::MappingStart => de::Error::invalid_type(Unexpected::Map, exp), Event::SequenceEnd => panic!("unexpected end of sequence"), Event::MappingEnd => panic!("unexpected end of mapping"), } } impl<'a> DeserializerFromEvents<'a> { fn deserialize_scalar<'de, V>(&mut self, visitor: V) -> Result where V: Visitor<'de>, { let (next, marker) = self.next()?; match next { Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_scalar(visitor), Event::Scalar(v, style, tag) => visit_scalar(v, *style, tag, visitor), other => Err(invalid_type(other, &visitor)), } .map_err(|err| error::fix_marker(err, marker, self.path)) } } impl<'de, 'a, 'r> de::Deserializer<'de> for &'r mut DeserializerFromEvents<'a> { type Error = Error; fn deserialize_any(self, visitor: V) -> Result where V: Visitor<'de>, { let (next, marker) = self.next()?; match next { Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_any(visitor), Event::Scalar(v, style, tag) => visit_scalar(v, *style, tag, visitor), Event::SequenceStart => self.visit_sequence(visitor), Event::MappingStart => self.visit_mapping(visitor), Event::SequenceEnd => panic!("unexpected end of sequence"), Event::MappingEnd => panic!("unexpected end of mapping"), } // The de::Error impl creates errors with unknown line and column. Fill // in the position here by looking at the current index in the input. .map_err(|err| error::fix_marker(err, marker, self.path)) } fn deserialize_bool(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_i8(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_i16(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_i32(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_i64(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_i128(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_u8(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_u16(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_u32(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_u64(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_u128(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_f32(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_f64(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_char(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_str(visitor) } fn deserialize_str(self, visitor: V) -> Result where V: Visitor<'de>, { let (next, marker) = self.next()?; match next { Event::Scalar(v, _, _) => visitor.visit_str(v), Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_str(visitor), other => Err(invalid_type(other, &visitor)), } .map_err(|err: Error| error::fix_marker(err, marker, self.path)) } fn deserialize_string(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_str(visitor) } fn deserialize_bytes(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_any(visitor) } fn deserialize_byte_buf(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_bytes(visitor) } /// Parses `null` as None and any other values as `Some(...)`. fn deserialize_option(self, visitor: V) -> Result where V: Visitor<'de>, { let is_some = match self.peek()?.0 { Event::Alias(mut pos) => { *self.pos += 1; return self.jump(&mut pos)?.deserialize_option(visitor); } Event::Scalar(v, style, tag) => { if *style != TScalarStyle::Plain { true } else if let Some(TokenType::Tag(handle, suffix)) = tag { if handle == "!!" && suffix == "null" { if v == "~" || v == "null" { false } else { return Err(de::Error::invalid_value(Unexpected::Str(v), &"null")); } } else { true } } else { v != "~" && v != "null" } } Event::SequenceStart | Event::MappingStart => true, Event::SequenceEnd => panic!("unexpected end of sequence"), Event::MappingEnd => panic!("unexpected end of mapping"), }; if is_some { visitor.visit_some(self) } else { *self.pos += 1; visitor.visit_none() } } fn deserialize_unit(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_scalar(visitor) } fn deserialize_unit_struct(self, _name: &'static str, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_unit(visitor) } /// Parses a newtype struct as the underlying value. fn deserialize_newtype_struct(self, _name: &'static str, visitor: V) -> Result where V: Visitor<'de>, { visitor.visit_newtype_struct(self) } fn deserialize_seq(self, visitor: V) -> Result where V: Visitor<'de>, { let (next, marker) = self.next()?; match next { Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_seq(visitor), Event::SequenceStart => self.visit_sequence(visitor), other => Err(invalid_type(other, &visitor)), } .map_err(|err| error::fix_marker(err, marker, self.path)) } fn deserialize_tuple(self, _len: usize, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_seq(visitor) } fn deserialize_tuple_struct( self, _name: &'static str, _len: usize, visitor: V, ) -> Result where V: Visitor<'de>, { self.deserialize_seq(visitor) } fn deserialize_map(self, visitor: V) -> Result where V: Visitor<'de>, { let (next, marker) = self.next()?; match next { Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_map(visitor), Event::MappingStart => self.visit_mapping(visitor), other => Err(invalid_type(other, &visitor)), } .map_err(|err| error::fix_marker(err, marker, self.path)) } fn deserialize_struct( self, name: &'static str, fields: &'static [&'static str], visitor: V, ) -> Result where V: Visitor<'de>, { let (next, marker) = self.next()?; match next { Event::Alias(mut pos) => self .jump(&mut pos)? .deserialize_struct(name, fields, visitor), Event::SequenceStart => self.visit_sequence(visitor), Event::MappingStart => self.visit_mapping(visitor), other => Err(invalid_type(other, &visitor)), } .map_err(|err| error::fix_marker(err, marker, self.path)) } /// Parses an enum as a single key:value pair where the key identifies the /// variant and the value gives the content. A String will also parse correctly /// to a unit enum value. fn deserialize_enum( self, name: &'static str, variants: &'static [&'static str], visitor: V, ) -> Result where V: Visitor<'de>, { let (next, marker) = self.peek()?; match next { Event::Alias(mut pos) => { *self.pos += 1; self.jump(&mut pos)? .deserialize_enum(name, variants, visitor) } Event::Scalar(_, _, t) => { if let Some(TokenType::Tag(handle, suffix)) = t { if handle == "!" { if let Some(tag) = variants.iter().find(|v| *v == suffix) { return visitor.visit_enum(EnumAccess { de: self, name, tag: Some(tag), }); } } } visitor.visit_enum(UnitVariantAccess { de: self }) } Event::MappingStart => { *self.pos += 1; let value = visitor.visit_enum(EnumAccess { de: self, name, tag: None, })?; self.end_mapping(1)?; Ok(value) } Event::SequenceStart => { let err = de::Error::invalid_type(Unexpected::Seq, &"string or singleton map"); Err(error::fix_marker(err, marker, self.path)) } Event::SequenceEnd => panic!("unexpected end of sequence"), Event::MappingEnd => panic!("unexpected end of mapping"), } } fn deserialize_identifier(self, visitor: V) -> Result where V: Visitor<'de>, { self.deserialize_str(visitor) } fn deserialize_ignored_any(self, visitor: V) -> Result where V: Visitor<'de>, { self.ignore_any(); visitor.visit_unit() } } /// Deserialize an instance of type `T` from a string of YAML text. /// /// This conversion can fail if the structure of the Value does not match the /// structure expected by `T`, for example if `T` is a struct type but the Value /// contains something other than a YAML map. It can also fail if the structure /// is correct but `T`'s implementation of `Deserialize` decides that something /// is wrong with the data, for example required struct fields are missing from /// the YAML map or some number is too big to fit in the expected primitive /// type. /// /// YAML currently does not support zero-copy deserialization. pub fn from_str(s: &str) -> Result where T: DeserializeOwned, { from_str_seed(s, PhantomData) } /// Deserialize an instance of type `T` from a string of YAML text with a seed. /// /// This conversion can fail if the structure of the Value does not match the /// structure expected by `T`, for example if `T` is a struct type but the Value /// contains something other than a YAML map. It can also fail if the structure /// is correct but `T`'s implementation of `Deserialize` decides that something /// is wrong with the data, for example required struct fields are missing from /// the YAML map or some number is too big to fit in the expected primitive /// type. /// /// YAML currently does not support zero-copy deserialization. pub fn from_str_seed(s: &str, seed: S) -> Result where S: for<'de> DeserializeSeed<'de, Value = T>, { seed.deserialize(Deserializer::from_str(s)) } /// Deserialize an instance of type `T` from an IO stream of YAML. /// /// This conversion can fail if the structure of the Value does not match the /// structure expected by `T`, for example if `T` is a struct type but the Value /// contains something other than a YAML map. It can also fail if the structure /// is correct but `T`'s implementation of `Deserialize` decides that something /// is wrong with the data, for example required struct fields are missing from /// the YAML map or some number is too big to fit in the expected primitive /// type. pub fn from_reader(rdr: R) -> Result where R: io::Read, T: DeserializeOwned, { from_reader_seed(rdr, PhantomData) } /// Deserialize an instance of type `T` from an IO stream of YAML with a seed. /// /// This conversion can fail if the structure of the Value does not match the /// structure expected by `T`, for example if `T` is a struct type but the Value /// contains something other than a YAML map. It can also fail if the structure /// is correct but `T`'s implementation of `Deserialize` decides that something /// is wrong with the data, for example required struct fields are missing from /// the YAML map or some number is too big to fit in the expected primitive /// type. pub fn from_reader_seed(rdr: R, seed: S) -> Result where R: io::Read, S: for<'de> DeserializeSeed<'de, Value = T>, { seed.deserialize(Deserializer::from_reader(rdr)) } /// Deserialize an instance of type `T` from bytes of YAML text. /// /// This conversion can fail if the structure of the Value does not match the /// structure expected by `T`, for example if `T` is a struct type but the Value /// contains something other than a YAML map. It can also fail if the structure /// is correct but `T`'s implementation of `Deserialize` decides that something /// is wrong with the data, for example required struct fields are missing from /// the YAML map or some number is too big to fit in the expected primitive /// type. /// /// YAML currently does not support zero-copy deserialization. pub fn from_slice(v: &[u8]) -> Result where T: DeserializeOwned, { from_slice_seed(v, PhantomData) } /// Deserialize an instance of type `T` from bytes of YAML text with a seed. /// /// This conversion can fail if the structure of the Value does not match the /// structure expected by `T`, for example if `T` is a struct type but the Value /// contains something other than a YAML map. It can also fail if the structure /// is correct but `T`'s implementation of `Deserialize` decides that something /// is wrong with the data, for example required struct fields are missing from /// the YAML map or some number is too big to fit in the expected primitive /// type. /// /// YAML currently does not support zero-copy deserialization. pub fn from_slice_seed(v: &[u8], seed: S) -> Result where S: for<'de> DeserializeSeed<'de, Value = T>, { seed.deserialize(Deserializer::from_slice(v)) }