summaryrefslogtreecommitdiffstats
path: root/vendor/toml/tests
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 12:41:41 +0000
commit10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87 (patch)
treebdffd5d80c26cf4a7a518281a204be1ace85b4c1 /vendor/toml/tests
parentReleasing progress-linux version 1.70.0+dfsg1-9~progress7.99u1. (diff)
downloadrustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.tar.xz
rustc-10ee2acdd26a7f1298c6f6d6b7af9b469fe29b87.zip
Merging upstream version 1.70.0+dfsg2.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/toml/tests')
-rw-r--r--vendor/toml/tests/decoder.rs67
-rw-r--r--vendor/toml/tests/decoder_compliance.rs21
-rw-r--r--vendor/toml/tests/encoder.rs81
-rw-r--r--vendor/toml/tests/encoder_compliance.rs14
-rw-r--r--vendor/toml/tests/testsuite/de_errors.rs460
-rw-r--r--vendor/toml/tests/testsuite/display.rs116
-rw-r--r--vendor/toml/tests/testsuite/display_tricky.rs55
-rw-r--r--vendor/toml/tests/testsuite/enum_external_deserialize.rs320
-rw-r--r--vendor/toml/tests/testsuite/float.rs80
-rw-r--r--vendor/toml/tests/testsuite/formatting.rs54
-rw-r--r--vendor/toml/tests/testsuite/macros.rs368
-rw-r--r--vendor/toml/tests/testsuite/main.rs15
-rw-r--r--vendor/toml/tests/testsuite/pretty.rs184
-rw-r--r--vendor/toml/tests/testsuite/serde.rs1074
-rw-r--r--vendor/toml/tests/testsuite/spanned.rs261
-rw-r--r--vendor/toml/tests/testsuite/spanned_impls.rs41
-rw-r--r--vendor/toml/tests/testsuite/tables_last.rs162
17 files changed, 3373 insertions, 0 deletions
diff --git a/vendor/toml/tests/decoder.rs b/vendor/toml/tests/decoder.rs
new file mode 100644
index 000000000..fe6db3f5e
--- /dev/null
+++ b/vendor/toml/tests/decoder.rs
@@ -0,0 +1,67 @@
+#![cfg(all(feature = "parse", feature = "display"))]
+
+#[derive(Copy, Clone)]
+pub struct Decoder;
+
+impl toml_test_harness::Decoder for Decoder {
+ fn name(&self) -> &str {
+ "toml"
+ }
+
+ fn decode(&self, data: &[u8]) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> {
+ let data = std::str::from_utf8(data).map_err(toml_test_harness::Error::new)?;
+ let document = data
+ .parse::<toml::Value>()
+ .map_err(toml_test_harness::Error::new)?;
+ value_to_decoded(&document)
+ }
+}
+
+fn value_to_decoded(
+ value: &toml::Value,
+) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> {
+ match value {
+ toml::Value::Integer(v) => Ok(toml_test_harness::Decoded::Value(
+ toml_test_harness::DecodedValue::from(*v),
+ )),
+ toml::Value::String(v) => Ok(toml_test_harness::Decoded::Value(
+ toml_test_harness::DecodedValue::from(v),
+ )),
+ toml::Value::Float(v) => Ok(toml_test_harness::Decoded::Value(
+ toml_test_harness::DecodedValue::from(*v),
+ )),
+ toml::Value::Datetime(v) => {
+ let value = v.to_string();
+ let value = match (v.date.is_some(), v.time.is_some(), v.offset.is_some()) {
+ (true, true, true) => toml_test_harness::DecodedValue::Datetime(value),
+ (true, true, false) => toml_test_harness::DecodedValue::DatetimeLocal(value),
+ (true, false, false) => toml_test_harness::DecodedValue::DateLocal(value),
+ (false, true, false) => toml_test_harness::DecodedValue::TimeLocal(value),
+ _ => unreachable!("Unsupported case"),
+ };
+ Ok(toml_test_harness::Decoded::Value(value))
+ }
+ toml::Value::Boolean(v) => Ok(toml_test_harness::Decoded::Value(
+ toml_test_harness::DecodedValue::from(*v),
+ )),
+ toml::Value::Array(v) => {
+ let v: Result<_, toml_test_harness::Error> = v.iter().map(value_to_decoded).collect();
+ Ok(toml_test_harness::Decoded::Array(v?))
+ }
+ toml::Value::Table(v) => table_to_decoded(v),
+ }
+}
+
+fn table_to_decoded(
+ value: &toml::value::Table,
+) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> {
+ let table: Result<_, toml_test_harness::Error> = value
+ .iter()
+ .map(|(k, v)| {
+ let k = k.to_owned();
+ let v = value_to_decoded(v)?;
+ Ok((k, v))
+ })
+ .collect();
+ Ok(toml_test_harness::Decoded::Table(table?))
+}
diff --git a/vendor/toml/tests/decoder_compliance.rs b/vendor/toml/tests/decoder_compliance.rs
new file mode 100644
index 000000000..5d4fc2a4d
--- /dev/null
+++ b/vendor/toml/tests/decoder_compliance.rs
@@ -0,0 +1,21 @@
+mod decoder;
+
+#[cfg(all(feature = "parse", feature = "display"))]
+fn main() {
+ let decoder = decoder::Decoder;
+ let mut harness = toml_test_harness::DecoderHarness::new(decoder);
+ harness
+ .ignore([
+ "valid/spec/float-0.toml",
+ // Unreleased
+ "valid/string/escape-esc.toml",
+ "valid/string/hex-escape.toml",
+ "valid/datetime/no-seconds.toml",
+ "valid/inline-table/newline.toml",
+ ])
+ .unwrap();
+ harness.test();
+}
+
+#[cfg(not(all(feature = "parse", feature = "display")))]
+fn main() {}
diff --git a/vendor/toml/tests/encoder.rs b/vendor/toml/tests/encoder.rs
new file mode 100644
index 000000000..eda62963c
--- /dev/null
+++ b/vendor/toml/tests/encoder.rs
@@ -0,0 +1,81 @@
+#![cfg(all(feature = "parse", feature = "display"))]
+
+#[derive(Copy, Clone)]
+pub struct Encoder;
+
+impl toml_test_harness::Encoder for Encoder {
+ fn name(&self) -> &str {
+ "toml"
+ }
+
+ fn encode(&self, data: toml_test_harness::Decoded) -> Result<String, toml_test_harness::Error> {
+ let value = from_decoded(&data)?;
+ let s = toml::to_string(&value).map_err(toml_test_harness::Error::new)?;
+ Ok(s)
+ }
+}
+
+fn from_decoded(
+ decoded: &toml_test_harness::Decoded,
+) -> Result<toml::Value, toml_test_harness::Error> {
+ let value = match decoded {
+ toml_test_harness::Decoded::Value(value) => from_decoded_value(value)?,
+ toml_test_harness::Decoded::Table(value) => toml::Value::Table(from_table(value)?),
+ toml_test_harness::Decoded::Array(value) => toml::Value::Array(from_array(value)?),
+ };
+ Ok(value)
+}
+
+fn from_decoded_value(
+ decoded: &toml_test_harness::DecodedValue,
+) -> Result<toml::Value, toml_test_harness::Error> {
+ match decoded {
+ toml_test_harness::DecodedValue::String(value) => Ok(toml::Value::String(value.clone())),
+ toml_test_harness::DecodedValue::Integer(value) => value
+ .parse::<i64>()
+ .map_err(toml_test_harness::Error::new)
+ .map(toml::Value::Integer),
+ toml_test_harness::DecodedValue::Float(value) => value
+ .parse::<f64>()
+ .map_err(toml_test_harness::Error::new)
+ .map(toml::Value::Float),
+ toml_test_harness::DecodedValue::Bool(value) => value
+ .parse::<bool>()
+ .map_err(toml_test_harness::Error::new)
+ .map(toml::Value::Boolean),
+ toml_test_harness::DecodedValue::Datetime(value) => value
+ .parse::<toml::value::Datetime>()
+ .map_err(toml_test_harness::Error::new)
+ .map(toml::Value::Datetime),
+ toml_test_harness::DecodedValue::DatetimeLocal(value) => value
+ .parse::<toml::value::Datetime>()
+ .map_err(toml_test_harness::Error::new)
+ .map(toml::Value::Datetime),
+ toml_test_harness::DecodedValue::DateLocal(value) => value
+ .parse::<toml::value::Datetime>()
+ .map_err(toml_test_harness::Error::new)
+ .map(toml::Value::Datetime),
+ toml_test_harness::DecodedValue::TimeLocal(value) => value
+ .parse::<toml::value::Datetime>()
+ .map_err(toml_test_harness::Error::new)
+ .map(toml::Value::Datetime),
+ }
+}
+
+fn from_table(
+ decoded: &std::collections::HashMap<String, toml_test_harness::Decoded>,
+) -> Result<toml::value::Table, toml_test_harness::Error> {
+ decoded
+ .iter()
+ .map(|(k, v)| {
+ let v = from_decoded(v)?;
+ Ok((k.to_owned(), v))
+ })
+ .collect()
+}
+
+fn from_array(
+ decoded: &[toml_test_harness::Decoded],
+) -> Result<toml::value::Array, toml_test_harness::Error> {
+ decoded.iter().map(from_decoded).collect()
+}
diff --git a/vendor/toml/tests/encoder_compliance.rs b/vendor/toml/tests/encoder_compliance.rs
new file mode 100644
index 000000000..380724831
--- /dev/null
+++ b/vendor/toml/tests/encoder_compliance.rs
@@ -0,0 +1,14 @@
+mod decoder;
+mod encoder;
+
+#[cfg(all(feature = "parse", feature = "display"))]
+fn main() {
+ let encoder = encoder::Encoder;
+ let decoder = decoder::Decoder;
+ let mut harness = toml_test_harness::EncoderHarness::new(encoder, decoder);
+ harness.ignore(["valid/spec/float-0.toml"]).unwrap();
+ harness.test();
+}
+
+#[cfg(not(all(feature = "parse", feature = "display")))]
+fn main() {}
diff --git a/vendor/toml/tests/testsuite/de_errors.rs b/vendor/toml/tests/testsuite/de_errors.rs
new file mode 100644
index 000000000..b3630bd4e
--- /dev/null
+++ b/vendor/toml/tests/testsuite/de_errors.rs
@@ -0,0 +1,460 @@
+use serde::{de, Deserialize};
+use std::fmt;
+
+macro_rules! bad {
+ ($toml:expr, $ty:ty, $msg:expr) => {
+ match toml::from_str::<$ty>($toml) {
+ Ok(s) => panic!("parsed to: {:#?}", s),
+ Err(e) => snapbox::assert_eq($msg, e.to_string()),
+ }
+ };
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+struct Parent<T> {
+ p_a: T,
+ p_b: Vec<Child<T>>,
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+#[serde(deny_unknown_fields)]
+struct Child<T> {
+ c_a: T,
+ c_b: T,
+}
+
+#[derive(Debug, PartialEq)]
+enum CasedString {
+ Lowercase(String),
+ Uppercase(String),
+}
+
+impl<'de> de::Deserialize<'de> for CasedString {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ struct CasedStringVisitor;
+
+ impl<'de> de::Visitor<'de> for CasedStringVisitor {
+ type Value = CasedString;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a string")
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ if s.is_empty() {
+ Err(de::Error::invalid_length(0, &"a non-empty string"))
+ } else if s.chars().all(|x| x.is_ascii_lowercase()) {
+ Ok(CasedString::Lowercase(s.to_string()))
+ } else if s.chars().all(|x| x.is_ascii_uppercase()) {
+ Ok(CasedString::Uppercase(s.to_string()))
+ } else {
+ Err(de::Error::invalid_value(
+ de::Unexpected::Str(s),
+ &"all lowercase or all uppercase",
+ ))
+ }
+ }
+ }
+
+ deserializer.deserialize_any(CasedStringVisitor)
+ }
+}
+
+#[test]
+fn custom_errors() {
+ toml::from_str::<Parent<CasedString>>(
+ "
+ p_a = 'a'
+ p_b = [{c_a = 'a', c_b = 'c'}]
+ ",
+ )
+ .unwrap();
+
+ // Custom error at p_b value.
+ bad!(
+ "
+ p_a = ''
+ # ^
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 2, column 19
+ |
+2 | p_a = ''
+ | ^^
+invalid length 0, expected a non-empty string
+"
+ );
+
+ // Missing field in table.
+ bad!(
+ "
+ p_a = 'a'
+ # ^
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 1, column 1
+ |
+1 |
+ | ^
+missing field `p_b`
+"
+ );
+
+ // Invalid type in p_b.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = 1
+ # ^
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 3, column 19
+ |
+3 | p_b = 1
+ | ^
+invalid type: integer `1`, expected a sequence
+"
+ );
+
+ // Sub-table in Vec is missing a field.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a'}
+ # ^
+ ]
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 4, column 17
+ |
+4 | {c_a = 'a'}
+ | ^^^^^^^^^^^
+missing field `c_b`
+"
+ );
+
+ // Sub-table in Vec has a field with a bad value.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a', c_b = '*'}
+ # ^
+ ]
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 4, column 35
+ |
+4 | {c_a = 'a', c_b = '*'}
+ | ^^^
+invalid value: string \"*\", expected all lowercase or all uppercase
+"
+ );
+
+ // Sub-table in Vec is missing a field.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a', c_b = 'b'},
+ {c_a = 'aa'}
+ # ^
+ ]
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 5, column 17
+ |
+5 | {c_a = 'aa'}
+ | ^^^^^^^^^^^^
+missing field `c_b`
+"
+ );
+
+ // Sub-table in the middle of a Vec is missing a field.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a', c_b = 'b'},
+ {c_a = 'aa'},
+ # ^
+ {c_a = 'aaa', c_b = 'bbb'},
+ ]
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 5, column 17
+ |
+5 | {c_a = 'aa'},
+ | ^^^^^^^^^^^^
+missing field `c_b`
+"
+ );
+
+ // Sub-table in the middle of a Vec has a field with a bad value.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a', c_b = 'b'},
+ {c_a = 'aa', c_b = 1},
+ # ^
+ {c_a = 'aaa', c_b = 'bbb'},
+ ]
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 5, column 36
+ |
+5 | {c_a = 'aa', c_b = 1},
+ | ^
+invalid type: integer `1`, expected a string
+"
+ );
+
+ // Sub-table in the middle of a Vec has an extra field.
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = 'a', c_b = 'b'},
+ {c_a = 'aa', c_b = 'bb', c_d = 'd'},
+ # ^
+ {c_a = 'aaa', c_b = 'bbb'},
+ {c_a = 'aaaa', c_b = 'bbbb'},
+ ]
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 5, column 42
+ |
+5 | {c_a = 'aa', c_b = 'bb', c_d = 'd'},
+ | ^^^
+unknown field `c_d`, expected `c_a` or `c_b`
+"
+ );
+
+ // Sub-table in the middle of a Vec is missing a field.
+ // FIXME: This location is pretty off.
+ bad!(
+ "
+ p_a = 'a'
+ [[p_b]]
+ c_a = 'a'
+ c_b = 'b'
+ [[p_b]]
+ c_a = 'aa'
+ # c_b = 'bb' # <- missing field
+ [[p_b]]
+ c_a = 'aaa'
+ c_b = 'bbb'
+ [[p_b]]
+ # ^
+ c_a = 'aaaa'
+ c_b = 'bbbb'
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 6, column 13
+ |
+6 | [[p_b]]
+ | ^^^^^^^^^^^^^^^^^^^
+missing field `c_b`
+"
+ );
+
+ // Sub-table in the middle of a Vec has a field with a bad value.
+ bad!(
+ "
+ p_a = 'a'
+ [[p_b]]
+ c_a = 'a'
+ c_b = 'b'
+ [[p_b]]
+ c_a = 'aa'
+ c_b = '*'
+ # ^
+ [[p_b]]
+ c_a = 'aaa'
+ c_b = 'bbb'
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 8, column 19
+ |
+8 | c_b = '*'
+ | ^^^
+invalid value: string \"*\", expected all lowercase or all uppercase
+"
+ );
+
+ // Sub-table in the middle of a Vec has an extra field.
+ bad!(
+ "
+ p_a = 'a'
+ [[p_b]]
+ c_a = 'a'
+ c_b = 'b'
+ [[p_b]]
+ c_a = 'aa'
+ c_d = 'dd' # unknown field
+ # ^
+ [[p_b]]
+ c_a = 'aaa'
+ c_b = 'bbb'
+ [[p_b]]
+ c_a = 'aaaa'
+ c_b = 'bbbb'
+ ",
+ Parent<CasedString>,
+ "\
+TOML parse error at line 8, column 13
+ |
+8 | c_d = 'dd' # unknown field
+ | ^^^
+unknown field `c_d`, expected `c_a` or `c_b`
+"
+ );
+}
+
+#[test]
+fn serde_derive_deserialize_errors() {
+ bad!(
+ "
+ p_a = ''
+ # ^
+ ",
+ Parent<String>,
+ "\
+TOML parse error at line 1, column 1
+ |
+1 |
+ | ^
+missing field `p_b`
+"
+ );
+
+ bad!(
+ "
+ p_a = ''
+ p_b = [
+ {c_a = ''}
+ # ^
+ ]
+ ",
+ Parent<String>,
+ "\
+TOML parse error at line 4, column 17
+ |
+4 | {c_a = ''}
+ | ^^^^^^^^^^
+missing field `c_b`
+"
+ );
+
+ bad!(
+ "
+ p_a = ''
+ p_b = [
+ {c_a = '', c_b = 1}
+ # ^
+ ]
+ ",
+ Parent<String>,
+ "\
+TOML parse error at line 4, column 34
+ |
+4 | {c_a = '', c_b = 1}
+ | ^
+invalid type: integer `1`, expected a string
+"
+ );
+
+ // FIXME: This location could be better.
+ bad!(
+ "
+ p_a = ''
+ p_b = [
+ {c_a = '', c_b = '', c_d = ''},
+ # ^
+ ]
+ ",
+ Parent<String>,
+ "\
+TOML parse error at line 4, column 38
+ |
+4 | {c_a = '', c_b = '', c_d = ''},
+ | ^^^
+unknown field `c_d`, expected `c_a` or `c_b`
+"
+ );
+
+ bad!(
+ "
+ p_a = 'a'
+ p_b = [
+ {c_a = '', c_b = 1, c_d = ''},
+ # ^
+ ]
+ ",
+ Parent<String>,
+ "\
+TOML parse error at line 4, column 34
+ |
+4 | {c_a = '', c_b = 1, c_d = ''},
+ | ^
+invalid type: integer `1`, expected a string
+"
+ );
+}
+
+#[test]
+fn error_handles_crlf() {
+ bad!(
+ "\r\n\
+ [t1]\r\n\
+ [t2]\r\n\
+ a = 1\r\n\
+ a = 2\r\n\
+ ",
+ toml::Value,
+ "\
+TOML parse error at line 5, column 1
+ |
+5 | a = 2
+ | ^
+duplicate key `a` in table `t2`
+"
+ );
+
+ // Should be the same as above.
+ bad!(
+ "\n\
+ [t1]\n\
+ [t2]\n\
+ a = 1\n\
+ a = 2\n\
+ ",
+ toml::Value,
+ "\
+TOML parse error at line 5, column 1
+ |
+5 | a = 2
+ | ^
+duplicate key `a` in table `t2`
+"
+ );
+}
diff --git a/vendor/toml/tests/testsuite/display.rs b/vendor/toml/tests/testsuite/display.rs
new file mode 100644
index 000000000..7430fac82
--- /dev/null
+++ b/vendor/toml/tests/testsuite/display.rs
@@ -0,0 +1,116 @@
+use toml::map::Map;
+use toml::Value::{Array, Boolean, Float, Integer, String, Table};
+
+macro_rules! map( ($($k:expr => $v:expr),*) => ({
+ let mut _m = Map::new();
+ $(_m.insert($k.to_string(), $v);)*
+ _m
+}) );
+
+#[test]
+fn simple_show() {
+ assert_eq!(String("foo".to_string()).to_string(), "\"foo\"");
+ assert_eq!(Integer(10).to_string(), "10");
+ assert_eq!(Float(10.0).to_string(), "10.0");
+ assert_eq!(Float(2.4).to_string(), "2.4");
+ assert_eq!(Boolean(true).to_string(), "true");
+ assert_eq!(Array(vec![]).to_string(), "[]");
+ assert_eq!(Array(vec![Integer(1), Integer(2)]).to_string(), "[1, 2]");
+}
+
+#[test]
+fn table() {
+ assert_eq!(map! {}.to_string(), "");
+ assert_eq!(
+ map! {
+ "test" => Integer(2),
+ "test2" => Integer(3) }
+ .to_string(),
+ "test = 2\ntest2 = 3\n"
+ );
+ assert_eq!(
+ map! {
+ "test" => Integer(2),
+ "test2" => Table(map! {
+ "test" => String("wut".to_string())
+ })
+ }
+ .to_string(),
+ "test = 2\n\
+ \n\
+ [test2]\n\
+ test = \"wut\"\n"
+ );
+ assert_eq!(
+ map! {
+ "test" => Integer(2),
+ "test2" => Table(map! {
+ "test" => String("wut".to_string())
+ })
+ }
+ .to_string(),
+ "test = 2\n\
+ \n\
+ [test2]\n\
+ test = \"wut\"\n"
+ );
+ assert_eq!(
+ map! {
+ "test" => Integer(2),
+ "test2" => Array(vec![Table(map! {
+ "test" => String("wut".to_string())
+ })])
+ }
+ .to_string(),
+ "test = 2\n\
+ \n\
+ [[test2]]\n\
+ test = \"wut\"\n"
+ );
+ #[cfg(feature = "preserve_order")]
+ assert_eq!(
+ map! {
+ "foo.bar" => Integer(2),
+ "foo\"bar" => Integer(2)
+ }
+ .to_string(),
+ "\"foo.bar\" = 2\n\
+ \"foo\\\"bar\" = 2\n"
+ );
+ assert_eq!(
+ map! {
+ "test" => Integer(2),
+ "test2" => Array(vec![Table(map! {
+ "test" => Array(vec![Integer(2)])
+ })])
+ }
+ .to_string(),
+ "test = 2\n\
+ \n\
+ [[test2]]\n\
+ test = [2]\n"
+ );
+ let table = map! {
+ "test" => Integer(2),
+ "test2" => Array(vec![Table(map! {
+ "test" => Array(vec![Array(vec![Integer(2), Integer(3)]),
+ Array(vec![String("foo".to_string()), String("bar".to_string())])])
+ })])
+ };
+ assert_eq!(
+ table.to_string(),
+ "test = 2\n\
+ \n\
+ [[test2]]\n\
+ test = [[2, 3], [\"foo\", \"bar\"]]\n"
+ );
+ assert_eq!(
+ map! {
+ "test" => Array(vec![Integer(2)]),
+ "test2" => Integer(2)
+ }
+ .to_string(),
+ "test = [2]\n\
+ test2 = 2\n"
+ );
+}
diff --git a/vendor/toml/tests/testsuite/display_tricky.rs b/vendor/toml/tests/testsuite/display_tricky.rs
new file mode 100644
index 000000000..379ae9138
--- /dev/null
+++ b/vendor/toml/tests/testsuite/display_tricky.rs
@@ -0,0 +1,55 @@
+use serde::Deserialize;
+use serde::Serialize;
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Recipe {
+ pub name: String,
+ pub description: Option<String>,
+ #[serde(default)]
+ pub modules: Vec<Modules>,
+ #[serde(default)]
+ pub packages: Vec<Packages>,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Modules {
+ pub name: String,
+ pub version: Option<String>,
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct Packages {
+ pub name: String,
+ pub version: Option<String>,
+}
+
+#[test]
+fn both_ends() {
+ let recipe_works = toml::from_str::<Recipe>(
+ r#"
+ name = "testing"
+ description = "example"
+ modules = []
+
+ [[packages]]
+ name = "base"
+ "#,
+ )
+ .unwrap();
+ toml::to_string(&recipe_works).unwrap();
+
+ let recipe_fails = toml::from_str::<Recipe>(
+ r#"
+ name = "testing"
+ description = "example"
+ packages = []
+
+ [[modules]]
+ name = "base"
+ "#,
+ )
+ .unwrap();
+
+ let recipe_toml = toml::Table::try_from(recipe_fails).unwrap();
+ recipe_toml.to_string();
+}
diff --git a/vendor/toml/tests/testsuite/enum_external_deserialize.rs b/vendor/toml/tests/testsuite/enum_external_deserialize.rs
new file mode 100644
index 000000000..6e0c2f768
--- /dev/null
+++ b/vendor/toml/tests/testsuite/enum_external_deserialize.rs
@@ -0,0 +1,320 @@
+use serde::Deserialize;
+
+#[derive(Debug, Deserialize, PartialEq)]
+struct OuterStruct {
+ inner: TheEnum,
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+enum TheEnum {
+ Plain,
+ Tuple(i64, bool),
+ NewType(String),
+ Struct { value: i64 },
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+struct Val {
+ val: TheEnum,
+}
+
+#[derive(Debug, Deserialize, PartialEq)]
+struct Multi {
+ enums: Vec<TheEnum>,
+}
+
+fn value_from_str<T>(s: &'_ str) -> Result<T, toml::de::Error>
+where
+ T: serde::de::DeserializeOwned,
+{
+ T::deserialize(toml::de::ValueDeserializer::new(s))
+}
+
+#[test]
+fn invalid_variant_returns_error_with_good_message_string() {
+ let error = value_from_str::<TheEnum>("\"NonExistent\"").unwrap_err();
+ snapbox::assert_eq(
+ r#"unknown variant `NonExistent`, expected one of `Plain`, `Tuple`, `NewType`, `Struct`
+"#,
+ error.to_string(),
+ );
+
+ let error = toml::from_str::<Val>("val = \"NonExistent\"").unwrap_err();
+ snapbox::assert_eq(
+ r#"TOML parse error at line 1, column 7
+ |
+1 | val = "NonExistent"
+ | ^^^^^^^^^^^^^
+unknown variant `NonExistent`, expected one of `Plain`, `Tuple`, `NewType`, `Struct`
+"#,
+ error.to_string(),
+ );
+}
+
+#[test]
+fn invalid_variant_returns_error_with_good_message_inline_table() {
+ let error = value_from_str::<TheEnum>("{ NonExistent = {} }").unwrap_err();
+ snapbox::assert_eq(
+ r#"unknown variant `NonExistent`, expected one of `Plain`, `Tuple`, `NewType`, `Struct`
+"#,
+ error.to_string(),
+ );
+
+ let error = toml::from_str::<Val>("val = { NonExistent = {} }").unwrap_err();
+ snapbox::assert_eq(
+ r#"TOML parse error at line 1, column 9
+ |
+1 | val = { NonExistent = {} }
+ | ^^^^^^^^^^^
+unknown variant `NonExistent`, expected one of `Plain`, `Tuple`, `NewType`, `Struct`
+"#,
+ error.to_string(),
+ );
+}
+
+#[test]
+fn extra_field_returns_expected_empty_table_error() {
+ let error = value_from_str::<TheEnum>("{ Plain = { extra_field = 404 } }").unwrap_err();
+ snapbox::assert_eq(
+ r#"expected empty table
+"#,
+ error.to_string(),
+ );
+
+ let error = toml::from_str::<Val>("val = { Plain = { extra_field = 404 } }").unwrap_err();
+ snapbox::assert_eq(
+ r#"TOML parse error at line 1, column 17
+ |
+1 | val = { Plain = { extra_field = 404 } }
+ | ^^^^^^^^^^^^^^^^^^^^^
+expected empty table
+"#,
+ error.to_string(),
+ );
+}
+
+#[test]
+fn extra_field_returns_expected_empty_table_error_struct_variant() {
+ let error = value_from_str::<TheEnum>("{ Struct = { value = 123, extra_0 = 0, extra_1 = 1 } }")
+ .unwrap_err();
+
+ snapbox::assert_eq(
+ r#"unexpected keys in table: extra_0, extra_1, available keys: value
+"#,
+ error.to_string(),
+ );
+
+ let error =
+ toml::from_str::<Val>("val = { Struct = { value = 123, extra_0 = 0, extra_1 = 1 } }")
+ .unwrap_err();
+
+ snapbox::assert_eq(
+ r#"TOML parse error at line 1, column 33
+ |
+1 | val = { Struct = { value = 123, extra_0 = 0, extra_1 = 1 } }
+ | ^^^^^^^
+unexpected keys in table: extra_0, extra_1, available keys: value
+"#,
+ error.to_string(),
+ );
+}
+
+mod enum_unit {
+ use super::*;
+
+ #[test]
+ fn from_str() {
+ assert_eq!(TheEnum::Plain, value_from_str("\"Plain\"").unwrap());
+
+ assert_eq!(
+ Val {
+ val: TheEnum::Plain
+ },
+ toml::from_str("val = \"Plain\"").unwrap()
+ );
+ }
+
+ #[test]
+ fn from_inline_table() {
+ assert_eq!(TheEnum::Plain, value_from_str("{ Plain = {} }").unwrap());
+ assert_eq!(
+ Val {
+ val: TheEnum::Plain
+ },
+ toml::from_str("val = { Plain = {} }").unwrap()
+ );
+ }
+
+ #[test]
+ fn from_std_table() {
+ assert_eq!(TheEnum::Plain, toml::from_str("[Plain]\n").unwrap());
+ }
+}
+
+mod enum_tuple {
+ use super::*;
+
+ #[test]
+ fn from_inline_table() {
+ assert_eq!(
+ TheEnum::Tuple(-123, true),
+ value_from_str("{ Tuple = { 0 = -123, 1 = true } }").unwrap()
+ );
+ assert_eq!(
+ Val {
+ val: TheEnum::Tuple(-123, true)
+ },
+ toml::from_str("val = { Tuple = { 0 = -123, 1 = true } }").unwrap()
+ );
+ }
+
+ #[test]
+ fn from_std_table() {
+ assert_eq!(
+ TheEnum::Tuple(-123, true),
+ toml::from_str(
+ r#"[Tuple]
+ 0 = -123
+ 1 = true
+ "#
+ )
+ .unwrap()
+ );
+ }
+}
+
+mod enum_newtype {
+ use super::*;
+
+ #[test]
+ fn from_inline_table() {
+ assert_eq!(
+ TheEnum::NewType("value".to_string()),
+ value_from_str(r#"{ NewType = "value" }"#).unwrap()
+ );
+ assert_eq!(
+ Val {
+ val: TheEnum::NewType("value".to_string()),
+ },
+ toml::from_str(r#"val = { NewType = "value" }"#).unwrap()
+ );
+ }
+
+ #[test]
+ fn from_std_table() {
+ assert_eq!(
+ TheEnum::NewType("value".to_string()),
+ toml::from_str(r#"NewType = "value""#).unwrap()
+ );
+ assert_eq!(
+ Val {
+ val: TheEnum::NewType("value".to_string()),
+ },
+ toml::from_str(
+ r#"[val]
+ NewType = "value"
+ "#
+ )
+ .unwrap()
+ );
+ }
+}
+
+mod enum_struct {
+ use super::*;
+
+ #[test]
+ fn from_inline_table() {
+ assert_eq!(
+ TheEnum::Struct { value: -123 },
+ value_from_str("{ Struct = { value = -123 } }").unwrap()
+ );
+ assert_eq!(
+ Val {
+ val: TheEnum::Struct { value: -123 }
+ },
+ toml::from_str("val = { Struct = { value = -123 } }").unwrap()
+ );
+ }
+
+ #[test]
+ fn from_std_table() {
+ assert_eq!(
+ TheEnum::Struct { value: -123 },
+ toml::from_str(
+ r#"[Struct]
+ value = -123
+ "#
+ )
+ .unwrap()
+ );
+ }
+
+ #[test]
+ fn from_nested_std_table() {
+ assert_eq!(
+ OuterStruct {
+ inner: TheEnum::Struct { value: -123 }
+ },
+ toml::from_str(
+ r#"[inner.Struct]
+ value = -123
+ "#
+ )
+ .unwrap()
+ );
+ }
+}
+
+mod enum_array {
+ use super::*;
+
+ #[test]
+ fn from_inline_tables() {
+ let toml_str = r#"
+ enums = [
+ { Plain = {} },
+ { Tuple = { 0 = -123, 1 = true } },
+ { NewType = "value" },
+ { Struct = { value = -123 } }
+ ]"#;
+ assert_eq!(
+ Multi {
+ enums: vec![
+ TheEnum::Plain,
+ TheEnum::Tuple(-123, true),
+ TheEnum::NewType("value".to_string()),
+ TheEnum::Struct { value: -123 },
+ ]
+ },
+ toml::from_str(toml_str).unwrap()
+ );
+ }
+
+ #[test]
+ fn from_std_table() {
+ let toml_str = r#"[[enums]]
+ Plain = {}
+
+ [[enums]]
+ Tuple = { 0 = -123, 1 = true }
+
+ [[enums]]
+ NewType = "value"
+
+ [[enums]]
+ Struct = { value = -123 }
+ "#;
+ assert_eq!(
+ Multi {
+ enums: vec![
+ TheEnum::Plain,
+ TheEnum::Tuple(-123, true),
+ TheEnum::NewType("value".to_string()),
+ TheEnum::Struct { value: -123 },
+ ]
+ },
+ toml::from_str(toml_str).unwrap()
+ );
+ }
+}
diff --git a/vendor/toml/tests/testsuite/float.rs b/vendor/toml/tests/testsuite/float.rs
new file mode 100644
index 000000000..d00813471
--- /dev/null
+++ b/vendor/toml/tests/testsuite/float.rs
@@ -0,0 +1,80 @@
+use serde::Deserialize;
+use serde::Serialize;
+use toml::Value;
+
+#[rustfmt::skip] // appears to be a bug in rustfmt to make this converge...
+macro_rules! float_inf_tests {
+ ($ty:ty) => {{
+ #[derive(Serialize, Deserialize)]
+ struct S {
+ sf1: $ty,
+ sf2: $ty,
+ sf3: $ty,
+ sf4: $ty,
+ sf5: $ty,
+ sf6: $ty,
+ sf7: $ty,
+ sf8: $ty,
+ }
+ let inf: S = toml::from_str(
+ r"
+ # infinity
+ sf1 = inf # positive infinity
+ sf2 = +inf # positive infinity
+ sf3 = -inf # negative infinity
+
+ # not a number
+ sf4 = nan # actual sNaN/qNaN encoding is implementation specific
+ sf5 = +nan # same as `nan`
+ sf6 = -nan # valid, actual encoding is implementation specific
+
+ # zero
+ sf7 = +0.0
+ sf8 = -0.0
+ ",
+ )
+ .expect("Parse infinities.");
+
+ assert!(inf.sf1.is_infinite());
+ assert!(inf.sf1.is_sign_positive());
+ assert!(inf.sf2.is_infinite());
+ assert!(inf.sf2.is_sign_positive());
+ assert!(inf.sf3.is_infinite());
+ assert!(inf.sf3.is_sign_negative());
+
+ assert!(inf.sf4.is_nan());
+ assert!(inf.sf4.is_sign_positive());
+ assert!(inf.sf5.is_nan());
+ assert!(inf.sf5.is_sign_positive());
+ assert!(inf.sf6.is_nan());
+ assert!(inf.sf6.is_sign_negative());
+
+ assert_eq!(inf.sf7, 0.0);
+ assert!(inf.sf7.is_sign_positive());
+ assert_eq!(inf.sf8, 0.0);
+ assert!(inf.sf8.is_sign_negative());
+
+ let s = toml::to_string(&inf).unwrap();
+ assert_eq!(
+ s,
+ "\
+sf1 = inf
+sf2 = inf
+sf3 = -inf
+sf4 = nan
+sf5 = nan
+sf6 = -nan
+sf7 = 0.0
+sf8 = -0.0
+"
+ );
+
+ toml::from_str::<Value>(&s).expect("roundtrip");
+ }};
+}
+
+#[test]
+fn float_inf() {
+ float_inf_tests!(f32);
+ float_inf_tests!(f64);
+}
diff --git a/vendor/toml/tests/testsuite/formatting.rs b/vendor/toml/tests/testsuite/formatting.rs
new file mode 100644
index 000000000..8240d1d30
--- /dev/null
+++ b/vendor/toml/tests/testsuite/formatting.rs
@@ -0,0 +1,54 @@
+use serde::Deserialize;
+use serde::Serialize;
+use toml::to_string;
+
+#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
+struct User {
+ pub name: String,
+ pub surname: String,
+}
+
+#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
+struct Users {
+ pub user: Vec<User>,
+}
+
+#[derive(Debug, Clone, Hash, PartialEq, Eq, Serialize, Deserialize)]
+struct TwoUsers {
+ pub user0: User,
+ pub user1: User,
+}
+
+#[test]
+fn no_unnecessary_newlines_array() {
+ assert!(!to_string(&Users {
+ user: vec![
+ User {
+ name: "John".to_string(),
+ surname: "Doe".to_string(),
+ },
+ User {
+ name: "Jane".to_string(),
+ surname: "Dough".to_string(),
+ },
+ ],
+ })
+ .unwrap()
+ .starts_with('\n'));
+}
+
+#[test]
+fn no_unnecessary_newlines_table() {
+ assert!(!to_string(&TwoUsers {
+ user0: User {
+ name: "John".to_string(),
+ surname: "Doe".to_string(),
+ },
+ user1: User {
+ name: "Jane".to_string(),
+ surname: "Dough".to_string(),
+ },
+ })
+ .unwrap()
+ .starts_with('\n'));
+}
diff --git a/vendor/toml/tests/testsuite/macros.rs b/vendor/toml/tests/testsuite/macros.rs
new file mode 100644
index 000000000..510070510
--- /dev/null
+++ b/vendor/toml/tests/testsuite/macros.rs
@@ -0,0 +1,368 @@
+use std::f64;
+
+use toml::toml;
+
+macro_rules! table {
+ ($($key:expr => $value:expr,)*) => {{
+ // https://github.com/rust-lang/rust/issues/60643
+ #[allow(unused_mut)]
+ let mut table = toml::value::Table::new();
+ $(
+ table.insert($key.to_string(), $value.into());
+ )*
+ toml::Value::Table(table)
+ }};
+}
+
+macro_rules! array {
+ ($($element:expr,)*) => {{
+ // https://github.com/rust-lang/rust/issues/60643
+ #![allow(clippy::vec_init_then_push)]
+ #[allow(unused_mut)]
+ let mut array = toml::value::Array::new();
+ $(
+ array.push($element.into());
+ )*
+ toml::Value::Array(array)
+ }};
+}
+
+macro_rules! datetime {
+ ($s:tt) => {
+ $s.parse::<toml::value::Datetime>().unwrap()
+ };
+}
+
+#[test]
+fn test_cargo_toml() {
+ // Simple sanity check of:
+ //
+ // - Ordinary tables
+ // - Inline tables
+ // - Inline arrays
+ // - String values
+ // - Table keys containing hyphen
+ // - Table headers containing hyphen
+ let actual = 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"
+ };
+
+ let expected = table! {
+ "package" => table! {
+ "name" => "toml".to_owned(),
+ "version" => "0.4.5".to_owned(),
+ "authors" => array! {
+ "Alex Crichton <alex@alexcrichton.com>".to_owned(),
+ },
+ },
+ "badges" => table! {
+ "travis-ci" => table! {
+ "repository" => "alexcrichton/toml-rs".to_owned(),
+ },
+ },
+ "dependencies" => table! {
+ "serde" => "1.0".to_owned(),
+ },
+ "dev-dependencies" => table! {
+ "serde_derive" => "1.0".to_owned(),
+ "serde_json" => "1.0".to_owned(),
+ },
+ };
+
+ assert_eq!(toml::Value::Table(actual), expected);
+}
+
+#[test]
+fn test_array() {
+ // Copied from the TOML spec.
+ let actual = toml! {
+ [[fruit]]
+ name = "apple"
+
+ [fruit.physical]
+ color = "red"
+ shape = "round"
+
+ [[fruit.variety]]
+ name = "red delicious"
+
+ [[fruit.variety]]
+ name = "granny smith"
+
+ [[fruit]]
+ name = "banana"
+
+ [[fruit.variety]]
+ name = "plantain"
+ };
+
+ let expected = table! {
+ "fruit" => array! {
+ table! {
+ "name" => "apple",
+ "physical" => table! {
+ "color" => "red",
+ "shape" => "round",
+ },
+ "variety" => array! {
+ table! {
+ "name" => "red delicious",
+ },
+ table! {
+ "name" => "granny smith",
+ },
+ },
+ },
+ table! {
+ "name" => "banana",
+ "variety" => array! {
+ table! {
+ "name" => "plantain",
+ },
+ },
+ },
+ },
+ };
+
+ assert_eq!(toml::Value::Table(actual), expected);
+}
+
+#[test]
+fn test_number() {
+ #![allow(clippy::unusual_byte_groupings)] // Verify the macro with odd formatting
+
+ let actual = toml! {
+ positive = 1
+ negative = -1
+ table = { positive = 1, negative = -1 }
+ array = [ 1, -1 ]
+ neg_zero = -0
+ pos_zero = +0
+ float = 1.618
+
+ sf1 = inf
+ sf2 = +inf
+ sf3 = -inf
+ sf7 = +0.0
+ sf8 = -0.0
+
+ hex = 0xa_b_c
+ oct = 0o755
+ bin = 0b11010110
+ };
+
+ let expected = table! {
+ "positive" => 1,
+ "negative" => -1,
+ "table" => table! {
+ "positive" => 1,
+ "negative" => -1,
+ },
+ "array" => array! {
+ 1,
+ -1,
+ },
+ "neg_zero" => -0,
+ "pos_zero" => 0,
+ "float" => 1.618,
+ "sf1" => f64::INFINITY,
+ "sf2" => f64::INFINITY,
+ "sf3" => f64::NEG_INFINITY,
+ "sf7" => 0.0,
+ "sf8" => -0.0,
+ "hex" => 2748,
+ "oct" => 493,
+ "bin" => 214,
+ };
+
+ assert_eq!(toml::Value::Table(actual), expected);
+}
+
+#[test]
+fn test_nan() {
+ let actual = toml! {
+ sf4 = nan
+ sf5 = +nan
+ sf6 = -nan
+ };
+ assert!(actual["sf4"].as_float().unwrap().is_nan());
+ assert!(actual["sf5"].as_float().unwrap().is_nan());
+ assert!(actual["sf6"].as_float().unwrap().is_nan());
+}
+
+#[test]
+fn test_datetime() {
+ let actual = toml! {
+ // Copied from the TOML spec.
+ odt1 = 1979-05-27T07:32:00Z
+ odt2 = 1979-05-27T00:32:00-07:00
+ odt3 = 1979-05-27T00:32:00.999999-07:00
+ odt4 = 1979-05-27 07:32:00Z
+ ldt1 = 1979-05-27T07:32:00
+ ldt2 = 1979-05-27T00:32:00.999999
+ ld1 = 1979-05-27
+ lt1 = 07:32:00
+ lt2 = 00:32:00.999999
+
+ table = {
+ odt1 = 1979-05-27T07:32:00Z,
+ odt2 = 1979-05-27T00:32:00-07:00,
+ odt3 = 1979-05-27T00:32:00.999999-07:00,
+ odt4 = 1979-05-27 07:32:00Z,
+ ldt1 = 1979-05-27T07:32:00,
+ ldt2 = 1979-05-27T00:32:00.999999,
+ ld1 = 1979-05-27,
+ lt1 = 07:32:00,
+ lt2 = 00:32:00.999999,
+ }
+
+ array = [
+ 1979-05-27T07:32:00Z,
+ 1979-05-27T00:32:00-07:00,
+ 1979-05-27T00:32:00.999999-07:00,
+ 1979-05-27 07:32:00Z,
+ 1979-05-27T07:32:00,
+ 1979-05-27T00:32:00.999999,
+ 1979-05-27,
+ 07:32:00,
+ 00:32:00.999999,
+ ]
+ };
+
+ let expected = table! {
+ "odt1" => datetime!("1979-05-27T07:32:00Z"),
+ "odt2" => datetime!("1979-05-27T00:32:00-07:00"),
+ "odt3" => datetime!("1979-05-27T00:32:00.999999-07:00"),
+ "odt4" => datetime!("1979-05-27 07:32:00Z"),
+ "ldt1" => datetime!("1979-05-27T07:32:00"),
+ "ldt2" => datetime!("1979-05-27T00:32:00.999999"),
+ "ld1" => datetime!("1979-05-27"),
+ "lt1" => datetime!("07:32:00"),
+ "lt2" => datetime!("00:32:00.999999"),
+
+ "table" => table! {
+ "odt1" => datetime!("1979-05-27T07:32:00Z"),
+ "odt2" => datetime!("1979-05-27T00:32:00-07:00"),
+ "odt3" => datetime!("1979-05-27T00:32:00.999999-07:00"),
+ "odt4" => datetime!("1979-05-27 07:32:00Z"),
+ "ldt1" => datetime!("1979-05-27T07:32:00"),
+ "ldt2" => datetime!("1979-05-27T00:32:00.999999"),
+ "ld1" => datetime!("1979-05-27"),
+ "lt1" => datetime!("07:32:00"),
+ "lt2" => datetime!("00:32:00.999999"),
+ },
+
+ "array" => array! {
+ datetime!("1979-05-27T07:32:00Z"),
+ datetime!("1979-05-27T00:32:00-07:00"),
+ datetime!("1979-05-27T00:32:00.999999-07:00"),
+ datetime!("1979-05-27 07:32:00Z"),
+ datetime!("1979-05-27T07:32:00"),
+ datetime!("1979-05-27T00:32:00.999999"),
+ datetime!("1979-05-27"),
+ datetime!("07:32:00"),
+ datetime!("00:32:00.999999"),
+ },
+ };
+
+ assert_eq!(toml::Value::Table(actual), expected);
+}
+
+// This test requires rustc >= 1.20.
+#[test]
+fn test_quoted_key() {
+ let actual = toml! {
+ "quoted" = true
+ table = { "quoted" = true }
+
+ [target."cfg(windows)".dependencies]
+ winapi = "0.2.8"
+ };
+
+ let expected = table! {
+ "quoted" => true,
+ "table" => table! {
+ "quoted" => true,
+ },
+ "target" => table! {
+ "cfg(windows)" => table! {
+ "dependencies" => table! {
+ "winapi" => "0.2.8",
+ },
+ },
+ },
+ };
+
+ assert_eq!(toml::Value::Table(actual), expected);
+}
+
+#[test]
+fn test_empty() {
+ let actual = toml! {
+ empty_inline_table = {}
+ empty_inline_array = []
+
+ [empty_table]
+
+ [[empty_array]]
+ };
+
+ let expected = table! {
+ "empty_inline_table" => table! {},
+ "empty_inline_array" => array! {},
+ "empty_table" => table! {},
+ "empty_array" => array! {
+ table! {},
+ },
+ };
+
+ assert_eq!(toml::Value::Table(actual), expected);
+}
+
+#[test]
+fn test_dotted_keys() {
+ let actual = toml! {
+ a.b = 123
+ a.c = 1979-05-27T07:32:00Z
+ [table]
+ a.b.c = 1
+ a . b . d = 2
+ in = { type.name = "cat", type.color = "blue" }
+ };
+
+ let expected = table! {
+ "a" => table! {
+ "b" => 123,
+ "c" => datetime!("1979-05-27T07:32:00Z"),
+ },
+ "table" => table! {
+ "a" => table! {
+ "b" => table! {
+ "c" => 1,
+ "d" => 2,
+ },
+ },
+ "in" => table! {
+ "type" => table! {
+ "name" => "cat",
+ "color" => "blue",
+ },
+ },
+ },
+ };
+
+ assert_eq!(toml::Value::Table(actual), expected);
+}
diff --git a/vendor/toml/tests/testsuite/main.rs b/vendor/toml/tests/testsuite/main.rs
new file mode 100644
index 000000000..14737878f
--- /dev/null
+++ b/vendor/toml/tests/testsuite/main.rs
@@ -0,0 +1,15 @@
+#![recursion_limit = "256"]
+#![cfg(all(feature = "parse", feature = "display"))]
+
+mod de_errors;
+mod display;
+mod display_tricky;
+mod enum_external_deserialize;
+mod float;
+mod formatting;
+mod macros;
+mod pretty;
+mod serde;
+mod spanned;
+mod spanned_impls;
+mod tables_last;
diff --git a/vendor/toml/tests/testsuite/pretty.rs b/vendor/toml/tests/testsuite/pretty.rs
new file mode 100644
index 000000000..3ae772b4f
--- /dev/null
+++ b/vendor/toml/tests/testsuite/pretty.rs
@@ -0,0 +1,184 @@
+use serde::ser::Serialize;
+use snapbox::assert_eq;
+
+const NO_PRETTY: &str = "\
+[example]
+array = [\"item 1\", \"item 2\"]
+empty = []
+oneline = \"this has no newlines.\"
+text = '''
+
+this is the first line\\nthis is the second line
+'''
+";
+
+#[test]
+fn no_pretty() {
+ let toml = NO_PRETTY;
+ let value: toml::Value = toml::from_str(toml).unwrap();
+ let mut result = String::with_capacity(128);
+ value.serialize(toml::Serializer::new(&mut result)).unwrap();
+ assert_eq(toml, &result);
+}
+
+const PRETTY_STD: &str = "\
+[example]
+array = [
+ \"item 1\",
+ \"item 2\",
+]
+empty = []
+one = [\"one\"]
+oneline = \"this has no newlines.\"
+text = \"\"\"
+this is the first line
+this is the second line
+\"\"\"
+";
+
+#[test]
+fn pretty_std() {
+ let toml = PRETTY_STD;
+ let value: toml::Value = toml::from_str(toml).unwrap();
+ let mut result = String::with_capacity(128);
+ value
+ .serialize(toml::Serializer::pretty(&mut result))
+ .unwrap();
+ assert_eq(toml, &result);
+}
+
+const PRETTY_TRICKY: &str = r##"[example]
+f = "\f"
+glass = """
+Nothing too unusual, except that I can eat glass in:
+- Greek: Μπορώ να φάω σπασμένα γυαλιά χωρίς να πάθω τίποτα.
+- Polish: Mogę jeść szkło, i mi nie szkodzi.
+- Hindi: मैं काँच खा सकता हूँ, मुझे उस से कोई पीडा नहीं होती.
+- Japanese: 私はガラスを食べられます。それは私を傷つけません。
+"""
+r = "\r"
+r_newline = """
+\r
+"""
+single = "this is a single line but has '' cuz it's tricky"
+single_tricky = "single line with ''' in it"
+tabs = """
+this is pretty standard
+\texcept for some \ttabs right here
+"""
+text = """
+this is the first line.
+This has a ''' in it and \"\"\" cuz it's tricky yo
+Also ' and \" because why not
+this is the fourth line
+"""
+"##;
+
+#[test]
+fn pretty_tricky() {
+ let toml = PRETTY_TRICKY;
+ let value: toml::Value = toml::from_str(toml).unwrap();
+ let mut result = String::with_capacity(128);
+ value
+ .serialize(toml::Serializer::pretty(&mut result))
+ .unwrap();
+ assert_eq(toml, &result);
+}
+
+const PRETTY_TABLE_ARRAY: &str = r##"[[array]]
+key = "foo"
+
+[[array]]
+key = "bar"
+
+[abc]
+doc = "this is a table"
+
+[example]
+single = "this is a single line string"
+"##;
+
+#[test]
+fn pretty_table_array() {
+ let toml = PRETTY_TABLE_ARRAY;
+ let value: toml::Value = toml::from_str(toml).unwrap();
+ let mut result = String::with_capacity(128);
+ value
+ .serialize(toml::Serializer::pretty(&mut result))
+ .unwrap();
+ assert_eq(toml, &result);
+}
+
+const TABLE_ARRAY: &str = r##"[[array]]
+key = "foo"
+
+[[array]]
+key = "bar"
+
+[abc]
+doc = "this is a table"
+
+[example]
+single = "this is a single line string"
+"##;
+
+#[test]
+fn table_array() {
+ let toml = TABLE_ARRAY;
+ let value: toml::Value = toml::from_str(toml).unwrap();
+ let mut result = String::with_capacity(128);
+ value.serialize(toml::Serializer::new(&mut result)).unwrap();
+ assert_eq(toml, &result);
+}
+
+const PRETTY_EMPTY_TABLE: &str = r#"[example]
+"#;
+
+#[test]
+fn pretty_empty_table() {
+ let toml = PRETTY_EMPTY_TABLE;
+ let value: toml::Value = toml::from_str(toml).unwrap();
+ let mut result = String::with_capacity(128);
+ value.serialize(toml::Serializer::new(&mut result)).unwrap();
+ assert_eq(toml, &result);
+}
+
+#[test]
+fn error_includes_key() {
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
+ struct Package {
+ name: String,
+ version: String,
+ authors: Vec<String>,
+ profile: Profile,
+ }
+
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
+ struct Profile {
+ dev: Dev,
+ }
+
+ #[derive(Debug, serde::Serialize, serde::Deserialize)]
+ struct Dev {
+ debug: U32OrBool,
+ }
+
+ #[derive(Clone, Debug, serde::Deserialize, serde::Serialize, Eq, PartialEq)]
+ #[serde(untagged, expecting = "expected a boolean or an integer")]
+ pub enum U32OrBool {
+ U32(u32),
+ Bool(bool),
+ }
+
+ let raw = r#"name = "foo"
+version = "0.0.0"
+authors = []
+
+[profile.dev]
+debug = true
+"#;
+
+ let pkg: Package = toml::from_str(raw).unwrap();
+ let pretty = toml::to_string_pretty(&pkg).unwrap();
+ assert_eq(raw, pretty);
+}
diff --git a/vendor/toml/tests/testsuite/serde.rs b/vendor/toml/tests/testsuite/serde.rs
new file mode 100644
index 000000000..3b9f65a4a
--- /dev/null
+++ b/vendor/toml/tests/testsuite/serde.rs
@@ -0,0 +1,1074 @@
+use serde::Deserialize;
+use serde::Deserializer;
+use serde::Serialize;
+use std::collections::BTreeMap;
+
+use toml::map::Map;
+use toml::Table;
+use toml::Value;
+
+macro_rules! t {
+ ($e:expr) => {
+ match $e {
+ Ok(t) => t,
+ Err(e) => panic!("{} failed with {}", stringify!($e), e),
+ }
+ };
+}
+
+macro_rules! equivalent {
+ ($literal:expr, $toml:expr,) => {{
+ let toml = $toml;
+ let literal = $literal;
+
+ // In/out of Value is equivalent
+ println!("try_from");
+ assert_eq!(t!(Table::try_from(literal.clone())), toml);
+ println!("try_into");
+ assert_eq!(literal, t!(toml.clone().try_into()));
+
+ // Through a string equivalent
+ println!("to_string");
+ snapbox::assert_eq(t!(toml::to_string(&toml)), t!(toml::to_string(&literal)));
+ println!("literal, from_str(toml)");
+ assert_eq!(literal, t!(toml::from_str(&t!(toml::to_string(&toml)))));
+ println!("toml, from_str(toml)");
+ assert_eq!(toml, t!(toml::from_str(&t!(toml::to_string(&toml)))));
+ }};
+}
+
+macro_rules! error {
+ ($ty:ty, $toml:expr, $msg_parse:expr, $msg_decode:expr) => {{
+ println!("attempting parsing");
+ match toml::from_str::<$ty>(&$toml.to_string()) {
+ Ok(_) => panic!("successful"),
+ Err(e) => snapbox::assert_eq($msg_parse, e.to_string()),
+ }
+
+ println!("attempting toml decoding");
+ match $toml.try_into::<$ty>() {
+ Ok(_) => panic!("successful"),
+ Err(e) => snapbox::assert_eq($msg_decode, e.to_string()),
+ }
+ }};
+}
+
+macro_rules! map( ($($k:ident: $v:expr),*) => ({
+ let mut _m = Map::new();
+ $(_m.insert(stringify!($k).to_string(), t!(Value::try_from($v)));)*
+ _m
+}) );
+
+#[test]
+fn smoke() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a: isize,
+ }
+
+ equivalent!(Foo { a: 2 }, map! { a: Value::Integer(2) },);
+}
+
+#[test]
+fn smoke_hyphen() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a_b: isize,
+ }
+
+ equivalent! {
+ Foo { a_b: 2 },
+ map! { a_b: Value::Integer(2)},
+ }
+
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo2 {
+ #[serde(rename = "a-b")]
+ a_b: isize,
+ }
+
+ let mut m = Map::new();
+ m.insert("a-b".to_string(), Value::Integer(2));
+ equivalent! {
+ Foo2 { a_b: 2 },
+ m,
+ }
+}
+
+#[test]
+fn nested() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a: isize,
+ b: Bar,
+ }
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Bar {
+ a: String,
+ }
+
+ equivalent! {
+ Foo { a: 2, b: Bar { a: "test".to_string() } },
+ map! {
+ a: Value::Integer(2),
+ b: map! {
+ a: Value::String("test".to_string())
+ }
+ },
+ }
+}
+
+#[test]
+fn application_decode_error() {
+ #[derive(PartialEq, Debug)]
+ struct Range10(usize);
+ impl<'de> serde::Deserialize<'de> for Range10 {
+ fn deserialize<D: Deserializer<'de>>(d: D) -> Result<Range10, D::Error> {
+ let x: usize = serde::Deserialize::deserialize(d)?;
+ if x > 10 {
+ Err(serde::de::Error::custom("more than 10"))
+ } else {
+ Ok(Range10(x))
+ }
+ }
+ }
+ let d_good = Value::Integer(5);
+ let d_bad1 = Value::String("not an isize".to_string());
+ let d_bad2 = Value::Integer(11);
+
+ assert_eq!(Range10(5), d_good.try_into().unwrap());
+
+ let err1: Result<Range10, _> = d_bad1.try_into();
+ assert!(err1.is_err());
+ let err2: Result<Range10, _> = d_bad2.try_into();
+ assert!(err2.is_err());
+}
+
+#[test]
+fn array() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a: Vec<isize>,
+ }
+
+ equivalent! {
+ Foo { a: vec![1, 2, 3, 4] },
+ map! {
+ a: Value::Array(vec![
+ Value::Integer(1),
+ Value::Integer(2),
+ Value::Integer(3),
+ Value::Integer(4)
+ ])
+ },
+ };
+}
+
+#[test]
+fn inner_structs_with_options() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a: Option<Box<Foo>>,
+ b: Bar,
+ }
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Bar {
+ a: String,
+ b: f64,
+ }
+
+ equivalent! {
+ Foo {
+ a: Some(Box::new(Foo {
+ a: None,
+ b: Bar { a: "foo".to_string(), b: 4.5 },
+ })),
+ b: Bar { a: "bar".to_string(), b: 1.0 },
+ },
+ map! {
+ a: map! {
+ b: map! {
+ a: Value::String("foo".to_string()),
+ b: Value::Float(4.5)
+ }
+ },
+ b: map! {
+ a: Value::String("bar".to_string()),
+ b: Value::Float(1.0)
+ }
+ },
+ }
+}
+
+#[test]
+#[cfg(feature = "preserve_order")]
+fn hashmap() {
+ use std::collections::HashSet;
+
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ set: HashSet<char>,
+ map: BTreeMap<String, isize>,
+ }
+
+ equivalent! {
+ Foo {
+ set: {
+ let mut s = HashSet::new();
+ s.insert('a');
+ s
+ },
+ map: {
+ let mut m = BTreeMap::new();
+ m.insert("bar".to_string(), 4);
+ m.insert("foo".to_string(), 10);
+ m
+ }
+ },
+ map! {
+ set: Value::Array(vec![Value::String("a".to_string())]),
+ map: map! {
+ bar: Value::Integer(4),
+ foo: Value::Integer(10)
+ }
+ },
+ }
+}
+
+#[test]
+fn table_array() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a: Vec<Bar>,
+ }
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Bar {
+ a: isize,
+ }
+
+ equivalent! {
+ Foo { a: vec![Bar { a: 1 }, Bar { a: 2 }] },
+ map! {
+ a: Value::Array(vec![
+ Value::Table(map!{ a: Value::Integer(1) }),
+ Value::Table(map!{ a: Value::Integer(2) }),
+ ])
+ },
+ }
+}
+
+#[test]
+fn type_errors() {
+ #[derive(Deserialize)]
+ #[allow(dead_code)]
+ struct Foo {
+ bar: isize,
+ }
+
+ error! {
+ Foo,
+ map! {
+ bar: Value::String("a".to_string())
+ },
+ r#"TOML parse error at line 1, column 7
+ |
+1 | bar = "a"
+ | ^^^
+invalid type: string "a", expected isize
+"#,
+ "invalid type: string \"a\", expected isize\nin `bar`\n"
+ }
+
+ #[derive(Deserialize)]
+ #[allow(dead_code)]
+ struct Bar {
+ foo: Foo,
+ }
+
+ error! {
+ Bar,
+ map! {
+ foo: map! {
+ bar: Value::String("a".to_string())
+ }
+ },
+ r#"TOML parse error at line 2, column 7
+ |
+2 | bar = "a"
+ | ^^^
+invalid type: string "a", expected isize
+"#,
+ "invalid type: string \"a\", expected isize\nin `foo.bar`\n"
+ }
+}
+
+#[test]
+fn missing_errors() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Foo {
+ bar: isize,
+ }
+
+ error! {
+ Foo,
+ map! { },
+ r#"TOML parse error at line 1, column 1
+ |
+1 |
+ | ^
+missing field `bar`
+"#,
+ "missing field `bar`\n"
+ }
+}
+
+#[test]
+fn parse_enum() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a: E,
+ }
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ #[serde(untagged)]
+ enum E {
+ Bar(isize),
+ Baz(String),
+ Last(Foo2),
+ }
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo2 {
+ test: String,
+ }
+
+ equivalent! {
+ Foo { a: E::Bar(10) },
+ map! { a: Value::Integer(10) },
+ }
+
+ equivalent! {
+ Foo { a: E::Baz("foo".to_string()) },
+ map! { a: Value::String("foo".to_string()) },
+ }
+
+ equivalent! {
+ Foo { a: E::Last(Foo2 { test: "test".to_string() }) },
+ map! { a: map! { test: Value::String("test".to_string()) } },
+ }
+}
+
+#[test]
+fn parse_enum_string() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a: Sort,
+ }
+
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ #[serde(rename_all = "lowercase")]
+ enum Sort {
+ Asc,
+ Desc,
+ }
+
+ equivalent! {
+ Foo { a: Sort::Desc },
+ map! { a: Value::String("desc".to_string()) },
+ }
+}
+
+#[test]
+#[cfg(feature = "preserve_order")]
+fn map_key_unit_variants() {
+ #[derive(Serialize, Deserialize, PartialEq, Eq, Debug, Clone, PartialOrd, Ord)]
+ enum Sort {
+ #[serde(rename = "ascending")]
+ Asc,
+ Desc,
+ }
+
+ let mut map = BTreeMap::new();
+ map.insert(Sort::Asc, 1);
+ map.insert(Sort::Desc, 2);
+
+ equivalent! {
+ map,
+ map! { ascending: Value::Integer(1), Desc: Value::Integer(2) },
+ }
+}
+
+// #[test]
+// fn unused_fields() {
+// #[derive(Serialize, Deserialize, PartialEq, Debug)]
+// struct Foo { a: isize }
+//
+// let v = Foo { a: 2 };
+// let mut d = Decoder::new(Table(map! {
+// a, Integer(2),
+// b, Integer(5)
+// }));
+// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
+//
+// assert_eq!(d.toml, Some(Table(map! {
+// b, Integer(5)
+// })));
+// }
+//
+// #[test]
+// fn unused_fields2() {
+// #[derive(Serialize, Deserialize, PartialEq, Debug)]
+// struct Foo { a: Bar }
+// #[derive(Serialize, Deserialize, PartialEq, Debug)]
+// struct Bar { a: isize }
+//
+// let v = Foo { a: Bar { a: 2 } };
+// let mut d = Decoder::new(Table(map! {
+// a, Table(map! {
+// a, Integer(2),
+// b, Integer(5)
+// })
+// }));
+// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
+//
+// assert_eq!(d.toml, Some(Table(map! {
+// a, Table(map! {
+// b, Integer(5)
+// })
+// })));
+// }
+//
+// #[test]
+// fn unused_fields3() {
+// #[derive(Serialize, Deserialize, PartialEq, Debug)]
+// struct Foo { a: Bar }
+// #[derive(Serialize, Deserialize, PartialEq, Debug)]
+// struct Bar { a: isize }
+//
+// let v = Foo { a: Bar { a: 2 } };
+// let mut d = Decoder::new(Table(map! {
+// a, Table(map! {
+// a, Integer(2)
+// })
+// }));
+// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
+//
+// assert_eq!(d.toml, None);
+// }
+//
+// #[test]
+// fn unused_fields4() {
+// #[derive(Serialize, Deserialize, PartialEq, Debug)]
+// struct Foo { a: BTreeMap<String, String> }
+//
+// let v = Foo { a: map! { a, "foo".to_string() } };
+// let mut d = Decoder::new(Table(map! {
+// a, Table(map! {
+// a, Value::String("foo".to_string())
+// })
+// }));
+// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
+//
+// assert_eq!(d.toml, None);
+// }
+//
+// #[test]
+// fn unused_fields5() {
+// #[derive(Serialize, Deserialize, PartialEq, Debug)]
+// struct Foo { a: Vec<String> }
+//
+// let v = Foo { a: vec!["a".to_string()] };
+// let mut d = Decoder::new(Table(map! {
+// a, Array(vec![Value::String("a".to_string())])
+// }));
+// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
+//
+// assert_eq!(d.toml, None);
+// }
+//
+// #[test]
+// fn unused_fields6() {
+// #[derive(Serialize, Deserialize, PartialEq, Debug)]
+// struct Foo { a: Option<Vec<String>> }
+//
+// let v = Foo { a: Some(vec![]) };
+// let mut d = Decoder::new(Table(map! {
+// a, Array(vec![])
+// }));
+// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
+//
+// assert_eq!(d.toml, None);
+// }
+//
+// #[test]
+// fn unused_fields7() {
+// #[derive(Serialize, Deserialize, PartialEq, Debug)]
+// struct Foo { a: Vec<Bar> }
+// #[derive(Serialize, Deserialize, PartialEq, Debug)]
+// struct Bar { a: isize }
+//
+// let v = Foo { a: vec![Bar { a: 1 }] };
+// let mut d = Decoder::new(Table(map! {
+// a, Array(vec![Table(map! {
+// a, Integer(1),
+// b, Integer(2)
+// })])
+// }));
+// assert_eq!(v, t!(Deserialize::deserialize(&mut d)));
+//
+// assert_eq!(d.toml, Some(Table(map! {
+// a, Array(vec![Table(map! {
+// b, Integer(2)
+// })])
+// })));
+// }
+
+#[test]
+fn empty_arrays() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a: Vec<Bar>,
+ }
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Bar;
+
+ equivalent! {
+ Foo { a: vec![] },
+ map! {a: Value::Array(Vec::new())},
+ }
+}
+
+#[test]
+fn empty_arrays2() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a: Option<Vec<Bar>>,
+ }
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Bar;
+
+ equivalent! {
+ Foo { a: None },
+ map! {},
+ }
+
+ equivalent! {
+ Foo { a: Some(vec![]) },
+ map! { a: Value::Array(vec![]) },
+ }
+}
+
+#[test]
+fn extra_keys() {
+ #[derive(Serialize, Deserialize)]
+ struct Foo {
+ a: isize,
+ }
+
+ let toml = map! { a: Value::Integer(2), b: Value::Integer(2) };
+ assert!(toml.clone().try_into::<Foo>().is_ok());
+ assert!(toml::from_str::<Foo>(&toml.to_string()).is_ok());
+}
+
+#[test]
+fn newtypes() {
+ #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
+ struct A {
+ b: B,
+ }
+
+ #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
+ struct B(u32);
+
+ equivalent! {
+ A { b: B(2) },
+ map! { b: Value::Integer(2) },
+ }
+}
+
+#[test]
+fn newtypes2() {
+ #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
+ struct A {
+ b: B,
+ }
+
+ #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
+ struct B(Option<C>);
+
+ #[derive(Deserialize, Serialize, PartialEq, Debug, Clone)]
+ struct C {
+ x: u32,
+ y: u32,
+ z: u32,
+ }
+
+ equivalent! {
+ A { b: B(Some(C { x: 0, y: 1, z: 2 })) },
+ map! {
+ b: map! {
+ x: Value::Integer(0),
+ y: Value::Integer(1),
+ z: Value::Integer(2)
+ }
+ },
+ }
+}
+
+#[derive(Debug, Default, PartialEq, Serialize, Deserialize)]
+struct CanBeEmpty {
+ a: Option<String>,
+ b: Option<String>,
+}
+
+#[test]
+fn table_structs_empty() {
+ let text = "[bar]\n\n[baz]\n\n[bazv]\na = \"foo\"\n\n[foo]\n";
+ let value: BTreeMap<String, CanBeEmpty> = toml::from_str(text).unwrap();
+ let mut expected: BTreeMap<String, CanBeEmpty> = BTreeMap::new();
+ expected.insert("bar".to_string(), CanBeEmpty::default());
+ expected.insert("baz".to_string(), CanBeEmpty::default());
+ expected.insert(
+ "bazv".to_string(),
+ CanBeEmpty {
+ a: Some("foo".to_string()),
+ b: None,
+ },
+ );
+ expected.insert("foo".to_string(), CanBeEmpty::default());
+ assert_eq!(value, expected);
+ snapbox::assert_eq(text, toml::to_string(&value).unwrap());
+}
+
+#[test]
+fn fixed_size_array() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Entity {
+ pos: [i32; 2],
+ }
+
+ equivalent! {
+ Entity { pos: [1, 2] },
+ map! {
+ pos: Value::Array(vec![
+ Value::Integer(1),
+ Value::Integer(2),
+ ])
+ },
+ }
+}
+
+#[test]
+fn homogeneous_tuple() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Collection {
+ elems: (i64, i64, i64),
+ }
+
+ equivalent! {
+ Collection { elems: (0, 1, 2) },
+ map! {
+ elems: Value::Array(vec![
+ Value::Integer(0),
+ Value::Integer(1),
+ Value::Integer(2),
+ ])
+ },
+ }
+}
+
+#[test]
+fn homogeneous_tuple_struct() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Object(Vec<String>, Vec<String>, Vec<String>);
+
+ equivalent! {
+ map! {
+ obj: Object(vec!["foo".to_string()], vec![], vec!["bar".to_string(), "baz".to_string()])
+ },
+ map! {
+ obj: Value::Array(vec![
+ Value::Array(vec![
+ Value::String("foo".to_string()),
+ ]),
+ Value::Array(vec![]),
+ Value::Array(vec![
+ Value::String("bar".to_string()),
+ Value::String("baz".to_string()),
+ ]),
+ ])
+ },
+ }
+}
+
+#[test]
+fn json_interoperability() {
+ #[derive(Serialize, Deserialize)]
+ struct Foo {
+ any: toml::Value,
+ }
+
+ let _foo: Foo = serde_json::from_str(
+ r#"
+ {"any":1}
+ "#,
+ )
+ .unwrap();
+}
+
+#[test]
+fn error_includes_key() {
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Package {
+ name: String,
+ version: String,
+ authors: Vec<String>,
+ profile: Profile,
+ }
+
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Profile {
+ dev: Dev,
+ }
+
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Dev {
+ debug: U32OrBool,
+ }
+
+ #[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
+ #[serde(untagged, expecting = "expected a boolean or an integer")]
+ pub enum U32OrBool {
+ U32(u32),
+ Bool(bool),
+ }
+
+ let res: Result<Package, _> = toml::from_str(
+ r#"
+[package]
+name = "foo"
+version = "0.0.0"
+authors = []
+
+[profile.dev]
+debug = 'a'
+"#,
+ );
+ let err = res.unwrap_err();
+ snapbox::assert_eq(
+ r#"TOML parse error at line 8, column 9
+ |
+8 | debug = 'a'
+ | ^^^
+expected a boolean or an integer
+"#,
+ err.to_string(),
+ );
+
+ let res: Result<Package, _> = toml::from_str(
+ r#"
+[package]
+name = "foo"
+version = "0.0.0"
+authors = []
+
+[profile]
+dev = { debug = 'a' }
+"#,
+ );
+ let err = res.unwrap_err();
+ snapbox::assert_eq(
+ r#"TOML parse error at line 8, column 17
+ |
+8 | dev = { debug = 'a' }
+ | ^^^
+expected a boolean or an integer
+"#,
+ err.to_string(),
+ );
+}
+
+#[test]
+fn newline_key_value() {
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Package {
+ name: String,
+ }
+
+ let package = Package {
+ name: "foo".to_owned(),
+ };
+ let raw = toml::to_string_pretty(&package).unwrap();
+ snapbox::assert_eq(
+ r#"name = "foo"
+"#,
+ raw,
+ );
+}
+
+#[test]
+fn newline_table() {
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Manifest {
+ package: Package,
+ }
+
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Package {
+ name: String,
+ }
+
+ let package = Manifest {
+ package: Package {
+ name: "foo".to_owned(),
+ },
+ };
+ let raw = toml::to_string_pretty(&package).unwrap();
+ snapbox::assert_eq(
+ r#"[package]
+name = "foo"
+"#,
+ raw,
+ );
+}
+
+#[test]
+fn newline_dotted_table() {
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Manifest {
+ profile: Profile,
+ }
+
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Profile {
+ dev: Dev,
+ }
+
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Dev {
+ debug: U32OrBool,
+ }
+
+ #[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
+ #[serde(untagged, expecting = "expected a boolean or an integer")]
+ pub enum U32OrBool {
+ U32(u32),
+ Bool(bool),
+ }
+
+ let package = Manifest {
+ profile: Profile {
+ dev: Dev {
+ debug: U32OrBool::Bool(true),
+ },
+ },
+ };
+ let raw = toml::to_string_pretty(&package).unwrap();
+ snapbox::assert_eq(
+ r#"[profile.dev]
+debug = true
+"#,
+ raw,
+ );
+}
+
+#[test]
+fn newline_mixed_tables() {
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Manifest {
+ cargo_features: Vec<String>,
+ package: Package,
+ profile: Profile,
+ }
+
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Package {
+ name: String,
+ version: String,
+ authors: Vec<String>,
+ }
+
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Profile {
+ dev: Dev,
+ }
+
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Dev {
+ debug: U32OrBool,
+ }
+
+ #[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
+ #[serde(untagged, expecting = "expected a boolean or an integer")]
+ pub enum U32OrBool {
+ U32(u32),
+ Bool(bool),
+ }
+
+ let package = Manifest {
+ cargo_features: vec![],
+ package: Package {
+ name: "foo".to_owned(),
+ version: "1.0.0".to_owned(),
+ authors: vec![],
+ },
+ profile: Profile {
+ dev: Dev {
+ debug: U32OrBool::Bool(true),
+ },
+ },
+ };
+ let raw = toml::to_string_pretty(&package).unwrap();
+ snapbox::assert_eq(
+ r#"cargo_features = []
+
+[package]
+name = "foo"
+version = "1.0.0"
+authors = []
+
+[profile.dev]
+debug = true
+"#,
+ raw,
+ );
+}
+
+#[test]
+fn integer_min() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a_b: i64,
+ }
+
+ equivalent! {
+ Foo { a_b: i64::MIN },
+ map! { a_b: Value::Integer(i64::MIN) },
+ }
+}
+
+#[test]
+fn integer_too_big() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a_b: u64,
+ }
+
+ let native = Foo { a_b: u64::MAX };
+ let err = Table::try_from(native.clone()).unwrap_err();
+ snapbox::assert_eq("u64 value was too large", err.to_string());
+ let err = toml::to_string(&native).unwrap_err();
+ snapbox::assert_eq("out-of-range value for u64 type", err.to_string());
+}
+
+#[test]
+fn integer_max() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a_b: i64,
+ }
+
+ equivalent! {
+ Foo { a_b: i64::MAX },
+ map! { a_b: Value::Integer(i64::MAX) },
+ }
+}
+
+#[test]
+fn float_min() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a_b: f64,
+ }
+
+ equivalent! {
+ Foo { a_b: f64::MIN },
+ map! { a_b: Value::Float(f64::MIN) },
+ }
+}
+
+#[test]
+fn float_max() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug, Clone)]
+ struct Foo {
+ a_b: f64,
+ }
+
+ equivalent! {
+ Foo { a_b: f64::MAX },
+ map! { a_b: Value::Float(f64::MAX) },
+ }
+}
+
+#[test]
+fn unsupported_root_type() {
+ let native = "value";
+ let err = toml::to_string_pretty(&native).unwrap_err();
+ snapbox::assert_eq("unsupported rust type", err.to_string());
+}
+
+#[test]
+fn unsupported_nested_type() {
+ #[derive(Debug, Serialize, Deserialize)]
+ struct Foo {
+ unused: (),
+ }
+
+ let native = Foo { unused: () };
+ let err = toml::to_string_pretty(&native).unwrap_err();
+ snapbox::assert_eq("unsupported unit type", err.to_string());
+}
+
+#[test]
+fn table_type_enum_regression_issue_388() {
+ #[derive(Deserialize)]
+ struct DataFile {
+ #[allow(dead_code)]
+ data: Compare,
+ }
+
+ #[derive(Deserialize)]
+ enum Compare {
+ Gt(u32),
+ }
+
+ let dotted_table = r#"
+ data.Gt = 5
+ "#;
+ assert!(toml::from_str::<DataFile>(dotted_table).is_ok());
+
+ let inline_table = r#"
+ data = { Gt = 5 }
+ "#;
+ assert!(toml::from_str::<DataFile>(inline_table).is_ok());
+}
+
+#[test]
+fn serialize_datetime_issue_333() {
+ use toml::{to_string, value::Date, value::Datetime};
+
+ #[derive(Serialize)]
+ struct Struct {
+ date: Datetime,
+ }
+
+ let toml = to_string(&Struct {
+ date: Datetime {
+ date: Some(Date {
+ year: 2022,
+ month: 1,
+ day: 1,
+ }),
+ time: None,
+ offset: None,
+ },
+ })
+ .unwrap();
+ assert_eq!(toml, "date = 2022-01-01\n");
+}
+
+#[test]
+fn datetime_offset_issue_496() {
+ let original = "value = 1911-01-01T10:11:12-00:36\n";
+ let toml = original.parse::<toml::Table>().unwrap();
+ let output = toml.to_string();
+ snapbox::assert_eq(original, output);
+}
diff --git a/vendor/toml/tests/testsuite/spanned.rs b/vendor/toml/tests/testsuite/spanned.rs
new file mode 100644
index 000000000..760c73aab
--- /dev/null
+++ b/vendor/toml/tests/testsuite/spanned.rs
@@ -0,0 +1,261 @@
+#![allow(renamed_and_removed_lints)]
+#![allow(clippy::blacklisted_name)]
+
+use std::collections::HashMap;
+use std::fmt::Debug;
+
+use serde::Deserialize;
+use toml::value::Datetime;
+use toml::Spanned;
+
+/// A set of good datetimes.
+pub fn good_datetimes() -> Vec<&'static str> {
+ vec![
+ "1997-09-09T09:09:09Z",
+ "1997-09-09T09:09:09+09:09",
+ "1997-09-09T09:09:09-09:09",
+ "1997-09-09T09:09:09",
+ "1997-09-09",
+ "09:09:09",
+ "1997-09-09T09:09:09.09Z",
+ "1997-09-09T09:09:09.09+09:09",
+ "1997-09-09T09:09:09.09-09:09",
+ "1997-09-09T09:09:09.09",
+ "09:09:09.09",
+ ]
+}
+
+#[test]
+fn test_spanned_field() {
+ #[derive(Deserialize)]
+ struct Foo<T> {
+ foo: Spanned<T>,
+ }
+
+ #[derive(Deserialize)]
+ struct BareFoo<T> {
+ foo: T,
+ }
+
+ fn good<T>(s: &str, expected: &str, end: Option<usize>)
+ where
+ T: serde::de::DeserializeOwned + Debug + PartialEq,
+ {
+ let foo: Foo<T> = toml::from_str(s).unwrap();
+
+ assert_eq!(6, foo.foo.span().start);
+ if let Some(end) = end {
+ assert_eq!(end, foo.foo.span().end);
+ } else {
+ assert_eq!(s.len(), foo.foo.span().end);
+ }
+ assert_eq!(expected, &s[foo.foo.span()]);
+
+ // Test for Spanned<> at the top level
+ let foo_outer: Spanned<BareFoo<T>> = toml::from_str(s).unwrap();
+
+ assert_eq!(0, foo_outer.span().start);
+ assert_eq!(s.len(), foo_outer.span().end);
+ assert_eq!(foo.foo.into_inner(), foo_outer.into_inner().foo);
+ }
+
+ good::<String>("foo = \"foo\"", "\"foo\"", None);
+ good::<u32>("foo = 42", "42", None);
+ // leading plus
+ good::<u32>("foo = +42", "+42", None);
+ // table
+ good::<HashMap<String, u32>>(
+ "foo = {\"foo\" = 42, \"bar\" = 42}",
+ "{\"foo\" = 42, \"bar\" = 42}",
+ None,
+ );
+ // array
+ good::<Vec<u32>>("foo = [0, 1, 2, 3, 4]", "[0, 1, 2, 3, 4]", None);
+ // datetime
+ good::<String>(
+ "foo = \"1997-09-09T09:09:09Z\"",
+ "\"1997-09-09T09:09:09Z\"",
+ None,
+ );
+
+ for expected in good_datetimes() {
+ let s = format!("foo = {}", expected);
+ good::<Datetime>(&s, expected, None);
+ }
+ // ending at something other than the absolute end
+ good::<u32>("foo = 42\nnoise = true", "42", Some(8));
+}
+
+#[test]
+fn test_inner_spanned_table() {
+ #[derive(Deserialize)]
+ struct Foo {
+ foo: Spanned<HashMap<Spanned<String>, Spanned<String>>>,
+ }
+
+ fn good(s: &str, zero: bool) {
+ let foo: Foo = toml::from_str(s).unwrap();
+
+ if zero {
+ assert_eq!(foo.foo.span().start, 0);
+ assert_eq!(foo.foo.span().end, 73);
+ } else {
+ assert_eq!(foo.foo.span().start, s.find('{').unwrap());
+ assert_eq!(foo.foo.span().end, s.find('}').unwrap() + 1);
+ }
+ for (k, v) in foo.foo.as_ref().iter() {
+ assert_eq!(&s[k.span().start..k.span().end], k.as_ref());
+ assert_eq!(&s[(v.span().start + 1)..(v.span().end - 1)], v.as_ref());
+ }
+ }
+
+ good(
+ "\
+ [foo]
+ a = 'b'
+ bar = 'baz'
+ c = 'd'
+ e = \"f\"
+ ",
+ true,
+ );
+
+ good(
+ "
+ foo = { a = 'b', bar = 'baz', c = 'd', e = \"f\" }",
+ false,
+ );
+}
+
+#[test]
+fn test_outer_spanned_table() {
+ #[derive(Deserialize)]
+ struct Foo {
+ foo: HashMap<Spanned<String>, Spanned<String>>,
+ }
+
+ fn good(s: &str) {
+ let foo: Foo = toml::from_str(s).unwrap();
+
+ for (k, v) in foo.foo.iter() {
+ assert_eq!(&s[k.span().start..k.span().end], k.as_ref());
+ assert_eq!(&s[(v.span().start + 1)..(v.span().end - 1)], v.as_ref());
+ }
+ }
+
+ good(
+ "
+ [foo]
+ a = 'b'
+ bar = 'baz'
+ c = 'd'
+ e = \"f\"
+ ",
+ );
+
+ good(
+ "
+ foo = { a = 'b', bar = 'baz', c = 'd', e = \"f\" }
+ ",
+ );
+}
+
+#[test]
+fn test_spanned_nested() {
+ #[derive(Deserialize)]
+ struct Foo {
+ foo: HashMap<Spanned<String>, HashMap<Spanned<String>, Spanned<String>>>,
+ }
+
+ fn good(s: &str) {
+ let foo: Foo = toml::from_str(s).unwrap();
+
+ for (k, v) in foo.foo.iter() {
+ assert_eq!(&s[k.span().start..k.span().end], k.as_ref());
+ for (n_k, n_v) in v.iter() {
+ assert_eq!(&s[n_k.span().start..n_k.span().end], n_k.as_ref());
+ assert_eq!(
+ &s[(n_v.span().start + 1)..(n_v.span().end - 1)],
+ n_v.as_ref()
+ );
+ }
+ }
+ }
+
+ good(
+ "
+ [foo.a]
+ a = 'b'
+ c = 'd'
+ e = \"f\"
+ [foo.bar]
+ baz = 'true'
+ ",
+ );
+
+ good(
+ "
+ [foo]
+ foo = { a = 'b', bar = 'baz', c = 'd', e = \"f\" }
+ bazz = {}
+ g = { h = 'i' }
+ ",
+ );
+}
+
+#[test]
+fn test_spanned_array() {
+ #[derive(Deserialize)]
+ struct Foo {
+ foo: Vec<Spanned<HashMap<Spanned<String>, Spanned<String>>>>,
+ }
+
+ let toml = "\
+ [[foo]]
+ a = 'b'
+ bar = 'baz'
+ c = 'd'
+ e = \"f\"
+ [[foo]]
+ a = 'c'
+ bar = 'baz'
+ c = 'g'
+ e = \"h\"
+ ";
+ let foo_list: Foo = toml::from_str(toml).unwrap();
+
+ for (foo, expected) in foo_list.foo.iter().zip([0..75, 84..159]) {
+ assert_eq!(foo.span(), expected);
+ for (k, v) in foo.as_ref().iter() {
+ assert_eq!(&toml[k.span().start..k.span().end], k.as_ref());
+ assert_eq!(&toml[(v.span().start + 1)..(v.span().end - 1)], v.as_ref());
+ }
+ }
+}
+
+#[test]
+fn deny_unknown_fields() {
+ #[derive(Debug, serde::Deserialize)]
+ #[serde(deny_unknown_fields)]
+ struct Example {
+ #[allow(dead_code)]
+ real: u32,
+ }
+
+ let error = toml::from_str::<Example>(
+ r#"# my comment
+# bla bla bla
+fake = 1"#,
+ )
+ .unwrap_err();
+ snapbox::assert_eq(
+ "\
+TOML parse error at line 3, column 1
+ |
+3 | fake = 1
+ | ^^^^
+unknown field `fake`, expected `real`
+",
+ error.to_string(),
+ );
+}
diff --git a/vendor/toml/tests/testsuite/spanned_impls.rs b/vendor/toml/tests/testsuite/spanned_impls.rs
new file mode 100644
index 000000000..5e866f92a
--- /dev/null
+++ b/vendor/toml/tests/testsuite/spanned_impls.rs
@@ -0,0 +1,41 @@
+use std::cmp::{Ord, Ordering, PartialOrd};
+
+use serde::Deserialize;
+use toml::{from_str, Spanned};
+
+#[test]
+fn test_spans_impls() {
+ #[derive(Deserialize)]
+ struct Foo {
+ bar: Spanned<bool>,
+ baz: Spanned<String>,
+ }
+ let f: Foo = from_str(
+ "
+ bar = true
+ baz = \"yes\"
+ ",
+ )
+ .unwrap();
+ let g: Foo = from_str(
+ "
+ baz = \"yes\"
+ bar = true
+ ",
+ )
+ .unwrap();
+ assert!(f.bar.span() != g.bar.span());
+ assert!(f.baz.span() != g.baz.span());
+
+ // test that eq still holds
+ assert_eq!(f.bar, g.bar);
+ assert_eq!(f.baz, g.baz);
+
+ // test that Ord returns equal order
+ assert_eq!(f.bar.cmp(&g.bar), Ordering::Equal);
+ assert_eq!(f.baz.cmp(&g.baz), Ordering::Equal);
+
+ // test that PartialOrd returns equal order
+ assert_eq!(f.bar.partial_cmp(&g.bar), Some(Ordering::Equal));
+ assert_eq!(f.baz.partial_cmp(&g.baz), Some(Ordering::Equal));
+}
diff --git a/vendor/toml/tests/testsuite/tables_last.rs b/vendor/toml/tests/testsuite/tables_last.rs
new file mode 100644
index 000000000..b0035579d
--- /dev/null
+++ b/vendor/toml/tests/testsuite/tables_last.rs
@@ -0,0 +1,162 @@
+use std::collections::HashMap;
+
+use serde::Deserialize;
+use serde::Serialize;
+
+#[test]
+fn always_works() {
+ // Ensure this works without the removed "toml::ser::tables_last"
+ #[derive(Serialize)]
+ struct A {
+ vals: HashMap<&'static str, Value>,
+ }
+
+ #[derive(Serialize)]
+ #[serde(untagged)]
+ enum Value {
+ Map(HashMap<&'static str, &'static str>),
+ Int(i32),
+ }
+
+ let mut a = A {
+ vals: HashMap::new(),
+ };
+ a.vals.insert("foo", Value::Int(0));
+
+ let mut sub = HashMap::new();
+ sub.insert("foo", "bar");
+ a.vals.insert("bar", Value::Map(sub));
+
+ toml::to_string(&a).unwrap();
+}
+
+#[test]
+fn vec_of_vec_issue_387() {
+ #[derive(Deserialize, Serialize, Debug)]
+ struct Glyph {
+ components: Vec<Component>,
+ contours: Vec<Contour>,
+ }
+
+ #[derive(Deserialize, Serialize, Debug)]
+ struct Point {
+ x: f64,
+ y: f64,
+ pt_type: String,
+ }
+
+ type Contour = Vec<Point>;
+
+ #[derive(Deserialize, Serialize, Debug)]
+ struct Component {
+ base: String,
+ transform: (f64, f64, f64, f64, f64, f64),
+ }
+
+ let comp1 = Component {
+ base: "b".to_string(),
+ transform: (1.0, 0.0, 0.0, 1.0, 0.0, 0.0),
+ };
+ let comp2 = Component {
+ base: "c".to_string(),
+ transform: (1.0, 0.0, 0.0, 1.0, 0.0, 0.0),
+ };
+ let components = vec![comp1, comp2];
+
+ let contours = vec![
+ vec![
+ Point {
+ x: 3.0,
+ y: 4.0,
+ pt_type: "line".to_string(),
+ },
+ Point {
+ x: 5.0,
+ y: 6.0,
+ pt_type: "line".to_string(),
+ },
+ ],
+ vec![
+ Point {
+ x: 0.0,
+ y: 0.0,
+ pt_type: "move".to_string(),
+ },
+ Point {
+ x: 7.0,
+ y: 9.0,
+ pt_type: "offcurve".to_string(),
+ },
+ Point {
+ x: 8.0,
+ y: 10.0,
+ pt_type: "offcurve".to_string(),
+ },
+ Point {
+ x: 11.0,
+ y: 12.0,
+ pt_type: "curve".to_string(),
+ },
+ ],
+ ];
+ let g1 = Glyph {
+ contours,
+ components,
+ };
+
+ let s = toml::to_string_pretty(&g1).unwrap();
+ let _g2: Glyph = toml::from_str(&s).unwrap();
+}
+
+#[test]
+fn vec_order_issue_356() {
+ #[derive(Serialize, Deserialize)]
+ struct Outer {
+ v1: Vec<Inner>,
+ v2: Vec<Inner>,
+ }
+
+ #[derive(Serialize, Deserialize)]
+ struct Inner {}
+
+ let outer = Outer {
+ v1: vec![Inner {}],
+ v2: vec![],
+ };
+ let s = toml::to_string_pretty(&outer).unwrap();
+ let _o: Outer = toml::from_str(&s).unwrap();
+}
+
+#[test]
+fn values_before_tables_issue_403() {
+ #[derive(Serialize, Deserialize)]
+ struct A {
+ a: String,
+ b: String,
+ }
+
+ #[derive(Serialize, Deserialize)]
+ struct B {
+ a: String,
+ b: Vec<String>,
+ }
+
+ #[derive(Serialize, Deserialize)]
+ struct C {
+ a: A,
+ b: Vec<String>,
+ c: Vec<B>,
+ }
+ toml::to_string(&C {
+ a: A {
+ a: "aa".to_string(),
+ b: "ab".to_string(),
+ },
+ b: vec!["b".to_string()],
+ c: vec![B {
+ a: "cba".to_string(),
+ b: vec!["cbb".to_string()],
+ }],
+ })
+ .unwrap();
+}