diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:19 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-30 03:57:19 +0000 |
commit | a0b8f38ab54ac451646aa00cd5e91b6c76f22a84 (patch) | |
tree | fc451898ccaf445814e26b46664d78702178101d /vendor/toml-0.5.11/src/value.rs | |
parent | Adding debian version 1.71.1+dfsg1-2. (diff) | |
download | rustc-a0b8f38ab54ac451646aa00cd5e91b6c76f22a84.tar.xz rustc-a0b8f38ab54ac451646aa00cd5e91b6c76f22a84.zip |
Merging upstream version 1.72.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/toml-0.5.11/src/value.rs')
-rw-r--r-- | vendor/toml-0.5.11/src/value.rs | 1081 |
1 files changed, 1081 insertions, 0 deletions
diff --git a/vendor/toml-0.5.11/src/value.rs b/vendor/toml-0.5.11/src/value.rs new file mode 100644 index 000000000..1a1756d10 --- /dev/null +++ b/vendor/toml-0.5.11/src/value.rs @@ -0,0 +1,1081 @@ +//! Definition of a TOML value + +use std::collections::{BTreeMap, HashMap}; +use std::fmt; +use std::hash::Hash; +use std::mem::discriminant; +use std::ops; +use std::str::FromStr; +use std::vec; + +use serde::de; +use serde::de::IntoDeserializer; +use serde::ser; + +use crate::datetime::{self, DatetimeFromString}; +pub use crate::datetime::{Date, Datetime, DatetimeParseError, Offset, Time}; + +pub use crate::map::{Entry, Map}; + +/// Representation of a TOML value. +#[derive(PartialEq, Clone, Debug)] +pub enum Value { + /// Represents a TOML string + String(String), + /// Represents a TOML integer + Integer(i64), + /// Represents a TOML float + Float(f64), + /// Represents a TOML boolean + Boolean(bool), + /// Represents a TOML datetime + Datetime(Datetime), + /// Represents a TOML array + Array(Array), + /// Represents a TOML table + Table(Table), +} + +/// Type representing a TOML array, payload of the `Value::Array` variant +pub type Array = Vec<Value>; + +/// Type representing a TOML table, payload of the `Value::Table` variant. +/// By default it is backed by a BTreeMap, enable the `preserve_order` feature +/// to use a LinkedHashMap instead. +pub type Table = Map<String, Value>; + +impl Value { + /// Convert a `T` into `toml::Value` which is an enum that can represent + /// any valid TOML data. + /// + /// This conversion can fail if `T`'s implementation of `Serialize` decides to + /// fail, or if `T` contains a map with non-string keys. + pub fn try_from<T>(value: T) -> Result<Value, crate::ser::Error> + where + T: ser::Serialize, + { + value.serialize(Serializer) + } + + /// Interpret a `toml::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 TOML table. 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 TOML map or some number is too big to fit in the expected + /// primitive type. + pub fn try_into<'de, T>(self) -> Result<T, crate::de::Error> + where + T: de::Deserialize<'de>, + { + de::Deserialize::deserialize(self) + } + + /// Index into a TOML array 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 + /// array. + /// + /// 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 an array 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 array. + pub fn get<I: Index>(&self, index: I) -> Option<&Value> { + index.index(self) + } + + /// Mutably index into a TOML array 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 array. + /// + /// 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 an array 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 array. + pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> { + index.index_mut(self) + } + + /// Extracts the integer value if it is an integer. + pub fn as_integer(&self) -> Option<i64> { + match *self { + Value::Integer(i) => Some(i), + _ => None, + } + } + + /// Tests whether this value is an integer. + pub fn is_integer(&self) -> bool { + self.as_integer().is_some() + } + + /// Extracts the float value if it is a float. + pub fn as_float(&self) -> Option<f64> { + match *self { + Value::Float(f) => Some(f), + _ => None, + } + } + + /// Tests whether this value is a float. + pub fn is_float(&self) -> bool { + self.as_float().is_some() + } + + /// Extracts the boolean value if it is a boolean. + pub fn as_bool(&self) -> Option<bool> { + match *self { + Value::Boolean(b) => Some(b), + _ => None, + } + } + + /// Tests whether this value is a boolean. + pub fn is_bool(&self) -> bool { + self.as_bool().is_some() + } + + /// Extracts the string of this value if it is a string. + pub fn as_str(&self) -> Option<&str> { + match *self { + Value::String(ref s) => Some(&**s), + _ => None, + } + } + + /// Tests if this value is a string. + pub fn is_str(&self) -> bool { + self.as_str().is_some() + } + + /// Extracts the datetime value if it is a datetime. + /// + /// Note that a parsed TOML value will only contain ISO 8601 dates. An + /// example date is: + /// + /// ```notrust + /// 1979-05-27T07:32:00Z + /// ``` + pub fn as_datetime(&self) -> Option<&Datetime> { + match *self { + Value::Datetime(ref s) => Some(s), + _ => None, + } + } + + /// Tests whether this value is a datetime. + pub fn is_datetime(&self) -> bool { + self.as_datetime().is_some() + } + + /// Extracts the array value if it is an array. + pub fn as_array(&self) -> Option<&Vec<Value>> { + match *self { + Value::Array(ref s) => Some(s), + _ => None, + } + } + + /// Extracts the array value if it is an array. + pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> { + match *self { + Value::Array(ref mut s) => Some(s), + _ => None, + } + } + + /// Tests whether this value is an array. + pub fn is_array(&self) -> bool { + self.as_array().is_some() + } + + /// Extracts the table value if it is a table. + pub fn as_table(&self) -> Option<&Table> { + match *self { + Value::Table(ref s) => Some(s), + _ => None, + } + } + + /// Extracts the table value if it is a table. + pub fn as_table_mut(&mut self) -> Option<&mut Table> { + match *self { + Value::Table(ref mut s) => Some(s), + _ => None, + } + } + + /// Tests whether this value is a table. + pub fn is_table(&self) -> bool { + self.as_table().is_some() + } + + /// Tests whether this and another value have the same type. + pub fn same_type(&self, other: &Value) -> bool { + discriminant(self) == discriminant(other) + } + + /// Returns a human-readable representation of the type of this value. + pub fn type_str(&self) -> &'static str { + match *self { + Value::String(..) => "string", + Value::Integer(..) => "integer", + Value::Float(..) => "float", + Value::Boolean(..) => "boolean", + Value::Datetime(..) => "datetime", + Value::Array(..) => "array", + Value::Table(..) => "table", + } + } +} + +impl<I> ops::Index<I> for Value +where + I: Index, +{ + type Output = Value; + + fn index(&self, index: I) -> &Value { + self.get(index).expect("index not found") + } +} + +impl<I> ops::IndexMut<I> for Value +where + I: Index, +{ + fn index_mut(&mut self, index: I) -> &mut Value { + self.get_mut(index).expect("index not found") + } +} + +impl<'a> From<&'a str> for Value { + #[inline] + fn from(val: &'a str) -> Value { + Value::String(val.to_string()) + } +} + +impl<V: Into<Value>> From<Vec<V>> for Value { + fn from(val: Vec<V>) -> Value { + Value::Array(val.into_iter().map(|v| v.into()).collect()) + } +} + +impl<S: Into<String>, V: Into<Value>> From<BTreeMap<S, V>> for Value { + fn from(val: BTreeMap<S, V>) -> Value { + let table = val.into_iter().map(|(s, v)| (s.into(), v.into())).collect(); + + Value::Table(table) + } +} + +impl<S: Into<String> + Hash + Eq, V: Into<Value>> From<HashMap<S, V>> for Value { + fn from(val: HashMap<S, V>) -> Value { + let table = val.into_iter().map(|(s, v)| (s.into(), v.into())).collect(); + + Value::Table(table) + } +} + +macro_rules! impl_into_value { + ($variant:ident : $T:ty) => { + impl From<$T> for Value { + #[inline] + fn from(val: $T) -> Value { + Value::$variant(val.into()) + } + } + }; +} + +impl_into_value!(String: String); +impl_into_value!(Integer: i64); +impl_into_value!(Integer: i32); +impl_into_value!(Integer: i8); +impl_into_value!(Integer: u8); +impl_into_value!(Integer: u32); +impl_into_value!(Float: f64); +impl_into_value!(Float: f32); +impl_into_value!(Boolean: bool); +impl_into_value!(Datetime: Datetime); +impl_into_value!(Table: Table); + +/// Types that can be used to index a `toml::Value` +/// +/// Currently this is implemented for `usize` to index arrays and `str` to index +/// tables. +/// +/// This trait is sealed and not intended for implementation outside of the +/// `toml` crate. +pub trait Index: Sealed { + #[doc(hidden)] + fn index<'a>(&self, val: &'a Value) -> Option<&'a Value>; + #[doc(hidden)] + fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value>; +} + +/// An implementation detail that should not be implemented, this will change in +/// the future and break code otherwise. +#[doc(hidden)] +pub trait Sealed {} +impl Sealed for usize {} +impl Sealed for str {} +impl Sealed for String {} +impl<'a, T: Sealed + ?Sized> Sealed for &'a T {} + +impl Index for usize { + fn index<'a>(&self, val: &'a Value) -> Option<&'a Value> { + match *val { + Value::Array(ref a) => a.get(*self), + _ => None, + } + } + + fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value> { + match *val { + Value::Array(ref mut a) => a.get_mut(*self), + _ => None, + } + } +} + +impl Index for str { + fn index<'a>(&self, val: &'a Value) -> Option<&'a Value> { + match *val { + Value::Table(ref a) => a.get(self), + _ => None, + } + } + + fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value> { + match *val { + Value::Table(ref mut a) => a.get_mut(self), + _ => None, + } + } +} + +impl Index for String { + fn index<'a>(&self, val: &'a Value) -> Option<&'a Value> { + self[..].index(val) + } + + fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value> { + self[..].index_mut(val) + } +} + +impl<'s, T: ?Sized> Index for &'s T +where + T: Index, +{ + fn index<'a>(&self, val: &'a Value) -> Option<&'a Value> { + (**self).index(val) + } + + fn index_mut<'a>(&self, val: &'a mut Value) -> Option<&'a mut Value> { + (**self).index_mut(val) + } +} + +impl fmt::Display for Value { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + crate::ser::to_string(self) + .expect("Unable to represent value as string") + .fmt(f) + } +} + +impl FromStr for Value { + type Err = crate::de::Error; + fn from_str(s: &str) -> Result<Value, Self::Err> { + crate::from_str(s) + } +} + +impl ser::Serialize for Value { + fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> + where + S: ser::Serializer, + { + use serde::ser::SerializeMap; + + match *self { + Value::String(ref s) => serializer.serialize_str(s), + Value::Integer(i) => serializer.serialize_i64(i), + Value::Float(f) => serializer.serialize_f64(f), + Value::Boolean(b) => serializer.serialize_bool(b), + Value::Datetime(ref s) => s.serialize(serializer), + Value::Array(ref a) => a.serialize(serializer), + Value::Table(ref t) => { + let mut map = serializer.serialize_map(Some(t.len()))?; + // Be sure to visit non-tables first (and also non + // array-of-tables) as all keys must be emitted first. + for (k, v) in t { + if !v.is_table() && !v.is_array() + || (v + .as_array() + .map(|a| !a.iter().any(|v| v.is_table())) + .unwrap_or(false)) + { + map.serialize_entry(k, v)?; + } + } + for (k, v) in t { + if v.as_array() + .map(|a| a.iter().any(|v| v.is_table())) + .unwrap_or(false) + { + map.serialize_entry(k, v)?; + } + } + for (k, v) in t { + if v.is_table() { + map.serialize_entry(k, v)?; + } + } + map.end() + } + } + } +} + +impl<'de> de::Deserialize<'de> for Value { + fn deserialize<D>(deserializer: D) -> Result<Value, D::Error> + where + D: de::Deserializer<'de>, + { + struct ValueVisitor; + + impl<'de> de::Visitor<'de> for ValueVisitor { + type Value = Value; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("any valid TOML value") + } + + fn visit_bool<E>(self, value: bool) -> Result<Value, E> { + Ok(Value::Boolean(value)) + } + + fn visit_i64<E>(self, value: i64) -> Result<Value, E> { + Ok(Value::Integer(value)) + } + + fn visit_u64<E: de::Error>(self, value: u64) -> Result<Value, E> { + if value <= i64::max_value() as u64 { + Ok(Value::Integer(value as i64)) + } else { + Err(de::Error::custom("u64 value was too large")) + } + } + + fn visit_u32<E>(self, value: u32) -> Result<Value, E> { + Ok(Value::Integer(value.into())) + } + + fn visit_i32<E>(self, value: i32) -> Result<Value, E> { + Ok(Value::Integer(value.into())) + } + + fn visit_f64<E>(self, value: f64) -> Result<Value, E> { + Ok(Value::Float(value)) + } + + fn visit_str<E>(self, value: &str) -> Result<Value, E> { + Ok(Value::String(value.into())) + } + + fn visit_string<E>(self, value: String) -> Result<Value, E> { + Ok(Value::String(value)) + } + + fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error> + where + D: de::Deserializer<'de>, + { + de::Deserialize::deserialize(deserializer) + } + + fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error> + where + V: de::SeqAccess<'de>, + { + let mut vec = Vec::new(); + while let Some(elem) = visitor.next_element()? { + vec.push(elem); + } + Ok(Value::Array(vec)) + } + + fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error> + where + V: de::MapAccess<'de>, + { + let mut key = String::new(); + let datetime = visitor.next_key_seed(DatetimeOrTable { key: &mut key })?; + match datetime { + Some(true) => { + let date: DatetimeFromString = visitor.next_value()?; + return Ok(Value::Datetime(date.value)); + } + None => return Ok(Value::Table(Map::new())), + Some(false) => {} + } + let mut map = Map::new(); + map.insert(key, visitor.next_value()?); + while let Some(key) = visitor.next_key::<String>()? { + if let Entry::Vacant(vacant) = map.entry(&key) { + vacant.insert(visitor.next_value()?); + } else { + let msg = format!("duplicate key: `{}`", key); + return Err(de::Error::custom(msg)); + } + } + Ok(Value::Table(map)) + } + } + + deserializer.deserialize_any(ValueVisitor) + } +} + +impl<'de> de::Deserializer<'de> for Value { + type Error = crate::de::Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, crate::de::Error> + where + V: de::Visitor<'de>, + { + match self { + Value::Boolean(v) => visitor.visit_bool(v), + Value::Integer(n) => visitor.visit_i64(n), + Value::Float(n) => visitor.visit_f64(n), + Value::String(v) => visitor.visit_string(v), + Value::Datetime(v) => visitor.visit_string(v.to_string()), + Value::Array(v) => { + let len = v.len(); + let mut deserializer = SeqDeserializer::new(v); + let seq = visitor.visit_seq(&mut deserializer)?; + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(seq) + } else { + Err(de::Error::invalid_length(len, &"fewer elements in array")) + } + } + Value::Table(v) => { + let len = v.len(); + let mut deserializer = MapDeserializer::new(v); + let map = visitor.visit_map(&mut deserializer)?; + let remaining = deserializer.iter.len(); + if remaining == 0 { + Ok(map) + } else { + Err(de::Error::invalid_length(len, &"fewer elements in map")) + } + } + } + } + + #[inline] + fn deserialize_enum<V>( + self, + _name: &str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, crate::de::Error> + where + V: de::Visitor<'de>, + { + match self { + Value::String(variant) => visitor.visit_enum(variant.into_deserializer()), + _ => Err(de::Error::invalid_type( + de::Unexpected::UnitVariant, + &"string only", + )), + } + } + + // `None` is interpreted as a missing field so be sure to implement `Some` + // as a present field. + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, crate::de::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_some(self) + } + + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, crate::de::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + serde::forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit seq + bytes byte_buf map unit_struct tuple_struct struct + tuple ignored_any identifier + } +} + +struct SeqDeserializer { + iter: vec::IntoIter<Value>, +} + +impl SeqDeserializer { + fn new(vec: Vec<Value>) -> Self { + SeqDeserializer { + iter: vec.into_iter(), + } + } +} + +impl<'de> de::SeqAccess<'de> for SeqDeserializer { + type Error = crate::de::Error; + + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, crate::de::Error> + where + T: de::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: <Map<String, Value> as IntoIterator>::IntoIter, + value: Option<(String, Value)>, +} + +impl MapDeserializer { + fn new(map: Map<String, Value>) -> Self { + MapDeserializer { + iter: map.into_iter(), + value: None, + } + } +} + +impl<'de> de::MapAccess<'de> for MapDeserializer { + type Error = crate::de::Error; + + fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, crate::de::Error> + where + T: de::DeserializeSeed<'de>, + { + match self.iter.next() { + Some((key, value)) => { + self.value = Some((key.clone(), value)); + seed.deserialize(Value::String(key)).map(Some) + } + None => Ok(None), + } + } + + fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, crate::de::Error> + where + T: de::DeserializeSeed<'de>, + { + let (key, res) = match self.value.take() { + Some((key, value)) => (key, seed.deserialize(value)), + None => return Err(de::Error::custom("value is missing")), + }; + res.map_err(|mut error| { + error.add_key_context(&key); + error + }) + } + + fn size_hint(&self) -> Option<usize> { + match self.iter.size_hint() { + (lower, Some(upper)) if lower == upper => Some(upper), + _ => None, + } + } +} + +impl<'de> de::IntoDeserializer<'de, crate::de::Error> for Value { + type Deserializer = Self; + + fn into_deserializer(self) -> Self { + self + } +} + +struct Serializer; + +impl ser::Serializer for Serializer { + type Ok = Value; + type Error = crate::ser::Error; + + type SerializeSeq = SerializeVec; + type SerializeTuple = SerializeVec; + type SerializeTupleStruct = SerializeVec; + type SerializeTupleVariant = SerializeVec; + type SerializeMap = SerializeMap; + type SerializeStruct = SerializeMap; + type SerializeStructVariant = ser::Impossible<Value, crate::ser::Error>; + + fn serialize_bool(self, value: bool) -> Result<Value, crate::ser::Error> { + Ok(Value::Boolean(value)) + } + + fn serialize_i8(self, value: i8) -> Result<Value, crate::ser::Error> { + self.serialize_i64(value.into()) + } + + fn serialize_i16(self, value: i16) -> Result<Value, crate::ser::Error> { + self.serialize_i64(value.into()) + } + + fn serialize_i32(self, value: i32) -> Result<Value, crate::ser::Error> { + self.serialize_i64(value.into()) + } + + fn serialize_i64(self, value: i64) -> Result<Value, crate::ser::Error> { + Ok(Value::Integer(value)) + } + + fn serialize_u8(self, value: u8) -> Result<Value, crate::ser::Error> { + self.serialize_i64(value.into()) + } + + fn serialize_u16(self, value: u16) -> Result<Value, crate::ser::Error> { + self.serialize_i64(value.into()) + } + + fn serialize_u32(self, value: u32) -> Result<Value, crate::ser::Error> { + self.serialize_i64(value.into()) + } + + fn serialize_u64(self, value: u64) -> Result<Value, crate::ser::Error> { + if value <= i64::max_value() as u64 { + self.serialize_i64(value as i64) + } else { + Err(ser::Error::custom("u64 value was too large")) + } + } + + fn serialize_f32(self, value: f32) -> Result<Value, crate::ser::Error> { + self.serialize_f64(value.into()) + } + + fn serialize_f64(self, value: f64) -> Result<Value, crate::ser::Error> { + Ok(Value::Float(value)) + } + + fn serialize_char(self, value: char) -> Result<Value, crate::ser::Error> { + let mut s = String::new(); + s.push(value); + self.serialize_str(&s) + } + + fn serialize_str(self, value: &str) -> Result<Value, crate::ser::Error> { + Ok(Value::String(value.to_owned())) + } + + fn serialize_bytes(self, value: &[u8]) -> Result<Value, crate::ser::Error> { + let vec = value.iter().map(|&b| Value::Integer(b.into())).collect(); + Ok(Value::Array(vec)) + } + + fn serialize_unit(self) -> Result<Value, crate::ser::Error> { + Err(crate::ser::Error::UnsupportedType) + } + + fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, crate::ser::Error> { + Err(crate::ser::Error::UnsupportedType) + } + + fn serialize_unit_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + ) -> Result<Value, crate::ser::Error> { + self.serialize_str(_variant) + } + + fn serialize_newtype_struct<T: ?Sized>( + self, + _name: &'static str, + value: &T, + ) -> Result<Value, crate::ser::Error> + where + T: ser::Serialize, + { + value.serialize(self) + } + + fn serialize_newtype_variant<T: ?Sized>( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _value: &T, + ) -> Result<Value, crate::ser::Error> + where + T: ser::Serialize, + { + Err(crate::ser::Error::UnsupportedType) + } + + fn serialize_none(self) -> Result<Value, crate::ser::Error> { + Err(crate::ser::Error::UnsupportedNone) + } + + fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Value, crate::ser::Error> + where + T: ser::Serialize, + { + value.serialize(self) + } + + fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, crate::ser::Error> { + Ok(SerializeVec { + vec: Vec::with_capacity(len.unwrap_or(0)), + }) + } + + fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, crate::ser::Error> { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_struct( + self, + _name: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleStruct, crate::ser::Error> { + self.serialize_seq(Some(len)) + } + + fn serialize_tuple_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + len: usize, + ) -> Result<Self::SerializeTupleVariant, crate::ser::Error> { + self.serialize_seq(Some(len)) + } + + fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, crate::ser::Error> { + Ok(SerializeMap { + map: Map::new(), + next_key: None, + }) + } + + fn serialize_struct( + self, + _name: &'static str, + len: usize, + ) -> Result<Self::SerializeStruct, crate::ser::Error> { + self.serialize_map(Some(len)) + } + + fn serialize_struct_variant( + self, + _name: &'static str, + _variant_index: u32, + _variant: &'static str, + _len: usize, + ) -> Result<Self::SerializeStructVariant, crate::ser::Error> { + Err(crate::ser::Error::UnsupportedType) + } +} + +struct SerializeVec { + vec: Vec<Value>, +} + +struct SerializeMap { + map: Map<String, Value>, + next_key: Option<String>, +} + +impl ser::SerializeSeq for SerializeVec { + type Ok = Value; + type Error = crate::ser::Error; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error> + where + T: ser::Serialize, + { + self.vec.push(Value::try_from(value)?); + Ok(()) + } + + fn end(self) -> Result<Value, crate::ser::Error> { + Ok(Value::Array(self.vec)) + } +} + +impl ser::SerializeTuple for SerializeVec { + type Ok = Value; + type Error = crate::ser::Error; + + fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error> + where + T: ser::Serialize, + { + ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Value, crate::ser::Error> { + ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeTupleStruct for SerializeVec { + type Ok = Value; + type Error = crate::ser::Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error> + where + T: ser::Serialize, + { + ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Value, crate::ser::Error> { + ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeTupleVariant for SerializeVec { + type Ok = Value; + type Error = crate::ser::Error; + + fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error> + where + T: ser::Serialize, + { + ser::SerializeSeq::serialize_element(self, value) + } + + fn end(self) -> Result<Value, crate::ser::Error> { + ser::SerializeSeq::end(self) + } +} + +impl ser::SerializeMap for SerializeMap { + type Ok = Value; + type Error = crate::ser::Error; + + fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), crate::ser::Error> + where + T: ser::Serialize, + { + match Value::try_from(key)? { + Value::String(s) => self.next_key = Some(s), + _ => return Err(crate::ser::Error::KeyNotString), + }; + Ok(()) + } + + fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error> + where + T: ser::Serialize, + { + let key = self.next_key.take(); + let key = key.expect("serialize_value called before serialize_key"); + match Value::try_from(value) { + Ok(value) => { + self.map.insert(key, value); + } + Err(crate::ser::Error::UnsupportedNone) => {} + Err(e) => return Err(e), + } + Ok(()) + } + + fn end(self) -> Result<Value, crate::ser::Error> { + Ok(Value::Table(self.map)) + } +} + +impl ser::SerializeStruct for SerializeMap { + type Ok = Value; + type Error = crate::ser::Error; + + fn serialize_field<T: ?Sized>( + &mut self, + key: &'static str, + value: &T, + ) -> Result<(), crate::ser::Error> + where + T: ser::Serialize, + { + ser::SerializeMap::serialize_key(self, key)?; + ser::SerializeMap::serialize_value(self, value) + } + + fn end(self) -> Result<Value, crate::ser::Error> { + ser::SerializeMap::end(self) + } +} + +struct DatetimeOrTable<'a> { + key: &'a mut String, +} + +impl<'a, 'de> de::DeserializeSeed<'de> for DatetimeOrTable<'a> { + type Value = bool; + + fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error> + where + D: de::Deserializer<'de>, + { + deserializer.deserialize_any(self) + } +} + +impl<'a, 'de> de::Visitor<'de> for DatetimeOrTable<'a> { + type Value = bool; + + fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result { + formatter.write_str("a string key") + } + + fn visit_str<E>(self, s: &str) -> Result<bool, E> + where + E: de::Error, + { + if s == datetime::FIELD { + Ok(true) + } else { + self.key.push_str(s); + Ok(false) + } + } + + fn visit_string<E>(self, s: String) -> Result<bool, E> + where + E: de::Error, + { + if s == datetime::FIELD { + Ok(true) + } else { + *self.key = s; + Ok(false) + } + } +} |