aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Vander Stoep <jeffv@google.com>2024-02-07 21:01:51 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2024-02-07 21:01:51 +0000
commitd3caacd55ecaf28f69cdb1fe3e06a356a604bc32 (patch)
tree68c2b5426766f3a2bc770792db8644d83602b4a5
parent20db17911dc856eefef9058804f30401ed0a3e7b (diff)
parent4fa63b698c83d34a9c686ee180b7519eedcb6b94 (diff)
downloadtoml_edit-d3caacd55ecaf28f69cdb1fe3e06a356a604bc32.tar.gz
Upgrade toml_edit to 0.22.4 am: 4fa63b698cHEADmastermain
Original change: https://android-review.googlesource.com/c/platform/external/rust/crates/toml_edit/+/2952815 Change-Id: I778f4cb6cb8798cb68426106e41fd34665789602 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--.cargo_vcs_info.json2
-rw-r--r--Android.bp4
-rw-r--r--Cargo.lock82
-rw-r--r--Cargo.toml40
-rw-r--r--Cargo.toml.orig29
-rw-r--r--LICENSE-APACHE403
-rw-r--r--LICENSE-MIT4
-rw-r--r--METADATA22
-rw-r--r--README.md11
-rw-r--r--src/array.rs59
-rw-r--r--src/array_of_tables.rs1
-rw-r--r--src/de/key.rs13
-rw-r--r--src/de/mod.rs3
-rw-r--r--src/de/table.rs8
-rw-r--r--src/de/table_enum.rs76
-rw-r--r--src/de/value.rs3
-rw-r--r--src/document.rs4
-rw-r--r--src/encode.rs387
-rw-r--r--src/error.rs (renamed from src/parser/errors.rs)86
-rw-r--r--src/inline_table.rs74
-rw-r--r--src/item.rs13
-rw-r--r--src/key.rs134
-rw-r--r--src/lib.rs17
-rw-r--r--src/parser/array.rs2
-rw-r--r--src/parser/datetime.rs40
-rw-r--r--src/parser/error.rs87
-rw-r--r--src/parser/inline_table.rs27
-rw-r--r--src/parser/key.rs36
-rw-r--r--src/parser/mod.rs18
-rw-r--r--src/parser/numbers.rs11
-rw-r--r--src/parser/state.rs23
-rw-r--r--src/parser/strings.rs12
-rw-r--r--src/parser/trivia.rs2
-rw-r--r--src/parser/value.rs4
-rw-r--r--src/raw_string.rs2
-rw-r--r--src/repr.rs22
-rw-r--r--src/ser/map.rs271
-rw-r--r--src/ser/mod.rs5
-rw-r--r--src/ser/value.rs28
-rw-r--r--src/table.rs55
-rw-r--r--src/value.rs12
-rw-r--r--src/visit.rs4
-rw-r--r--src/visit_mut.rs6
-rw-r--r--tests/decoder_compliance.rs12
-rw-r--r--tests/encoder_compliance.rs6
-rw-r--r--tests/fixtures/invalid/array/array.stderr6
-rw-r--r--tests/fixtures/invalid/array/double-comma-1.stderr6
-rw-r--r--tests/fixtures/invalid/array/double-comma-2.stderr6
-rw-r--r--tests/fixtures/invalid/array/extend-defined-aot.stderr5
-rw-r--r--tests/fixtures/invalid/array/missing-separator-1.stderr6
-rw-r--r--tests/fixtures/invalid/array/missing-separator-2.stderr (renamed from tests/fixtures/invalid/array/missing-separator.stderr)0
-rw-r--r--tests/fixtures/invalid/array/no-close-1.stderr (renamed from tests/fixtures/invalid/array/no-close.stderr)2
-rw-r--r--tests/fixtures/invalid/array/no-close-2.stderr6
-rw-r--r--tests/fixtures/invalid/array/no-close-3.stderr6
-rw-r--r--tests/fixtures/invalid/array/no-close-4.stderr6
-rw-r--r--tests/fixtures/invalid/array/no-close-5.stderr6
-rw-r--r--tests/fixtures/invalid/array/no-close-6.stderr6
-rw-r--r--tests/fixtures/invalid/array/no-close-7.stderr6
-rw-r--r--tests/fixtures/invalid/array/no-close-8.stderr6
-rw-r--r--tests/fixtures/invalid/array/no-close-table-1.stderr (renamed from tests/fixtures/invalid/array/no-close-table.stderr)0
-rw-r--r--tests/fixtures/invalid/array/no-comma-1.stderr6
-rw-r--r--tests/fixtures/invalid/array/no-comma-2.stderr6
-rw-r--r--tests/fixtures/invalid/array/no-comma-3.stderr6
-rw-r--r--tests/fixtures/invalid/array/only-comma-1.stderr6
-rw-r--r--tests/fixtures/invalid/array/only-comma-2.stderr6
-rw-r--r--tests/fixtures/invalid/bool/almost-false-with-extra.stderr6
-rw-r--r--tests/fixtures/invalid/bool/almost-false.stderr6
-rw-r--r--tests/fixtures/invalid/bool/almost-true-with-extra.stderr6
-rw-r--r--tests/fixtures/invalid/bool/almost-true.stderr6
-rw-r--r--tests/fixtures/invalid/bool/bool.stderr6
-rw-r--r--tests/fixtures/invalid/bool/capitalized-false.stderr6
-rw-r--r--tests/fixtures/invalid/bool/capitalized-true.stderr6
-rw-r--r--tests/fixtures/invalid/bool/just-f.stderr6
-rw-r--r--tests/fixtures/invalid/bool/just-t.stderr6
-rw-r--r--tests/fixtures/invalid/bool/mixed-case-false.stderr6
-rw-r--r--tests/fixtures/invalid/bool/mixed-case-true.stderr6
-rw-r--r--tests/fixtures/invalid/bool/mixed-case.stderr6
-rw-r--r--tests/fixtures/invalid/bool/starting-same-false.stderr6
-rw-r--r--tests/fixtures/invalid/bool/starting-same-true.stderr6
-rw-r--r--tests/fixtures/invalid/bool/wrong-case-false.stderr6
-rw-r--r--tests/fixtures/invalid/bool/wrong-case-true.stderr6
-rw-r--r--tests/fixtures/invalid/control/bare-formfeed.stderr6
-rw-r--r--tests/fixtures/invalid/control/bare-null.stderrbin126 -> 142 bytes
-rw-r--r--tests/fixtures/invalid/control/comment-cr.stderr6
-rw-r--r--tests/fixtures/invalid/control/comment-del.stderr6
-rw-r--r--tests/fixtures/invalid/control/comment-ff.stderr5
-rw-r--r--tests/fixtures/invalid/control/comment-lf.stderr6
-rw-r--r--tests/fixtures/invalid/control/comment-null.stderrbin124 -> 128 bytes
-rw-r--r--tests/fixtures/invalid/control/comment-us.stderr6
-rw-r--r--tests/fixtures/invalid/control/control.stderr9
-rw-r--r--tests/fixtures/invalid/control/multi-cr.stderr6
-rw-r--r--tests/fixtures/invalid/control/multi-del.stderr6
-rw-r--r--tests/fixtures/invalid/control/multi-lf.stderr6
-rw-r--r--tests/fixtures/invalid/control/multi-us.stderr6
-rw-r--r--tests/fixtures/invalid/control/rawmulti-cd.stderr6
-rw-r--r--tests/fixtures/invalid/control/rawmulti-del.stderr6
-rw-r--r--tests/fixtures/invalid/control/rawmulti-lf.stderr6
-rw-r--r--tests/fixtures/invalid/control/rawmulti-us.stderr6
-rw-r--r--tests/fixtures/invalid/control/rawstring-cr.stderr6
-rw-r--r--tests/fixtures/invalid/control/rawstring-del.stderr6
-rw-r--r--tests/fixtures/invalid/control/rawstring-lf.stderr6
-rw-r--r--tests/fixtures/invalid/control/rawstring-us.stderr6
-rw-r--r--tests/fixtures/invalid/control/string-bs.stderr6
-rw-r--r--tests/fixtures/invalid/control/string-cr.stderr6
-rw-r--r--tests/fixtures/invalid/control/string-del.stderr6
-rw-r--r--tests/fixtures/invalid/control/string-lf.stderr6
-rw-r--r--tests/fixtures/invalid/control/string-us.stderr6
-rw-r--r--tests/fixtures/invalid/datetime/feb-29.stderr6
-rw-r--r--tests/fixtures/invalid/datetime/feb-30.stderr6
-rw-r--r--tests/fixtures/invalid/datetime/no-leads-month.stderr5
-rw-r--r--tests/fixtures/invalid/datetime/time-no-leads.stderr6
-rw-r--r--tests/fixtures/invalid/datetime/y10k.stderr5
-rw-r--r--tests/fixtures/invalid/encoding/bad-codepoint.stderr1
-rw-r--r--tests/fixtures/invalid/encoding/utf16-comment.stderr (renamed from tests/fixtures/invalid/encoding/utf16.stderr)bin105 -> 105 bytes
-rw-r--r--tests/fixtures/invalid/encoding/utf16-key.stderrbin0 -> 79 bytes
-rw-r--r--tests/fixtures/invalid/float/exp-point-3.stderr6
-rw-r--r--tests/fixtures/invalid/float/exp-trailing-us-1.stderr6
-rw-r--r--tests/fixtures/invalid/float/exp-trailing-us-2.stderr6
-rw-r--r--tests/fixtures/invalid/float/exp-trailing-us.stderr7
-rw-r--r--tests/fixtures/invalid/float/inf-capital.stderr6
-rw-r--r--tests/fixtures/invalid/float/nan-capital.stderr6
-rw-r--r--tests/fixtures/invalid/float/trailing-us-exp-1.stderr6
-rw-r--r--tests/fixtures/invalid/float/trailing-us-exp-2.stderr6
-rw-r--r--tests/fixtures/invalid/float/trailing-us-exp.stderr6
-rw-r--r--tests/fixtures/invalid/inline-table/bad-key-syntax.stderr6
-rw-r--r--tests/fixtures/invalid/inline-table/duplicate-key-1.stderr (renamed from tests/fixtures/invalid/inline-table/duplicate-key.stderr)0
-rw-r--r--tests/fixtures/invalid/inline-table/duplicate-key-2.stderr5
-rw-r--r--tests/fixtures/invalid/inline-table/duplicate-key-3.stderr5
-rw-r--r--tests/fixtures/invalid/inline-table/duplicate-key-4.stderr5
-rw-r--r--tests/fixtures/invalid/inline-table/empty-1.stderr (renamed from tests/fixtures/invalid/inline-table/empty.stderr)0
-rw-r--r--tests/fixtures/invalid/inline-table/empty-2.stderr6
-rw-r--r--tests/fixtures/invalid/inline-table/empty-3.stderr6
-rw-r--r--tests/fixtures/invalid/inline-table/no-close-1.stderr6
-rw-r--r--tests/fixtures/invalid/inline-table/no-close-2.stderr6
-rw-r--r--tests/fixtures/invalid/inline-table/no-comma-1.stderr (renamed from tests/fixtures/invalid/inline-table/no-comma.stderr)0
-rw-r--r--tests/fixtures/invalid/inline-table/no-comma-2.stderr6
-rw-r--r--tests/fixtures/invalid/inline-table/overwrite-01.stderr (renamed from tests/fixtures/invalid/inline-table/overwrite.stderr)0
-rw-r--r--tests/fixtures/invalid/inline-table/overwrite-02.stderr (renamed from tests/fixtures/invalid/inline-table/add.stderr)0
-rw-r--r--tests/fixtures/invalid/inline-table/overwrite-03.stderr5
-rw-r--r--tests/fixtures/invalid/inline-table/overwrite-04.stderr6
-rw-r--r--tests/fixtures/invalid/inline-table/overwrite-05.stderr6
-rw-r--r--tests/fixtures/invalid/inline-table/overwrite-06.stderr5
-rw-r--r--tests/fixtures/invalid/inline-table/overwrite-07.stderr5
-rw-r--r--tests/fixtures/invalid/inline-table/overwrite-08.stderr5
-rw-r--r--tests/fixtures/invalid/inline-table/overwrite-09.stderr5
-rw-r--r--tests/fixtures/invalid/inline-table/overwrite-10.stderr5
-rw-r--r--tests/fixtures/invalid/integer/invalid-hex-1.stderr5
-rw-r--r--tests/fixtures/invalid/integer/invalid-hex-2.stderr5
-rw-r--r--tests/fixtures/invalid/integer/leading-us-bin.stderr2
-rw-r--r--tests/fixtures/invalid/integer/leading-us-hex.stderr2
-rw-r--r--tests/fixtures/invalid/integer/negative-oct.stderr2
-rw-r--r--tests/fixtures/invalid/integer/positive-oct.stderr2
-rw-r--r--tests/fixtures/invalid/key/dotted-redefine-table-1.stderr5
-rw-r--r--tests/fixtures/invalid/key/dotted-redefine-table-2.stderr (renamed from tests/fixtures/invalid/key/dotted-redefine-table.stderr)0
-rw-r--r--tests/fixtures/invalid/key/duplicate-keys-1.stderr5
-rw-r--r--tests/fixtures/invalid/key/duplicate-keys-2.stderr (renamed from tests/fixtures/invalid/key/duplicate-keys.stderr)0
-rw-r--r--tests/fixtures/invalid/key/duplicate-keys-3.stderr5
-rw-r--r--tests/fixtures/invalid/key/duplicate-keys-4.stderr5
-rw-r--r--tests/fixtures/invalid/key/duplicate.stderr5
-rw-r--r--tests/fixtures/invalid/key/end-in-escape.stderr6
-rw-r--r--tests/fixtures/invalid/key/newline-1.stderr (renamed from tests/fixtures/invalid/key/newline.stderr)0
-rw-r--r--tests/fixtures/invalid/key/newline-2.stderr5
-rw-r--r--tests/fixtures/invalid/key/newline-3.stderr5
-rw-r--r--tests/fixtures/invalid/key/newline-4.stderr (renamed from tests/fixtures/invalid/key/multiline.stderr)0
-rw-r--r--tests/fixtures/invalid/key/newline-5.stderr5
-rw-r--r--tests/fixtures/invalid/key/two-equals-1.stderr (renamed from tests/fixtures/invalid/key/two-equals.stderr)0
-rw-r--r--tests/fixtures/invalid/key/two-equals-2.stderr (renamed from tests/fixtures/invalid/key/two-equals2.stderr)0
-rw-r--r--tests/fixtures/invalid/key/two-equals-3.stderr (renamed from tests/fixtures/invalid/key/two-equals3.stderr)0
-rw-r--r--tests/fixtures/invalid/key/without-value-5.stderr5
-rw-r--r--tests/fixtures/invalid/key/without-value-6.stderr6
-rw-r--r--tests/fixtures/invalid/key/without-value-7.stderr5
-rw-r--r--tests/fixtures/invalid/local-date/feb-29.stderr6
-rw-r--r--tests/fixtures/invalid/local-date/feb-30.stderr6
-rw-r--r--tests/fixtures/invalid/local-date/mday-over.stderr6
-rw-r--r--tests/fixtures/invalid/local-date/mday-under.stderr6
-rw-r--r--tests/fixtures/invalid/local-date/month-over.stderr6
-rw-r--r--tests/fixtures/invalid/local-date/month-under.stderr6
-rw-r--r--tests/fixtures/invalid/local-date/no-leads-with-milli.stderr5
-rw-r--r--tests/fixtures/invalid/local-date/no-leads.stderr5
-rw-r--r--tests/fixtures/invalid/local-date/trailing-t.stderr (renamed from tests/fixtures/invalid/datetime/trailing-t.stderr)0
-rw-r--r--tests/fixtures/invalid/local-date/y10k.stderr5
-rw-r--r--tests/fixtures/invalid/local-datetime/feb-29.stderr6
-rw-r--r--tests/fixtures/invalid/local-datetime/feb-30.stderr6
-rw-r--r--tests/fixtures/invalid/local-datetime/hour-over.stderr5
-rw-r--r--tests/fixtures/invalid/local-datetime/mday-over.stderr6
-rw-r--r--tests/fixtures/invalid/local-datetime/mday-under.stderr6
-rw-r--r--tests/fixtures/invalid/local-datetime/minute-over.stderr6
-rw-r--r--tests/fixtures/invalid/local-datetime/month-over.stderr6
-rw-r--r--tests/fixtures/invalid/local-datetime/month-under.stderr6
-rw-r--r--tests/fixtures/invalid/local-datetime/no-leads-with-milli.stderr5
-rw-r--r--tests/fixtures/invalid/local-datetime/no-leads.stderr5
-rw-r--r--tests/fixtures/invalid/local-datetime/no-secs.stderr5
-rw-r--r--tests/fixtures/invalid/local-datetime/no-t.stderr5
-rw-r--r--tests/fixtures/invalid/local-datetime/second-over.stderr6
-rw-r--r--tests/fixtures/invalid/local-datetime/time-no-leads.stderr5
-rw-r--r--tests/fixtures/invalid/local-datetime/y10k.stderr5
-rw-r--r--tests/fixtures/invalid/local-time/hour-over.stderr5
-rw-r--r--tests/fixtures/invalid/local-time/minute-over.stderr6
-rw-r--r--tests/fixtures/invalid/local-time/no-secs.stderr5
-rw-r--r--tests/fixtures/invalid/local-time/second-over.stderr6
-rw-r--r--tests/fixtures/invalid/local-time/time-no-leads-2.stderr (renamed from tests/fixtures/invalid/datetime/time-no-leads-2.stderr)0
-rw-r--r--tests/fixtures/invalid/local-time/time-no-leads.stderr5
-rw-r--r--tests/fixtures/invalid/string/bad-codepoint.stderr6
-rw-r--r--tests/fixtures/invalid/string/bad-escape-3.stderr5
-rw-r--r--tests/fixtures/invalid/string/bad-uni-esc-1.stderr6
-rw-r--r--tests/fixtures/invalid/string/bad-uni-esc-2.stderr6
-rw-r--r--tests/fixtures/invalid/string/bad-uni-esc-3.stderr6
-rw-r--r--tests/fixtures/invalid/string/bad-uni-esc-4.stderr6
-rw-r--r--tests/fixtures/invalid/string/bad-uni-esc-5.stderr6
-rw-r--r--tests/fixtures/invalid/string/bad-uni-esc-6.stderr6
-rw-r--r--tests/fixtures/invalid/string/bad-uni-esc-7.stderr5
-rw-r--r--tests/fixtures/invalid/string/multiline-bad-escape-4.stderr5
-rw-r--r--tests/fixtures/invalid/string/multiline-escape-space-1.stderr (renamed from tests/fixtures/invalid/string/multiline-escape-space.stderr)0
-rw-r--r--tests/fixtures/invalid/string/multiline-escape-space-2.stderr6
-rw-r--r--tests/fixtures/invalid/string/multiline-lit-no-close-1.stderr5
-rw-r--r--tests/fixtures/invalid/string/multiline-lit-no-close-2.stderr5
-rw-r--r--tests/fixtures/invalid/string/multiline-lit-no-close-3.stderr5
-rw-r--r--tests/fixtures/invalid/string/multiline-lit-no-close-4.stderr5
-rw-r--r--tests/fixtures/invalid/string/multiline-no-close-1.stderr (renamed from tests/fixtures/invalid/string/multiline-no-close.stderr)0
-rw-r--r--tests/fixtures/invalid/string/multiline-no-close-3.stderr5
-rw-r--r--tests/fixtures/invalid/string/multiline-no-close-4.stderr5
-rw-r--r--tests/fixtures/invalid/string/multiline-no-close-5.stderr5
-rw-r--r--tests/fixtures/invalid/string/no-close-1.stderr (renamed from tests/fixtures/invalid/string/no-close.stderr)0
-rw-r--r--tests/fixtures/invalid/string/no-close-2.stderr5
-rw-r--r--tests/fixtures/invalid/string/no-close-3.stderr5
-rw-r--r--tests/fixtures/invalid/string/no-close-4.stderr5
-rw-r--r--tests/fixtures/invalid/string/string.stderr (renamed from tests/fixtures/invalid/string/bad-hex-esc.stderr)0
-rw-r--r--tests/fixtures/invalid/table/append-to-array-with-dotted-keys.stderr5
-rw-r--r--tests/fixtures/invalid/table/array-no-close-1.stderr (renamed from tests/fixtures/invalid/table/array-missing-bracket.stderr)0
-rw-r--r--tests/fixtures/invalid/table/array-no-close-2.stderr6
-rw-r--r--tests/fixtures/invalid/table/duplicate-key-dotted-array.stderr6
-rw-r--r--tests/fixtures/invalid/table/no-close-1.stderr6
-rw-r--r--tests/fixtures/invalid/table/no-close-2.stderr6
-rw-r--r--tests/fixtures/invalid/table/no-close-3.stderr (renamed from tests/fixtures/invalid/table/quoted-no-close.stderr)0
-rw-r--r--tests/fixtures/invalid/table/no-close-4.stderr5
-rw-r--r--tests/fixtures/invalid/table/no-close-5.stderr6
-rw-r--r--tests/fixtures/invalid/table/overwrite-array-in-parent.stderr5
-rw-r--r--tests/fixtures/invalid/table/overwrite-bool-with-array.stderr6
-rw-r--r--tests/fixtures/invalid/table/overwrite-with-deep-table.stderr6
-rw-r--r--tests/fixtures/invalid/table/redefine-1.stderr (renamed from tests/fixtures/invalid/table/redefine.stderr)0
-rw-r--r--tests/fixtures/invalid/table/redefine-2.stderr6
-rw-r--r--tests/fixtures/invalid/table/redefine-3.stderr6
-rw-r--r--tests/fixtures/invalid/table/super-twice.stderr6
-rw-r--r--tests/testsuite/edit.rs7
-rw-r--r--tests/testsuite/float.rs60
-rw-r--r--tests/testsuite/main.rs1
-rw-r--r--tests/testsuite/parse.rs26
247 files changed, 2331 insertions, 874 deletions
diff --git a/.cargo_vcs_info.json b/.cargo_vcs_info.json
index fbf4047..7288de0 100644
--- a/.cargo_vcs_info.json
+++ b/.cargo_vcs_info.json
@@ -1,6 +1,6 @@
{
"git": {
- "sha1": "5753e4fd8ddf78980c41aabaec78a935eaba93e1"
+ "sha1": "a20848d8a228605e2e4fa30b01c1a71d448de175"
},
"path_in_vcs": "crates/toml_edit"
} \ No newline at end of file
diff --git a/Android.bp b/Android.bp
index 457de19..48f9cce 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5,11 +5,13 @@ rust_library_host {
name: "libtoml_edit",
crate_name: "toml_edit",
cargo_env_compat: true,
- cargo_pkg_version: "0.19.14",
+ cargo_pkg_version: "0.22.4",
srcs: ["src/lib.rs"],
edition: "2021",
features: [
"default",
+ "display",
+ "parse",
"serde",
],
rustlibs: [
diff --git a/Cargo.lock b/Cargo.lock
index 5dfc8c2..15a049c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -184,6 +184,15 @@ dependencies = [
]
[[package]]
+name = "escape8259"
+version = "0.5.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ba4f4911e3666fcd7826997b4745c8224295a6f3072f1418c3067b97a67557ee"
+dependencies = [
+ "rustversion",
+]
+
+[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -337,6 +346,18 @@ dependencies = [
]
[[package]]
+name = "libtest-mimic"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7f0f4c6f44ecfd52e8b443f2ad18f2b996540135771561283c2352ce56a1c70b"
+dependencies = [
+ "clap",
+ "escape8259",
+ "termcolor",
+ "threadpool",
+]
+
+[[package]]
name = "linux-raw-sys"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -430,18 +451,18 @@ dependencies = [
[[package]]
name = "proc-macro2"
-version = "1.0.56"
+version = "1.0.67"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
+checksum = "3d433d9f1a3e8c1263d9456598b16fec66f4acc9a74dacffd35c7bb09b3a1328"
dependencies = [
"unicode-ident",
]
[[package]]
name = "quote"
-version = "1.0.26"
+version = "1.0.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
+checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
dependencies = [
"proc-macro2",
]
@@ -478,10 +499,16 @@ dependencies = [
]
[[package]]
+name = "rustversion"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4"
+
+[[package]]
name = "ryu"
-version = "1.0.11"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
+checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741"
[[package]]
name = "same-file"
@@ -494,22 +521,22 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.160"
+version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c"
+checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.160"
+version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df"
+checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
- "syn 2.0.15",
+ "syn 2.0.41",
]
[[package]]
@@ -525,9 +552,9 @@ dependencies = [
[[package]]
name = "serde_spanned"
-version = "0.6.3"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
+checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1"
dependencies = [
"serde",
]
@@ -547,7 +574,7 @@ dependencies = [
"anstream",
"anstyle",
"ignore",
- "libtest-mimic",
+ "libtest-mimic 0.6.0",
"normalize-line-endings",
"similar",
"snapbox-macros",
@@ -587,9 +614,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "2.0.15"
+version = "2.0.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
+checksum = "44c8b28c477cc3bf0e7966561e3460130e1255f7a1cf71931075f1c5e7a7e269"
dependencies = [
"proc-macro2",
"quote",
@@ -625,52 +652,53 @@ dependencies = [
[[package]]
name = "toml-test"
-version = "0.3.4"
+version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37351256790aa1dbd6d60f4ff08e55e7f372e292f3e9040d6e077463d9a779c3"
+checksum = "1ec3892835fb31e181a87e1758275a64b0d7c6c9e9618aeb61a647bd487314c0"
dependencies = [
"chrono",
+ "ryu",
"serde",
"serde_json",
]
[[package]]
name = "toml-test-data"
-version = "1.3.0"
+version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "93f351b6d6005ee802b0d4a53ca1cdf05636f441df4d299e62cba57f1da52646"
+checksum = "c6b5bad99e813ce8c67d1d67c9b9f37c8451933f45eae0ab2b3583975f1cc15d"
dependencies = [
"include_dir",
]
[[package]]
name = "toml-test-harness"
-version = "0.4.3"
+version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0e00fda5710922fe6b3005bf6a5050c303d6f9625249c37b7386e8818f4af675"
+checksum = "1be4b8d761dee51b4694e9f1d622a1d7f9c135a8b8265459e16d09ac5b16a05d"
dependencies = [
"ignore",
- "libtest-mimic",
+ "libtest-mimic 0.6.0",
"toml-test",
"toml-test-data",
]
[[package]]
name = "toml_datetime"
-version = "0.6.3"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
+checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
-version = "0.19.14"
+version = "0.22.4"
dependencies = [
"indexmap",
"kstring",
- "libtest-mimic",
+ "libtest-mimic 0.7.0",
"serde",
"serde_json",
"serde_spanned",
diff --git a/Cargo.toml b/Cargo.toml
index 26929ff..2e27069 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -11,9 +11,9 @@
[package]
edition = "2021"
-rust-version = "1.64.0"
+rust-version = "1.69"
name = "toml_edit"
-version = "0.19.14"
+version = "0.22.4"
authors = [
"Andronik Ordian <write@reusable.software>",
"Ed Page <eopage@gmail.com>",
@@ -29,6 +29,7 @@ include = [
"examples/**/*",
"tests/**/*",
]
+autotests = false
description = "Yet another format-preserving TOML parser."
readme = "README.md"
keywords = [
@@ -92,18 +93,35 @@ search = "<!-- next-url -->"
[[example]]
name = "visit"
test = true
+required-features = [
+ "parse",
+ "display",
+]
+
+[[test]]
+name = "testsuite"
+required-features = [
+ "parse",
+ "display",
+]
[[test]]
name = "decoder_compliance"
harness = false
+required-features = ["parse"]
[[test]]
name = "encoder_compliance"
harness = false
+required-features = [
+ "parse",
+ "display",
+]
[[test]]
name = "invalid"
harness = false
+required-features = ["parse"]
[dependencies.indexmap]
version = "2.0.0"
@@ -119,18 +137,19 @@ version = "1.0.145"
optional = true
[dependencies.serde_spanned]
-version = "0.6.3"
+version = "0.6.5"
features = ["serde"]
optional = true
[dependencies.toml_datetime]
-version = "0.6.3"
+version = "0.6.5"
[dependencies.winnow]
version = "0.5.0"
+optional = true
[dev-dependencies.libtest-mimic]
-version = "0.6.0"
+version = "0.7.0"
[dev-dependencies.serde_json]
version = "1.0.96"
@@ -140,13 +159,18 @@ version = "0.4.11"
features = ["harness"]
[dev-dependencies.toml-test-data]
-version = "1.3.0"
+version = "1.8.0"
[dev-dependencies.toml-test-harness]
-version = "0.4.3"
+version = "0.4.8"
[features]
-default = []
+default = [
+ "parse",
+ "display",
+]
+display = []
+parse = ["dep:winnow"]
perf = ["dep:kstring"]
serde = [
"dep:serde",
diff --git a/Cargo.toml.orig b/Cargo.toml.orig
index cda679f..9ab60c1 100644
--- a/Cargo.toml.orig
+++ b/Cargo.toml.orig
@@ -1,10 +1,11 @@
[package]
name = "toml_edit"
-version = "0.19.14"
+version = "0.22.4"
keywords = ["encoding", "toml"]
categories = ["encoding", "parser-implementations", "parsing", "config"]
description = "Yet another format-preserving TOML parser."
authors = ["Andronik Ordian <write@reusable.software>", "Ed Page <eopage@gmail.com>"]
+autotests = false
repository.workspace = true
license.workspace = true
edition.workspace = true
@@ -12,8 +13,8 @@ rust-version.workspace = true
include.workspace = true
[package.metadata.docs.rs]
-rustdoc-args = ["--cfg", "docsrs"]
features = ["serde"]
+rustdoc-args = ["--cfg", "docsrs"]
[package.metadata.release]
tag-name = "v{{version}}"
@@ -26,7 +27,9 @@ pre-release-replacements = [
]
[features]
-default = []
+default = ["parse", "display"]
+parse = ["dep:winnow"]
+display = []
perf = ["dep:kstring"]
serde = ["dep:serde", "toml_datetime/serde", "dep:serde_spanned"]
# Provide a method disable_recursion_limit to parse arbitrarily deep structures
@@ -38,31 +41,39 @@ unbounded = []
[dependencies]
indexmap = { version = "2.0.0", features = ["std"] }
-winnow = "0.5.0"
+winnow = { version = "0.5.0", optional = true }
serde = { version = "1.0.145", optional = true }
kstring = { version = "2.0.0", features = ["max_inline"], optional = true }
-toml_datetime = { version = "0.6.3", path = "../toml_datetime" }
-serde_spanned = { version = "0.6.3", path = "../serde_spanned", features = ["serde"], optional = true }
+toml_datetime = { version = "0.6.5", path = "../toml_datetime" }
+serde_spanned = { version = "0.6.5", path = "../serde_spanned", features = ["serde"], optional = true }
[dev-dependencies]
serde_json = "1.0.96"
-toml-test-harness = "0.4.3"
-toml-test-data = "1.3.0"
-libtest-mimic = "0.6.0"
+toml-test-harness = "0.4.8"
+toml-test-data = "1.8.0"
+libtest-mimic = "0.7.0"
snapbox = { version = "0.4.11", features = ["harness"] }
[[test]]
+name = "testsuite"
+required-features = ["parse", "display"]
+
+[[test]]
name = "decoder_compliance"
+required-features = ["parse"]
harness = false
[[test]]
name = "encoder_compliance"
+required-features = ["parse", "display"]
harness = false
[[test]]
name = "invalid"
+required-features = ["parse"]
harness = false
[[example]]
name = "visit"
+required-features = ["parse", "display"]
test = true
diff --git a/LICENSE-APACHE b/LICENSE-APACHE
index 16fe87b..8f71f43 100644
--- a/LICENSE-APACHE
+++ b/LICENSE-APACHE
@@ -1,201 +1,202 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
diff --git a/LICENSE-MIT b/LICENSE-MIT
index b9e61a2..a2d0108 100644
--- a/LICENSE-MIT
+++ b/LICENSE-MIT
@@ -1,6 +1,4 @@
-MIT License
-
-Copyright (c) 2017 Andronik Ordian
+Copyright (c) Individual contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/METADATA b/METADATA
index 6a96df6..6c3f465 100644
--- a/METADATA
+++ b/METADATA
@@ -1,20 +1,24 @@
+# This project was upgraded with external_updater.
+# Usage: tools/external_updater/updater.sh update external/rust/crates/toml_edit
+# For more info, check https://cs.android.com/android/platform/superproject/+/main:tools/external_updater/README.md
+
name: "toml_edit"
description: "Yet another format-preserving TOML parser."
third_party {
+ license_type: NOTICE
+ last_upgrade_date {
+ year: 2024
+ month: 2
+ day: 7
+ }
identifier {
type: "crates.io"
- value: "https://crates.io/crates/toml_edit"
+ value: "https://static.crates.io/crates/toml_edit/toml_edit-0.22.4.crate"
+ version: "0.19.14"
}
identifier {
type: "Archive"
value: "https://static.crates.io/crates/toml_edit/toml_edit-0.19.14.crate"
- }
- version: "0.19.14"
- # Dual-licensed, using the least restrictive per go/thirdpartylicenses#same.
- license_type: NOTICE
- last_upgrade_date {
- year: 2023
- month: 8
- day: 23
+ version: "0.22.4"
}
}
diff --git a/README.md b/README.md
index f1c74ee..b6d1275 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# toml_edit
-[![Build Status](https://github.com/ordian/toml_edit/workflows/Continuous%20integration/badge.svg)](https://github.com/ordian/toml_edit/actions)
-[![codecov](https://codecov.io/gh/ordian/toml_edit/branch/master/graph/badge.svg)](https://codecov.io/gh/ordian/toml_edit)
+[![Build Status](https://github.com/toml-rs/toml/workflows/Continuous%20integration/badge.svg)](https://github.com/toml-rs/toml/actions)
+[![codecov](https://codecov.io/gh/toml-rs/toml/branch/master/graph/badge.svg)](https://codecov.io/gh/toml-rs/toml)
[![crates.io](https://img.shields.io/crates/v/toml_edit.svg)](https://crates.io/crates/toml_edit)
[![docs](https://docs.rs/toml_edit/badge.svg)](https://docs.rs/toml_edit)
[![Join the chat at https://gitter.im/toml_edit/Lobby](https://badges.gitter.im/a.svg)](https://gitter.im/toml_edit/Lobby)
@@ -9,7 +9,7 @@
This crate allows you to parse and modify toml
documents, while preserving comments, spaces *and
-relative order* or items.
+relative order* of items.
`toml_edit` is primarily tailored for [cargo-edit](https://github.com/killercup/cargo-edit/) needs.
@@ -42,8 +42,7 @@ c = { d = "hello" }
Things it does not preserve:
-* Scattered array of tables (tables are reordered by default, see [test]).
-* Order of dotted keys, see [issue](https://github.com/ordian/toml_edit/issues/163).
+* Order of dotted keys, see [issue](https://github.com/toml-rs/toml/issues/163).
## License
@@ -55,5 +54,3 @@ Licensed under either of
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
-
-[test]: https://github.com/ordian/toml_edit/blob/f09bd5d075fdb7d2ef8d9bb3270a34506c276753/tests/test_valid.rs#L84
diff --git a/src/array.rs b/src/array.rs
index 045b451..377f676 100644
--- a/src/array.rs
+++ b/src/array.rs
@@ -183,9 +183,11 @@ impl Array {
/// # Examples
///
/// ```rust
+ /// # #[cfg(feature = "parse")] {
/// let formatted_value = "'literal'".parse::<toml_edit::Value>().unwrap();
/// let mut arr = toml_edit::Array::new();
/// arr.push_formatted(formatted_value);
+ /// # }
/// ```
pub fn push_formatted(&mut self, v: Value) {
self.values.push(Item::Value(v));
@@ -223,12 +225,14 @@ impl Array {
/// # Examples
///
/// ```rust
+ /// # #[cfg(feature = "parse")] {
/// let mut arr = toml_edit::Array::new();
/// arr.push(1);
/// arr.push("foo");
///
/// let formatted_value = "'start'".parse::<toml_edit::Value>().unwrap();
/// arr.insert_formatted(0, formatted_value);
+ /// # }
/// ```
pub fn insert_formatted(&mut self, index: usize, v: Value) {
self.values.insert(index, Item::Value(v))
@@ -269,12 +273,14 @@ impl Array {
/// # Examples
///
/// ```rust
+ /// # #[cfg(feature = "parse")] {
/// let mut arr = toml_edit::Array::new();
/// arr.push(1);
/// arr.push("foo");
///
/// let formatted_value = "'start'".parse::<toml_edit::Value>().unwrap();
/// arr.replace_formatted(0, formatted_value);
+ /// # }
/// ```
pub fn replace_formatted(&mut self, index: usize, v: Value) -> Value {
match mem::replace(&mut self.values[index], Item::Value(v)) {
@@ -317,6 +323,56 @@ impl Array {
.retain(|item| item.as_value().map(&mut keep).unwrap_or(false));
}
+ /// Sorts the slice with a comparator function.
+ ///
+ /// This sort is stable (i.e., does not reorder equal elements) and *O*(*n* \* log(*n*)) worst-case.
+ ///
+ /// The comparator function must define a total ordering for the elements in the slice. If
+ /// the ordering is not total, the order of the elements is unspecified. An order is a
+ /// total order if it is (for all `a`, `b` and `c`):
+ ///
+ /// * total and antisymmetric: exactly one of `a < b`, `a == b` or `a > b` is true, and
+ /// * transitive, `a < b` and `b < c` implies `a < c`. The same must hold for both `==` and `>`.
+ ///
+ /// For example, while [`f64`] doesn't implement [`Ord`] because `NaN != NaN`, we can use
+ /// `partial_cmp` as our sort function when we know the slice doesn't contain a `NaN`.
+ #[inline]
+ pub fn sort_by<F>(&mut self, mut compare: F)
+ where
+ F: FnMut(&Value, &Value) -> std::cmp::Ordering,
+ {
+ self.values.sort_by(move |lhs, rhs| {
+ let lhs = lhs.as_value();
+ let rhs = rhs.as_value();
+ match (lhs, rhs) {
+ (None, None) => std::cmp::Ordering::Equal,
+ (Some(_), None) => std::cmp::Ordering::Greater,
+ (None, Some(_)) => std::cmp::Ordering::Less,
+ (Some(lhs), Some(rhs)) => compare(lhs, rhs),
+ }
+ })
+ }
+
+ /// Sorts the array with a key extraction function.
+ ///
+ /// This sort is stable (i.e., does not reorder equal elements) and *O*(*m* \* *n* \* log(*n*))
+ /// worst-case, where the key function is *O*(*m*).
+ #[inline]
+ pub fn sort_by_key<K, F>(&mut self, mut f: F)
+ where
+ F: FnMut(&Value) -> K,
+ K: Ord,
+ {
+ #[allow(clippy::manual_map)] // needed for lifetimes
+ self.values.sort_by_key(move |item| {
+ if let Some(value) = item.as_value() {
+ Some(f(value))
+ } else {
+ None
+ }
+ });
+ }
+
fn value_op<T>(
&mut self,
v: Value,
@@ -333,9 +389,10 @@ impl Array {
}
}
+#[cfg(feature = "display")]
impl std::fmt::Display for Array {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- crate::encode::Encode::encode(self, f, None, ("", ""))
+ crate::encode::encode_array(self, f, None, ("", ""))
}
}
diff --git a/src/array_of_tables.rs b/src/array_of_tables.rs
index c4d7194..2e602a2 100644
--- a/src/array_of_tables.rs
+++ b/src/array_of_tables.rs
@@ -158,6 +158,7 @@ impl<'s> IntoIterator for &'s ArrayOfTables {
}
}
+#[cfg(feature = "display")]
impl std::fmt::Display for ArrayOfTables {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
// HACK: Without the header, we don't really have a proper way of printing this
diff --git a/src/de/key.rs b/src/de/key.rs
index 3da41df..a3b2825 100644
--- a/src/de/key.rs
+++ b/src/de/key.rs
@@ -62,9 +62,20 @@ impl<'de> serde::de::Deserializer<'de> for KeyDeserializer {
self.deserialize_any(visitor)
}
+ fn deserialize_newtype_struct<V>(
+ self,
+ _name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: serde::de::Visitor<'de>,
+ {
+ visitor.visit_newtype_struct(self)
+ }
+
serde::forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
- bytes byte_buf map option unit newtype_struct
+ bytes byte_buf map option unit
ignored_any unit_struct tuple_struct tuple identifier
}
}
diff --git a/src/de/mod.rs b/src/de/mod.rs
index 09ea120..9b8a2c7 100644
--- a/src/de/mod.rs
+++ b/src/de/mod.rs
@@ -87,6 +87,7 @@ impl From<Error> for crate::TomlError {
impl std::error::Error for Error {}
/// Convert a value into `T`.
+#[cfg(feature = "parse")]
pub fn from_str<T>(s: &'_ str) -> Result<T, Error>
where
T: DeserializeOwned,
@@ -96,6 +97,7 @@ where
}
/// Convert a value into `T`.
+#[cfg(feature = "parse")]
pub fn from_slice<T>(s: &'_ [u8]) -> Result<T, Error>
where
T: DeserializeOwned,
@@ -125,6 +127,7 @@ impl Deserializer {
}
}
+#[cfg(feature = "parse")]
impl std::str::FromStr for Deserializer {
type Err = Error;
diff --git a/src/de/table.rs b/src/de/table.rs
index 0b6183e..33aa397 100644
--- a/src/de/table.rs
+++ b/src/de/table.rs
@@ -118,7 +118,7 @@ impl crate::InlineTable {
pub(crate) struct TableMapAccess {
iter: indexmap::map::IntoIter<crate::InternalString, crate::table::TableKeyValue>,
span: Option<std::ops::Range<usize>>,
- value: Option<(crate::InternalString, crate::Item)>,
+ value: Option<(crate::Key, crate::Item)>,
}
impl TableMapAccess {
@@ -149,7 +149,7 @@ impl<'de> serde::de::MapAccess<'de> for TableMapAccess {
}
e
});
- self.value = Some((v.key.into(), v.value));
+ self.value = Some((v.key, v.value));
ret
}
None => Ok(None),
@@ -162,13 +162,13 @@ impl<'de> serde::de::MapAccess<'de> for TableMapAccess {
{
match self.value.take() {
Some((k, v)) => {
- let span = v.span();
+ let span = v.span().or_else(|| k.span());
seed.deserialize(crate::de::ValueDeserializer::new(v))
.map_err(|mut e: Self::Error| {
if e.span().is_none() {
e.set_span(span);
}
- e.add_key(k.as_str().to_owned());
+ e.add_key(k.get().to_owned());
e
})
}
diff --git a/src/de/table_enum.rs b/src/de/table_enum.rs
index 197ad6e..0ceeab6 100644
--- a/src/de/table_enum.rs
+++ b/src/de/table_enum.rs
@@ -16,6 +16,20 @@ impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer {
fn unit_variant(self) -> Result<(), Self::Error> {
match self.value {
+ crate::Item::ArrayOfTables(values) => {
+ if values.is_empty() {
+ Ok(())
+ } else {
+ Err(Error::custom("expected empty array", values.span()))
+ }
+ }
+ crate::Item::Value(crate::Value::Array(values)) => {
+ if values.is_empty() {
+ Ok(())
+ } else {
+ Err(Error::custom("expected empty table", values.span()))
+ }
+ }
crate::Item::Table(values) => {
if values.is_empty() {
Ok(())
@@ -49,9 +63,41 @@ impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer {
V: serde::de::Visitor<'de>,
{
match self.value {
+ crate::Item::ArrayOfTables(values) => {
+ let values_span = values.span();
+ let tuple_values = values.values.into_iter().collect::<Vec<_>>();
+
+ if tuple_values.len() == len {
+ serde::de::Deserializer::deserialize_seq(
+ super::ArrayDeserializer::new(tuple_values, values_span),
+ visitor,
+ )
+ } else {
+ Err(Error::custom(
+ format!("expected tuple with length {}", len),
+ values_span,
+ ))
+ }
+ }
+ crate::Item::Value(crate::Value::Array(values)) => {
+ let values_span = values.span();
+ let tuple_values = values.values.into_iter().collect::<Vec<_>>();
+
+ if tuple_values.len() == len {
+ serde::de::Deserializer::deserialize_seq(
+ super::ArrayDeserializer::new(tuple_values, values_span),
+ visitor,
+ )
+ } else {
+ Err(Error::custom(
+ format!("expected tuple with length {}", len),
+ values_span,
+ ))
+ }
+ }
crate::Item::Table(values) => {
let values_span = values.span();
- let tuple_values = values
+ let tuple_values: Result<Vec<_>, _> = values
.items
.into_iter()
.enumerate()
@@ -68,17 +114,8 @@ impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer {
)),
},
)
- // Fold all values into a `Vec`, or return the first error.
- .fold(Ok(Vec::with_capacity(len)), |result, value_result| {
- result.and_then(move |mut tuple_values| match value_result {
- Ok(value) => {
- tuple_values.push(value);
- Ok(tuple_values)
- }
- // `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>`
- Err(e) => Err(e),
- })
- })?;
+ .collect();
+ let tuple_values = tuple_values?;
if tuple_values.len() == len {
serde::de::Deserializer::deserialize_seq(
@@ -94,7 +131,7 @@ impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer {
}
crate::Item::Value(crate::Value::InlineTable(values)) => {
let values_span = values.span();
- let tuple_values = values
+ let tuple_values: Result<Vec<_>, _> = values
.items
.into_iter()
.enumerate()
@@ -111,17 +148,8 @@ impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer {
)),
},
)
- // Fold all values into a `Vec`, or return the first error.
- .fold(Ok(Vec::with_capacity(len)), |result, value_result| {
- result.and_then(move |mut tuple_values| match value_result {
- Ok(value) => {
- tuple_values.push(value);
- Ok(tuple_values)
- }
- // `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>`
- Err(e) => Err(e),
- })
- })?;
+ .collect();
+ let tuple_values = tuple_values?;
if tuple_values.len() == len {
serde::de::Deserializer::deserialize_seq(
diff --git a/src/de/value.rs b/src/de/value.rs
index 3984287..ba6ce6d 100644
--- a/src/de/value.rs
+++ b/src/de/value.rs
@@ -5,7 +5,7 @@ use crate::de::Error;
/// Deserialization implementation for TOML [values][crate::Value].
///
-/// Can be creater either directly from TOML strings, using [`std::str::FromStr`],
+/// Can be created either directly from TOML strings, using [`std::str::FromStr`],
/// or from parsed [values][crate::Value] using [`serde::de::IntoDeserializer::into_deserializer`].
///
/// # Example
@@ -241,6 +241,7 @@ impl crate::Item {
}
}
+#[cfg(feature = "parse")]
impl std::str::FromStr for ValueDeserializer {
type Err = Error;
diff --git a/src/document.rs b/src/document.rs
index 67dd293..f20e61a 100644
--- a/src/document.rs
+++ b/src/document.rs
@@ -1,6 +1,5 @@
use std::str::FromStr;
-use crate::parser;
use crate::table::Iter;
use crate::{Item, RawString, Table};
@@ -78,12 +77,13 @@ impl Default for Document {
}
}
+#[cfg(feature = "parse")]
impl FromStr for Document {
type Err = crate::TomlError;
/// Parses a document from a &str
fn from_str(s: &str) -> Result<Self, Self::Err> {
- let mut d = parser::parse_document(s)?;
+ let mut d = crate::parser::parse_document(s)?;
d.despan();
Ok(d)
}
diff --git a/src/encode.rs b/src/encode.rs
index 9940f28..30b153a 100644
--- a/src/encode.rs
+++ b/src/encode.rs
@@ -13,218 +13,185 @@ use crate::value::{
};
use crate::{Array, InlineTable, Item, Table, Value};
-pub(crate) trait Encode {
- fn encode(
- &self,
- buf: &mut dyn Write,
- input: Option<&str>,
- default_decor: (&str, &str),
- ) -> Result;
+pub(crate) fn encode_key(this: &Key, buf: &mut dyn Write, input: Option<&str>) -> Result {
+ if let Some(input) = input {
+ let repr = this
+ .as_repr()
+ .map(Cow::Borrowed)
+ .unwrap_or_else(|| Cow::Owned(this.default_repr()));
+ repr.encode(buf, input)?;
+ } else {
+ let repr = this.display_repr();
+ write!(buf, "{}", repr)?;
+ };
+
+ Ok(())
}
-impl Encode for Key {
- fn encode(
- &self,
- buf: &mut dyn Write,
- input: Option<&str>,
- default_decor: (&str, &str),
- ) -> Result {
- let decor = self.decor();
- decor.prefix_encode(buf, input, default_decor.0)?;
-
- if let Some(input) = input {
- let repr = self
- .as_repr()
- .map(Cow::Borrowed)
- .unwrap_or_else(|| Cow::Owned(self.default_repr()));
- repr.encode(buf, input)?;
+fn encode_key_path(
+ this: &[Key],
+ buf: &mut dyn Write,
+ input: Option<&str>,
+ default_decor: (&str, &str),
+) -> Result {
+ let leaf_decor = this.last().expect("always at least one key").leaf_decor();
+ for (i, key) in this.iter().enumerate() {
+ let dotted_decor = key.dotted_decor();
+
+ let first = i == 0;
+ let last = i + 1 == this.len();
+
+ if first {
+ leaf_decor.prefix_encode(buf, input, default_decor.0)?;
} else {
- let repr = self.display_repr();
- write!(buf, "{}", repr)?;
- };
+ write!(buf, ".")?;
+ dotted_decor.prefix_encode(buf, input, DEFAULT_KEY_PATH_DECOR.0)?;
+ }
+
+ encode_key(key, buf, input)?;
- decor.suffix_encode(buf, input, default_decor.1)?;
- Ok(())
+ if last {
+ leaf_decor.suffix_encode(buf, input, default_decor.1)?;
+ } else {
+ dotted_decor.suffix_encode(buf, input, DEFAULT_KEY_PATH_DECOR.1)?;
+ }
}
+ Ok(())
}
-impl<'k> Encode for &'k [Key] {
- fn encode(
- &self,
- buf: &mut dyn Write,
- input: Option<&str>,
- default_decor: (&str, &str),
- ) -> Result {
- for (i, key) in self.iter().enumerate() {
- let first = i == 0;
- let last = i + 1 == self.len();
-
- let prefix = if first {
- default_decor.0
- } else {
- DEFAULT_KEY_PATH_DECOR.0
- };
- let suffix = if last {
- default_decor.1
- } else {
- DEFAULT_KEY_PATH_DECOR.1
- };
+pub(crate) fn encode_key_path_ref(
+ this: &[&Key],
+ buf: &mut dyn Write,
+ input: Option<&str>,
+ default_decor: (&str, &str),
+) -> Result {
+ let leaf_decor = this.last().expect("always at least one key").leaf_decor();
+ for (i, key) in this.iter().enumerate() {
+ let dotted_decor = key.dotted_decor();
- if !first {
- write!(buf, ".")?;
- }
- key.encode(buf, input, (prefix, suffix))?;
+ let first = i == 0;
+ let last = i + 1 == this.len();
+
+ if first {
+ leaf_decor.prefix_encode(buf, input, default_decor.0)?;
+ } else {
+ write!(buf, ".")?;
+ dotted_decor.prefix_encode(buf, input, DEFAULT_KEY_PATH_DECOR.0)?;
}
- Ok(())
- }
-}
-impl<'k> Encode for &'k [&'k Key] {
- fn encode(
- &self,
- buf: &mut dyn Write,
- input: Option<&str>,
- default_decor: (&str, &str),
- ) -> Result {
- for (i, key) in self.iter().enumerate() {
- let first = i == 0;
- let last = i + 1 == self.len();
-
- let prefix = if first {
- default_decor.0
- } else {
- DEFAULT_KEY_PATH_DECOR.0
- };
- let suffix = if last {
- default_decor.1
- } else {
- DEFAULT_KEY_PATH_DECOR.1
- };
+ encode_key(key, buf, input)?;
- if !first {
- write!(buf, ".")?;
- }
- key.encode(buf, input, (prefix, suffix))?;
+ if last {
+ leaf_decor.suffix_encode(buf, input, default_decor.1)?;
+ } else {
+ dotted_decor.suffix_encode(buf, input, DEFAULT_KEY_PATH_DECOR.1)?;
}
- Ok(())
}
+ Ok(())
}
-impl<T> Encode for Formatted<T>
-where
- T: ValueRepr,
-{
- fn encode(
- &self,
- buf: &mut dyn Write,
- input: Option<&str>,
- default_decor: (&str, &str),
- ) -> Result {
- let decor = self.decor();
- decor.prefix_encode(buf, input, default_decor.0)?;
-
- if let Some(input) = input {
- let repr = self
- .as_repr()
- .map(Cow::Borrowed)
- .unwrap_or_else(|| Cow::Owned(self.default_repr()));
- repr.encode(buf, input)?;
- } else {
- let repr = self.display_repr();
- write!(buf, "{}", repr)?;
- };
+pub(crate) fn encode_formatted<T: ValueRepr>(
+ this: &Formatted<T>,
+ buf: &mut dyn Write,
+ input: Option<&str>,
+ default_decor: (&str, &str),
+) -> Result {
+ let decor = this.decor();
+ decor.prefix_encode(buf, input, default_decor.0)?;
+
+ if let Some(input) = input {
+ let repr = this
+ .as_repr()
+ .map(Cow::Borrowed)
+ .unwrap_or_else(|| Cow::Owned(this.default_repr()));
+ repr.encode(buf, input)?;
+ } else {
+ let repr = this.display_repr();
+ write!(buf, "{}", repr)?;
+ };
- decor.suffix_encode(buf, input, default_decor.1)?;
- Ok(())
- }
+ decor.suffix_encode(buf, input, default_decor.1)?;
+ Ok(())
}
-impl Encode for Array {
- fn encode(
- &self,
- buf: &mut dyn Write,
- input: Option<&str>,
- default_decor: (&str, &str),
- ) -> Result {
- let decor = self.decor();
- decor.prefix_encode(buf, input, default_decor.0)?;
- write!(buf, "[")?;
-
- for (i, elem) in self.iter().enumerate() {
- let inner_decor;
- if i == 0 {
- inner_decor = DEFAULT_LEADING_VALUE_DECOR;
- } else {
- inner_decor = DEFAULT_VALUE_DECOR;
- write!(buf, ",")?;
- }
- elem.encode(buf, input, inner_decor)?;
- }
- if self.trailing_comma() && !self.is_empty() {
+pub(crate) fn encode_array(
+ this: &Array,
+ buf: &mut dyn Write,
+ input: Option<&str>,
+ default_decor: (&str, &str),
+) -> Result {
+ let decor = this.decor();
+ decor.prefix_encode(buf, input, default_decor.0)?;
+ write!(buf, "[")?;
+
+ for (i, elem) in this.iter().enumerate() {
+ let inner_decor;
+ if i == 0 {
+ inner_decor = DEFAULT_LEADING_VALUE_DECOR;
+ } else {
+ inner_decor = DEFAULT_VALUE_DECOR;
write!(buf, ",")?;
}
+ encode_value(elem, buf, input, inner_decor)?;
+ }
+ if this.trailing_comma() && !this.is_empty() {
+ write!(buf, ",")?;
+ }
- self.trailing().encode_with_default(buf, input, "")?;
- write!(buf, "]")?;
- decor.suffix_encode(buf, input, default_decor.1)?;
+ this.trailing().encode_with_default(buf, input, "")?;
+ write!(buf, "]")?;
+ decor.suffix_encode(buf, input, default_decor.1)?;
- Ok(())
- }
+ Ok(())
}
-impl Encode for InlineTable {
- fn encode(
- &self,
- buf: &mut dyn Write,
- input: Option<&str>,
- default_decor: (&str, &str),
- ) -> Result {
- let decor = self.decor();
- decor.prefix_encode(buf, input, default_decor.0)?;
- write!(buf, "{{")?;
- self.preamble().encode_with_default(buf, input, "")?;
-
- let children = self.get_values();
- let len = children.len();
- for (i, (key_path, value)) in children.into_iter().enumerate() {
- if i != 0 {
- write!(buf, ",")?;
- }
- let inner_decor = if i == len - 1 {
- DEFAULT_TRAILING_VALUE_DECOR
- } else {
- DEFAULT_VALUE_DECOR
- };
- key_path
- .as_slice()
- .encode(buf, input, DEFAULT_INLINE_KEY_DECOR)?;
- write!(buf, "=")?;
- value.encode(buf, input, inner_decor)?;
+pub(crate) fn encode_table(
+ this: &InlineTable,
+ buf: &mut dyn Write,
+ input: Option<&str>,
+ default_decor: (&str, &str),
+) -> Result {
+ let decor = this.decor();
+ decor.prefix_encode(buf, input, default_decor.0)?;
+ write!(buf, "{{")?;
+ this.preamble().encode_with_default(buf, input, "")?;
+
+ let children = this.get_values();
+ let len = children.len();
+ for (i, (key_path, value)) in children.into_iter().enumerate() {
+ if i != 0 {
+ write!(buf, ",")?;
}
+ let inner_decor = if i == len - 1 {
+ DEFAULT_TRAILING_VALUE_DECOR
+ } else {
+ DEFAULT_VALUE_DECOR
+ };
+ encode_key_path_ref(&key_path, buf, input, DEFAULT_INLINE_KEY_DECOR)?;
+ write!(buf, "=")?;
+ encode_value(value, buf, input, inner_decor)?;
+ }
- write!(buf, "}}")?;
- decor.suffix_encode(buf, input, default_decor.1)?;
+ write!(buf, "}}")?;
+ decor.suffix_encode(buf, input, default_decor.1)?;
- Ok(())
- }
+ Ok(())
}
-impl Encode for Value {
- fn encode(
- &self,
- buf: &mut dyn Write,
- input: Option<&str>,
- default_decor: (&str, &str),
- ) -> Result {
- match self {
- Value::String(repr) => repr.encode(buf, input, default_decor),
- Value::Integer(repr) => repr.encode(buf, input, default_decor),
- Value::Float(repr) => repr.encode(buf, input, default_decor),
- Value::Boolean(repr) => repr.encode(buf, input, default_decor),
- Value::Datetime(repr) => repr.encode(buf, input, default_decor),
- Value::Array(array) => array.encode(buf, input, default_decor),
- Value::InlineTable(table) => table.encode(buf, input, default_decor),
- }
+pub(crate) fn encode_value(
+ this: &Value,
+ buf: &mut dyn Write,
+ input: Option<&str>,
+ default_decor: (&str, &str),
+) -> Result {
+ match this {
+ Value::String(repr) => encode_formatted(repr, buf, input, default_decor),
+ Value::Integer(repr) => encode_formatted(repr, buf, input, default_decor),
+ Value::Float(repr) => encode_formatted(repr, buf, input, default_decor),
+ Value::Boolean(repr) => encode_formatted(repr, buf, input, default_decor),
+ Value::Datetime(repr) => encode_formatted(repr, buf, input, default_decor),
+ Value::Array(array) => encode_array(array, buf, input, default_decor),
+ Value::InlineTable(table) => encode_table(table, buf, input, default_decor),
}
}
@@ -275,11 +242,7 @@ where
for kv in table.items.values() {
match kv.value {
Item::Table(ref t) => {
- let mut key = kv.key.clone();
- if t.is_dotted() {
- // May have newlines and generally isn't written for standard tables
- key.decor_mut().clear();
- }
+ let key = kv.key.clone();
path.push(key);
visit_nested_tables(t, path, false, callback)?;
path.pop();
@@ -332,7 +295,7 @@ fn visit_table(
};
table.decor.prefix_encode(buf, input, default_decor.0)?;
write!(buf, "[[")?;
- path.encode(buf, input, DEFAULT_KEY_PATH_DECOR)?;
+ encode_key_path(path, buf, input, DEFAULT_KEY_PATH_DECOR)?;
write!(buf, "]]")?;
table.decor.suffix_encode(buf, input, default_decor.1)?;
writeln!(buf)?;
@@ -345,16 +308,16 @@ fn visit_table(
};
table.decor.prefix_encode(buf, input, default_decor.0)?;
write!(buf, "[")?;
- path.encode(buf, input, DEFAULT_KEY_PATH_DECOR)?;
+ encode_key_path(path, buf, input, DEFAULT_KEY_PATH_DECOR)?;
write!(buf, "]")?;
table.decor.suffix_encode(buf, input, default_decor.1)?;
writeln!(buf)?;
}
// print table body
for (key_path, value) in children {
- key_path.as_slice().encode(buf, input, DEFAULT_KEY_DECOR)?;
+ encode_key_path_ref(&key_path, buf, input, DEFAULT_KEY_DECOR)?;
write!(buf, "=")?;
- value.encode(buf, input, DEFAULT_VALUE_DECOR)?;
+ encode_value(value, buf, input, DEFAULT_VALUE_DECOR)?;
writeln!(buf)?;
}
Ok(())
@@ -390,7 +353,7 @@ pub(crate) fn to_string_repr(
'\u{8}' => output.push_str("\\b"),
'\u{9}' => output.push_str("\\t"),
'\u{a}' => match style {
- StringStyle::NewlineTripple => output.push('\n'),
+ StringStyle::NewlineTriple => output.push('\n'),
StringStyle::OnelineSingle => output.push_str("\\n"),
_ => unreachable!(),
},
@@ -412,59 +375,56 @@ pub(crate) fn to_string_repr(
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
pub(crate) enum StringStyle {
- NewlineTripple,
- OnelineTripple,
+ NewlineTriple,
+ OnelineTriple,
OnelineSingle,
}
impl StringStyle {
fn literal_start(self) -> &'static str {
match self {
- Self::NewlineTripple => "'''\n",
- Self::OnelineTripple => "'''",
+ Self::NewlineTriple => "'''\n",
+ Self::OnelineTriple => "'''",
Self::OnelineSingle => "'",
}
}
fn literal_end(self) -> &'static str {
match self {
- Self::NewlineTripple => "'''",
- Self::OnelineTripple => "'''",
+ Self::NewlineTriple => "'''",
+ Self::OnelineTriple => "'''",
Self::OnelineSingle => "'",
}
}
fn standard_start(self) -> &'static str {
match self {
- Self::NewlineTripple => "\"\"\"\n",
- // note: OnelineTripple can happen if do_pretty wants to do
+ Self::NewlineTriple => "\"\"\"\n",
+ // note: OnelineTriple can happen if do_pretty wants to do
// '''it's one line'''
// but literal == false
- Self::OnelineTripple | Self::OnelineSingle => "\"",
+ Self::OnelineTriple | Self::OnelineSingle => "\"",
}
}
fn standard_end(self) -> &'static str {
match self {
- Self::NewlineTripple => "\"\"\"",
- // note: OnelineTripple can happen if do_pretty wants to do
+ Self::NewlineTriple => "\"\"\"",
+ // note: OnelineTriple can happen if do_pretty wants to do
// '''it's one line'''
// but literal == false
- Self::OnelineTripple | Self::OnelineSingle => "\"",
+ Self::OnelineTriple | Self::OnelineSingle => "\"",
}
}
}
fn infer_style(value: &str) -> (StringStyle, bool) {
- // For doing pretty prints we store in a new String
- // because there are too many cases where pretty cannot
- // work. We need to determine:
+ // We need to determine:
// - if we are a "multi-line" pretty (if there are \n)
// - if ['''] appears if multi or ['] if single
// - if there are any invalid control characters
//
// Doing it any other way would require multiple passes
// to determine if a pretty string works or not.
- let mut out = String::with_capacity(value.len() * 2);
let mut ty = StringStyle::OnelineSingle;
// found consecutive single quotes
let mut max_found_singles = 0;
@@ -490,18 +450,17 @@ fn infer_style(value: &str) -> (StringStyle, bool) {
'\\' => {
prefer_literal = true;
}
- '\n' => ty = StringStyle::NewlineTripple,
+ '\n' => ty = StringStyle::NewlineTriple,
// Escape codes are needed if any ascii control
// characters are present, including \b \f \r.
c if c <= '\u{1f}' || c == '\u{7f}' => can_be_pretty = false,
_ => {}
}
- out.push(ch);
} else {
// the string cannot be represented as pretty,
// still check if it should be multiline
if ch == '\n' {
- ty = StringStyle::NewlineTripple;
+ ty = StringStyle::NewlineTriple;
}
}
}
@@ -513,7 +472,7 @@ fn infer_style(value: &str) -> (StringStyle, bool) {
can_be_pretty = false;
}
if !can_be_pretty {
- debug_assert!(ty != StringStyle::OnelineTripple);
+ debug_assert!(ty != StringStyle::OnelineTriple);
return (ty, false);
}
if found_singles > max_found_singles {
@@ -522,7 +481,7 @@ fn infer_style(value: &str) -> (StringStyle, bool) {
debug_assert!(max_found_singles < 3);
if ty == StringStyle::OnelineSingle && max_found_singles >= 1 {
// no newlines, but must use ''' because it has ' in it
- ty = StringStyle::OnelineTripple;
+ ty = StringStyle::OnelineTriple;
}
(ty, true)
}
diff --git a/src/parser/errors.rs b/src/error.rs
index 859ed53..a983019 100644
--- a/src/parser/errors.rs
+++ b/src/error.rs
@@ -1,12 +1,6 @@
use std::error::Error as StdError;
use std::fmt::{Display, Formatter, Result};
-use crate::parser::prelude::*;
-use crate::Key;
-
-use winnow::error::ContextError;
-use winnow::error::ParseError;
-
/// Type representing a TOML parse error
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct TomlError {
@@ -17,7 +11,14 @@ pub struct TomlError {
}
impl TomlError {
- pub(crate) fn new(error: ParseError<Input<'_>, ContextError>, mut original: Input<'_>) -> Self {
+ #[cfg(feature = "parse")]
+ pub(crate) fn new(
+ error: winnow::error::ParseError<
+ crate::parser::prelude::Input<'_>,
+ winnow::error::ContextError,
+ >,
+ mut original: crate::parser::prelude::Input<'_>,
+ ) -> Self {
use winnow::stream::Stream;
let offset = error.offset();
@@ -166,7 +167,6 @@ fn translate_position(input: &[u8], index: usize) -> (usize, usize) {
None => 0,
};
let line = input[0..line_start].iter().filter(|b| **b == b'\n').count();
- let line = line;
let column = std::str::from_utf8(&input[line_start..=index])
.map(|s| s.chars().count() - 1)
@@ -244,73 +244,3 @@ mod test_translate_position {
assert_eq!(position, (1, 2));
}
}
-
-#[derive(Debug, Clone)]
-pub(crate) enum CustomError {
- DuplicateKey {
- key: String,
- table: Option<Vec<Key>>,
- },
- DottedKeyExtendWrongType {
- key: Vec<Key>,
- actual: &'static str,
- },
- OutOfRange,
- #[cfg_attr(feature = "unbounded", allow(dead_code))]
- RecursionLimitExceeded,
-}
-
-impl CustomError {
- pub(crate) fn duplicate_key(path: &[Key], i: usize) -> Self {
- assert!(i < path.len());
- let key = &path[i];
- let repr = key.display_repr();
- Self::DuplicateKey {
- key: repr.into(),
- table: Some(path[..i].to_vec()),
- }
- }
-
- pub(crate) fn extend_wrong_type(path: &[Key], i: usize, actual: &'static str) -> Self {
- assert!(i < path.len());
- Self::DottedKeyExtendWrongType {
- key: path[..=i].to_vec(),
- actual,
- }
- }
-}
-
-impl StdError for CustomError {
- fn description(&self) -> &'static str {
- "TOML parse error"
- }
-}
-
-impl Display for CustomError {
- fn fmt(&self, f: &mut Formatter<'_>) -> Result {
- match self {
- CustomError::DuplicateKey { key, table } => {
- if let Some(table) = table {
- if table.is_empty() {
- write!(f, "duplicate key `{}` in document root", key)
- } else {
- let path = table.iter().map(|k| k.get()).collect::<Vec<_>>().join(".");
- write!(f, "duplicate key `{}` in table `{}`", key, path)
- }
- } else {
- write!(f, "duplicate key `{}`", key)
- }
- }
- CustomError::DottedKeyExtendWrongType { key, actual } => {
- let path = key.iter().map(|k| k.get()).collect::<Vec<_>>().join(".");
- write!(
- f,
- "dotted key `{}` attempted to extend non-table type ({})",
- path, actual
- )
- }
- CustomError::OutOfRange => write!(f, "value is out of range"),
- CustomError::RecursionLimitExceeded => write!(f, "recursion limit exceded"),
- }
- }
-}
diff --git a/src/inline_table.rs b/src/inline_table.rs
index 3dc6c0c..316637d 100644
--- a/src/inline_table.rs
+++ b/src/inline_table.rs
@@ -11,6 +11,8 @@ use crate::{InternalString, Item, KeyMut, RawString, Table, Value};
pub struct InlineTable {
// `preamble` represents whitespaces in an empty table
preamble: RawString,
+ // Whether to hide an empty table
+ pub(crate) implicit: bool,
// prefix before `{` and suffix after `}`
decor: Decor,
pub(crate) span: Option<std::ops::Range<usize>>,
@@ -55,10 +57,10 @@ impl InlineTable {
values
}
- pub(crate) fn append_values<'s, 'c>(
+ pub(crate) fn append_values<'s>(
&'s self,
parent: &[&'s Key],
- values: &'c mut Vec<(Vec<&'s Key>, &'s Value)>,
+ values: &mut Vec<(Vec<&'s Key>, &'s Value)>,
) {
for value in self.items.values() {
let mut path = parent.to_vec();
@@ -133,6 +135,36 @@ impl InlineTable {
}
}
+ /// If a table has no key/value pairs and implicit, it will not be displayed.
+ ///
+ /// # Examples
+ ///
+ /// ```notrust
+ /// [target."x86_64/windows.json".dependencies]
+ /// ```
+ ///
+ /// In the document above, tables `target` and `target."x86_64/windows.json"` are implicit.
+ ///
+ /// ```
+ /// # #[cfg(feature = "parse")] {
+ /// # #[cfg(feature = "display")] {
+ /// use toml_edit::Document;
+ /// let mut doc = "[a]\n[a.b]\n".parse::<Document>().expect("invalid toml");
+ ///
+ /// doc["a"].as_table_mut().unwrap().set_implicit(true);
+ /// assert_eq!(doc.to_string(), "[a.b]\n");
+ /// # }
+ /// # }
+ /// ```
+ pub(crate) fn set_implicit(&mut self, implicit: bool) {
+ self.implicit = implicit;
+ }
+
+ /// If a table has no key/value pairs and implicit, it will not be displayed.
+ pub(crate) fn is_implicit(&self) -> bool {
+ self.implicit
+ }
+
/// Change this table's dotted status
pub fn set_dotted(&mut self, yes: bool) {
self.dotted = yes;
@@ -153,14 +185,28 @@ impl InlineTable {
&self.decor
}
+ /// Returns an accessor to a key's formatting
+ pub fn key(&self, key: &str) -> Option<&'_ Key> {
+ self.items.get(key).map(|kv| &kv.key)
+ }
+
+ /// Returns an accessor to a key's formatting
+ pub fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
+ self.items.get_mut(key).map(|kv| kv.key.as_mut())
+ }
+
/// Returns the decor associated with a given key of the table.
+ #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
pub fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
- self.items.get_mut(key).map(|kv| &mut kv.key.decor)
+ #![allow(deprecated)]
+ self.items.get_mut(key).map(|kv| kv.key.leaf_decor_mut())
}
/// Returns the decor associated with a given key of the table.
+ #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
pub fn key_decor(&self, key: &str) -> Option<&Decor> {
- self.items.get(key).map(|kv| &kv.key.decor)
+ #![allow(deprecated)]
+ self.items.get(key).map(|kv| kv.key.leaf_decor())
}
/// Set whitespace after before element
@@ -383,9 +429,10 @@ impl InlineTable {
}
}
+#[cfg(feature = "display")]
impl std::fmt::Display for InlineTable {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- crate::encode::Encode::encode(self, f, None, ("", ""))
+ crate::encode::encode_table(self, f, None, ("", ""))
}
}
@@ -436,13 +483,14 @@ impl<'s> IntoIterator for &'s InlineTable {
}
fn decorate_inline_table(table: &mut InlineTable) {
- for (key_decor, value) in table
+ for (mut key, value) in table
.items
.iter_mut()
- .filter(|&(_, ref kv)| kv.value.is_value())
- .map(|(_, kv)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap()))
+ .filter(|(_, kv)| kv.value.is_value())
+ .map(|(_, kv)| (kv.key.as_mut(), kv.value.as_value_mut().unwrap()))
{
- key_decor.clear();
+ key.leaf_decor_mut().clear();
+ key.dotted_decor_mut().clear();
value.decor_mut().clear();
}
}
@@ -530,10 +578,18 @@ impl TableLike for InlineTable {
self.is_dotted()
}
+ fn key(&self, key: &str) -> Option<&'_ Key> {
+ self.key(key)
+ }
+ fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
+ self.key_mut(key)
+ }
fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
+ #![allow(deprecated)]
self.key_decor_mut(key)
}
fn key_decor(&self, key: &str) -> Option<&Decor> {
+ #![allow(deprecated)]
self.key_decor(key)
}
}
diff --git a/src/item.rs b/src/item.rs
index 2025fd9..b58806e 100644
--- a/src/item.rs
+++ b/src/item.rs
@@ -7,9 +7,10 @@ use crate::table::TableLike;
use crate::{Array, InlineTable, Table, Value};
/// Type representing either a value, a table, an array of tables, or none.
-#[derive(Debug)]
+#[derive(Debug, Default)]
pub enum Item {
/// Type representing none.
+ #[default]
None,
/// Type representing value.
Value(Value),
@@ -328,12 +329,7 @@ impl Clone for Item {
}
}
-impl Default for Item {
- fn default() -> Self {
- Item::None
- }
-}
-
+#[cfg(feature = "parse")]
impl FromStr for Item {
type Err = crate::TomlError;
@@ -344,6 +340,7 @@ impl FromStr for Item {
}
}
+#[cfg(feature = "display")]
impl std::fmt::Display for Item {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self {
@@ -363,6 +360,7 @@ impl std::fmt::Display for Item {
///
/// # Examples
/// ```rust
+/// # #[cfg(feature = "display")] {
/// # use snapbox::assert_eq;
/// # use toml_edit::*;
/// let mut table = Table::default();
@@ -377,6 +375,7 @@ impl std::fmt::Display for Item {
/// key2 = 42
/// key3 = ["hello", '\, world']
/// "#);
+/// # }
/// ```
pub fn value<V: Into<Value>>(v: V) -> Item {
Item::Value(v.into())
diff --git a/src/key.rs b/src/key.rs
index c1ee165..2f4c30a 100644
--- a/src/key.rs
+++ b/src/key.rs
@@ -1,9 +1,6 @@
use std::borrow::Cow;
use std::str::FromStr;
-use crate::encode::{to_string_repr, StringStyle};
-use crate::parser;
-use crate::parser::key::is_unquoted_char;
use crate::repr::{Decor, Repr};
use crate::InternalString;
@@ -33,7 +30,8 @@ use crate::InternalString;
pub struct Key {
key: InternalString,
pub(crate) repr: Option<Repr>,
- pub(crate) decor: Decor,
+ pub(crate) leaf_decor: Decor,
+ pub(crate) dotted_decor: Decor,
}
impl Key {
@@ -42,13 +40,15 @@ impl Key {
Self {
key: key.into(),
repr: None,
- decor: Default::default(),
+ leaf_decor: Default::default(),
+ dotted_decor: Default::default(),
}
}
/// Parse a TOML key expression
///
/// Unlike `"".parse<Key>()`, this supports dotted keys.
+ #[cfg(feature = "parse")]
pub fn parse(repr: &str) -> Result<Vec<Self>, crate::TomlError> {
Self::try_parse_path(repr)
}
@@ -59,8 +59,20 @@ impl Key {
}
/// While creating the `Key`, add `Decor` to it
- pub fn with_decor(mut self, decor: Decor) -> Self {
- self.decor = decor;
+ #[deprecated(since = "0.21.1", note = "Replaced with `with_leaf_decor`")]
+ pub fn with_decor(self, decor: Decor) -> Self {
+ self.with_leaf_decor(decor)
+ }
+
+ /// While creating the `Key`, add `Decor` to it for the line entry
+ pub fn with_leaf_decor(mut self, decor: Decor) -> Self {
+ self.leaf_decor = decor;
+ self
+ }
+
+ /// While creating the `Key`, add `Decor` to it for between dots
+ pub fn with_dotted_decor(mut self, decor: Decor) -> Self {
+ self.dotted_decor = decor;
self
}
@@ -84,11 +96,13 @@ impl Key {
}
/// Returns the default raw representation.
+ #[cfg(feature = "display")]
pub fn default_repr(&self) -> Repr {
to_key_repr(&self.key)
}
/// Returns a raw representation.
+ #[cfg(feature = "display")]
pub fn display_repr(&self) -> Cow<'_, str> {
self.as_repr()
.and_then(|r| r.as_raw().as_str())
@@ -99,13 +113,35 @@ impl Key {
}
/// Returns the surrounding whitespace
+ #[deprecated(since = "0.21.1", note = "Replaced with `decor_mut`")]
pub fn decor_mut(&mut self) -> &mut Decor {
- &mut self.decor
+ self.leaf_decor_mut()
+ }
+
+ /// Returns the surrounding whitespace for the line entry
+ pub fn leaf_decor_mut(&mut self) -> &mut Decor {
+ &mut self.leaf_decor
+ }
+
+ /// Returns the surrounding whitespace for between dots
+ pub fn dotted_decor_mut(&mut self) -> &mut Decor {
+ &mut self.dotted_decor
}
/// Returns the surrounding whitespace
+ #[deprecated(since = "0.21.1", note = "Replaced with `decor`")]
pub fn decor(&self) -> &Decor {
- &self.decor
+ self.leaf_decor()
+ }
+
+ /// Returns the surrounding whitespace for the line entry
+ pub fn leaf_decor(&self) -> &Decor {
+ &self.leaf_decor
+ }
+
+ /// Returns the surrounding whitespace for between dots
+ pub fn dotted_decor(&self) -> &Decor {
+ &self.dotted_decor
}
/// Returns the location within the original document
@@ -115,7 +151,8 @@ impl Key {
}
pub(crate) fn despan(&mut self, input: &str) {
- self.decor.despan(input);
+ self.leaf_decor.despan(input);
+ self.dotted_decor.despan(input);
if let Some(repr) = &mut self.repr {
repr.despan(input)
}
@@ -123,18 +160,21 @@ impl Key {
/// Auto formats the key.
pub fn fmt(&mut self) {
- self.repr = Some(to_key_repr(&self.key));
- self.decor.clear();
+ self.repr = None;
+ self.leaf_decor.clear();
+ self.dotted_decor.clear();
}
+ #[cfg(feature = "parse")]
fn try_parse_simple(s: &str) -> Result<Key, crate::TomlError> {
- let mut key = parser::parse_key(s)?;
+ let mut key = crate::parser::parse_key(s)?;
key.despan(s);
Ok(key)
}
+ #[cfg(feature = "parse")]
fn try_parse_path(s: &str) -> Result<Vec<Key>, crate::TomlError> {
- let mut keys = parser::parse_key_path(s)?;
+ let mut keys = crate::parser::parse_key_path(s)?;
for key in &mut keys {
key.despan(s);
}
@@ -148,7 +188,8 @@ impl Clone for Key {
Self {
key: self.key.clone(),
repr: self.repr.clone(),
- decor: self.decor.clone(),
+ leaf_decor: self.leaf_decor.clone(),
+ dotted_decor: self.dotted_decor.clone(),
}
}
}
@@ -209,12 +250,14 @@ impl PartialEq<String> for Key {
}
}
+#[cfg(feature = "display")]
impl std::fmt::Display for Key {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- crate::encode::Encode::encode(self, f, None, ("", ""))
+ crate::encode::encode_key(self, f, None)
}
}
+#[cfg(feature = "parse")]
impl FromStr for Key {
type Err = crate::TomlError;
@@ -226,11 +269,33 @@ impl FromStr for Key {
}
}
+#[cfg(feature = "display")]
fn to_key_repr(key: &str) -> Repr {
- if key.as_bytes().iter().copied().all(is_unquoted_char) && !key.is_empty() {
- Repr::new_unchecked(key)
- } else {
- to_string_repr(key, Some(StringStyle::OnelineSingle), Some(false))
+ #[cfg(feature = "parse")]
+ {
+ if key
+ .as_bytes()
+ .iter()
+ .copied()
+ .all(crate::parser::key::is_unquoted_char)
+ && !key.is_empty()
+ {
+ Repr::new_unchecked(key)
+ } else {
+ crate::encode::to_string_repr(
+ key,
+ Some(crate::encode::StringStyle::OnelineSingle),
+ Some(false),
+ )
+ }
+ }
+ #[cfg(not(feature = "parse"))]
+ {
+ crate::encode::to_string_repr(
+ key,
+ Some(crate::encode::StringStyle::OnelineSingle),
+ Some(false),
+ )
}
}
@@ -265,7 +330,7 @@ impl From<Key> for InternalString {
}
}
-/// A mutable reference to a `Key`
+/// A mutable reference to a `Key`'s formatting
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct KeyMut<'k> {
key: &'k mut Key,
@@ -283,25 +348,51 @@ impl<'k> KeyMut<'k> {
}
/// Returns the default raw representation.
+ #[cfg(feature = "display")]
pub fn default_repr(&self) -> Repr {
self.key.default_repr()
}
/// Returns a raw representation.
+ #[cfg(feature = "display")]
pub fn display_repr(&self) -> Cow<str> {
self.key.display_repr()
}
/// Returns the surrounding whitespace
+ #[deprecated(since = "0.21.1", note = "Replaced with `decor_mut`")]
pub fn decor_mut(&mut self) -> &mut Decor {
+ #![allow(deprecated)]
self.key.decor_mut()
}
+ /// Returns the surrounding whitespace for the line entry
+ pub fn leaf_decor_mut(&mut self) -> &mut Decor {
+ self.key.leaf_decor_mut()
+ }
+
+ /// Returns the surrounding whitespace for between dots
+ pub fn dotted_decor_mut(&mut self) -> &mut Decor {
+ self.key.dotted_decor_mut()
+ }
+
/// Returns the surrounding whitespace
+ #[deprecated(since = "0.21.1", note = "Replaced with `decor`")]
pub fn decor(&self) -> &Decor {
+ #![allow(deprecated)]
self.key.decor()
}
+ /// Returns the surrounding whitespace for the line entry
+ pub fn leaf_decor(&self) -> &Decor {
+ self.key.leaf_decor()
+ }
+
+ /// Returns the surrounding whitespace for between dots
+ pub fn dotted_decor(&self) -> &Decor {
+ self.key.dotted_decor()
+ }
+
/// Auto formats the key.
pub fn fmt(&mut self) {
self.key.fmt()
@@ -337,6 +428,7 @@ impl<'s> PartialEq<String> for KeyMut<'s> {
}
}
+#[cfg(feature = "display")]
impl<'k> std::fmt::Display for KeyMut<'k> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&self.key, f)
diff --git a/src/lib.rs b/src/lib.rs
index 80c0ddd..25e3d20 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -14,6 +14,8 @@
//! # Example
//!
//! ```rust
+//! # #[cfg(feature = "parse")] {
+//! # #[cfg(feature = "display")] {
//! use toml_edit::{Document, value};
//!
//! let toml = r#"
@@ -32,47 +34,54 @@
//! c = { d = "hello" }
//! "#;
//! assert_eq!(doc.to_string(), expected);
+//! # }
+//! # }
//! ```
//!
//! ## Controlling formatting
//!
//! By default, values are created with default formatting
//! ```rust
+//! # #[cfg(feature = "display")] {
//! let mut doc = toml_edit::Document::new();
//! doc["foo"] = toml_edit::value("bar");
//! let expected = r#"foo = "bar"
//! "#;
//! assert_eq!(doc.to_string(), expected);
+//! # }
//! ```
//!
//! You can choose a custom TOML representation by parsing the value.
//! ```rust
+//! # #[cfg(feature = "display")] {
//! let mut doc = toml_edit::Document::new();
//! doc["foo"] = "'bar'".parse::<toml_edit::Item>().unwrap();
//! let expected = r#"foo = 'bar'
//! "#;
//! assert_eq!(doc.to_string(), expected);
+//! # }
//! ```
//!
//! ## Limitations
//!
//! Things it does not preserve:
//!
-//! * Scattered array of tables (tables are reordered by default, see [test]).
-//! * Order of dotted keys, see [issue](https://github.com/ordian/toml_edit/issues/163).
+//! * Order of dotted keys, see [issue](https://github.com/toml-rs/toml/issues/163).
//!
//! [`toml`]: https://docs.rs/toml/latest/toml/
-//! [test]: https://github.com/ordian/toml_edit/blob/f09bd5d075fdb7d2ef8d9bb3270a34506c276753/tests/test_valid.rs#L84
mod array;
mod array_of_tables;
mod document;
+#[cfg(feature = "display")]
mod encode;
+mod error;
mod index;
mod inline_table;
mod internal_string;
mod item;
mod key;
+#[cfg(feature = "parse")]
mod parser;
mod raw_string;
mod repr;
@@ -92,6 +101,7 @@ pub use crate::array_of_tables::{
ArrayOfTables, ArrayOfTablesIntoIter, ArrayOfTablesIter, ArrayOfTablesIterMut,
};
pub use crate::document::Document;
+pub use crate::error::TomlError;
pub use crate::inline_table::{
InlineEntry, InlineOccupiedEntry, InlineTable, InlineTableIntoIter, InlineTableIter,
InlineTableIterMut, InlineVacantEntry,
@@ -99,7 +109,6 @@ pub use crate::inline_table::{
pub use crate::internal_string::InternalString;
pub use crate::item::{array, table, value, Item};
pub use crate::key::{Key, KeyMut};
-pub use crate::parser::TomlError;
pub use crate::raw_string::RawString;
pub use crate::repr::{Decor, Formatted, Repr};
pub use crate::table::{
diff --git a/src/parser/array.rs b/src/parser/array.rs
index e3b1f3f..0783191 100644
--- a/src/parser/array.rs
+++ b/src/parser/array.rs
@@ -81,6 +81,8 @@ pub(crate) fn array_value<'i>(
}
#[cfg(test)]
+#[cfg(feature = "parse")]
+#[cfg(feature = "display")]
mod test {
use super::*;
diff --git a/src/parser/datetime.rs b/src/parser/datetime.rs
index 6e89b97..945dc69 100644
--- a/src/parser/datetime.rs
+++ b/src/parser/datetime.rs
@@ -1,6 +1,6 @@
use std::ops::RangeInclusive;
-use crate::parser::errors::CustomError;
+use crate::parser::error::CustomError;
use crate::parser::prelude::*;
use crate::parser::trivia::from_utf8_unchecked;
@@ -9,6 +9,7 @@ use winnow::combinator::alt;
use winnow::combinator::cut_err;
use winnow::combinator::opt;
use winnow::combinator::preceded;
+use winnow::stream::Stream as _;
use winnow::token::one_of;
use winnow::token::take_while;
use winnow::trace::trace;
@@ -53,12 +54,35 @@ pub(crate) fn date_time(input: &mut Input<'_>) -> PResult<Datetime> {
// full-date = date-fullyear "-" date-month "-" date-mday
pub(crate) fn full_date(input: &mut Input<'_>) -> PResult<Date> {
- trace(
- "full-date",
- (date_fullyear, b'-', cut_err((date_month, b'-', date_mday)))
- .map(|(year, _, (month, _, day))| Date { year, month, day }),
- )
- .parse_next(input)
+ trace("full-date", full_date_).parse_next(input)
+}
+
+fn full_date_(input: &mut Input<'_>) -> PResult<Date> {
+ let year = date_fullyear.parse_next(input)?;
+ let _ = b'-'.parse_next(input)?;
+ let month = cut_err(date_month).parse_next(input)?;
+ let _ = cut_err(b'-').parse_next(input)?;
+ let day_start = input.checkpoint();
+ let day = cut_err(date_mday).parse_next(input)?;
+
+ let is_leap_year = (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0));
+ let max_days_in_month = match month {
+ 2 if is_leap_year => 29,
+ 2 => 28,
+ 4 | 6 | 9 | 11 => 30,
+ _ => 31,
+ };
+ if max_days_in_month < day {
+ input.reset(day_start);
+ return Err(winnow::error::ErrMode::from_external_error(
+ input,
+ winnow::error::ErrorKind::Verify,
+ CustomError::OutOfRange,
+ )
+ .cut());
+ }
+
+ Ok(Date { year, month, day })
}
// partial-time = time-hour ":" time-minute ":" time-second [time-secfrac]
@@ -239,6 +263,8 @@ pub(crate) fn unsigned_digits<'i, const MIN: usize, const MAX: usize>(
const DIGIT: RangeInclusive<u8> = b'0'..=b'9';
#[cfg(test)]
+#[cfg(feature = "parse")]
+#[cfg(feature = "display")]
mod test {
use super::*;
diff --git a/src/parser/error.rs b/src/parser/error.rs
new file mode 100644
index 0000000..22e8e66
--- /dev/null
+++ b/src/parser/error.rs
@@ -0,0 +1,87 @@
+use std::error::Error as StdError;
+use std::fmt::{Display, Formatter, Result};
+
+use crate::Key;
+
+#[derive(Debug, Clone)]
+pub(crate) enum CustomError {
+ DuplicateKey {
+ key: String,
+ table: Option<Vec<Key>>,
+ },
+ DottedKeyExtendWrongType {
+ key: Vec<Key>,
+ actual: &'static str,
+ },
+ OutOfRange,
+ #[cfg_attr(feature = "unbounded", allow(dead_code))]
+ RecursionLimitExceeded,
+}
+
+impl CustomError {
+ pub(crate) fn duplicate_key(path: &[Key], i: usize) -> Self {
+ assert!(i < path.len());
+ let key = &path[i];
+ let repr = key
+ .as_repr()
+ .and_then(|key| key.as_raw().as_str())
+ .map(|s| s.to_owned())
+ .unwrap_or_else(|| {
+ #[cfg(feature = "display")]
+ {
+ key.default_repr().as_raw().as_str().unwrap().to_owned()
+ }
+ #[cfg(not(feature = "display"))]
+ {
+ format!("{:?}", key.get())
+ }
+ });
+ Self::DuplicateKey {
+ key: repr,
+ table: Some(path[..i].to_vec()),
+ }
+ }
+
+ pub(crate) fn extend_wrong_type(path: &[Key], i: usize, actual: &'static str) -> Self {
+ assert!(i < path.len());
+ Self::DottedKeyExtendWrongType {
+ key: path[..=i].to_vec(),
+ actual,
+ }
+ }
+}
+
+impl StdError for CustomError {
+ fn description(&self) -> &'static str {
+ "TOML parse error"
+ }
+}
+
+impl Display for CustomError {
+ fn fmt(&self, f: &mut Formatter<'_>) -> Result {
+ match self {
+ CustomError::DuplicateKey { key, table } => {
+ if let Some(table) = table {
+ if table.is_empty() {
+ write!(f, "duplicate key `{}` in document root", key)
+ } else {
+ let path = table.iter().map(|k| k.get()).collect::<Vec<_>>().join(".");
+ write!(f, "duplicate key `{}` in table `{}`", key, path)
+ }
+ } else {
+ write!(f, "duplicate key `{}`", key)
+ }
+ }
+ CustomError::DottedKeyExtendWrongType { key, actual } => {
+ let path = key.iter().map(|k| k.get()).collect::<Vec<_>>().join(".");
+ write!(
+ f,
+ "dotted key `{}` attempted to extend non-table type ({})",
+ path, actual
+ )
+ }
+ CustomError::OutOfRange => write!(f, "value is out of range"),
+ CustomError::RecursionLimitExceeded => write!(f, "recursion limit exceeded"),
+ }
+ }
+}
diff --git a/src/parser/inline_table.rs b/src/parser/inline_table.rs
index 994e003..c2e6619 100644
--- a/src/parser/inline_table.rs
+++ b/src/parser/inline_table.rs
@@ -5,7 +5,7 @@ use winnow::token::one_of;
use winnow::trace::trace;
use crate::key::Key;
-use crate::parser::errors::CustomError;
+use crate::parser::error::CustomError;
use crate::parser::key::key;
use crate::parser::prelude::*;
use crate::parser::trivia::ws;
@@ -44,6 +44,16 @@ fn table_from_pairs(
for (path, kv) in v {
let table = descend_path(&mut root, &path)?;
+
+ // "Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed"
+ let mixed_table_types = table.is_dotted() == path.is_empty();
+ if mixed_table_types {
+ return Err(CustomError::DuplicateKey {
+ key: kv.key.get().into(),
+ table: None,
+ });
+ }
+
let key: InternalString = kv.key.get_internal().into();
match table.items.entry(key) {
Entry::Vacant(o) => {
@@ -64,15 +74,26 @@ fn descend_path<'a>(
mut table: &'a mut InlineTable,
path: &'a [Key],
) -> Result<&'a mut InlineTable, CustomError> {
+ let dotted = !path.is_empty();
for (i, key) in path.iter().enumerate() {
let entry = table.entry_format(key).or_insert_with(|| {
let mut new_table = InlineTable::new();
- new_table.set_dotted(true);
+ new_table.set_implicit(dotted);
+ new_table.set_dotted(dotted);
Value::InlineTable(new_table)
});
match *entry {
Value::InlineTable(ref mut sweet_child_of_mine) => {
+ // Since tables cannot be defined more than once, redefining such tables using a
+ // [table] header is not allowed. Likewise, using dotted keys to redefine tables
+ // already defined in [table] form is not allowed.
+ if dotted && !sweet_child_of_mine.is_implicit() {
+ return Err(CustomError::DuplicateKey {
+ key: key.get().into(),
+ table: None,
+ });
+ }
table = sweet_child_of_mine;
}
ref v => {
@@ -144,6 +165,8 @@ fn keyval<'i>(
}
#[cfg(test)]
+#[cfg(feature = "parse")]
+#[cfg(feature = "display")]
mod test {
use super::*;
diff --git a/src/parser/key.rs b/src/parser/key.rs
index 12715da..e72b195 100644
--- a/src/parser/key.rs
+++ b/src/parser/key.rs
@@ -7,7 +7,7 @@ use winnow::token::take_while;
use winnow::trace::trace;
use crate::key::Key;
-use crate::parser::errors::CustomError;
+use crate::parser::error::CustomError;
use crate::parser::prelude::*;
use crate::parser::strings::{basic_string, literal_string};
use crate::parser::trivia::{from_utf8_unchecked, ws};
@@ -18,13 +18,13 @@ use crate::RawString;
// key = simple-key / dotted-key
// dotted-key = simple-key 1*( dot-sep simple-key )
pub(crate) fn key(input: &mut Input<'_>) -> PResult<Vec<Key>> {
- trace(
+ let mut key_path = trace(
"dotted-key",
separated1(
(ws.span(), simple_key, ws.span()).map(|(pre, (raw, key), suffix)| {
Key::new(key)
.with_repr_unchecked(Repr::new_unchecked(raw))
- .with_decor(Decor::new(
+ .with_dotted_decor(Decor::new(
RawString::with_span(pre),
RawString::with_span(suffix),
))
@@ -38,7 +38,31 @@ pub(crate) fn key(input: &mut Input<'_>) -> PResult<Vec<Key>> {
Ok::<_, CustomError>(k)
}),
)
- .parse_next(input)
+ .parse_next(input)?;
+
+ let mut leaf_decor = Decor::new("", "");
+ {
+ let first_dotted_decor = key_path
+ .first_mut()
+ .expect("always at least one key")
+ .dotted_decor_mut();
+ if let Some(prefix) = first_dotted_decor.prefix().cloned() {
+ leaf_decor.set_prefix(prefix);
+ first_dotted_decor.set_prefix("");
+ }
+ }
+ let last_key = &mut key_path.last_mut().expect("always at least one key");
+ {
+ let last_dotted_decor = last_key.dotted_decor_mut();
+ if let Some(suffix) = last_dotted_decor.suffix().cloned() {
+ leaf_decor.set_suffix(suffix);
+ last_dotted_decor.set_suffix("");
+ }
+ }
+
+ *last_key.leaf_decor_mut() = leaf_decor;
+
+ Ok(key_path)
}
// simple-key = quoted-key / unquoted-key
@@ -88,6 +112,8 @@ const UNQUOTED_CHAR: (
const DOT_SEP: u8 = b'.';
#[cfg(test)]
+#[cfg(feature = "parse")]
+#[cfg(feature = "display")]
mod test {
use super::*;
@@ -96,7 +122,7 @@ mod test {
let cases = [
("a", "a"),
(r#""hello\n ""#, "hello\n "),
- (r#"'hello\n '"#, "hello\\n "),
+ (r"'hello\n '", "hello\\n "),
];
for (input, expected) in cases {
diff --git a/src/parser/mod.rs b/src/parser/mod.rs
index 1b3cc4f..e032202 100644
--- a/src/parser/mod.rs
+++ b/src/parser/mod.rs
@@ -3,7 +3,7 @@
pub(crate) mod array;
pub(crate) mod datetime;
pub(crate) mod document;
-pub(crate) mod errors;
+pub(crate) mod error;
pub(crate) mod inline_table;
pub(crate) mod key;
pub(crate) mod numbers;
@@ -13,7 +13,7 @@ pub(crate) mod table;
pub(crate) mod trivia;
pub(crate) mod value;
-pub use errors::TomlError;
+pub use crate::error::TomlError;
pub(crate) fn parse_document(raw: &str) -> Result<crate::Document, TomlError> {
use prelude::*;
@@ -95,11 +95,11 @@ pub(crate) mod prelude {
#[cfg(not(feature = "unbounded"))]
impl RecursionCheck {
- pub(crate) fn check_depth(depth: usize) -> Result<(), super::errors::CustomError> {
+ pub(crate) fn check_depth(depth: usize) -> Result<(), super::error::CustomError> {
if depth < 128 {
Ok(())
} else {
- Err(super::errors::CustomError::RecursionLimitExceeded)
+ Err(super::error::CustomError::RecursionLimitExceeded)
}
}
@@ -114,7 +114,7 @@ pub(crate) mod prelude {
Err(winnow::error::ErrMode::from_external_error(
input,
winnow::error::ErrorKind::Eof,
- super::errors::CustomError::RecursionLimitExceeded,
+ super::error::CustomError::RecursionLimitExceeded,
))
}
}
@@ -126,7 +126,7 @@ pub(crate) mod prelude {
#[cfg(feature = "unbounded")]
impl RecursionCheck {
- pub(crate) fn check_depth(_depth: usize) -> Result<(), super::errors::CustomError> {
+ pub(crate) fn check_depth(_depth: usize) -> Result<(), super::error::CustomError> {
Ok(())
}
@@ -140,6 +140,8 @@ pub(crate) mod prelude {
}
#[cfg(test)]
+#[cfg(feature = "parse")]
+#[cfg(feature = "display")]
mod test {
use super::*;
@@ -182,10 +184,10 @@ hosts = [
"omega"
]
- 'some.wierd .stuff' = """
+ 'some.weird .stuff' = """
like
that
- # """ # this broke my sintax highlighting
+ # """ # this broke my syntax highlighting
" also. like " = '''
that
'''
diff --git a/src/parser/numbers.rs b/src/parser/numbers.rs
index 6e4757f..9681526 100644
--- a/src/parser/numbers.rs
+++ b/src/parser/numbers.rs
@@ -301,7 +301,7 @@ pub(crate) fn inf(input: &mut Input<'_>) -> PResult<f64> {
const INF: &[u8] = b"inf";
// nan = %x6e.61.6e ; nan
pub(crate) fn nan(input: &mut Input<'_>) -> PResult<f64> {
- tag(NAN).value(f64::NAN).parse_next(input)
+ tag(NAN).value(f64::NAN.copysign(1.0)).parse_next(input)
}
const NAN: &[u8] = b"nan";
@@ -319,6 +319,8 @@ pub(crate) const HEXDIG: (RangeInclusive<u8>, RangeInclusive<u8>, RangeInclusive
(DIGIT, b'A'..=b'F', b'a'..=b'f');
#[cfg(test)]
+#[cfg(feature = "parse")]
+#[cfg(feature = "display")]
mod test {
use super::*;
@@ -353,6 +355,7 @@ mod test {
fn assert_float_eq(actual: f64, expected: f64) {
if expected.is_nan() {
assert!(actual.is_nan());
+ assert_eq!(expected.is_sign_positive(), actual.is_sign_positive());
} else if expected.is_infinite() {
assert!(actual.is_infinite());
assert_eq!(expected.is_sign_positive(), actual.is_sign_positive());
@@ -376,9 +379,9 @@ mod test {
("9_224_617.445_991_228_313", 9_224_617.445_991_227),
("-1.7976931348623157e+308", std::f64::MIN),
("1.7976931348623157e+308", std::f64::MAX),
- ("nan", f64::NAN),
- ("+nan", f64::NAN),
- ("-nan", f64::NAN),
+ ("nan", f64::NAN.copysign(1.0)),
+ ("+nan", f64::NAN.copysign(1.0)),
+ ("-nan", f64::NAN.copysign(-1.0)),
("inf", f64::INFINITY),
("+inf", f64::INFINITY),
("-inf", f64::NEG_INFINITY),
diff --git a/src/parser/state.rs b/src/parser/state.rs
index efa884d..187dd5f 100644
--- a/src/parser/state.rs
+++ b/src/parser/state.rs
@@ -1,5 +1,5 @@
use crate::key::Key;
-use crate::parser::errors::CustomError;
+use crate::parser::error::CustomError;
use crate::repr::Decor;
use crate::table::TableKeyValue;
use crate::{ArrayOfTables, Document, InternalString, Item, RawString, Table};
@@ -39,26 +39,21 @@ impl ParseState {
pub(crate) fn on_keyval(
&mut self,
- mut path: Vec<Key>,
+ path: Vec<Key>,
mut kv: TableKeyValue,
) -> Result<(), CustomError> {
{
let mut prefix = self.trailing.take();
- let first_key = if path.is_empty() {
- &mut kv.key
- } else {
- &mut path[0]
- };
let prefix = match (
prefix.take(),
- first_key.decor.prefix().and_then(|d| d.span()),
+ kv.key.leaf_decor.prefix().and_then(|d| d.span()),
) {
(Some(p), Some(k)) => Some(p.start..k.end),
(Some(p), None) | (None, Some(p)) => Some(p),
(None, None) => None,
};
- first_key
- .decor
+ kv.key
+ .leaf_decor
.set_prefix(prefix.map(RawString::with_span).unwrap_or_default());
}
@@ -94,7 +89,7 @@ impl ParseState {
Ok(())
}
- pub(crate) fn start_aray_table(
+ pub(crate) fn start_array_table(
&mut self,
path: Vec<Key>,
decor: Decor,
@@ -217,9 +212,9 @@ impl ParseState {
Ok(())
}
- pub(crate) fn descend_path<'t, 'k>(
+ pub(crate) fn descend_path<'t>(
mut table: &'t mut Table,
- path: &'k [Key],
+ path: &[Key],
dotted: bool,
) -> Result<&'t mut Table, CustomError> {
for (i, key) in path.iter().enumerate() {
@@ -297,7 +292,7 @@ impl ParseState {
.take()
.map(RawString::with_span)
.unwrap_or_default();
- self.start_aray_table(
+ self.start_array_table(
path,
Decor::new(leading, RawString::with_span(trailing)),
span,
diff --git a/src/parser/strings.rs b/src/parser/strings.rs
index 26f9cc2..675b5c6 100644
--- a/src/parser/strings.rs
+++ b/src/parser/strings.rs
@@ -21,7 +21,7 @@ use winnow::token::tag;
use winnow::token::take_while;
use winnow::trace::trace;
-use crate::parser::errors::CustomError;
+use crate::parser::error::CustomError;
use crate::parser::numbers::HEXDIG;
use crate::parser::prelude::*;
use crate::parser::trivia::{from_utf8_unchecked, newline, ws, ws_newlines, NON_ASCII, WSCHAR};
@@ -363,6 +363,8 @@ fn mll_quotes<'i>(
}
#[cfg(test)]
+#[cfg(feature = "parse")]
+#[cfg(feature = "display")]
mod test {
use super::*;
@@ -440,10 +442,10 @@ The quick brown \
#[test]
fn literal_string() {
let inputs = [
- r#"'C:\Users\nodejs\templates'"#,
- r#"'\\ServerX\admin$\system32\'"#,
+ r"'C:\Users\nodejs\templates'",
+ r"'\\ServerX\admin$\system32\'",
r#"'Tom "Dubs" Preston-Werner'"#,
- r#"'<\i\c*\s*>'"#,
+ r"'<\i\c*\s*>'",
];
for input in &inputs {
@@ -456,7 +458,7 @@ The quick brown \
#[test]
fn ml_literal_string() {
let inputs = [
- r#"'''I [dw]on't need \d{2} apples'''"#,
+ r"'''I [dw]on't need \d{2} apples'''",
r#"''''one_quote''''"#,
];
for input in &inputs {
diff --git a/src/parser/trivia.rs b/src/parser/trivia.rs
index a359805..4575fb1 100644
--- a/src/parser/trivia.rs
+++ b/src/parser/trivia.rs
@@ -120,6 +120,8 @@ pub(crate) fn line_trailing(input: &mut Input<'_>) -> PResult<std::ops::Range<us
}
#[cfg(test)]
+#[cfg(feature = "parse")]
+#[cfg(feature = "display")]
mod test {
use super::*;
diff --git a/src/parser/value.rs b/src/parser/value.rs
index 14cd951..33300ec 100644
--- a/src/parser/value.rs
+++ b/src/parser/value.rs
@@ -121,6 +121,8 @@ fn apply_raw(mut val: Value, span: std::ops::Range<usize>) -> Result<Value, std:
}
#[cfg(test)]
+#[cfg(feature = "parse")]
+#[cfg(feature = "display")]
mod test {
use super::*;
@@ -131,7 +133,7 @@ mod test {
"-239",
"1e200",
"9_224_617.445_991_228_313",
- r#"'''I [dw]on't need \d{2} apples'''"#,
+ r"'''I [dw]on't need \d{2} apples'''",
r#"'''
The first newline is
trimmed in raw strings.
diff --git a/src/raw_string.rs b/src/raw_string.rs
index c5961f1..53714a1 100644
--- a/src/raw_string.rs
+++ b/src/raw_string.rs
@@ -80,6 +80,7 @@ impl RawString {
}
}
+ #[cfg(feature = "display")]
pub(crate) fn encode(&self, buf: &mut dyn std::fmt::Write, input: &str) -> std::fmt::Result {
let raw = self.to_str(input);
for part in raw.split('\r') {
@@ -88,6 +89,7 @@ impl RawString {
Ok(())
}
+ #[cfg(feature = "display")]
pub(crate) fn encode_with_default(
&self,
buf: &mut dyn std::fmt::Write,
diff --git a/src/repr.rs b/src/repr.rs
index d4ab6c2..ad41bbf 100644
--- a/src/repr.rs
+++ b/src/repr.rs
@@ -44,11 +44,13 @@ where
}
/// Returns the default raw representation.
+ #[cfg(feature = "display")]
pub fn default_repr(&self) -> Repr {
self.value.to_repr()
}
/// Returns a raw representation.
+ #[cfg(feature = "display")]
pub fn display_repr(&self) -> Cow<str> {
self.as_repr()
.and_then(|r| r.as_raw().as_str())
@@ -82,7 +84,7 @@ where
/// Auto formats the value.
pub fn fmt(&mut self) {
- self.repr = Some(self.value.to_repr());
+ self.repr = None;
}
}
@@ -103,20 +105,33 @@ where
}
}
+#[cfg(feature = "display")]
impl<T> std::fmt::Display for Formatted<T>
where
T: ValueRepr,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- crate::encode::Encode::encode(self, f, None, ("", ""))
+ crate::encode::encode_formatted(self, f, None, ("", ""))
}
}
pub trait ValueRepr: crate::private::Sealed {
/// The TOML representation of the value
+ #[cfg(feature = "display")]
fn to_repr(&self) -> Repr;
}
+#[cfg(not(feature = "display"))]
+mod inner {
+ use super::ValueRepr;
+
+ impl ValueRepr for String {}
+ impl ValueRepr for i64 {}
+ impl ValueRepr for f64 {}
+ impl ValueRepr for bool {}
+ impl ValueRepr for toml_datetime::Datetime {}
+}
+
/// TOML-encoded value
#[derive(Eq, PartialEq, Clone, Hash)]
pub struct Repr {
@@ -144,6 +159,7 @@ impl Repr {
self.raw_value.despan(input)
}
+ #[cfg(feature = "display")]
pub(crate) fn encode(&self, buf: &mut dyn std::fmt::Write, input: &str) -> std::fmt::Result {
self.as_raw().encode(buf, input)
}
@@ -185,6 +201,7 @@ impl Decor {
self.prefix.as_ref()
}
+ #[cfg(feature = "display")]
pub(crate) fn prefix_encode(
&self,
buf: &mut dyn std::fmt::Write,
@@ -208,6 +225,7 @@ impl Decor {
self.suffix.as_ref()
}
+ #[cfg(feature = "display")]
pub(crate) fn suffix_encode(
&self,
buf: &mut dyn std::fmt::Write,
diff --git a/src/ser/map.rs b/src/ser/map.rs
index d743e3d..47e56ba 100644
--- a/src/ser/map.rs
+++ b/src/ser/map.rs
@@ -1,4 +1,4 @@
-use super::{Error, KeySerializer};
+use super::{Error, KeySerializer, SerializeValueArray, ValueSerializer};
#[doc(hidden)]
pub enum SerializeMap {
@@ -165,7 +165,6 @@ impl serde::ser::SerializeMap for SerializeInlineTable {
where
T: serde::ser::Serialize,
{
- self.key = None;
self.key = Some(input.serialize(KeySerializer)?);
Ok(())
}
@@ -174,7 +173,8 @@ impl serde::ser::SerializeMap for SerializeInlineTable {
where
T: serde::ser::Serialize,
{
- let res = value.serialize(super::ValueSerializer {});
+ let mut value_serializer = MapValueSerializer::new();
+ let res = value.serialize(&mut value_serializer);
match res {
Ok(item) => {
let key = self.key.take().unwrap();
@@ -185,7 +185,7 @@ impl serde::ser::SerializeMap for SerializeInlineTable {
self.items.insert(key, kv);
}
Err(e) => {
- if e != Error::UnsupportedNone {
+ if !(e == Error::UnsupportedNone && value_serializer.is_none) {
return Err(e);
}
}
@@ -210,7 +210,8 @@ impl serde::ser::SerializeStruct for SerializeInlineTable {
where
T: serde::ser::Serialize,
{
- let res = value.serialize(super::ValueSerializer {});
+ let mut value_serializer = MapValueSerializer::new();
+ let res = value.serialize(&mut value_serializer);
match res {
Ok(item) => {
let kv = crate::table::TableKeyValue::new(
@@ -220,7 +221,7 @@ impl serde::ser::SerializeStruct for SerializeInlineTable {
self.items.insert(crate::InternalString::from(key), kv);
}
Err(e) => {
- if e != Error::UnsupportedNone {
+ if !(e == Error::UnsupportedNone && value_serializer.is_none) {
return Err(e);
}
}
@@ -403,3 +404,261 @@ impl serde::ser::Serializer for DatetimeFieldSerializer {
Err(Error::DateInvalid)
}
}
+
+#[derive(Default)]
+struct MapValueSerializer {
+ is_none: bool,
+}
+
+impl MapValueSerializer {
+ fn new() -> Self {
+ Self { is_none: false }
+ }
+}
+
+impl serde::ser::Serializer for &mut MapValueSerializer {
+ type Ok = crate::Value;
+ type Error = Error;
+ type SerializeSeq = super::SerializeValueArray;
+ type SerializeTuple = super::SerializeValueArray;
+ type SerializeTupleStruct = super::SerializeValueArray;
+ type SerializeTupleVariant = super::SerializeTupleVariant;
+ type SerializeMap = super::SerializeMap;
+ type SerializeStruct = super::SerializeMap;
+ type SerializeStructVariant = super::SerializeStructVariant;
+
+ fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_bool(v)
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_i8(v)
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_i16(v)
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_i32(v)
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_i64(v)
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_u8(v)
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_u16(v)
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_u32(v)
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_u64(v)
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_f32(v)
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_f64(v)
+ }
+
+ fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_char(v)
+ }
+
+ fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_str(v)
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_bytes(value)
+ }
+
+ fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+ self.is_none = true;
+ Err(Error::UnsupportedNone)
+ }
+
+ fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ ValueSerializer::new().serialize_some(value)
+ }
+
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_unit()
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_unit_struct(name)
+ }
+
+ fn serialize_unit_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Self::Ok, Self::Error> {
+ ValueSerializer::new().serialize_unit_variant(name, variant_index, variant)
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ name: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ ValueSerializer::new().serialize_newtype_struct(name, value)
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ ValueSerializer::new().serialize_newtype_variant(name, variant_index, variant, value)
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ ValueSerializer::new().serialize_seq(len)
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ ValueSerializer::new().serialize_tuple(len)
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+ ValueSerializer::new().serialize_tuple_struct(name, len)
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+ ValueSerializer::new().serialize_tuple_variant(name, variant_index, variant, len)
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ ValueSerializer::new().serialize_map(len)
+ }
+
+ fn serialize_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStruct, Self::Error> {
+ ValueSerializer::new().serialize_struct(name, len)
+ }
+
+ fn serialize_struct_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant, Self::Error> {
+ ValueSerializer::new().serialize_struct_variant(name, variant_index, variant, len)
+ }
+}
+
+pub type SerializeTupleVariant = SerializeVariant<SerializeValueArray>;
+pub type SerializeStructVariant = SerializeVariant<SerializeMap>;
+
+pub struct SerializeVariant<T> {
+ variant: &'static str,
+ inner: T,
+}
+
+impl SerializeVariant<SerializeValueArray> {
+ pub(crate) fn tuple(variant: &'static str, len: usize) -> Self {
+ Self {
+ variant,
+ inner: SerializeValueArray::with_capacity(len),
+ }
+ }
+}
+
+impl SerializeVariant<SerializeMap> {
+ pub(crate) fn struct_(variant: &'static str, len: usize) -> Self {
+ Self {
+ variant,
+ inner: SerializeMap::table_with_capacity(len),
+ }
+ }
+}
+
+impl serde::ser::SerializeTupleVariant for SerializeVariant<SerializeValueArray> {
+ type Ok = crate::Value;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: serde::ser::Serialize,
+ {
+ serde::ser::SerializeSeq::serialize_element(&mut self.inner, value)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ let inner = serde::ser::SerializeSeq::end(self.inner)?;
+ let mut items = crate::table::KeyValuePairs::new();
+ let kv = crate::table::TableKeyValue::new(
+ crate::Key::new(self.variant),
+ crate::Item::Value(inner),
+ );
+ items.insert(crate::InternalString::from(self.variant), kv);
+ Ok(crate::Value::InlineTable(crate::InlineTable::with_pairs(
+ items,
+ )))
+ }
+}
+
+impl serde::ser::SerializeStructVariant for SerializeVariant<SerializeMap> {
+ type Ok = crate::Value;
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
+ where
+ T: serde::ser::Serialize + ?Sized,
+ {
+ serde::ser::SerializeStruct::serialize_field(&mut self.inner, key, value)
+ }
+
+ #[inline]
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ let inner = serde::ser::SerializeStruct::end(self.inner)?;
+ let mut items = crate::table::KeyValuePairs::new();
+ let kv = crate::table::TableKeyValue::new(
+ crate::Key::new(self.variant),
+ crate::Item::Value(inner),
+ );
+ items.insert(crate::InternalString::from(self.variant), kv);
+ Ok(crate::Value::InlineTable(crate::InlineTable::with_pairs(
+ items,
+ )))
+ }
+}
diff --git a/src/ser/mod.rs b/src/ser/mod.rs
index 2c31020..ba31708 100644
--- a/src/ser/mod.rs
+++ b/src/ser/mod.rs
@@ -24,7 +24,7 @@ pub enum Error {
OutOfRange(Option<&'static str>),
/// `None` could not be serialized to TOML
UnsupportedNone,
- /// Key was not convertable to `String` for serializing to TOML
+ /// Key was not convertible to `String` for serializing to TOML
KeyNotString,
/// A serialized date was invalid
DateInvalid,
@@ -84,6 +84,7 @@ impl std::error::Error for Error {}
/// Serialization can fail if `T`'s implementation of `Serialize` decides to
/// fail, if `T` contains a map with non-string keys, or if `T` attempts to
/// serialize an unsupported datatype such as an enum, tuple, or tuple struct.
+#[cfg(feature = "display")]
pub fn to_vec<T: ?Sized>(value: &T) -> Result<Vec<u8>, Error>
where
T: serde::ser::Serialize,
@@ -127,6 +128,7 @@ where
/// let toml = toml_edit::ser::to_string(&config).unwrap();
/// println!("{}", toml)
/// ```
+#[cfg(feature = "display")]
pub fn to_string<T: ?Sized>(value: &T) -> Result<String, Error>
where
T: serde::ser::Serialize,
@@ -138,6 +140,7 @@ where
///
/// This is identical to `to_string` except the output string has a more
/// "pretty" output. See `ValueSerializer::pretty` for more details.
+#[cfg(feature = "display")]
pub fn to_string_pretty<T: ?Sized>(value: &T) -> Result<String, Error>
where
T: serde::ser::Serialize,
diff --git a/src/ser/value.rs b/src/ser/value.rs
index d29390a..47a17a3 100644
--- a/src/ser/value.rs
+++ b/src/ser/value.rs
@@ -60,10 +60,10 @@ impl serde::ser::Serializer for ValueSerializer {
type SerializeSeq = super::SerializeValueArray;
type SerializeTuple = super::SerializeValueArray;
type SerializeTupleStruct = super::SerializeValueArray;
- type SerializeTupleVariant = super::SerializeValueArray;
+ type SerializeTupleVariant = super::SerializeTupleVariant;
type SerializeMap = super::SerializeMap;
type SerializeStruct = super::SerializeMap;
- type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
+ type SerializeStructVariant = super::SerializeStructVariant;
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
Ok(v.into())
@@ -108,7 +108,17 @@ impl serde::ser::Serializer for ValueSerializer {
self.serialize_f64(v as f64)
}
- fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
+ fn serialize_f64(self, mut v: f64) -> Result<Self::Ok, Self::Error> {
+ // Discard sign of NaN when serialized using Serde.
+ //
+ // In all likelihood the sign of NaNs is not meaningful in the user's
+ // program. Ending up with `-nan` in the TOML document would usually be
+ // surprising and undesirable, when the sign of the NaN was not
+ // intentionally controlled by the caller, or may even be
+ // nondeterministic if it comes from arithmetic operations or a cast.
+ if v.is_nan() {
+ v = v.copysign(1.0);
+ }
Ok(v.into())
}
@@ -205,10 +215,10 @@ impl serde::ser::Serializer for ValueSerializer {
self,
_name: &'static str,
_variant_index: u32,
- _variant: &'static str,
+ variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
- self.serialize_seq(Some(len))
+ Ok(super::SerializeTupleVariant::tuple(variant, len))
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
@@ -233,11 +243,11 @@ impl serde::ser::Serializer for ValueSerializer {
fn serialize_struct_variant(
self,
- name: &'static str,
+ _name: &'static str,
_variant_index: u32,
- _variant: &'static str,
- _len: usize,
+ variant: &'static str,
+ len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
- Err(Error::UnsupportedType(Some(name)))
+ Ok(super::SerializeStructVariant::struct_(variant, len))
}
}
diff --git a/src/table.rs b/src/table.rs
index 45d6d61..cc0d2b2 100644
--- a/src/table.rs
+++ b/src/table.rs
@@ -70,10 +70,10 @@ impl Table {
values
}
- fn append_values<'s, 'c>(
+ fn append_values<'s>(
&'s self,
parent: &[&'s Key],
- values: &'c mut Vec<(Vec<&'s Key>, &'s Value)>,
+ values: &mut Vec<(Vec<&'s Key>, &'s Value)>,
) {
for value in self.items.values() {
let mut path = parent.to_vec();
@@ -165,11 +165,15 @@ impl Table {
/// In the document above, tables `target` and `target."x86_64/windows.json"` are implicit.
///
/// ```
+ /// # #[cfg(feature = "parse")] {
+ /// # #[cfg(feature = "display")] {
/// use toml_edit::Document;
/// let mut doc = "[a]\n[a.b]\n".parse::<Document>().expect("invalid toml");
///
/// doc["a"].as_table_mut().unwrap().set_implicit(true);
/// assert_eq!(doc.to_string(), "[a.b]\n");
+ /// # }
+ /// # }
/// ```
pub fn set_implicit(&mut self, implicit: bool) {
self.implicit = implicit;
@@ -214,14 +218,28 @@ impl Table {
&self.decor
}
+ /// Returns an accessor to a key's formatting
+ pub fn key(&self, key: &str) -> Option<&'_ Key> {
+ self.items.get(key).map(|kv| &kv.key)
+ }
+
+ /// Returns an accessor to a key's formatting
+ pub fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
+ self.items.get_mut(key).map(|kv| kv.key.as_mut())
+ }
+
/// Returns the decor associated with a given key of the table.
+ #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
pub fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
- self.items.get_mut(key).map(|kv| &mut kv.key.decor)
+ #![allow(deprecated)]
+ self.items.get_mut(key).map(|kv| kv.key.leaf_decor_mut())
}
/// Returns the decor associated with a given key of the table.
+ #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
pub fn key_decor(&self, key: &str) -> Option<&Decor> {
- self.items.get(key).map(|kv| &kv.key.decor)
+ #![allow(deprecated)]
+ self.items.get(key).map(|kv| kv.key.leaf_decor())
}
/// Returns the location within the original document
@@ -413,15 +431,15 @@ impl Table {
}
}
+#[cfg(feature = "display")]
impl std::fmt::Display for Table {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- use crate::encode::Encode;
let children = self.get_values();
// print table body
for (key_path, value) in children {
- key_path.as_slice().encode(f, None, DEFAULT_KEY_DECOR)?;
+ crate::encode::encode_key_path_ref(&key_path, f, None, DEFAULT_KEY_DECOR)?;
write!(f, "=")?;
- value.encode(f, None, DEFAULT_VALUE_DECOR)?;
+ crate::encode::encode_value(value, f, None, DEFAULT_VALUE_DECOR)?;
writeln!(f)?;
}
Ok(())
@@ -471,13 +489,14 @@ impl<'s> IntoIterator for &'s Table {
pub(crate) type KeyValuePairs = IndexMap<InternalString, TableKeyValue>;
fn decorate_table(table: &mut Table) {
- for (key_decor, value) in table
+ for (mut key, value) in table
.items
.iter_mut()
- .filter(|&(_, ref kv)| kv.value.is_value())
- .map(|(_, kv)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap()))
+ .filter(|(_, kv)| kv.value.is_value())
+ .map(|(_, kv)| (kv.key.as_mut(), kv.value.as_value_mut().unwrap()))
{
- key_decor.clear();
+ key.leaf_decor_mut().clear();
+ key.dotted_decor_mut().clear();
value.decor_mut().clear();
}
}
@@ -557,9 +576,15 @@ pub trait TableLike: crate::private::Sealed {
/// Check if this is a wrapper for dotted keys, rather than a standard table
fn is_dotted(&self) -> bool;
+ /// Returns an accessor to a key's formatting
+ fn key(&self, key: &str) -> Option<&'_ Key>;
+ /// Returns an accessor to a key's formatting
+ fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>>;
/// Returns the decor associated with a given key of the table.
+ #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor>;
/// Returns the decor associated with a given key of the table.
+ #[deprecated(since = "0.21.1", note = "Replaced with `key_mut`")]
fn key_decor(&self, key: &str) -> Option<&Decor>;
}
@@ -617,10 +642,18 @@ impl TableLike for Table {
self.set_dotted(yes)
}
+ fn key(&self, key: &str) -> Option<&'_ Key> {
+ self.key(key)
+ }
+ fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
+ self.key_mut(key)
+ }
fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
+ #![allow(deprecated)]
self.key_decor_mut(key)
}
fn key_decor(&self, key: &str) -> Option<&Decor> {
+ #![allow(deprecated)]
self.key_decor(key)
}
}
diff --git a/src/value.rs b/src/value.rs
index f10da9a..f416434 100644
--- a/src/value.rs
+++ b/src/value.rs
@@ -4,7 +4,6 @@ use std::str::FromStr;
use toml_datetime::*;
use crate::key::Key;
-use crate::parser;
use crate::repr::{Decor, Formatted};
use crate::{Array, InlineTable, InternalString, RawString};
@@ -190,10 +189,12 @@ impl Value {
/// Sets the prefix and the suffix for value.
/// # Example
/// ```rust
+ /// # #[cfg(feature = "display")] {
/// let mut v = toml_edit::Value::from(42);
/// assert_eq!(&v.to_string(), "42");
/// let d = v.decorated(" ", " ");
/// assert_eq!(&d.to_string(), " 42 ");
+ /// # }
/// ```
pub fn decorated(mut self, prefix: impl Into<RawString>, suffix: impl Into<RawString>) -> Self {
self.decorate(prefix, suffix);
@@ -231,12 +232,13 @@ impl Value {
}
}
+#[cfg(feature = "parse")]
impl FromStr for Value {
type Err = crate::TomlError;
/// Parses a value from a &str
fn from_str(s: &str) -> Result<Self, Self::Err> {
- parser::parse_value(s)
+ crate::parser::parse_value(s)
}
}
@@ -284,6 +286,7 @@ impl From<i64> for Value {
impl From<f64> for Value {
fn from(f: f64) -> Self {
+ // Preserve sign of NaN. It may get written to TOML as `-nan`.
Value::Float(Formatted::new(f))
}
}
@@ -346,9 +349,10 @@ impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for Value {
}
}
+#[cfg(feature = "display")]
impl std::fmt::Display for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- crate::encode::Encode::encode(self, f, None, ("", ""))
+ crate::encode::encode_value(self, f, None, ("", ""))
}
}
@@ -360,6 +364,8 @@ pub(crate) const DEFAULT_TRAILING_VALUE_DECOR: (&str, &str) = (" ", " ");
pub(crate) const DEFAULT_LEADING_VALUE_DECOR: (&str, &str) = ("", "");
#[cfg(test)]
+#[cfg(feature = "parse")]
+#[cfg(feature = "display")]
mod tests {
use super::*;
diff --git a/src/visit.rs b/src/visit.rs
index 1bc640a..6d7be0b 100644
--- a/src/visit.rs
+++ b/src/visit.rs
@@ -43,6 +43,7 @@
//! This visitor stores every string in the document.
//!
//! ```
+//! # #[cfg(feature = "parse")] {
//! # use toml_edit::*;
//! use toml_edit::visit::*;
//!
@@ -67,10 +68,11 @@
//! visitor.visit_document(&document);
//!
//! assert_eq!(visitor.strings, vec!["sky-castle", "surrounds-you"]);
+//! # }
//! ```
//!
//! For a more complex example where the visitor has internal state, see `examples/visit.rs`
-//! [on GitHub](https://github.com/ordian/toml_edit/blob/master/examples/visit.rs).
+//! [on GitHub](https://github.com/toml-rs/toml/blob/main/crates/toml_edit/examples/visit.rs).
use crate::{
Array, ArrayOfTables, Datetime, Document, Formatted, InlineTable, Item, Table, TableLike, Value,
diff --git a/src/visit_mut.rs b/src/visit_mut.rs
index 2c2af97..c823cfb 100644
--- a/src/visit_mut.rs
+++ b/src/visit_mut.rs
@@ -45,6 +45,8 @@
//! 2 decimal points.
//!
//! ```
+//! # #[cfg(feature = "parse")] {
+//! # #[cfg(feature = "display")] {
//! # use toml_edit::*;
//! use toml_edit::visit_mut::*;
//!
@@ -80,10 +82,12 @@
//! "#;
//!
//! assert_eq!(format!("{}", document), output);
+//! # }
+//! # }
//! ```
//!
//! For a more complex example where the visitor has internal state, see `examples/visit.rs`
-//! [on GitHub](https://github.com/ordian/toml_edit/blob/master/examples/visit.rs).
+//! [on GitHub](https://github.com/toml-rs/toml/blob/main/crates/toml_edit/examples/visit.rs).
use crate::{
Array, ArrayOfTables, Datetime, Document, Formatted, InlineTable, Item, KeyMut, Table,
diff --git a/tests/decoder_compliance.rs b/tests/decoder_compliance.rs
index 0f0b350..37a9335 100644
--- a/tests/decoder_compliance.rs
+++ b/tests/decoder_compliance.rs
@@ -3,15 +3,7 @@ mod decoder;
fn main() {
let decoder = decoder::Decoder;
let mut harness = toml_test_harness::DecoderHarness::new(decoder);
- harness
- .ignore([
- "valid/spec/float-0.toml", // Test issue; `Decoder` turns `6.626e-34` into `0.0`
- // Unreleased
- "valid/string/escape-esc.toml",
- "valid/string/hex-escape.toml",
- "valid/datetime/no-seconds.toml",
- "valid/inline-table/newline.toml",
- ])
- .unwrap();
+ harness.version("1.0.0");
+ harness.ignore([]).unwrap();
harness.test();
}
diff --git a/tests/encoder_compliance.rs b/tests/encoder_compliance.rs
index ad65d75..355c540 100644
--- a/tests/encoder_compliance.rs
+++ b/tests/encoder_compliance.rs
@@ -5,10 +5,6 @@ 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", // Test issue; `Decoder` turns `6.626e-34` into `0.0`
- ])
- .unwrap();
+ harness.version("1.0.0");
harness.test();
}
diff --git a/tests/fixtures/invalid/array/array.stderr b/tests/fixtures/invalid/array/array.stderr
new file mode 100644
index 0000000..6cb810d
--- /dev/null
+++ b/tests/fixtures/invalid/array/array.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 21
+ |
+1 | double-comma-1 = [1,,2]
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/array/double-comma-1.stderr b/tests/fixtures/invalid/array/double-comma-1.stderr
index 543e1b6..6cb810d 100644
--- a/tests/fixtures/invalid/array/double-comma-1.stderr
+++ b/tests/fixtures/invalid/array/double-comma-1.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 12
+TOML parse error at line 1, column 21
|
-1 | array = [1,,2]
- | ^
+1 | double-comma-1 = [1,,2]
+ | ^
invalid array
expected `]`
diff --git a/tests/fixtures/invalid/array/double-comma-2.stderr b/tests/fixtures/invalid/array/double-comma-2.stderr
index 694d7ec..60ab5b5 100644
--- a/tests/fixtures/invalid/array/double-comma-2.stderr
+++ b/tests/fixtures/invalid/array/double-comma-2.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 14
+TOML parse error at line 1, column 23
|
-1 | array = [1,2,,]
- | ^
+1 | double-comma-2 = [1,2,,]
+ | ^
invalid array
expected `]`
diff --git a/tests/fixtures/invalid/array/extend-defined-aot.stderr b/tests/fixtures/invalid/array/extend-defined-aot.stderr
new file mode 100644
index 0000000..970e0ec
--- /dev/null
+++ b/tests/fixtures/invalid/array/extend-defined-aot.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 3, column 1
+ |
+3 | arr.val1=1
+ | ^
+duplicate key `val1`
diff --git a/tests/fixtures/invalid/array/missing-separator-1.stderr b/tests/fixtures/invalid/array/missing-separator-1.stderr
new file mode 100644
index 0000000..1202bb1
--- /dev/null
+++ b/tests/fixtures/invalid/array/missing-separator-1.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 14
+ |
+1 | arrr = [true false]
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/array/missing-separator.stderr b/tests/fixtures/invalid/array/missing-separator-2.stderr
index 8e21f51..8e21f51 100644
--- a/tests/fixtures/invalid/array/missing-separator.stderr
+++ b/tests/fixtures/invalid/array/missing-separator-2.stderr
diff --git a/tests/fixtures/invalid/array/no-close.stderr b/tests/fixtures/invalid/array/no-close-1.stderr
index a4f0a88..6f0a3e8 100644
--- a/tests/fixtures/invalid/array/no-close.stderr
+++ b/tests/fixtures/invalid/array/no-close-1.stderr
@@ -1,6 +1,6 @@
TOML parse error at line 1, column 24
|
-1 | long_array = [ 1, 2, 3
+1 | no-close-1 = [ 1, 2, 3
| ^
invalid array
expected `]`
diff --git a/tests/fixtures/invalid/array/no-close-2.stderr b/tests/fixtures/invalid/array/no-close-2.stderr
index 81ae5a9..96c4d64 100644
--- a/tests/fixtures/invalid/array/no-close-2.stderr
+++ b/tests/fixtures/invalid/array/no-close-2.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 11
+TOML parse error at line 1, column 18
|
-1 | x = [42 #
- | ^
+1 | no-close-2 = [1,
+ | ^
invalid array
expected `]`
diff --git a/tests/fixtures/invalid/array/no-close-3.stderr b/tests/fixtures/invalid/array/no-close-3.stderr
new file mode 100644
index 0000000..b84e3b9
--- /dev/null
+++ b/tests/fixtures/invalid/array/no-close-3.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 21
+ |
+1 | no-close-3 = [42 #]
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/array/no-close-4.stderr b/tests/fixtures/invalid/array/no-close-4.stderr
new file mode 100644
index 0000000..ecf4224
--- /dev/null
+++ b/tests/fixtures/invalid/array/no-close-4.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 25
+ |
+1 | no-close-4 = [{ key = 42
+ | ^
+invalid inline table
+expected `}`
diff --git a/tests/fixtures/invalid/array/no-close-5.stderr b/tests/fixtures/invalid/array/no-close-5.stderr
new file mode 100644
index 0000000..c5e9674
--- /dev/null
+++ b/tests/fixtures/invalid/array/no-close-5.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 27
+ |
+1 | no-close-5 = [{ key = 42}
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/array/no-close-6.stderr b/tests/fixtures/invalid/array/no-close-6.stderr
new file mode 100644
index 0000000..2512a43
--- /dev/null
+++ b/tests/fixtures/invalid/array/no-close-6.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 26
+ |
+1 | no-close-6 = [{ key = 42 #}]
+ | ^
+invalid inline table
+expected `}`
diff --git a/tests/fixtures/invalid/array/no-close-7.stderr b/tests/fixtures/invalid/array/no-close-7.stderr
new file mode 100644
index 0000000..a49e988
--- /dev/null
+++ b/tests/fixtures/invalid/array/no-close-7.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 30
+ |
+1 | no-close-7 = [{ key = 42} #]
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/array/no-close-8.stderr b/tests/fixtures/invalid/array/no-close-8.stderr
new file mode 100644
index 0000000..0e25a0b
--- /dev/null
+++ b/tests/fixtures/invalid/array/no-close-8.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 16
+ |
+1 | no-close-8 = [
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/array/no-close-table.stderr b/tests/fixtures/invalid/array/no-close-table-1.stderr
index b4c3c32..b4c3c32 100644
--- a/tests/fixtures/invalid/array/no-close-table.stderr
+++ b/tests/fixtures/invalid/array/no-close-table-1.stderr
diff --git a/tests/fixtures/invalid/array/no-comma-1.stderr b/tests/fixtures/invalid/array/no-comma-1.stderr
new file mode 100644
index 0000000..e50fb69
--- /dev/null
+++ b/tests/fixtures/invalid/array/no-comma-1.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 20
+ |
+1 | no-comma-1 = [true false]
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/array/no-comma-2.stderr b/tests/fixtures/invalid/array/no-comma-2.stderr
new file mode 100644
index 0000000..b34d709
--- /dev/null
+++ b/tests/fixtures/invalid/array/no-comma-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 18
+ |
+1 | no-comma-2 = [ 1 2 3 ]
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/array/no-comma-3.stderr b/tests/fixtures/invalid/array/no-comma-3.stderr
new file mode 100644
index 0000000..c7cbec4
--- /dev/null
+++ b/tests/fixtures/invalid/array/no-comma-3.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 22
+ |
+1 | no-comma-3 = [ 1 #,]
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/array/only-comma-1.stderr b/tests/fixtures/invalid/array/only-comma-1.stderr
new file mode 100644
index 0000000..3616ca9
--- /dev/null
+++ b/tests/fixtures/invalid/array/only-comma-1.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 17
+ |
+1 | only-comma-1 = [,]
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/array/only-comma-2.stderr b/tests/fixtures/invalid/array/only-comma-2.stderr
new file mode 100644
index 0000000..8284be5
--- /dev/null
+++ b/tests/fixtures/invalid/array/only-comma-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 17
+ |
+1 | only-comma-2 = [,,]
+ | ^
+invalid array
+expected `]`
diff --git a/tests/fixtures/invalid/bool/almost-false-with-extra.stderr b/tests/fixtures/invalid/bool/almost-false-with-extra.stderr
index cd6c1cd..1517084 100644
--- a/tests/fixtures/invalid/bool/almost-false-with-extra.stderr
+++ b/tests/fixtures/invalid/bool/almost-false-with-extra.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 5
+TOML parse error at line 1, column 27
|
-1 | a = falsify
- | ^
+1 | almost-false-with-extra = falsify
+ | ^
invalid string
expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/almost-false.stderr b/tests/fixtures/invalid/bool/almost-false.stderr
index 550020b..ba22196 100644
--- a/tests/fixtures/invalid/bool/almost-false.stderr
+++ b/tests/fixtures/invalid/bool/almost-false.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 5
+TOML parse error at line 1, column 27
|
-1 | a = fals
- | ^
+1 | almost-false = fals
+ | ^
invalid string
expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/almost-true-with-extra.stderr b/tests/fixtures/invalid/bool/almost-true-with-extra.stderr
index c75c553..23e230e 100644
--- a/tests/fixtures/invalid/bool/almost-true-with-extra.stderr
+++ b/tests/fixtures/invalid/bool/almost-true-with-extra.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 5
+TOML parse error at line 1, column 27
|
-1 | a = truthy
- | ^
+1 | almost-true-with-extra = truthy
+ | ^
invalid string
expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/almost-true.stderr b/tests/fixtures/invalid/bool/almost-true.stderr
index 0c97e00..21bdf37 100644
--- a/tests/fixtures/invalid/bool/almost-true.stderr
+++ b/tests/fixtures/invalid/bool/almost-true.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 5
+TOML parse error at line 1, column 27
|
-1 | a = tru
- | ^
+1 | almost-true = tru
+ | ^
invalid string
expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/bool.stderr b/tests/fixtures/invalid/bool/bool.stderr
new file mode 100644
index 0000000..1517084
--- /dev/null
+++ b/tests/fixtures/invalid/bool/bool.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 27
+ |
+1 | almost-false-with-extra = falsify
+ | ^
+invalid string
+expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/capitalized-false.stderr b/tests/fixtures/invalid/bool/capitalized-false.stderr
new file mode 100644
index 0000000..fd318ca
--- /dev/null
+++ b/tests/fixtures/invalid/bool/capitalized-false.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 28
+ |
+1 | capitalized-false = False
+ | ^
+invalid string
+expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/capitalized-true.stderr b/tests/fixtures/invalid/bool/capitalized-true.stderr
new file mode 100644
index 0000000..cb32d8e
--- /dev/null
+++ b/tests/fixtures/invalid/bool/capitalized-true.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 28
+ |
+1 | capitalized-true = True
+ | ^
+invalid string
+expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/just-f.stderr b/tests/fixtures/invalid/bool/just-f.stderr
index ed2b9f0..cc4fb78 100644
--- a/tests/fixtures/invalid/bool/just-f.stderr
+++ b/tests/fixtures/invalid/bool/just-f.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 5
+TOML parse error at line 1, column 27
|
-1 | a = f
- | ^
+1 | just-f = f
+ | ^
invalid string
expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/just-t.stderr b/tests/fixtures/invalid/bool/just-t.stderr
index 2c8b6a5..f2d889b 100644
--- a/tests/fixtures/invalid/bool/just-t.stderr
+++ b/tests/fixtures/invalid/bool/just-t.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 5
+TOML parse error at line 1, column 27
|
-1 | a = t
- | ^
+1 | just-t = t
+ | ^
invalid string
expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/mixed-case-false.stderr b/tests/fixtures/invalid/bool/mixed-case-false.stderr
new file mode 100644
index 0000000..d96dc60
--- /dev/null
+++ b/tests/fixtures/invalid/bool/mixed-case-false.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 27
+ |
+1 | mixed-case-false = falsE
+ | ^
+invalid string
+expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/mixed-case-true.stderr b/tests/fixtures/invalid/bool/mixed-case-true.stderr
new file mode 100644
index 0000000..e7f8289
--- /dev/null
+++ b/tests/fixtures/invalid/bool/mixed-case-true.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 27
+ |
+1 | mixed-case-true = trUe
+ | ^
+invalid string
+expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/mixed-case.stderr b/tests/fixtures/invalid/bool/mixed-case.stderr
index b7c6192..994020e 100644
--- a/tests/fixtures/invalid/bool/mixed-case.stderr
+++ b/tests/fixtures/invalid/bool/mixed-case.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 9
+TOML parse error at line 1, column 27
|
-1 | valid = False
- | ^
+1 | mixed-case = valid = False
+ | ^
invalid string
expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/starting-same-false.stderr b/tests/fixtures/invalid/bool/starting-same-false.stderr
index b332089..1cc00d5 100644
--- a/tests/fixtures/invalid/bool/starting-same-false.stderr
+++ b/tests/fixtures/invalid/bool/starting-same-false.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 10
+TOML parse error at line 1, column 32
|
-1 | a = falsey
- | ^
+1 | starting-same-false = falsey
+ | ^
expected newline, `#`
diff --git a/tests/fixtures/invalid/bool/starting-same-true.stderr b/tests/fixtures/invalid/bool/starting-same-true.stderr
index 6053103..a7cc00b 100644
--- a/tests/fixtures/invalid/bool/starting-same-true.stderr
+++ b/tests/fixtures/invalid/bool/starting-same-true.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 9
+TOML parse error at line 1, column 31
|
-1 | a = truer
- | ^
+1 | starting-same-true = truer
+ | ^
expected newline, `#`
diff --git a/tests/fixtures/invalid/bool/wrong-case-false.stderr b/tests/fixtures/invalid/bool/wrong-case-false.stderr
index f67444c..fd15caa 100644
--- a/tests/fixtures/invalid/bool/wrong-case-false.stderr
+++ b/tests/fixtures/invalid/bool/wrong-case-false.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 5
+TOML parse error at line 1, column 27
|
-1 | b = FALSE
- | ^
+1 | wrong-case-false = FALSE
+ | ^
invalid string
expected `"`, `'`
diff --git a/tests/fixtures/invalid/bool/wrong-case-true.stderr b/tests/fixtures/invalid/bool/wrong-case-true.stderr
index 82bb619..bc60a4c 100644
--- a/tests/fixtures/invalid/bool/wrong-case-true.stderr
+++ b/tests/fixtures/invalid/bool/wrong-case-true.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 5
+TOML parse error at line 1, column 27
|
-1 | a = TRUE
- | ^
+1 | wrong-case-true = TRUE
+ | ^
invalid string
expected `"`, `'`
diff --git a/tests/fixtures/invalid/control/bare-formfeed.stderr b/tests/fixtures/invalid/control/bare-formfeed.stderr
index 313274a..449ec87 100644
--- a/tests/fixtures/invalid/control/bare-formfeed.stderr
+++ b/tests/fixtures/invalid/control/bare-formfeed.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 17
+TOML parse error at line 1, column 21
|
-1 | bare-formfeed =
- | ^
+1 | bare-formfeed =
+ | ^
invalid string
expected `"`, `'`
diff --git a/tests/fixtures/invalid/control/bare-null.stderr b/tests/fixtures/invalid/control/bare-null.stderr
index cd5e936..9c8231d 100644
--- a/tests/fixtures/invalid/control/bare-null.stderr
+++ b/tests/fixtures/invalid/control/bare-null.stderr
Binary files differ
diff --git a/tests/fixtures/invalid/control/comment-cr.stderr b/tests/fixtures/invalid/control/comment-cr.stderr
index fb262e5..54e42df 100644
--- a/tests/fixtures/invalid/control/comment-cr.stderr
+++ b/tests/fixtures/invalid/control/comment-cr.stderr
@@ -1,6 +1,6 @@
-TOML parse error at line 1, column 45
+TOML parse error at line 1, column 47
|
-1 | comment-cr = "Carriage return in comment" #
+1 | comment-cr = "Carriage return in comment" #
a=1
- | ^
+ | ^
expected newline, `#`
diff --git a/tests/fixtures/invalid/control/comment-del.stderr b/tests/fixtures/invalid/control/comment-del.stderr
index 3d25d68..5eae7a4 100644
--- a/tests/fixtures/invalid/control/comment-del.stderr
+++ b/tests/fixtures/invalid/control/comment-del.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 24
+TOML parse error at line 1, column 27
|
-1 | comment-del = "0x7f" # 
- | ^
+1 | comment-del = "0x7f" # 
+ | ^
expected newline, `#`
diff --git a/tests/fixtures/invalid/control/comment-ff.stderr b/tests/fixtures/invalid/control/comment-ff.stderr
new file mode 100644
index 0000000..6f54974
--- /dev/null
+++ b/tests/fixtures/invalid/control/comment-ff.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 27
+ |
+1 | comment-ff = "0x7f" #
+ | ^
+expected newline, `#`
diff --git a/tests/fixtures/invalid/control/comment-lf.stderr b/tests/fixtures/invalid/control/comment-lf.stderr
index 1613710..3eacd62 100644
--- a/tests/fixtures/invalid/control/comment-lf.stderr
+++ b/tests/fixtures/invalid/control/comment-lf.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 25
+TOML parse error at line 1, column 27
|
-1 | comment-lf = "ctrl-P" # 
- | ^
+1 | comment-lf = "ctrl-P" # 
+ | ^
expected newline, `#`
diff --git a/tests/fixtures/invalid/control/comment-null.stderr b/tests/fixtures/invalid/control/comment-null.stderr
index 4955b9d..ba5bc80 100644
--- a/tests/fixtures/invalid/control/comment-null.stderr
+++ b/tests/fixtures/invalid/control/comment-null.stderr
Binary files differ
diff --git a/tests/fixtures/invalid/control/comment-us.stderr b/tests/fixtures/invalid/control/comment-us.stderr
index b48d4f3..f34076e 100644
--- a/tests/fixtures/invalid/control/comment-us.stderr
+++ b/tests/fixtures/invalid/control/comment-us.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 25
+TOML parse error at line 1, column 27
|
-1 | comment-us = "ctrl-_" # 
- | ^
+1 | comment-us = "ctrl-_" # 
+ | ^
expected newline, `#`
diff --git a/tests/fixtures/invalid/control/control.stderr b/tests/fixtures/invalid/control/control.stderr
index 486aacf..f214b54 100644
--- a/tests/fixtures/invalid/control/control.stderr
+++ b/tests/fixtures/invalid/control/control.stderr
@@ -1,6 +1,5 @@
-TOML parse error at line 9, column 22
+TOML parse error at line 9, column 1
|
-9 | string-null = "null\x00"
- | ^
-invalid escape sequence
-expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"`
+9 | comment-cr = "Carriage return in comment" # \x0da=1
+ | ^
+duplicate key `comment-cr` in document root
diff --git a/tests/fixtures/invalid/control/multi-cr.stderr b/tests/fixtures/invalid/control/multi-cr.stderr
new file mode 100644
index 0000000..d5c749c
--- /dev/null
+++ b/tests/fixtures/invalid/control/multi-cr.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 21
+ |
+1 | multi-cr = """null
+"""
+ | ^
+invalid multiline basic string
diff --git a/tests/fixtures/invalid/control/multi-del.stderr b/tests/fixtures/invalid/control/multi-del.stderr
index 62702da..a1b54b7 100644
--- a/tests/fixtures/invalid/control/multi-del.stderr
+++ b/tests/fixtures/invalid/control/multi-del.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 20
+TOML parse error at line 1, column 21
|
-1 | multi-del = """null"""
- | ^
+1 | multi-del = """null"""
+ | ^
invalid multiline basic string
diff --git a/tests/fixtures/invalid/control/multi-lf.stderr b/tests/fixtures/invalid/control/multi-lf.stderr
index 7b7a138..a0a8f7b 100644
--- a/tests/fixtures/invalid/control/multi-lf.stderr
+++ b/tests/fixtures/invalid/control/multi-lf.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 19
+TOML parse error at line 1, column 21
|
-1 | multi-lf = """null"""
- | ^
+1 | multi-lf = """null"""
+ | ^
invalid multiline basic string
diff --git a/tests/fixtures/invalid/control/multi-us.stderr b/tests/fixtures/invalid/control/multi-us.stderr
index cf8e732..ac556b2 100644
--- a/tests/fixtures/invalid/control/multi-us.stderr
+++ b/tests/fixtures/invalid/control/multi-us.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 19
+TOML parse error at line 1, column 21
|
-1 | multi-us = """null"""
- | ^
+1 | multi-us = """null"""
+ | ^
invalid multiline basic string
diff --git a/tests/fixtures/invalid/control/rawmulti-cd.stderr b/tests/fixtures/invalid/control/rawmulti-cd.stderr
new file mode 100644
index 0000000..1027009
--- /dev/null
+++ b/tests/fixtures/invalid/control/rawmulti-cd.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 24
+ |
+1 | rawmulti-cd = '''null
+'''
+ | ^
+invalid multiline literal string
diff --git a/tests/fixtures/invalid/control/rawmulti-del.stderr b/tests/fixtures/invalid/control/rawmulti-del.stderr
index 3beeae0..7972a2b 100644
--- a/tests/fixtures/invalid/control/rawmulti-del.stderr
+++ b/tests/fixtures/invalid/control/rawmulti-del.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 23
+TOML parse error at line 1, column 24
|
-1 | rawmulti-del = '''null'''
- | ^
+1 | rawmulti-del = '''null'''
+ | ^
invalid multiline literal string
diff --git a/tests/fixtures/invalid/control/rawmulti-lf.stderr b/tests/fixtures/invalid/control/rawmulti-lf.stderr
index 40782a2..1898ec8 100644
--- a/tests/fixtures/invalid/control/rawmulti-lf.stderr
+++ b/tests/fixtures/invalid/control/rawmulti-lf.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 22
+TOML parse error at line 1, column 24
|
-1 | rawmulti-lf = '''null'''
- | ^
+1 | rawmulti-lf = '''null'''
+ | ^
invalid multiline literal string
diff --git a/tests/fixtures/invalid/control/rawmulti-us.stderr b/tests/fixtures/invalid/control/rawmulti-us.stderr
index d413d54..4c412f7 100644
--- a/tests/fixtures/invalid/control/rawmulti-us.stderr
+++ b/tests/fixtures/invalid/control/rawmulti-us.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 22
+TOML parse error at line 1, column 24
|
-1 | rawmulti-us = '''null'''
- | ^
+1 | rawmulti-us = '''null'''
+ | ^
invalid multiline literal string
diff --git a/tests/fixtures/invalid/control/rawstring-cr.stderr b/tests/fixtures/invalid/control/rawstring-cr.stderr
new file mode 100644
index 0000000..bc8a1a2
--- /dev/null
+++ b/tests/fixtures/invalid/control/rawstring-cr.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 23
+ |
+1 | rawstring-cr = 'null
+'
+ | ^
+invalid literal string
diff --git a/tests/fixtures/invalid/control/rawstring-del.stderr b/tests/fixtures/invalid/control/rawstring-del.stderr
index 640ba46..e80e322 100644
--- a/tests/fixtures/invalid/control/rawstring-del.stderr
+++ b/tests/fixtures/invalid/control/rawstring-del.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 22
+TOML parse error at line 1, column 23
|
-1 | rawstring-del = 'null'
- | ^
+1 | rawstring-del = 'null'
+ | ^
invalid literal string
diff --git a/tests/fixtures/invalid/control/rawstring-lf.stderr b/tests/fixtures/invalid/control/rawstring-lf.stderr
index e6499b6..b8874c6 100644
--- a/tests/fixtures/invalid/control/rawstring-lf.stderr
+++ b/tests/fixtures/invalid/control/rawstring-lf.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 21
+TOML parse error at line 1, column 23
|
-1 | rawstring-lf = 'null'
- | ^
+1 | rawstring-lf = 'null'
+ | ^
invalid literal string
diff --git a/tests/fixtures/invalid/control/rawstring-us.stderr b/tests/fixtures/invalid/control/rawstring-us.stderr
index 492cdf7..9cf3fae 100644
--- a/tests/fixtures/invalid/control/rawstring-us.stderr
+++ b/tests/fixtures/invalid/control/rawstring-us.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 21
+TOML parse error at line 1, column 23
|
-1 | rawstring-us = 'null'
- | ^
+1 | rawstring-us = 'null'
+ | ^
invalid literal string
diff --git a/tests/fixtures/invalid/control/string-bs.stderr b/tests/fixtures/invalid/control/string-bs.stderr
index 556ba1d..3f7b5ee 100644
--- a/tests/fixtures/invalid/control/string-bs.stderr
+++ b/tests/fixtures/invalid/control/string-bs.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 23
+TOML parse error at line 1, column 25
|
-1 | string-bs = "backspace"
- | ^
+1 | string-bs = "backspace"
+ | ^
invalid basic string
diff --git a/tests/fixtures/invalid/control/string-cr.stderr b/tests/fixtures/invalid/control/string-cr.stderr
new file mode 100644
index 0000000..0eff4c2
--- /dev/null
+++ b/tests/fixtures/invalid/control/string-cr.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 20
+ |
+1 | string-cr = "null
+"
+ | ^
+invalid basic string
diff --git a/tests/fixtures/invalid/control/string-del.stderr b/tests/fixtures/invalid/control/string-del.stderr
index 85d7af3..b6ace6b 100644
--- a/tests/fixtures/invalid/control/string-del.stderr
+++ b/tests/fixtures/invalid/control/string-del.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 19
+TOML parse error at line 1, column 20
|
-1 | string-del = "null"
- | ^
+1 | string-del = "null"
+ | ^
invalid basic string
diff --git a/tests/fixtures/invalid/control/string-lf.stderr b/tests/fixtures/invalid/control/string-lf.stderr
index fbf0d1a..c3b141e 100644
--- a/tests/fixtures/invalid/control/string-lf.stderr
+++ b/tests/fixtures/invalid/control/string-lf.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 18
+TOML parse error at line 1, column 20
|
-1 | string-lf = "null"
- | ^
+1 | string-lf = "null"
+ | ^
invalid basic string
diff --git a/tests/fixtures/invalid/control/string-us.stderr b/tests/fixtures/invalid/control/string-us.stderr
index 8278e57..26f2f6a 100644
--- a/tests/fixtures/invalid/control/string-us.stderr
+++ b/tests/fixtures/invalid/control/string-us.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 18
+TOML parse error at line 1, column 20
|
-1 | string-us = "null"
- | ^
+1 | string-us = "null"
+ | ^
invalid basic string
diff --git a/tests/fixtures/invalid/datetime/feb-29.stderr b/tests/fixtures/invalid/datetime/feb-29.stderr
new file mode 100644
index 0000000..63fac67
--- /dev/null
+++ b/tests/fixtures/invalid/datetime/feb-29.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 29
+ |
+1 | "not a leap year" = 2100-02-29T15:15:15Z
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/datetime/feb-30.stderr b/tests/fixtures/invalid/datetime/feb-30.stderr
new file mode 100644
index 0000000..2b5212a
--- /dev/null
+++ b/tests/fixtures/invalid/datetime/feb-30.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 44
+ |
+1 | "only 28 or 29 days in february" = 1988-02-30T15:15:15Z
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/datetime/no-leads-month.stderr b/tests/fixtures/invalid/datetime/no-leads-month.stderr
new file mode 100644
index 0000000..3e0ccf7
--- /dev/null
+++ b/tests/fixtures/invalid/datetime/no-leads-month.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 17
+ |
+2 | no-leads = 1987-7-05T17:45:00Z
+ | ^
+invalid date-time
diff --git a/tests/fixtures/invalid/datetime/time-no-leads.stderr b/tests/fixtures/invalid/datetime/time-no-leads.stderr
index 7a98902..012f62f 100644
--- a/tests/fixtures/invalid/datetime/time-no-leads.stderr
+++ b/tests/fixtures/invalid/datetime/time-no-leads.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 2, column 6
+TOML parse error at line 2, column 15
|
-2 | d = 1:32:00
- | ^
+2 | d = 2023-10-01T1:32:00Z
+ | ^
expected newline, `#`
diff --git a/tests/fixtures/invalid/datetime/y10k.stderr b/tests/fixtures/invalid/datetime/y10k.stderr
new file mode 100644
index 0000000..dc5cfc5
--- /dev/null
+++ b/tests/fixtures/invalid/datetime/y10k.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 10
+ |
+2 | d = 10000-01-01 00:00:00z
+ | ^
+expected newline, `#`
diff --git a/tests/fixtures/invalid/encoding/bad-codepoint.stderr b/tests/fixtures/invalid/encoding/bad-codepoint.stderr
new file mode 100644
index 0000000..89ef2c7
--- /dev/null
+++ b/tests/fixtures/invalid/encoding/bad-codepoint.stderr
@@ -0,0 +1 @@
+invalid utf-8 sequence of 1 bytes from index 29 \ No newline at end of file
diff --git a/tests/fixtures/invalid/encoding/utf16.stderr b/tests/fixtures/invalid/encoding/utf16-comment.stderr
index 6886165..6886165 100644
--- a/tests/fixtures/invalid/encoding/utf16.stderr
+++ b/tests/fixtures/invalid/encoding/utf16-comment.stderr
Binary files differ
diff --git a/tests/fixtures/invalid/encoding/utf16-key.stderr b/tests/fixtures/invalid/encoding/utf16-key.stderr
new file mode 100644
index 0000000..16bedc0
--- /dev/null
+++ b/tests/fixtures/invalid/encoding/utf16-key.stderr
Binary files differ
diff --git a/tests/fixtures/invalid/float/exp-point-3.stderr b/tests/fixtures/invalid/float/exp-point-3.stderr
new file mode 100644
index 0000000..873791c
--- /dev/null
+++ b/tests/fixtures/invalid/float/exp-point-3.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 17
+ |
+1 | exp-point-3 = 3.e+20
+ | ^
+invalid floating-point number
+expected digit
diff --git a/tests/fixtures/invalid/float/exp-trailing-us-1.stderr b/tests/fixtures/invalid/float/exp-trailing-us-1.stderr
new file mode 100644
index 0000000..254bdf2
--- /dev/null
+++ b/tests/fixtures/invalid/float/exp-trailing-us-1.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 23
+ |
+1 | exp-trailing-us-1 = 1_e2
+ | ^
+invalid integer
+expected digit
diff --git a/tests/fixtures/invalid/float/exp-trailing-us-2.stderr b/tests/fixtures/invalid/float/exp-trailing-us-2.stderr
new file mode 100644
index 0000000..b2986ad
--- /dev/null
+++ b/tests/fixtures/invalid/float/exp-trailing-us-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 25
+ |
+1 | exp-trailing-us-2 = 1.2_e2
+ | ^
+invalid floating-point number
+expected digit, digit
diff --git a/tests/fixtures/invalid/float/exp-trailing-us.stderr b/tests/fixtures/invalid/float/exp-trailing-us.stderr
index 9a28184..b7e2ad9 100644
--- a/tests/fixtures/invalid/float/exp-trailing-us.stderr
+++ b/tests/fixtures/invalid/float/exp-trailing-us.stderr
@@ -1,5 +1,6 @@
-TOML parse error at line 1, column 21
+TOML parse error at line 1, column 24
|
-1 | exp-trailing-us = 1e_23_
- | ^
+1 | exp-trailing-us = 1e23_
+ | ^
invalid floating-point number
+expected digit
diff --git a/tests/fixtures/invalid/float/inf-capital.stderr b/tests/fixtures/invalid/float/inf-capital.stderr
new file mode 100644
index 0000000..ca7a1b1
--- /dev/null
+++ b/tests/fixtures/invalid/float/inf-capital.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 5
+ |
+1 | v = Inf
+ | ^
+invalid string
+expected `"`, `'`
diff --git a/tests/fixtures/invalid/float/nan-capital.stderr b/tests/fixtures/invalid/float/nan-capital.stderr
new file mode 100644
index 0000000..ae3b4d9
--- /dev/null
+++ b/tests/fixtures/invalid/float/nan-capital.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 5
+ |
+1 | v = NaN
+ | ^
+invalid string
+expected `"`, `'`
diff --git a/tests/fixtures/invalid/float/trailing-us-exp-1.stderr b/tests/fixtures/invalid/float/trailing-us-exp-1.stderr
new file mode 100644
index 0000000..cf0fabc
--- /dev/null
+++ b/tests/fixtures/invalid/float/trailing-us-exp-1.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 23
+ |
+1 | trailing-us-exp-1 = 1_e2
+ | ^
+invalid integer
+expected digit
diff --git a/tests/fixtures/invalid/float/trailing-us-exp-2.stderr b/tests/fixtures/invalid/float/trailing-us-exp-2.stderr
new file mode 100644
index 0000000..83ff120
--- /dev/null
+++ b/tests/fixtures/invalid/float/trailing-us-exp-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 25
+ |
+1 | trailing-us-exp-2 = 1.2_e2
+ | ^
+invalid floating-point number
+expected digit, digit
diff --git a/tests/fixtures/invalid/float/trailing-us-exp.stderr b/tests/fixtures/invalid/float/trailing-us-exp.stderr
deleted file mode 100644
index 811f951..0000000
--- a/tests/fixtures/invalid/float/trailing-us-exp.stderr
+++ /dev/null
@@ -1,6 +0,0 @@
-TOML parse error at line 2, column 21
- |
-2 | trailing-us-exp = 1_e2
- | ^
-invalid integer
-expected digit
diff --git a/tests/fixtures/invalid/inline-table/bad-key-syntax.stderr b/tests/fixtures/invalid/inline-table/bad-key-syntax.stderr
new file mode 100644
index 0000000..c8ce45a
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/bad-key-syntax.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 14
+ |
+1 | tbl = { a = 1, [b] }
+ | ^
+invalid inline table
+expected `}`
diff --git a/tests/fixtures/invalid/inline-table/duplicate-key.stderr b/tests/fixtures/invalid/inline-table/duplicate-key-1.stderr
index acee967..acee967 100644
--- a/tests/fixtures/invalid/inline-table/duplicate-key.stderr
+++ b/tests/fixtures/invalid/inline-table/duplicate-key-1.stderr
diff --git a/tests/fixtures/invalid/inline-table/duplicate-key-2.stderr b/tests/fixtures/invalid/inline-table/duplicate-key-2.stderr
new file mode 100644
index 0000000..91b41fd
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/duplicate-key-2.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 11
+ |
+1 | table1 = { table2.dupe = 1, table2.dupe = 2 }
+ | ^
+duplicate key `dupe`
diff --git a/tests/fixtures/invalid/inline-table/duplicate-key-3.stderr b/tests/fixtures/invalid/inline-table/duplicate-key-3.stderr
new file mode 100644
index 0000000..79a8041
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/duplicate-key-3.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 8
+ |
+1 | tbl = { fruit = { apple.color = "red" }, fruit.apple.texture = { smooth = true } }
+ | ^
+duplicate key `fruit`
diff --git a/tests/fixtures/invalid/inline-table/duplicate-key-4.stderr b/tests/fixtures/invalid/inline-table/duplicate-key-4.stderr
new file mode 100644
index 0000000..7b86044
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/duplicate-key-4.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 8
+ |
+1 | tbl = { a.b = "a_b", a.b.c = "a_b_c" }
+ | ^
+dotted key `a.b` attempted to extend non-table type (string)
diff --git a/tests/fixtures/invalid/inline-table/empty.stderr b/tests/fixtures/invalid/inline-table/empty-1.stderr
index 0fcfd34..0fcfd34 100644
--- a/tests/fixtures/invalid/inline-table/empty.stderr
+++ b/tests/fixtures/invalid/inline-table/empty-1.stderr
diff --git a/tests/fixtures/invalid/inline-table/empty-2.stderr b/tests/fixtures/invalid/inline-table/empty-2.stderr
new file mode 100644
index 0000000..ea51c18
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/empty-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 6
+ |
+1 | t = {,
+ | ^
+invalid inline table
+expected `}`
diff --git a/tests/fixtures/invalid/inline-table/empty-3.stderr b/tests/fixtures/invalid/inline-table/empty-3.stderr
new file mode 100644
index 0000000..ca4a29a
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/empty-3.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 6
+ |
+1 | t = {
+ | ^
+invalid inline table
+expected `}`
diff --git a/tests/fixtures/invalid/inline-table/no-close-1.stderr b/tests/fixtures/invalid/inline-table/no-close-1.stderr
new file mode 100644
index 0000000..d371b65
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/no-close-1.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 4
+ |
+1 | a={
+ | ^
+invalid inline table
+expected `}`
diff --git a/tests/fixtures/invalid/inline-table/no-close-2.stderr b/tests/fixtures/invalid/inline-table/no-close-2.stderr
new file mode 100644
index 0000000..3b42d78
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/no-close-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 7
+ |
+1 | a={b=1
+ | ^
+invalid inline table
+expected `}`
diff --git a/tests/fixtures/invalid/inline-table/no-comma.stderr b/tests/fixtures/invalid/inline-table/no-comma-1.stderr
index 8955218..8955218 100644
--- a/tests/fixtures/invalid/inline-table/no-comma.stderr
+++ b/tests/fixtures/invalid/inline-table/no-comma-1.stderr
diff --git a/tests/fixtures/invalid/inline-table/no-comma-2.stderr b/tests/fixtures/invalid/inline-table/no-comma-2.stderr
new file mode 100644
index 0000000..128ac53
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/no-comma-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 31
+ |
+1 | arrr = { comma-missing = true valid-toml = false }
+ | ^
+invalid inline table
+expected `}`
diff --git a/tests/fixtures/invalid/inline-table/overwrite.stderr b/tests/fixtures/invalid/inline-table/overwrite-01.stderr
index 5c48ee2..5c48ee2 100644
--- a/tests/fixtures/invalid/inline-table/overwrite.stderr
+++ b/tests/fixtures/invalid/inline-table/overwrite-01.stderr
diff --git a/tests/fixtures/invalid/inline-table/add.stderr b/tests/fixtures/invalid/inline-table/overwrite-02.stderr
index 4108142..4108142 100644
--- a/tests/fixtures/invalid/inline-table/add.stderr
+++ b/tests/fixtures/invalid/inline-table/overwrite-02.stderr
diff --git a/tests/fixtures/invalid/inline-table/overwrite-03.stderr b/tests/fixtures/invalid/inline-table/overwrite-03.stderr
new file mode 100644
index 0000000..c1ab1d7
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/overwrite-03.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 1
+ |
+2 | a.b = 2
+ | ^
+dotted key `a` attempted to extend non-table type (inline table)
diff --git a/tests/fixtures/invalid/inline-table/overwrite-04.stderr b/tests/fixtures/invalid/inline-table/overwrite-04.stderr
new file mode 100644
index 0000000..993e04e
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/overwrite-04.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 1
+ |
+3 | [[inline-t.nest]]
+ | ^
+invalid table header
+dotted key `inline-t` attempted to extend non-table type (inline table)
diff --git a/tests/fixtures/invalid/inline-table/overwrite-05.stderr b/tests/fixtures/invalid/inline-table/overwrite-05.stderr
new file mode 100644
index 0000000..bf1953d
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/overwrite-05.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 1
+ |
+3 | [inline-t.nest]
+ | ^
+invalid table header
+dotted key `inline-t` attempted to extend non-table type (inline table)
diff --git a/tests/fixtures/invalid/inline-table/overwrite-06.stderr b/tests/fixtures/invalid/inline-table/overwrite-06.stderr
new file mode 100644
index 0000000..1e5d4cd
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/overwrite-06.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 6
+ |
+1 | a = { b = 1, b.c = 2 }
+ | ^
+dotted key `b` attempted to extend non-table type (integer)
diff --git a/tests/fixtures/invalid/inline-table/overwrite-07.stderr b/tests/fixtures/invalid/inline-table/overwrite-07.stderr
new file mode 100644
index 0000000..9e5efba
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/overwrite-07.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 8
+ |
+1 | tab = { inner.table = [{}], inner.table.val = "bad" }
+ | ^
+dotted key `inner.table` attempted to extend non-table type (array)
diff --git a/tests/fixtures/invalid/inline-table/overwrite-08.stderr b/tests/fixtures/invalid/inline-table/overwrite-08.stderr
new file mode 100644
index 0000000..8322330
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/overwrite-08.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 8
+ |
+1 | tab = { inner = { dog = "best" }, inner.cat = "worst" }
+ | ^
+duplicate key `inner`
diff --git a/tests/fixtures/invalid/inline-table/overwrite-09.stderr b/tests/fixtures/invalid/inline-table/overwrite-09.stderr
new file mode 100644
index 0000000..9d68dbb
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/overwrite-09.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 5, column 1
+ |
+5 | nested.inline-t.nest = 2
+ | ^
+duplicate key `nested`
diff --git a/tests/fixtures/invalid/inline-table/overwrite-10.stderr b/tests/fixtures/invalid/inline-table/overwrite-10.stderr
new file mode 100644
index 0000000..18af75a
--- /dev/null
+++ b/tests/fixtures/invalid/inline-table/overwrite-10.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 4, column 6
+ |
+4 | a = {b.a = 1, b = 2, b.c = 3}
+ | ^
+duplicate key `b`
diff --git a/tests/fixtures/invalid/integer/invalid-hex-1.stderr b/tests/fixtures/invalid/integer/invalid-hex-1.stderr
new file mode 100644
index 0000000..b899e6a
--- /dev/null
+++ b/tests/fixtures/invalid/integer/invalid-hex-1.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 22
+ |
+1 | invalid-hex-1 = 0xaafz
+ | ^
+expected newline, `#`
diff --git a/tests/fixtures/invalid/integer/invalid-hex-2.stderr b/tests/fixtures/invalid/integer/invalid-hex-2.stderr
new file mode 100644
index 0000000..4df3e2f
--- /dev/null
+++ b/tests/fixtures/invalid/integer/invalid-hex-2.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 19
+ |
+1 | invalid-hex-2 = 0xgabba00f1
+ | ^
+invalid hexadecimal integer
diff --git a/tests/fixtures/invalid/integer/leading-us-bin.stderr b/tests/fixtures/invalid/integer/leading-us-bin.stderr
index c893e75..c979c19 100644
--- a/tests/fixtures/invalid/integer/leading-us-bin.stderr
+++ b/tests/fixtures/invalid/integer/leading-us-bin.stderr
@@ -1,6 +1,6 @@
TOML parse error at line 1, column 18
|
-1 | leading-us-bin = _0o1
+1 | leading-us-bin = _0b1
| ^
invalid integer
expected leading digit
diff --git a/tests/fixtures/invalid/integer/leading-us-hex.stderr b/tests/fixtures/invalid/integer/leading-us-hex.stderr
index 12eb8e6..1824a8b 100644
--- a/tests/fixtures/invalid/integer/leading-us-hex.stderr
+++ b/tests/fixtures/invalid/integer/leading-us-hex.stderr
@@ -1,6 +1,6 @@
TOML parse error at line 1, column 18
|
-1 | leading-us-hex = _0o1
+1 | leading-us-hex = _0x1
| ^
invalid integer
expected leading digit
diff --git a/tests/fixtures/invalid/integer/negative-oct.stderr b/tests/fixtures/invalid/integer/negative-oct.stderr
index fcf3140..9e922c6 100644
--- a/tests/fixtures/invalid/integer/negative-oct.stderr
+++ b/tests/fixtures/invalid/integer/negative-oct.stderr
@@ -1,5 +1,5 @@
TOML parse error at line 1, column 18
|
-1 | negative-oct = -0o99
+1 | negative-oct = -0o755
| ^
expected newline, `#`
diff --git a/tests/fixtures/invalid/integer/positive-oct.stderr b/tests/fixtures/invalid/integer/positive-oct.stderr
index cc09466..30d2ab3 100644
--- a/tests/fixtures/invalid/integer/positive-oct.stderr
+++ b/tests/fixtures/invalid/integer/positive-oct.stderr
@@ -1,5 +1,5 @@
TOML parse error at line 1, column 18
|
-1 | positive-oct = +0o99
+1 | positive-oct = +0o755
| ^
expected newline, `#`
diff --git a/tests/fixtures/invalid/key/dotted-redefine-table-1.stderr b/tests/fixtures/invalid/key/dotted-redefine-table-1.stderr
new file mode 100644
index 0000000..f51a108
--- /dev/null
+++ b/tests/fixtures/invalid/key/dotted-redefine-table-1.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 1
+ |
+2 | a.b = true
+ | ^
+dotted key `a` attempted to extend non-table type (boolean)
diff --git a/tests/fixtures/invalid/key/dotted-redefine-table.stderr b/tests/fixtures/invalid/key/dotted-redefine-table-2.stderr
index 3a2b8d5..3a2b8d5 100644
--- a/tests/fixtures/invalid/key/dotted-redefine-table.stderr
+++ b/tests/fixtures/invalid/key/dotted-redefine-table-2.stderr
diff --git a/tests/fixtures/invalid/key/duplicate-keys-1.stderr b/tests/fixtures/invalid/key/duplicate-keys-1.stderr
new file mode 100644
index 0000000..c58dd3c
--- /dev/null
+++ b/tests/fixtures/invalid/key/duplicate-keys-1.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 1
+ |
+2 | name = "Pradyun"
+ | ^
+duplicate key `name` in document root
diff --git a/tests/fixtures/invalid/key/duplicate-keys.stderr b/tests/fixtures/invalid/key/duplicate-keys-2.stderr
index 74149f8..74149f8 100644
--- a/tests/fixtures/invalid/key/duplicate-keys.stderr
+++ b/tests/fixtures/invalid/key/duplicate-keys-2.stderr
diff --git a/tests/fixtures/invalid/key/duplicate-keys-3.stderr b/tests/fixtures/invalid/key/duplicate-keys-3.stderr
new file mode 100644
index 0000000..94a019f
--- /dev/null
+++ b/tests/fixtures/invalid/key/duplicate-keys-3.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 1
+ |
+2 | "spelling" = "favourite"
+ | ^
+duplicate key `spelling` in document root
diff --git a/tests/fixtures/invalid/key/duplicate-keys-4.stderr b/tests/fixtures/invalid/key/duplicate-keys-4.stderr
new file mode 100644
index 0000000..2bd02ab
--- /dev/null
+++ b/tests/fixtures/invalid/key/duplicate-keys-4.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 1
+ |
+2 | 'spelling' = "favourite"
+ | ^
+duplicate key `spelling` in document root
diff --git a/tests/fixtures/invalid/key/duplicate.stderr b/tests/fixtures/invalid/key/duplicate.stderr
deleted file mode 100644
index 8c7d7b7..0000000
--- a/tests/fixtures/invalid/key/duplicate.stderr
+++ /dev/null
@@ -1,5 +0,0 @@
-TOML parse error at line 3, column 1
- |
-3 | name = "Pradyun"
- | ^
-duplicate key `name` in document root
diff --git a/tests/fixtures/invalid/key/end-in-escape.stderr b/tests/fixtures/invalid/key/end-in-escape.stderr
new file mode 100644
index 0000000..5916980
--- /dev/null
+++ b/tests/fixtures/invalid/key/end-in-escape.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 30
+ |
+1 | "backslash is the last char\
+ | ^
+invalid escape sequence
+expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"`
diff --git a/tests/fixtures/invalid/key/newline.stderr b/tests/fixtures/invalid/key/newline-1.stderr
index 141932e..141932e 100644
--- a/tests/fixtures/invalid/key/newline.stderr
+++ b/tests/fixtures/invalid/key/newline-1.stderr
diff --git a/tests/fixtures/invalid/key/newline-2.stderr b/tests/fixtures/invalid/key/newline-2.stderr
new file mode 100644
index 0000000..ac205e1
--- /dev/null
+++ b/tests/fixtures/invalid/key/newline-2.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 8
+ |
+1 | "quoted
+ | ^
+invalid basic string
diff --git a/tests/fixtures/invalid/key/newline-3.stderr b/tests/fixtures/invalid/key/newline-3.stderr
new file mode 100644
index 0000000..ee7c519
--- /dev/null
+++ b/tests/fixtures/invalid/key/newline-3.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 8
+ |
+1 | 'quoted
+ | ^
+invalid literal string
diff --git a/tests/fixtures/invalid/key/multiline.stderr b/tests/fixtures/invalid/key/newline-4.stderr
index b4241ee..b4241ee 100644
--- a/tests/fixtures/invalid/key/multiline.stderr
+++ b/tests/fixtures/invalid/key/newline-4.stderr
diff --git a/tests/fixtures/invalid/key/newline-5.stderr b/tests/fixtures/invalid/key/newline-5.stderr
new file mode 100644
index 0000000..18e3ab3
--- /dev/null
+++ b/tests/fixtures/invalid/key/newline-5.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 3
+ |
+1 | '''long
+ | ^
+expected `.`, `=`
diff --git a/tests/fixtures/invalid/key/two-equals.stderr b/tests/fixtures/invalid/key/two-equals-1.stderr
index 2f92886..2f92886 100644
--- a/tests/fixtures/invalid/key/two-equals.stderr
+++ b/tests/fixtures/invalid/key/two-equals-1.stderr
diff --git a/tests/fixtures/invalid/key/two-equals2.stderr b/tests/fixtures/invalid/key/two-equals-2.stderr
index f2adb1f..f2adb1f 100644
--- a/tests/fixtures/invalid/key/two-equals2.stderr
+++ b/tests/fixtures/invalid/key/two-equals-2.stderr
diff --git a/tests/fixtures/invalid/key/two-equals3.stderr b/tests/fixtures/invalid/key/two-equals-3.stderr
index dbee169..dbee169 100644
--- a/tests/fixtures/invalid/key/two-equals3.stderr
+++ b/tests/fixtures/invalid/key/two-equals-3.stderr
diff --git a/tests/fixtures/invalid/key/without-value-5.stderr b/tests/fixtures/invalid/key/without-value-5.stderr
new file mode 100644
index 0000000..711eab1
--- /dev/null
+++ b/tests/fixtures/invalid/key/without-value-5.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 6
+ |
+1 | fs.fw
+ | ^
+expected `.`, `=`
diff --git a/tests/fixtures/invalid/key/without-value-6.stderr b/tests/fixtures/invalid/key/without-value-6.stderr
new file mode 100644
index 0000000..c380d70
--- /dev/null
+++ b/tests/fixtures/invalid/key/without-value-6.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 8
+ |
+1 | fs.fw =
+ | ^
+invalid string
+expected `"`, `'`
diff --git a/tests/fixtures/invalid/key/without-value-7.stderr b/tests/fixtures/invalid/key/without-value-7.stderr
new file mode 100644
index 0000000..8565837
--- /dev/null
+++ b/tests/fixtures/invalid/key/without-value-7.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 3
+ |
+1 | fs.
+ | ^
+expected `.`, `=`
diff --git a/tests/fixtures/invalid/local-date/feb-29.stderr b/tests/fixtures/invalid/local-date/feb-29.stderr
new file mode 100644
index 0000000..b0ae76d
--- /dev/null
+++ b/tests/fixtures/invalid/local-date/feb-29.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 29
+ |
+1 | "not a leap year" = 2100-02-29
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-date/feb-30.stderr b/tests/fixtures/invalid/local-date/feb-30.stderr
new file mode 100644
index 0000000..7f64348
--- /dev/null
+++ b/tests/fixtures/invalid/local-date/feb-30.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 44
+ |
+1 | "only 28 or 29 days in february" = 1988-02-30
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-date/mday-over.stderr b/tests/fixtures/invalid/local-date/mday-over.stderr
new file mode 100644
index 0000000..f2d1876
--- /dev/null
+++ b/tests/fixtures/invalid/local-date/mday-over.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 13
+ |
+3 | d = 2006-01-32
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-date/mday-under.stderr b/tests/fixtures/invalid/local-date/mday-under.stderr
new file mode 100644
index 0000000..fab958d
--- /dev/null
+++ b/tests/fixtures/invalid/local-date/mday-under.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 13
+ |
+3 | d = 2006-01-00
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-date/month-over.stderr b/tests/fixtures/invalid/local-date/month-over.stderr
new file mode 100644
index 0000000..ec6d090
--- /dev/null
+++ b/tests/fixtures/invalid/local-date/month-over.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 2, column 10
+ |
+2 | d = 2006-13-01
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-date/month-under.stderr b/tests/fixtures/invalid/local-date/month-under.stderr
new file mode 100644
index 0000000..3e8324a
--- /dev/null
+++ b/tests/fixtures/invalid/local-date/month-under.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 2, column 10
+ |
+2 | d = 2007-00-01
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-date/no-leads-with-milli.stderr b/tests/fixtures/invalid/local-date/no-leads-with-milli.stderr
new file mode 100644
index 0000000..e0e3046
--- /dev/null
+++ b/tests/fixtures/invalid/local-date/no-leads-with-milli.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 22
+ |
+2 | with-milli = 1987-07-5
+ | ^
+invalid date-time
diff --git a/tests/fixtures/invalid/local-date/no-leads.stderr b/tests/fixtures/invalid/local-date/no-leads.stderr
new file mode 100644
index 0000000..e7b5d69
--- /dev/null
+++ b/tests/fixtures/invalid/local-date/no-leads.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 17
+ |
+2 | no-leads = 1987-7-05
+ | ^
+invalid date-time
diff --git a/tests/fixtures/invalid/datetime/trailing-t.stderr b/tests/fixtures/invalid/local-date/trailing-t.stderr
index 061ec26..061ec26 100644
--- a/tests/fixtures/invalid/datetime/trailing-t.stderr
+++ b/tests/fixtures/invalid/local-date/trailing-t.stderr
diff --git a/tests/fixtures/invalid/local-date/y10k.stderr b/tests/fixtures/invalid/local-date/y10k.stderr
new file mode 100644
index 0000000..244266e
--- /dev/null
+++ b/tests/fixtures/invalid/local-date/y10k.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 10
+ |
+2 | d = 10000-01-01
+ | ^
+expected newline, `#`
diff --git a/tests/fixtures/invalid/local-datetime/feb-29.stderr b/tests/fixtures/invalid/local-datetime/feb-29.stderr
new file mode 100644
index 0000000..8aac712
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/feb-29.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 29
+ |
+1 | "not a leap year" = 2100-02-29T15:15:15
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-datetime/feb-30.stderr b/tests/fixtures/invalid/local-datetime/feb-30.stderr
new file mode 100644
index 0000000..6175c5e
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/feb-30.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 44
+ |
+1 | "only 28 or 29 days in february" = 1988-02-30T15:15:15
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-datetime/hour-over.stderr b/tests/fixtures/invalid/local-datetime/hour-over.stderr
new file mode 100644
index 0000000..bc255ed
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/hour-over.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 15
+ |
+2 | d = 2006-01-01T24:00:00
+ | ^
+expected newline, `#`
diff --git a/tests/fixtures/invalid/local-datetime/mday-over.stderr b/tests/fixtures/invalid/local-datetime/mday-over.stderr
new file mode 100644
index 0000000..0556e3a
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/mday-over.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 13
+ |
+3 | d = 2006-01-32T00:00:00
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-datetime/mday-under.stderr b/tests/fixtures/invalid/local-datetime/mday-under.stderr
new file mode 100644
index 0000000..036e963
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/mday-under.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 13
+ |
+3 | d = 2006-01-00T00:00:00
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-datetime/minute-over.stderr b/tests/fixtures/invalid/local-datetime/minute-over.stderr
new file mode 100644
index 0000000..039fc6e
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/minute-over.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 2, column 19
+ |
+2 | d = 2006-01-01T00:60:00
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-datetime/month-over.stderr b/tests/fixtures/invalid/local-datetime/month-over.stderr
new file mode 100644
index 0000000..0d2dca2
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/month-over.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 2, column 10
+ |
+2 | d = 2006-13-01T00:00:00
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-datetime/month-under.stderr b/tests/fixtures/invalid/local-datetime/month-under.stderr
new file mode 100644
index 0000000..6ce30cb
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/month-under.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 2, column 10
+ |
+2 | d = 2007-00-01T00:00:00
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-datetime/no-leads-with-milli.stderr b/tests/fixtures/invalid/local-datetime/no-leads-with-milli.stderr
new file mode 100644
index 0000000..5ec75e9
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/no-leads-with-milli.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 22
+ |
+2 | with-milli = 1987-07-5T17:45:00.12
+ | ^
+invalid date-time
diff --git a/tests/fixtures/invalid/local-datetime/no-leads.stderr b/tests/fixtures/invalid/local-datetime/no-leads.stderr
new file mode 100644
index 0000000..7d2c879
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/no-leads.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 17
+ |
+2 | no-leads = 1987-7-05T17:45:00
+ | ^
+invalid date-time
diff --git a/tests/fixtures/invalid/local-datetime/no-secs.stderr b/tests/fixtures/invalid/local-datetime/no-secs.stderr
new file mode 100644
index 0000000..7585e1b
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/no-secs.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 27
+ |
+2 | no-secs = 1987-07-05T17:45
+ | ^
+invalid date-time
diff --git a/tests/fixtures/invalid/local-datetime/no-t.stderr b/tests/fixtures/invalid/local-datetime/no-t.stderr
new file mode 100644
index 0000000..0f520a2
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/no-t.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 18
+ |
+2 | no-t = 1987-07-0517:45:00
+ | ^
+expected newline, `#`
diff --git a/tests/fixtures/invalid/local-datetime/second-over.stderr b/tests/fixtures/invalid/local-datetime/second-over.stderr
new file mode 100644
index 0000000..63d0007
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/second-over.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 22
+ |
+3 | d = 2006-01-01T00:00:61
+ | ^
+invalid date-time
+value is out of range
diff --git a/tests/fixtures/invalid/local-datetime/time-no-leads.stderr b/tests/fixtures/invalid/local-datetime/time-no-leads.stderr
new file mode 100644
index 0000000..012f62f
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/time-no-leads.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 15
+ |
+2 | d = 2023-10-01T1:32:00Z
+ | ^
+expected newline, `#`
diff --git a/tests/fixtures/invalid/local-datetime/y10k.stderr b/tests/fixtures/invalid/local-datetime/y10k.stderr
new file mode 100644
index 0000000..2d4015d
--- /dev/null
+++ b/tests/fixtures/invalid/local-datetime/y10k.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 10
+ |
+2 | d = 10000-01-01 00:00:00
+ | ^
+expected newline, `#`
diff --git a/tests/fixtures/invalid/local-time/hour-over.stderr b/tests/fixtures/invalid/local-time/hour-over.stderr
new file mode 100644
index 0000000..1f669e3
--- /dev/null
+++ b/tests/fixtures/invalid/local-time/hour-over.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 7
+ |
+2 | d = 24:00:00
+ | ^
+expected newline, `#`
diff --git a/tests/fixtures/invalid/local-time/minute-over.stderr b/tests/fixtures/invalid/local-time/minute-over.stderr
new file mode 100644
index 0000000..efb676f
--- /dev/null
+++ b/tests/fixtures/invalid/local-time/minute-over.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 2, column 8
+ |
+2 | d = 00:60:00
+ | ^
+invalid time
+value is out of range
diff --git a/tests/fixtures/invalid/local-time/no-secs.stderr b/tests/fixtures/invalid/local-time/no-secs.stderr
new file mode 100644
index 0000000..2fa8ba3
--- /dev/null
+++ b/tests/fixtures/invalid/local-time/no-secs.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 16
+ |
+2 | no-secs = 17:45
+ | ^
+invalid time
diff --git a/tests/fixtures/invalid/local-time/second-over.stderr b/tests/fixtures/invalid/local-time/second-over.stderr
new file mode 100644
index 0000000..a608f89
--- /dev/null
+++ b/tests/fixtures/invalid/local-time/second-over.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 11
+ |
+3 | d = 00:00:61
+ | ^
+invalid time
+value is out of range
diff --git a/tests/fixtures/invalid/datetime/time-no-leads-2.stderr b/tests/fixtures/invalid/local-time/time-no-leads-2.stderr
index fd77fb2..fd77fb2 100644
--- a/tests/fixtures/invalid/datetime/time-no-leads-2.stderr
+++ b/tests/fixtures/invalid/local-time/time-no-leads-2.stderr
diff --git a/tests/fixtures/invalid/local-time/time-no-leads.stderr b/tests/fixtures/invalid/local-time/time-no-leads.stderr
new file mode 100644
index 0000000..7a98902
--- /dev/null
+++ b/tests/fixtures/invalid/local-time/time-no-leads.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 6
+ |
+2 | d = 1:32:00
+ | ^
+expected newline, `#`
diff --git a/tests/fixtures/invalid/string/bad-codepoint.stderr b/tests/fixtures/invalid/string/bad-codepoint.stderr
deleted file mode 100644
index 4061c79..0000000
--- a/tests/fixtures/invalid/string/bad-codepoint.stderr
+++ /dev/null
@@ -1,6 +0,0 @@
-TOML parse error at line 1, column 76
- |
-1 | invalid-codepoint = "This string contains a non scalar unicode codepoint \uD801"
- | ^
-invalid unicode 4-digit hex code
-value is out of range
diff --git a/tests/fixtures/invalid/string/bad-escape-3.stderr b/tests/fixtures/invalid/string/bad-escape-3.stderr
new file mode 100644
index 0000000..ea10886
--- /dev/null
+++ b/tests/fixtures/invalid/string/bad-escape-3.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 16
+ |
+1 | backslash = "\"
+ | ^
+invalid basic string
diff --git a/tests/fixtures/invalid/string/bad-uni-esc-1.stderr b/tests/fixtures/invalid/string/bad-uni-esc-1.stderr
index a9e439b..71d8ed3 100644
--- a/tests/fixtures/invalid/string/bad-uni-esc-1.stderr
+++ b/tests/fixtures/invalid/string/bad-uni-esc-1.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 13
+TOML parse error at line 1, column 23
|
-1 | str = "val\ue"
- | ^
+1 | bad-uni-esc-1 = "val\ue"
+ | ^
invalid unicode 4-digit hex code
diff --git a/tests/fixtures/invalid/string/bad-uni-esc-2.stderr b/tests/fixtures/invalid/string/bad-uni-esc-2.stderr
index 87c8681..06138c1 100644
--- a/tests/fixtures/invalid/string/bad-uni-esc-2.stderr
+++ b/tests/fixtures/invalid/string/bad-uni-esc-2.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 13
+TOML parse error at line 1, column 23
|
-1 | str = "val\Ux"
- | ^
+1 | bad-uni-esc-2 = "val\Ux"
+ | ^
invalid unicode 8-digit hex code
diff --git a/tests/fixtures/invalid/string/bad-uni-esc-3.stderr b/tests/fixtures/invalid/string/bad-uni-esc-3.stderr
index 61f8ded..c82355c 100644
--- a/tests/fixtures/invalid/string/bad-uni-esc-3.stderr
+++ b/tests/fixtures/invalid/string/bad-uni-esc-3.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 13
+TOML parse error at line 1, column 23
|
-1 | str = "val\U0000000"
- | ^
+1 | bad-uni-esc-3 = "val\U0000000"
+ | ^
invalid unicode 8-digit hex code
diff --git a/tests/fixtures/invalid/string/bad-uni-esc-4.stderr b/tests/fixtures/invalid/string/bad-uni-esc-4.stderr
index 1a781d9..71fb48c 100644
--- a/tests/fixtures/invalid/string/bad-uni-esc-4.stderr
+++ b/tests/fixtures/invalid/string/bad-uni-esc-4.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 13
+TOML parse error at line 1, column 23
|
-1 | str = "val\U0000"
- | ^
+1 | bad-uni-esc-4 = "val\U0000"
+ | ^
invalid unicode 8-digit hex code
diff --git a/tests/fixtures/invalid/string/bad-uni-esc-5.stderr b/tests/fixtures/invalid/string/bad-uni-esc-5.stderr
index 88773ca..d79798f 100644
--- a/tests/fixtures/invalid/string/bad-uni-esc-5.stderr
+++ b/tests/fixtures/invalid/string/bad-uni-esc-5.stderr
@@ -1,5 +1,5 @@
-TOML parse error at line 1, column 13
+TOML parse error at line 1, column 23
|
-1 | str = "val\Ugggggggg"
- | ^
+1 | bad-uni-esc-5 = "val\Ugggggggg"
+ | ^
invalid unicode 8-digit hex code
diff --git a/tests/fixtures/invalid/string/bad-uni-esc-6.stderr b/tests/fixtures/invalid/string/bad-uni-esc-6.stderr
new file mode 100644
index 0000000..7eb5ff0
--- /dev/null
+++ b/tests/fixtures/invalid/string/bad-uni-esc-6.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 72
+ |
+1 | bad-uni-esc-6 = "This string contains a non scalar unicode codepoint \uD801"
+ | ^
+invalid unicode 4-digit hex code
+value is out of range
diff --git a/tests/fixtures/invalid/string/bad-uni-esc-7.stderr b/tests/fixtures/invalid/string/bad-uni-esc-7.stderr
new file mode 100644
index 0000000..c53ef12
--- /dev/null
+++ b/tests/fixtures/invalid/string/bad-uni-esc-7.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 20
+ |
+1 | bad-uni-esc-7 = "\uabag"
+ | ^
+invalid unicode 4-digit hex code
diff --git a/tests/fixtures/invalid/string/multiline-bad-escape-4.stderr b/tests/fixtures/invalid/string/multiline-bad-escape-4.stderr
new file mode 100644
index 0000000..d662a4d
--- /dev/null
+++ b/tests/fixtures/invalid/string/multiline-bad-escape-4.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 21
+ |
+1 | backslash = """\"""
+ | ^
+invalid multiline basic string
diff --git a/tests/fixtures/invalid/string/multiline-escape-space.stderr b/tests/fixtures/invalid/string/multiline-escape-space-1.stderr
index 4b3c32b..4b3c32b 100644
--- a/tests/fixtures/invalid/string/multiline-escape-space.stderr
+++ b/tests/fixtures/invalid/string/multiline-escape-space-1.stderr
diff --git a/tests/fixtures/invalid/string/multiline-escape-space-2.stderr b/tests/fixtures/invalid/string/multiline-escape-space-2.stderr
new file mode 100644
index 0000000..b5ed276
--- /dev/null
+++ b/tests/fixtures/invalid/string/multiline-escape-space-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 4, column 7
+ |
+4 | gee \ """
+ | ^
+invalid escape sequence
+expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"`
diff --git a/tests/fixtures/invalid/string/multiline-lit-no-close-1.stderr b/tests/fixtures/invalid/string/multiline-lit-no-close-1.stderr
new file mode 100644
index 0000000..1731932
--- /dev/null
+++ b/tests/fixtures/invalid/string/multiline-lit-no-close-1.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 2, column 20
+ |
+2 | this will fail
+ | ^
+invalid multiline literal string
diff --git a/tests/fixtures/invalid/string/multiline-lit-no-close-2.stderr b/tests/fixtures/invalid/string/multiline-lit-no-close-2.stderr
new file mode 100644
index 0000000..347c6de
--- /dev/null
+++ b/tests/fixtures/invalid/string/multiline-lit-no-close-2.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 7
+ |
+1 | x='''
+ | ^
+invalid multiline literal string
diff --git a/tests/fixtures/invalid/string/multiline-lit-no-close-3.stderr b/tests/fixtures/invalid/string/multiline-lit-no-close-3.stderr
new file mode 100644
index 0000000..b6d5ec5
--- /dev/null
+++ b/tests/fixtures/invalid/string/multiline-lit-no-close-3.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 4, column 7
+ |
+4 | eteta
+ | ^
+invalid multiline literal string
diff --git a/tests/fixtures/invalid/string/multiline-lit-no-close-4.stderr b/tests/fixtures/invalid/string/multiline-lit-no-close-4.stderr
new file mode 100644
index 0000000..5dea96d
--- /dev/null
+++ b/tests/fixtures/invalid/string/multiline-lit-no-close-4.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 3, column 8
+ |
+3 | gee ''
+ | ^
+invalid multiline literal string
diff --git a/tests/fixtures/invalid/string/multiline-no-close.stderr b/tests/fixtures/invalid/string/multiline-no-close-1.stderr
index 99e967a..99e967a 100644
--- a/tests/fixtures/invalid/string/multiline-no-close.stderr
+++ b/tests/fixtures/invalid/string/multiline-no-close-1.stderr
diff --git a/tests/fixtures/invalid/string/multiline-no-close-3.stderr b/tests/fixtures/invalid/string/multiline-no-close-3.stderr
new file mode 100644
index 0000000..eff9fe4
--- /dev/null
+++ b/tests/fixtures/invalid/string/multiline-no-close-3.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 4, column 7
+ |
+4 | eteta
+ | ^
+invalid multiline basic string
diff --git a/tests/fixtures/invalid/string/multiline-no-close-4.stderr b/tests/fixtures/invalid/string/multiline-no-close-4.stderr
new file mode 100644
index 0000000..e19582f
--- /dev/null
+++ b/tests/fixtures/invalid/string/multiline-no-close-4.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 3, column 8
+ |
+3 | gee ""
+ | ^
+invalid multiline basic string
diff --git a/tests/fixtures/invalid/string/multiline-no-close-5.stderr b/tests/fixtures/invalid/string/multiline-no-close-5.stderr
new file mode 100644
index 0000000..00c1735
--- /dev/null
+++ b/tests/fixtures/invalid/string/multiline-no-close-5.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 3, column 8
+ |
+3 | gee\
+ | ^
+invalid multiline basic string
diff --git a/tests/fixtures/invalid/string/no-close.stderr b/tests/fixtures/invalid/string/no-close-1.stderr
index f23223d..f23223d 100644
--- a/tests/fixtures/invalid/string/no-close.stderr
+++ b/tests/fixtures/invalid/string/no-close-1.stderr
diff --git a/tests/fixtures/invalid/string/no-close-2.stderr b/tests/fixtures/invalid/string/no-close-2.stderr
new file mode 100644
index 0000000..a80fe60
--- /dev/null
+++ b/tests/fixtures/invalid/string/no-close-2.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 29
+ |
+1 | "a-string".must-be = "closed
+ | ^
+invalid basic string
diff --git a/tests/fixtures/invalid/string/no-close-3.stderr b/tests/fixtures/invalid/string/no-close-3.stderr
new file mode 100644
index 0000000..029b40a
--- /dev/null
+++ b/tests/fixtures/invalid/string/no-close-3.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 42
+ |
+1 | no-ending-quote = 'One time, at band camp
+ | ^
+invalid literal string
diff --git a/tests/fixtures/invalid/string/no-close-4.stderr b/tests/fixtures/invalid/string/no-close-4.stderr
new file mode 100644
index 0000000..9e47ef7
--- /dev/null
+++ b/tests/fixtures/invalid/string/no-close-4.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 29
+ |
+1 | 'a-string'.must-be = 'closed
+ | ^
+invalid literal string
diff --git a/tests/fixtures/invalid/string/bad-hex-esc.stderr b/tests/fixtures/invalid/string/string.stderr
index 5d5577f..5d5577f 100644
--- a/tests/fixtures/invalid/string/bad-hex-esc.stderr
+++ b/tests/fixtures/invalid/string/string.stderr
diff --git a/tests/fixtures/invalid/table/append-to-array-with-dotted-keys.stderr b/tests/fixtures/invalid/table/append-to-array-with-dotted-keys.stderr
new file mode 100644
index 0000000..0fb4b2e
--- /dev/null
+++ b/tests/fixtures/invalid/table/append-to-array-with-dotted-keys.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 4, column 1
+ |
+4 | b.y = 2
+ | ^
+duplicate key `y`
diff --git a/tests/fixtures/invalid/table/array-missing-bracket.stderr b/tests/fixtures/invalid/table/array-no-close-1.stderr
index ed370ef..ed370ef 100644
--- a/tests/fixtures/invalid/table/array-missing-bracket.stderr
+++ b/tests/fixtures/invalid/table/array-no-close-1.stderr
diff --git a/tests/fixtures/invalid/table/array-no-close-2.stderr b/tests/fixtures/invalid/table/array-no-close-2.stderr
new file mode 100644
index 0000000..a723c14
--- /dev/null
+++ b/tests/fixtures/invalid/table/array-no-close-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 26
+ |
+1 | [[closing-bracket.missing]
+ | ^
+invalid table header
+expected `.`, `]]`
diff --git a/tests/fixtures/invalid/table/duplicate-key-dotted-array.stderr b/tests/fixtures/invalid/table/duplicate-key-dotted-array.stderr
new file mode 100644
index 0000000..0cf32ab
--- /dev/null
+++ b/tests/fixtures/invalid/table/duplicate-key-dotted-array.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 4, column 1
+ |
+4 | [[fruit.apple]]
+ | ^
+invalid table header
+duplicate key `apple` in table `fruit`
diff --git a/tests/fixtures/invalid/table/no-close-1.stderr b/tests/fixtures/invalid/table/no-close-1.stderr
new file mode 100644
index 0000000..2e184fa
--- /dev/null
+++ b/tests/fixtures/invalid/table/no-close-1.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 8
+ |
+1 | [where will it end
+ | ^
+invalid table header
+expected `.`, `]`
diff --git a/tests/fixtures/invalid/table/no-close-2.stderr b/tests/fixtures/invalid/table/no-close-2.stderr
new file mode 100644
index 0000000..a7adf38
--- /dev/null
+++ b/tests/fixtures/invalid/table/no-close-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 25
+ |
+1 | [closing-bracket.missingö
+ | ^
+invalid table header
+expected `.`, `]`
diff --git a/tests/fixtures/invalid/table/quoted-no-close.stderr b/tests/fixtures/invalid/table/no-close-3.stderr
index 2b05e95..2b05e95 100644
--- a/tests/fixtures/invalid/table/quoted-no-close.stderr
+++ b/tests/fixtures/invalid/table/no-close-3.stderr
diff --git a/tests/fixtures/invalid/table/no-close-4.stderr b/tests/fixtures/invalid/table/no-close-4.stderr
new file mode 100644
index 0000000..022f1fa
--- /dev/null
+++ b/tests/fixtures/invalid/table/no-close-4.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 1, column 2
+ |
+1 | [
+ | ^
+invalid key
diff --git a/tests/fixtures/invalid/table/no-close-5.stderr b/tests/fixtures/invalid/table/no-close-5.stderr
new file mode 100644
index 0000000..38c7bee
--- /dev/null
+++ b/tests/fixtures/invalid/table/no-close-5.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 1, column 11
+ |
+1 | [fwfw.wafw
+ | ^
+invalid table header
+expected `.`, `]`
diff --git a/tests/fixtures/invalid/table/overwrite-array-in-parent.stderr b/tests/fixtures/invalid/table/overwrite-array-in-parent.stderr
new file mode 100644
index 0000000..8a774ff
--- /dev/null
+++ b/tests/fixtures/invalid/table/overwrite-array-in-parent.stderr
@@ -0,0 +1,5 @@
+TOML parse error at line 4, column 1
+ |
+4 | arr = 2
+ | ^
+duplicate key `arr` in table `parent-table`
diff --git a/tests/fixtures/invalid/table/overwrite-bool-with-array.stderr b/tests/fixtures/invalid/table/overwrite-bool-with-array.stderr
new file mode 100644
index 0000000..f52c773
--- /dev/null
+++ b/tests/fixtures/invalid/table/overwrite-bool-with-array.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 2, column 1
+ |
+2 | [[a]]
+ | ^
+invalid table header
+duplicate key `a` in document root
diff --git a/tests/fixtures/invalid/table/overwrite-with-deep-table.stderr b/tests/fixtures/invalid/table/overwrite-with-deep-table.stderr
new file mode 100644
index 0000000..48773b6
--- /dev/null
+++ b/tests/fixtures/invalid/table/overwrite-with-deep-table.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 2, column 1
+ |
+2 | [a.b.c.d]
+ | ^
+invalid table header
+dotted key `a` attempted to extend non-table type (integer)
diff --git a/tests/fixtures/invalid/table/redefine.stderr b/tests/fixtures/invalid/table/redefine-1.stderr
index 99c1f98..99c1f98 100644
--- a/tests/fixtures/invalid/table/redefine.stderr
+++ b/tests/fixtures/invalid/table/redefine-1.stderr
diff --git a/tests/fixtures/invalid/table/redefine-2.stderr b/tests/fixtures/invalid/table/redefine-2.stderr
new file mode 100644
index 0000000..43bbb56
--- /dev/null
+++ b/tests/fixtures/invalid/table/redefine-2.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 1
+ |
+3 | [t1.t2]
+ | ^
+invalid table header
+duplicate key `t2` in table `t1`
diff --git a/tests/fixtures/invalid/table/redefine-3.stderr b/tests/fixtures/invalid/table/redefine-3.stderr
new file mode 100644
index 0000000..63bfc24
--- /dev/null
+++ b/tests/fixtures/invalid/table/redefine-3.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 1
+ |
+3 | [t1.t2.t3]
+ | ^
+invalid table header
+duplicate key `t3` in table `t1.t2`
diff --git a/tests/fixtures/invalid/table/super-twice.stderr b/tests/fixtures/invalid/table/super-twice.stderr
new file mode 100644
index 0000000..b36517a
--- /dev/null
+++ b/tests/fixtures/invalid/table/super-twice.stderr
@@ -0,0 +1,6 @@
+TOML parse error at line 3, column 1
+ |
+3 | [a]
+ | ^
+invalid table header
+duplicate key `a` in document root
diff --git a/tests/testsuite/edit.rs b/tests/testsuite/edit.rs
index 28f73c1..94c20d4 100644
--- a/tests/testsuite/edit.rs
+++ b/tests/testsuite/edit.rs
@@ -853,3 +853,10 @@ src.git = "https://github.com/nixos/nixpkgs"
"#,
);
}
+
+#[test]
+fn sorting_with_references() {
+ let values = vec!["foo", "qux", "bar"];
+ let mut array = toml_edit::Array::from_iter(values);
+ array.sort_by(|lhs, rhs| lhs.as_str().cmp(&rhs.as_str()));
+}
diff --git a/tests/testsuite/float.rs b/tests/testsuite/float.rs
new file mode 100644
index 0000000..34e792e
--- /dev/null
+++ b/tests/testsuite/float.rs
@@ -0,0 +1,60 @@
+use toml_edit::Document;
+
+macro_rules! float_inf_tests {
+ ($ty:ty) => {{
+ let document = 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
+ ";
+
+ let document = document.parse::<Document>().unwrap();
+ let float = |k| document[k].as_float().unwrap();
+
+ assert!(float("sf1").is_infinite());
+ assert!(float("sf1").is_sign_positive());
+ assert!(float("sf2").is_infinite());
+ assert!(float("sf2").is_sign_positive());
+ assert!(float("sf3").is_infinite());
+ assert!(float("sf3").is_sign_negative());
+
+ assert!(float("sf4").is_nan());
+ assert!(float("sf4").is_sign_positive());
+ assert!(float("sf5").is_nan());
+ assert!(float("sf5").is_sign_positive());
+ assert!(float("sf6").is_nan());
+ assert!(float("sf6").is_sign_negative());
+
+ assert_eq!(float("sf7"), 0.0);
+ assert!(float("sf7").is_sign_positive());
+ assert_eq!(float("sf8"), 0.0);
+ assert!(float("sf8").is_sign_negative());
+
+ let mut document = Document::new();
+ document["sf4"] = toml_edit::value(f64::NAN.copysign(1.0));
+ document["sf6"] = toml_edit::value(f64::NAN.copysign(-1.0));
+ assert_eq!(
+ document.to_string(),
+ "\
+sf4 = nan
+sf6 = -nan
+"
+ );
+ }};
+}
+
+#[test]
+fn test_float() {
+ float_inf_tests!(f32);
+ float_inf_tests!(f64);
+}
diff --git a/tests/testsuite/main.rs b/tests/testsuite/main.rs
index 1476c5d..0592f3c 100644
--- a/tests/testsuite/main.rs
+++ b/tests/testsuite/main.rs
@@ -3,6 +3,7 @@
mod convert;
mod datetime;
mod edit;
+mod float;
mod invalid;
mod parse;
mod stackoverflow;
diff --git a/tests/testsuite/parse.rs b/tests/testsuite/parse.rs
index f1c3c27..f22b61d 100644
--- a/tests/testsuite/parse.rs
+++ b/tests/testsuite/parse.rs
@@ -56,11 +56,11 @@ multiline basic string
""""#
)
.is_str());
- assert!(parse_value!(r#"'literal string\ \'"#).is_str());
+ assert!(parse_value!(r"'literal string\ \'").is_str());
assert!(parse_value!(
- r#"'''multiline
+ r"'''multiline
literal \ \
-string'''"#
+string'''"
)
.is_str());
assert!(parse_value!(r#"{ hello = "world", a = 1}"#).is_inline_table());
@@ -1488,3 +1488,23 @@ fn despan_keys() {
assert_eq!(doc.to_string(), "aaaaaa = 1\nbbb = 2\n");
}
+
+#[test]
+fn dotted_key_comment_roundtrip() {
+ let input = r###"
+rust.unsafe_op_in_unsafe_fn = "deny"
+
+rust.explicit_outlives_requirements = "warn"
+# rust.unused_crate_dependencies = "warn"
+
+clippy.cast_lossless = "warn"
+clippy.doc_markdown = "warn"
+clippy.exhaustive_enums = "warn"
+"###;
+ let expected = input;
+
+ let manifest: toml_edit::Document = input.parse().unwrap();
+ let actual = manifest.to_string();
+
+ assert_eq(expected, actual);
+}