summaryrefslogtreecommitdiffstats
path: root/vendor/toml-0.7.5/src
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-07 05:48:48 +0000
commitef24de24a82fe681581cc130f342363c47c0969a (patch)
tree0d494f7e1a38b95c92426f58fe6eaa877303a86c /vendor/toml-0.7.5/src
parentReleasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff)
downloadrustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz
rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/toml-0.7.5/src')
-rw-r--r--vendor/toml-0.7.5/src/de.rs322
-rw-r--r--vendor/toml-0.7.5/src/edit.rs91
-rw-r--r--vendor/toml-0.7.5/src/fmt.rs60
-rw-r--r--vendor/toml-0.7.5/src/lib.rs182
-rw-r--r--vendor/toml-0.7.5/src/macros.rs460
-rw-r--r--vendor/toml-0.7.5/src/map.rs595
-rw-r--r--vendor/toml-0.7.5/src/ser.rs1087
-rw-r--r--vendor/toml-0.7.5/src/table.rs114
-rw-r--r--vendor/toml-0.7.5/src/value.rs1455
9 files changed, 4366 insertions, 0 deletions
diff --git a/vendor/toml-0.7.5/src/de.rs b/vendor/toml-0.7.5/src/de.rs
new file mode 100644
index 000000000..9eb4c4188
--- /dev/null
+++ b/vendor/toml-0.7.5/src/de.rs
@@ -0,0 +1,322 @@
+//! Deserializing TOML into Rust structures.
+//!
+//! This module contains all the Serde support for deserializing TOML documents
+//! into Rust structures. Note that some top-level functions here are also
+//! provided at the top of the crate.
+
+/// Deserializes a string into a type.
+///
+/// This function will attempt to interpret `s` as a TOML document and
+/// deserialize `T` from the document.
+///
+/// To deserializes TOML values, instead of documents, see [`ValueDeserializer`].
+///
+/// # Examples
+///
+/// ```
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize)]
+/// struct Config {
+/// title: String,
+/// owner: Owner,
+/// }
+///
+/// #[derive(Deserialize)]
+/// struct Owner {
+/// name: String,
+/// }
+///
+/// let config: Config = toml::from_str(r#"
+/// title = 'TOML Example'
+///
+/// [owner]
+/// name = 'Lisa'
+/// "#).unwrap();
+///
+/// assert_eq!(config.title, "TOML Example");
+/// assert_eq!(config.owner.name, "Lisa");
+/// ```
+#[cfg(feature = "parse")]
+pub fn from_str<T>(s: &'_ str) -> Result<T, Error>
+where
+ T: serde::de::DeserializeOwned,
+{
+ T::deserialize(Deserializer::new(s))
+}
+
+/// Errors that can occur when deserializing a type.
+#[derive(Debug, PartialEq, Eq, Clone)]
+pub struct Error {
+ inner: crate::edit::de::Error,
+}
+
+impl Error {
+ fn new(inner: crate::edit::de::Error) -> Self {
+ Self { inner }
+ }
+
+ pub(crate) fn add_key(&mut self, key: String) {
+ self.inner.add_key(key)
+ }
+
+ /// What went wrong
+ pub fn message(&self) -> &str {
+ self.inner.message()
+ }
+
+ /// The start/end index into the original document where the error occurred
+ #[cfg(feature = "parse")]
+ pub fn span(&self) -> Option<std::ops::Range<usize>> {
+ self.inner.span()
+ }
+}
+
+impl serde::de::Error for Error {
+ fn custom<T>(msg: T) -> Self
+ where
+ T: std::fmt::Display,
+ {
+ Error::new(crate::edit::de::Error::custom(msg))
+ }
+}
+
+impl std::fmt::Display for Error {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.inner.fmt(f)
+ }
+}
+
+impl std::error::Error for Error {}
+
+/// Deserialization TOML document
+///
+/// To deserializes TOML values, instead of documents, see [`ValueDeserializer`].
+#[cfg(feature = "parse")]
+pub struct Deserializer<'a> {
+ input: &'a str,
+}
+
+#[cfg(feature = "parse")]
+impl<'a> Deserializer<'a> {
+ /// Deserialization implementation for TOML.
+ pub fn new(input: &'a str) -> Self {
+ Self { input }
+ }
+}
+
+#[cfg(feature = "parse")]
+impl<'de, 'a> serde::Deserializer<'de> for Deserializer<'a> {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ let inner = self
+ .input
+ .parse::<toml_edit::de::Deserializer>()
+ .map_err(Error::new)?;
+ inner.deserialize_any(visitor).map_err(Error::new)
+ }
+
+ // `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, Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ let inner = self
+ .input
+ .parse::<toml_edit::de::Deserializer>()
+ .map_err(Error::new)?;
+ inner.deserialize_option(visitor).map_err(Error::new)
+ }
+
+ fn deserialize_newtype_struct<V>(
+ self,
+ name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ let inner = self
+ .input
+ .parse::<toml_edit::de::Deserializer>()
+ .map_err(Error::new)?;
+ inner
+ .deserialize_newtype_struct(name, visitor)
+ .map_err(Error::new)
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ name: &'static str,
+ fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ let inner = self
+ .input
+ .parse::<toml_edit::de::Deserializer>()
+ .map_err(Error::new)?;
+ inner
+ .deserialize_struct(name, fields, visitor)
+ .map_err(Error::new)
+ }
+
+ // Called when the type to deserialize is an enum, as opposed to a field in the type.
+ fn deserialize_enum<V>(
+ self,
+ name: &'static str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ let inner = self
+ .input
+ .parse::<toml_edit::de::Deserializer>()
+ .map_err(Error::new)?;
+ inner
+ .deserialize_enum(name, variants, visitor)
+ .map_err(Error::new)
+ }
+
+ serde::forward_to_deserialize_any! {
+ bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
+ bytes byte_buf map unit
+ ignored_any unit_struct tuple_struct tuple identifier
+ }
+}
+
+/// Deserialization TOML [value][crate::Value]
+///
+/// # Example
+///
+/// ```
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize)]
+/// struct Config {
+/// title: String,
+/// owner: Owner,
+/// }
+///
+/// #[derive(Deserialize)]
+/// struct Owner {
+/// name: String,
+/// }
+///
+/// let config = Config::deserialize(toml::de::ValueDeserializer::new(
+/// r#"{ title = 'TOML Example', owner = { name = 'Lisa' } }"#
+/// )).unwrap();
+///
+/// assert_eq!(config.title, "TOML Example");
+/// assert_eq!(config.owner.name, "Lisa");
+/// ```
+#[cfg(feature = "parse")]
+pub struct ValueDeserializer<'a> {
+ input: &'a str,
+}
+
+#[cfg(feature = "parse")]
+impl<'a> ValueDeserializer<'a> {
+ /// Deserialization implementation for TOML.
+ pub fn new(input: &'a str) -> Self {
+ Self { input }
+ }
+}
+
+#[cfg(feature = "parse")]
+impl<'de, 'a> serde::Deserializer<'de> for ValueDeserializer<'a> {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ let inner = self
+ .input
+ .parse::<toml_edit::de::ValueDeserializer>()
+ .map_err(Error::new)?;
+ inner.deserialize_any(visitor).map_err(Error::new)
+ }
+
+ // `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, Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ let inner = self
+ .input
+ .parse::<toml_edit::de::ValueDeserializer>()
+ .map_err(Error::new)?;
+ inner.deserialize_option(visitor).map_err(Error::new)
+ }
+
+ fn deserialize_newtype_struct<V>(
+ self,
+ name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ let inner = self
+ .input
+ .parse::<toml_edit::de::ValueDeserializer>()
+ .map_err(Error::new)?;
+ inner
+ .deserialize_newtype_struct(name, visitor)
+ .map_err(Error::new)
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ name: &'static str,
+ fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ let inner = self
+ .input
+ .parse::<toml_edit::de::ValueDeserializer>()
+ .map_err(Error::new)?;
+ inner
+ .deserialize_struct(name, fields, visitor)
+ .map_err(Error::new)
+ }
+
+ // Called when the type to deserialize is an enum, as opposed to a field in the type.
+ fn deserialize_enum<V>(
+ self,
+ name: &'static str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ let inner = self
+ .input
+ .parse::<toml_edit::de::ValueDeserializer>()
+ .map_err(Error::new)?;
+ inner
+ .deserialize_enum(name, variants, visitor)
+ .map_err(Error::new)
+ }
+
+ serde::forward_to_deserialize_any! {
+ bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
+ bytes byte_buf map unit
+ ignored_any unit_struct tuple_struct tuple identifier
+ }
+}
diff --git a/vendor/toml-0.7.5/src/edit.rs b/vendor/toml-0.7.5/src/edit.rs
new file mode 100644
index 000000000..90fb284ca
--- /dev/null
+++ b/vendor/toml-0.7.5/src/edit.rs
@@ -0,0 +1,91 @@
+#[cfg(feature = "parse")]
+pub(crate) mod de {
+ pub(crate) use toml_edit::de::Error;
+}
+
+#[cfg(not(feature = "parse"))]
+pub(crate) mod de {
+ /// Errors that can occur when deserializing a type.
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ pub struct Error {
+ inner: String,
+ }
+
+ impl Error {
+ /// Add key while unwinding
+ pub fn add_key(&mut self, _key: String) {}
+
+ /// What went wrong
+ pub fn message(&self) -> &str {
+ self.inner.as_str()
+ }
+ }
+
+ impl serde::de::Error for Error {
+ fn custom<T>(msg: T) -> Self
+ where
+ T: std::fmt::Display,
+ {
+ Error {
+ inner: msg.to_string(),
+ }
+ }
+ }
+
+ impl std::fmt::Display for Error {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.inner.fmt(f)
+ }
+ }
+
+ impl std::error::Error for Error {}
+}
+
+#[cfg(feature = "display")]
+pub(crate) mod ser {
+ pub(crate) use toml_edit::ser::Error;
+}
+
+#[cfg(not(feature = "display"))]
+pub(crate) mod ser {
+ #[derive(Debug, Clone, PartialEq, Eq)]
+ #[non_exhaustive]
+ pub(crate) enum Error {
+ UnsupportedType(Option<&'static str>),
+ UnsupportedNone,
+ KeyNotString,
+ Custom(String),
+ }
+
+ impl Error {
+ pub(crate) fn custom<T>(msg: T) -> Self
+ where
+ T: std::fmt::Display,
+ {
+ Error::Custom(msg.to_string())
+ }
+ }
+
+ impl serde::ser::Error for Error {
+ fn custom<T>(msg: T) -> Self
+ where
+ T: std::fmt::Display,
+ {
+ Self::custom(msg)
+ }
+ }
+
+ impl std::fmt::Display for Error {
+ fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ match self {
+ Self::UnsupportedType(Some(t)) => write!(formatter, "unsupported {t} type"),
+ Self::UnsupportedType(None) => write!(formatter, "unsupported rust type"),
+ Self::UnsupportedNone => "unsupported None value".fmt(formatter),
+ Self::KeyNotString => "map key was not a string".fmt(formatter),
+ Self::Custom(s) => s.fmt(formatter),
+ }
+ }
+ }
+
+ impl std::error::Error for Error {}
+}
diff --git a/vendor/toml-0.7.5/src/fmt.rs b/vendor/toml-0.7.5/src/fmt.rs
new file mode 100644
index 000000000..0e96bf050
--- /dev/null
+++ b/vendor/toml-0.7.5/src/fmt.rs
@@ -0,0 +1,60 @@
+#[derive(Copy, Clone, Default)]
+pub(crate) struct DocumentFormatter {
+ pub(crate) multiline_array: bool,
+}
+
+impl toml_edit::visit_mut::VisitMut for DocumentFormatter {
+ fn visit_document_mut(&mut self, node: &mut toml_edit::Document) {
+ toml_edit::visit_mut::visit_document_mut(self, node);
+ }
+
+ fn visit_item_mut(&mut self, node: &mut toml_edit::Item) {
+ let other = std::mem::take(node);
+ let other = match other.into_table().map(toml_edit::Item::Table) {
+ Ok(i) => i,
+ Err(i) => i,
+ };
+ let other = match other
+ .into_array_of_tables()
+ .map(toml_edit::Item::ArrayOfTables)
+ {
+ Ok(i) => i,
+ Err(i) => i,
+ };
+ *node = other;
+
+ toml_edit::visit_mut::visit_item_mut(self, node);
+ }
+
+ fn visit_table_mut(&mut self, node: &mut toml_edit::Table) {
+ node.decor_mut().clear();
+
+ // Empty tables could be semantically meaningful, so make sure they are not implicit
+ if !node.is_empty() {
+ node.set_implicit(true);
+ }
+
+ toml_edit::visit_mut::visit_table_mut(self, node);
+ }
+
+ fn visit_value_mut(&mut self, node: &mut toml_edit::Value) {
+ node.decor_mut().clear();
+
+ toml_edit::visit_mut::visit_value_mut(self, node);
+ }
+
+ fn visit_array_mut(&mut self, node: &mut toml_edit::Array) {
+ toml_edit::visit_mut::visit_array_mut(self, node);
+
+ if !self.multiline_array || (0..=1).contains(&node.len()) {
+ node.set_trailing("");
+ node.set_trailing_comma(false);
+ } else {
+ for item in node.iter_mut() {
+ item.decor_mut().set_prefix("\n ");
+ }
+ node.set_trailing("\n");
+ node.set_trailing_comma(true);
+ }
+ }
+}
diff --git a/vendor/toml-0.7.5/src/lib.rs b/vendor/toml-0.7.5/src/lib.rs
new file mode 100644
index 000000000..61e6a4c75
--- /dev/null
+++ b/vendor/toml-0.7.5/src/lib.rs
@@ -0,0 +1,182 @@
+//! A [serde]-compatible [TOML]-parsing library
+//!
+//! TOML itself is a simple, ergonomic, and readable configuration format:
+//!
+//! ```toml
+//! [package]
+//! name = "toml"
+//! version = "0.4.2"
+//! authors = ["Alex Crichton <alex@alexcrichton.com>"]
+//!
+//! [dependencies]
+//! serde = "1.0"
+//! ```
+//!
+//! The TOML format tends to be relatively common throughout the Rust community
+//! for configuration, notably being used by [Cargo], Rust's package manager.
+//!
+//! ## TOML values
+//!
+//! A TOML document is represented with the [`Table`] type which maps `String` to the [`Value`] enum:
+//!
+//! ```rust
+//! # use toml::value::{Datetime, Array, Table};
+//! pub enum Value {
+//! String(String),
+//! Integer(i64),
+//! Float(f64),
+//! Boolean(bool),
+//! Datetime(Datetime),
+//! Array(Array),
+//! Table(Table),
+//! }
+//! ```
+//!
+//! ## Parsing TOML
+//!
+//! The easiest way to parse a TOML document is via the [`Table`] type:
+//!
+#![cfg_attr(not(feature = "parse"), doc = " ```ignore")]
+#![cfg_attr(feature = "parse", doc = " ```")]
+//! use toml::Table;
+//!
+//! let value = "foo = 'bar'".parse::<Table>().unwrap();
+//!
+//! assert_eq!(value["foo"].as_str(), Some("bar"));
+//! ```
+//!
+//! The [`Table`] type implements a number of convenience methods and
+//! traits; the example above uses [`FromStr`] to parse a [`str`] into a
+//! [`Table`].
+//!
+//! ## Deserialization and Serialization
+//!
+//! This crate supports [`serde`] 1.0 with a number of
+//! implementations of the `Deserialize`, `Serialize`, `Deserializer`, and
+//! `Serializer` traits. Namely, you'll find:
+//!
+//! * `Deserialize for Table`
+//! * `Serialize for Table`
+//! * `Deserialize for Value`
+//! * `Serialize for Value`
+//! * `Deserialize for Datetime`
+//! * `Serialize for Datetime`
+//! * `Deserializer for de::Deserializer`
+//! * `Serializer for ser::Serializer`
+//! * `Deserializer for Table`
+//! * `Deserializer for Value`
+//!
+//! This means that you can use Serde to deserialize/serialize the
+//! [`Table`] type as well as [`Value`] and [`Datetime`] type in this crate. You can also
+//! use the [`Deserializer`], [`Serializer`], or [`Table`] type itself to act as
+//! a deserializer/serializer for arbitrary types.
+//!
+//! An example of deserializing with TOML is:
+//!
+#![cfg_attr(not(feature = "parse"), doc = " ```ignore")]
+#![cfg_attr(feature = "parse", doc = " ```")]
+//! use serde::Deserialize;
+//!
+//! #[derive(Deserialize)]
+//! struct Config {
+//! ip: String,
+//! port: Option<u16>,
+//! keys: Keys,
+//! }
+//!
+//! #[derive(Deserialize)]
+//! struct Keys {
+//! github: String,
+//! travis: Option<String>,
+//! }
+//!
+//! let config: Config = toml::from_str(r#"
+//! ip = '127.0.0.1'
+//!
+//! [keys]
+//! github = 'xxxxxxxxxxxxxxxxx'
+//! travis = 'yyyyyyyyyyyyyyyyy'
+//! "#).unwrap();
+//!
+//! assert_eq!(config.ip, "127.0.0.1");
+//! assert_eq!(config.port, None);
+//! assert_eq!(config.keys.github, "xxxxxxxxxxxxxxxxx");
+//! assert_eq!(config.keys.travis.as_ref().unwrap(), "yyyyyyyyyyyyyyyyy");
+//! ```
+//!
+//! You can serialize types in a similar fashion:
+//!
+#![cfg_attr(not(feature = "display"), doc = " ```ignore")]
+#![cfg_attr(feature = "display", doc = " ```")]
+//! use serde::Serialize;
+//!
+//! #[derive(Serialize)]
+//! struct Config {
+//! ip: String,
+//! port: Option<u16>,
+//! keys: Keys,
+//! }
+//!
+//! #[derive(Serialize)]
+//! struct Keys {
+//! github: String,
+//! travis: Option<String>,
+//! }
+//!
+//! let config = Config {
+//! ip: "127.0.0.1".to_string(),
+//! port: None,
+//! keys: Keys {
+//! github: "xxxxxxxxxxxxxxxxx".to_string(),
+//! travis: Some("yyyyyyyyyyyyyyyyy".to_string()),
+//! },
+//! };
+//!
+//! let toml = toml::to_string(&config).unwrap();
+//! ```
+//!
+//! [TOML]: https://github.com/toml-lang/toml
+//! [Cargo]: https://crates.io/
+//! [`serde`]: https://serde.rs/
+//! [serde]: https://serde.rs/
+
+#![deny(missing_docs)]
+#![warn(rust_2018_idioms)]
+// Makes rustc abort compilation if there are any unsafe blocks in the crate.
+// Presence of this annotation is picked up by tools such as cargo-geiger
+// and lets them ensure that there is indeed no unsafe code as opposed to
+// something they couldn't detect (e.g. unsafe added via macro expansion, etc).
+#![forbid(unsafe_code)]
+#![cfg_attr(docsrs, feature(doc_auto_cfg))]
+
+pub mod map;
+pub mod value;
+
+pub mod de;
+pub mod ser;
+
+#[doc(hidden)]
+pub mod macros;
+
+mod edit;
+#[cfg(feature = "display")]
+mod fmt;
+mod table;
+
+#[cfg(feature = "parse")]
+#[doc(inline)]
+pub use crate::de::{from_str, Deserializer};
+#[cfg(feature = "display")]
+#[doc(inline)]
+pub use crate::ser::{to_string, to_string_pretty, Serializer};
+#[doc(inline)]
+pub use crate::value::Value;
+
+pub use serde_spanned::Spanned;
+pub use table::Table;
+
+// Shortcuts for the module doc-comment
+#[allow(unused_imports)]
+use core::str::FromStr;
+#[allow(unused_imports)]
+use toml_datetime::Datetime;
diff --git a/vendor/toml-0.7.5/src/macros.rs b/vendor/toml-0.7.5/src/macros.rs
new file mode 100644
index 000000000..d86cc52f5
--- /dev/null
+++ b/vendor/toml-0.7.5/src/macros.rs
@@ -0,0 +1,460 @@
+pub use serde::de::{Deserialize, IntoDeserializer};
+
+use crate::value::{Array, Table, Value};
+
+/// Construct a [`Table`] from TOML syntax.
+///
+/// ```rust
+/// let cargo_toml = toml::toml! {
+/// [package]
+/// name = "toml"
+/// version = "0.4.5"
+/// authors = ["Alex Crichton <alex@alexcrichton.com>"]
+///
+/// [badges]
+/// travis-ci = { repository = "alexcrichton/toml-rs" }
+///
+/// [dependencies]
+/// serde = "1.0"
+///
+/// [dev-dependencies]
+/// serde_derive = "1.0"
+/// serde_json = "1.0"
+/// };
+///
+/// println!("{:#?}", cargo_toml);
+/// ```
+#[macro_export]
+macro_rules! toml {
+ ($($toml:tt)+) => {{
+ let table = $crate::value::Table::new();
+ let mut root = $crate::Value::Table(table);
+ $crate::toml_internal!(@toplevel root [] $($toml)+);
+ match root {
+ $crate::Value::Table(table) => table,
+ _ => unreachable!(),
+ }
+ }};
+}
+
+// TT-muncher to parse TOML syntax into a toml::Value.
+//
+// @toplevel -- Parse tokens outside of an inline table or inline array. In
+// this state, `[table headers]` and `[[array headers]]` are
+// allowed and `key = value` pairs are not separated by commas.
+//
+// @topleveldatetime -- Helper to parse a Datetime from string and insert it
+// into a table, continuing in the @toplevel state.
+//
+// @path -- Turn a path segment into a string. Segments that look like idents
+// are stringified, while quoted segments like `"cfg(windows)"`
+// are not.
+//
+// @value -- Parse the value part of a `key = value` pair, which may be a
+// primitive or inline table or inline array.
+//
+// @table -- Parse the contents of an inline table, returning them as a
+// toml::Value::Table.
+//
+// @tabledatetime -- Helper to parse a Datetime from string and insert it
+// into a table, continuing in the @table state.
+//
+// @array -- Parse the contents of an inline array, returning them as a
+// toml::Value::Array.
+//
+// @arraydatetime -- Helper to parse a Datetime from string and push it into
+// an array, continuing in the @array state.
+//
+// @trailingcomma -- Helper to append a comma to a sequence of tokens if the
+// sequence is non-empty and does not already end in a trailing
+// comma.
+//
+#[macro_export]
+#[doc(hidden)]
+macro_rules! toml_internal {
+ // Base case, no elements remaining.
+ (@toplevel $root:ident [$($path:tt)*]) => {};
+
+ // Parse negative number `key = -value`.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = - $v:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@toplevel $root [$($path)*] $($($k)-+).+ = (-$v) $($rest)*);
+ };
+
+ // Parse positive number `key = +value`.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = + $v:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@toplevel $root [$($path)*] $($($k)-+).+ = ($v) $($rest)*);
+ };
+
+ // Parse offset datetime `key = 1979-05-27T00:32:00.999999-07:00`.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
+ };
+ // Space instead of T.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
+ };
+
+ // Parse offset datetime `key = 1979-05-27T00:32:00-07:00`.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
+ };
+ // Space instead of T.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*);
+ };
+
+ // Parse local datetime `key = 1979-05-27T00:32:00.999999`.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
+ };
+ // Space instead of T.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*);
+ };
+
+ // Parse offset datetime `key = 1979-05-27T07:32:00Z` and local datetime `key = 1979-05-27T07:32:00`.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*);
+ };
+ // Space instead of T.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec) $($rest)*);
+ };
+
+ // Parse local date `key = 1979-05-27`.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($yr - $mo - $day) $($rest)*);
+ };
+
+ // Parse local time `key = 00:32:00.999999`.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt . $frac:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($hr : $min : $sec . $frac) $($rest)*);
+ };
+
+ // Parse local time `key = 07:32:00`.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt $($rest:tt)*) => {
+ $crate::toml_internal!(@topleveldatetime $root [$($path)*] $($($k)-+).+ = ($hr : $min : $sec) $($rest)*);
+ };
+
+ // Parse any other `key = value` including string, inline array, inline
+ // table, number, and boolean.
+ (@toplevel $root:ident [$($path:tt)*] $($($k:tt)-+).+ = $v:tt $($rest:tt)*) => {{
+ $crate::macros::insert_toml(
+ &mut $root,
+ &[$($path)* $(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
+ $crate::toml_internal!(@value $v));
+ $crate::toml_internal!(@toplevel $root [$($path)*] $($rest)*);
+ }};
+
+ // Parse array header `[[bin]]`.
+ (@toplevel $root:ident $oldpath:tt [[$($($path:tt)-+).+]] $($rest:tt)*) => {
+ $crate::macros::push_toml(
+ &mut $root,
+ &[$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+]);
+ $crate::toml_internal!(@toplevel $root [$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+] $($rest)*);
+ };
+
+ // Parse table header `[patch.crates-io]`.
+ (@toplevel $root:ident $oldpath:tt [$($($path:tt)-+).+] $($rest:tt)*) => {
+ $crate::macros::insert_toml(
+ &mut $root,
+ &[$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+],
+ $crate::Value::Table($crate::value::Table::new()));
+ $crate::toml_internal!(@toplevel $root [$(&concat!($("-", $crate::toml_internal!(@path $path),)+)[1..],)+] $($rest)*);
+ };
+
+ // Parse datetime from string and insert into table.
+ (@topleveldatetime $root:ident [$($path:tt)*] $($($k:tt)-+).+ = ($($datetime:tt)+) $($rest:tt)*) => {
+ $crate::macros::insert_toml(
+ &mut $root,
+ &[$($path)* $(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
+ $crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
+ $crate::toml_internal!(@toplevel $root [$($path)*] $($rest)*);
+ };
+
+ // Turn a path segment into a string.
+ (@path $ident:ident) => {
+ stringify!($ident)
+ };
+
+ // For a path segment that is not an ident, expect that it is already a
+ // quoted string, like in `[target."cfg(windows)".dependencies]`.
+ (@path $quoted:tt) => {
+ $quoted
+ };
+
+ // Construct a Value from an inline table.
+ (@value { $($inline:tt)* }) => {{
+ let mut table = $crate::Value::Table($crate::value::Table::new());
+ $crate::toml_internal!(@trailingcomma (@table table) $($inline)*);
+ table
+ }};
+
+ // Construct a Value from an inline array.
+ (@value [ $($inline:tt)* ]) => {{
+ let mut array = $crate::value::Array::new();
+ $crate::toml_internal!(@trailingcomma (@array array) $($inline)*);
+ $crate::Value::Array(array)
+ }};
+
+ (@value (-nan)) => {
+ $crate::Value::Float(-::std::f64::NAN)
+ };
+
+ (@value (nan)) => {
+ $crate::Value::Float(::std::f64::NAN)
+ };
+
+ (@value nan) => {
+ $crate::Value::Float(::std::f64::NAN)
+ };
+
+ (@value (-inf)) => {
+ $crate::Value::Float(::std::f64::NEG_INFINITY)
+ };
+
+ (@value (inf)) => {
+ $crate::Value::Float(::std::f64::INFINITY)
+ };
+
+ (@value inf) => {
+ $crate::Value::Float(::std::f64::INFINITY)
+ };
+
+ // Construct a Value from any other type, probably string or boolean or number.
+ (@value $v:tt) => {{
+ // TODO: Implement this with something like serde_json::to_value instead.
+ let de = $crate::macros::IntoDeserializer::<$crate::de::Error>::into_deserializer($v);
+ <$crate::Value as $crate::macros::Deserialize>::deserialize(de).unwrap()
+ }};
+
+ // Base case of inline table.
+ (@table $root:ident) => {};
+
+ // Parse negative number `key = -value`.
+ (@table $root:ident $($($k:tt)-+).+ = - $v:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@table $root $($($k)-+).+ = (-$v) , $($rest)*);
+ };
+
+ // Parse positive number `key = +value`.
+ (@table $root:ident $($($k:tt)-+).+ = + $v:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@table $root $($($k)-+).+ = ($v) , $($rest)*);
+ };
+
+ // Parse offset datetime `key = 1979-05-27T00:32:00.999999-07:00`.
+ (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
+ };
+ // Space instead of T.
+ (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
+ };
+
+ // Parse offset datetime `key = 1979-05-27T00:32:00-07:00`.
+ (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
+ };
+ // Space instead of T.
+ (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*);
+ };
+
+ // Parse local datetime `key = 1979-05-27T00:32:00.999999`.
+ (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
+ };
+ // Space instead of T.
+ (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*);
+ };
+
+ // Parse offset datetime `key = 1979-05-27T07:32:00Z` and local datetime `key = 1979-05-27T07:32:00`.
+ (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*);
+ };
+ // Space instead of T.
+ (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day T $hr : $min : $sec) $($rest)*);
+ };
+
+ // Parse local date `key = 1979-05-27`.
+ (@table $root:ident $($($k:tt)-+).+ = $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($yr - $mo - $day) $($rest)*);
+ };
+
+ // Parse local time `key = 00:32:00.999999`.
+ (@table $root:ident $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($hr : $min : $sec . $frac) $($rest)*);
+ };
+
+ // Parse local time `key = 07:32:00`.
+ (@table $root:ident $($($k:tt)-+).+ = $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@tabledatetime $root $($($k)-+).+ = ($hr : $min : $sec) $($rest)*);
+ };
+
+ // Parse any other type, probably string or boolean or number.
+ (@table $root:ident $($($k:tt)-+).+ = $v:tt , $($rest:tt)*) => {
+ $crate::macros::insert_toml(
+ &mut $root,
+ &[$(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
+ $crate::toml_internal!(@value $v));
+ $crate::toml_internal!(@table $root $($rest)*);
+ };
+
+ // Parse a Datetime from string and continue in @table state.
+ (@tabledatetime $root:ident $($($k:tt)-+).+ = ($($datetime:tt)*) $($rest:tt)*) => {
+ $crate::macros::insert_toml(
+ &mut $root,
+ &[$(&concat!($("-", $crate::toml_internal!(@path $k),)+)[1..], )+],
+ $crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
+ $crate::toml_internal!(@table $root $($rest)*);
+ };
+
+ // Base case of inline array.
+ (@array $root:ident) => {};
+
+ // Parse negative number `-value`.
+ (@array $root:ident - $v:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@array $root (-$v) , $($rest)*);
+ };
+
+ // Parse positive number `+value`.
+ (@array $root:ident + $v:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@array $root ($v) , $($rest)*);
+ };
+
+ // Parse offset datetime `1979-05-27T00:32:00.999999-07:00`.
+ (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
+ };
+ // Space instead of T.
+ (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec . $frac - $tzh : $tzm) $($rest)*);
+ };
+
+ // Parse offset datetime `1979-05-27T00:32:00-07:00`.
+ (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec - $tzh : $tzm) $($rest)*);
+ };
+ // Space instead of T.
+ (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt - $tzh:tt : $tzm:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec - $tzh : $tzm) $($rest)*);
+ };
+
+ // Parse local datetime `1979-05-27T00:32:00.999999`.
+ (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec . $frac) $($rest)*);
+ };
+ // Space instead of T.
+ (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec . $frac) $($rest)*);
+ };
+
+ // Parse offset datetime `1979-05-27T07:32:00Z` and local datetime `1979-05-27T07:32:00`.
+ (@array $root:ident $yr:tt - $mo:tt - $dhr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec) $($rest)*);
+ };
+ // Space instead of T.
+ (@array $root:ident $yr:tt - $mo:tt - $day:tt $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day T $hr : $min : $sec) $($rest)*);
+ };
+
+ // Parse local date `1979-05-27`.
+ (@array $root:ident $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($yr - $mo - $day) $($rest)*);
+ };
+
+ // Parse local time `00:32:00.999999`.
+ (@array $root:ident $hr:tt : $min:tt : $sec:tt . $frac:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($hr : $min : $sec . $frac) $($rest)*);
+ };
+
+ // Parse local time `07:32:00`.
+ (@array $root:ident $hr:tt : $min:tt : $sec:tt , $($rest:tt)*) => {
+ $crate::toml_internal!(@arraydatetime $root ($hr : $min : $sec) $($rest)*);
+ };
+
+ // Parse any other type, probably string or boolean or number.
+ (@array $root:ident $v:tt , $($rest:tt)*) => {
+ $root.push($crate::toml_internal!(@value $v));
+ $crate::toml_internal!(@array $root $($rest)*);
+ };
+
+ // Parse a Datetime from string and continue in @array state.
+ (@arraydatetime $root:ident ($($datetime:tt)*) $($rest:tt)*) => {
+ $root.push($crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
+ $crate::toml_internal!(@array $root $($rest)*);
+ };
+
+ // No trailing comma required if the tokens are empty.
+ (@trailingcomma ($($args:tt)*)) => {
+ $crate::toml_internal!($($args)*);
+ };
+
+ // Tokens end with a trailing comma, do not append another one.
+ (@trailingcomma ($($args:tt)*) ,) => {
+ $crate::toml_internal!($($args)* ,);
+ };
+
+ // Tokens end with something other than comma, append a trailing comma.
+ (@trailingcomma ($($args:tt)*) $last:tt) => {
+ $crate::toml_internal!($($args)* $last ,);
+ };
+
+ // Not yet at the last token.
+ (@trailingcomma ($($args:tt)*) $first:tt $($rest:tt)+) => {
+ $crate::toml_internal!(@trailingcomma ($($args)* $first) $($rest)+);
+ };
+}
+
+// Called when parsing a `key = value` pair.
+// Inserts an entry into the table at the given path.
+pub fn insert_toml(root: &mut Value, path: &[&str], value: Value) {
+ *traverse(root, path) = value;
+}
+
+// Called when parsing an `[[array header]]`.
+// Pushes an empty table onto the array at the given path.
+pub fn push_toml(root: &mut Value, path: &[&str]) {
+ let target = traverse(root, path);
+ if !target.is_array() {
+ *target = Value::Array(Array::new());
+ }
+ target
+ .as_array_mut()
+ .unwrap()
+ .push(Value::Table(Table::new()));
+}
+
+fn traverse<'a>(root: &'a mut Value, path: &[&str]) -> &'a mut Value {
+ let mut cur = root;
+ for &key in path {
+ // Lexical lifetimes :D
+ let cur1 = cur;
+
+ // From the TOML spec:
+ //
+ // > Each double-bracketed sub-table will belong to the most recently
+ // > defined table element above it.
+ let cur2 = if cur1.is_array() {
+ cur1.as_array_mut().unwrap().last_mut().unwrap()
+ } else {
+ cur1
+ };
+
+ // We are about to index into this value, so it better be a table.
+ if !cur2.is_table() {
+ *cur2 = Value::Table(Table::new());
+ }
+
+ if !cur2.as_table().unwrap().contains_key(key) {
+ // Insert an empty table for the next loop iteration to point to.
+ let empty = Value::Table(Table::new());
+ cur2.as_table_mut().unwrap().insert(key.to_owned(), empty);
+ }
+
+ // Step into the current table.
+ cur = cur2.as_table_mut().unwrap().get_mut(key).unwrap();
+ }
+ cur
+}
diff --git a/vendor/toml-0.7.5/src/map.rs b/vendor/toml-0.7.5/src/map.rs
new file mode 100644
index 000000000..5b3ff19b4
--- /dev/null
+++ b/vendor/toml-0.7.5/src/map.rs
@@ -0,0 +1,595 @@
+// Copyright 2017 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A map of `String` to [Value].
+//!
+//! By default the map is backed by a [`BTreeMap`]. Enable the `preserve_order`
+//! feature of toml-rs to use [`IndexMap`] instead.
+//!
+//! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
+//! [`IndexMap`]: https://docs.rs/indexmap
+
+use crate::value::Value;
+use serde::{de, ser};
+use std::borrow::Borrow;
+use std::fmt::{self, Debug};
+use std::hash::Hash;
+use std::iter::FromIterator;
+use std::ops;
+
+#[cfg(not(feature = "preserve_order"))]
+use std::collections::{btree_map, BTreeMap};
+
+#[cfg(feature = "preserve_order")]
+use indexmap::{self, IndexMap};
+
+/// Represents a TOML key/value type.
+pub struct Map<K, V> {
+ map: MapImpl<K, V>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type MapImpl<K, V> = BTreeMap<K, V>;
+#[cfg(feature = "preserve_order")]
+type MapImpl<K, V> = IndexMap<K, V>;
+
+impl Map<String, Value> {
+ /// Makes a new empty Map.
+ #[inline]
+ pub fn new() -> Self {
+ Map {
+ map: MapImpl::new(),
+ }
+ }
+
+ #[cfg(not(feature = "preserve_order"))]
+ /// Makes a new empty Map with the given initial capacity.
+ #[inline]
+ pub fn with_capacity(capacity: usize) -> Self {
+ // does not support with_capacity
+ let _ = capacity;
+ Map {
+ map: BTreeMap::new(),
+ }
+ }
+
+ #[cfg(feature = "preserve_order")]
+ /// Makes a new empty Map with the given initial capacity.
+ #[inline]
+ pub fn with_capacity(capacity: usize) -> Self {
+ Map {
+ map: IndexMap::with_capacity(capacity),
+ }
+ }
+
+ /// Clears the map, removing all values.
+ #[inline]
+ pub fn clear(&mut self) {
+ self.map.clear()
+ }
+
+ /// Returns a reference to the value corresponding to the key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but the ordering
+ /// on the borrowed form *must* match the ordering on the key type.
+ #[inline]
+ pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&Value>
+ where
+ String: Borrow<Q>,
+ Q: Ord + Eq + Hash,
+ {
+ self.map.get(key)
+ }
+
+ /// Returns true if the map contains a value for the specified key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but the ordering
+ /// on the borrowed form *must* match the ordering on the key type.
+ #[inline]
+ pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
+ where
+ String: Borrow<Q>,
+ Q: Ord + Eq + Hash,
+ {
+ self.map.contains_key(key)
+ }
+
+ /// Returns a mutable reference to the value corresponding to the key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but the ordering
+ /// on the borrowed form *must* match the ordering on the key type.
+ #[inline]
+ pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut Value>
+ where
+ String: Borrow<Q>,
+ Q: Ord + Eq + Hash,
+ {
+ self.map.get_mut(key)
+ }
+
+ /// Inserts a key-value pair into the map.
+ ///
+ /// If the map did not have this key present, `None` is returned.
+ ///
+ /// If the map did have this key present, the value is updated, and the old
+ /// value is returned. The key is not updated, though; this matters for
+ /// types that can be `==` without being identical.
+ #[inline]
+ pub fn insert(&mut self, k: String, v: Value) -> Option<Value> {
+ self.map.insert(k, v)
+ }
+
+ /// Removes a key from the map, returning the value at the key if the key
+ /// was previously in the map.
+ ///
+ /// The key may be any borrowed form of the map's key type, but the ordering
+ /// on the borrowed form *must* match the ordering on the key type.
+ #[inline]
+ pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<Value>
+ where
+ String: Borrow<Q>,
+ Q: Ord + Eq + Hash,
+ {
+ self.map.remove(key)
+ }
+
+ /// Gets the given key's corresponding entry in the map for in-place
+ /// manipulation.
+ pub fn entry<S>(&mut self, key: S) -> Entry<'_>
+ where
+ S: Into<String>,
+ {
+ #[cfg(feature = "preserve_order")]
+ use indexmap::map::Entry as EntryImpl;
+ #[cfg(not(feature = "preserve_order"))]
+ use std::collections::btree_map::Entry as EntryImpl;
+
+ match self.map.entry(key.into()) {
+ EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
+ EntryImpl::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
+ }
+ }
+
+ /// Returns the number of elements in the map.
+ #[inline]
+ pub fn len(&self) -> usize {
+ self.map.len()
+ }
+
+ /// Returns true if the map contains no elements.
+ #[inline]
+ pub fn is_empty(&self) -> bool {
+ self.map.is_empty()
+ }
+
+ /// Gets an iterator over the entries of the map.
+ #[inline]
+ pub fn iter(&self) -> Iter<'_> {
+ Iter {
+ iter: self.map.iter(),
+ }
+ }
+
+ /// Gets a mutable iterator over the entries of the map.
+ #[inline]
+ pub fn iter_mut(&mut self) -> IterMut<'_> {
+ IterMut {
+ iter: self.map.iter_mut(),
+ }
+ }
+
+ /// Gets an iterator over the keys of the map.
+ #[inline]
+ pub fn keys(&self) -> Keys<'_> {
+ Keys {
+ iter: self.map.keys(),
+ }
+ }
+
+ /// Gets an iterator over the values of the map.
+ #[inline]
+ pub fn values(&self) -> Values<'_> {
+ Values {
+ iter: self.map.values(),
+ }
+ }
+}
+
+impl Default for Map<String, Value> {
+ #[inline]
+ fn default() -> Self {
+ Map {
+ map: MapImpl::new(),
+ }
+ }
+}
+
+impl Clone for Map<String, Value> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Map {
+ map: self.map.clone(),
+ }
+ }
+}
+
+impl PartialEq for Map<String, Value> {
+ #[inline]
+ fn eq(&self, other: &Self) -> bool {
+ self.map.eq(&other.map)
+ }
+}
+
+/// Access an element of this map. Panics if the given key is not present in the
+/// map.
+impl<'a, Q: ?Sized> ops::Index<&'a Q> for Map<String, Value>
+where
+ String: Borrow<Q>,
+ Q: Ord + Eq + Hash,
+{
+ type Output = Value;
+
+ fn index(&self, index: &Q) -> &Value {
+ self.map.index(index)
+ }
+}
+
+/// Mutably access an element of this map. Panics if the given key is not
+/// present in the map.
+impl<'a, Q: ?Sized> ops::IndexMut<&'a Q> for Map<String, Value>
+where
+ String: Borrow<Q>,
+ Q: Ord + Eq + Hash,
+{
+ fn index_mut(&mut self, index: &Q) -> &mut Value {
+ self.map.get_mut(index).expect("no entry found for key")
+ }
+}
+
+impl Debug for Map<String, Value> {
+ #[inline]
+ fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
+ self.map.fmt(formatter)
+ }
+}
+
+impl ser::Serialize for Map<String, Value> {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ use serde::ser::SerializeMap;
+ let mut map = serializer.serialize_map(Some(self.len()))?;
+ for (k, v) in self {
+ map.serialize_key(k)?;
+ map.serialize_value(v)?;
+ }
+ map.end()
+ }
+}
+
+impl<'de> de::Deserialize<'de> for Map<String, Value> {
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ struct Visitor;
+
+ impl<'de> de::Visitor<'de> for Visitor {
+ type Value = Map<String, Value>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a map")
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Map::new())
+ }
+
+ #[inline]
+ fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: de::MapAccess<'de>,
+ {
+ let mut values = Map::new();
+
+ while let Some((key, value)) = visitor.next_entry()? {
+ values.insert(key, value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ deserializer.deserialize_map(Visitor)
+ }
+}
+
+impl FromIterator<(String, Value)> for Map<String, Value> {
+ fn from_iter<T>(iter: T) -> Self
+ where
+ T: IntoIterator<Item = (String, Value)>,
+ {
+ Map {
+ map: FromIterator::from_iter(iter),
+ }
+ }
+}
+
+impl Extend<(String, Value)> for Map<String, Value> {
+ fn extend<T>(&mut self, iter: T)
+ where
+ T: IntoIterator<Item = (String, Value)>,
+ {
+ self.map.extend(iter);
+ }
+}
+
+macro_rules! delegate_iterator {
+ (($name:ident $($generics:tt)*) => $item:ty) => {
+ impl $($generics)* Iterator for $name $($generics)* {
+ type Item = $item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next()
+ }
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+ }
+
+ impl $($generics)* DoubleEndedIterator for $name $($generics)* {
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter.next_back()
+ }
+ }
+
+ impl $($generics)* ExactSizeIterator for $name $($generics)* {
+ #[inline]
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+ }
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// A view into a single entry in a map, which may either be vacant or occupied.
+/// This enum is constructed from the [`entry`] method on [`Map`].
+///
+/// [`entry`]: struct.Map.html#method.entry
+/// [`Map`]: struct.Map.html
+pub enum Entry<'a> {
+ /// A vacant Entry.
+ Vacant(VacantEntry<'a>),
+ /// An occupied Entry.
+ Occupied(OccupiedEntry<'a>),
+}
+
+/// A vacant Entry. It is part of the [`Entry`] enum.
+///
+/// [`Entry`]: enum.Entry.html
+pub struct VacantEntry<'a> {
+ vacant: VacantEntryImpl<'a>,
+}
+
+/// An occupied Entry. It is part of the [`Entry`] enum.
+///
+/// [`Entry`]: enum.Entry.html
+pub struct OccupiedEntry<'a> {
+ occupied: OccupiedEntryImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type VacantEntryImpl<'a> = btree_map::VacantEntry<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type VacantEntryImpl<'a> = indexmap::map::VacantEntry<'a, String, Value>;
+
+#[cfg(not(feature = "preserve_order"))]
+type OccupiedEntryImpl<'a> = btree_map::OccupiedEntry<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type OccupiedEntryImpl<'a> = indexmap::map::OccupiedEntry<'a, String, Value>;
+
+impl<'a> Entry<'a> {
+ /// Returns a reference to this entry's key.
+ pub fn key(&self) -> &String {
+ match *self {
+ Entry::Vacant(ref e) => e.key(),
+ Entry::Occupied(ref e) => e.key(),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting the default if empty, and
+ /// returns a mutable reference to the value in the entry.
+ pub fn or_insert(self, default: Value) -> &'a mut Value {
+ match self {
+ Entry::Vacant(entry) => entry.insert(default),
+ Entry::Occupied(entry) => entry.into_mut(),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting the result of the default
+ /// function if empty, and returns a mutable reference to the value in the
+ /// entry.
+ pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
+ where
+ F: FnOnce() -> Value,
+ {
+ match self {
+ Entry::Vacant(entry) => entry.insert(default()),
+ Entry::Occupied(entry) => entry.into_mut(),
+ }
+ }
+}
+
+impl<'a> VacantEntry<'a> {
+ /// Gets a reference to the key that would be used when inserting a value
+ /// through the VacantEntry.
+ #[inline]
+ pub fn key(&self) -> &String {
+ self.vacant.key()
+ }
+
+ /// Sets the value of the entry with the VacantEntry's key, and returns a
+ /// mutable reference to it.
+ #[inline]
+ pub fn insert(self, value: Value) -> &'a mut Value {
+ self.vacant.insert(value)
+ }
+}
+
+impl<'a> OccupiedEntry<'a> {
+ /// Gets a reference to the key in the entry.
+ #[inline]
+ pub fn key(&self) -> &String {
+ self.occupied.key()
+ }
+
+ /// Gets a reference to the value in the entry.
+ #[inline]
+ pub fn get(&self) -> &Value {
+ self.occupied.get()
+ }
+
+ /// Gets a mutable reference to the value in the entry.
+ #[inline]
+ pub fn get_mut(&mut self) -> &mut Value {
+ self.occupied.get_mut()
+ }
+
+ /// Converts the entry into a mutable reference to its value.
+ #[inline]
+ pub fn into_mut(self) -> &'a mut Value {
+ self.occupied.into_mut()
+ }
+
+ /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns
+ /// the entry's old value.
+ #[inline]
+ pub fn insert(&mut self, value: Value) -> Value {
+ self.occupied.insert(value)
+ }
+
+ /// Takes the value of the entry out of the map, and returns it.
+ #[inline]
+ pub fn remove(self) -> Value {
+ self.occupied.remove()
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+impl<'a> IntoIterator for &'a Map<String, Value> {
+ type Item = (&'a String, &'a Value);
+ type IntoIter = Iter<'a>;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ Iter {
+ iter: self.map.iter(),
+ }
+ }
+}
+
+/// An iterator over a toml::Map's entries.
+pub struct Iter<'a> {
+ iter: IterImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type IterImpl<'a> = btree_map::Iter<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type IterImpl<'a> = indexmap::map::Iter<'a, String, Value>;
+
+delegate_iterator!((Iter<'a>) => (&'a String, &'a Value));
+
+//////////////////////////////////////////////////////////////////////////////
+
+impl<'a> IntoIterator for &'a mut Map<String, Value> {
+ type Item = (&'a String, &'a mut Value);
+ type IntoIter = IterMut<'a>;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ IterMut {
+ iter: self.map.iter_mut(),
+ }
+ }
+}
+
+/// A mutable iterator over a toml::Map's entries.
+pub struct IterMut<'a> {
+ iter: IterMutImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type IterMutImpl<'a> = btree_map::IterMut<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type IterMutImpl<'a> = indexmap::map::IterMut<'a, String, Value>;
+
+delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value));
+
+//////////////////////////////////////////////////////////////////////////////
+
+impl IntoIterator for Map<String, Value> {
+ type Item = (String, Value);
+ type IntoIter = IntoIter;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ IntoIter {
+ iter: self.map.into_iter(),
+ }
+ }
+}
+
+/// An owning iterator over a toml::Map's entries.
+pub struct IntoIter {
+ iter: IntoIterImpl,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type IntoIterImpl = btree_map::IntoIter<String, Value>;
+#[cfg(feature = "preserve_order")]
+type IntoIterImpl = indexmap::map::IntoIter<String, Value>;
+
+delegate_iterator!((IntoIter) => (String, Value));
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// An iterator over a toml::Map's keys.
+pub struct Keys<'a> {
+ iter: KeysImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type KeysImpl<'a> = btree_map::Keys<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type KeysImpl<'a> = indexmap::map::Keys<'a, String, Value>;
+
+delegate_iterator!((Keys<'a>) => &'a String);
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// An iterator over a toml::Map's values.
+pub struct Values<'a> {
+ iter: ValuesImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type ValuesImpl<'a> = btree_map::Values<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type ValuesImpl<'a> = indexmap::map::Values<'a, String, Value>;
+
+delegate_iterator!((Values<'a>) => &'a Value);
diff --git a/vendor/toml-0.7.5/src/ser.rs b/vendor/toml-0.7.5/src/ser.rs
new file mode 100644
index 000000000..f1ab24bb8
--- /dev/null
+++ b/vendor/toml-0.7.5/src/ser.rs
@@ -0,0 +1,1087 @@
+//! Serializing Rust structures into TOML.
+//!
+//! This module contains all the Serde support for serializing Rust structures
+//! into TOML documents (as strings). Note that some top-level functions here
+//! are also provided at the top of the crate.
+
+/// Serialize the given data structure as a String of TOML.
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// fail, if `T` contains a map with non-string keys, or if `T` attempts to
+/// serialize an unsupported datatype such as an enum, tuple, or tuple struct.
+///
+/// To serialize TOML values, instead of documents, see [`ValueSerializer`].
+///
+/// # Examples
+///
+/// ```
+/// use serde::Serialize;
+///
+/// #[derive(Serialize)]
+/// struct Config {
+/// database: Database,
+/// }
+///
+/// #[derive(Serialize)]
+/// struct Database {
+/// ip: String,
+/// port: Vec<u16>,
+/// connection_max: u32,
+/// enabled: bool,
+/// }
+///
+/// let config = Config {
+/// database: Database {
+/// ip: "192.168.1.1".to_string(),
+/// port: vec![8001, 8002, 8003],
+/// connection_max: 5000,
+/// enabled: false,
+/// },
+/// };
+///
+/// let toml = toml::to_string(&config).unwrap();
+/// println!("{}", toml)
+/// ```
+#[cfg(feature = "display")]
+pub fn to_string<T: ?Sized>(value: &T) -> Result<String, Error>
+where
+ T: serde::ser::Serialize,
+{
+ let mut output = String::new();
+ let serializer = Serializer::new(&mut output);
+ value.serialize(serializer)?;
+ Ok(output)
+}
+
+/// Serialize the given data structure as a "pretty" String of TOML.
+///
+/// This is identical to `to_string` except the output string has a more
+/// "pretty" output. See `Serializer::pretty` for more details.
+///
+/// To serialize TOML values, instead of documents, see [`ValueSerializer`].
+///
+/// For greater customization, instead serialize to a
+/// [`toml_edit::Document`](https://docs.rs/toml_edit/latest/toml_edit/struct.Document.html).
+#[cfg(feature = "display")]
+pub fn to_string_pretty<T: ?Sized>(value: &T) -> Result<String, Error>
+where
+ T: serde::ser::Serialize,
+{
+ let mut output = String::new();
+ let serializer = Serializer::pretty(&mut output);
+ value.serialize(serializer)?;
+ Ok(output)
+}
+
+/// Errors that can occur when serializing a type.
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub struct Error {
+ pub(crate) inner: crate::edit::ser::Error,
+}
+
+impl Error {
+ pub(crate) fn new(inner: impl std::fmt::Display) -> Self {
+ Self {
+ inner: crate::edit::ser::Error::Custom(inner.to_string()),
+ }
+ }
+
+ #[cfg(feature = "display")]
+ pub(crate) fn wrap(inner: crate::edit::ser::Error) -> Self {
+ Self { inner }
+ }
+
+ pub(crate) fn unsupported_type(t: Option<&'static str>) -> Self {
+ Self {
+ inner: crate::edit::ser::Error::UnsupportedType(t),
+ }
+ }
+
+ pub(crate) fn unsupported_none() -> Self {
+ Self {
+ inner: crate::edit::ser::Error::UnsupportedNone,
+ }
+ }
+
+ pub(crate) fn key_not_string() -> Self {
+ Self {
+ inner: crate::edit::ser::Error::KeyNotString,
+ }
+ }
+}
+
+impl serde::ser::Error for Error {
+ fn custom<T>(msg: T) -> Self
+ where
+ T: std::fmt::Display,
+ {
+ Error::new(msg)
+ }
+}
+
+impl std::fmt::Display for Error {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ self.inner.fmt(f)
+ }
+}
+
+impl std::error::Error for Error {}
+
+/// Serialization for TOML documents.
+///
+/// This structure implements serialization support for TOML to serialize an
+/// arbitrary type to TOML. Note that the TOML format does not support all
+/// datatypes in Rust, such as enums, tuples, and tuple structs. These types
+/// will generate an error when serialized.
+///
+/// Currently a serializer always writes its output to an in-memory `String`,
+/// which is passed in when creating the serializer itself.
+///
+/// To serialize TOML values, instead of documents, see [`ValueSerializer`].
+#[non_exhaustive]
+#[cfg(feature = "display")]
+pub struct Serializer<'d> {
+ dst: &'d mut String,
+ settings: crate::fmt::DocumentFormatter,
+}
+
+#[cfg(feature = "display")]
+impl<'d> Serializer<'d> {
+ /// Creates a new serializer which will emit TOML into the buffer provided.
+ ///
+ /// The serializer can then be used to serialize a type after which the data
+ /// will be present in `dst`.
+ pub fn new(dst: &'d mut String) -> Self {
+ Self {
+ dst,
+ settings: Default::default(),
+ }
+ }
+
+ /// Apply a default "pretty" policy to the document
+ ///
+ /// For greater customization, instead serialize to a
+ /// [`toml_edit::Document`](https://docs.rs/toml_edit/latest/toml_edit/struct.Document.html).
+ pub fn pretty(dst: &'d mut String) -> Self {
+ let mut ser = Serializer::new(dst);
+ ser.settings.multiline_array = true;
+ ser
+ }
+}
+
+#[cfg(feature = "display")]
+impl<'d> serde::ser::Serializer for Serializer<'d> {
+ type Ok = ();
+ type Error = Error;
+ type SerializeSeq = SerializeDocumentArray<'d>;
+ type SerializeTuple = SerializeDocumentArray<'d>;
+ type SerializeTupleStruct = SerializeDocumentArray<'d>;
+ type SerializeTupleVariant = SerializeDocumentArray<'d>;
+ type SerializeMap = SerializeDocumentTable<'d>;
+ type SerializeStruct = SerializeDocumentTable<'d>;
+ type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
+
+ fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_bool(v),
+ )
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_i8(v),
+ )
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_i16(v),
+ )
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_i32(v),
+ )
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_i64(v),
+ )
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_u8(v),
+ )
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_u16(v),
+ )
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_u32(v),
+ )
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_u64(v),
+ )
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_f32(v),
+ )
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_f64(v),
+ )
+ }
+
+ fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_char(v),
+ )
+ }
+
+ fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_str(v),
+ )
+ }
+
+ fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_bytes(v),
+ )
+ }
+
+ fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_none(),
+ )
+ }
+
+ fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_some(v),
+ )
+ }
+
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_unit(),
+ )
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_unit_struct(name),
+ )
+ }
+
+ fn serialize_unit_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Self::Ok, Self::Error> {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_unit_variant(
+ name,
+ variant_index,
+ variant,
+ ),
+ )
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ name: &'static str,
+ v: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_newtype_struct(name, v),
+ )
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ write_document(
+ self.dst,
+ self.settings,
+ toml_edit::ser::ValueSerializer::new().serialize_newtype_variant(
+ name,
+ variant_index,
+ variant,
+ value,
+ ),
+ )
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ let ser = toml_edit::ser::ValueSerializer::new()
+ .serialize_seq(len)
+ .map_err(Error::wrap)?;
+ let ser = SerializeDocumentArray::new(self, ser);
+ Ok(ser)
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::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, Self::Error> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ let ser = toml_edit::ser::ValueSerializer::new()
+ .serialize_map(len)
+ .map_err(Error::wrap)?;
+ let ser = SerializeDocumentTable::new(self, ser);
+ Ok(ser)
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStruct, Self::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, Self::Error> {
+ Err(Error::unsupported_type(Some(name)))
+ }
+}
+
+/// Serialization for TOML [values][crate::Value].
+///
+/// This structure implements serialization support for TOML to serialize an
+/// arbitrary type to TOML. Note that the TOML format does not support all
+/// datatypes in Rust, such as enums, tuples, and tuple structs. These types
+/// will generate an error when serialized.
+///
+/// Currently a serializer always writes its output to an in-memory `String`,
+/// which is passed in when creating the serializer itself.
+///
+/// # Examples
+///
+/// ```
+/// use serde::Serialize;
+///
+/// #[derive(Serialize)]
+/// struct Config {
+/// database: Database,
+/// }
+///
+/// #[derive(Serialize)]
+/// struct Database {
+/// ip: String,
+/// port: Vec<u16>,
+/// connection_max: u32,
+/// enabled: bool,
+/// }
+///
+/// let config = Config {
+/// database: Database {
+/// ip: "192.168.1.1".to_string(),
+/// port: vec![8001, 8002, 8003],
+/// connection_max: 5000,
+/// enabled: false,
+/// },
+/// };
+///
+/// let mut value = String::new();
+/// serde::Serialize::serialize(
+/// &config,
+/// toml::ser::ValueSerializer::new(&mut value)
+/// ).unwrap();
+/// println!("{}", value)
+/// ```
+#[non_exhaustive]
+#[cfg(feature = "display")]
+pub struct ValueSerializer<'d> {
+ dst: &'d mut String,
+}
+
+#[cfg(feature = "display")]
+impl<'d> ValueSerializer<'d> {
+ /// Creates a new serializer which will emit TOML into the buffer provided.
+ ///
+ /// The serializer can then be used to serialize a type after which the data
+ /// will be present in `dst`.
+ pub fn new(dst: &'d mut String) -> Self {
+ Self { dst }
+ }
+}
+
+#[cfg(feature = "display")]
+impl<'d> serde::ser::Serializer for ValueSerializer<'d> {
+ type Ok = ();
+ type Error = Error;
+ type SerializeSeq = SerializeValueArray<'d>;
+ type SerializeTuple = SerializeValueArray<'d>;
+ type SerializeTupleStruct = SerializeValueArray<'d>;
+ type SerializeTupleVariant = SerializeValueArray<'d>;
+ type SerializeMap = SerializeValueTable<'d>;
+ type SerializeStruct = SerializeValueTable<'d>;
+ type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
+
+ fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_bool(v),
+ )
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_i8(v),
+ )
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_i16(v),
+ )
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_i32(v),
+ )
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_i64(v),
+ )
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_u8(v),
+ )
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_u16(v),
+ )
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_u32(v),
+ )
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_u64(v),
+ )
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_f32(v),
+ )
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_f64(v),
+ )
+ }
+
+ fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_char(v),
+ )
+ }
+
+ fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_str(v),
+ )
+ }
+
+ fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_bytes(v),
+ )
+ }
+
+ fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_none(),
+ )
+ }
+
+ fn serialize_some<T: ?Sized>(self, v: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_some(v),
+ )
+ }
+
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_unit(),
+ )
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_unit_struct(name),
+ )
+ }
+
+ fn serialize_unit_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Self::Ok, Self::Error> {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_unit_variant(
+ name,
+ variant_index,
+ variant,
+ ),
+ )
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ name: &'static str,
+ v: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_newtype_struct(name, v),
+ )
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ write_value(
+ self.dst,
+ toml_edit::ser::ValueSerializer::new().serialize_newtype_variant(
+ name,
+ variant_index,
+ variant,
+ value,
+ ),
+ )
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ let ser = toml_edit::ser::ValueSerializer::new()
+ .serialize_seq(len)
+ .map_err(Error::wrap)?;
+ let ser = SerializeValueArray::new(self, ser);
+ Ok(ser)
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::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, Self::Error> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ let ser = toml_edit::ser::ValueSerializer::new()
+ .serialize_map(len)
+ .map_err(Error::wrap)?;
+ let ser = SerializeValueTable::new(self, ser);
+ Ok(ser)
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStruct, Self::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, Self::Error> {
+ Err(Error::unsupported_type(Some(name)))
+ }
+}
+
+#[cfg(feature = "display")]
+use internal::*;
+
+#[cfg(feature = "display")]
+mod internal {
+ use super::*;
+
+ use crate::fmt::DocumentFormatter;
+
+ type InnerSerializeDocumentSeq =
+ <toml_edit::ser::ValueSerializer as serde::Serializer>::SerializeSeq;
+
+ #[doc(hidden)]
+ pub struct SerializeDocumentArray<'d> {
+ inner: InnerSerializeDocumentSeq,
+ dst: &'d mut String,
+ settings: DocumentFormatter,
+ }
+
+ impl<'d> SerializeDocumentArray<'d> {
+ pub(crate) fn new(ser: Serializer<'d>, inner: InnerSerializeDocumentSeq) -> Self {
+ Self {
+ inner,
+ dst: ser.dst,
+ settings: ser.settings,
+ }
+ }
+ }
+
+ impl<'d> serde::ser::SerializeSeq for SerializeDocumentArray<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_element(value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_document(self.dst, self.settings, self.inner.end())
+ }
+ }
+
+ impl<'d> serde::ser::SerializeTuple for SerializeDocumentArray<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_element(value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_document(self.dst, self.settings, self.inner.end())
+ }
+ }
+
+ impl<'d> serde::ser::SerializeTupleVariant for SerializeDocumentArray<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_field(value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_document(self.dst, self.settings, self.inner.end())
+ }
+ }
+
+ impl<'d> serde::ser::SerializeTupleStruct for SerializeDocumentArray<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_field(value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_document(self.dst, self.settings, self.inner.end())
+ }
+ }
+
+ type InnerSerializeDocumentTable =
+ <toml_edit::ser::ValueSerializer as serde::Serializer>::SerializeMap;
+
+ #[doc(hidden)]
+ pub struct SerializeDocumentTable<'d> {
+ inner: InnerSerializeDocumentTable,
+ dst: &'d mut String,
+ settings: DocumentFormatter,
+ }
+
+ impl<'d> SerializeDocumentTable<'d> {
+ pub(crate) fn new(ser: Serializer<'d>, inner: InnerSerializeDocumentTable) -> Self {
+ Self {
+ inner,
+ dst: ser.dst,
+ settings: ser.settings,
+ }
+ }
+ }
+
+ impl<'d> serde::ser::SerializeMap for SerializeDocumentTable<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_key<T: ?Sized>(&mut self, input: &T) -> Result<(), Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_key(input).map_err(Error::wrap)
+ }
+
+ fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_value(value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_document(self.dst, self.settings, self.inner.end())
+ }
+ }
+
+ impl<'d> serde::ser::SerializeStruct for SerializeDocumentTable<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_field(key, value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_document(self.dst, self.settings, self.inner.end())
+ }
+ }
+
+ pub(crate) fn write_document(
+ dst: &mut String,
+ mut settings: DocumentFormatter,
+ value: Result<toml_edit::Value, crate::edit::ser::Error>,
+ ) -> Result<(), Error> {
+ use std::fmt::Write;
+
+ let value = value.map_err(Error::wrap)?;
+ let mut table = match toml_edit::Item::Value(value).into_table() {
+ Ok(i) => i,
+ Err(_) => {
+ return Err(Error::unsupported_type(None));
+ }
+ };
+
+ use toml_edit::visit_mut::VisitMut as _;
+ settings.visit_table_mut(&mut table);
+
+ let doc: toml_edit::Document = table.into();
+ write!(dst, "{}", doc).unwrap();
+
+ Ok(())
+ }
+
+ type InnerSerializeValueSeq =
+ <toml_edit::ser::ValueSerializer as serde::Serializer>::SerializeSeq;
+
+ #[doc(hidden)]
+ pub struct SerializeValueArray<'d> {
+ inner: InnerSerializeValueSeq,
+ dst: &'d mut String,
+ }
+
+ impl<'d> SerializeValueArray<'d> {
+ pub(crate) fn new(ser: ValueSerializer<'d>, inner: InnerSerializeValueSeq) -> Self {
+ Self {
+ inner,
+ dst: ser.dst,
+ }
+ }
+ }
+
+ impl<'d> serde::ser::SerializeSeq for SerializeValueArray<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_element(value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_value(self.dst, self.inner.end())
+ }
+ }
+
+ impl<'d> serde::ser::SerializeTuple for SerializeValueArray<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_element(value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_value(self.dst, self.inner.end())
+ }
+ }
+
+ impl<'d> serde::ser::SerializeTupleVariant for SerializeValueArray<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_field(value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_value(self.dst, self.inner.end())
+ }
+ }
+
+ impl<'d> serde::ser::SerializeTupleStruct for SerializeValueArray<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_field(value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_value(self.dst, self.inner.end())
+ }
+ }
+
+ type InnerSerializeValueTable =
+ <toml_edit::ser::ValueSerializer as serde::Serializer>::SerializeMap;
+
+ #[doc(hidden)]
+ pub struct SerializeValueTable<'d> {
+ inner: InnerSerializeValueTable,
+ dst: &'d mut String,
+ }
+
+ impl<'d> SerializeValueTable<'d> {
+ pub(crate) fn new(ser: ValueSerializer<'d>, inner: InnerSerializeValueTable) -> Self {
+ Self {
+ inner,
+ dst: ser.dst,
+ }
+ }
+ }
+
+ impl<'d> serde::ser::SerializeMap for SerializeValueTable<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_key<T: ?Sized>(&mut self, input: &T) -> Result<(), Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_key(input).map_err(Error::wrap)
+ }
+
+ fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_value(value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_value(self.dst, self.inner.end())
+ }
+ }
+
+ impl<'d> serde::ser::SerializeStruct for SerializeValueTable<'d> {
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ self.inner.serialize_field(key, value).map_err(Error::wrap)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ write_value(self.dst, self.inner.end())
+ }
+ }
+
+ pub(crate) fn write_value(
+ dst: &mut String,
+ value: Result<toml_edit::Value, crate::edit::ser::Error>,
+ ) -> Result<(), Error> {
+ use std::fmt::Write;
+
+ let value = value.map_err(Error::wrap)?;
+
+ write!(dst, "{}", value).unwrap();
+
+ Ok(())
+ }
+}
diff --git a/vendor/toml-0.7.5/src/table.rs b/vendor/toml-0.7.5/src/table.rs
new file mode 100644
index 000000000..a2d392bde
--- /dev/null
+++ b/vendor/toml-0.7.5/src/table.rs
@@ -0,0 +1,114 @@
+use std::fmt;
+
+use serde::de;
+use serde::ser;
+
+use crate::map::Map;
+use crate::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 Table {
+ /// Convert a `T` into `toml::Table`.
+ ///
+ /// 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<Self, crate::ser::Error>
+ where
+ T: ser::Serialize,
+ {
+ value.serialize(crate::value::TableSerializer)
+ }
+
+ /// Interpret a `toml::Table` as an instance of type `T`.
+ ///
+ /// This conversion can fail if the structure of the `Table` does not match the structure
+ /// expected by `T`, for example if `T` is a bool which can't be mapped to a `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)
+ }
+}
+
+#[cfg(feature = "display")]
+impl fmt::Display for Table {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ crate::ser::to_string(self)
+ .expect("Unable to represent value as string")
+ .fmt(f)
+ }
+}
+
+#[cfg(feature = "parse")]
+impl std::str::FromStr for Table {
+ type Err = crate::de::Error;
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ crate::from_str(s)
+ }
+}
+
+impl<'de> de::Deserializer<'de> for Table {
+ type Error = crate::de::Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, crate::de::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ Value::Table(self).deserialize_any(visitor)
+ }
+
+ #[inline]
+ fn deserialize_enum<V>(
+ self,
+ name: &'static str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, crate::de::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ Value::Table(self).deserialize_enum(name, variants, visitor)
+ }
+
+ // `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>,
+ {
+ Value::Table(self).deserialize_option(visitor)
+ }
+
+ fn deserialize_newtype_struct<V>(
+ self,
+ name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, crate::de::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ Value::Table(self).deserialize_newtype_struct(name, visitor)
+ }
+
+ 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
+ }
+}
+
+impl<'de> de::IntoDeserializer<'de, crate::de::Error> for Table {
+ type Deserializer = Self;
+
+ fn into_deserializer(self) -> Self {
+ self
+ }
+}
diff --git a/vendor/toml-0.7.5/src/value.rs b/vendor/toml-0.7.5/src/value.rs
new file mode 100644
index 000000000..2785d9de9
--- /dev/null
+++ b/vendor/toml-0.7.5/src/value.rs
@@ -0,0 +1,1455 @@
+//! Definition of a TOML [value][Value]
+
+use std::collections::{BTreeMap, HashMap};
+use std::fmt;
+use std::hash::Hash;
+use std::mem::discriminant;
+use std::ops;
+use std::vec;
+
+use serde::de;
+use serde::de::IntoDeserializer;
+use serde::ser;
+
+use toml_datetime::__unstable as datetime;
+pub use toml_datetime::{Date, Datetime, DatetimeParseError, Offset, Time};
+
+/// Type representing a TOML array, payload of the `Value::Array` variant
+pub type Array = Vec<Value>;
+
+#[doc(no_inline)]
+pub use crate::Table;
+
+/// 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),
+}
+
+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(ValueSerializer)
+ }
+
+ /// 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)
+ }
+}
+
+#[cfg(feature = "display")]
+impl fmt::Display for Value {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use serde::Serialize as _;
+
+ let mut output = String::new();
+ let serializer = crate::ser::ValueSerializer::new(&mut output);
+ self.serialize(serializer).unwrap();
+ output.fmt(f)
+ }
+}
+
+#[cfg(feature = "parse")]
+impl std::str::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: datetime::DatetimeFromString = visitor.next_value()?;
+ return Ok(Value::Datetime(date.value));
+ }
+ None => return Ok(Value::Table(Table::new())),
+ Some(false) => {}
+ }
+ let mut map = Table::new();
+ map.insert(key, visitor.next_value()?);
+ while let Some(key) = visitor.next_key::<String>()? {
+ if let crate::map::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)
+ }
+}
+
+// This is wrapped by `Table` and any trait methods implemented here need to be wrapped there.
+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: &'static 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()),
+ Value::Table(variant) => {
+ use de::Error;
+ if variant.is_empty() {
+ Err(crate::de::Error::custom(
+ "wanted exactly 1 element, found 0 elements",
+ ))
+ } else if variant.len() != 1 {
+ Err(crate::de::Error::custom(
+ "wanted exactly 1 element, more than 1 element",
+ ))
+ } else {
+ let deserializer = MapDeserializer::new(variant);
+ visitor.visit_enum(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: <Table as IntoIterator>::IntoIter,
+ value: Option<(String, Value)>,
+}
+
+impl MapDeserializer {
+ fn new(map: Table) -> 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(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::EnumAccess<'de> for MapDeserializer {
+ type Error = crate::de::Error;
+ type Variant = MapEnumDeserializer;
+
+ fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
+ where
+ V: serde::de::DeserializeSeed<'de>,
+ {
+ use de::Error;
+ let (key, value) = match self.iter.next() {
+ Some(pair) => pair,
+ None => {
+ return Err(Error::custom(
+ "expected table with exactly 1 entry, found empty table",
+ ));
+ }
+ };
+
+ let val = seed.deserialize(key.into_deserializer())?;
+
+ let variant = MapEnumDeserializer::new(value);
+
+ Ok((val, variant))
+ }
+}
+
+/// Deserializes table values into enum variants.
+pub(crate) struct MapEnumDeserializer {
+ value: Value,
+}
+
+impl MapEnumDeserializer {
+ pub(crate) fn new(value: Value) -> Self {
+ MapEnumDeserializer { value }
+ }
+}
+
+impl<'de> serde::de::VariantAccess<'de> for MapEnumDeserializer {
+ type Error = crate::de::Error;
+
+ fn unit_variant(self) -> Result<(), Self::Error> {
+ use de::Error;
+ match self.value {
+ Value::Table(values) => {
+ if values.is_empty() {
+ Ok(())
+ } else {
+ Err(Error::custom("expected empty table"))
+ }
+ }
+ e => Err(Error::custom(format!(
+ "expected table, found {}",
+ e.type_str()
+ ))),
+ }
+ }
+
+ fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
+ where
+ T: serde::de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(self.value.into_deserializer())
+ }
+
+ fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ use de::Error;
+ match self.value {
+ Value::Table(values) => {
+ let tuple_values = values
+ .into_iter()
+ .enumerate()
+ .map(|(index, (key, value))| match key.parse::<usize>() {
+ Ok(key_index) if key_index == index => Ok(value),
+ Ok(_) | Err(_) => Err(Error::custom(format!(
+ "expected table key `{}`, but was `{}`",
+ index, key
+ ))),
+ })
+ // Fold all values into a `Vec`, or return the first error.
+ .fold(Ok(Vec::with_capacity(len)), |result, value_result| {
+ result.and_then(move |mut tuple_values| match value_result {
+ Ok(value) => {
+ tuple_values.push(value);
+ Ok(tuple_values)
+ }
+ // `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>`
+ Err(e) => Err(e),
+ })
+ })?;
+
+ if tuple_values.len() == len {
+ serde::de::Deserializer::deserialize_seq(
+ tuple_values.into_deserializer(),
+ visitor,
+ )
+ } else {
+ Err(Error::custom(format!("expected tuple with length {}", len)))
+ }
+ }
+ e => Err(Error::custom(format!(
+ "expected table, found {}",
+ e.type_str()
+ ))),
+ }
+ }
+
+ fn struct_variant<V>(
+ self,
+ fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ serde::de::Deserializer::deserialize_struct(
+ self.value.into_deserializer(),
+ "", // TODO: this should be the variant name
+ fields,
+ visitor,
+ )
+ }
+}
+
+impl<'de> de::IntoDeserializer<'de, crate::de::Error> for Value {
+ type Deserializer = Self;
+
+ fn into_deserializer(self) -> Self {
+ self
+ }
+}
+
+struct ValueSerializer;
+
+impl ser::Serializer for ValueSerializer {
+ type Ok = Value;
+ type Error = crate::ser::Error;
+
+ type SerializeSeq = ValueSerializeVec;
+ type SerializeTuple = ValueSerializeVec;
+ type SerializeTupleStruct = ValueSerializeVec;
+ type SerializeTupleVariant = ValueSerializeVec;
+ type SerializeMap = ValueSerializeMap;
+ type SerializeStruct = ValueSerializeMap;
+ 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::unsupported_type(Some("unit")))
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<Value, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(Some(name)))
+ }
+
+ 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,
+ {
+ let value = value.serialize(ValueSerializer)?;
+ let mut table = Table::new();
+ table.insert(variant.to_owned(), value);
+ Ok(table.into())
+ }
+
+ fn serialize_none(self) -> Result<Value, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_none())
+ }
+
+ 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(ValueSerializeVec {
+ 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(ValueSerializeMap {
+ ser: SerializeMap {
+ map: Table::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::unsupported_type(Some(name)))
+ }
+}
+
+pub(crate) struct TableSerializer;
+
+impl ser::Serializer for TableSerializer {
+ type Ok = Table;
+ type Error = crate::ser::Error;
+
+ type SerializeSeq = ser::Impossible<Table, crate::ser::Error>;
+ type SerializeTuple = ser::Impossible<Table, crate::ser::Error>;
+ type SerializeTupleStruct = ser::Impossible<Table, crate::ser::Error>;
+ type SerializeTupleVariant = ser::Impossible<Table, crate::ser::Error>;
+ type SerializeMap = SerializeMap;
+ type SerializeStruct = SerializeMap;
+ type SerializeStructVariant = ser::Impossible<Table, crate::ser::Error>;
+
+ fn serialize_bool(self, _value: bool) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_i8(self, _value: i8) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_i16(self, _value: i16) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_i32(self, _value: i32) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_i64(self, _value: i64) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_u8(self, _value: u8) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_u16(self, _value: u16) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_u32(self, _value: u32) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_u64(self, _value: u64) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_f32(self, _value: f32) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_f64(self, _value: f64) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_char(self, _value: char) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_str(self, _value: &str) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_bytes(self, _value: &[u8]) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_unit(self) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_unit_variant(
+ self,
+ name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ ) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(Some(name)))
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ _name: &'static str,
+ value: &T,
+ ) -> Result<Table, 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<Table, crate::ser::Error>
+ where
+ T: ser::Serialize,
+ {
+ let value = value.serialize(ValueSerializer)?;
+ let mut table = Table::new();
+ table.insert(variant.to_owned(), value);
+ Ok(table)
+ }
+
+ fn serialize_none(self) -> Result<Table, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_none())
+ }
+
+ fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Table, crate::ser::Error>
+ where
+ T: ser::Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(None))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(Some(name)))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant, crate::ser::Error> {
+ Err(crate::ser::Error::unsupported_type(Some(name)))
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, crate::ser::Error> {
+ Ok(SerializeMap {
+ map: Table::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::unsupported_type(Some(name)))
+ }
+}
+
+struct ValueSerializeVec {
+ vec: Vec<Value>,
+}
+
+impl ser::SerializeSeq for ValueSerializeVec {
+ 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 ValueSerializeVec {
+ 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 ValueSerializeVec {
+ 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 ValueSerializeVec {
+ 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)
+ }
+}
+
+pub(crate) struct SerializeMap {
+ map: Table,
+ next_key: Option<String>,
+}
+
+impl ser::SerializeMap for SerializeMap {
+ type Ok = Table;
+ 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::key_not_string()),
+ };
+ 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 {
+ inner: crate::edit::ser::Error::UnsupportedNone,
+ }) => {}
+ Err(e) => return Err(e),
+ }
+ Ok(())
+ }
+
+ fn end(self) -> Result<Table, crate::ser::Error> {
+ Ok(self.map)
+ }
+}
+
+impl ser::SerializeStruct for SerializeMap {
+ type Ok = Table;
+ 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<Table, crate::ser::Error> {
+ ser::SerializeMap::end(self)
+ }
+}
+
+struct ValueSerializeMap {
+ ser: SerializeMap,
+}
+
+impl ser::SerializeMap for ValueSerializeMap {
+ 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,
+ {
+ self.ser.serialize_key(key)
+ }
+
+ fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), crate::ser::Error>
+ where
+ T: ser::Serialize,
+ {
+ self.ser.serialize_value(value)
+ }
+
+ fn end(self) -> Result<Value, crate::ser::Error> {
+ self.ser.end().map(Value::Table)
+ }
+}
+
+impl ser::SerializeStruct for ValueSerializeMap {
+ 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)
+ }
+ }
+}