summaryrefslogtreecommitdiffstats
path: root/third_party/rust/serde_yaml/src/value
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-19 00:47:55 +0000
commit26a029d407be480d791972afb5975cf62c9360a6 (patch)
treef435a8308119effd964b339f76abb83a57c29483 /third_party/rust/serde_yaml/src/value
parentInitial commit. (diff)
downloadfirefox-26a029d407be480d791972afb5975cf62c9360a6.tar.xz
firefox-26a029d407be480d791972afb5975cf62c9360a6.zip
Adding upstream version 124.0.1.upstream/124.0.1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/rust/serde_yaml/src/value')
-rw-r--r--third_party/rust/serde_yaml/src/value/de.rs707
-rw-r--r--third_party/rust/serde_yaml/src/value/from.rs180
-rw-r--r--third_party/rust/serde_yaml/src/value/index.rs260
-rw-r--r--third_party/rust/serde_yaml/src/value/mod.rs648
-rw-r--r--third_party/rust/serde_yaml/src/value/partial_eq.rs149
-rw-r--r--third_party/rust/serde_yaml/src/value/ser.rs25
6 files changed, 1969 insertions, 0 deletions
diff --git a/third_party/rust/serde_yaml/src/value/de.rs b/third_party/rust/serde_yaml/src/value/de.rs
new file mode 100644
index 0000000000..61e0469693
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/de.rs
@@ -0,0 +1,707 @@
+use crate::{number, Error, Mapping, Sequence, Value};
+use serde::de::{
+ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as SError, Expected,
+ MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor,
+};
+use serde::forward_to_deserialize_any;
+use std::fmt;
+use std::vec;
+
+impl<'de> Deserialize<'de> for Value {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct ValueVisitor;
+
+ impl<'de> Visitor<'de> for ValueVisitor {
+ type Value = Value;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("any YAML value")
+ }
+
+ fn visit_bool<E>(self, b: bool) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Bool(b))
+ }
+
+ fn visit_i64<E>(self, i: i64) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Number(i.into()))
+ }
+
+ fn visit_u64<E>(self, u: u64) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Number(u.into()))
+ }
+
+ fn visit_f64<E>(self, f: f64) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Number(f.into()))
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::String(s.to_owned()))
+ }
+
+ fn visit_string<E>(self, s: String) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::String(s))
+ }
+
+ fn visit_unit<E>(self) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Null)
+ }
+
+ fn visit_none<E>(self) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Null)
+ }
+
+ fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer)
+ }
+
+ fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error>
+ where
+ V: SeqAccess<'de>,
+ {
+ let mut vec = Vec::new();
+
+ while let Some(element) = visitor.next_element()? {
+ vec.push(element);
+ }
+
+ Ok(Value::Sequence(vec))
+ }
+
+ fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
+ where
+ V: MapAccess<'de>,
+ {
+ let mut values = Mapping::new();
+
+ while let Some((key, value)) = visitor.next_entry()? {
+ values.insert(key, value);
+ }
+
+ Ok(Value::Mapping(values))
+ }
+ }
+
+ deserializer.deserialize_any(ValueVisitor)
+ }
+}
+
+impl Value {
+ fn deserialize_number<'de, V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Number(n) => n.deserialize_any(visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+}
+
+fn visit_sequence<'de, V>(sequence: Sequence, visitor: V) -> Result<V::Value, Error>
+where
+ V: Visitor<'de>,
+{
+ let len = sequence.len();
+ let mut deserializer = SeqDeserializer::new(sequence);
+ let seq = visitor.visit_seq(&mut deserializer)?;
+ let remaining = deserializer.iter.len();
+ if remaining == 0 {
+ Ok(seq)
+ } else {
+ Err(Error::invalid_length(len, &"fewer elements in sequence"))
+ }
+}
+
+fn visit_mapping<'de, V>(mapping: Mapping, visitor: V) -> Result<V::Value, Error>
+where
+ V: Visitor<'de>,
+{
+ let len = mapping.len();
+ let mut deserializer = MapDeserializer::new(mapping);
+ let map = visitor.visit_map(&mut deserializer)?;
+ let remaining = deserializer.iter.len();
+ if remaining == 0 {
+ Ok(map)
+ } else {
+ Err(Error::invalid_length(len, &"fewer elements in map"))
+ }
+}
+
+impl<'de> Deserializer<'de> for Value {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Null => visitor.visit_unit(),
+ Value::Bool(v) => visitor.visit_bool(v),
+ Value::Number(n) => n.deserialize_any(visitor),
+ Value::String(v) => visitor.visit_string(v),
+ Value::Sequence(v) => visit_sequence(v, visitor),
+ Value::Mapping(v) => visit_mapping(v, visitor),
+ }
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Bool(v) => visitor.visit_bool(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_string(visitor)
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_string(visitor)
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::String(v) => visitor.visit_string(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_byte_buf(visitor)
+ }
+
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::String(v) => visitor.visit_string(v),
+ Value::Sequence(v) => visit_sequence(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Null => visitor.visit_none(),
+ _ => visitor.visit_some(self),
+ }
+ }
+
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Null => visitor.visit_unit(),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_unit(visitor)
+ }
+
+ fn deserialize_newtype_struct<V>(
+ self,
+ _name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_newtype_struct(self)
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Sequence(v) => visit_sequence(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_tuple_struct<V>(
+ self,
+ _name: &'static str,
+ _len: usize,
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Mapping(v) => visit_mapping(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ _name: &'static str,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Sequence(v) => visit_sequence(v, visitor),
+ Value::Mapping(v) => visit_mapping(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ _name: &str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ let (variant, value) = match self {
+ Value::Mapping(value) => {
+ let mut iter = value.into_iter();
+ let (variant, value) = match iter.next() {
+ Some(v) => v,
+ None => {
+ return Err(Error::invalid_value(
+ Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ };
+ // enums are encoded in json as maps with a single key:value pair
+ if iter.next().is_some() {
+ return Err(Error::invalid_value(
+ Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ (variant, Some(value))
+ }
+ Value::String(variant) => (Value::String(variant), None),
+ other => {
+ return Err(Error::invalid_type(other.unexpected(), &"string or map"));
+ }
+ };
+
+ visitor.visit_enum(EnumDeserializer { variant, value })
+ }
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_string(visitor)
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ drop(self);
+ visitor.visit_unit()
+ }
+}
+
+struct EnumDeserializer {
+ variant: Value,
+ value: Option<Value>,
+}
+
+impl<'de> EnumAccess<'de> for EnumDeserializer {
+ type Error = Error;
+ type Variant = VariantDeserializer;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ let visitor = VariantDeserializer { value: self.value };
+ seed.deserialize(self.variant).map(|v| (v, visitor))
+ }
+}
+
+struct VariantDeserializer {
+ value: Option<Value>,
+}
+
+impl<'de> VariantAccess<'de> for VariantDeserializer {
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<(), Error> {
+ match self.value {
+ Some(value) => Deserialize::deserialize(value),
+ None => Ok(()),
+ }
+ }
+
+ fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.value {
+ Some(value) => seed.deserialize(value),
+ None => Err(Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"newtype variant",
+ )),
+ }
+ }
+
+ fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.value {
+ Some(Value::Sequence(v)) => {
+ Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
+ }
+ Some(other) => Err(Error::invalid_type(other.unexpected(), &"tuple variant")),
+ None => Err(Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"tuple variant",
+ )),
+ }
+ }
+
+ fn struct_variant<V>(
+ self,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.value {
+ Some(Value::Mapping(v)) => {
+ Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
+ }
+ Some(other) => Err(Error::invalid_type(other.unexpected(), &"struct variant")),
+ None => Err(Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"struct variant",
+ )),
+ }
+ }
+}
+
+struct SeqDeserializer {
+ iter: vec::IntoIter<Value>,
+}
+
+impl SeqDeserializer {
+ fn new(vec: Vec<Value>) -> Self {
+ SeqDeserializer {
+ iter: vec.into_iter(),
+ }
+ }
+}
+
+impl<'de> Deserializer<'de> for SeqDeserializer {
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ let len = self.iter.len();
+ if len == 0 {
+ visitor.visit_unit()
+ } else {
+ let ret = visitor.visit_seq(&mut self)?;
+ let remaining = self.iter.len();
+ if remaining == 0 {
+ Ok(ret)
+ } else {
+ Err(Error::invalid_length(len, &"fewer elements in sequence"))
+ }
+ }
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ drop(self);
+ visitor.visit_unit()
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
+ byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
+ map struct enum identifier
+ }
+}
+
+impl<'de> SeqAccess<'de> for SeqDeserializer {
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some(value) => seed.deserialize(value).map(Some),
+ None => Ok(None),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ match self.iter.size_hint() {
+ (lower, Some(upper)) if lower == upper => Some(upper),
+ _ => None,
+ }
+ }
+}
+
+struct MapDeserializer {
+ iter: <Mapping as IntoIterator>::IntoIter,
+ value: Option<Value>,
+}
+
+impl MapDeserializer {
+ fn new(map: Mapping) -> Self {
+ MapDeserializer {
+ iter: map.into_iter(),
+ value: None,
+ }
+ }
+}
+
+impl<'de> MapAccess<'de> for MapDeserializer {
+ type Error = Error;
+
+ fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some((key, value)) => {
+ self.value = Some(value);
+ seed.deserialize(key).map(Some)
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.value.take() {
+ Some(value) => seed.deserialize(value),
+ None => panic!("visit_value called before visit_key"),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ match self.iter.size_hint() {
+ (lower, Some(upper)) if lower == upper => Some(upper),
+ _ => None,
+ }
+ }
+}
+
+impl<'de> Deserializer<'de> for MapDeserializer {
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_map(self)
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ drop(self);
+ visitor.visit_unit()
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
+ byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
+ map struct enum identifier
+ }
+}
+
+impl Value {
+ #[cold]
+ fn invalid_type<E>(&self, exp: &dyn Expected) -> E
+ where
+ E: de::Error,
+ {
+ de::Error::invalid_type(self.unexpected(), exp)
+ }
+
+ #[cold]
+ fn unexpected(&self) -> Unexpected {
+ match self {
+ Value::Null => Unexpected::Unit,
+ Value::Bool(b) => Unexpected::Bool(*b),
+ Value::Number(n) => number::unexpected(n),
+ Value::String(s) => Unexpected::Str(s),
+ Value::Sequence(_) => Unexpected::Seq,
+ Value::Mapping(_) => Unexpected::Map,
+ }
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/value/from.rs b/third_party/rust/serde_yaml/src/value/from.rs
new file mode 100644
index 0000000000..c02855d3b1
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/from.rs
@@ -0,0 +1,180 @@
+use crate::{Mapping, Value};
+
+// Implement a bunch of conversion to make it easier to create YAML values
+// on the fly.
+
+macro_rules! from_number {
+ ($($ty:ident)*) => {
+ $(
+ impl From<$ty> for Value {
+ fn from(n: $ty) -> Self {
+ Value::Number(n.into())
+ }
+ }
+ )*
+ };
+}
+
+from_number! {
+ i8 i16 i32 i64 isize
+ u8 u16 u32 u64 usize
+ f32 f64
+}
+
+impl From<bool> for Value {
+ /// Convert boolean to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let b = false;
+ /// let x: Value = b.into();
+ /// ```
+ fn from(f: bool) -> Self {
+ Value::Bool(f)
+ }
+}
+
+impl From<String> for Value {
+ /// Convert `String` to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let s: String = "lorem".to_string();
+ /// let x: Value = s.into();
+ /// ```
+ fn from(f: String) -> Self {
+ Value::String(f)
+ }
+}
+
+impl<'a> From<&'a str> for Value {
+ /// Convert string slice to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let s: &str = "lorem";
+ /// let x: Value = s.into();
+ /// ```
+ fn from(f: &str) -> Self {
+ Value::String(f.to_string())
+ }
+}
+
+use std::borrow::Cow;
+
+impl<'a> From<Cow<'a, str>> for Value {
+ /// Convert copy-on-write string to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ /// use std::borrow::Cow;
+ ///
+ /// let s: Cow<str> = Cow::Borrowed("lorem");
+ /// let x: Value = s.into();
+ /// ```
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ /// use std::borrow::Cow;
+ ///
+ /// let s: Cow<str> = Cow::Owned("lorem".to_string());
+ /// let x: Value = s.into();
+ /// ```
+ fn from(f: Cow<'a, str>) -> Self {
+ Value::String(f.to_string())
+ }
+}
+
+impl From<Mapping> for Value {
+ /// Convert map (with string keys) to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::{Mapping, Value};
+ ///
+ /// let mut m = Mapping::new();
+ /// m.insert("Lorem".into(), "ipsum".into());
+ /// let x: Value = m.into();
+ /// ```
+ fn from(f: Mapping) -> Self {
+ Value::Mapping(f)
+ }
+}
+
+impl<T: Into<Value>> From<Vec<T>> for Value {
+ /// Convert a `Vec` to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let v = vec!["lorem", "ipsum", "dolor"];
+ /// let x: Value = v.into();
+ /// ```
+ fn from(f: Vec<T>) -> Self {
+ Value::Sequence(f.into_iter().map(Into::into).collect())
+ }
+}
+
+impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value {
+ /// Convert a slice to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let v: &[&str] = &["lorem", "ipsum", "dolor"];
+ /// let x: Value = v.into();
+ /// ```
+ fn from(f: &'a [T]) -> Self {
+ Value::Sequence(f.iter().cloned().map(Into::into).collect())
+ }
+}
+
+use std::iter::FromIterator;
+
+impl<T: Into<Value>> FromIterator<T> for Value {
+ /// Convert an iteratable type to a YAML sequence
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let v = std::iter::repeat(42).take(5);
+ /// let x: Value = v.collect();
+ /// ```
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"];
+ /// let x: Value = v.into_iter().collect();
+ /// ```
+ ///
+ /// ```
+ /// use std::iter::FromIterator;
+ /// use serde_yaml::Value;
+ ///
+ /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]);
+ /// ```
+ fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
+ let vec = iter.into_iter().map(T::into).collect();
+
+ Value::Sequence(vec)
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/value/index.rs b/third_party/rust/serde_yaml/src/value/index.rs
new file mode 100644
index 0000000000..b5f5e90160
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/index.rs
@@ -0,0 +1,260 @@
+use crate::{Mapping, Value};
+use std::fmt;
+use std::ops;
+
+/// A type that can be used to index into a `serde_yaml::Value`. See the `get`
+/// and `get_mut` methods of `Value`.
+///
+/// This trait is sealed and cannot be implemented for types outside of
+/// `serde_yaml`.
+pub trait Index: private::Sealed {
+ /// Return None if the key is not already in the sequence or object.
+ #[doc(hidden)]
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>;
+
+ /// Return None if the key is not already in the sequence or object.
+ #[doc(hidden)]
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>;
+
+ /// Panic if sequence index out of bounds. If key is not already in the object,
+ /// insert it with a value of null. Panic if Value is a type that cannot be
+ /// indexed into, except if Value is null then it can be treated as an empty
+ /// object.
+ #[doc(hidden)]
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value;
+}
+
+impl Index for usize {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ match v {
+ Value::Sequence(vec) => vec.get(*self),
+ Value::Mapping(vec) => vec.get(&Value::Number((*self).into())),
+ _ => None,
+ }
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ match v {
+ Value::Sequence(vec) => vec.get_mut(*self),
+ Value::Mapping(vec) => vec.get_mut(&Value::Number((*self).into())),
+ _ => None,
+ }
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ match v {
+ Value::Sequence(vec) => {
+ let len = vec.len();
+ vec.get_mut(*self).unwrap_or_else(|| {
+ panic!(
+ "cannot access index {} of YAML sequence of length {}",
+ self, len
+ )
+ })
+ }
+ Value::Mapping(map) => {
+ let n = Value::Number((*self).into());
+ // TODO: use entry() once LinkedHashMap supports entry()
+ // https://github.com/contain-rs/linked-hash-map/issues/5
+ if !map.contains_key(&n) {
+ map.insert(n.clone(), Value::Null);
+ }
+ map.get_mut(&n).unwrap()
+ }
+ _ => panic!("cannot access index {} of YAML {}", self, Type(v)),
+ }
+ }
+}
+
+impl Index for Value {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ match v {
+ Value::Mapping(map) => map.get(self),
+ _ => None,
+ }
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ match v {
+ Value::Mapping(map) => map.get_mut(self),
+ _ => None,
+ }
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ if let Value::Null = *v {
+ let mut map = Mapping::new();
+ map.insert(self.clone(), Value::Null);
+ *v = Value::Mapping(map);
+ }
+ match v {
+ Value::Mapping(map) => {
+ // TODO: use entry() once LinkedHashMap supports entry()
+ // https://github.com/contain-rs/linked-hash-map/issues/5
+ if !map.contains_key(self) {
+ map.insert(self.clone(), Value::Null);
+ }
+ map.get_mut(self).unwrap()
+ }
+ _ => panic!("cannot access key {:?} in YAML {}", self, Type(v)),
+ }
+ }
+}
+
+impl Index for str {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ Value::String(self.into()).index_into(v)
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ Value::String(self.into()).index_into_mut(v)
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ Value::String(self.into()).index_or_insert(v)
+ }
+}
+
+impl Index for String {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ Value::String(self.clone()).index_into(v)
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ Value::String(self.clone()).index_into_mut(v)
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ Value::String(self.clone()).index_or_insert(v)
+ }
+}
+
+impl<'a, T> Index for &'a T
+where
+ T: ?Sized + Index,
+{
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ (**self).index_into(v)
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ (**self).index_into_mut(v)
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ (**self).index_or_insert(v)
+ }
+}
+
+// Prevent users from implementing the Index trait.
+mod private {
+ pub trait Sealed {}
+ impl Sealed for usize {}
+ impl Sealed for str {}
+ impl Sealed for String {}
+ impl Sealed for super::Value {}
+ impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {}
+}
+
+/// Used in panic messages.
+struct Type<'a>(&'a Value);
+
+impl<'a> fmt::Display for Type<'a> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self.0 {
+ Value::Null => formatter.write_str("null"),
+ Value::Bool(_) => formatter.write_str("boolean"),
+ Value::Number(_) => formatter.write_str("number"),
+ Value::String(_) => formatter.write_str("string"),
+ Value::Sequence(_) => formatter.write_str("sequence"),
+ Value::Mapping(_) => formatter.write_str("mapping"),
+ }
+ }
+}
+
+// The usual semantics of Index is to panic on invalid indexing.
+//
+// That said, the usual semantics are for things like `Vec` and `BTreeMap` which
+// have different use cases than Value. If you are working with a Vec, you know
+// that you are working with a Vec and you can get the len of the Vec and make
+// sure your indices are within bounds. The Value use cases are more
+// loosey-goosey. You got some YAML from an endpoint and you want to pull values
+// out of it. Outside of this Index impl, you already have the option of using
+// `value.as_sequence()` and working with the Vec directly, or matching on
+// `Value::Sequence` and getting the Vec directly. The Index impl means you can
+// skip that and index directly into the thing using a concise syntax. You don't
+// have to check the type, you don't have to check the len, it is all about what
+// you expect the Value to look like.
+//
+// Basically the use cases that would be well served by panicking here are
+// better served by using one of the other approaches: `get` and `get_mut`,
+// `as_sequence`, or match. The value of this impl is that it adds a way of
+// working with Value that is not well served by the existing approaches:
+// concise and careless and sometimes that is exactly what you want.
+impl<I> ops::Index<I> for Value
+where
+ I: Index,
+{
+ type Output = Value;
+
+ /// Index into a `serde_yaml::Value` using the syntax `value[0]` or
+ /// `value["k"]`.
+ ///
+ /// Returns `Value::Null` if the type of `self` does not match the type of
+ /// the index, for example if the index is a string and `self` is a sequence
+ /// or a number. Also returns `Value::Null` if the given key does not exist
+ /// in the map or the given index is not within the bounds of the sequence.
+ ///
+ /// For retrieving deeply nested values, you should have a look at the
+ /// `Value::pointer` method.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let data = yaml(r#"{ x: { y: [z, zz] } }"#);
+ ///
+ /// assert_eq!(data["x"]["y"], yaml(r#"["z", "zz"]"#));
+ /// assert_eq!(data["x"]["y"][0], yaml(r#""z""#));
+ ///
+ /// assert_eq!(data["a"], yaml(r#"null"#)); // returns null for undefined values
+ /// assert_eq!(data["a"]["b"], yaml(r#"null"#)); // does not panic
+ /// ```
+ fn index(&self, index: I) -> &Value {
+ static NULL: Value = Value::Null;
+ index.index_into(self).unwrap_or(&NULL)
+ }
+}
+
+impl<I> ops::IndexMut<I> for Value
+where
+ I: Index,
+{
+ /// Write into a `serde_yaml::Value` using the syntax `value[0] = ...` or
+ /// `value["k"] = ...`.
+ ///
+ /// If the index is a number, the value must be a sequence of length bigger
+ /// than the index. Indexing into a value that is not a sequence or a
+ /// sequence that is too small will panic.
+ ///
+ /// If the index is a string, the value must be an object or null which is
+ /// treated like an empty object. If the key is not already present in the
+ /// object, it will be inserted with a value of null. Indexing into a value
+ /// that is neither an object nor null will panic.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let mut data = yaml(r#"{x: 0}"#);
+ ///
+ /// // replace an existing key
+ /// data["x"] = yaml(r#"1"#);
+ ///
+ /// // insert a new key
+ /// data["y"] = yaml(r#"[false, false, false]"#);
+ ///
+ /// // replace a value in a sequence
+ /// data["y"][0] = yaml(r#"true"#);
+ ///
+ /// // inserted a deeply nested key
+ /// data["a"]["b"]["c"]["d"] = yaml(r#"true"#);
+ ///
+ /// println!("{:?}", data);
+ /// ```
+ fn index_mut(&mut self, index: I) -> &mut Value {
+ index.index_or_insert(self)
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/value/mod.rs b/third_party/rust/serde_yaml/src/value/mod.rs
new file mode 100644
index 0000000000..a71091bffb
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/mod.rs
@@ -0,0 +1,648 @@
+mod de;
+mod from;
+mod index;
+mod partial_eq;
+mod ser;
+
+use crate::ser::SerializerToYaml;
+use crate::{Error, Mapping};
+use serde::de::{Deserialize, DeserializeOwned, IntoDeserializer};
+use serde::Serialize;
+use std::f64;
+use std::hash::{Hash, Hasher};
+use std::str::FromStr;
+use yaml_rust::Yaml;
+
+pub use self::index::Index;
+pub use crate::number::Number;
+
+/// Represents any valid YAML value.
+#[derive(Clone, PartialOrd, Debug)]
+pub enum Value {
+ /// Represents a YAML null value.
+ Null,
+ /// Represents a YAML boolean.
+ Bool(bool),
+ /// Represents a YAML numerical value, whether integer or floating point.
+ Number(Number),
+ /// Represents a YAML string.
+ String(String),
+ /// Represents a YAML sequence in which the elements are
+ /// `serde_yaml::Value`.
+ Sequence(Sequence),
+ /// Represents a YAML mapping in which the keys and values are both
+ /// `serde_yaml::Value`.
+ Mapping(Mapping),
+}
+
+/// The default value is `Value::Null`.
+///
+/// This is useful for handling omitted `Value` fields when deserializing.
+///
+/// # Examples
+///
+/// ```
+/// # use serde_derive::Deserialize;
+/// use serde::Deserialize;
+/// use serde_yaml::Value;
+///
+/// #[derive(Deserialize)]
+/// struct Settings {
+/// level: i32,
+/// #[serde(default)]
+/// extras: Value,
+/// }
+///
+/// # fn try_main() -> Result<(), serde_yaml::Error> {
+/// let data = r#" { "level": 42 } "#;
+/// let s: Settings = serde_yaml::from_str(data)?;
+///
+/// assert_eq!(s.level, 42);
+/// assert_eq!(s.extras, Value::Null);
+/// #
+/// # Ok(())
+/// # }
+/// #
+/// # try_main().unwrap()
+/// ```
+impl Default for Value {
+ fn default() -> Value {
+ Value::Null
+ }
+}
+
+/// A YAML sequence in which the elements are `serde_yaml::Value`.
+pub type Sequence = Vec<Value>;
+
+/// Convert a `T` into `serde_yaml::Value` which is an enum that can represent
+/// any valid YAML data.
+///
+/// This conversion can fail if `T`'s implementation of `Serialize` decides to
+/// return an error.
+///
+/// ```
+/// # use serde_yaml::Value;
+/// let val = serde_yaml::to_value("s").unwrap();
+/// assert_eq!(val, Value::String("s".to_owned()));
+/// ```
+pub fn to_value<T>(value: T) -> Result<Value, Error>
+where
+ T: Serialize,
+{
+ value.serialize(SerializerToYaml).map(yaml_to_value)
+}
+
+/// Interpret a `serde_yaml::Value` as an instance of type `T`.
+///
+/// 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.
+///
+/// ```
+/// # use serde_yaml::Value;
+/// let val = Value::String("foo".to_owned());
+/// let s: String = serde_yaml::from_value(val).unwrap();
+/// assert_eq!("foo", s);
+/// ```
+pub fn from_value<T>(value: Value) -> Result<T, Error>
+where
+ T: DeserializeOwned,
+{
+ Deserialize::deserialize(value)
+}
+
+impl Value {
+ /// Index into a YAML sequence or map. A string index can be used to access
+ /// a value in a map, and a usize index can be used to access an element of
+ /// an sequence.
+ ///
+ /// Returns `None` if the type of `self` does not match the type of the
+ /// index, for example if the index is a string and `self` is a sequence or
+ /// a number. Also returns `None` if the given key does not exist in the map
+ /// or the given index is not within the bounds of the sequence.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// #
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let object: Value = yaml(r#"{ A: 65, B: 66, C: 67 }"#);
+ /// let x = object.get("A").unwrap();
+ /// assert_eq!(x, 65);
+ ///
+ /// let sequence: Value = yaml(r#"[ "A", "B", "C" ]"#);
+ /// let x = sequence.get(2).unwrap();
+ /// assert_eq!(x, &Value::String("C".into()));
+ ///
+ /// assert_eq!(sequence.get("A"), None);
+ /// ```
+ ///
+ /// Square brackets can also be used to index into a value in a more concise
+ /// way. This returns `Value::Null` in cases where `get` would have returned
+ /// `None`.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// #
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let object = yaml(r#"
+ /// ---
+ /// A: [a, á, à]
+ /// B: [b, b́]
+ /// C: [c, ć, ć̣, ḉ]
+ /// 42: true
+ /// "#);
+ /// assert_eq!(object["B"][0], Value::String("b".into()));
+ ///
+ /// assert_eq!(object[Value::String("D".into())], Value::Null);
+ /// assert_eq!(object["D"], Value::Null);
+ /// assert_eq!(object[0]["x"]["y"]["z"], Value::Null);
+ ///
+ /// assert_eq!(object[42], Value::Bool(true));
+ /// ```
+ pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
+ index.index_into(self)
+ }
+
+ /// Index into a YAML sequence or map. A string index can be used to access
+ /// a value in a map, and a usize index can be used to access an element of
+ /// an sequence.
+ ///
+ /// Returns `None` if the type of `self` does not match the type of the
+ /// index, for example if the index is a string and `self` is a sequence or
+ /// a number. Also returns `None` if the given key does not exist in the map
+ /// or the given index is not within the bounds of the sequence.
+ pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
+ index.index_into_mut(self)
+ }
+
+ /// Returns true if the `Value` is a Null. Returns false otherwise.
+ ///
+ /// For any Value on which `is_null` returns true, `as_null` is guaranteed
+ /// to return `Some(())`.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("null").unwrap();
+ /// assert!(v.is_null());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert!(!v.is_null());
+ /// ```
+ pub fn is_null(&self) -> bool {
+ if let Value::Null = *self {
+ true
+ } else {
+ false
+ }
+ }
+
+ /// If the `Value` is a Null, returns (). Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("null").unwrap();
+ /// assert_eq!(v.as_null(), Some(()));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_null(), None);
+ /// ```
+ pub fn as_null(&self) -> Option<()> {
+ match self {
+ Value::Null => Some(()),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a Boolean. Returns false otherwise.
+ ///
+ /// For any Value on which `is_boolean` returns true, `as_bool` is
+ /// guaranteed to return the boolean value.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert!(v.is_bool());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("42").unwrap();
+ /// assert!(!v.is_bool());
+ /// ```
+ pub fn is_bool(&self) -> bool {
+ self.as_bool().is_some()
+ }
+
+ /// If the `Value` is a Boolean, returns the associated bool. Returns None
+ /// otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert_eq!(v.as_bool(), Some(true));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("42").unwrap();
+ /// assert_eq!(v.as_bool(), None);
+ /// ```
+ pub fn as_bool(&self) -> Option<bool> {
+ match self {
+ Value::Bool(b) => Some(*b),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a Number. Returns false otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("5").unwrap();
+ /// assert!(v.is_number());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert!(!v.is_number());
+ /// ```
+ pub fn is_number(&self) -> bool {
+ match self {
+ Value::Number(_) => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if the `Value` is an integer between `i64::MIN` and
+ /// `i64::MAX`.
+ ///
+ /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to
+ /// return the integer value.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("1337").unwrap();
+ /// assert!(v.is_i64());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("null").unwrap();
+ /// assert!(!v.is_i64());
+ /// ```
+ pub fn is_i64(&self) -> bool {
+ self.as_i64().is_some()
+ }
+
+ /// If the `Value` is an integer, represent it as i64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("1337").unwrap();
+ /// assert_eq!(v.as_i64(), Some(1337));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_i64(), None);
+ /// ```
+ pub fn as_i64(&self) -> Option<i64> {
+ match self {
+ Value::Number(n) => n.as_i64(),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is an integer between `u64::MIN` and
+ /// `u64::MAX`.
+ ///
+ /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to
+ /// return the integer value.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("1337").unwrap();
+ /// assert!(v.is_u64());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("null").unwrap();
+ /// assert!(!v.is_u64());
+ /// ```
+ pub fn is_u64(&self) -> bool {
+ self.as_u64().is_some()
+ }
+
+ /// If the `Value` is an integer, represent it as u64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("1337").unwrap();
+ /// assert_eq!(v.as_u64(), Some(1337));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_u64(), None);
+ /// ```
+ pub fn as_u64(&self) -> Option<u64> {
+ match self {
+ Value::Number(n) => n.as_u64(),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a number that can be represented by f64.
+ ///
+ /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to
+ /// return the floating point value.
+ ///
+ /// Currently this function returns true if and only if both `is_i64` and
+ /// `is_u64` return false but this is not a guarantee in the future.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("256.01").unwrap();
+ /// assert!(v.is_f64());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert!(!v.is_f64());
+ /// ```
+ pub fn is_f64(&self) -> bool {
+ match self {
+ Value::Number(n) => n.is_f64(),
+ _ => false,
+ }
+ }
+
+ /// If the `Value` is a number, represent it as f64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("13.37").unwrap();
+ /// assert_eq!(v.as_f64(), Some(13.37));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_f64(), None);
+ /// ```
+ pub fn as_f64(&self) -> Option<f64> {
+ match self {
+ Value::Number(i) => i.as_f64(),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a String. Returns false otherwise.
+ ///
+ /// For any Value on which `is_string` returns true, `as_str` is guaranteed
+ /// to return the string slice.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("'lorem ipsum'").unwrap();
+ /// assert!(v.is_string());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("42").unwrap();
+ /// assert!(!v.is_string());
+ /// ```
+ pub fn is_string(&self) -> bool {
+ self.as_str().is_some()
+ }
+
+ /// If the `Value` is a String, returns the associated str. Returns None
+ /// otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("'lorem ipsum'").unwrap();
+ /// assert_eq!(v.as_str(), Some("lorem ipsum"));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_str(), None);
+ /// ```
+ pub fn as_str(&self) -> Option<&str> {
+ match self {
+ Value::String(s) => Some(s),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a sequence. Returns false otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("[1, 2, 3]").unwrap();
+ /// assert!(v.is_sequence());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert!(!v.is_sequence());
+ /// ```
+ pub fn is_sequence(&self) -> bool {
+ self.as_sequence().is_some()
+ }
+
+ /// If the `Value` is a sequence, return a reference to it if possible.
+ /// Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Number};
+ /// let v: Value = serde_yaml::from_str("[1, 2]").unwrap();
+ /// assert_eq!(v.as_sequence(), Some(&vec![Value::Number(Number::from(1)), Value::Number(Number::from(2))]));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_sequence(), None);
+ /// ```
+ pub fn as_sequence(&self) -> Option<&Sequence> {
+ match self {
+ Value::Sequence(seq) => Some(seq),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a sequence, return a mutable reference to it if
+ /// possible. Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Number};
+ /// let mut v: Value = serde_yaml::from_str("[1]").unwrap();
+ /// let s = v.as_sequence_mut().unwrap();
+ /// s.push(Value::Number(Number::from(2)));
+ /// assert_eq!(s, &vec![Value::Number(Number::from(1)), Value::Number(Number::from(2))]);
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let mut v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_sequence_mut(), None);
+ /// ```
+ pub fn as_sequence_mut(&mut self) -> Option<&mut Sequence> {
+ match self {
+ Value::Sequence(seq) => Some(seq),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a mapping. Returns false otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("a: 42").unwrap();
+ /// assert!(v.is_mapping());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert!(!v.is_mapping());
+ /// ```
+ pub fn is_mapping(&self) -> bool {
+ self.as_mapping().is_some()
+ }
+
+ /// If the `Value` is a mapping, return a reference to it if possible.
+ /// Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Mapping, Number};
+ /// let v: Value = serde_yaml::from_str("a: 42").unwrap();
+ ///
+ /// let mut expected = Mapping::new();
+ /// expected.insert(Value::String("a".into()),Value::Number(Number::from(42)));
+ ///
+ /// assert_eq!(v.as_mapping(), Some(&expected));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_mapping(), None);
+ /// ```
+ pub fn as_mapping(&self) -> Option<&Mapping> {
+ match self {
+ Value::Mapping(map) => Some(map),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a mapping, return a reference to it if possible.
+ /// Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Mapping, Number};
+ /// let mut v: Value = serde_yaml::from_str("a: 42").unwrap();
+ /// let m = v.as_mapping_mut().unwrap();
+ /// m.insert(Value::String("b".into()), Value::Number(Number::from(21)));
+ ///
+ /// let mut expected = Mapping::new();
+ /// expected.insert(Value::String("a".into()), Value::Number(Number::from(42)));
+ /// expected.insert(Value::String("b".into()), Value::Number(Number::from(21)));
+ ///
+ /// assert_eq!(m, &expected);
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Mapping};
+ /// let mut v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_mapping_mut(), None);
+ /// ```
+ pub fn as_mapping_mut(&mut self) -> Option<&mut Mapping> {
+ match self {
+ Value::Mapping(map) => Some(map),
+ _ => None,
+ }
+ }
+}
+
+fn yaml_to_value(yaml: Yaml) -> Value {
+ match yaml {
+ Yaml::Real(f) => {
+ if f == ".inf" {
+ Value::Number(f64::INFINITY.into())
+ } else if f == "-.inf" {
+ Value::Number(f64::NEG_INFINITY.into())
+ } else if f == ".nan" {
+ Value::Number(f64::NAN.into())
+ } else if let Ok(n) = u64::from_str(&f) {
+ Value::Number(n.into())
+ } else if let Ok(n) = i64::from_str(&f) {
+ Value::Number(n.into())
+ } else if let Ok(n) = f64::from_str(&f) {
+ Value::Number(n.into())
+ } else {
+ Value::String(f)
+ }
+ }
+ Yaml::Integer(i) => Value::Number(i.into()),
+ Yaml::String(s) => Value::String(s),
+ Yaml::Boolean(b) => Value::Bool(b),
+ Yaml::Array(sequence) => Value::Sequence(sequence.into_iter().map(yaml_to_value).collect()),
+ Yaml::Hash(hash) => Value::Mapping(
+ hash.into_iter()
+ .map(|(k, v)| (yaml_to_value(k), yaml_to_value(v)))
+ .collect(),
+ ),
+ Yaml::Alias(_) => panic!("alias unsupported"),
+ Yaml::Null => Value::Null,
+ Yaml::BadValue => panic!("bad value"),
+ }
+}
+
+impl Eq for Value {}
+
+impl Hash for Value {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ match self {
+ Value::Null => 0.hash(state),
+ Value::Bool(b) => (1, b).hash(state),
+ Value::Number(i) => (2, i).hash(state),
+ Value::String(s) => (3, s).hash(state),
+ Value::Sequence(seq) => (4, seq).hash(state),
+ Value::Mapping(map) => (5, map).hash(state),
+ }
+ }
+}
+
+impl<'de> IntoDeserializer<'de, Error> for Value {
+ type Deserializer = Self;
+
+ fn into_deserializer(self) -> Self::Deserializer {
+ self
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/value/partial_eq.rs b/third_party/rust/serde_yaml/src/value/partial_eq.rs
new file mode 100644
index 0000000000..ff9b1f8f8a
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/partial_eq.rs
@@ -0,0 +1,149 @@
+use crate::Value;
+
+impl PartialEq for Value {
+ fn eq(&self, other: &Value) -> bool {
+ match (self, other) {
+ (Value::Null, Value::Null) => true,
+ (Value::Bool(a), Value::Bool(b)) => a == b,
+ (Value::Number(a), Value::Number(b)) => a == b,
+ (Value::String(a), Value::String(b)) => a == b,
+ (Value::Sequence(a), Value::Sequence(b)) => a == b,
+ (Value::Mapping(a), Value::Mapping(b)) => a == b,
+ _ => false,
+ }
+ }
+}
+
+impl PartialEq<str> for Value {
+ /// Compare `str` with YAML value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!(Value::String("lorem".into()) == *"lorem");
+ /// ```
+ fn eq(&self, other: &str) -> bool {
+ self.as_str().map_or(false, |s| s == other)
+ }
+}
+
+impl<'a> PartialEq<&'a str> for Value {
+ /// Compare `&str` with YAML value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!(Value::String("lorem".into()) == "lorem");
+ /// ```
+ fn eq(&self, other: &&str) -> bool {
+ self.as_str().map_or(false, |s| s == *other)
+ }
+}
+
+impl PartialEq<Value> for str {
+ /// Compare YAML value with `str`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!(*"lorem" == Value::String("lorem".into()));
+ /// ```
+ fn eq(&self, other: &Value) -> bool {
+ other.as_str().map_or(false, |s| s == self)
+ }
+}
+
+impl<'a> PartialEq<Value> for &'a str {
+ /// Compare `&str` with YAML value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!("lorem" == Value::String("lorem".into()));
+ /// ```
+ fn eq(&self, other: &Value) -> bool {
+ other.as_str().map_or(false, |s| s == *self)
+ }
+}
+
+impl PartialEq<String> for Value {
+ /// Compare YAML value with String
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!(Value::String("lorem".into()) == "lorem".to_string());
+ /// ```
+ fn eq(&self, other: &String) -> bool {
+ self.as_str().map_or(false, |s| s == other)
+ }
+}
+
+impl PartialEq<Value> for String {
+ /// Compare `String` with YAML value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!("lorem".to_string() == Value::String("lorem".into()));
+ /// ```
+ fn eq(&self, other: &Value) -> bool {
+ other.as_str().map_or(false, |s| s == self)
+ }
+}
+
+impl PartialEq<bool> for Value {
+ /// Compare YAML value with bool
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!(Value::Bool(true) == true);
+ /// ```
+ fn eq(&self, other: &bool) -> bool {
+ self.as_bool().map_or(false, |b| b == *other)
+ }
+}
+
+macro_rules! partialeq_numeric {
+ ($([$($ty:ty)*], $conversion:ident, $base:ty)*) => {
+ $($(
+ impl PartialEq<$ty> for Value {
+ fn eq(&self, other: &$ty) -> bool {
+ self.$conversion().map_or(false, |i| i == (*other as $base))
+ }
+ }
+
+ impl PartialEq<Value> for $ty {
+ fn eq(&self, other: &Value) -> bool {
+ other.$conversion().map_or(false, |i| i == (*self as $base))
+ }
+ }
+
+ impl<'a> PartialEq<$ty> for &'a Value {
+ fn eq(&self, other: &$ty) -> bool {
+ self.$conversion().map_or(false, |i| i == (*other as $base))
+ }
+ }
+
+ impl<'a> PartialEq<$ty> for &'a mut Value {
+ fn eq(&self, other: &$ty) -> bool {
+ self.$conversion().map_or(false, |i| i == (*other as $base))
+ }
+ }
+ )*)*
+ }
+}
+
+partialeq_numeric! {
+ [i8 i16 i32 i64 isize], as_i64, i64
+ [u8 u16 u32 u64 usize], as_u64, u64
+ [f32 f64], as_f64, f64
+}
diff --git a/third_party/rust/serde_yaml/src/value/ser.rs b/third_party/rust/serde_yaml/src/value/ser.rs
new file mode 100644
index 0000000000..f2c4bb438c
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/ser.rs
@@ -0,0 +1,25 @@
+use crate::Value;
+use serde::Serialize;
+
+impl Serialize for Value {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ match self {
+ Value::Null => serializer.serialize_unit(),
+ Value::Bool(b) => serializer.serialize_bool(*b),
+ Value::Number(n) => n.serialize(serializer),
+ Value::String(s) => serializer.serialize_str(s),
+ Value::Sequence(seq) => seq.serialize(serializer),
+ Value::Mapping(hash) => {
+ use serde::ser::SerializeMap;
+ let mut map = serializer.serialize_map(Some(hash.len()))?;
+ for (k, v) in hash {
+ map.serialize_entry(k, v)?;
+ }
+ map.end()
+ }
+ }
+ }
+}