summaryrefslogtreecommitdiffstats
path: root/vendor/toml-0.5.11/src/value.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:19 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 03:57:19 +0000
commita0b8f38ab54ac451646aa00cd5e91b6c76f22a84 (patch)
treefc451898ccaf445814e26b46664d78702178101d /vendor/toml-0.5.11/src/value.rs
parentAdding debian version 1.71.1+dfsg1-2. (diff)
downloadrustc-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.rs1081
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)
+ }
+ }
+}