aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml1
-rw-r--r--src/lib.rs3
-rw-r--r--src/macros.rs373
-rw-r--r--test-suite/Cargo.toml15
-rw-r--r--test-suite/build.rs8
-rw-r--r--test-suite/tests/README.md (renamed from tests/README.md)0
-rw-r--r--test-suite/tests/backcompat.rs (renamed from tests/backcompat.rs)0
-rw-r--r--test-suite/tests/datetime.rs (renamed from tests/datetime.rs)0
-rw-r--r--test-suite/tests/display-tricky.rs (renamed from tests/display-tricky.rs)0
-rw-r--r--test-suite/tests/display.rs (renamed from tests/display.rs)0
-rw-r--r--test-suite/tests/formatting.rs (renamed from tests/formatting.rs)0
-rw-r--r--test-suite/tests/invalid-encoder-misc.rs (renamed from tests/invalid-encoder-misc.rs)0
-rw-r--r--test-suite/tests/invalid-encoder/array-mixed-types-ints-and-floats.json (renamed from tests/invalid-encoder/array-mixed-types-ints-and-floats.json)0
-rw-r--r--test-suite/tests/invalid-misc.rs (renamed from tests/invalid-misc.rs)0
-rw-r--r--test-suite/tests/invalid.rs (renamed from tests/invalid.rs)0
-rw-r--r--test-suite/tests/invalid/array-mixed-types-arrays-and-ints.toml (renamed from tests/invalid/array-mixed-types-arrays-and-ints.toml)0
-rw-r--r--test-suite/tests/invalid/array-mixed-types-ints-and-floats.toml (renamed from tests/invalid/array-mixed-types-ints-and-floats.toml)0
-rw-r--r--test-suite/tests/invalid/array-mixed-types-strings-and-ints.toml (renamed from tests/invalid/array-mixed-types-strings-and-ints.toml)0
-rw-r--r--test-suite/tests/invalid/datetime-malformed-no-leads.toml (renamed from tests/invalid/datetime-malformed-no-leads.toml)0
-rw-r--r--test-suite/tests/invalid/datetime-malformed-no-secs.toml (renamed from tests/invalid/datetime-malformed-no-secs.toml)0
-rw-r--r--test-suite/tests/invalid/datetime-malformed-no-t.toml (renamed from tests/invalid/datetime-malformed-no-t.toml)0
-rw-r--r--test-suite/tests/invalid/datetime-malformed-with-milli.toml (renamed from tests/invalid/datetime-malformed-with-milli.toml)0
-rw-r--r--test-suite/tests/invalid/duplicate-key-table.toml (renamed from tests/invalid/duplicate-key-table.toml)0
-rw-r--r--test-suite/tests/invalid/duplicate-keys.toml (renamed from tests/invalid/duplicate-keys.toml)0
-rw-r--r--test-suite/tests/invalid/duplicate-tables.toml (renamed from tests/invalid/duplicate-tables.toml)0
-rw-r--r--test-suite/tests/invalid/empty-implicit-table.toml (renamed from tests/invalid/empty-implicit-table.toml)0
-rw-r--r--test-suite/tests/invalid/empty-table.toml (renamed from tests/invalid/empty-table.toml)0
-rw-r--r--test-suite/tests/invalid/float-no-leading-zero.toml (renamed from tests/invalid/float-no-leading-zero.toml)0
-rw-r--r--test-suite/tests/invalid/float-no-trailing-digits.toml (renamed from tests/invalid/float-no-trailing-digits.toml)0
-rw-r--r--test-suite/tests/invalid/key-after-array.toml (renamed from tests/invalid/key-after-array.toml)0
-rw-r--r--test-suite/tests/invalid/key-after-table.toml (renamed from tests/invalid/key-after-table.toml)0
-rw-r--r--test-suite/tests/invalid/key-empty.toml (renamed from tests/invalid/key-empty.toml)0
-rw-r--r--test-suite/tests/invalid/key-hash.toml (renamed from tests/invalid/key-hash.toml)0
-rw-r--r--test-suite/tests/invalid/key-newline.toml (renamed from tests/invalid/key-newline.toml)0
-rw-r--r--test-suite/tests/invalid/key-open-bracket.toml (renamed from tests/invalid/key-open-bracket.toml)0
-rw-r--r--test-suite/tests/invalid/key-single-open-bracket.toml (renamed from tests/invalid/key-single-open-bracket.toml)0
-rw-r--r--test-suite/tests/invalid/key-space.toml (renamed from tests/invalid/key-space.toml)0
-rw-r--r--test-suite/tests/invalid/key-start-bracket.toml (renamed from tests/invalid/key-start-bracket.toml)0
-rw-r--r--test-suite/tests/invalid/key-two-equals.toml (renamed from tests/invalid/key-two-equals.toml)0
-rw-r--r--test-suite/tests/invalid/string-bad-byte-escape.toml (renamed from tests/invalid/string-bad-byte-escape.toml)0
-rw-r--r--test-suite/tests/invalid/string-bad-escape.toml (renamed from tests/invalid/string-bad-escape.toml)0
-rw-r--r--test-suite/tests/invalid/string-byte-escapes.toml (renamed from tests/invalid/string-byte-escapes.toml)0
-rw-r--r--test-suite/tests/invalid/string-no-close.toml (renamed from tests/invalid/string-no-close.toml)0
-rw-r--r--test-suite/tests/invalid/table-array-implicit.toml (renamed from tests/invalid/table-array-implicit.toml)0
-rw-r--r--test-suite/tests/invalid/table-array-malformed-bracket.toml (renamed from tests/invalid/table-array-malformed-bracket.toml)0
-rw-r--r--test-suite/tests/invalid/table-array-malformed-empty.toml (renamed from tests/invalid/table-array-malformed-empty.toml)0
-rw-r--r--test-suite/tests/invalid/table-empty.toml (renamed from tests/invalid/table-empty.toml)0
-rw-r--r--test-suite/tests/invalid/table-nested-brackets-close.toml (renamed from tests/invalid/table-nested-brackets-close.toml)0
-rw-r--r--test-suite/tests/invalid/table-nested-brackets-open.toml (renamed from tests/invalid/table-nested-brackets-open.toml)0
-rw-r--r--test-suite/tests/invalid/table-whitespace.toml (renamed from tests/invalid/table-whitespace.toml)0
-rw-r--r--test-suite/tests/invalid/table-with-pound.toml (renamed from tests/invalid/table-with-pound.toml)0
-rw-r--r--test-suite/tests/invalid/text-after-array-entries.toml (renamed from tests/invalid/text-after-array-entries.toml)0
-rw-r--r--test-suite/tests/invalid/text-after-integer.toml (renamed from tests/invalid/text-after-integer.toml)0
-rw-r--r--test-suite/tests/invalid/text-after-string.toml (renamed from tests/invalid/text-after-string.toml)0
-rw-r--r--test-suite/tests/invalid/text-after-table.toml (renamed from tests/invalid/text-after-table.toml)0
-rw-r--r--test-suite/tests/invalid/text-before-array-separator.toml (renamed from tests/invalid/text-before-array-separator.toml)0
-rw-r--r--test-suite/tests/invalid/text-in-array.toml (renamed from tests/invalid/text-in-array.toml)0
-rw-r--r--test-suite/tests/macros.rs286
-rw-r--r--test-suite/tests/parser.rs (renamed from tests/parser.rs)0
-rw-r--r--test-suite/tests/pretty.rs (renamed from tests/pretty.rs)0
-rw-r--r--test-suite/tests/serde.rs (renamed from tests/serde.rs)0
-rw-r--r--test-suite/tests/tables-last.rs (renamed from tests/tables-last.rs)0
-rw-r--r--test-suite/tests/valid.rs (renamed from tests/valid.rs)0
-rw-r--r--test-suite/tests/valid/array-empty.json (renamed from tests/valid/array-empty.json)0
-rw-r--r--test-suite/tests/valid/array-empty.toml (renamed from tests/valid/array-empty.toml)0
-rw-r--r--test-suite/tests/valid/array-nospaces.json (renamed from tests/valid/array-nospaces.json)0
-rw-r--r--test-suite/tests/valid/array-nospaces.toml (renamed from tests/valid/array-nospaces.toml)0
-rw-r--r--test-suite/tests/valid/arrays-hetergeneous.json (renamed from tests/valid/arrays-hetergeneous.json)0
-rw-r--r--test-suite/tests/valid/arrays-hetergeneous.toml (renamed from tests/valid/arrays-hetergeneous.toml)0
-rw-r--r--test-suite/tests/valid/arrays-nested.json (renamed from tests/valid/arrays-nested.json)0
-rw-r--r--test-suite/tests/valid/arrays-nested.toml (renamed from tests/valid/arrays-nested.toml)0
-rw-r--r--test-suite/tests/valid/arrays.json (renamed from tests/valid/arrays.json)0
-rw-r--r--test-suite/tests/valid/arrays.toml (renamed from tests/valid/arrays.toml)0
-rw-r--r--test-suite/tests/valid/bool.json (renamed from tests/valid/bool.json)0
-rw-r--r--test-suite/tests/valid/bool.toml (renamed from tests/valid/bool.toml)0
-rw-r--r--test-suite/tests/valid/comments-everywhere.json (renamed from tests/valid/comments-everywhere.json)0
-rw-r--r--test-suite/tests/valid/comments-everywhere.toml (renamed from tests/valid/comments-everywhere.toml)0
-rw-r--r--test-suite/tests/valid/datetime-truncate.json (renamed from tests/valid/datetime-truncate.json)0
-rw-r--r--test-suite/tests/valid/datetime-truncate.toml (renamed from tests/valid/datetime-truncate.toml)0
-rw-r--r--test-suite/tests/valid/datetime.json (renamed from tests/valid/datetime.json)0
-rw-r--r--test-suite/tests/valid/datetime.toml (renamed from tests/valid/datetime.toml)0
-rw-r--r--test-suite/tests/valid/empty.json (renamed from tests/valid/empty.json)0
-rw-r--r--test-suite/tests/valid/empty.toml (renamed from tests/valid/empty.toml)0
-rw-r--r--test-suite/tests/valid/example-bom.toml (renamed from tests/valid/example-bom.toml)0
-rw-r--r--test-suite/tests/valid/example-v0.3.0.json (renamed from tests/valid/example-v0.3.0.json)0
-rw-r--r--test-suite/tests/valid/example-v0.3.0.toml (renamed from tests/valid/example-v0.3.0.toml)0
-rw-r--r--test-suite/tests/valid/example-v0.4.0.json (renamed from tests/valid/example-v0.4.0.json)0
-rw-r--r--test-suite/tests/valid/example-v0.4.0.toml (renamed from tests/valid/example-v0.4.0.toml)0
-rw-r--r--test-suite/tests/valid/example.json (renamed from tests/valid/example.json)0
-rw-r--r--test-suite/tests/valid/example.toml (renamed from tests/valid/example.toml)0
-rw-r--r--test-suite/tests/valid/example2.json (renamed from tests/valid/example2.json)0
-rw-r--r--test-suite/tests/valid/example2.toml (renamed from tests/valid/example2.toml)0
-rw-r--r--test-suite/tests/valid/float.json (renamed from tests/valid/float.json)0
-rw-r--r--test-suite/tests/valid/float.toml (renamed from tests/valid/float.toml)0
-rw-r--r--test-suite/tests/valid/hard_example.json (renamed from tests/valid/hard_example.json)0
-rw-r--r--test-suite/tests/valid/hard_example.toml (renamed from tests/valid/hard_example.toml)0
-rw-r--r--test-suite/tests/valid/implicit-and-explicit-after.json (renamed from tests/valid/implicit-and-explicit-after.json)0
-rw-r--r--test-suite/tests/valid/implicit-and-explicit-after.toml (renamed from tests/valid/implicit-and-explicit-after.toml)0
-rw-r--r--test-suite/tests/valid/implicit-and-explicit-before.json (renamed from tests/valid/implicit-and-explicit-before.json)0
-rw-r--r--test-suite/tests/valid/implicit-and-explicit-before.toml (renamed from tests/valid/implicit-and-explicit-before.toml)0
-rw-r--r--test-suite/tests/valid/implicit-groups.json (renamed from tests/valid/implicit-groups.json)0
-rw-r--r--test-suite/tests/valid/implicit-groups.toml (renamed from tests/valid/implicit-groups.toml)0
-rw-r--r--test-suite/tests/valid/integer.json (renamed from tests/valid/integer.json)0
-rw-r--r--test-suite/tests/valid/integer.toml (renamed from tests/valid/integer.toml)0
-rw-r--r--test-suite/tests/valid/key-equals-nospace.json (renamed from tests/valid/key-equals-nospace.json)0
-rw-r--r--test-suite/tests/valid/key-equals-nospace.toml (renamed from tests/valid/key-equals-nospace.toml)0
-rw-r--r--test-suite/tests/valid/key-quote-newline.json (renamed from tests/valid/key-quote-newline.json)0
-rw-r--r--test-suite/tests/valid/key-quote-newline.toml (renamed from tests/valid/key-quote-newline.toml)0
-rw-r--r--test-suite/tests/valid/key-space.json (renamed from tests/valid/key-space.json)0
-rw-r--r--test-suite/tests/valid/key-space.toml (renamed from tests/valid/key-space.toml)0
-rw-r--r--test-suite/tests/valid/key-special-chars.json (renamed from tests/valid/key-special-chars.json)0
-rw-r--r--test-suite/tests/valid/key-special-chars.toml (renamed from tests/valid/key-special-chars.toml)0
-rw-r--r--test-suite/tests/valid/key-with-pound.json (renamed from tests/valid/key-with-pound.json)0
-rw-r--r--test-suite/tests/valid/key-with-pound.toml (renamed from tests/valid/key-with-pound.toml)0
-rw-r--r--test-suite/tests/valid/long-float.json (renamed from tests/valid/long-float.json)0
-rw-r--r--test-suite/tests/valid/long-float.toml (renamed from tests/valid/long-float.toml)0
-rw-r--r--test-suite/tests/valid/long-integer.json (renamed from tests/valid/long-integer.json)0
-rw-r--r--test-suite/tests/valid/long-integer.toml (renamed from tests/valid/long-integer.toml)0
-rw-r--r--test-suite/tests/valid/multiline-string.json (renamed from tests/valid/multiline-string.json)0
-rw-r--r--test-suite/tests/valid/multiline-string.toml (renamed from tests/valid/multiline-string.toml)0
-rw-r--r--test-suite/tests/valid/raw-multiline-string.json (renamed from tests/valid/raw-multiline-string.json)0
-rw-r--r--test-suite/tests/valid/raw-multiline-string.toml (renamed from tests/valid/raw-multiline-string.toml)0
-rw-r--r--test-suite/tests/valid/raw-string.json (renamed from tests/valid/raw-string.json)0
-rw-r--r--test-suite/tests/valid/raw-string.toml (renamed from tests/valid/raw-string.toml)0
-rw-r--r--test-suite/tests/valid/string-empty.json (renamed from tests/valid/string-empty.json)0
-rw-r--r--test-suite/tests/valid/string-empty.toml (renamed from tests/valid/string-empty.toml)0
-rw-r--r--test-suite/tests/valid/string-escapes.json (renamed from tests/valid/string-escapes.json)0
-rw-r--r--test-suite/tests/valid/string-escapes.toml (renamed from tests/valid/string-escapes.toml)0
-rw-r--r--test-suite/tests/valid/string-simple.json (renamed from tests/valid/string-simple.json)0
-rw-r--r--test-suite/tests/valid/string-simple.toml (renamed from tests/valid/string-simple.toml)0
-rw-r--r--test-suite/tests/valid/string-with-pound.json (renamed from tests/valid/string-with-pound.json)0
-rw-r--r--test-suite/tests/valid/string-with-pound.toml (renamed from tests/valid/string-with-pound.toml)0
-rw-r--r--test-suite/tests/valid/table-array-implicit.json (renamed from tests/valid/table-array-implicit.json)0
-rw-r--r--test-suite/tests/valid/table-array-implicit.toml (renamed from tests/valid/table-array-implicit.toml)0
-rw-r--r--test-suite/tests/valid/table-array-many.json (renamed from tests/valid/table-array-many.json)0
-rw-r--r--test-suite/tests/valid/table-array-many.toml (renamed from tests/valid/table-array-many.toml)0
-rw-r--r--test-suite/tests/valid/table-array-nest-no-keys.json (renamed from tests/valid/table-array-nest-no-keys.json)0
-rw-r--r--test-suite/tests/valid/table-array-nest-no-keys.toml (renamed from tests/valid/table-array-nest-no-keys.toml)0
-rw-r--r--test-suite/tests/valid/table-array-nest.json (renamed from tests/valid/table-array-nest.json)0
-rw-r--r--test-suite/tests/valid/table-array-nest.toml (renamed from tests/valid/table-array-nest.toml)0
-rw-r--r--test-suite/tests/valid/table-array-one.json (renamed from tests/valid/table-array-one.json)0
-rw-r--r--test-suite/tests/valid/table-array-one.toml (renamed from tests/valid/table-array-one.toml)0
-rw-r--r--test-suite/tests/valid/table-empty.json (renamed from tests/valid/table-empty.json)0
-rw-r--r--test-suite/tests/valid/table-empty.toml (renamed from tests/valid/table-empty.toml)0
-rw-r--r--test-suite/tests/valid/table-multi-empty.json (renamed from tests/valid/table-multi-empty.json)0
-rw-r--r--test-suite/tests/valid/table-multi-empty.toml (renamed from tests/valid/table-multi-empty.toml)0
-rw-r--r--test-suite/tests/valid/table-sub-empty.json (renamed from tests/valid/table-sub-empty.json)0
-rw-r--r--test-suite/tests/valid/table-sub-empty.toml (renamed from tests/valid/table-sub-empty.toml)0
-rw-r--r--test-suite/tests/valid/table-whitespace.json (renamed from tests/valid/table-whitespace.json)0
-rw-r--r--test-suite/tests/valid/table-whitespace.toml (renamed from tests/valid/table-whitespace.toml)0
-rw-r--r--test-suite/tests/valid/table-with-pound.json (renamed from tests/valid/table-with-pound.json)0
-rw-r--r--test-suite/tests/valid/table-with-pound.toml (renamed from tests/valid/table-with-pound.toml)0
-rw-r--r--test-suite/tests/valid/unicode-escape.json (renamed from tests/valid/unicode-escape.json)0
-rw-r--r--test-suite/tests/valid/unicode-escape.toml (renamed from tests/valid/unicode-escape.toml)0
-rw-r--r--test-suite/tests/valid/unicode-literal.json (renamed from tests/valid/unicode-literal.json)0
-rw-r--r--test-suite/tests/valid/unicode-literal.toml (renamed from tests/valid/unicode-literal.toml)0
156 files changed, 686 insertions, 0 deletions
diff --git a/.travis.yml b/.travis.yml
index e4c5407..0715ef1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,6 +9,7 @@ before_script:
- pip install 'travis-cargo<0.2' --user && export PATH=$HOME/.local/bin:$PATH
script:
- cargo test
+ - cargo test --manifest-path test-suite/Cargo.toml
- rustdoc --test README.md -L target
- test "$TRAVIS_RUST_VERSION" != "1.15.0" && cargo doc --no-deps || echo "skipping cargo doc"
after_success:
diff --git a/src/lib.rs b/src/lib.rs
index c4a7e9d..1c4842b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -166,3 +166,6 @@ pub mod de;
#[doc(no_inline)]
pub use de::{from_slice, from_str, Deserializer};
mod tokens;
+
+#[doc(hidden)]
+pub mod macros;
diff --git a/src/macros.rs b/src/macros.rs
new file mode 100644
index 0000000..7a2bcd3
--- /dev/null
+++ b/src/macros.rs
@@ -0,0 +1,373 @@
+pub use serde::de::{Deserialize, IntoDeserializer};
+
+use value::{Value, Table, Array};
+
+/// Construct a [`toml::Value`] from TOML syntax.
+///
+/// [`toml::Value`]: value/enum.Value.html
+///
+/// ```rust
+/// #[macro_use]
+/// extern crate toml;
+///
+/// fn main() {
+/// let cargo_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);
+ toml_internal!(@toplevel root [] $($toml)+);
+ root
+ }};
+}
+
+// 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)*) => {
+ 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)*) => {
+ toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($yr - $mo - $dhr : $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)*) => {
+ toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($yr - $mo - $dhr : $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)*) => {
+ toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($yr - $mo - $dhr : $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)*) => {
+ toml_internal!(@topleveldatetime $root [$($path)*] $($k)-+ = ($yr - $mo - $dhr : $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)*) => {
+ 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)*) => {
+ 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)*) => {
+ 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!($("-", toml_internal!(@path $k),)+)[1..]],
+ toml_internal!(@value $v));
+ 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!($("-", toml_internal!(@path $path),)+)[1..],)+]);
+ toml_internal!(@toplevel $root [$(&concat!($("-", 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!($("-", toml_internal!(@path $path),)+)[1..],)+],
+ $crate::Value::Table($crate::value::Table::new()));
+ toml_internal!(@toplevel $root [$(&concat!($("-", 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!($("-", toml_internal!(@path $k),)+)[1..]],
+ $crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
+ 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::new();
+ toml_internal!(@trailingcomma (@table table) $($inline)*);
+ $crate::Value::Table(table)
+ }};
+
+ // Construct a Value from an inline array.
+ (@value [ $($inline:tt)* ]) => {{
+ let mut array = $crate::value::Array::new();
+ toml_internal!(@trailingcomma (@array array) $($inline)*);
+ $crate::Value::Array(array)
+ }};
+
+ // 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)*) => {
+ 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)*) => {
+ toml_internal!(@tabledatetime $root $($k)-+ = ($yr - $mo - $dhr : $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)*) => {
+ toml_internal!(@tabledatetime $root $($k)-+ = ($yr - $mo - $dhr : $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)*) => {
+ toml_internal!(@tabledatetime $root $($k)-+ = ($yr - $mo - $dhr : $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)*) => {
+ toml_internal!(@tabledatetime $root $($k)-+ = ($yr - $mo - $dhr : $min : $sec) $($rest)*);
+ };
+
+ // Parse local date `key = 1979-05-27`.
+ (@table $root:ident $($k:tt)-+ = $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => {
+ 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)*) => {
+ 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)*) => {
+ 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)*) => {
+ $root.insert(
+ concat!($("-", toml_internal!(@path $k),)+)[1..].to_owned(),
+ toml_internal!(@value $v));
+ toml_internal!(@table $root $($rest)*);
+ };
+
+ // Parse a Datetime from string and continue in @table state.
+ (@tabledatetime $root:ident $($k:tt)-+ = ($($datetime:tt)*) $($rest:tt)*) => {
+ $root.insert(
+ concat!($("-", toml_internal!(@path $k),)+)[1..].to_owned(),
+ $crate::Value::Datetime(concat!($(stringify!($datetime)),+).parse().unwrap()));
+ toml_internal!(@table $root $($rest)*);
+ };
+
+ // Base case of inline array.
+ (@array $root:ident) => {};
+
+ // Parse negative number `-value`.
+ (@array $root:ident - $v:tt , $($rest:tt)*) => {
+ 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)*) => {
+ toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $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)*) => {
+ toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $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)*) => {
+ toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $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)*) => {
+ toml_internal!(@arraydatetime $root ($yr - $mo - $dhr : $min : $sec) $($rest)*);
+ };
+
+ // Parse local date `1979-05-27`.
+ (@array $root:ident $yr:tt - $mo:tt - $day:tt , $($rest:tt)*) => {
+ 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)*) => {
+ 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)*) => {
+ 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(toml_internal!(@value $v));
+ 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()));
+ toml_internal!(@array $root $($rest)*);
+ };
+
+ // No trailing comma required if the tokens are empty.
+ (@trailingcomma ($($args:tt)*)) => {
+ toml_internal!($($args)*);
+ };
+
+ // Tokens end with a trailing comma, do not append another one.
+ (@trailingcomma ($($args:tt)*) ,) => {
+ toml_internal!($($args)* ,);
+ };
+
+ // Tokens end with something other than comma, append a trailing comma.
+ (@trailingcomma ($($args:tt)*) $last:tt) => {
+ toml_internal!($($args)* $last ,);
+ };
+
+ // Not yet at the last token.
+ (@trailingcomma ($($args:tt)*) $first:tt $($rest:tt)+) => {
+ 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;
+ let cur2;
+
+ // From the TOML spec:
+ //
+ // > Each double-bracketed sub-table will belong to the most recently
+ // > defined table element above it.
+ if cur1.is_array() {
+ cur2 = cur1.as_array_mut().unwrap().last_mut().unwrap();
+ } else {
+ cur2 = 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/test-suite/Cargo.toml b/test-suite/Cargo.toml
new file mode 100644
index 0000000..10ffbcb
--- /dev/null
+++ b/test-suite/Cargo.toml
@@ -0,0 +1,15 @@
+[package]
+name = "toml_test_suite"
+version = "0.0.0"
+authors = ["Alex Crichton <alex@alexcrichton.com>"]
+build = "build.rs"
+publish = false
+
+[build-dependencies]
+rustc_version = "0.2"
+
+[dev-dependencies]
+toml = { path = ".." }
+serde = "1.0"
+serde_derive = "1.0"
+serde_json = "1.0"
diff --git a/test-suite/build.rs b/test-suite/build.rs
new file mode 100644
index 0000000..ca63946
--- /dev/null
+++ b/test-suite/build.rs
@@ -0,0 +1,8 @@
+extern crate rustc_version;
+use rustc_version::{version, Version};
+
+fn main() {
+ if version().unwrap() >= Version::parse("1.20.0").unwrap() {
+ println!(r#"cargo:rustc-cfg=feature="test-quoted-keys-in-macro""#);
+ }
+}
diff --git a/tests/README.md b/test-suite/tests/README.md
index ebbc01c..ebbc01c 100644
--- a/tests/README.md
+++ b/test-suite/tests/README.md
diff --git a/tests/backcompat.rs b/test-suite/tests/backcompat.rs
index 1b3f599..1b3f599 100644
--- a/tests/backcompat.rs
+++ b/test-suite/tests/backcompat.rs
diff --git a/tests/datetime.rs b/test-suite/tests/datetime.rs
index 948e863..948e863 100644
--- a/tests/datetime.rs
+++ b/test-suite/tests/datetime.rs
diff --git a/tests/display-tricky.rs b/test-suite/tests/display-tricky.rs
index 069e0f9..069e0f9 100644
--- a/tests/display-tricky.rs
+++ b/test-suite/tests/display-tricky.rs
diff --git a/tests/display.rs b/test-suite/tests/display.rs
index ca4fdd8..ca4fdd8 100644
--- a/tests/display.rs
+++ b/test-suite/tests/display.rs
diff --git a/tests/formatting.rs b/test-suite/tests/formatting.rs
index 4ba1418..4ba1418 100644
--- a/tests/formatting.rs
+++ b/test-suite/tests/formatting.rs
diff --git a/tests/invalid-encoder-misc.rs b/test-suite/tests/invalid-encoder-misc.rs
index 272f58f..272f58f 100644
--- a/tests/invalid-encoder-misc.rs
+++ b/test-suite/tests/invalid-encoder-misc.rs
diff --git a/tests/invalid-encoder/array-mixed-types-ints-and-floats.json b/test-suite/tests/invalid-encoder/array-mixed-types-ints-and-floats.json
index 2d42ead..2d42ead 100644
--- a/tests/invalid-encoder/array-mixed-types-ints-and-floats.json
+++ b/test-suite/tests/invalid-encoder/array-mixed-types-ints-and-floats.json
diff --git a/tests/invalid-misc.rs b/test-suite/tests/invalid-misc.rs
index bb70b97..bb70b97 100644
--- a/tests/invalid-misc.rs
+++ b/test-suite/tests/invalid-misc.rs
diff --git a/tests/invalid.rs b/test-suite/tests/invalid.rs
index 4679684..4679684 100644
--- a/tests/invalid.rs
+++ b/test-suite/tests/invalid.rs
diff --git a/tests/invalid/array-mixed-types-arrays-and-ints.toml b/test-suite/tests/invalid/array-mixed-types-arrays-and-ints.toml
index 051ec73..051ec73 100644
--- a/tests/invalid/array-mixed-types-arrays-and-ints.toml
+++ b/test-suite/tests/invalid/array-mixed-types-arrays-and-ints.toml
diff --git a/tests/invalid/array-mixed-types-ints-and-floats.toml b/test-suite/tests/invalid/array-mixed-types-ints-and-floats.toml
index a5aa9b7..a5aa9b7 100644
--- a/tests/invalid/array-mixed-types-ints-and-floats.toml
+++ b/test-suite/tests/invalid/array-mixed-types-ints-and-floats.toml
diff --git a/tests/invalid/array-mixed-types-strings-and-ints.toml b/test-suite/tests/invalid/array-mixed-types-strings-and-ints.toml
index f348308..f348308 100644
--- a/tests/invalid/array-mixed-types-strings-and-ints.toml
+++ b/test-suite/tests/invalid/array-mixed-types-strings-and-ints.toml
diff --git a/tests/invalid/datetime-malformed-no-leads.toml b/test-suite/tests/invalid/datetime-malformed-no-leads.toml
index 123f173..123f173 100644
--- a/tests/invalid/datetime-malformed-no-leads.toml
+++ b/test-suite/tests/invalid/datetime-malformed-no-leads.toml
diff --git a/tests/invalid/datetime-malformed-no-secs.toml b/test-suite/tests/invalid/datetime-malformed-no-secs.toml
index ba93900..ba93900 100644
--- a/tests/invalid/datetime-malformed-no-secs.toml
+++ b/test-suite/tests/invalid/datetime-malformed-no-secs.toml
diff --git a/tests/invalid/datetime-malformed-no-t.toml b/test-suite/tests/invalid/datetime-malformed-no-t.toml
index 617e3c5..617e3c5 100644
--- a/tests/invalid/datetime-malformed-no-t.toml
+++ b/test-suite/tests/invalid/datetime-malformed-no-t.toml
diff --git a/tests/invalid/datetime-malformed-with-milli.toml b/test-suite/tests/invalid/datetime-malformed-with-milli.toml
index eef792f..eef792f 100644
--- a/tests/invalid/datetime-malformed-with-milli.toml
+++ b/test-suite/tests/invalid/datetime-malformed-with-milli.toml
diff --git a/tests/invalid/duplicate-key-table.toml b/test-suite/tests/invalid/duplicate-key-table.toml
index cedf05f..cedf05f 100644
--- a/tests/invalid/duplicate-key-table.toml
+++ b/test-suite/tests/invalid/duplicate-key-table.toml
diff --git a/tests/invalid/duplicate-keys.toml b/test-suite/tests/invalid/duplicate-keys.toml
index 9b5aee0..9b5aee0 100644
--- a/tests/invalid/duplicate-keys.toml
+++ b/test-suite/tests/invalid/duplicate-keys.toml
diff --git a/tests/invalid/duplicate-tables.toml b/test-suite/tests/invalid/duplicate-tables.toml
index 8ddf49b..8ddf49b 100644
--- a/tests/invalid/duplicate-tables.toml
+++ b/test-suite/tests/invalid/duplicate-tables.toml
diff --git a/tests/invalid/empty-implicit-table.toml b/test-suite/tests/invalid/empty-implicit-table.toml
index 0cc36d0..0cc36d0 100644
--- a/tests/invalid/empty-implicit-table.toml
+++ b/test-suite/tests/invalid/empty-implicit-table.toml
diff --git a/tests/invalid/empty-table.toml b/test-suite/tests/invalid/empty-table.toml
index fe51488..fe51488 100644
--- a/tests/invalid/empty-table.toml
+++ b/test-suite/tests/invalid/empty-table.toml
diff --git a/tests/invalid/float-no-leading-zero.toml b/test-suite/tests/invalid/float-no-leading-zero.toml
index cab76bf..cab76bf 100644
--- a/tests/invalid/float-no-leading-zero.toml
+++ b/test-suite/tests/invalid/float-no-leading-zero.toml
diff --git a/tests/invalid/float-no-trailing-digits.toml b/test-suite/tests/invalid/float-no-trailing-digits.toml
index cbff2d0..cbff2d0 100644
--- a/tests/invalid/float-no-trailing-digits.toml
+++ b/test-suite/tests/invalid/float-no-trailing-digits.toml
diff --git a/tests/invalid/key-after-array.toml b/test-suite/tests/invalid/key-after-array.toml
index 5c1a1b0..5c1a1b0 100644
--- a/tests/invalid/key-after-array.toml
+++ b/test-suite/tests/invalid/key-after-array.toml
diff --git a/tests/invalid/key-after-table.toml b/test-suite/tests/invalid/key-after-table.toml
index 4bc8213..4bc8213 100644
--- a/tests/invalid/key-after-table.toml
+++ b/test-suite/tests/invalid/key-after-table.toml
diff --git a/tests/invalid/key-empty.toml b/test-suite/tests/invalid/key-empty.toml
index 09f998f..09f998f 100644
--- a/tests/invalid/key-empty.toml
+++ b/test-suite/tests/invalid/key-empty.toml
diff --git a/tests/invalid/key-hash.toml b/test-suite/tests/invalid/key-hash.toml
index e321b1f..e321b1f 100644
--- a/tests/invalid/key-hash.toml
+++ b/test-suite/tests/invalid/key-hash.toml
diff --git a/tests/invalid/key-newline.toml b/test-suite/tests/invalid/key-newline.toml
index 707aad5..707aad5 100644
--- a/tests/invalid/key-newline.toml
+++ b/test-suite/tests/invalid/key-newline.toml
diff --git a/tests/invalid/key-open-bracket.toml b/test-suite/tests/invalid/key-open-bracket.toml
index f0aeb16..f0aeb16 100644
--- a/tests/invalid/key-open-bracket.toml
+++ b/test-suite/tests/invalid/key-open-bracket.toml
diff --git a/tests/invalid/key-single-open-bracket.toml b/test-suite/tests/invalid/key-single-open-bracket.toml
index 8e2f0be..8e2f0be 100644
--- a/tests/invalid/key-single-open-bracket.toml
+++ b/test-suite/tests/invalid/key-single-open-bracket.toml
diff --git a/tests/invalid/key-space.toml b/test-suite/tests/invalid/key-space.toml
index 201806d..201806d 100644
--- a/tests/invalid/key-space.toml
+++ b/test-suite/tests/invalid/key-space.toml
diff --git a/tests/invalid/key-start-bracket.toml b/test-suite/tests/invalid/key-start-bracket.toml
index e0597ae..e0597ae 100644
--- a/tests/invalid/key-start-bracket.toml
+++ b/test-suite/tests/invalid/key-start-bracket.toml
diff --git a/tests/invalid/key-two-equals.toml b/test-suite/tests/invalid/key-two-equals.toml
index 25a0378..25a0378 100644
--- a/tests/invalid/key-two-equals.toml
+++ b/test-suite/tests/invalid/key-two-equals.toml
diff --git a/tests/invalid/string-bad-byte-escape.toml b/test-suite/tests/invalid/string-bad-byte-escape.toml
index 4c7be59..4c7be59 100644
--- a/tests/invalid/string-bad-byte-escape.toml
+++ b/test-suite/tests/invalid/string-bad-byte-escape.toml
diff --git a/tests/invalid/string-bad-escape.toml b/test-suite/tests/invalid/string-bad-escape.toml
index 60acb0c..60acb0c 100644
--- a/tests/invalid/string-bad-escape.toml
+++ b/test-suite/tests/invalid/string-bad-escape.toml
diff --git a/tests/invalid/string-byte-escapes.toml b/test-suite/tests/invalid/string-byte-escapes.toml
index e94452a..e94452a 100644
--- a/tests/invalid/string-byte-escapes.toml
+++ b/test-suite/tests/invalid/string-byte-escapes.toml
diff --git a/tests/invalid/string-no-close.toml b/test-suite/tests/invalid/string-no-close.toml
index 0c292fc..0c292fc 100644
--- a/tests/invalid/string-no-close.toml
+++ b/test-suite/tests/invalid/string-no-close.toml
diff --git a/tests/invalid/table-array-implicit.toml b/test-suite/tests/invalid/table-array-implicit.toml
index 05f2507..05f2507 100644
--- a/tests/invalid/table-array-implicit.toml
+++ b/test-suite/tests/invalid/table-array-implicit.toml
diff --git a/tests/invalid/table-array-malformed-bracket.toml b/test-suite/tests/invalid/table-array-malformed-bracket.toml
index 39c73b0..39c73b0 100644
--- a/tests/invalid/table-array-malformed-bracket.toml
+++ b/test-suite/tests/invalid/table-array-malformed-bracket.toml
diff --git a/tests/invalid/table-array-malformed-empty.toml b/test-suite/tests/invalid/table-array-malformed-empty.toml
index a470ca3..a470ca3 100644
--- a/tests/invalid/table-array-malformed-empty.toml
+++ b/test-suite/tests/invalid/table-array-malformed-empty.toml
diff --git a/tests/invalid/table-empty.toml b/test-suite/tests/invalid/table-empty.toml
index fe51488..fe51488 100644
--- a/tests/invalid/table-empty.toml
+++ b/test-suite/tests/invalid/table-empty.toml
diff --git a/tests/invalid/table-nested-brackets-close.toml b/test-suite/tests/invalid/table-nested-brackets-close.toml
index c8b5a67..c8b5a67 100644
--- a/tests/invalid/table-nested-brackets-close.toml
+++ b/test-suite/tests/invalid/table-nested-brackets-close.toml
diff --git a/tests/invalid/table-nested-brackets-open.toml b/test-suite/tests/invalid/table-nested-brackets-open.toml
index 246d7e9..246d7e9 100644
--- a/tests/invalid/table-nested-brackets-open.toml
+++ b/test-suite/tests/invalid/table-nested-brackets-open.toml
diff --git a/tests/invalid/table-whitespace.toml b/test-suite/tests/invalid/table-whitespace.toml
index 79bbcb1..79bbcb1 100644
--- a/tests/invalid/table-whitespace.toml
+++ b/test-suite/tests/invalid/table-whitespace.toml
diff --git a/tests/invalid/table-with-pound.toml b/test-suite/tests/invalid/table-with-pound.toml
index 0d8edb5..0d8edb5 100644
--- a/tests/invalid/table-with-pound.toml
+++ b/test-suite/tests/invalid/table-with-pound.toml
diff --git a/tests/invalid/text-after-array-entries.toml b/test-suite/tests/invalid/text-after-array-entries.toml
index 1a72890..1a72890 100644
--- a/tests/invalid/text-after-array-entries.toml
+++ b/test-suite/tests/invalid/text-after-array-entries.toml
diff --git a/tests/invalid/text-after-integer.toml b/test-suite/tests/invalid/text-after-integer.toml
index 42de7af..42de7af 100644
--- a/tests/invalid/text-after-integer.toml
+++ b/test-suite/tests/invalid/text-after-integer.toml
diff --git a/tests/invalid/text-after-string.toml b/test-suite/tests/invalid/text-after-string.toml
index c92a6f1..c92a6f1 100644
--- a/tests/invalid/text-after-string.toml
+++ b/test-suite/tests/invalid/text-after-string.toml
diff --git a/tests/invalid/text-after-table.toml b/test-suite/tests/invalid/text-after-table.toml
index 87da9db..87da9db 100644
--- a/tests/invalid/text-after-table.toml
+++ b/test-suite/tests/invalid/text-after-table.toml
diff --git a/tests/invalid/text-before-array-separator.toml b/test-suite/tests/invalid/text-before-array-separator.toml
index 9b06a39..9b06a39 100644
--- a/tests/invalid/text-before-array-separator.toml
+++ b/test-suite/tests/invalid/text-before-array-separator.toml
diff --git a/tests/invalid/text-in-array.toml b/test-suite/tests/invalid/text-in-array.toml
index a6a6c42..a6a6c42 100644
--- a/tests/invalid/text-in-array.toml
+++ b/test-suite/tests/invalid/text-in-array.toml
diff --git a/test-suite/tests/macros.rs b/test-suite/tests/macros.rs
new file mode 100644
index 0000000..439420d
--- /dev/null
+++ b/test-suite/tests/macros.rs
@@ -0,0 +1,286 @@
+#![recursion_limit = "128"]
+
+#[macro_use]
+extern crate toml;
+
+macro_rules! table {
+ ($($key:expr => $value:expr,)*) => {{
+ let mut table = toml::value::Table::new();
+ $(
+ table.insert($key.to_string(), $value.into());
+ )*
+ toml::Value::Table(table)
+ }};
+}
+
+macro_rules! array {
+ ($($element:expr,)*) => {{
+ 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!(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!(actual, expected);
+}
+
+#[test]
+fn test_number() {
+ let actual = toml! {
+ positive = 1
+ negative = -1
+ table = { positive = 1, negative = -1 }
+ array = [ 1, -1 ]
+ };
+
+ let expected = table! {
+ "positive" => 1,
+ "negative" => -1,
+ "table" => table! {
+ "positive" => 1,
+ "negative" => -1,
+ },
+ "array" => array! {
+ 1,
+ -1,
+ },
+ };
+
+ assert_eq!(actual, expected);
+}
+
+#[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
+ 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,
+ 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-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"),
+ "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"),
+ "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-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!(actual, expected);
+}
+
+// This test requires rustc >= 1.20.
+#[test]
+#[cfg(feature = "test-quoted-keys-in-macro")]
+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!(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!(actual, expected);
+}
diff --git a/tests/parser.rs b/test-suite/tests/parser.rs
index 2282416..2282416 100644
--- a/tests/parser.rs
+++ b/test-suite/tests/parser.rs
diff --git a/tests/pretty.rs b/test-suite/tests/pretty.rs
index 19ed22d..19ed22d 100644
--- a/tests/pretty.rs
+++ b/test-suite/tests/pretty.rs
diff --git a/tests/serde.rs b/test-suite/tests/serde.rs
index 57fa5db..57fa5db 100644
--- a/tests/serde.rs
+++ b/test-suite/tests/serde.rs
diff --git a/tests/tables-last.rs b/test-suite/tests/tables-last.rs
index d05c8f0..d05c8f0 100644
--- a/tests/tables-last.rs
+++ b/test-suite/tests/tables-last.rs
diff --git a/tests/valid.rs b/test-suite/tests/valid.rs
index b186800..b186800 100644
--- a/tests/valid.rs
+++ b/test-suite/tests/valid.rs
diff --git a/tests/valid/array-empty.json b/test-suite/tests/valid/array-empty.json
index 2fbf256..2fbf256 100644
--- a/tests/valid/array-empty.json
+++ b/test-suite/tests/valid/array-empty.json
diff --git a/tests/valid/array-empty.toml b/test-suite/tests/valid/array-empty.toml
index fa58dc6..fa58dc6 100644
--- a/tests/valid/array-empty.toml
+++ b/test-suite/tests/valid/array-empty.toml
diff --git a/tests/valid/array-nospaces.json b/test-suite/tests/valid/array-nospaces.json
index 1833d61..1833d61 100644
--- a/tests/valid/array-nospaces.json
+++ b/test-suite/tests/valid/array-nospaces.json
diff --git a/tests/valid/array-nospaces.toml b/test-suite/tests/valid/array-nospaces.toml
index 6618936..6618936 100644
--- a/tests/valid/array-nospaces.toml
+++ b/test-suite/tests/valid/array-nospaces.toml
diff --git a/tests/valid/arrays-hetergeneous.json b/test-suite/tests/valid/arrays-hetergeneous.json
index 478fa5c..478fa5c 100644
--- a/tests/valid/arrays-hetergeneous.json
+++ b/test-suite/tests/valid/arrays-hetergeneous.json
diff --git a/tests/valid/arrays-hetergeneous.toml b/test-suite/tests/valid/arrays-hetergeneous.toml
index a246fcf..a246fcf 100644
--- a/tests/valid/arrays-hetergeneous.toml
+++ b/test-suite/tests/valid/arrays-hetergeneous.toml
diff --git a/tests/valid/arrays-nested.json b/test-suite/tests/valid/arrays-nested.json
index d21920c..d21920c 100644
--- a/tests/valid/arrays-nested.json
+++ b/test-suite/tests/valid/arrays-nested.json
diff --git a/tests/valid/arrays-nested.toml b/test-suite/tests/valid/arrays-nested.toml
index ce33022..ce33022 100644
--- a/tests/valid/arrays-nested.toml
+++ b/test-suite/tests/valid/arrays-nested.toml
diff --git a/tests/valid/arrays.json b/test-suite/tests/valid/arrays.json
index 58aedbc..58aedbc 100644
--- a/tests/valid/arrays.json
+++ b/test-suite/tests/valid/arrays.json
diff --git a/tests/valid/arrays.toml b/test-suite/tests/valid/arrays.toml
index c435f57..c435f57 100644
--- a/tests/valid/arrays.toml
+++ b/test-suite/tests/valid/arrays.toml
diff --git a/tests/valid/bool.json b/test-suite/tests/valid/bool.json
index ae368e9..ae368e9 100644
--- a/tests/valid/bool.json
+++ b/test-suite/tests/valid/bool.json
diff --git a/tests/valid/bool.toml b/test-suite/tests/valid/bool.toml
index a8a829b..a8a829b 100644
--- a/tests/valid/bool.toml
+++ b/test-suite/tests/valid/bool.toml
diff --git a/tests/valid/comments-everywhere.json b/test-suite/tests/valid/comments-everywhere.json
index e69a2e9..e69a2e9 100644
--- a/tests/valid/comments-everywhere.json
+++ b/test-suite/tests/valid/comments-everywhere.json
diff --git a/tests/valid/comments-everywhere.toml b/test-suite/tests/valid/comments-everywhere.toml
index 3dca74c..3dca74c 100644
--- a/tests/valid/comments-everywhere.toml
+++ b/test-suite/tests/valid/comments-everywhere.toml
diff --git a/tests/valid/datetime-truncate.json b/test-suite/tests/valid/datetime-truncate.json
index 8c512e1..8c512e1 100644
--- a/tests/valid/datetime-truncate.json
+++ b/test-suite/tests/valid/datetime-truncate.json
diff --git a/tests/valid/datetime-truncate.toml b/test-suite/tests/valid/datetime-truncate.toml
index 05de841..05de841 100644
--- a/tests/valid/datetime-truncate.toml
+++ b/test-suite/tests/valid/datetime-truncate.toml
diff --git a/tests/valid/datetime.json b/test-suite/tests/valid/datetime.json
index 2ca93ce..2ca93ce 100644
--- a/tests/valid/datetime.json
+++ b/test-suite/tests/valid/datetime.json
diff --git a/tests/valid/datetime.toml b/test-suite/tests/valid/datetime.toml
index 2e99340..2e99340 100644
--- a/tests/valid/datetime.toml
+++ b/test-suite/tests/valid/datetime.toml
diff --git a/tests/valid/empty.json b/test-suite/tests/valid/empty.json
index 0967ef4..0967ef4 100644
--- a/tests/valid/empty.json
+++ b/test-suite/tests/valid/empty.json
diff --git a/tests/valid/empty.toml b/test-suite/tests/valid/empty.toml
index e69de29..e69de29 100644
--- a/tests/valid/empty.toml
+++ b/test-suite/tests/valid/empty.toml
diff --git a/tests/valid/example-bom.toml b/test-suite/tests/valid/example-bom.toml
index fb5ac81..fb5ac81 100644
--- a/tests/valid/example-bom.toml
+++ b/test-suite/tests/valid/example-bom.toml
diff --git a/tests/valid/example-v0.3.0.json b/test-suite/tests/valid/example-v0.3.0.json
index 1d9dcb5..1d9dcb5 100644
--- a/tests/valid/example-v0.3.0.json
+++ b/test-suite/tests/valid/example-v0.3.0.json
diff --git a/tests/valid/example-v0.3.0.toml b/test-suite/tests/valid/example-v0.3.0.toml
index 76aacc3..76aacc3 100644
--- a/tests/valid/example-v0.3.0.toml
+++ b/test-suite/tests/valid/example-v0.3.0.toml
diff --git a/tests/valid/example-v0.4.0.json b/test-suite/tests/valid/example-v0.4.0.json
index d5cac34..d5cac34 100644
--- a/tests/valid/example-v0.4.0.json
+++ b/test-suite/tests/valid/example-v0.4.0.json
diff --git a/tests/valid/example-v0.4.0.toml b/test-suite/tests/valid/example-v0.4.0.toml
index ffbcce0..ffbcce0 100644
--- a/tests/valid/example-v0.4.0.toml
+++ b/test-suite/tests/valid/example-v0.4.0.toml
diff --git a/tests/valid/example.json b/test-suite/tests/valid/example.json
index 48aa907..48aa907 100644
--- a/tests/valid/example.json
+++ b/test-suite/tests/valid/example.json
diff --git a/tests/valid/example.toml b/test-suite/tests/valid/example.toml
index 8cb02e0..8cb02e0 100644
--- a/tests/valid/example.toml
+++ b/test-suite/tests/valid/example.toml
diff --git a/tests/valid/example2.json b/test-suite/tests/valid/example2.json
index 3249a97..3249a97 100644
--- a/tests/valid/example2.json
+++ b/test-suite/tests/valid/example2.json
diff --git a/tests/valid/example2.toml b/test-suite/tests/valid/example2.toml
index bc12c99..bc12c99 100644
--- a/tests/valid/example2.toml
+++ b/test-suite/tests/valid/example2.toml
diff --git a/tests/valid/float.json b/test-suite/tests/valid/float.json
index b8a2e97..b8a2e97 100644
--- a/tests/valid/float.json
+++ b/test-suite/tests/valid/float.json
diff --git a/tests/valid/float.toml b/test-suite/tests/valid/float.toml
index 7c528d2..7c528d2 100644
--- a/tests/valid/float.toml
+++ b/test-suite/tests/valid/float.toml
diff --git a/tests/valid/hard_example.json b/test-suite/tests/valid/hard_example.json
index 9762e58..9762e58 100644
--- a/tests/valid/hard_example.json
+++ b/test-suite/tests/valid/hard_example.json
diff --git a/tests/valid/hard_example.toml b/test-suite/tests/valid/hard_example.toml
index 38856c8..38856c8 100644
--- a/tests/valid/hard_example.toml
+++ b/test-suite/tests/valid/hard_example.toml
diff --git a/tests/valid/implicit-and-explicit-after.json b/test-suite/tests/valid/implicit-and-explicit-after.json
index 374bd09..374bd09 100644
--- a/tests/valid/implicit-and-explicit-after.json
+++ b/test-suite/tests/valid/implicit-and-explicit-after.json
diff --git a/tests/valid/implicit-and-explicit-after.toml b/test-suite/tests/valid/implicit-and-explicit-after.toml
index c0e8865..c0e8865 100644
--- a/tests/valid/implicit-and-explicit-after.toml
+++ b/test-suite/tests/valid/implicit-and-explicit-after.toml
diff --git a/tests/valid/implicit-and-explicit-before.json b/test-suite/tests/valid/implicit-and-explicit-before.json
index 374bd09..374bd09 100644
--- a/tests/valid/implicit-and-explicit-before.json
+++ b/test-suite/tests/valid/implicit-and-explicit-before.json
diff --git a/tests/valid/implicit-and-explicit-before.toml b/test-suite/tests/valid/implicit-and-explicit-before.toml
index eee68ff..eee68ff 100644
--- a/tests/valid/implicit-and-explicit-before.toml
+++ b/test-suite/tests/valid/implicit-and-explicit-before.toml
diff --git a/tests/valid/implicit-groups.json b/test-suite/tests/valid/implicit-groups.json
index fbae7fc..fbae7fc 100644
--- a/tests/valid/implicit-groups.json
+++ b/test-suite/tests/valid/implicit-groups.json
diff --git a/tests/valid/implicit-groups.toml b/test-suite/tests/valid/implicit-groups.toml
index b6333e4..b6333e4 100644
--- a/tests/valid/implicit-groups.toml
+++ b/test-suite/tests/valid/implicit-groups.toml
diff --git a/tests/valid/integer.json b/test-suite/tests/valid/integer.json
index 61985a1..61985a1 100644
--- a/tests/valid/integer.json
+++ b/test-suite/tests/valid/integer.json
diff --git a/tests/valid/integer.toml b/test-suite/tests/valid/integer.toml
index c4f6297..c4f6297 100644
--- a/tests/valid/integer.toml
+++ b/test-suite/tests/valid/integer.toml
diff --git a/tests/valid/key-equals-nospace.json b/test-suite/tests/valid/key-equals-nospace.json
index 1f8709a..1f8709a 100644
--- a/tests/valid/key-equals-nospace.json
+++ b/test-suite/tests/valid/key-equals-nospace.json
diff --git a/tests/valid/key-equals-nospace.toml b/test-suite/tests/valid/key-equals-nospace.toml
index 560901c..560901c 100644
--- a/tests/valid/key-equals-nospace.toml
+++ b/test-suite/tests/valid/key-equals-nospace.toml
diff --git a/tests/valid/key-quote-newline.json b/test-suite/tests/valid/key-quote-newline.json
index 12473e4..12473e4 100644
--- a/tests/valid/key-quote-newline.json
+++ b/test-suite/tests/valid/key-quote-newline.json
diff --git a/tests/valid/key-quote-newline.toml b/test-suite/tests/valid/key-quote-newline.toml
index a2639bf..a2639bf 100644
--- a/tests/valid/key-quote-newline.toml
+++ b/test-suite/tests/valid/key-quote-newline.toml
diff --git a/tests/valid/key-space.json b/test-suite/tests/valid/key-space.json
index 9d1f769..9d1f769 100644
--- a/tests/valid/key-space.json
+++ b/test-suite/tests/valid/key-space.json
diff --git a/tests/valid/key-space.toml b/test-suite/tests/valid/key-space.toml
index f4f36c4..f4f36c4 100644
--- a/tests/valid/key-space.toml
+++ b/test-suite/tests/valid/key-space.toml
diff --git a/tests/valid/key-special-chars.json b/test-suite/tests/valid/key-special-chars.json
index 6550ebd..6550ebd 100644
--- a/tests/valid/key-special-chars.json
+++ b/test-suite/tests/valid/key-special-chars.json
diff --git a/tests/valid/key-special-chars.toml b/test-suite/tests/valid/key-special-chars.toml
index dc43625..dc43625 100644
--- a/tests/valid/key-special-chars.toml
+++ b/test-suite/tests/valid/key-special-chars.toml
diff --git a/tests/valid/key-with-pound.json b/test-suite/tests/valid/key-with-pound.json
index ee39e1d..ee39e1d 100644
--- a/tests/valid/key-with-pound.json
+++ b/test-suite/tests/valid/key-with-pound.json
diff --git a/tests/valid/key-with-pound.toml b/test-suite/tests/valid/key-with-pound.toml
index 65b766f..65b766f 100644
--- a/tests/valid/key-with-pound.toml
+++ b/test-suite/tests/valid/key-with-pound.toml
diff --git a/tests/valid/long-float.json b/test-suite/tests/valid/long-float.json
index 8ceed47..8ceed47 100644
--- a/tests/valid/long-float.json
+++ b/test-suite/tests/valid/long-float.json
diff --git a/tests/valid/long-float.toml b/test-suite/tests/valid/long-float.toml
index 9558ae4..9558ae4 100644
--- a/tests/valid/long-float.toml
+++ b/test-suite/tests/valid/long-float.toml
diff --git a/tests/valid/long-integer.json b/test-suite/tests/valid/long-integer.json
index 16c331e..16c331e 100644
--- a/tests/valid/long-integer.json
+++ b/test-suite/tests/valid/long-integer.json
diff --git a/tests/valid/long-integer.toml b/test-suite/tests/valid/long-integer.toml
index 424a13a..424a13a 100644
--- a/tests/valid/long-integer.toml
+++ b/test-suite/tests/valid/long-integer.toml
diff --git a/tests/valid/multiline-string.json b/test-suite/tests/valid/multiline-string.json
index 075bf50..075bf50 100644
--- a/tests/valid/multiline-string.json
+++ b/test-suite/tests/valid/multiline-string.json
diff --git a/tests/valid/multiline-string.toml b/test-suite/tests/valid/multiline-string.toml
index 15b1143..15b1143 100644
--- a/tests/valid/multiline-string.toml
+++ b/test-suite/tests/valid/multiline-string.toml
diff --git a/tests/valid/raw-multiline-string.json b/test-suite/tests/valid/raw-multiline-string.json
index b43cce5..b43cce5 100644
--- a/tests/valid/raw-multiline-string.json
+++ b/test-suite/tests/valid/raw-multiline-string.json
diff --git a/tests/valid/raw-multiline-string.toml b/test-suite/tests/valid/raw-multiline-string.toml
index 8094c03..8094c03 100644
--- a/tests/valid/raw-multiline-string.toml
+++ b/test-suite/tests/valid/raw-multiline-string.toml
diff --git a/tests/valid/raw-string.json b/test-suite/tests/valid/raw-string.json
index 693ab9b..693ab9b 100644
--- a/tests/valid/raw-string.json
+++ b/test-suite/tests/valid/raw-string.json
diff --git a/tests/valid/raw-string.toml b/test-suite/tests/valid/raw-string.toml
index 92acd25..92acd25 100644
--- a/tests/valid/raw-string.toml
+++ b/test-suite/tests/valid/raw-string.toml
diff --git a/tests/valid/string-empty.json b/test-suite/tests/valid/string-empty.json
index 6c26d69..6c26d69 100644
--- a/tests/valid/string-empty.json
+++ b/test-suite/tests/valid/string-empty.json
diff --git a/tests/valid/string-empty.toml b/test-suite/tests/valid/string-empty.toml
index e37e681..e37e681 100644
--- a/tests/valid/string-empty.toml
+++ b/test-suite/tests/valid/string-empty.toml
diff --git a/tests/valid/string-escapes.json b/test-suite/tests/valid/string-escapes.json
index 62dac51..62dac51 100644
--- a/tests/valid/string-escapes.json
+++ b/test-suite/tests/valid/string-escapes.json
diff --git a/tests/valid/string-escapes.toml b/test-suite/tests/valid/string-escapes.toml
index c5d4954..c5d4954 100644
--- a/tests/valid/string-escapes.toml
+++ b/test-suite/tests/valid/string-escapes.toml
diff --git a/tests/valid/string-simple.json b/test-suite/tests/valid/string-simple.json
index 2e05f99..2e05f99 100644
--- a/tests/valid/string-simple.json
+++ b/test-suite/tests/valid/string-simple.json
diff --git a/tests/valid/string-simple.toml b/test-suite/tests/valid/string-simple.toml
index e17ade6..e17ade6 100644
--- a/tests/valid/string-simple.toml
+++ b/test-suite/tests/valid/string-simple.toml
diff --git a/tests/valid/string-with-pound.json b/test-suite/tests/valid/string-with-pound.json
index 33cdc9c..33cdc9c 100644
--- a/tests/valid/string-with-pound.json
+++ b/test-suite/tests/valid/string-with-pound.json
diff --git a/tests/valid/string-with-pound.toml b/test-suite/tests/valid/string-with-pound.toml
index 5fd8746..5fd8746 100644
--- a/tests/valid/string-with-pound.toml
+++ b/test-suite/tests/valid/string-with-pound.toml
diff --git a/tests/valid/table-array-implicit.json b/test-suite/tests/valid/table-array-implicit.json
index 32e4640..32e4640 100644
--- a/tests/valid/table-array-implicit.json
+++ b/test-suite/tests/valid/table-array-implicit.json
diff --git a/tests/valid/table-array-implicit.toml b/test-suite/tests/valid/table-array-implicit.toml
index 3157ac9..3157ac9 100644
--- a/tests/valid/table-array-implicit.toml
+++ b/test-suite/tests/valid/table-array-implicit.toml
diff --git a/tests/valid/table-array-many.json b/test-suite/tests/valid/table-array-many.json
index 84df2da..84df2da 100644
--- a/tests/valid/table-array-many.json
+++ b/test-suite/tests/valid/table-array-many.json
diff --git a/tests/valid/table-array-many.toml b/test-suite/tests/valid/table-array-many.toml
index 46062be..46062be 100644
--- a/tests/valid/table-array-many.toml
+++ b/test-suite/tests/valid/table-array-many.toml
diff --git a/tests/valid/table-array-nest-no-keys.json b/test-suite/tests/valid/table-array-nest-no-keys.json
index 7537b1a..7537b1a 100644
--- a/tests/valid/table-array-nest-no-keys.json
+++ b/test-suite/tests/valid/table-array-nest-no-keys.json
diff --git a/tests/valid/table-array-nest-no-keys.toml b/test-suite/tests/valid/table-array-nest-no-keys.toml
index ad6eb10..ad6eb10 100644
--- a/tests/valid/table-array-nest-no-keys.toml
+++ b/test-suite/tests/valid/table-array-nest-no-keys.toml
diff --git a/tests/valid/table-array-nest.json b/test-suite/tests/valid/table-array-nest.json
index c117afa..c117afa 100644
--- a/tests/valid/table-array-nest.json
+++ b/test-suite/tests/valid/table-array-nest.json
diff --git a/tests/valid/table-array-nest.toml b/test-suite/tests/valid/table-array-nest.toml
index d659a3d..d659a3d 100644
--- a/tests/valid/table-array-nest.toml
+++ b/test-suite/tests/valid/table-array-nest.toml
diff --git a/tests/valid/table-array-one.json b/test-suite/tests/valid/table-array-one.json
index d75faae..d75faae 100644
--- a/tests/valid/table-array-one.json
+++ b/test-suite/tests/valid/table-array-one.json
diff --git a/tests/valid/table-array-one.toml b/test-suite/tests/valid/table-array-one.toml
index cd7e1b6..cd7e1b6 100644
--- a/tests/valid/table-array-one.toml
+++ b/test-suite/tests/valid/table-array-one.toml
diff --git a/tests/valid/table-empty.json b/test-suite/tests/valid/table-empty.json
index 6f3873a..6f3873a 100644
--- a/tests/valid/table-empty.json
+++ b/test-suite/tests/valid/table-empty.json
diff --git a/tests/valid/table-empty.toml b/test-suite/tests/valid/table-empty.toml
index 8bb6a0a..8bb6a0a 100644
--- a/tests/valid/table-empty.toml
+++ b/test-suite/tests/valid/table-empty.toml
diff --git a/tests/valid/table-multi-empty.json b/test-suite/tests/valid/table-multi-empty.json
index a6e17c9..a6e17c9 100644
--- a/tests/valid/table-multi-empty.json
+++ b/test-suite/tests/valid/table-multi-empty.json
diff --git a/tests/valid/table-multi-empty.toml b/test-suite/tests/valid/table-multi-empty.toml
index 2266ed2..2266ed2 100644
--- a/tests/valid/table-multi-empty.toml
+++ b/test-suite/tests/valid/table-multi-empty.toml
diff --git a/tests/valid/table-sub-empty.json b/test-suite/tests/valid/table-sub-empty.json
index 9787770..9787770 100644
--- a/tests/valid/table-sub-empty.json
+++ b/test-suite/tests/valid/table-sub-empty.json
diff --git a/tests/valid/table-sub-empty.toml b/test-suite/tests/valid/table-sub-empty.toml
index 70b7fe1..70b7fe1 100644
--- a/tests/valid/table-sub-empty.toml
+++ b/test-suite/tests/valid/table-sub-empty.toml
diff --git a/tests/valid/table-whitespace.json b/test-suite/tests/valid/table-whitespace.json
index 3a73ec8..3a73ec8 100644
--- a/tests/valid/table-whitespace.json
+++ b/test-suite/tests/valid/table-whitespace.json
diff --git a/tests/valid/table-whitespace.toml b/test-suite/tests/valid/table-whitespace.toml
index daf881d..daf881d 100644
--- a/tests/valid/table-whitespace.toml
+++ b/test-suite/tests/valid/table-whitespace.toml
diff --git a/tests/valid/table-with-pound.json b/test-suite/tests/valid/table-with-pound.json
index 5e594e4..5e594e4 100644
--- a/tests/valid/table-with-pound.json
+++ b/test-suite/tests/valid/table-with-pound.json
diff --git a/tests/valid/table-with-pound.toml b/test-suite/tests/valid/table-with-pound.toml
index 33f2c4f..33f2c4f 100644
--- a/tests/valid/table-with-pound.toml
+++ b/test-suite/tests/valid/table-with-pound.toml
diff --git a/tests/valid/unicode-escape.json b/test-suite/tests/valid/unicode-escape.json
index 32948c6..32948c6 100644
--- a/tests/valid/unicode-escape.json
+++ b/test-suite/tests/valid/unicode-escape.json
diff --git a/tests/valid/unicode-escape.toml b/test-suite/tests/valid/unicode-escape.toml
index c0d5a25..c0d5a25 100644
--- a/tests/valid/unicode-escape.toml
+++ b/test-suite/tests/valid/unicode-escape.toml
diff --git a/tests/valid/unicode-literal.json b/test-suite/tests/valid/unicode-literal.json
index 00aa2f8..00aa2f8 100644
--- a/tests/valid/unicode-literal.json
+++ b/test-suite/tests/valid/unicode-literal.json
diff --git a/tests/valid/unicode-literal.toml b/test-suite/tests/valid/unicode-literal.toml
index c65723c..c65723c 100644
--- a/tests/valid/unicode-literal.toml
+++ b/test-suite/tests/valid/unicode-literal.toml