Vendor dependencies for 0.3.0 release

This commit is contained in:
2025-09-27 10:29:08 -05:00
parent 0c8d39d483
commit 82ab7f317b
26803 changed files with 16134934 additions and 0 deletions

1
vendor/toml_edit/.cargo-checksum.json vendored Normal file
View File

@@ -0,0 +1 @@
{"files":{"Cargo.lock":"c97974d85fd5c5661af37e5454b13f5a25936c3e867ab96c98f2642ae6b0cdbc","Cargo.toml":"0aec5ccb5bed61f3678e05f76ab0d042ef69682b7d4cfa327ca0a0172c59c65a","LICENSE-APACHE":"c6596eb7be8581c18be736c846fb9173b69eccf6ef94c5135893ec56bd92ba08","LICENSE-MIT":"6efb0476a1cc085077ed49357026d8c173bf33017278ef440f222fb9cbcb66e6","README.md":"45bd9020cfbe94d0f24da3b919496734377a345cb74f0daa7ddb30f9973638e5","examples/visit.rs":"58655db33a2d0eecd26177f9b33e0a4cbc305c74def024f448e168d3ed382e68","src/array.rs":"3ecef4d404150c54bbc44db81c98ae3ce03324577219a3d94aa1bb8f991f7010","src/array_of_tables.rs":"34a87ffd2d02b09cdda89c304d6baa87abcabcf0af8c6d67094b8ff3f5aab044","src/de/array.rs":"91e9d9093705cc0d33ae0aefe270b8f90e41bb8052cd8981827358df5aa47465","src/de/error.rs":"7df0414be4760d39ab11035c1a6ad80590db7a814d4164bd88008034eb8997aa","src/de/key.rs":"97db0d94d056a0360a8e8d1f990c4c387e90f4fc6a94bb118c6f58178756f7dd","src/de/mod.rs":"15169c6a209b472897f59bf75fbd7f408a6df493a8a551cd6d72f1f760f1bee9","src/de/table.rs":"8c53f30f81b52a593ed7075d1e4b7899e2025496467ecf7279c2bd4830c1212f","src/de/table_enum.rs":"03acfecd1879555393838f402878a8d51d9c5b089c40d105c657a7c1349d84d5","src/de/value.rs":"fc5abb860ac28d83f34dd0a51bb52b10634b5423800c13057c394b607c2be458","src/document.rs":"5e4417c020535c3f3993439ce7570c4d87a540a0285f0d9fc49b81aa10a4c3ac","src/encode.rs":"2aceb991a0839b013987683a8f01bdb2efa6d15b5dceb7ff7e35558db8635e40","src/error.rs":"58d6aba5381ff4d7c2476fecdd44bf902cfdef3857bb29ca731789b9726e3db7","src/index.rs":"4fbb12f9182552a9c7f5fadcf364a01ce01c03ba65bd9a29a129aca6cfa05995","src/inline_table.rs":"81145387d3758949ea022ae5bb9699a5a65b1929567be109b018f38a1b2376a7","src/item.rs":"cc831f4fff5a4631b23b2a1251b30f42a56d6b358ac962705133f96510a61683","src/key.rs":"c280e888b066b2981250191ca2d1dd2eb8b54dc64f7b8b9f6a48434d88dc85bc","src/lib.rs":"12b2add9ceab4c6d8c407823a80d02b03e1ec25d9f1b3b5204d9221754d0185d","src/parser/array.rs":"3e9c2a5cdb8aae6ee085db078b8f552df541199687e3917b3052e1752faf0af5","src/parser/debug.rs":"d74042b87745c6e02e647b68514ab620580faeee7b00d880fff7d62fbf7b8cee","src/parser/document.rs":"70725ff45f79aafca634eb57fb39bda275e3bcb0db5fb7573aecd43ef3406577","src/parser/inline_table.rs":"19cdcd596461a4a309e7a7da42961ed238008a7bf34f0ee3f184561652b99d47","src/parser/key.rs":"e8f4b9f2ddd0c636e85f725a899c18f92e16a1ff16ce676c976a35e050c23711","src/parser/mod.rs":"21c0defe5913d9dbcf9aacb60388c9676b647ca6e17c6ac6d90f708b8f520c4c","src/parser/value.rs":"cdcc6b16ebd0261607097fd2af91ef6ab033a5853dbfa7c84ccea4697f9693db","src/raw_string.rs":"970113e5f5ade16159b71e97c9e65c5b5f7086394f9a73e9e133c203fa2eb0f0","src/repr.rs":"974e5b665624c928459a1eb205f9b340abfa0a6370a162bdd4d2d74b9b597e1c","src/ser/array.rs":"988ee10ce30291e479826d4c5061f0ae51497c770ad43cd906ba90ada1be274b","src/ser/error.rs":"d9922fd36e6ed00a1d22e04613accc904112dcd512103c3a8da5a5399907a98c","src/ser/key.rs":"7e6292fe7ffe79ba7641d7f37b3137a61d208c5732bf993d62e5365a517b0a71","src/ser/map.rs":"06587721d410a177c058c58f1b43cfa5247814a26172cb4d8521b14d2785e238","src/ser/mod.rs":"9fdc50158068df57bc6e05200c85710e3c80e8532747e5cfbcde989a4da97816","src/ser/pretty.rs":"c5edeb2c42cea1ed9b4b74be66fe2ab6d21b5e71d98b10c20675aaaa18f724ac","src/ser/value.rs":"4e1b590507e2dc5e68c162397ce7ee895326ee9f901d37aa821828de7dc288f0","src/table.rs":"3535d9fa2821773a6172477ae40882a8ea13c3605cc052d12dfaaab33d35adf3","src/value.rs":"06b6c1ff892584df18d68a4e902f7f95edffc88b07435606135dabfbd429a242","src/visit.rs":"732d9970455c62dae0523949dd9bdd16e76c05ed9de57720ea4c62d70e7efb2b","src/visit_mut.rs":"77934daa4ec1df159fc72f13431b5a635e4bbce15267a82da4647aa860a1e37f"},"package":"f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b"}

946
vendor/toml_edit/Cargo.lock generated vendored Normal file
View File

@@ -0,0 +1,946 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "aho-corasick"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
dependencies = [
"memchr",
]
[[package]]
name = "anstream"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3ae563653d1938f79b1ab1b5e668c87c76a9930414574a6583a7b7e11a8e6192"
dependencies = [
"anstyle",
"anstyle-parse",
"anstyle-query",
"anstyle-wincon",
"colorchoice",
"is_terminal_polyfill",
"utf8parse",
]
[[package]]
name = "anstyle"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "anstyle-parse"
version = "0.2.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2"
dependencies = [
"utf8parse",
]
[[package]]
name = "anstyle-query"
version = "1.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
dependencies = [
"windows-sys 0.60.2",
]
[[package]]
name = "anstyle-wincon"
version = "3.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
dependencies = [
"anstyle",
"once_cell_polyfill",
"windows-sys 0.60.2",
]
[[package]]
name = "autocfg"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bit-set"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
[[package]]
name = "bitflags"
version = "2.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394"
[[package]]
name = "bstr"
version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "234113d19d0d7d613b40e86fb654acf958910802bcceab913a4f9e7cda03b1a4"
dependencies = [
"memchr",
"serde",
]
[[package]]
name = "cfg-if"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd1289c04a9ea8cb22300a459a72a385d7c73d3259e2ed7dcb2af674838cfa9"
[[package]]
name = "chrono"
version = "0.4.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2"
dependencies = [
"num-traits",
]
[[package]]
name = "colorchoice"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75"
[[package]]
name = "crossbeam-deque"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51"
dependencies = [
"crossbeam-epoch",
"crossbeam-utils",
]
[[package]]
name = "crossbeam-epoch"
version = "0.9.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e"
dependencies = [
"crossbeam-utils",
]
[[package]]
name = "crossbeam-utils"
version = "0.8.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "erased-serde"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e004d887f51fcb9fef17317a2f3525c887d8aa3f4f50fed920816a688284a5b7"
dependencies = [
"serde",
"typeid",
]
[[package]]
name = "errno"
version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.61.0",
]
[[package]]
name = "fastrand"
version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "getrandom"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"libc",
"r-efi",
"wasi",
]
[[package]]
name = "globset"
version = "0.4.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "54a1028dfc5f5df5da8a56a73e6c153c9a9708ec57232470703592a3f18e49f5"
dependencies = [
"aho-corasick",
"bstr",
"log",
"regex-automata",
"regex-syntax",
]
[[package]]
name = "hashbrown"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
[[package]]
name = "ignore"
version = "0.4.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d89fd380afde86567dfba715db065673989d6253f42b88179abd3eae47bda4b"
dependencies = [
"crossbeam-deque",
"globset",
"log",
"memchr",
"regex-automata",
"same-file",
"walkdir",
"winapi-util",
]
[[package]]
name = "include_dir"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "923d117408f1e49d914f1a379a309cffe4f18c05cf4e3d12e613a15fc81bd0dd"
dependencies = [
"include_dir_macros",
]
[[package]]
name = "include_dir_macros"
version = "0.7.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7cab85a7ed0bd5f0e76d93846e0147172bed2e2d3f859bcc33a8d9699cad1a75"
dependencies = [
"proc-macro2",
"quote",
]
[[package]]
name = "indexmap"
version = "2.11.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "is_terminal_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
[[package]]
name = "itoa"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "json-write"
version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4085027557b9a870495ab8b7b411e14576055491d7220c88b11b7e2ba198b297"
[[package]]
name = "lazy_static"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "lexarg"
version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84373d01a60bb462a2e7caa28796669692d38ba075028a656bd626ac211062d4"
dependencies = [
"lexarg-error",
"lexarg-parser",
]
[[package]]
name = "lexarg-error"
version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "178daf11ee95fa4bf31ff1af878dda4c637dc08a37aabdd63ae3683481fd13a9"
dependencies = [
"lexarg-parser",
]
[[package]]
name = "lexarg-parser"
version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "67367be9ace12a2d51c03741b5280ff3029a833c49a4ec1193223a1a8cfbc863"
[[package]]
name = "libc"
version = "0.2.175"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
[[package]]
name = "libtest-json"
version = "0.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a8f58e30343a6bfe0fb896b0bb92cf482c34ed047c637aac4b561d0b251b638c"
dependencies = [
"json-write",
]
[[package]]
name = "libtest-lexarg"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "914e11e515e22a1b2a0aac76c0615e6417d470789c2f0433a0598a5b6aae491f"
dependencies = [
"lexarg",
"lexarg-error",
]
[[package]]
name = "libtest2-harness"
version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1ca907aef7f70aceecb01e88588062946dd0af0727d80a68d9a1e928dacf07c9"
dependencies = [
"anstream",
"anstyle",
"lexarg-error",
"lexarg-parser",
"libtest-json",
"libtest-lexarg",
]
[[package]]
name = "libtest2-mimic"
version = "0.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a91f49bdcba4db89919ae87029787d2102f051e5dcf635df29e3bfdf55b2a4ac"
dependencies = [
"libtest-json",
"libtest2-harness",
]
[[package]]
name = "linux-raw-sys"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039"
[[package]]
name = "log"
version = "0.4.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432"
[[package]]
name = "memchr"
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "normalize-line-endings"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
[[package]]
name = "num-traits"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841"
dependencies = [
"autocfg",
]
[[package]]
name = "once_cell"
version = "1.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "once_cell_polyfill"
version = "1.70.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4895175b425cb1f87721b59f0f286c2092bd4af812243672510e1ac53e2e0ad"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy",
]
[[package]]
name = "proc-macro2"
version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [
"unicode-ident",
]
[[package]]
name = "proptest"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fcdab19deb5195a31cf7726a210015ff1496ba1464fd42cb4f537b8b01b471f"
dependencies = [
"bit-set",
"bit-vec",
"bitflags",
"lazy_static",
"num-traits",
"rand",
"rand_chacha",
"rand_xorshift",
"regex-syntax",
"rusty-fork",
"tempfile",
"unarray",
]
[[package]]
name = "quick-error"
version = "1.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
[[package]]
name = "quote"
version = "1.0.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rand"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_xorshift"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a"
dependencies = [
"rand_core",
]
[[package]]
name = "regex-automata"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b9458fa0bfeeac22b5ca447c63aaf45f28439a709ccd244698632f9aa6394d6"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
]
[[package]]
name = "regex-syntax"
version = "0.8.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "caf4aa5b0f434c91fe5c7f1ecb6a5ece2130b02ad2a590589dda5146df959001"
[[package]]
name = "rustix"
version = "1.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e"
dependencies = [
"bitflags",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.61.0",
]
[[package]]
name = "rusty-fork"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb3dcc6e454c328bb824492db107ab7c0ae8fcffe4ad210136ef014458c1bc4f"
dependencies = [
"fnv",
"quick-error",
"tempfile",
"wait-timeout",
]
[[package]]
name = "ryu"
version = "1.0.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502"
dependencies = [
"winapi-util",
]
[[package]]
name = "serde"
version = "1.0.225"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd6c24dee235d0da097043389623fb913daddf92c76e9f5a1db88607a0bcbd1d"
dependencies = [
"serde_core",
"serde_derive",
]
[[package]]
name = "serde-untagged"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9faf48a4a2d2693be24c6289dbe26552776eb7737074e6722891fadbe6c5058"
dependencies = [
"erased-serde",
"serde",
"serde_core",
"typeid",
]
[[package]]
name = "serde_core"
version = "1.0.225"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "659356f9a0cb1e529b24c01e43ad2bdf520ec4ceaf83047b83ddcc2251f96383"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
version = "1.0.225"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ea936adf78b1f766949a4977b91d2f5595825bd6ec079aa9543ad2685fc4516"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "serde_json"
version = "1.0.145"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
"serde_core",
]
[[package]]
name = "serde_spanned"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee"
dependencies = [
"serde_core",
]
[[package]]
name = "similar"
version = "2.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
[[package]]
name = "snapbox"
version = "0.6.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "96dcfc4581e3355d70ac2ee14cfdf81dce3d85c85f1ed9e2c1d3013f53b3436b"
dependencies = [
"anstream",
"anstyle",
"normalize-line-endings",
"similar",
"snapbox-macros",
]
[[package]]
name = "snapbox-macros"
version = "0.3.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16569f53ca23a41bb6f62e0a5084aa1661f4814a67fa33696a79073e03a664af"
dependencies = [
"anstream",
]
[[package]]
name = "syn"
version = "2.0.106"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tempfile"
version = "3.22.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84fa4d11fadde498443cca10fd3ac23c951f0dc59e080e9f4b93d4df4e4eea53"
dependencies = [
"fastrand",
"getrandom",
"once_cell",
"rustix",
"windows-sys 0.61.0",
]
[[package]]
name = "toml-test"
version = "2.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "36ecba8b17b5b0e3fe952335b981ce2fb477b3bff362d01d7db18d52b1b6733b"
dependencies = [
"chrono",
"ryu",
"serde",
"serde_json",
]
[[package]]
name = "toml-test-data"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea600d3ed690c00626705b301d30e25787300d80d9dc0b582097f4d6308599c3"
dependencies = [
"include_dir",
]
[[package]]
name = "toml-test-harness"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99a0b9e5066013f8b5ac9c5c9402605b222636e1ab115074977bf27e745e4252"
dependencies = [
"ignore",
"libtest2-mimic",
"snapbox",
"toml-test",
"toml-test-data",
]
[[package]]
name = "toml_datetime"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1"
dependencies = [
"serde_core",
]
[[package]]
name = "toml_edit"
version = "0.23.6"
dependencies = [
"anstream",
"anstyle",
"indexmap",
"proptest",
"serde",
"serde-untagged",
"serde_core",
"serde_json",
"serde_spanned",
"snapbox",
"toml-test-data",
"toml-test-harness",
"toml_datetime",
"toml_parser",
"toml_writer",
"walkdir",
"winnow",
]
[[package]]
name = "toml_parser"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627"
dependencies = [
"anstream",
"anstyle",
"winnow",
]
[[package]]
name = "toml_writer"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
[[package]]
name = "typeid"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
[[package]]
name = "unarray"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
[[package]]
name = "unicode-ident"
version = "1.0.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f63a545481291138910575129486daeaf8ac54aee4387fe7906919f7830c7d9d"
[[package]]
name = "utf8parse"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
[[package]]
name = "wait-timeout"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11"
dependencies = [
"libc",
]
[[package]]
name = "walkdir"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b"
dependencies = [
"same-file",
"winapi-util",
]
[[package]]
name = "wasi"
version = "0.14.4+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88a5f4a424faf49c3c2c344f166f0662341d470ea185e939657aaff130f0ec4a"
dependencies = [
"wit-bindgen",
]
[[package]]
name = "winapi-util"
version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.61.0",
]
[[package]]
name = "windows-link"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-link"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65"
[[package]]
name = "windows-sys"
version = "0.60.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.61.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e201184e40b2ede64bc2ea34968b28e33622acdbbf37104f0e4a33f7abe657aa"
dependencies = [
"windows-link 0.2.0",
]
[[package]]
name = "windows-targets"
version = "0.53.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91"
dependencies = [
"windows-link 0.1.3",
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764"
[[package]]
name = "windows_aarch64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c"
[[package]]
name = "windows_i686_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3"
[[package]]
name = "windows_i686_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11"
[[package]]
name = "windows_i686_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d"
[[package]]
name = "windows_x86_64_gnu"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57"
[[package]]
name = "windows_x86_64_msvc"
version = "0.53.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.7.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
dependencies = [
"memchr",
]
[[package]]
name = "wit-bindgen"
version = "0.45.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c573471f125075647d03df72e026074b7203790d41351cd6edc96f46bcccd36"
[[package]]
name = "zerocopy"
version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0894878a5fa3edfd6da3f88c4805f4c8558e2b996227a3d864f47fe11e38282c"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88d2b8d9c68ad2b9e4340d7832716a4d21a22a1154777ad56ea55c51a9cf3831"
dependencies = [
"proc-macro2",
"quote",
"syn",
]

265
vendor/toml_edit/Cargo.toml vendored Normal file
View File

@@ -0,0 +1,265 @@
# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
#
# When uploading crates to the registry Cargo will automatically
# "normalize" Cargo.toml files for maximal compatibility
# with all versions of Cargo and also rewrite `path` dependencies
# to registry (e.g., crates.io) dependencies.
#
# If you are reading this file be aware that the original Cargo.toml
# will likely look very different (and much more reasonable).
# See Cargo.toml.orig for the original contents.
[package]
edition = "2021"
rust-version = "1.76"
name = "toml_edit"
version = "0.23.6"
build = false
include = [
"build.rs",
"src/**/*",
"Cargo.toml",
"Cargo.lock",
"LICENSE*",
"README.md",
"examples/**/*",
]
autolib = false
autobins = false
autoexamples = false
autotests = false
autobenches = false
description = "Yet another format-preserving TOML parser."
readme = "README.md"
keywords = [
"encoding",
"toml",
]
categories = [
"encoding",
"parser-implementations",
"parsing",
"config",
]
license = "MIT OR Apache-2.0"
repository = "https://github.com/toml-rs/toml"
[package.metadata.docs.rs]
all-features = true
rustdoc-args = [
"--cfg",
"docsrs",
"--generate-link-to-definition",
]
[package.metadata.release]
tag-name = "v{{version}}"
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = "Unreleased"
replace = "{{version}}"
min = 1
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = '\.\.\.HEAD'
replace = "...{{tag_name}}"
exactly = 1
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = "ReleaseDate"
replace = "{{date}}"
min = 1
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = "<!-- next-header -->"
replace = """
<!-- next-header -->
## [Unreleased] - ReleaseDate
"""
exactly = 1
[[package.metadata.release.pre-release-replacements]]
file = "CHANGELOG.md"
search = "<!-- next-url -->"
replace = """
<!-- next-url -->
[Unreleased]: https://github.com/toml-rs/toml/compare/{{tag_name}}...HEAD"""
exactly = 1
[features]
debug = [
"toml_parser?/debug",
"dep:anstream",
"dep:anstyle",
"display",
]
default = [
"parse",
"display",
]
display = ["dep:toml_writer"]
parse = [
"dep:toml_parser",
"dep:winnow",
]
serde = [
"dep:serde_core",
"toml_datetime/serde",
"dep:serde_spanned",
]
unbounded = []
[lib]
name = "toml_edit"
path = "src/lib.rs"
[[example]]
name = "visit"
path = "examples/visit.rs"
test = true
required-features = [
"parse",
"display",
]
[dependencies.anstream]
version = "0.6.20"
optional = true
[dependencies.anstyle]
version = "1.0.11"
optional = true
[dependencies.indexmap]
version = "2.11.4"
features = ["std"]
[dependencies.serde_core]
version = "1.0.225"
optional = true
[dependencies.serde_spanned]
version = "1.0.2"
features = ["serde"]
optional = true
[dependencies.toml_datetime]
version = "0.7.2"
[dependencies.toml_parser]
version = "1.0.3"
optional = true
[dependencies.toml_writer]
version = "1.0.3"
optional = true
[dependencies.winnow]
version = "0.7.13"
optional = true
[dev-dependencies.proptest]
version = "1.7.0"
[dev-dependencies.serde]
version = "1.0.225"
features = ["derive"]
[dev-dependencies.serde-untagged]
version = "0.1.9"
[dev-dependencies.serde_json]
version = "1.0.145"
[dev-dependencies.snapbox]
version = "0.6.21"
[dev-dependencies.toml-test-data]
version = "2.3.3"
[dev-dependencies.toml-test-harness]
version = "1.3.3"
features = ["snapshot"]
[dev-dependencies.walkdir]
version = "2.5.0"
[lints.clippy]
bool_assert_comparison = "allow"
branches_sharing_code = "allow"
checked_conversions = "warn"
collapsible_else_if = "allow"
create_dir = "warn"
dbg_macro = "warn"
debug_assert_with_mut_call = "warn"
doc_markdown = "warn"
empty_enum = "warn"
enum_glob_use = "warn"
expl_impl_clone_on_copy = "warn"
explicit_deref_methods = "warn"
explicit_into_iter_loop = "warn"
fallible_impl_from = "warn"
filter_map_next = "warn"
flat_map_option = "warn"
float_cmp_const = "warn"
fn_params_excessive_bools = "warn"
from_iter_instead_of_collect = "warn"
get_first = "allow"
if_same_then_else = "allow"
implicit_clone = "warn"
imprecise_flops = "warn"
inconsistent_struct_constructor = "warn"
inefficient_to_string = "warn"
infinite_loop = "warn"
invalid_upcast_comparisons = "warn"
large_digit_groups = "warn"
large_stack_arrays = "warn"
large_types_passed_by_value = "warn"
let_and_return = "allow"
linkedlist = "warn"
lossy_float_literal = "warn"
macro_use_imports = "warn"
mem_forget = "warn"
mutex_integer = "warn"
needless_bool = "allow"
needless_continue = "allow"
needless_for_each = "warn"
negative_feature_names = "warn"
path_buf_push_overwrite = "warn"
ptr_as_ptr = "warn"
rc_mutex = "warn"
redundant_feature_names = "warn"
ref_option_ref = "warn"
rest_pat_in_fully_bound_structs = "warn"
result_large_err = "allow"
same_functions_in_if_condition = "warn"
self_named_module_files = "warn"
semicolon_if_nothing_returned = "warn"
str_to_string = "warn"
string_add = "warn"
string_add_assign = "warn"
string_lit_as_bytes = "warn"
string_to_string = "warn"
todo = "warn"
trait_duplication_in_bounds = "warn"
uninlined_format_args = "warn"
use_self = "warn"
verbose_file_reads = "warn"
wildcard_imports = "warn"
zero_sized_map_values = "warn"
[lints.rust]
unnameable_types = "allow"
unreachable_pub = "warn"
unsafe_op_in_unsafe_fn = "warn"
unused_lifetimes = "warn"
unused_macro_rules = "warn"
unused_qualifications = "warn"
[lints.rust.rust_2018_idioms]
level = "warn"
priority = -1

202
vendor/toml_edit/LICENSE-APACHE vendored Normal file
View File

@@ -0,0 +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.

19
vendor/toml_edit/LICENSE-MIT vendored Normal file
View File

@@ -0,0 +1,19 @@
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
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

61
vendor/toml_edit/README.md vendored Normal file
View File

@@ -0,0 +1,61 @@
# 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)
This crate allows you to parse and modify toml
documents, while preserving comments, spaces *and
relative order* of items.
`toml_edit` is primarily tailored for [cargo-edit](https://github.com/killercup/cargo-edit/) needs.
## Example
```rust
use toml_edit::{DocumentMut, value};
fn main() {
let toml = r#"
"hello" = 'toml!' # comment
['a'.b]
"#;
let mut doc = toml.parse::<DocumentMut>().expect("invalid doc");
assert_eq!(doc.to_string(), toml);
// let's add a new key/value pair inside a.b: c = {d = "hello"}
doc["a"]["b"]["c"]["d"] = value("hello");
// autoformat inline table a.b.c: { d = "hello" }
doc["a"]["b"]["c"].as_inline_table_mut().map(|t| t.fmt());
let expected = r#"
"hello" = 'toml!' # comment
['a'.b]
c = { d = "hello" }
"#;
assert_eq!(doc.to_string(), expected);
}
```
## Limitations
Things it does not preserve:
* Order of dotted keys, see [issue](https://github.com/toml-rs/toml/issues/163).
## License
Licensed under either of
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <https://www.apache.org/licenses/LICENSE-2.0>)
* MIT license ([LICENSE-MIT](LICENSE-MIT) or <https://opensource.org/license/mit>)
at your option.
### 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.

284
vendor/toml_edit/examples/visit.rs vendored Normal file
View File

@@ -0,0 +1,284 @@
//! Example for how to use `VisitMut` to iterate over a table.
use std::collections::BTreeSet;
use toml_edit::visit::{visit_table_like_kv, Visit};
use toml_edit::visit_mut::{visit_table_like_kv_mut, visit_table_mut, VisitMut};
use toml_edit::{Array, DocumentMut, InlineTable, Item, KeyMut, Table, Value};
/// This models the visit state for dependency keys in a `Cargo.toml`.
///
/// Dependencies can be specified as:
///
/// ```toml
/// [dependencies]
/// dep1 = "0.2"
///
/// [build-dependencies]
/// dep2 = "0.3"
///
/// [dev-dependencies]
/// dep3 = "0.4"
///
/// [target.'cfg(windows)'.dependencies]
/// dep4 = "0.5"
///
/// # and target build- and dev-dependencies
/// ```
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
enum VisitState {
/// Represents the root of the table.
Root,
/// Represents "dependencies", "build-dependencies" or "dev-dependencies", or the target
/// forms of these.
Dependencies,
/// A table within dependencies.
SubDependencies,
/// Represents "target".
Target,
/// "target.[TARGET]".
TargetWithSpec,
/// Represents some other state.
Other,
}
impl VisitState {
/// Figures out the next visit state, given the current state and the given key.
fn descend(self, key: &str) -> Self {
match (self, key) {
(
Self::Root | Self::TargetWithSpec,
"dependencies" | "build-dependencies" | "dev-dependencies",
) => Self::Dependencies,
(Self::Root, "target") => Self::Target,
(Self::Root | Self::TargetWithSpec, _) => Self::Other,
(Self::Target, _) => Self::TargetWithSpec,
(Self::Dependencies, _) => Self::SubDependencies,
(Self::SubDependencies, _) => Self::SubDependencies,
(Self::Other, _) => Self::Other,
}
}
}
/// Collect the names of every dependency key.
#[derive(Debug)]
struct DependencyNameVisitor<'doc> {
state: VisitState,
names: BTreeSet<&'doc str>,
}
impl<'doc> Visit<'doc> for DependencyNameVisitor<'doc> {
fn visit_table_like_kv(&mut self, key: &'doc str, node: &'doc Item) {
if self.state == VisitState::Dependencies {
self.names.insert(key);
} else {
// Since we're only interested in collecting the top-level keys right under
// [dependencies], don't recurse unconditionally.
let old_state = self.state;
// Figure out the next state given the key.
self.state = self.state.descend(key);
// Recurse further into the document tree.
visit_table_like_kv(self, key, node);
// Restore the old state after it's done.
self.state = old_state;
}
}
}
/// Normalize all dependency tables into the format:
///
/// ```toml
/// [dependencies]
/// dep = { version = "1.0", features = ["foo", "bar"], ... }
/// ```
///
/// leaving other tables untouched.
#[derive(Debug)]
struct NormalizeDependencyTablesVisitor {
state: VisitState,
}
impl VisitMut for NormalizeDependencyTablesVisitor {
fn visit_table_mut(&mut self, node: &mut Table) {
visit_table_mut(self, node);
// The conversion from regular tables into inline ones might leave some explicit parent
// tables hanging, so convert them to implicit.
if matches!(self.state, VisitState::Target | VisitState::TargetWithSpec) {
node.set_implicit(true);
}
}
fn visit_table_like_kv_mut(&mut self, mut key: KeyMut<'_>, node: &mut Item) {
let old_state = self.state;
// Figure out the next state given the key.
self.state = self.state.descend(key.get());
match self.state {
VisitState::Target | VisitState::TargetWithSpec | VisitState::Dependencies => {
// Top-level dependency row, or above: turn inline tables into regular ones.
if let Item::Value(Value::InlineTable(inline_table)) = node {
let inline_table = std::mem::replace(inline_table, InlineTable::new());
let table = inline_table.into_table();
key.fmt();
*node = Item::Table(table);
}
}
VisitState::SubDependencies => {
// Individual dependency: turn regular tables into inline ones.
if let Item::Table(table) = node {
// Turn the table into an inline table.
let table = std::mem::replace(table, Table::new());
let inline_table = table.into_inline_table();
key.fmt();
*node = Item::Value(Value::InlineTable(inline_table));
}
}
_ => {}
}
// Recurse further into the document tree.
visit_table_like_kv_mut(self, key, node);
// Restore the old state after it's done.
self.state = old_state;
}
fn visit_array_mut(&mut self, node: &mut Array) {
// Format any arrays within dependencies to be on the same line.
if matches!(
self.state,
VisitState::Dependencies | VisitState::SubDependencies
) {
node.fmt();
}
}
}
/// This is the input provided to `visit_mut_example`.
static INPUT: &str = r#"
[package]
name = "my-package"
[package.metadata.foo]
bar = 42
[dependencies]
atty = "0.2"
cargo-platform = { path = "crates/cargo-platform", version = "0.1.2" }
[dependencies.pretty_env_logger]
version = "0.4"
optional = true
[target.'cfg(windows)'.dependencies]
fwdansi = "1.1.0"
[target.'cfg(windows)'.dependencies.winapi]
version = "0.3"
features = [
"handleapi",
"jobapi",
]
[target.'cfg(unix)']
dev-dependencies = { miniz_oxide = "0.5" }
[dev-dependencies.cargo-test-macro]
path = "crates/cargo-test-macro"
[build-dependencies.flate2]
version = "0.4"
"#;
/// This is the output produced by `visit_mut_example`.
#[cfg(test)]
static VISIT_MUT_OUTPUT: &str = r#"
[package]
name = "my-package"
[package.metadata.foo]
bar = 42
[dependencies]
atty = "0.2"
cargo-platform = { path = "crates/cargo-platform", version = "0.1.2" }
pretty_env_logger = { version = "0.4", optional = true }
[target.'cfg(windows)'.dependencies]
fwdansi = "1.1.0"
winapi = { version = "0.3", features = ["handleapi", "jobapi"] }
[target.'cfg(unix)'.dev-dependencies]
miniz_oxide = "0.5"
[dev-dependencies]
cargo-test-macro = { path = "crates/cargo-test-macro" }
[build-dependencies]
flate2 = { version = "0.4" }
"#;
fn visit_example(document: &DocumentMut) -> BTreeSet<&str> {
let mut visitor = DependencyNameVisitor {
state: VisitState::Root,
names: BTreeSet::new(),
};
visitor.visit_document(document);
visitor.names
}
fn visit_mut_example(document: &mut DocumentMut) {
let mut visitor = NormalizeDependencyTablesVisitor {
state: VisitState::Root,
};
visitor.visit_document_mut(document);
}
fn main() {
let mut document: DocumentMut = INPUT.parse().expect("input is valid TOML");
println!("** visit example");
println!("{:?}", visit_example(&document));
println!("** visit_mut example");
visit_mut_example(&mut document);
println!("{document}");
}
#[cfg(test)]
#[test]
fn visit_correct() {
let document: DocumentMut = INPUT.parse().expect("input is valid TOML");
let names = visit_example(&document);
let expected = vec![
"atty",
"cargo-platform",
"pretty_env_logger",
"fwdansi",
"winapi",
"miniz_oxide",
"cargo-test-macro",
"flate2",
]
.into_iter()
.collect();
assert_eq!(names, expected);
}
#[cfg(test)]
#[test]
fn visit_mut_correct() {
let mut document: DocumentMut = INPUT.parse().expect("input is valid TOML");
visit_mut_example(&mut document);
assert_eq!(format!("{document}"), VISIT_MUT_OUTPUT);
}

442
vendor/toml_edit/src/array.rs vendored Normal file
View File

@@ -0,0 +1,442 @@
use std::iter::FromIterator;
use std::mem;
use crate::repr::Decor;
use crate::value::{DEFAULT_LEADING_VALUE_DECOR, DEFAULT_VALUE_DECOR};
use crate::{Item, RawString, Value};
/// A TOML [`Value`] that contains a sequence of [`Value`]s
#[derive(Debug, Default, Clone)]
pub struct Array {
// `trailing` represents whitespaces, newlines
// and comments in an empty array or after the trailing comma
trailing: RawString,
trailing_comma: bool,
// prefix before `[` and suffix after `]`
decor: Decor,
pub(crate) span: Option<std::ops::Range<usize>>,
// always Vec<Item::Value>
pub(crate) values: Vec<Item>,
}
/// An owned iterator type over [`Array`]'s [`Value`]s
pub type ArrayIntoIter = Box<dyn Iterator<Item = Value>>;
/// An iterator type over [`Array`]'s [`Value`]s
pub type ArrayIter<'a> = Box<dyn Iterator<Item = &'a Value> + 'a>;
/// An iterator type over [`Array`]'s [`Value`]s
pub type ArrayIterMut<'a> = Box<dyn Iterator<Item = &'a mut Value> + 'a>;
/// Constructors
///
/// See also `FromIterator`
impl Array {
/// Create an empty `Array`
///
/// # Examples
///
/// ```rust
/// let mut arr = toml_edit::Array::new();
/// ```
pub fn new() -> Self {
Default::default()
}
pub(crate) fn with_vec(values: Vec<Item>) -> Self {
Self {
values,
..Default::default()
}
}
}
/// Formatting
impl Array {
/// Auto formats the array.
pub fn fmt(&mut self) {
decorate_array(self);
}
/// Set whether the array will use a trailing comma
pub fn set_trailing_comma(&mut self, yes: bool) {
self.trailing_comma = yes;
}
/// Whether the array will use a trailing comma
pub fn trailing_comma(&self) -> bool {
self.trailing_comma
}
/// Set whitespace after last element
pub fn set_trailing(&mut self, trailing: impl Into<RawString>) {
self.trailing = trailing.into();
}
/// Whitespace after last element
pub fn trailing(&self) -> &RawString {
&self.trailing
}
/// Returns the surrounding whitespace
pub fn decor_mut(&mut self) -> &mut Decor {
&mut self.decor
}
/// Returns the surrounding whitespace
pub fn decor(&self) -> &Decor {
&self.decor
}
/// The location within the original document
///
/// This generally requires a [`Document`][crate::Document].
pub fn span(&self) -> Option<std::ops::Range<usize>> {
self.span.clone()
}
pub(crate) fn despan(&mut self, input: &str) {
self.span = None;
self.decor.despan(input);
self.trailing.despan(input);
for value in &mut self.values {
value.despan(input);
}
}
}
impl Array {
/// Returns an iterator over all values.
pub fn iter(&self) -> ArrayIter<'_> {
Box::new(self.values.iter().filter_map(Item::as_value))
}
/// Returns an iterator over all values.
pub fn iter_mut(&mut self) -> ArrayIterMut<'_> {
Box::new(self.values.iter_mut().filter_map(Item::as_value_mut))
}
/// Returns the length of the underlying Vec.
///
/// In some rare cases, placeholder elements will exist. For a more accurate count, call
/// `a.iter().count()`
///
/// # Examples
///
/// ```rust
/// let mut arr = toml_edit::Array::new();
/// arr.push(1);
/// arr.push("foo");
/// assert_eq!(arr.len(), 2);
/// ```
pub fn len(&self) -> usize {
self.values.len()
}
/// Return true if `self.len() == 0`.
///
/// # Examples
///
/// ```rust
/// let mut arr = toml_edit::Array::new();
/// assert!(arr.is_empty());
///
/// arr.push(1);
/// arr.push("foo");
/// assert!(! arr.is_empty());
/// ```
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Clears the array, removing all values. Keeps the allocated memory for reuse.
pub fn clear(&mut self) {
self.values.clear();
}
/// Returns a reference to the value at the given index, or `None` if the index is out of
/// bounds.
pub fn get(&self, index: usize) -> Option<&Value> {
self.values.get(index).and_then(Item::as_value)
}
/// Returns a reference to the value at the given index, or `None` if the index is out of
/// bounds.
pub fn get_mut(&mut self, index: usize) -> Option<&mut Value> {
self.values.get_mut(index).and_then(Item::as_value_mut)
}
/// Appends a new value to the end of the array, applying default formatting to it.
///
/// # Examples
///
/// ```rust
/// let mut arr = toml_edit::Array::new();
/// arr.push(1);
/// arr.push("foo");
/// ```
pub fn push<V: Into<Value>>(&mut self, v: V) {
self.values.push(Item::Value(v.into()));
}
/// Appends a new, already formatted value to the end of the 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));
}
/// Inserts an element at the given position within the array, applying default formatting to
/// it and shifting all values after it to the right.
///
/// # Panics
///
/// Panics if `index > len`.
///
/// # Examples
///
/// ```rust
/// let mut arr = toml_edit::Array::new();
/// arr.push(1);
/// arr.push("foo");
///
/// arr.insert(0, "start");
/// ```
pub fn insert<V: Into<Value>>(&mut self, index: usize, v: V) {
self.values.insert(index, Item::Value(v.into()));
}
/// Inserts an already formatted value at the given position within the array, shifting all
/// values after it to the right.
///
/// # Panics
///
/// Panics if `index > len`.
///
/// # 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));
}
/// Replaces the element at the given position within the array, preserving existing formatting.
///
/// # Panics
///
/// Panics if `index >= len`.
///
/// # Examples
///
/// ```rust
/// let mut arr = toml_edit::Array::new();
/// arr.push(1);
/// arr.push("foo");
///
/// arr.replace(0, "start");
/// ```
pub fn replace<V: Into<Value>>(&mut self, index: usize, v: V) -> Value {
// Read the existing value's decor and preserve it.
let existing_decor = self
.get(index)
.unwrap_or_else(|| panic!("index {} out of bounds (len = {})", index, self.len()))
.decor();
let mut value = v.into();
*value.decor_mut() = existing_decor.clone();
self.replace_formatted(index, value)
}
/// Replaces the element at the given position within the array with an already formatted value.
///
/// # Panics
///
/// Panics if `index >= len`.
///
/// # 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)) {
Item::Value(old_value) => old_value,
x => panic!("non-value item {x:?} in an array"),
}
}
/// Removes the value at the given index.
///
/// # Examples
///
/// ```rust
/// let mut arr = toml_edit::Array::new();
/// arr.push(1);
/// arr.push("foo");
///
/// arr.remove(0);
/// assert_eq!(arr.len(), 1);
/// ```
pub fn remove(&mut self, index: usize) -> Value {
let removed = self.values.remove(index);
match removed {
Item::Value(v) => v,
x => panic!("non-value item {x:?} in an array"),
}
}
/// Retains only the values specified by the `keep` predicate.
///
/// In other words, remove all values for which `keep(&value)` returns `false`.
///
/// This method operates in place, visiting each element exactly once in the
/// original order, and preserves the order of the retained elements.
pub fn retain<F>(&mut self, mut keep: F)
where
F: FnMut(&Value) -> bool,
{
self.values
.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
}
});
}
}
#[cfg(feature = "display")]
impl std::fmt::Display for Array {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
crate::encode::encode_array(self, f, None, ("", ""))
}
}
impl<V: Into<Value>> Extend<V> for Array {
fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T) {
for value in iter {
self.push_formatted(value.into());
}
}
}
impl<V: Into<Value>> FromIterator<V> for Array {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = V>,
{
let v = iter.into_iter().map(|a| Item::Value(a.into()));
Self {
values: v.collect(),
..Default::default()
}
}
}
impl IntoIterator for Array {
type Item = Value;
type IntoIter = ArrayIntoIter;
fn into_iter(self) -> Self::IntoIter {
Box::new(
self.values
.into_iter()
.filter(|v| v.is_value())
.map(|v| v.into_value().unwrap()),
)
}
}
impl<'s> IntoIterator for &'s Array {
type Item = &'s Value;
type IntoIter = ArrayIter<'s>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
fn decorate_array(array: &mut Array) {
for (i, value) in array
.values
.iter_mut()
.filter_map(Item::as_value_mut)
.enumerate()
{
// [value1, value2, value3]
if i == 0 {
value.decorate(DEFAULT_LEADING_VALUE_DECOR.0, DEFAULT_LEADING_VALUE_DECOR.1);
} else {
value.decorate(DEFAULT_VALUE_DECOR.0, DEFAULT_VALUE_DECOR.1);
}
}
// Since everything is now on the same line, remove trailing commas and whitespace.
array.set_trailing_comma(false);
array.set_trailing("");
}

172
vendor/toml_edit/src/array_of_tables.rs vendored Normal file
View File

@@ -0,0 +1,172 @@
use std::iter::FromIterator;
use crate::{Array, Item, Table};
/// A top-level sequence of [`Table`]s, each under their own header
#[derive(Clone, Debug, Default)]
pub struct ArrayOfTables {
// Always Vec<Item::Table>, just `Item` to make `Index` work
pub(crate) span: Option<std::ops::Range<usize>>,
pub(crate) values: Vec<Item>,
}
/// Constructors
///
/// See also `FromIterator`
impl ArrayOfTables {
/// Creates an empty array of tables.
pub fn new() -> Self {
Default::default()
}
}
/// Formatting
impl ArrayOfTables {
/// Convert to an inline array
pub fn into_array(mut self) -> Array {
for value in self.values.iter_mut() {
value.make_value();
}
let mut a = Array::with_vec(self.values);
a.fmt();
a
}
/// The location within the original document
///
/// This generally requires a [`Document`][crate::Document].
pub fn span(&self) -> Option<std::ops::Range<usize>> {
self.span.clone()
}
pub(crate) fn despan(&mut self, input: &str) {
self.span = None;
for value in &mut self.values {
value.despan(input);
}
}
}
impl ArrayOfTables {
/// Returns an iterator over tables.
pub fn iter(&self) -> ArrayOfTablesIter<'_> {
Box::new(self.values.iter().filter_map(Item::as_table))
}
/// Returns an iterator over tables.
pub fn iter_mut(&mut self) -> ArrayOfTablesIterMut<'_> {
Box::new(self.values.iter_mut().filter_map(Item::as_table_mut))
}
/// Returns the length of the underlying Vec.
/// To get the actual number of items use `a.iter().count()`.
pub fn len(&self) -> usize {
self.values.len()
}
/// Returns true if `self.len() == 0`.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Removes all the tables.
pub fn clear(&mut self) {
self.values.clear();
}
/// Returns an optional reference to the table.
pub fn get(&self, index: usize) -> Option<&Table> {
self.values.get(index).and_then(Item::as_table)
}
/// Returns an optional mutable reference to the table.
pub fn get_mut(&mut self, index: usize) -> Option<&mut Table> {
self.values.get_mut(index).and_then(Item::as_table_mut)
}
/// Appends a table to the array.
pub fn push(&mut self, table: Table) {
self.values.push(Item::Table(table));
}
/// Removes a table with the given index.
pub fn remove(&mut self, index: usize) -> Table {
self.values
.remove(index)
.into_table()
.expect("cannot have any other item in an array-of-tables")
}
/// Retains only the elements specified by the `keep` predicate.
///
/// In other words, remove all tables for which `keep(&table)` returns `false`.
///
/// This method operates in place, visiting each element exactly once in the
/// original order, and preserves the order of the retained elements.
pub fn retain<F>(&mut self, mut keep: F)
where
F: FnMut(&Table) -> bool,
{
self.values
.retain(|item| item.as_table().map(&mut keep).unwrap_or(false));
}
}
/// An iterator type over [`ArrayOfTables`]'s [`Table`]s
pub type ArrayOfTablesIter<'a> = Box<dyn Iterator<Item = &'a Table> + 'a>;
/// An iterator type over [`ArrayOfTables`]'s [`Table`]s
pub type ArrayOfTablesIterMut<'a> = Box<dyn Iterator<Item = &'a mut Table> + 'a>;
/// An iterator type over [`ArrayOfTables`]'s [`Table`]s
pub type ArrayOfTablesIntoIter = Box<dyn Iterator<Item = Table>>;
impl Extend<Table> for ArrayOfTables {
fn extend<T: IntoIterator<Item = Table>>(&mut self, iter: T) {
for value in iter {
self.push(value);
}
}
}
impl FromIterator<Table> for ArrayOfTables {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = Table>,
{
let v = iter.into_iter().map(Item::Table);
Self {
values: v.collect(),
span: None,
}
}
}
impl IntoIterator for ArrayOfTables {
type Item = Table;
type IntoIter = ArrayOfTablesIntoIter;
fn into_iter(self) -> Self::IntoIter {
Box::new(
self.values
.into_iter()
.filter(|v| v.is_table())
.map(|v| v.into_table().unwrap()),
)
}
}
impl<'s> IntoIterator for &'s ArrayOfTables {
type Item = &'s Table;
type IntoIter = ArrayOfTablesIter<'s>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
#[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
self.clone().into_array().fmt(f)
}
}

87
vendor/toml_edit/src/de/array.rs vendored Normal file
View File

@@ -0,0 +1,87 @@
use crate::de::Error;
pub(crate) struct ArrayDeserializer {
input: Vec<crate::Item>,
span: Option<std::ops::Range<usize>>,
}
impl ArrayDeserializer {
pub(crate) fn new(input: Vec<crate::Item>, span: Option<std::ops::Range<usize>>) -> Self {
Self { input, span }
}
}
impl<'de> serde_core::Deserializer<'de> for ArrayDeserializer {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde_core::de::Visitor<'de>,
{
visitor.visit_seq(ArraySeqAccess::new(self.input))
}
fn deserialize_struct<V>(
self,
name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
if serde_spanned::de::is_spanned(name) {
if let Some(span) = self.span.clone() {
return visitor.visit_map(
serde_spanned::de::SpannedDeserializer::<Self, Error>::new(self, span),
);
} else {
return Err(Error::custom("value is missing a span", None));
}
}
self.deserialize_any(visitor)
}
serde_core::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
ignored_any unit_struct tuple_struct tuple enum identifier
}
}
impl serde_core::de::IntoDeserializer<'_, Error> for ArrayDeserializer {
type Deserializer = Self;
fn into_deserializer(self) -> Self::Deserializer {
self
}
}
pub(crate) struct ArraySeqAccess {
iter: std::vec::IntoIter<crate::Item>,
}
impl ArraySeqAccess {
pub(crate) fn new(input: Vec<crate::Item>) -> Self {
Self {
iter: input.into_iter(),
}
}
}
impl<'de> serde_core::de::SeqAccess<'de> for ArraySeqAccess {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: serde_core::de::DeserializeSeed<'de>,
{
match self.iter.next() {
Some(v) => seed
.deserialize(crate::de::ValueDeserializer::new(v))
.map(Some),
None => Ok(None),
}
}
}

75
vendor/toml_edit/src/de/error.rs vendored Normal file
View File

@@ -0,0 +1,75 @@
/// Errors that can occur when deserializing a type.
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Error {
inner: crate::TomlError,
}
impl Error {
pub(crate) fn custom<T>(msg: T, span: Option<std::ops::Range<usize>>) -> Self
where
T: std::fmt::Display,
{
Self {
inner: crate::TomlError::custom(msg.to_string(), span),
}
}
/// Add key while unwinding
pub fn add_key(&mut self, key: String) {
self.inner.add_key(key);
}
/// What went wrong
pub fn message(&self) -> &str {
self.inner.message()
}
/// The start/end index into the original document where the error occurred
pub fn span(&self) -> Option<std::ops::Range<usize>> {
self.inner.span()
}
pub(crate) fn set_span(&mut self, span: Option<std::ops::Range<usize>>) {
self.inner.set_span(span);
}
/// Provide the encoded TOML the error applies to
pub fn set_input(&mut self, input: Option<&str>) {
self.inner.set_input(input);
}
}
impl serde_core::de::Error for Error {
fn custom<T>(msg: T) -> Self
where
T: std::fmt::Display,
{
Self::custom(msg, None)
}
}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
impl std::fmt::Debug for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.inner.fmt(f)
}
}
impl From<crate::TomlError> for Error {
fn from(e: crate::TomlError) -> Self {
Self { inner: e }
}
}
impl From<Error> for crate::TomlError {
fn from(e: Error) -> Self {
e.inner
}
}
impl std::error::Error for Error {}

158
vendor/toml_edit/src/de/key.rs vendored Normal file
View File

@@ -0,0 +1,158 @@
use serde_core::de::IntoDeserializer;
use super::Error;
pub(crate) struct KeyDeserializer {
span: Option<std::ops::Range<usize>>,
key: crate::Key,
}
impl KeyDeserializer {
pub(crate) fn new(key: crate::Key, span: Option<std::ops::Range<usize>>) -> Self {
Self { span, key }
}
}
impl IntoDeserializer<'_, Error> for KeyDeserializer {
type Deserializer = Self;
fn into_deserializer(self) -> Self::Deserializer {
self
}
}
impl<'de> serde_core::de::Deserializer<'de> for KeyDeserializer {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
self.key.into_deserializer().deserialize_any(visitor)
}
fn deserialize_enum<V>(
self,
name: &str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: serde_core::de::Visitor<'de>,
{
let _ = name;
let _ = variants;
visitor.visit_enum(self)
}
fn deserialize_struct<V>(
self,
name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
if serde_spanned::de::is_spanned(name) {
if let Some(span) = self.span.clone() {
return visitor.visit_map(
serde_spanned::de::SpannedDeserializer::<&str, Error>::new(
self.key.get(),
span,
),
);
} else {
return Err(Error::custom("value is missing a span", None));
}
}
self.deserialize_any(visitor)
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
serde_core::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
ignored_any unit_struct tuple_struct tuple identifier
}
}
impl<'de> serde_core::de::EnumAccess<'de> for KeyDeserializer {
type Error = Error;
type Variant = UnitOnly<Self::Error>;
fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
where
T: serde_core::de::DeserializeSeed<'de>,
{
seed.deserialize(self).map(unit_only)
}
}
pub(crate) struct UnitOnly<E> {
marker: std::marker::PhantomData<E>,
}
fn unit_only<T, E>(t: T) -> (T, UnitOnly<E>) {
(
t,
UnitOnly {
marker: std::marker::PhantomData,
},
)
}
impl<'de, E> serde_core::de::VariantAccess<'de> for UnitOnly<E>
where
E: serde_core::de::Error,
{
type Error = E;
fn unit_variant(self) -> Result<(), Self::Error> {
Ok(())
}
fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
where
T: serde_core::de::DeserializeSeed<'de>,
{
Err(serde_core::de::Error::invalid_type(
serde_core::de::Unexpected::UnitVariant,
&"newtype variant",
))
}
fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
where
V: serde_core::de::Visitor<'de>,
{
Err(serde_core::de::Error::invalid_type(
serde_core::de::Unexpected::UnitVariant,
&"tuple variant",
))
}
fn struct_variant<V>(
self,
_fields: &'static [&'static str],
_visitor: V,
) -> Result<V::Value, Self::Error>
where
V: serde_core::de::Visitor<'de>,
{
Err(serde_core::de::Error::invalid_type(
serde_core::de::Unexpected::UnitVariant,
&"struct variant",
))
}
}

250
vendor/toml_edit/src/de/mod.rs vendored Normal file
View File

@@ -0,0 +1,250 @@
//! Deserializing TOML into Rust structures.
//!
//! This module contains all the Serde support for deserializing TOML documents into Rust structures.
use serde_core::de::DeserializeOwned;
mod array;
mod error;
mod key;
mod table;
mod table_enum;
mod value;
use array::ArrayDeserializer;
use key::KeyDeserializer;
use table::TableDeserializer;
use table_enum::TableEnumDeserializer;
use toml_datetime::de::DatetimeDeserializer;
pub use error::Error;
pub use value::ValueDeserializer;
/// Deserializes a string into a type.
///
/// This function will attempt to interpret `s` as a TOML document and
/// deserialize `T` from the document.
///
/// To deserializes TOML values, instead of documents, see [`ValueDeserializer`].
///
/// # Examples
///
/// ```
/// use serde::Deserialize;
///
/// #[derive(Deserialize)]
/// struct Config {
/// title: String,
/// owner: Owner,
/// }
///
/// #[derive(Deserialize)]
/// struct Owner {
/// name: String,
/// }
///
/// let config: Config = toml_edit::de::from_str(r#"
/// title = 'TOML Example'
///
/// [owner]
/// name = 'Lisa'
/// "#).unwrap();
///
/// assert_eq!(config.title, "TOML Example");
/// assert_eq!(config.owner.name, "Lisa");
/// ```
#[cfg(feature = "parse")]
pub fn from_str<T>(s: &'_ str) -> Result<T, Error>
where
T: DeserializeOwned,
{
let de = Deserializer::parse(s)?;
T::deserialize(de)
}
/// Deserializes bytes into a type.
///
/// This function will attempt to interpret `s` as a TOML document and
/// deserialize `T` from the document.
///
/// To deserializes TOML values, instead of documents, see [`ValueDeserializer`].
#[cfg(feature = "parse")]
pub fn from_slice<T>(s: &'_ [u8]) -> Result<T, Error>
where
T: DeserializeOwned,
{
let s = std::str::from_utf8(s).map_err(|e| Error::custom(e, None))?;
from_str(s)
}
/// Convert a [`DocumentMut`][crate::DocumentMut] into `T`.
pub fn from_document<T>(d: impl Into<Deserializer>) -> Result<T, Error>
where
T: DeserializeOwned,
{
let deserializer = d.into();
T::deserialize(deserializer)
}
/// Deserialization for TOML [documents][crate::DocumentMut].
pub struct Deserializer<S = String> {
root: crate::Item,
raw: Option<S>,
}
#[cfg(feature = "parse")]
impl<S: AsRef<str>> Deserializer<S> {
/// Parse a TOML document
pub fn parse(raw: S) -> Result<Self, Error> {
crate::Document::parse(raw)
.map(Self::from)
.map_err(Into::into)
}
}
impl From<crate::DocumentMut> for Deserializer {
fn from(doc: crate::DocumentMut) -> Self {
let crate::DocumentMut { root, .. } = doc;
Self { root, raw: None }
}
}
impl<S> From<crate::Document<S>> for Deserializer<S> {
fn from(doc: crate::Document<S>) -> Self {
let crate::Document { root, raw, .. } = doc;
let raw = Some(raw);
Self { root, raw }
}
}
#[cfg(feature = "parse")]
impl std::str::FromStr for Deserializer {
type Err = Error;
/// Parses a document from a &str
fn from_str(s: &str) -> Result<Self, Self::Err> {
let doc: crate::Document<_> = s.parse().map_err(Error::from)?;
Ok(Self::from(doc))
}
}
impl<'de, S: AsRef<str>> serde_core::Deserializer<'de> for Deserializer<S> {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde_core::de::Visitor<'de>,
{
let raw = self.raw;
ValueDeserializer::new(self.root)
.deserialize_any(visitor)
.map_err(|mut e: Self::Error| {
let raw = raw.as_ref().map(|r| r.as_ref());
e.set_input(raw);
e
})
}
// `None` is interpreted as a missing field so be sure to implement `Some`
// as a present field.
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
let raw = self.raw;
ValueDeserializer::new(self.root)
.deserialize_option(visitor)
.map_err(|mut e: Self::Error| {
let raw = raw.as_ref().map(|r| r.as_ref());
e.set_input(raw);
e
})
}
fn deserialize_newtype_struct<V>(
self,
name: &'static str,
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
let raw = self.raw;
ValueDeserializer::new(self.root)
.deserialize_newtype_struct(name, visitor)
.map_err(|mut e: Self::Error| {
let raw = raw.as_ref().map(|r| r.as_ref());
e.set_input(raw);
e
})
}
fn deserialize_struct<V>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
let raw = self.raw;
ValueDeserializer::new(self.root)
.deserialize_struct(name, fields, visitor)
.map_err(|mut e: Self::Error| {
let raw = raw.as_ref().map(|r| r.as_ref());
e.set_input(raw);
e
})
}
// Called when the type to deserialize is an enum, as opposed to a field in the type.
fn deserialize_enum<V>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
let raw = self.raw;
ValueDeserializer::new(self.root)
.deserialize_enum(name, variants, visitor)
.map_err(|mut e: Self::Error| {
let raw = raw.as_ref().map(|r| r.as_ref());
e.set_input(raw);
e
})
}
serde_core::forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
bytes byte_buf map unit
ignored_any unit_struct tuple_struct tuple identifier
}
}
impl serde_core::de::IntoDeserializer<'_, Error> for Deserializer {
type Deserializer = Self;
fn into_deserializer(self) -> Self::Deserializer {
self
}
}
impl serde_core::de::IntoDeserializer<'_, Error> for crate::DocumentMut {
type Deserializer = Deserializer;
fn into_deserializer(self) -> Self::Deserializer {
Deserializer::from(self)
}
}
impl serde_core::de::IntoDeserializer<'_, Error> for crate::Document<String> {
type Deserializer = Deserializer;
fn into_deserializer(self) -> Self::Deserializer {
Deserializer::from(self)
}
}

207
vendor/toml_edit/src/de/table.rs vendored Normal file
View File

@@ -0,0 +1,207 @@
use serde_core::de::IntoDeserializer;
use crate::de::Error;
pub(crate) struct TableDeserializer {
span: Option<std::ops::Range<usize>>,
items: crate::table::KeyValuePairs,
}
impl TableDeserializer {
pub(crate) fn new(
items: crate::table::KeyValuePairs,
span: Option<std::ops::Range<usize>>,
) -> Self {
Self { span, items }
}
}
impl<'de> serde_core::Deserializer<'de> for TableDeserializer {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde_core::de::Visitor<'de>,
{
visitor.visit_map(TableMapAccess::new(self))
}
// `None` is interpreted as a missing field so be sure to implement `Some`
// as a present field.
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
visitor.visit_some(self)
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
fn deserialize_struct<V>(
self,
name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
if serde_spanned::de::is_spanned(name) {
if let Some(span) = self.span.clone() {
return visitor.visit_map(
serde_spanned::de::SpannedDeserializer::<Self, Error>::new(self, span),
);
} else {
return Err(Error::custom("value is missing a span", None));
}
}
self.deserialize_any(visitor)
}
// Called when the type to deserialize is an enum, as opposed to a field in the type.
fn deserialize_enum<V>(
self,
_name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
if self.items.is_empty() {
Err(Error::custom(
"wanted exactly 1 element, found 0 elements",
self.span,
))
} else if self.items.len() != 1 {
Err(Error::custom(
"wanted exactly 1 element, more than 1 element",
self.span,
))
} else {
visitor.visit_enum(TableMapAccess::new(self))
}
}
serde_core::forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
bytes byte_buf map unit
ignored_any unit_struct tuple_struct tuple identifier
}
}
impl IntoDeserializer<'_, Error> for TableDeserializer {
type Deserializer = Self;
fn into_deserializer(self) -> Self::Deserializer {
self
}
}
pub(crate) struct TableMapAccess {
iter: indexmap::map::IntoIter<crate::Key, crate::Item>,
span: Option<std::ops::Range<usize>>,
value: Option<(crate::Key, crate::Item)>,
}
impl TableMapAccess {
pub(crate) fn new(input: TableDeserializer) -> Self {
Self {
iter: input.items.into_iter(),
span: input.span,
value: None,
}
}
}
impl<'de> serde_core::de::MapAccess<'de> for TableMapAccess {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
where
K: serde_core::de::DeserializeSeed<'de>,
{
match self.iter.next() {
Some((k, v)) => {
let key_span = k.span();
let ret = seed
.deserialize(super::KeyDeserializer::new(k.clone(), key_span.clone()))
.map(Some)
.map_err(|mut e: Self::Error| {
if e.span().is_none() {
e.set_span(key_span);
}
e
});
self.value = Some((k, v));
ret
}
None => Ok(None),
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
where
V: serde_core::de::DeserializeSeed<'de>,
{
match self.value.take() {
Some((k, v)) => {
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.get().to_owned());
e
})
}
None => {
panic!("no more values in next_value_seed, internal error in ValueDeserializer")
}
}
}
}
impl<'de> serde_core::de::EnumAccess<'de> for TableMapAccess {
type Error = Error;
type Variant = super::TableEnumDeserializer;
fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
where
V: serde_core::de::DeserializeSeed<'de>,
{
let (key, value) = match self.iter.next() {
Some(pair) => pair,
None => {
return Err(Error::custom(
"expected table with exactly 1 entry, found empty table",
self.span,
));
}
};
let val = seed
.deserialize(key.into_deserializer())
.map_err(|mut e: Self::Error| {
if e.span().is_none() {
e.set_span(key.span());
}
e
})?;
let variant = super::TableEnumDeserializer::new(value);
Ok((val, variant))
}
}

176
vendor/toml_edit/src/de/table_enum.rs vendored Normal file
View File

@@ -0,0 +1,176 @@
use crate::de::Error;
/// Deserializes table values into enum variants.
pub(crate) struct TableEnumDeserializer {
value: crate::Item,
}
impl TableEnumDeserializer {
pub(crate) fn new(value: crate::Item) -> Self {
Self { value }
}
}
impl<'de> serde_core::de::VariantAccess<'de> for TableEnumDeserializer {
type Error = Error;
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(())
} else {
Err(Error::custom("expected empty table", values.span()))
}
}
crate::Item::Value(crate::Value::InlineTable(values)) => {
if values.is_empty() {
Ok(())
} else {
Err(Error::custom("expected empty table", values.span()))
}
}
e => Err(Error::custom(
format!("expected table, found {}", e.type_name()),
e.span(),
)),
}
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
where
T: serde_core::de::DeserializeSeed<'de>,
{
seed.deserialize(super::ValueDeserializer::new(self.value))
}
fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde_core::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_core::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_core::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: Result<Vec<_>, _> = values
.items
.into_iter()
.enumerate()
.map(|(index, (key, value))| match key.get().parse::<usize>() {
Ok(key_index) if key_index == index => Ok(value),
Ok(_) | Err(_) => Err(Error::custom(
format!("expected table key `{}`, but was `{}`", index, key.get()),
key.span(),
)),
})
.collect();
let tuple_values = tuple_values?;
if tuple_values.len() == len {
serde_core::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::InlineTable(values)) => {
let values_span = values.span();
let tuple_values: Result<Vec<_>, _> = values
.items
.into_iter()
.enumerate()
.map(|(index, (key, value))| match key.get().parse::<usize>() {
Ok(key_index) if key_index == index => Ok(value),
Ok(_) | Err(_) => Err(Error::custom(
format!("expected table key `{}`, but was `{}`", index, key.get()),
key.span(),
)),
})
.collect();
let tuple_values = tuple_values?;
if tuple_values.len() == len {
serde_core::de::Deserializer::deserialize_seq(
super::ArrayDeserializer::new(tuple_values, values_span),
visitor,
)
} else {
Err(Error::custom(
format!("expected tuple with length {len}"),
values_span,
))
}
}
e => Err(Error::custom(
format!("expected table, found {}", e.type_name()),
e.span(),
)),
}
}
fn struct_variant<V>(
self,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: serde_core::de::Visitor<'de>,
{
serde_core::de::Deserializer::deserialize_struct(
super::ValueDeserializer::new(self.value).with_struct_key_validation(),
"", // TODO: this should be the variant name
fields,
visitor,
)
}
}

293
vendor/toml_edit/src/de/value.rs vendored Normal file
View File

@@ -0,0 +1,293 @@
use serde_core::de::IntoDeserializer as _;
use crate::de::ArrayDeserializer;
use crate::de::DatetimeDeserializer;
use crate::de::Error;
use crate::de::TableDeserializer;
/// Deserialization implementation for TOML [values][crate::Value].
///
/// Can be created either directly from TOML strings, using [`std::str::FromStr`],
/// or from parsed [values][crate::Value] using
/// [`IntoDeserializer::into_deserializer`][serde_core::de::IntoDeserializer::into_deserializer].
///
/// # Example
///
/// ```
/// # #[cfg(feature = "parse")] {
/// # #[cfg(feature = "display")] {
/// use serde::Deserialize;
///
/// #[derive(Deserialize)]
/// struct Config {
/// title: String,
/// owner: Owner,
/// }
///
/// #[derive(Deserialize)]
/// struct Owner {
/// name: String,
/// }
///
/// let value = r#"{ title = 'TOML Example', owner = { name = 'Lisa' } }"#;
/// let deserializer = value.parse::<toml_edit::de::ValueDeserializer>().unwrap();
/// let config = Config::deserialize(deserializer).unwrap();
/// assert_eq!(config.title, "TOML Example");
/// assert_eq!(config.owner.name, "Lisa");
/// # }
/// # }
/// ```
pub struct ValueDeserializer {
input: crate::Item,
validate_struct_keys: bool,
}
impl ValueDeserializer {
pub(crate) fn new(input: crate::Item) -> Self {
Self {
input,
validate_struct_keys: false,
}
}
pub(crate) fn with_struct_key_validation(mut self) -> Self {
self.validate_struct_keys = true;
self
}
}
impl<'de> serde_core::Deserializer<'de> for ValueDeserializer {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: serde_core::de::Visitor<'de>,
{
let span = self.input.span();
match self.input {
crate::Item::None => visitor.visit_none(),
crate::Item::Value(crate::Value::String(v)) => visitor.visit_string(v.into_value()),
crate::Item::Value(crate::Value::Integer(v)) => visitor.visit_i64(v.into_value()),
crate::Item::Value(crate::Value::Float(v)) => visitor.visit_f64(v.into_value()),
crate::Item::Value(crate::Value::Boolean(v)) => visitor.visit_bool(v.into_value()),
crate::Item::Value(crate::Value::Datetime(v)) => {
visitor.visit_map(DatetimeDeserializer::new(v.into_value()))
}
crate::Item::Value(crate::Value::Array(v)) => {
ArrayDeserializer::new(v.values, v.span).deserialize_any(visitor)
}
crate::Item::Value(crate::Value::InlineTable(v)) => {
TableDeserializer::new(v.items, v.span).deserialize_any(visitor)
}
crate::Item::Table(v) => {
TableDeserializer::new(v.items, v.span).deserialize_any(visitor)
}
crate::Item::ArrayOfTables(v) => {
ArrayDeserializer::new(v.values, v.span).deserialize_any(visitor)
}
}
.map_err(|mut e: Self::Error| {
if e.span().is_none() {
e.set_span(span);
}
e
})
}
// `None` is interpreted as a missing field so be sure to implement `Some`
// as a present field.
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
let span = self.input.span();
visitor.visit_some(self).map_err(|mut e: Self::Error| {
if e.span().is_none() {
e.set_span(span);
}
e
})
}
fn deserialize_newtype_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
let span = self.input.span();
visitor
.visit_newtype_struct(self)
.map_err(|mut e: Self::Error| {
if e.span().is_none() {
e.set_span(span);
}
e
})
}
fn deserialize_struct<V>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
if serde_spanned::de::is_spanned(name) {
if let Some(span) = self.input.span() {
return visitor.visit_map(
serde_spanned::de::SpannedDeserializer::<Self, Error>::new(self, span),
);
} else {
return Err(Error::custom("value is missing a span", None));
}
}
if toml_datetime::de::is_datetime(name) {
let span = self.input.span();
if let crate::Item::Value(crate::Value::Datetime(d)) = self.input {
return visitor
.visit_map(DatetimeDeserializer::new(d.into_value()))
.map_err(|mut e: Self::Error| {
if e.span().is_none() {
e.set_span(span);
}
e
});
}
}
if self.validate_struct_keys {
let span = self.input.span();
match &self.input {
crate::Item::Table(values) => validate_struct_keys(&values.items, fields),
crate::Item::Value(crate::Value::InlineTable(values)) => {
validate_struct_keys(&values.items, fields)
}
_ => Ok(()),
}
.map_err(|mut e: Self::Error| {
if e.span().is_none() {
e.set_span(span);
}
e
})?;
}
self.deserialize_any(visitor)
}
// Called when the type to deserialize is an enum, as opposed to a field in the type.
fn deserialize_enum<V>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: serde_core::de::Visitor<'de>,
{
let span = self.input.span();
match self.input {
crate::Item::Value(crate::Value::String(v)) => {
visitor.visit_enum(v.into_value().into_deserializer())
}
crate::Item::Value(crate::Value::InlineTable(v)) => {
if v.is_empty() {
Err(Error::custom(
"wanted exactly 1 element, found 0 elements",
v.span(),
))
} else if v.len() != 1 {
Err(Error::custom(
"wanted exactly 1 element, more than 1 element",
v.span(),
))
} else {
TableDeserializer::new(v.items, v.span)
.deserialize_enum(name, variants, visitor)
}
}
crate::Item::Table(v) => {
TableDeserializer::new(v.items, v.span).deserialize_enum(name, variants, visitor)
}
e => Err(Error::custom("wanted string or table", e.span())),
}
.map_err(|mut e: Self::Error| {
if e.span().is_none() {
e.set_span(span);
}
e
})
}
serde_core::forward_to_deserialize_any! {
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
bytes byte_buf map unit
ignored_any unit_struct tuple_struct tuple identifier
}
}
impl serde_core::de::IntoDeserializer<'_, Error> for ValueDeserializer {
type Deserializer = Self;
fn into_deserializer(self) -> Self::Deserializer {
self
}
}
impl serde_core::de::IntoDeserializer<'_, Error> for crate::Value {
type Deserializer = ValueDeserializer;
fn into_deserializer(self) -> Self::Deserializer {
ValueDeserializer::new(crate::Item::Value(self))
}
}
#[cfg(feature = "parse")]
impl std::str::FromStr for ValueDeserializer {
type Err = Error;
/// Parses a value from a &str
fn from_str(s: &str) -> Result<Self, Self::Err> {
let value = s.parse::<crate::Value>().map_err(Error::from)?;
Ok(value.into_deserializer())
}
}
pub(crate) fn validate_struct_keys(
table: &crate::table::KeyValuePairs,
fields: &'static [&'static str],
) -> Result<(), Error> {
let extra_fields = table
.keys()
.filter_map(|key| {
if !fields.contains(&key.get()) {
Some(key.clone())
} else {
None
}
})
.collect::<Vec<_>>();
if extra_fields.is_empty() {
Ok(())
} else {
Err(Error::custom(
format!(
"unexpected keys in table: {}, available keys: {}",
extra_fields
.iter()
.map(|k| k.get())
.collect::<Vec<_>>()
.join(", "),
fields.join(", "),
),
extra_fields[0].span(),
))
}
}

246
vendor/toml_edit/src/document.rs vendored Normal file
View File

@@ -0,0 +1,246 @@
use std::str::FromStr;
use crate::table::Iter;
use crate::{Item, RawString, Table};
/// The root TOML [`Table`], containing [`Key`][crate::Key]/[`Value`][crate::Value] pairs and all other logic [`Table`]s
#[derive(Debug, Clone)]
pub struct Document<S> {
pub(crate) root: Item,
// Trailing comments and whitespaces
pub(crate) trailing: RawString,
pub(crate) raw: S,
}
impl Document<&'static str> {
/// Creates an empty document
pub fn new() -> Self {
Default::default()
}
}
#[cfg(feature = "parse")]
impl<S: AsRef<str>> Document<S> {
/// Parse a TOML document
pub fn parse(raw: S) -> Result<Self, crate::TomlError> {
let source = toml_parser::Source::new(raw.as_ref());
let mut sink = crate::error::TomlSink::<Option<_>>::new(source);
let doc = crate::parser::parse_document(source, &mut sink);
if let Some(err) = sink.into_inner() {
Err(err)
} else {
Ok(Self {
root: doc.root,
trailing: doc.trailing,
raw,
})
}
}
}
impl<S: AsRef<str>> Document<S> {
/// # Panics
///
/// If run on a [`DocumentMut`] not generated by the parser
pub(crate) fn despan(&mut self) {
self.root.despan(self.raw.as_ref());
self.trailing.despan(self.raw.as_ref());
}
}
impl<S> Document<S> {
/// Returns a reference to the root item.
pub fn as_item(&self) -> &Item {
&self.root
}
/// Returns the root item.
pub fn into_item(self) -> Item {
self.root
}
/// Returns a reference to the root table.
pub fn as_table(&self) -> &Table {
self.root.as_table().expect("root should always be a table")
}
/// Returns the root table.
pub fn into_table(self) -> Table {
self.root
.into_table()
.expect("root should always be a table")
}
/// Returns an iterator over the root table.
pub fn iter(&self) -> Iter<'_> {
self.as_table().iter()
}
/// Whitespace after last element
pub fn trailing(&self) -> &RawString {
&self.trailing
}
}
impl<S: AsRef<str>> Document<S> {
/// Access the raw, unparsed document
pub fn raw(&self) -> &str {
self.raw.as_ref()
}
}
impl<S: AsRef<str>> Document<S> {
/// Allow editing of the [`DocumentMut`]
pub fn into_mut(mut self) -> DocumentMut {
self.despan();
DocumentMut {
root: self.root,
trailing: self.trailing,
}
}
}
impl Default for Document<&'static str> {
fn default() -> Self {
Self {
root: Item::Table(Table::with_pos(Some(0))),
trailing: Default::default(),
raw: "",
}
}
}
#[cfg(feature = "parse")]
impl FromStr for Document<String> {
type Err = crate::TomlError;
/// Parses a document from a &str
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::parse(s.to_owned())
}
}
impl<S> std::ops::Deref for Document<S> {
type Target = Table;
fn deref(&self) -> &Self::Target {
self.as_table()
}
}
/// The editable root TOML [`Table`], containing [`Key`][crate::Key]/[`Value`][crate::Value] pairs and all other logic [`Table`]s
#[derive(Debug, Clone)]
pub struct DocumentMut {
pub(crate) root: Item,
// Trailing comments and whitespaces
pub(crate) trailing: RawString,
}
impl DocumentMut {
/// Creates an empty document
pub fn new() -> Self {
Default::default()
}
/// Returns a reference to the root item.
pub fn as_item(&self) -> &Item {
&self.root
}
/// Returns a mutable reference to the root item.
pub fn as_item_mut(&mut self) -> &mut Item {
&mut self.root
}
/// Returns the root item.
pub fn into_item(self) -> Item {
self.root
}
/// Returns a reference to the root table.
pub fn as_table(&self) -> &Table {
self.root.as_table().expect("root should always be a table")
}
/// Returns a mutable reference to the root table.
pub fn as_table_mut(&mut self) -> &mut Table {
self.root
.as_table_mut()
.expect("root should always be a table")
}
/// Returns the root table.
pub fn into_table(self) -> Table {
self.root
.into_table()
.expect("root should always be a table")
}
/// Returns an iterator over the root table.
pub fn iter(&self) -> Iter<'_> {
self.as_table().iter()
}
/// Set whitespace after last element
pub fn set_trailing(&mut self, trailing: impl Into<RawString>) {
self.trailing = trailing.into();
}
/// Whitespace after last element
pub fn trailing(&self) -> &RawString {
&self.trailing
}
}
impl Default for DocumentMut {
fn default() -> Self {
Self {
root: Item::Table(Table::with_pos(Some(0))),
trailing: Default::default(),
}
}
}
#[cfg(feature = "parse")]
impl FromStr for DocumentMut {
type Err = crate::TomlError;
/// Parses a document from a &str
fn from_str(s: &str) -> Result<Self, Self::Err> {
let im = Document::from_str(s)?;
Ok(im.into_mut())
}
}
impl std::ops::Deref for DocumentMut {
type Target = Table;
fn deref(&self) -> &Self::Target {
self.as_table()
}
}
impl std::ops::DerefMut for DocumentMut {
fn deref_mut(&mut self) -> &mut Self::Target {
self.as_table_mut()
}
}
impl From<Table> for DocumentMut {
fn from(root: Table) -> Self {
Self {
root: Item::Table(root),
..Default::default()
}
}
}
#[test]
#[cfg(feature = "parse")]
#[cfg(feature = "display")]
fn default_roundtrip() {
DocumentMut::default()
.to_string()
.parse::<DocumentMut>()
.unwrap();
}

410
vendor/toml_edit/src/encode.rs vendored Normal file
View File

@@ -0,0 +1,410 @@
use std::borrow::Cow;
use std::fmt::{Display, Formatter, Result, Write};
use toml_datetime::Datetime;
use toml_writer::ToTomlValue as _;
use toml_writer::TomlWrite as _;
use crate::inline_table::DEFAULT_INLINE_KEY_DECOR;
use crate::key::Key;
use crate::repr::{Formatted, Repr, ValueRepr};
use crate::table::{
DEFAULT_KEY_DECOR, DEFAULT_KEY_PATH_DECOR, DEFAULT_ROOT_DECOR, DEFAULT_TABLE_DECOR,
};
use crate::value::{
DEFAULT_LEADING_VALUE_DECOR, DEFAULT_TRAILING_VALUE_DECOR, DEFAULT_VALUE_DECOR,
};
use crate::DocumentMut;
use crate::{Array, InlineTable, Item, Table, Value};
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(())
}
fn encode_key_path(
this: &[Key],
mut 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 {
buf.key_sep()?;
dotted_decor.prefix_encode(buf, input, DEFAULT_KEY_PATH_DECOR.0)?;
}
encode_key(key, buf, input)?;
if last {
leaf_decor.suffix_encode(buf, input, default_decor.1)?;
} else {
dotted_decor.suffix_encode(buf, input, DEFAULT_KEY_PATH_DECOR.1)?;
}
}
Ok(())
}
pub(crate) fn encode_key_path_ref(
this: &[&Key],
mut 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 {
buf.key_sep()?;
dotted_decor.prefix_encode(buf, input, DEFAULT_KEY_PATH_DECOR.0)?;
}
encode_key(key, buf, input)?;
if last {
leaf_decor.suffix_encode(buf, input, default_decor.1)?;
} else {
dotted_decor.suffix_encode(buf, input, DEFAULT_KEY_PATH_DECOR.1)?;
}
}
Ok(())
}
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(())
}
pub(crate) fn encode_array(
this: &Array,
mut buf: &mut dyn Write,
input: Option<&str>,
default_decor: (&str, &str),
) -> Result {
let decor = this.decor();
decor.prefix_encode(buf, input, default_decor.0)?;
buf.open_array()?;
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;
buf.val_sep()?;
}
encode_value(elem, buf, input, inner_decor)?;
}
if this.trailing_comma() && !this.is_empty() {
buf.val_sep()?;
}
this.trailing().encode_with_default(buf, input, "")?;
buf.close_array()?;
decor.suffix_encode(buf, input, default_decor.1)?;
Ok(())
}
pub(crate) fn encode_table(
this: &InlineTable,
mut buf: &mut dyn Write,
input: Option<&str>,
default_decor: (&str, &str),
) -> Result {
let decor = this.decor();
decor.prefix_encode(buf, input, default_decor.0)?;
buf.open_inline_table()?;
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 {
buf.val_sep()?;
}
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)?;
buf.keyval_sep()?;
encode_value(value, buf, input, inner_decor)?;
}
buf.close_inline_table()?;
decor.suffix_encode(buf, input, default_decor.1)?;
Ok(())
}
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),
}
}
impl Display for DocumentMut {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
let decor = self.decor();
decor.prefix_encode(f, None, DEFAULT_ROOT_DECOR.0)?;
let mut path = Vec::new();
let mut last_position = 0;
let mut tables = Vec::new();
visit_nested_tables(self.as_table(), &mut path, false, &mut |t, p, is_array| {
if let Some(pos) = t.position() {
last_position = pos;
}
tables.push((last_position, t, p.clone(), is_array));
Ok(())
})
.unwrap();
tables.sort_by_key(|&(id, _, _, _)| id);
let mut first_table = true;
for (_, table, path, is_array) in tables {
visit_table(f, None, table, &path, is_array, &mut first_table)?;
}
decor.suffix_encode(f, None, DEFAULT_ROOT_DECOR.1)?;
self.trailing().encode_with_default(f, None, "")
}
}
fn visit_nested_tables<'t, F>(
table: &'t Table,
path: &mut Vec<Key>,
is_array_of_tables: bool,
callback: &mut F,
) -> Result
where
F: FnMut(&'t Table, &Vec<Key>, bool) -> Result,
{
if !table.is_dotted() {
callback(table, path, is_array_of_tables)?;
}
for (key, value) in table.items.iter() {
match value {
Item::Table(ref t) => {
let key = key.clone();
path.push(key);
visit_nested_tables(t, path, false, callback)?;
path.pop();
}
Item::ArrayOfTables(ref a) => {
for t in a.iter() {
let key = key.clone();
path.push(key);
visit_nested_tables(t, path, true, callback)?;
path.pop();
}
}
_ => {}
}
}
Ok(())
}
fn visit_table(
mut buf: &mut dyn Write,
input: Option<&str>,
table: &Table,
path: &[Key],
is_array_of_tables: bool,
first_table: &mut bool,
) -> Result {
let children = table.get_values();
// We are intentionally hiding implicit tables without any tables nested under them (ie
// `table.is_empty()` which is in contrast to `table.get_values().is_empty()`). We are
// trusting the user that an empty implicit table is not semantically meaningful
//
// This allows a user to delete all tables under this implicit table and the implicit table
// will disappear.
//
// However, this means that users need to take care in deciding what tables get marked as
// implicit.
let is_visible_std_table = !(table.implicit && children.is_empty());
if path.is_empty() {
// don't print header for the root node
if !children.is_empty() {
*first_table = false;
}
} else if is_array_of_tables {
let default_decor = if *first_table {
*first_table = false;
("", DEFAULT_TABLE_DECOR.1)
} else {
DEFAULT_TABLE_DECOR
};
table.decor.prefix_encode(buf, input, default_decor.0)?;
buf.open_array_of_tables_header()?;
encode_key_path(path, buf, input, DEFAULT_KEY_PATH_DECOR)?;
buf.close_array_of_tables_header()?;
table.decor.suffix_encode(buf, input, default_decor.1)?;
writeln!(buf)?;
} else if is_visible_std_table {
let default_decor = if *first_table {
*first_table = false;
("", DEFAULT_TABLE_DECOR.1)
} else {
DEFAULT_TABLE_DECOR
};
table.decor.prefix_encode(buf, input, default_decor.0)?;
buf.open_table_header()?;
encode_key_path(path, buf, input, DEFAULT_KEY_PATH_DECOR)?;
buf.close_table_header()?;
table.decor.suffix_encode(buf, input, default_decor.1)?;
writeln!(buf)?;
}
// print table body
for (key_path, value) in children {
encode_key_path_ref(&key_path, buf, input, DEFAULT_KEY_DECOR)?;
buf.keyval_sep()?;
encode_value(value, buf, input, DEFAULT_VALUE_DECOR)?;
writeln!(buf)?;
}
Ok(())
}
impl ValueRepr for String {
fn to_repr(&self) -> Repr {
let output = toml_writer::TomlStringBuilder::new(self.as_str())
.as_default()
.to_toml_value();
Repr::new_unchecked(output)
}
}
impl ValueRepr for i64 {
fn to_repr(&self) -> Repr {
let repr = self.to_toml_value();
Repr::new_unchecked(repr)
}
}
impl ValueRepr for f64 {
fn to_repr(&self) -> Repr {
let repr = self.to_toml_value();
Repr::new_unchecked(repr)
}
}
impl ValueRepr for bool {
fn to_repr(&self) -> Repr {
let repr = self.to_toml_value();
Repr::new_unchecked(repr)
}
}
impl ValueRepr for Datetime {
fn to_repr(&self) -> Repr {
Repr::new_unchecked(self.to_string())
}
}
#[cfg(test)]
mod test {
use super::*;
use proptest::prelude::*;
proptest! {
#[test]
#[cfg(feature = "parse")]
fn parseable_string(string in "\\PC*") {
let value = Value::from(string.clone());
let encoded = value.to_string();
let _: Value = encoded.parse().unwrap_or_else(|err| {
panic!("error: {err}
string:
```
{string}
```
value:
```
{value}
```
")
});
}
}
proptest! {
#[test]
#[cfg(feature = "parse")]
fn parseable_key(string in "\\PC*") {
let key = Key::new(string.clone());
let encoded = key.to_string();
let _: Key = encoded.parse().unwrap_or_else(|err| {
panic!("error: {err}
string:
```
{string}
```
key:
```
{key}
```
")
});
}
}
}

299
vendor/toml_edit/src/error.rs vendored Normal file
View File

@@ -0,0 +1,299 @@
/// A TOML parse error
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
pub struct TomlError {
message: String,
input: Option<std::sync::Arc<str>>,
keys: Vec<String>,
span: Option<std::ops::Range<usize>>,
}
impl TomlError {
#[cfg(feature = "parse")]
pub(crate) fn new(input: std::sync::Arc<str>, error: toml_parser::ParseError) -> Self {
let mut message = String::new();
message.push_str(error.description());
if let Some(expected) = error.expected() {
message.push_str(", expected ");
if expected.is_empty() {
message.push_str("nothing");
} else {
for (i, expected) in expected.iter().enumerate() {
if i != 0 {
message.push_str(", ");
}
match expected {
toml_parser::Expected::Literal(desc) => {
message.push_str(&render_literal(desc));
}
toml_parser::Expected::Description(desc) => message.push_str(desc),
_ => message.push_str("etc"),
}
}
}
}
let span = error.unexpected().map(|span| span.start()..span.end());
Self {
message,
input: Some(input),
keys: Vec::new(),
span,
}
}
#[cfg(feature = "serde")]
pub(crate) fn custom(message: String, span: Option<std::ops::Range<usize>>) -> Self {
Self {
message,
input: None,
keys: Vec::new(),
span,
}
}
#[cfg(feature = "serde")]
pub(crate) fn add_key(&mut self, key: String) {
self.keys.insert(0, key);
}
/// What went wrong
pub fn message(&self) -> &str {
&self.message
}
/// The start/end index into the original document where the error occurred
pub fn span(&self) -> Option<std::ops::Range<usize>> {
self.span.clone()
}
#[cfg(feature = "serde")]
pub(crate) fn set_span(&mut self, span: Option<std::ops::Range<usize>>) {
self.span = span;
}
#[cfg(feature = "serde")]
pub(crate) fn set_input(&mut self, input: Option<&str>) {
self.input = input.map(|s| s.into());
}
}
fn render_literal(literal: &str) -> String {
match literal {
"\n" => "newline".to_owned(),
"`" => "'`'".to_owned(),
s if s.chars().all(|c| c.is_ascii_control()) => {
format!("`{}`", s.escape_debug())
}
s => format!("`{s}`"),
}
}
/// Displays a TOML parse error
///
/// # Example
///
/// TOML parse error at line 1, column 10
/// |
/// 1 | 00:32:00.a999999
/// | ^
/// Unexpected `a`
/// Expected `digit`
/// While parsing a Time
/// While parsing a Date-Time
impl std::fmt::Display for TomlError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut context = false;
if let (Some(input), Some(span)) = (&self.input, self.span()) {
context = true;
let (line, column) = translate_position(input.as_bytes(), span.start);
let line_num = line + 1;
let col_num = column + 1;
let gutter = line_num.to_string().len();
let content = input.split('\n').nth(line).expect("valid line number");
let highlight_len = span.end - span.start;
// Allow highlight to go one past the line
let highlight_len = highlight_len.min(content.len().saturating_sub(column));
writeln!(f, "TOML parse error at line {line_num}, column {col_num}")?;
// |
for _ in 0..=gutter {
write!(f, " ")?;
}
writeln!(f, "|")?;
// 1 | 00:32:00.a999999
write!(f, "{line_num} | ")?;
writeln!(f, "{content}")?;
// | ^
for _ in 0..=gutter {
write!(f, " ")?;
}
write!(f, "|")?;
for _ in 0..=column {
write!(f, " ")?;
}
// The span will be empty at eof, so we need to make sure we always print at least
// one `^`
write!(f, "^")?;
for _ in 1..highlight_len {
write!(f, "^")?;
}
writeln!(f)?;
}
writeln!(f, "{}", self.message)?;
if !context && !self.keys.is_empty() {
writeln!(f, "in `{}`", self.keys.join("."))?;
}
Ok(())
}
}
impl std::error::Error for TomlError {}
fn translate_position(input: &[u8], index: usize) -> (usize, usize) {
if input.is_empty() {
return (0, index);
}
let safe_index = index.min(input.len() - 1);
let column_offset = index - safe_index;
let index = safe_index;
let nl = input[0..index]
.iter()
.rev()
.enumerate()
.find(|(_, b)| **b == b'\n')
.map(|(nl, _)| index - nl - 1);
let line_start = match nl {
Some(nl) => nl + 1,
None => 0,
};
let line = input[0..line_start].iter().filter(|b| **b == b'\n').count();
let column = std::str::from_utf8(&input[line_start..=index])
.map(|s| s.chars().count() - 1)
.unwrap_or_else(|_| index - line_start);
let column = column + column_offset;
(line, column)
}
#[cfg(feature = "parse")]
pub(crate) struct TomlSink<'i, S> {
source: toml_parser::Source<'i>,
input: Option<std::sync::Arc<str>>,
sink: S,
}
#[cfg(feature = "parse")]
impl<'i, S: Default> TomlSink<'i, S> {
pub(crate) fn new(source: toml_parser::Source<'i>) -> Self {
Self {
source,
input: None,
sink: Default::default(),
}
}
pub(crate) fn into_inner(self) -> S {
self.sink
}
}
#[cfg(feature = "parse")]
impl<'i> toml_parser::ErrorSink for TomlSink<'i, Option<TomlError>> {
fn report_error(&mut self, error: toml_parser::ParseError) {
if self.sink.is_none() {
let input = self
.input
.get_or_insert_with(|| std::sync::Arc::from(self.source.input()));
let error = TomlError::new(input.clone(), error);
self.sink = Some(error);
}
}
}
#[cfg(feature = "parse")]
impl<'i> toml_parser::ErrorSink for TomlSink<'i, Vec<TomlError>> {
fn report_error(&mut self, error: toml_parser::ParseError) {
let input = self
.input
.get_or_insert_with(|| std::sync::Arc::from(self.source.input()));
let error = TomlError::new(input.clone(), error);
self.sink.push(error);
}
}
#[cfg(test)]
mod test_translate_position {
use super::*;
#[test]
fn empty() {
let input = b"";
let index = 0;
let position = translate_position(&input[..], index);
assert_eq!(position, (0, 0));
}
#[test]
fn start() {
let input = b"Hello";
let index = 0;
let position = translate_position(&input[..], index);
assert_eq!(position, (0, 0));
}
#[test]
fn end() {
let input = b"Hello";
let index = input.len() - 1;
let position = translate_position(&input[..], index);
assert_eq!(position, (0, input.len() - 1));
}
#[test]
fn after() {
let input = b"Hello";
let index = input.len();
let position = translate_position(&input[..], index);
assert_eq!(position, (0, input.len()));
}
#[test]
fn first_line() {
let input = b"Hello\nWorld\n";
let index = 2;
let position = translate_position(&input[..], index);
assert_eq!(position, (0, 2));
}
#[test]
fn end_of_line() {
let input = b"Hello\nWorld\n";
let index = 5;
let position = translate_position(&input[..], index);
assert_eq!(position, (0, 5));
}
#[test]
fn start_of_second_line() {
let input = b"Hello\nWorld\n";
let index = 6;
let position = translate_position(&input[..], index);
assert_eq!(position, (1, 0));
}
#[test]
fn second_line() {
let input = b"Hello\nWorld\n";
let index = 8;
let position = translate_position(&input[..], index);
assert_eq!(position, (1, 2));
}
}

142
vendor/toml_edit/src/index.rs vendored Normal file
View File

@@ -0,0 +1,142 @@
use std::ops;
use crate::key::Key;
use crate::DocumentMut;
use crate::{value, InlineTable, Item, Table, Value};
// copied from
// https://github.com/serde-rs/json/blob/master/src/value/index.rs
pub trait Index: crate::private::Sealed {
#[doc(hidden)]
fn index<'v>(&self, val: &'v Item) -> Option<&'v Item>;
#[doc(hidden)]
fn index_mut<'v>(&self, val: &'v mut Item) -> Option<&'v mut Item>;
}
impl Index for usize {
fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> {
match *v {
Item::ArrayOfTables(ref aot) => aot.values.get(*self),
Item::Value(ref a) if a.is_array() => a.as_array().and_then(|a| a.values.get(*self)),
_ => None,
}
}
fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> {
match *v {
Item::ArrayOfTables(ref mut vec) => vec.values.get_mut(*self),
Item::Value(ref mut a) => a.as_array_mut().and_then(|a| a.values.get_mut(*self)),
_ => None,
}
}
}
impl Index for str {
fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> {
match *v {
Item::Table(ref t) => t.get(self),
Item::Value(ref v) => v
.as_inline_table()
.and_then(|t| t.items.get(self))
.and_then(|value| if !value.is_none() { Some(value) } else { None }),
_ => None,
}
}
fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> {
if let Item::None = *v {
let mut t = InlineTable::default();
t.items.insert(Key::new(self), Item::None);
*v = value(Value::InlineTable(t));
}
match *v {
Item::Table(ref mut t) => Some(t.entry(self).or_insert(Item::None)),
Item::Value(ref mut v) => v
.as_inline_table_mut()
.map(|t| t.items.entry(Key::new(self)).or_insert_with(|| Item::None)),
_ => None,
}
}
}
impl Index for String {
fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> {
self[..].index(v)
}
fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> {
self[..].index_mut(v)
}
}
impl<T: ?Sized> Index for &T
where
T: Index,
{
fn index<'v>(&self, v: &'v Item) -> Option<&'v Item> {
(**self).index(v)
}
fn index_mut<'v>(&self, v: &'v mut Item) -> Option<&'v mut Item> {
(**self).index_mut(v)
}
}
impl<I> ops::Index<I> for Item
where
I: Index,
{
type Output = Self;
fn index(&self, index: I) -> &Self {
index.index(self).expect("index not found")
}
}
impl<I> ops::IndexMut<I> for Item
where
I: Index,
{
fn index_mut(&mut self, index: I) -> &mut Self {
index.index_mut(self).expect("index not found")
}
}
impl<'s> ops::Index<&'s str> for Table {
type Output = Item;
fn index(&self, key: &'s str) -> &Item {
self.get(key).expect("index not found")
}
}
impl<'s> ops::IndexMut<&'s str> for Table {
fn index_mut(&mut self, key: &'s str) -> &mut Item {
self.entry(key).or_insert(Item::None)
}
}
impl<'s> ops::Index<&'s str> for InlineTable {
type Output = Value;
fn index(&self, key: &'s str) -> &Value {
self.get(key).expect("index not found")
}
}
impl<'s> ops::IndexMut<&'s str> for InlineTable {
fn index_mut(&mut self, key: &'s str) -> &mut Value {
self.get_mut(key).expect("index not found")
}
}
impl<'s> ops::Index<&'s str> for DocumentMut {
type Output = Item;
fn index(&self, key: &'s str) -> &Item {
self.root.index(key)
}
}
impl<'s> ops::IndexMut<&'s str> for DocumentMut {
fn index_mut(&mut self, key: &'s str) -> &mut Item {
self.root.index_mut(key)
}
}

734
vendor/toml_edit/src/inline_table.rs vendored Normal file
View File

@@ -0,0 +1,734 @@
use std::iter::FromIterator;
use crate::key::Key;
use crate::repr::Decor;
use crate::table::{Iter, IterMut, KeyValuePairs, TableLike};
use crate::{Item, KeyMut, RawString, Table, Value};
/// A TOML [`Value`] that contains a collection of [`Key`]/[`Value`] pairs
#[derive(Debug, Default, Clone)]
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>>,
// whether this is a proxy for dotted keys
dotted: bool,
pub(crate) items: KeyValuePairs,
}
/// Constructors
///
/// See also `FromIterator`
impl InlineTable {
/// Creates an empty table.
pub fn new() -> Self {
Default::default()
}
pub(crate) fn with_pairs(items: KeyValuePairs) -> Self {
Self {
items,
..Default::default()
}
}
/// Convert to a table
pub fn into_table(self) -> Table {
let mut t = Table::with_pairs(self.items);
t.fmt();
t
}
}
/// Formatting
impl InlineTable {
/// Get key/values for values that are visually children of this table
///
/// For example, this will return dotted keys
pub fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
let mut values = Vec::new();
let root = Vec::new();
self.append_values(&root, &mut values);
values
}
pub(crate) fn append_values<'s>(
&'s self,
parent: &[&'s Key],
values: &mut Vec<(Vec<&'s Key>, &'s Value)>,
) {
for (key, value) in self.items.iter() {
let mut path = parent.to_vec();
path.push(key);
match value {
Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
table.append_values(&path, values);
}
Item::Value(value) => {
values.push((path, value));
}
Item::Table(table) => {
table.append_all_values(&path, values);
}
_ => {}
}
}
}
/// Auto formats the table.
pub fn fmt(&mut self) {
decorate_inline_table(self);
}
/// Sorts [Key]/[Value]-pairs of the table
///
/// <div class="warning">
///
/// This is not recursive.
///
/// </div>
pub fn sort_values(&mut self) {
// Assuming standard tables have their position set and this won't negatively impact them
self.items.sort_keys();
for value in self.items.values_mut() {
match value {
Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
table.sort_values();
}
_ => {}
}
}
}
/// Sort [Key]/[Value]-pairs of the table using the using the comparison function `compare`
///
/// The comparison function receives two key and value pairs to compare (you can sort by keys or
/// values or their combination as needed).
///
/// <div class="warning">
///
/// This is not recursive.
///
/// </div>
pub fn sort_values_by<F>(&mut self, mut compare: F)
where
F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering,
{
self.sort_values_by_internal(&mut compare);
}
fn sort_values_by_internal<F>(&mut self, compare: &mut F)
where
F: FnMut(&Key, &Value, &Key, &Value) -> std::cmp::Ordering,
{
let modified_cmp =
|key1: &Key, val1: &Item, key2: &Key, val2: &Item| -> std::cmp::Ordering {
match (val1.as_value(), val2.as_value()) {
(Some(v1), Some(v2)) => compare(key1, v1, key2, v2),
(Some(_), None) => std::cmp::Ordering::Greater,
(None, Some(_)) => std::cmp::Ordering::Less,
(None, None) => std::cmp::Ordering::Equal,
}
};
self.items.sort_by(modified_cmp);
for value in self.items.values_mut() {
match value {
Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
table.sort_values_by_internal(compare);
}
_ => {}
}
}
}
/// 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::DocumentMut;
/// let mut doc = "[a]\n[a.b]\n".parse::<DocumentMut>().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;
}
/// Check if this is a wrapper for dotted keys, rather than a standard table
pub fn is_dotted(&self) -> bool {
self.dotted
}
/// Returns the surrounding whitespace
pub fn decor_mut(&mut self) -> &mut Decor {
&mut self.decor
}
/// Returns the surrounding whitespace
pub fn decor(&self) -> &Decor {
&self.decor
}
/// Returns an accessor to a key's formatting
pub fn key(&self, key: &str) -> Option<&'_ Key> {
self.items.get_full(key).map(|(_, key, _)| key)
}
/// Returns an accessor to a key's formatting
pub fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
use indexmap::map::MutableKeys;
self.items
.get_full_mut2(key)
.map(|(_, key, _)| key.as_mut())
}
/// Set whitespace after before element
pub fn set_preamble(&mut self, preamble: impl Into<RawString>) {
self.preamble = preamble.into();
}
/// Whitespace after before element
pub fn preamble(&self) -> &RawString {
&self.preamble
}
/// The location within the original document
///
/// This generally requires a [`Document`][crate::Document].
pub fn span(&self) -> Option<std::ops::Range<usize>> {
self.span.clone()
}
pub(crate) fn despan(&mut self, input: &str) {
use indexmap::map::MutableKeys;
self.span = None;
self.decor.despan(input);
self.preamble.despan(input);
for (key, value) in self.items.iter_mut2() {
key.despan(input);
value.despan(input);
}
}
}
impl InlineTable {
/// Returns an iterator over key/value pairs.
pub fn iter(&self) -> InlineTableIter<'_> {
Box::new(
self.items
.iter()
.filter(|(_, value)| !value.is_none())
.map(|(key, value)| (key.get(), value.as_value().unwrap())),
)
}
/// Returns an iterator over key/value pairs.
pub fn iter_mut(&mut self) -> InlineTableIterMut<'_> {
use indexmap::map::MutableKeys;
Box::new(
self.items
.iter_mut2()
.filter(|(_, value)| value.is_value())
.map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap())),
)
}
/// Returns the number of key/value pairs.
pub fn len(&self) -> usize {
self.iter().count()
}
/// Returns true if the table is empty.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
pub fn clear(&mut self) {
self.items.clear();
}
/// Gets the given key's corresponding entry in the Table for in-place manipulation.
pub fn entry(&'_ mut self, key: impl Into<String>) -> InlineEntry<'_> {
match self.items.entry(key.into().into()) {
indexmap::map::Entry::Occupied(mut entry) => {
// Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code.
let scratch = std::mem::take(entry.get_mut());
let scratch = Item::Value(
scratch
.into_value()
// HACK: `Item::None` is a corner case of a corner case, let's just pick a
// "safe" value
.unwrap_or_else(|_| Value::InlineTable(Default::default())),
);
*entry.get_mut() = scratch;
InlineEntry::Occupied(InlineOccupiedEntry { entry })
}
indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { entry }),
}
}
/// Gets the given key's corresponding entry in the Table for in-place manipulation.
pub fn entry_format<'a>(&'a mut self, key: &Key) -> InlineEntry<'a> {
// Accept a `&Key` to be consistent with `entry`
match self.items.entry(key.clone()) {
indexmap::map::Entry::Occupied(mut entry) => {
// Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code.
let scratch = std::mem::take(entry.get_mut());
let scratch = Item::Value(
scratch
.into_value()
// HACK: `Item::None` is a corner case of a corner case, let's just pick a
// "safe" value
.unwrap_or_else(|_| Value::InlineTable(Default::default())),
);
*entry.get_mut() = scratch;
InlineEntry::Occupied(InlineOccupiedEntry { entry })
}
indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry { entry }),
}
}
/// Return an optional reference to the value at the given the key.
pub fn get(&self, key: &str) -> Option<&Value> {
self.items.get(key).and_then(|value| value.as_value())
}
/// Return an optional mutable reference to the value at the given the key.
pub fn get_mut(&mut self, key: &str) -> Option<&mut Value> {
self.items
.get_mut(key)
.and_then(|value| value.as_value_mut())
}
/// Return references to the key-value pair stored for key, if it is present, else None.
pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
self.items.get_full(key).and_then(|(_, key, value)| {
if !value.is_none() {
Some((key, value))
} else {
None
}
})
}
/// Return mutable references to the key-value pair stored for key, if it is present, else None.
pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
use indexmap::map::MutableKeys;
self.items.get_full_mut2(key).and_then(|(_, key, value)| {
if !value.is_none() {
Some((key.as_mut(), value))
} else {
None
}
})
}
/// Returns true if the table contains given key.
pub fn contains_key(&self, key: &str) -> bool {
if let Some(value) = self.items.get(key) {
value.is_value()
} else {
false
}
}
/// Inserts a key/value pair if the table does not contain the key.
/// Returns a mutable reference to the corresponding value.
pub fn get_or_insert<V: Into<Value>>(
&mut self,
key: impl Into<String>,
value: V,
) -> &mut Value {
let key = key.into();
self.items
.entry(Key::new(key))
.or_insert(Item::Value(value.into()))
.as_value_mut()
.expect("non-value type in inline table")
}
/// Inserts a key-value pair into the map.
pub fn insert(&mut self, key: impl Into<String>, value: Value) -> Option<Value> {
use indexmap::map::MutableEntryKey;
let key = Key::new(key);
let value = Item::Value(value);
match self.items.entry(key.clone()) {
indexmap::map::Entry::Occupied(mut entry) => {
entry.key_mut().fmt();
let old = std::mem::replace(entry.get_mut(), value);
old.into_value().ok()
}
indexmap::map::Entry::Vacant(entry) => {
entry.insert(value);
None
}
}
}
/// Inserts a key-value pair into the map.
pub fn insert_formatted(&mut self, key: &Key, value: Value) -> Option<Value> {
use indexmap::map::MutableEntryKey;
let value = Item::Value(value);
match self.items.entry(key.clone()) {
indexmap::map::Entry::Occupied(mut entry) => {
*entry.key_mut() = key.clone();
let old = std::mem::replace(entry.get_mut(), value);
old.into_value().ok()
}
indexmap::map::Entry::Vacant(entry) => {
entry.insert(value);
None
}
}
}
/// Removes an item given the key.
pub fn remove(&mut self, key: &str) -> Option<Value> {
self.items
.shift_remove(key)
.and_then(|value| value.into_value().ok())
}
/// Removes a key from the map, returning the stored key and value if the key was previously in the map.
pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Value)> {
self.items
.shift_remove_entry(key)
.and_then(|(key, value)| Some((key, value.into_value().ok()?)))
}
/// Retains only the elements specified by the `keep` predicate.
///
/// In other words, remove all pairs `(key, value)` for which
/// `keep(&key, &mut value)` returns `false`.
///
/// The elements are visited in iteration order.
pub fn retain<F>(&mut self, mut keep: F)
where
F: FnMut(&str, &mut Value) -> bool,
{
self.items.retain(|key, item| {
item.as_value_mut()
.map(|value| keep(key, value))
.unwrap_or(false)
});
}
}
#[cfg(feature = "display")]
impl std::fmt::Display for InlineTable {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
crate::encode::encode_table(self, f, None, ("", ""))
}
}
impl<K: Into<Key>, V: Into<Value>> Extend<(K, V)> for InlineTable {
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
for (key, value) in iter {
let key = key.into();
let value = Item::Value(value.into());
self.items.insert(key, value);
}
}
}
impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for InlineTable {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
{
let mut table = Self::new();
table.extend(iter);
table
}
}
impl IntoIterator for InlineTable {
type Item = (String, Value);
type IntoIter = InlineTableIntoIter;
fn into_iter(self) -> Self::IntoIter {
Box::new(
self.items
.into_iter()
.filter(|(_, value)| value.is_value())
.map(|(key, value)| (key.into(), value.into_value().unwrap())),
)
}
}
impl<'s> IntoIterator for &'s InlineTable {
type Item = (&'s str, &'s Value);
type IntoIter = InlineTableIter<'s>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
fn decorate_inline_table(table: &mut InlineTable) {
use indexmap::map::MutableKeys;
for (mut key, value) in table
.items
.iter_mut2()
.filter(|(_, value)| value.is_value())
.map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap()))
{
key.leaf_decor_mut().clear();
key.dotted_decor_mut().clear();
value.decor_mut().clear();
}
}
/// An owned iterator type over an [`InlineTable`]'s [`Key`]/[`Value`] pairs
pub type InlineTableIntoIter = Box<dyn Iterator<Item = (String, Value)>>;
/// An iterator type over [`InlineTable`]'s [`Key`]/[`Value`] pairs
pub type InlineTableIter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Value)> + 'a>;
/// A mutable iterator type over [`InlineTable`]'s [`Key`]/[`Value`] pairs
pub type InlineTableIterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Value)> + 'a>;
impl TableLike for InlineTable {
fn iter(&self) -> Iter<'_> {
Box::new(self.items.iter().map(|(key, value)| (key.get(), value)))
}
fn iter_mut(&mut self) -> IterMut<'_> {
use indexmap::map::MutableKeys;
Box::new(
self.items
.iter_mut2()
.map(|(key, value)| (key.as_mut(), value)),
)
}
fn clear(&mut self) {
self.clear();
}
fn entry<'a>(&'a mut self, key: &str) -> crate::Entry<'a> {
// Accept a `&str` rather than an owned type to keep `String`, well, internal
match self.items.entry(key.into()) {
indexmap::map::Entry::Occupied(entry) => {
crate::Entry::Occupied(crate::OccupiedEntry { entry })
}
indexmap::map::Entry::Vacant(entry) => {
crate::Entry::Vacant(crate::VacantEntry { entry })
}
}
}
fn entry_format<'a>(&'a mut self, key: &Key) -> crate::Entry<'a> {
// Accept a `&Key` to be consistent with `entry`
match self.items.entry(key.get().into()) {
indexmap::map::Entry::Occupied(entry) => {
crate::Entry::Occupied(crate::OccupiedEntry { entry })
}
indexmap::map::Entry::Vacant(entry) => {
crate::Entry::Vacant(crate::VacantEntry { entry })
}
}
}
fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
self.items.get(key)
}
fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
self.items.get_mut(key)
}
fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
self.get_key_value(key)
}
fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
self.get_key_value_mut(key)
}
fn contains_key(&self, key: &str) -> bool {
self.contains_key(key)
}
fn insert(&mut self, key: &str, value: Item) -> Option<Item> {
self.insert(key, value.into_value().unwrap())
.map(Item::Value)
}
fn remove(&mut self, key: &str) -> Option<Item> {
self.remove(key).map(Item::Value)
}
fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
self.get_values()
}
fn fmt(&mut self) {
self.fmt();
}
fn sort_values(&mut self) {
self.sort_values();
}
fn set_dotted(&mut self, yes: bool) {
self.set_dotted(yes);
}
fn is_dotted(&self) -> bool {
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)
}
}
// `{ key1 = value1, ... }`
pub(crate) const DEFAULT_INLINE_KEY_DECOR: (&str, &str) = (" ", " ");
/// A view into a single location in an [`InlineTable`], which may be vacant or occupied.
pub enum InlineEntry<'a> {
/// An occupied Entry.
Occupied(InlineOccupiedEntry<'a>),
/// A vacant Entry.
Vacant(InlineVacantEntry<'a>),
}
impl<'a> InlineEntry<'a> {
/// Returns the entry key
///
/// # Examples
///
/// ```
/// use toml_edit::Table;
///
/// let mut map = Table::new();
///
/// assert_eq!("hello", map.entry("hello").key());
/// ```
pub fn key(&self) -> &str {
match self {
InlineEntry::Occupied(e) => e.key(),
InlineEntry::Vacant(e) => e.key(),
}
}
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
pub fn or_insert(self, default: Value) -> &'a mut Value {
match self {
InlineEntry::Occupied(entry) => entry.into_mut(),
InlineEntry::Vacant(entry) => entry.insert(default),
}
}
/// Ensures a value is in the entry by inserting the result of the default function if empty,
/// and returns a mutable reference to the value in the entry.
pub fn or_insert_with<F: FnOnce() -> Value>(self, default: F) -> &'a mut Value {
match self {
InlineEntry::Occupied(entry) => entry.into_mut(),
InlineEntry::Vacant(entry) => entry.insert(default()),
}
}
}
/// A view into a single occupied location in an [`InlineTable`].
pub struct InlineOccupiedEntry<'a> {
entry: indexmap::map::OccupiedEntry<'a, Key, Item>,
}
impl<'a> InlineOccupiedEntry<'a> {
/// Gets a reference to the entry key
///
/// # Examples
///
/// ```
/// use toml_edit::Table;
///
/// let mut map = Table::new();
///
/// assert_eq!("foo", map.entry("foo").key());
/// ```
pub fn key(&self) -> &str {
self.entry.key().get()
}
/// Gets a mutable reference to the entry key
pub fn key_mut(&mut self) -> KeyMut<'_> {
use indexmap::map::MutableEntryKey;
self.entry.key_mut().as_mut()
}
/// Gets a reference to the value in the entry.
pub fn get(&self) -> &Value {
self.entry.get().as_value().unwrap()
}
/// Gets a mutable reference to the value in the entry.
pub fn get_mut(&mut self) -> &mut Value {
self.entry.get_mut().as_value_mut().unwrap()
}
/// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
/// with a lifetime bound to the map itself
pub fn into_mut(self) -> &'a mut Value {
self.entry.into_mut().as_value_mut().unwrap()
}
/// Sets the value of the entry, and returns the entry's old value
pub fn insert(&mut self, value: Value) -> Value {
let value = Item::Value(value);
self.entry.insert(value).into_value().unwrap()
}
/// Takes the value out of the entry, and returns it
pub fn remove(self) -> Value {
self.entry.shift_remove().into_value().unwrap()
}
}
/// A view into a single empty location in an [`InlineTable`].
pub struct InlineVacantEntry<'a> {
entry: indexmap::map::VacantEntry<'a, Key, Item>,
}
impl<'a> InlineVacantEntry<'a> {
/// Gets a reference to the entry key
///
/// # Examples
///
/// ```
/// use toml_edit::Table;
///
/// let mut map = Table::new();
///
/// assert_eq!("foo", map.entry("foo").key());
/// ```
pub fn key(&self) -> &str {
self.entry.key().get()
}
/// Sets the value of the entry with the `VacantEntry`'s key,
/// and returns a mutable reference to it
pub fn insert(self, value: Value) -> &'a mut Value {
let entry = self.entry;
let value = Item::Value(value);
entry.insert(value).as_value_mut().unwrap()
}
}

450
vendor/toml_edit/src/item.rs vendored Normal file
View File

@@ -0,0 +1,450 @@
use std::str::FromStr;
use toml_datetime::Datetime;
use crate::array_of_tables::ArrayOfTables;
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, Default)]
pub enum Item {
/// Type representing none.
#[default]
None,
/// Type representing value.
Value(Value),
/// Type representing table.
Table(Table),
/// Type representing array of tables.
ArrayOfTables(ArrayOfTables),
}
impl Item {
/// Sets `self` to the given item if `self` is none and
/// returns a mutable reference to `self`.
pub fn or_insert(&mut self, item: Self) -> &mut Self {
if self.is_none() {
*self = item;
}
self
}
}
// TODO: This should be generated by macro or derive
/// Downcasting
impl Item {
/// Text description of value type
pub fn type_name(&self) -> &'static str {
match self {
Self::None => "none",
Self::Value(v) => v.type_name(),
Self::Table(..) => "table",
Self::ArrayOfTables(..) => "array of tables",
}
}
/// Index into a TOML array or map. A string index can be used to access a
/// value in a map, and a usize index can be used to access an element of an
/// array.
///
/// Returns `None` if:
/// - The type of `self` does not match the type of the
/// index, for example if the index is a string and `self` is an array or a
/// number.
/// - The given key does not exist in the map
/// or the given index is not within the bounds of the array.
pub fn get<I: crate::index::Index>(&self, index: I) -> Option<&Self> {
index.index(self)
}
/// Mutably index into a TOML array or map. A string index can be used to
/// access a value in a map, and a usize index can be used to access an
/// element of an array.
///
/// Returns `None` if:
/// - The type of `self` does not match the type of the
/// index, for example if the index is a string and `self` is an array or a
/// number.
/// - The given key does not exist in the map
/// or the given index is not within the bounds of the array.
pub fn get_mut<I: crate::index::Index>(&mut self, index: I) -> Option<&mut Self> {
index.index_mut(self)
}
/// Casts `self` to [`Value`]
pub fn as_value(&self) -> Option<&Value> {
match *self {
Self::Value(ref v) => Some(v),
_ => None,
}
}
/// Casts `self` to [`Table`]
///
/// <div class="warning">
///
/// To operate on both [`Table`]s and [`InlineTable`]s, see [`Item::as_table_like`]
///
/// </div>
pub fn as_table(&self) -> Option<&Table> {
match *self {
Self::Table(ref t) => Some(t),
_ => None,
}
}
/// Casts `self` to [`ArrayOfTables`]
pub fn as_array_of_tables(&self) -> Option<&ArrayOfTables> {
match *self {
Self::ArrayOfTables(ref a) => Some(a),
_ => None,
}
}
/// Casts `self` to mutable [`Value`].
pub fn as_value_mut(&mut self) -> Option<&mut Value> {
match *self {
Self::Value(ref mut v) => Some(v),
_ => None,
}
}
/// Casts `self` to mutable [`Table`]
///
/// <div class="warning">
///
/// To operate on both [`Table`]s and [`InlineTable`]s, see [`Item::as_table_like_mut`]
///
/// </div>
pub fn as_table_mut(&mut self) -> Option<&mut Table> {
match *self {
Self::Table(ref mut t) => Some(t),
_ => None,
}
}
/// Casts `self` to mutable [`ArrayOfTables`]
pub fn as_array_of_tables_mut(&mut self) -> Option<&mut ArrayOfTables> {
match *self {
Self::ArrayOfTables(ref mut a) => Some(a),
_ => None,
}
}
/// Casts `self` to [`Value`]
pub fn into_value(self) -> Result<Value, Self> {
match self {
Self::None => Err(self),
Self::Value(v) => Ok(v),
Self::Table(v) => {
let v = v.into_inline_table();
Ok(Value::InlineTable(v))
}
Self::ArrayOfTables(v) => {
let v = v.into_array();
Ok(Value::Array(v))
}
}
}
/// In-place convert to a value
pub fn make_value(&mut self) {
let other = std::mem::take(self);
let other = other.into_value().map(Item::Value).unwrap_or(Self::None);
*self = other;
}
/// Casts `self` to [`Table`]
///
/// <div class="warning">
///
/// This does not include [`InlineTable`]s
///
/// </div>
pub fn into_table(self) -> Result<Table, Self> {
match self {
Self::Table(t) => Ok(t),
Self::Value(Value::InlineTable(t)) => Ok(t.into_table()),
_ => Err(self),
}
}
/// Casts `self` to [`ArrayOfTables`]
pub fn into_array_of_tables(self) -> Result<ArrayOfTables, Self> {
match self {
Self::ArrayOfTables(a) => Ok(a),
Self::Value(Value::Array(a)) => {
if a.is_empty() {
Err(Self::Value(Value::Array(a)))
} else if a.iter().all(|v| v.is_inline_table()) {
let mut aot = ArrayOfTables::new();
aot.values = a.values;
for value in aot.values.iter_mut() {
value.make_item();
}
Ok(aot)
} else {
Err(Self::Value(Value::Array(a)))
}
}
_ => Err(self),
}
}
// Starting private because the name is unclear
pub(crate) fn make_item(&mut self) {
let other = std::mem::take(self);
let other = match other.into_table().map(Item::Table) {
Ok(i) => i,
Err(i) => i,
};
let other = match other.into_array_of_tables().map(Item::ArrayOfTables) {
Ok(i) => i,
Err(i) => i,
};
*self = other;
}
/// Returns true if `self` is a [`Value`]
pub fn is_value(&self) -> bool {
self.as_value().is_some()
}
/// Returns true if `self` is a [`Table`]
///
/// <div class="warning">
///
/// To operate on both [`Table`]s and [`InlineTable`]s, see [`Item::is_table_like`]
///
/// </div>
pub fn is_table(&self) -> bool {
self.as_table().is_some()
}
/// Returns true if `self` is an [`ArrayOfTables`]
pub fn is_array_of_tables(&self) -> bool {
self.as_array_of_tables().is_some()
}
/// Returns true if `self` is `None`.
pub fn is_none(&self) -> bool {
matches!(*self, Self::None)
}
// Duplicate Value downcasting API
/// Casts `self` to integer.
pub fn as_integer(&self) -> Option<i64> {
self.as_value().and_then(Value::as_integer)
}
/// Returns true if `self` is an integer.
pub fn is_integer(&self) -> bool {
self.as_integer().is_some()
}
/// Casts `self` to float.
pub fn as_float(&self) -> Option<f64> {
self.as_value().and_then(Value::as_float)
}
/// Returns true if `self` is a float.
pub fn is_float(&self) -> bool {
self.as_float().is_some()
}
/// Casts `self` to boolean.
pub fn as_bool(&self) -> Option<bool> {
self.as_value().and_then(Value::as_bool)
}
/// Returns true if `self` is a boolean.
pub fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
/// Casts `self` to str.
pub fn as_str(&self) -> Option<&str> {
self.as_value().and_then(Value::as_str)
}
/// Returns true if `self` is a string.
pub fn is_str(&self) -> bool {
self.as_str().is_some()
}
/// Casts `self` to date-time.
pub fn as_datetime(&self) -> Option<&Datetime> {
self.as_value().and_then(Value::as_datetime)
}
/// Returns true if `self` is a date-time.
pub fn is_datetime(&self) -> bool {
self.as_datetime().is_some()
}
/// Casts `self` to array.
pub fn as_array(&self) -> Option<&Array> {
self.as_value().and_then(Value::as_array)
}
/// Casts `self` to mutable array.
pub fn as_array_mut(&mut self) -> Option<&mut Array> {
self.as_value_mut().and_then(Value::as_array_mut)
}
/// Returns true if `self` is an array.
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
/// Casts `self` to inline table.
pub fn as_inline_table(&self) -> Option<&InlineTable> {
self.as_value().and_then(Value::as_inline_table)
}
/// Casts `self` to mutable inline table.
pub fn as_inline_table_mut(&mut self) -> Option<&mut InlineTable> {
self.as_value_mut().and_then(Value::as_inline_table_mut)
}
/// Returns true if `self` is an inline table.
pub fn is_inline_table(&self) -> bool {
self.as_inline_table().is_some()
}
/// Casts `self` to either a table or an inline table.
pub fn as_table_like(&self) -> Option<&dyn TableLike> {
self.as_table()
.map(|t| t as &dyn TableLike)
.or_else(|| self.as_inline_table().map(|t| t as &dyn TableLike))
}
/// Casts `self` to either a table or an inline table.
pub fn as_table_like_mut(&mut self) -> Option<&mut dyn TableLike> {
match self {
Self::Table(t) => Some(t as &mut dyn TableLike),
Self::Value(Value::InlineTable(t)) => Some(t as &mut dyn TableLike),
_ => None,
}
}
/// Returns true if `self` is either a table, or an inline table.
pub fn is_table_like(&self) -> bool {
self.as_table_like().is_some()
}
/// The location within the original document
///
/// This generally requires a [`Document`][crate::Document].
pub fn span(&self) -> Option<std::ops::Range<usize>> {
match self {
Self::None => None,
Self::Value(v) => v.span(),
Self::Table(v) => v.span(),
Self::ArrayOfTables(v) => v.span(),
}
}
pub(crate) fn despan(&mut self, input: &str) {
match self {
Self::None => {}
Self::Value(v) => v.despan(input),
Self::Table(v) => v.despan(input),
Self::ArrayOfTables(v) => v.despan(input),
}
}
}
impl Clone for Item {
#[inline(never)]
fn clone(&self) -> Self {
match self {
Self::None => Self::None,
Self::Value(v) => Self::Value(v.clone()),
Self::Table(v) => Self::Table(v.clone()),
Self::ArrayOfTables(v) => Self::ArrayOfTables(v.clone()),
}
}
}
#[cfg(feature = "parse")]
impl FromStr for Item {
type Err = crate::TomlError;
/// Parses a value from a &str
fn from_str(s: &str) -> Result<Self, Self::Err> {
let value = s.parse::<Value>()?;
Ok(Self::Value(value))
}
}
impl<'b> From<&'b Self> for Item {
fn from(s: &'b Self) -> Self {
s.clone()
}
}
impl From<Table> for Item {
fn from(s: Table) -> Self {
Self::Table(s)
}
}
impl From<ArrayOfTables> for Item {
fn from(s: ArrayOfTables) -> Self {
Self::ArrayOfTables(s)
}
}
impl<V: Into<Value>> From<V> for Item {
fn from(s: V) -> Self {
Self::Value(s.into())
}
}
#[cfg(feature = "display")]
impl std::fmt::Display for Item {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match &self {
Self::None => Ok(()),
Self::Value(v) => v.fmt(f),
Self::Table(v) => v.fmt(f),
Self::ArrayOfTables(v) => v.fmt(f),
}
}
}
/// Returns a formatted value.
///
/// Since formatting is part of a `Value`, the right hand side of the
/// assignment needs to be decorated with a space before the value.
/// The `value` function does just that.
///
/// # Examples
/// ```rust
/// # #[cfg(feature = "display")] {
/// # #[cfg(feature = "parse")] {
/// # use toml_edit::*;
/// let mut table = Table::default();
/// let mut array = Array::default();
/// array.push("hello");
/// array.push("\\, world"); // \ is only allowed in a literal string
/// table["key1"] = value("value1");
/// table["key2"] = value(42);
/// table["key3"] = value(array);
/// assert_eq!(table.to_string(),
/// r#"key1 = "value1"
/// key2 = 42
/// key3 = ["hello", '\, world']
/// "#);
/// # }
/// # }
/// ```
pub fn value<V: Into<Value>>(v: V) -> Item {
Item::Value(v.into())
}
/// Returns an empty table.
pub fn table() -> Item {
Item::Table(Table::new())
}
/// Returns an empty array of tables.
pub fn array() -> Item {
Item::ArrayOfTables(ArrayOfTables::new())
}
#[test]
#[cfg(feature = "parse")]
#[cfg(feature = "display")]
fn string_roundtrip() {
value("hello").to_string().parse::<Item>().unwrap();
}

397
vendor/toml_edit/src/key.rs vendored Normal file
View File

@@ -0,0 +1,397 @@
use std::borrow::Cow;
use std::str::FromStr;
#[cfg(feature = "display")]
use toml_writer::ToTomlKey as _;
use crate::repr::{Decor, Repr};
/// For Key/[`Value`][crate::Value] pairs under a [`Table`][crate::Table] header or inside an
/// [`InlineTable`][crate::InlineTable]
///
/// # Examples
///
/// ```notrust
/// [dependencies."nom"]
/// version = "5.0"
/// 'literal key' = "nonsense"
/// "basic string key" = 42
/// ```
///
/// There are 3 types of keys:
///
/// 1. Bare keys (`version` and `dependencies`)
///
/// 2. Basic quoted keys (`"basic string key"` and `"nom"`)
///
/// 3. Literal quoted keys (`'literal key'`)
///
/// For details see [toml spec](https://github.com/toml-lang/toml/#keyvalue-pair).
///
/// To parse a key use `FromStr` trait implementation: `"string".parse::<Key>()`.
#[derive(Debug)]
pub struct Key {
key: String,
pub(crate) repr: Option<Repr>,
pub(crate) leaf_decor: Decor,
pub(crate) dotted_decor: Decor,
}
impl Key {
/// Create a new table key
pub fn new(key: impl Into<String>) -> Self {
Self {
key: key.into(),
repr: None,
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)
}
pub(crate) fn with_repr_unchecked(mut self, repr: Repr) -> Self {
self.repr = Some(repr);
self
}
/// 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
}
/// Access a mutable proxy for the `Key`.
pub fn as_mut(&mut self) -> KeyMut<'_> {
KeyMut { key: self }
}
/// Returns the parsed key value.
pub fn get(&self) -> &str {
&self.key
}
/// Returns key raw representation, if available.
pub fn as_repr(&self) -> Option<&Repr> {
self.repr.as_ref()
}
/// Returns the default raw representation.
#[cfg(feature = "display")]
pub fn default_repr(&self) -> Repr {
let output = toml_writer::TomlKeyBuilder::new(&self.key)
.as_default()
.to_toml_key();
Repr::new_unchecked(output)
}
/// 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())
.map(Cow::Borrowed)
.unwrap_or_else(|| {
Cow::Owned(self.default_repr().as_raw().as_str().unwrap().to_owned())
})
}
/// 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 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
}
/// The location within the original document
///
/// This generally requires a [`Document`][crate::Document].
pub fn span(&self) -> Option<std::ops::Range<usize>> {
self.repr.as_ref().and_then(|r| r.span())
}
pub(crate) fn despan(&mut self, input: &str) {
self.leaf_decor.despan(input);
self.dotted_decor.despan(input);
if let Some(repr) = &mut self.repr {
repr.despan(input);
}
}
/// Auto formats the key.
pub fn fmt(&mut self) {
self.repr = None;
self.leaf_decor.clear();
self.dotted_decor.clear();
}
#[cfg(feature = "parse")]
fn try_parse_simple(s: &str) -> Result<Self, crate::TomlError> {
let source = toml_parser::Source::new(s);
let mut sink = crate::error::TomlSink::<Option<_>>::new(source);
let mut key = crate::parser::parse_key(source, &mut sink);
if let Some(err) = sink.into_inner() {
Err(err)
} else {
key.despan(s);
Ok(key)
}
}
#[cfg(feature = "parse")]
fn try_parse_path(s: &str) -> Result<Vec<Self>, crate::TomlError> {
let source = toml_parser::Source::new(s);
let mut sink = crate::error::TomlSink::<Option<_>>::new(source);
let mut keys = crate::parser::parse_key_path(source, &mut sink);
if let Some(err) = sink.into_inner() {
Err(err)
} else {
for key in &mut keys {
key.despan(s);
}
Ok(keys)
}
}
}
impl Clone for Key {
#[inline(never)]
fn clone(&self) -> Self {
Self {
key: self.key.clone(),
repr: self.repr.clone(),
leaf_decor: self.leaf_decor.clone(),
dotted_decor: self.dotted_decor.clone(),
}
}
}
impl std::ops::Deref for Key {
type Target = str;
fn deref(&self) -> &Self::Target {
self.get()
}
}
impl std::borrow::Borrow<str> for Key {
#[inline]
fn borrow(&self) -> &str {
self.get()
}
}
impl std::hash::Hash for Key {
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
self.get().hash(state);
}
}
impl Ord for Key {
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
self.get().cmp(other.get())
}
}
impl PartialOrd for Key {
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
Some(self.cmp(other))
}
}
impl Eq for Key {}
impl PartialEq for Key {
#[inline]
fn eq(&self, other: &Self) -> bool {
PartialEq::eq(self.get(), other.get())
}
}
impl PartialEq<str> for Key {
#[inline]
fn eq(&self, other: &str) -> bool {
PartialEq::eq(self.get(), other)
}
}
impl PartialEq<&str> for Key {
#[inline]
fn eq(&self, other: &&str) -> bool {
PartialEq::eq(self.get(), *other)
}
}
impl PartialEq<String> for Key {
#[inline]
fn eq(&self, other: &String) -> bool {
PartialEq::eq(self.get(), other.as_str())
}
}
#[cfg(feature = "display")]
impl std::fmt::Display for Key {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
crate::encode::encode_key(self, f, None)
}
}
#[cfg(feature = "parse")]
impl FromStr for Key {
type Err = crate::TomlError;
/// Tries to parse a key from a &str,
/// if fails, tries as basic quoted key (surrounds with "")
/// and then literal quoted key (surrounds with '')
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::try_parse_simple(s)
}
}
impl<'b> From<&'b str> for Key {
fn from(s: &'b str) -> Self {
Self::new(s)
}
}
impl<'b> From<&'b String> for Key {
fn from(s: &'b String) -> Self {
Self::new(s)
}
}
impl From<String> for Key {
fn from(s: String) -> Self {
Self::new(s)
}
}
#[doc(hidden)]
impl From<Key> for String {
fn from(key: Key) -> Self {
key.key
}
}
/// A mutable reference to a [`Key`]'s formatting
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
pub struct KeyMut<'k> {
key: &'k mut Key,
}
impl KeyMut<'_> {
/// Returns the parsed key value.
pub fn get(&self) -> &str {
self.key.get()
}
/// Returns the raw representation, if available.
pub fn as_repr(&self) -> Option<&Repr> {
self.key.as_repr()
}
/// 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 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 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();
}
}
impl std::ops::Deref for KeyMut<'_> {
type Target = str;
fn deref(&self) -> &Self::Target {
self.get()
}
}
impl PartialEq<str> for KeyMut<'_> {
#[inline]
fn eq(&self, other: &str) -> bool {
PartialEq::eq(self.get(), other)
}
}
impl<'s> PartialEq<&'s str> for KeyMut<'s> {
#[inline]
fn eq(&self, other: &&str) -> bool {
PartialEq::eq(self.get(), *other)
}
}
impl PartialEq<String> for KeyMut<'_> {
#[inline]
fn eq(&self, other: &String) -> bool {
PartialEq::eq(self.get(), other.as_str())
}
}
#[cfg(feature = "display")]
impl std::fmt::Display for KeyMut<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
std::fmt::Display::fmt(&self.key, f)
}
}
#[test]
#[cfg(feature = "parse")]
#[cfg(feature = "display")]
fn string_roundtrip() {
Key::new("hello").to_string().parse::<Key>().unwrap();
}

147
vendor/toml_edit/src/lib.rs vendored Normal file
View File

@@ -0,0 +1,147 @@
//! # `toml_edit`
//!
//! This crate allows you to parse and modify toml
//! documents, while preserving comments, spaces *and
//! relative order* of items.
//!
//! If you also need the ease of a more traditional API, see the [`toml`] crate.
//!
//! # Example
//!
//! ```rust
//! # #[cfg(feature = "parse")] {
//! # #[cfg(feature = "display")] {
//! use toml_edit::{DocumentMut, value};
//!
//! let toml = r#"
//! "hello" = 'toml!' # comment
//! ['a'.b]
//! "#;
//! let mut doc = toml.parse::<DocumentMut>().expect("invalid doc");
//! assert_eq!(doc.to_string(), toml);
//! // let's add a new key/value pair inside a.b: c = {d = "hello"}
//! doc["a"]["b"]["c"]["d"] = value("hello");
//! // autoformat inline table a.b.c: { d = "hello" }
//! doc["a"]["b"]["c"].as_inline_table_mut().map(|t| t.fmt());
//! let expected = r#"
//! "hello" = 'toml!' # comment
//! ['a'.b]
//! c = { d = "hello" }
//! "#;
//! assert_eq!(doc.to_string(), expected);
//! # }
//! # }
//! ```
//!
//! ## Controlling formatting
//!
//! By default, values are created with default formatting
//! ```rust
//! # #[cfg(feature = "display")] {
//! # #[cfg(feature = "parse")] {
//! let mut doc = toml_edit::DocumentMut::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")] {
//! # #[cfg(feature = "parse")] {
//! let mut doc = toml_edit::DocumentMut::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:
//!
//! * Order of dotted keys, see [issue](https://github.com/toml-rs/toml/issues/163).
//!
//! [`toml`]: https://docs.rs/toml/latest/toml/
// https://github.com/Marwes/combine/issues/172
#![recursion_limit = "256"]
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
#![warn(missing_docs)]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
mod array;
mod array_of_tables;
mod document;
#[cfg(feature = "display")]
mod encode;
mod error;
mod index;
mod inline_table;
mod item;
mod key;
#[cfg(feature = "parse")]
mod parser;
mod raw_string;
mod repr;
mod table;
mod value;
#[cfg(feature = "serde")]
pub mod de;
#[cfg(feature = "serde")]
pub mod ser;
pub mod visit;
pub mod visit_mut;
pub use crate::array::{Array, ArrayIntoIter, ArrayIter, ArrayIterMut};
pub use crate::array_of_tables::{
ArrayOfTables, ArrayOfTablesIntoIter, ArrayOfTablesIter, ArrayOfTablesIterMut,
};
pub use crate::document::DocumentMut;
/// Type representing a parsed TOML document
#[deprecated(since = "0.23.0", note = "Replaced with `Document`")]
pub type ImDocument<S> = Document<S>;
pub use crate::document::Document;
pub use crate::error::TomlError;
pub use crate::inline_table::{
InlineEntry, InlineOccupiedEntry, InlineTable, InlineTableIntoIter, InlineTableIter,
InlineTableIterMut, InlineVacantEntry,
};
pub use crate::item::{array, table, value, Item};
pub use crate::key::{Key, KeyMut};
pub use crate::raw_string::RawString;
pub use crate::repr::{Decor, Formatted, Repr};
pub use crate::table::{
Entry, IntoIter, Iter, IterMut, OccupiedEntry, Table, TableLike, VacantEntry,
};
pub use crate::value::Value;
pub use toml_datetime::*;
// Prevent users from some traits.
pub(crate) mod private {
pub trait Sealed {}
impl Sealed for usize {}
impl Sealed for str {}
impl Sealed for String {}
impl Sealed for i64 {}
impl Sealed for f64 {}
impl Sealed for bool {}
impl Sealed for crate::Datetime {}
impl<T: ?Sized> Sealed for &T where T: Sealed {}
impl Sealed for crate::Table {}
impl Sealed for crate::InlineTable {}
}
#[doc = include_str!("../README.md")]
#[cfg(doctest)]
#[cfg(feature = "display")]
#[cfg(feature = "parse")]
pub struct ReadmeDoctests;

156
vendor/toml_edit/src/parser/array.rs vendored Normal file
View File

@@ -0,0 +1,156 @@
use crate::parser::inline_table::on_inline_table;
use crate::parser::value::on_scalar;
use crate::{Array, RawString, Value};
use crate::parser::prelude::*;
/// ```bnf
/// ;; Array
///
/// array = array-open array-values array-close
/// array-values = ws-comment-newline val ws-comment-newline array-sep array-values
/// array-values =/ ws-comment-newline val ws-comment-newline [ array-sep ]
/// ```
pub(crate) fn on_array(
open_event: &toml_parser::parser::Event,
input: &mut Input<'_>,
source: toml_parser::Source<'_>,
errors: &mut dyn ErrorSink,
) -> Value {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("array::on_array");
let mut result = Array::new();
let mut state = State::default();
state.open(open_event);
while let Some(event) = input.next_token() {
match event.kind() {
EventKind::StdTableOpen
| EventKind::ArrayTableOpen
| EventKind::InlineTableClose
| EventKind::SimpleKey
| EventKind::KeySep
| EventKind::KeyValSep
| EventKind::StdTableClose
| EventKind::ArrayTableClose => {
#[cfg(feature = "debug")]
trace(
&format!("unexpected {event:?}"),
anstyle::AnsiColor::Red.on_default(),
);
break;
}
EventKind::Error => {
#[cfg(feature = "debug")]
trace(
&format!("unexpected {event:?}"),
anstyle::AnsiColor::Red.on_default(),
);
continue;
}
EventKind::InlineTableOpen => {
let value = on_inline_table(event, input, source, errors);
state.capture_value(event, value);
}
EventKind::ArrayOpen => {
let value = on_array(event, input, source, errors);
state.capture_value(event, value);
}
EventKind::Scalar => {
let value = on_scalar(event, source, errors);
state.capture_value(event, value);
}
EventKind::ValueSep => {
state.finish_value(event, &mut result);
state.sep_value(event);
}
EventKind::Whitespace | EventKind::Comment | EventKind::Newline => {
state.whitespace(event);
}
EventKind::ArrayClose => {
state.finish_value(event, &mut result);
state.close(open_event, event, &mut result);
break;
}
}
}
Value::Array(result)
}
#[derive(Default)]
struct State {
current_prefix: Option<toml_parser::Span>,
current_value: Option<Value>,
trailing_start: Option<usize>,
current_suffix: Option<toml_parser::Span>,
}
impl State {
fn open(&mut self, open_event: &toml_parser::parser::Event) {
self.trailing_start = Some(open_event.span().end());
}
fn whitespace(&mut self, event: &toml_parser::parser::Event) {
let decor = if self.is_prefix() {
self.current_prefix.get_or_insert(event.span())
} else {
self.current_suffix.get_or_insert(event.span())
};
*decor = decor.append(event.span());
}
fn is_prefix(&self) -> bool {
self.current_value.is_none()
}
fn capture_value(&mut self, event: &toml_parser::parser::Event, value: Value) {
self.trailing_start = None;
self.current_prefix
.get_or_insert_with(|| event.span().before());
self.current_value = Some(value);
}
fn finish_value(&mut self, event: &toml_parser::parser::Event, result: &mut Array) {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("array::finish_value");
if let Some(mut value) = self.current_value.take() {
let prefix = self
.current_prefix
.take()
.expect("setting a value should set a prefix");
let suffix = self
.current_suffix
.take()
.unwrap_or_else(|| event.span().before());
let decor = value.decor_mut();
decor.set_prefix(RawString::with_span(prefix.start()..prefix.end()));
decor.set_suffix(RawString::with_span(suffix.start()..suffix.end()));
result.push_formatted(value);
}
}
fn sep_value(&mut self, event: &toml_parser::parser::Event) {
self.trailing_start = Some(event.span().end());
}
fn close(
&mut self,
open_event: &toml_parser::parser::Event,
close_event: &toml_parser::parser::Event,
result: &mut Array,
) {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("array::close");
let trailing_comma = self.trailing_start.is_some() && !result.is_empty();
let span = open_event.span().append(close_event.span());
let trailing_start = self
.trailing_start
.unwrap_or_else(|| close_event.span().start());
let trailing_end = close_event.span().start();
result.set_trailing_comma(trailing_comma);
result.set_trailing(RawString::with_span(trailing_start..trailing_end));
result.span = Some(span.start()..span.end());
}
}

98
vendor/toml_edit/src/parser/debug.rs vendored Normal file
View File

@@ -0,0 +1,98 @@
pub(crate) struct TraceScope {
text: String,
style: anstyle::Style,
guard: DebugDepthGuard,
}
impl TraceScope {
pub(crate) fn new(text: impl core::fmt::Display) -> Self {
let text = text.to_string();
let style = anstyle::Style::new();
trace(&format!("> {text}"), style);
Self {
text,
style,
guard: DEBUG_DEPTH.scoped(),
}
}
}
impl Drop for TraceScope {
fn drop(&mut self) {
let text = &self.text;
let style = self.style;
drop(self.guard.take());
trace(&format!("< {text}"), style);
}
}
pub(crate) fn trace(text: &str, style: anstyle::Style) {
#![allow(unexpected_cfgs)] // HACK: fixed in newer versions
let depth = DEBUG_DEPTH.depth();
anstream::eprintln!("{:depth$}{style}{text}{style:#}", "");
}
pub(crate) struct DebugDepth(core::sync::atomic::AtomicUsize);
impl DebugDepth {
pub(crate) fn scoped(&self) -> DebugDepthGuard {
DebugDepthGuard::new()
}
pub(crate) fn enter_unchecked(&self) -> usize {
self.0.fetch_add(1, core::sync::atomic::Ordering::SeqCst)
}
pub(crate) fn exit_unchecked(&self) {
let _ = self.0.fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
}
pub(crate) fn depth(&self) -> usize {
self.0.load(core::sync::atomic::Ordering::SeqCst)
}
}
static DEBUG_DEPTH: DebugDepth = DebugDepth(core::sync::atomic::AtomicUsize::new(0));
pub(crate) struct DebugDepthGuard {
depth: usize,
inc: bool,
}
impl DebugDepthGuard {
pub(crate) fn new() -> Self {
let depth = DEBUG_DEPTH.enter_unchecked();
Self { depth, inc: true }
}
fn take(&mut self) -> Self {
let depth = self.depth;
let inc = self.inc;
self.inc = false;
Self { depth, inc }
}
}
impl Drop for DebugDepthGuard {
fn drop(&mut self) {
if self.inc {
DEBUG_DEPTH.exit_unchecked();
}
}
}
impl AsRef<usize> for DebugDepthGuard {
#[inline(always)]
fn as_ref(&self) -> &usize {
&self.depth
}
}
impl core::ops::Deref for DebugDepthGuard {
type Target = usize;
#[inline(always)]
fn deref(&self) -> &Self::Target {
&self.depth
}
}

517
vendor/toml_edit/src/parser/document.rs vendored Normal file
View File

@@ -0,0 +1,517 @@
use crate::key::Key;
use crate::parser::key::on_key;
use crate::parser::prelude::*;
use crate::parser::value::value;
use crate::repr::Decor;
use crate::Item;
use crate::RawString;
use crate::Value;
use crate::{ArrayOfTables, Document, Table};
/// ```bnf
/// ;; TOML
///
/// toml = expression *( newline expression )
///
/// expression = ( ( ws comment ) /
/// ( ws keyval ws [ comment ] ) /
/// ( ws table ws [ comment ] ) /
/// ws )
/// ```
pub(crate) fn document<'s>(
input: &mut Input<'_>,
source: toml_parser::Source<'s>,
errors: &mut dyn ErrorSink,
) -> Document<&'s str> {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("document::document");
let mut state = State::default();
while let Some(event) = input.next_token() {
match event.kind() {
EventKind::InlineTableOpen
| EventKind::InlineTableClose
| EventKind::ArrayOpen
| EventKind::ArrayClose
| EventKind::Scalar
| EventKind::ValueSep
| EventKind::Error
| EventKind::KeySep
| EventKind::KeyValSep
| EventKind::StdTableClose
| EventKind::ArrayTableClose => {
#[cfg(feature = "debug")]
trace(
&format!("unexpected {event:?}"),
anstyle::AnsiColor::Red.on_default(),
);
continue;
}
EventKind::StdTableOpen | EventKind::ArrayTableOpen => {
state.finish_table(errors);
let prefix = state.take_trailing();
let header = on_table(event, input, source, errors);
let suffix = ws_comment_newline(input)
.map(|s| RawString::with_span(s.start()..s.end()))
.unwrap_or_default();
let decor = Decor::new(prefix, suffix);
state.start_table(header, decor, errors);
}
EventKind::SimpleKey => {
let key_prefix = state.take_trailing();
let (path, key) = on_key(event, input, source, errors);
let Some(mut key) = key else {
break;
};
let Some(next_event) = input.next_token() else {
break;
};
let keyval_event;
let key_suffix;
if next_event.kind() == EventKind::Whitespace {
key_suffix = Some(next_event);
let Some(next_event) = input.next_token() else {
break;
};
keyval_event = next_event;
} else {
key_suffix = None;
keyval_event = next_event;
}
if keyval_event.kind() != EventKind::KeyValSep {
break;
}
let key_suffix = key_suffix
.map(|e| RawString::with_span(e.span().start()..e.span().end()))
.unwrap_or_default();
key.leaf_decor.set_prefix(key_prefix);
key.leaf_decor.set_suffix(key_suffix);
let value_prefix = if input
.first()
.map(|e| e.kind() == EventKind::Whitespace)
.unwrap_or(false)
{
input
.next_token()
.map(|e| RawString::with_span(e.span().start()..e.span().end()))
} else {
None
}
.unwrap_or_default();
let mut value = value(input, source, errors);
let value_suffix = ws_comment_newline(input)
.map(|s| RawString::with_span(s.start()..s.end()))
.unwrap_or_default();
let decor = value.decor_mut();
decor.set_prefix(value_prefix);
decor.set_suffix(value_suffix);
state.capture_key_value(path, key, value, errors);
}
EventKind::Whitespace | EventKind::Comment | EventKind::Newline => {
state.capture_trailing(event);
}
}
}
state.finish_table(errors);
let trailing = state.take_trailing();
Document {
root: Item::Table(state.root),
trailing,
raw: source.input(),
}
}
/// ```bnf
/// ;; Standard Table
///
/// std-table = std-table-open key *( table-key-sep key) std-table-close
///
/// ;; Array Table
///
/// array-table = array-table-open key *( table-key-sep key) array-table-close
/// ```
fn on_table(
open_event: &toml_parser::parser::Event,
input: &mut Input<'_>,
source: toml_parser::Source<'_>,
errors: &mut dyn ErrorSink,
) -> TableHeader {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("document::on_table");
let is_array = open_event.kind() == EventKind::ArrayTableOpen;
let mut current_path = None;
let mut current_key = None;
let mut current_span = open_event.span();
let mut current_prefix = None;
let mut current_suffix = None;
while let Some(event) = input.next_token() {
match event.kind() {
EventKind::InlineTableOpen
| EventKind::InlineTableClose
| EventKind::ArrayOpen
| EventKind::ArrayClose
| EventKind::Scalar
| EventKind::ValueSep
| EventKind::Error
| EventKind::KeySep
| EventKind::KeyValSep
| EventKind::StdTableOpen
| EventKind::ArrayTableOpen
| EventKind::Comment
| EventKind::Newline => {
#[cfg(feature = "debug")]
trace(
&format!("unexpected {event:?}"),
anstyle::AnsiColor::Red.on_default(),
);
continue;
}
EventKind::ArrayTableClose | EventKind::StdTableClose => {
current_span = current_span.append(event.span());
break;
}
EventKind::SimpleKey => {
current_prefix.get_or_insert_with(|| event.span().before());
let (path, key) = on_key(event, input, source, errors);
current_path = Some(path);
current_key = key;
current_suffix.get_or_insert_with(|| event.span().after());
}
EventKind::Whitespace => {
if current_key.is_some() {
current_suffix = Some(event.span());
} else {
current_prefix = Some(event.span());
}
}
}
}
let prefix = current_prefix
.take()
.expect("setting a key should set a prefix");
let suffix = current_suffix
.take()
.expect("setting a key should set a suffix");
if let Some(last_key) = current_key.as_mut() {
let prefix = RawString::with_span(prefix.start()..prefix.end());
let suffix = RawString::with_span(suffix.start()..suffix.end());
let leaf_decor = Decor::new(prefix, suffix);
*last_key.leaf_decor_mut() = leaf_decor;
}
TableHeader {
path: current_path.unwrap_or_default(),
key: current_key,
span: current_span,
is_array,
}
}
struct TableHeader {
path: Vec<Key>,
key: Option<Key>,
span: toml_parser::Span,
is_array: bool,
}
fn ws_comment_newline(input: &mut Input<'_>) -> Option<toml_parser::Span> {
let mut current_span = None;
while let Some(event) = input.next_token() {
match event.kind() {
EventKind::InlineTableOpen
| EventKind::InlineTableClose
| EventKind::ArrayOpen
| EventKind::ArrayClose
| EventKind::Scalar
| EventKind::ValueSep
| EventKind::Error
| EventKind::SimpleKey
| EventKind::KeySep
| EventKind::KeyValSep
| EventKind::StdTableOpen
| EventKind::ArrayTableOpen
| EventKind::StdTableClose
| EventKind::ArrayTableClose => {
#[cfg(feature = "debug")]
trace(
&format!("unexpected {event:?}"),
anstyle::AnsiColor::Red.on_default(),
);
}
EventKind::Whitespace | EventKind::Comment => {
let span = current_span.get_or_insert_with(|| event.span());
*span = span.append(event.span());
}
EventKind::Newline => {
break;
}
}
}
current_span
}
#[derive(Default)]
struct State {
root: Table,
current_table: Table,
current_trailing: Option<toml_parser::Span>,
current_header: Option<TableHeader>,
current_position: isize,
}
impl State {
fn capture_trailing(&mut self, event: &toml_parser::parser::Event) {
let decor = self.current_trailing.get_or_insert(event.span());
*decor = decor.append(event.span());
}
fn capture_key_value(
&mut self,
path: Vec<Key>,
key: Key,
value: Value,
errors: &mut dyn ErrorSink,
) {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("document::capture_key_value");
#[cfg(feature = "debug")]
trace(
&format!(
"path={:?}",
path.iter().map(|k| k.get()).collect::<Vec<_>>()
),
anstyle::AnsiColor::Blue.on_default(),
);
#[cfg(feature = "debug")]
trace(
&format!("key={key}",),
anstyle::AnsiColor::Blue.on_default(),
);
#[cfg(feature = "debug")]
trace(
&format!("value={value:?}",),
anstyle::AnsiColor::Blue.on_default(),
);
let dotted = true;
let Some(parent_table) = descend_path(&mut self.current_table, &path, dotted, errors)
else {
return;
};
// "Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed"
let mixed_table_types = parent_table.is_dotted() == path.is_empty();
if mixed_table_types {
let key_span = get_key_span(&key).expect("all keys have spans");
errors.report_error(ParseError::new("duplicate key").with_unexpected(key_span));
return;
}
let key_span = get_key_span(&key).expect("all keys have spans");
match parent_table.items.entry(key) {
indexmap::map::Entry::Vacant(o) => {
o.insert(Item::Value(value));
}
indexmap::map::Entry::Occupied(existing) => {
// "Since tables cannot be defined more than once, redefining such tables using a [table] header is not allowed"
let old_span = existing.key().span().expect("all items have spans");
let old_span = toml_parser::Span::new_unchecked(old_span.start, old_span.end);
errors.report_error(
ParseError::new("duplicate key")
.with_unexpected(key_span)
.with_context(old_span),
);
}
}
}
fn finish_table(&mut self, errors: &mut dyn ErrorSink) {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("document::finish_table");
let mut prev_table = std::mem::take(&mut self.current_table);
if let Some(header) = self.current_header.take() {
let Some(key) = &header.key else {
return;
};
prev_table.span = Some(header.span.start()..header.span.end());
let parent_key = &header.path;
let dotted = false;
let Some(parent_table) = descend_path(&mut self.root, parent_key, dotted, errors)
else {
return;
};
#[cfg(feature = "debug")]
trace(
&format!("key={key}",),
anstyle::AnsiColor::Blue.on_default(),
);
if header.is_array {
let entry = parent_table
.entry_format(key)
.or_insert(Item::ArrayOfTables(ArrayOfTables::new()));
let Some(array) = entry.as_array_of_tables_mut() else {
let key_span = get_key_span(key).expect("all keys have spans");
let old_span = entry.span().unwrap_or_default();
let old_span = toml_parser::Span::new_unchecked(old_span.start, old_span.end);
errors.report_error(
ParseError::new("duplicate key")
.with_unexpected(key_span)
.with_context(old_span),
);
return;
};
array.push(prev_table);
let span = if let (Some(first), Some(last)) = (
array.values.first().and_then(|t| t.span()),
array.values.last().and_then(|t| t.span()),
) {
Some((first.start)..(last.end))
} else {
None
};
array.span = span;
} else {
let existing = parent_table.insert_formatted(key, Item::Table(prev_table));
debug_assert!(existing.is_none());
}
} else {
prev_table.span = Some(Default::default());
self.root = prev_table;
}
}
fn start_table(&mut self, header: TableHeader, decor: Decor, errors: &mut dyn ErrorSink) {
if !header.is_array {
// 1. Look up the table on start to ensure the duplicate_key error points to the right line
// 2. Ensure any child tables from an implicit table are preserved
let root = &mut self.root;
if let (Some(parent_table), Some(key)) =
(descend_path(root, &header.path, false, errors), &header.key)
{
if let Some((old_key, old_value)) = parent_table.remove_entry(key.get()) {
match old_value {
Item::Table(t) if t.implicit && !t.is_dotted() => {
self.current_table = t;
}
// 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.
old_value => {
let old_span = old_key.span().expect("all items have spans");
let old_span =
toml_parser::Span::new_unchecked(old_span.start, old_span.end);
let key_span = get_key_span(key).expect("all keys have spans");
errors.report_error(
ParseError::new("duplicate key")
.with_unexpected(key_span)
.with_context(old_span),
);
if let Item::Table(t) = old_value {
self.current_table = t;
}
}
}
}
}
}
self.current_position += 1;
self.current_table.decor = decor;
self.current_table.set_implicit(false);
self.current_table.set_dotted(false);
self.current_table.set_position(self.current_position);
self.current_table.span = Some(header.span.start()..header.span.end());
self.current_header = Some(header);
}
fn take_trailing(&mut self) -> RawString {
self.current_trailing
.take()
.map(|s| RawString::with_span(s.start()..s.end()))
.unwrap_or_default()
}
}
fn descend_path<'t>(
mut table: &'t mut Table,
path: &[Key],
dotted: bool,
errors: &mut dyn ErrorSink,
) -> Option<&'t mut Table> {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("document::descend_path");
#[cfg(feature = "debug")]
trace(
&format!(
"path={:?}",
path.iter().map(|k| k.get()).collect::<Vec<_>>()
),
anstyle::AnsiColor::Blue.on_default(),
);
for key in path.iter() {
table = match table.entry_format(key) {
crate::Entry::Vacant(entry) => {
let mut new_table = Table::new();
new_table.span = key.span();
new_table.set_implicit(true);
new_table.set_dotted(dotted);
entry.insert(Item::Table(new_table)).as_table_mut().unwrap()
}
crate::Entry::Occupied(entry) => {
match entry.into_mut() {
Item::ArrayOfTables(ref mut array) => {
debug_assert!(!array.is_empty());
let index = array.len() - 1;
let last_child = array.get_mut(index).unwrap();
last_child
}
Item::Table(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() {
let key_span = get_key_span(key).expect("all keys have spans");
errors.report_error(
ParseError::new("duplicate key").with_unexpected(key_span),
);
return None;
}
sweet_child_of_mine
}
Item::Value(ref existing) => {
let old_span = existing.span().expect("all items have spans");
let old_span =
toml_parser::Span::new_unchecked(old_span.start, old_span.end);
let key_span = get_key_span(key).expect("all keys have spans");
errors.report_error(
ParseError::new(format!(
"cannot extend value of type {} with a dotted key",
existing.type_name()
))
.with_unexpected(key_span)
.with_context(old_span),
);
return None;
}
Item::None => unreachable!(),
}
}
};
}
Some(table)
}
fn get_key_span(key: &Key) -> Option<toml_parser::Span> {
key.as_repr()
.and_then(|r| r.span())
.map(|s| toml_parser::Span::new_unchecked(s.start, s.end))
}

View File

@@ -0,0 +1,285 @@
use crate::key::Key;
use crate::parser::array::on_array;
use crate::parser::key::on_key;
use crate::parser::prelude::*;
use crate::parser::value::on_scalar;
use crate::repr::Decor;
use crate::{InlineTable, Item, RawString, Value};
use indexmap::map::Entry;
/// ```bnf
/// ;; Inline Table
///
/// inline-table = inline-table-open inline-table-keyvals inline-table-close
/// ```
pub(crate) fn on_inline_table(
open_event: &toml_parser::parser::Event,
input: &mut Input<'_>,
source: toml_parser::Source<'_>,
errors: &mut dyn ErrorSink,
) -> Value {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("inline_table::on_inline_table");
let mut result = InlineTable::new();
let mut state = State::default();
while let Some(event) = input.next_token() {
match event.kind() {
EventKind::StdTableOpen
| EventKind::ArrayTableOpen
| EventKind::StdTableClose
| EventKind::ArrayClose
| EventKind::ArrayTableClose
| EventKind::KeySep => {
#[cfg(feature = "debug")]
trace(
&format!("unexpected {event:?}"),
anstyle::AnsiColor::Red.on_default(),
);
break;
}
EventKind::Error => {
#[cfg(feature = "debug")]
trace(
&format!("unexpected {event:?}"),
anstyle::AnsiColor::Red.on_default(),
);
continue;
}
EventKind::SimpleKey => {
let (path, key) = on_key(event, input, source, errors);
state.capture_key(event, path, key);
}
EventKind::KeyValSep => {
state.finish_key(event);
}
EventKind::InlineTableOpen => {
let value = on_inline_table(event, input, source, errors);
state.capture_value(event, value);
}
EventKind::ArrayOpen => {
let value = on_array(event, input, source, errors);
state.capture_value(event, value);
}
EventKind::Scalar => {
let value = on_scalar(event, source, errors);
state.capture_value(event, value);
}
EventKind::ValueSep => {
state.finish_value(event, &mut result, errors);
}
EventKind::Whitespace | EventKind::Comment | EventKind::Newline => {
state.whitespace(event);
}
EventKind::InlineTableClose => {
state.finish_value(event, &mut result, errors);
state.close(open_event, event, &mut result);
break;
}
}
}
Value::InlineTable(result)
}
#[derive(Default)]
struct State {
current_prefix: Option<toml_parser::Span>,
current_key: Option<(Vec<Key>, Key)>,
seen_keyval_sep: bool,
current_value: Option<Value>,
current_suffix: Option<toml_parser::Span>,
}
impl State {
fn whitespace(&mut self, event: &toml_parser::parser::Event) {
let decor = if self.is_prefix() {
self.current_prefix.get_or_insert(event.span())
} else {
self.current_suffix.get_or_insert(event.span())
};
*decor = decor.append(event.span());
}
fn is_prefix(&self) -> bool {
if self.seen_keyval_sep {
self.current_value.is_none()
} else {
self.current_key.is_none()
}
}
fn capture_key(
&mut self,
event: &toml_parser::parser::Event,
path: Vec<Key>,
key: Option<Key>,
) {
self.current_prefix
.get_or_insert_with(|| event.span().before());
if let Some(key) = key {
self.current_key = Some((path, key));
}
}
fn finish_key(&mut self, event: &toml_parser::parser::Event) {
self.seen_keyval_sep = true;
if let Some(last_key) = self.current_key.as_mut().map(|(_, k)| k) {
let prefix = self
.current_prefix
.take()
.expect("setting a key should set a prefix");
let suffix = self
.current_suffix
.take()
.unwrap_or_else(|| event.span().before());
let prefix = RawString::with_span(prefix.start()..prefix.end());
let suffix = RawString::with_span(suffix.start()..suffix.end());
let leaf_decor = Decor::new(prefix, suffix);
*last_key.leaf_decor_mut() = leaf_decor;
}
}
fn capture_value(&mut self, event: &toml_parser::parser::Event, value: Value) {
self.current_prefix
.get_or_insert_with(|| event.span().before());
self.current_value = Some(value);
}
fn finish_value(
&mut self,
event: &toml_parser::parser::Event,
result: &mut InlineTable,
errors: &mut dyn ErrorSink,
) {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("inline_table::finish_value");
self.seen_keyval_sep = false;
if let (Some((path, key)), Some(mut value)) =
(self.current_key.take(), self.current_value.take())
{
let prefix = self
.current_prefix
.take()
.expect("setting a value should set a prefix");
let suffix = self
.current_suffix
.take()
.unwrap_or_else(|| event.span().before());
let Some(table) = descend_path(result, &path, true, errors) else {
return;
};
let decor = value.decor_mut();
decor.set_prefix(RawString::with_span(prefix.start()..prefix.end()));
decor.set_suffix(RawString::with_span(suffix.start()..suffix.end()));
// "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 {
let key_span = get_key_span(&key).unwrap_or_else(|| event.span());
errors.report_error(ParseError::new("duplicate key").with_unexpected(key_span));
} else {
let key_span = get_key_span(&key).unwrap_or_else(|| event.span());
match table.items.entry(key) {
Entry::Vacant(o) => {
o.insert(Item::Value(value));
}
Entry::Occupied(o) => {
let old_span = get_key_span(o.key()).unwrap_or_else(|| event.span());
errors.report_error(
ParseError::new("duplicate key")
.with_unexpected(key_span)
.with_context(old_span),
);
}
}
}
}
}
fn close(
&mut self,
open_event: &toml_parser::parser::Event,
close_event: &toml_parser::parser::Event,
result: &mut InlineTable,
) {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("inline_table::close");
let span = open_event.span().append(close_event.span());
let preamble = self
.current_prefix
.take()
.map(|prefix| RawString::with_span(prefix.start()..prefix.end()));
result.span = Some(span.start()..span.end());
if let Some(preamble) = preamble {
result.set_preamble(preamble);
}
}
}
fn descend_path<'a>(
mut table: &'a mut InlineTable,
path: &'a [Key],
dotted: bool,
errors: &mut dyn ErrorSink,
) -> Option<&'a mut InlineTable> {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("inline_table::descend_path");
#[cfg(feature = "debug")]
trace(
&format!("key={:?}", path.iter().map(|k| k.get()).collect::<Vec<_>>()),
anstyle::AnsiColor::Blue.on_default(),
);
for key in path.iter() {
table = match table.entry_format(key) {
crate::InlineEntry::Vacant(entry) => {
let mut new_table = InlineTable::new();
new_table.span = key.span();
new_table.set_implicit(true);
new_table.set_dotted(dotted);
entry
.insert(Value::InlineTable(new_table))
.as_inline_table_mut()
.unwrap()
}
crate::InlineEntry::Occupied(entry) => {
match entry.into_mut() {
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() {
let key_span = get_key_span(key).expect("all keys have spans");
errors.report_error(
ParseError::new("duplicate key").with_unexpected(key_span),
);
return None;
}
sweet_child_of_mine
}
item => {
let key_span = get_key_span(key).expect("all keys have spans");
errors.report_error(
ParseError::new(format!(
"cannot extend value of type {} with a dotted key",
item.type_name()
))
.with_unexpected(key_span),
);
return None;
}
}
}
};
}
Some(table)
}
fn get_key_span(key: &Key) -> Option<toml_parser::Span> {
key.as_repr()
.and_then(|r| r.span())
.map(|s| toml_parser::Span::new_unchecked(s.start, s.end))
}

168
vendor/toml_edit/src/parser/key.rs vendored Normal file
View File

@@ -0,0 +1,168 @@
use crate::key::Key;
use crate::parser::prelude::*;
use crate::repr::Decor;
use crate::repr::Repr;
use crate::RawString;
/// ```bnf
/// key = simple-key / dotted-key
/// dotted-key = simple-key 1*( dot-sep simple-key )
/// ```
pub(crate) fn on_key(
key_event: &toml_parser::parser::Event,
input: &mut Input<'_>,
source: toml_parser::Source<'_>,
errors: &mut dyn ErrorSink,
) -> (Vec<Key>, Option<Key>) {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("key::on_key");
let mut result_path = Vec::new();
let mut result_key = None;
let mut state = State::new(key_event);
if more_key(input) {
while let Some(event) = input.next_token() {
match event.kind() {
EventKind::StdTableOpen
| EventKind::ArrayTableOpen
| EventKind::InlineTableOpen
| EventKind::InlineTableClose
| EventKind::ArrayOpen
| EventKind::ArrayClose
| EventKind::Scalar
| EventKind::ValueSep
| EventKind::Comment
| EventKind::Newline
| EventKind::KeyValSep
| EventKind::StdTableClose
| EventKind::ArrayTableClose
| EventKind::Error => {
#[cfg(feature = "debug")]
trace(
&format!("unexpected {event:?}"),
anstyle::AnsiColor::Red.on_default(),
);
continue;
}
EventKind::SimpleKey => {
state.current_key = Some(*event);
if !more_key(input) {
break;
}
}
EventKind::Whitespace => {
state.whitespace(event);
}
EventKind::KeySep => {
state.close_key(&mut result_path, &mut result_key, source, errors);
}
}
}
}
state.close_key(&mut result_path, &mut result_key, source, errors);
#[cfg(not(feature = "unbounded"))]
if super::LIMIT <= result_path.len() as u32 {
errors.report_error(ParseError::new("recursion limit"));
return (Vec::new(), None);
}
(result_path, result_key)
}
fn more_key(input: &Input<'_>) -> bool {
let first = input.get(0).map(|e| e.kind());
let second = input.get(1).map(|e| e.kind());
if first == Some(EventKind::KeySep) {
true
} else if first == Some(EventKind::Whitespace) && second == Some(EventKind::KeySep) {
true
} else {
false
}
}
struct State {
current_prefix: Option<toml_parser::Span>,
current_key: Option<toml_parser::parser::Event>,
current_suffix: Option<toml_parser::Span>,
}
impl State {
fn new(key_event: &toml_parser::parser::Event) -> Self {
Self {
current_prefix: None,
current_key: Some(*key_event),
current_suffix: None,
}
}
fn whitespace(&mut self, event: &toml_parser::parser::Event) {
if self.current_key.is_some() {
self.current_suffix = Some(event.span());
} else {
self.current_prefix = Some(event.span());
}
}
fn close_key(
&mut self,
result_path: &mut Vec<Key>,
result_key: &mut Option<Key>,
source: toml_parser::Source<'_>,
errors: &mut dyn ErrorSink,
) {
let Some(key) = self.current_key.take() else {
return;
};
let prefix_span = self
.current_prefix
.take()
.unwrap_or_else(|| key.span().before());
let prefix = RawString::with_span(prefix_span.start()..prefix_span.end());
let suffix_span = self
.current_suffix
.take()
.unwrap_or_else(|| key.span().after());
let suffix = RawString::with_span(suffix_span.start()..suffix_span.end());
let key_span = key.span();
let key_raw = RawString::with_span(key_span.start()..key_span.end());
let raw = source.get(key).unwrap();
let mut decoded = std::borrow::Cow::Borrowed("");
raw.decode_key(&mut decoded, errors);
let key = Key::new(decoded)
.with_repr_unchecked(Repr::new_unchecked(key_raw))
.with_dotted_decor(Decor::new(prefix, suffix));
if let Some(last_key) = result_key.replace(key) {
result_path.push(last_key);
}
}
}
/// ```bnf
/// simple-key = quoted-key / unquoted-key
/// quoted-key = basic-string / literal-string
/// ```
pub(crate) fn on_simple_key(
event: &toml_parser::parser::Event,
source: toml_parser::Source<'_>,
errors: &mut dyn ErrorSink,
) -> (RawString, String) {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("key::on_simple_key");
let raw = source.get(event).unwrap();
let mut key = std::borrow::Cow::Borrowed("");
raw.decode_key(&mut key, errors);
let span = event.span();
let raw = RawString::with_span(span.start()..span.end());
let key = String::from(key);
(raw, key)
}

156
vendor/toml_edit/src/parser/mod.rs vendored Normal file
View File

@@ -0,0 +1,156 @@
#![allow(clippy::type_complexity)]
use crate::RawString;
#[cfg(not(feature = "unbounded"))]
use toml_parser::parser::RecursionGuard;
use toml_parser::parser::ValidateWhitespace;
use winnow::stream::Stream as _;
pub(crate) mod array;
#[cfg(feature = "debug")]
pub(crate) mod debug;
pub(crate) mod document;
pub(crate) mod inline_table;
pub(crate) mod key;
pub(crate) mod value;
pub(crate) fn parse_document<'s>(
source: toml_parser::Source<'s>,
errors: &mut dyn prelude::ErrorSink,
) -> crate::Document<&'s str> {
let tokens = source.lex().into_vec();
let mut events = Vec::with_capacity(tokens.len());
let mut receiver = ValidateWhitespace::new(&mut events, source);
#[cfg(not(feature = "unbounded"))]
let mut receiver = RecursionGuard::new(&mut receiver, LIMIT);
#[cfg(not(feature = "unbounded"))]
let receiver = &mut receiver;
#[cfg(feature = "unbounded")]
let receiver = &mut receiver;
toml_parser::parser::parse_document(&tokens, receiver, errors);
let mut input = prelude::Input::new(&events);
let doc = document::document(&mut input, source, errors);
doc
}
pub(crate) fn parse_key(
source: toml_parser::Source<'_>,
errors: &mut dyn prelude::ErrorSink,
) -> crate::Key {
let tokens = source.lex().into_vec();
let mut events = Vec::with_capacity(tokens.len());
let mut receiver = ValidateWhitespace::new(&mut events, source);
#[cfg(not(feature = "unbounded"))]
let mut receiver = RecursionGuard::new(&mut receiver, LIMIT);
#[cfg(not(feature = "unbounded"))]
let receiver = &mut receiver;
#[cfg(feature = "unbounded")]
let receiver = &mut receiver;
toml_parser::parser::parse_simple_key(&tokens, receiver, errors);
if let Some(event) = events
.iter()
.find(|e| e.kind() == toml_parser::parser::EventKind::SimpleKey)
{
let (raw, key) = key::on_simple_key(event, source, errors);
crate::Key::new(key).with_repr_unchecked(crate::Repr::new_unchecked(raw))
} else {
let key = source.input();
let raw = RawString::with_span(0..source.input().len());
crate::Key::new(key).with_repr_unchecked(crate::Repr::new_unchecked(raw))
}
}
pub(crate) fn parse_key_path(
source: toml_parser::Source<'_>,
errors: &mut dyn prelude::ErrorSink,
) -> Vec<crate::Key> {
let tokens = source.lex().into_vec();
let mut events = Vec::with_capacity(tokens.len());
let mut receiver = ValidateWhitespace::new(&mut events, source);
#[cfg(not(feature = "unbounded"))]
let mut receiver = RecursionGuard::new(&mut receiver, LIMIT);
#[cfg(not(feature = "unbounded"))]
let receiver = &mut receiver;
#[cfg(feature = "unbounded")]
let receiver = &mut receiver;
toml_parser::parser::parse_key(&tokens, receiver, errors);
let mut input = prelude::Input::new(&events);
let mut prefix = None;
let mut path = None;
let mut key = None;
let mut suffix = None;
while let Some(event) = input.next_token() {
match event.kind() {
toml_parser::parser::EventKind::Whitespace => {
let raw = RawString::with_span(event.span().start()..event.span().end());
if prefix.is_none() {
prefix = Some(raw);
} else if suffix.is_none() {
suffix = Some(raw);
}
}
_ => {
let (local_path, local_key) = key::on_key(event, &mut input, source, errors);
path = Some(local_path);
key = local_key;
}
}
}
if let Some(mut key) = key {
if let Some(prefix) = prefix {
key.leaf_decor.set_prefix(prefix);
}
if let Some(suffix) = suffix {
key.leaf_decor.set_suffix(suffix);
}
let mut path = path.unwrap_or_default();
path.push(key);
path
} else {
Default::default()
}
}
pub(crate) fn parse_value(
source: toml_parser::Source<'_>,
errors: &mut dyn prelude::ErrorSink,
) -> crate::Value {
let tokens = source.lex().into_vec();
let mut events = Vec::with_capacity(tokens.len());
let mut receiver = ValidateWhitespace::new(&mut events, source);
#[cfg(not(feature = "unbounded"))]
let mut receiver = RecursionGuard::new(&mut receiver, LIMIT);
#[cfg(not(feature = "unbounded"))]
let receiver = &mut receiver;
#[cfg(feature = "unbounded")]
let receiver = &mut receiver;
toml_parser::parser::parse_value(&tokens, receiver, errors);
let mut input = prelude::Input::new(&events);
let value = value::value(&mut input, source, errors);
value
}
#[cfg(not(feature = "unbounded"))]
const LIMIT: u32 = 80;
pub(crate) mod prelude {
pub(crate) use toml_parser::parser::EventKind;
pub(crate) use toml_parser::ErrorSink;
pub(crate) use toml_parser::ParseError;
pub(crate) use winnow::stream::Stream as _;
pub(crate) type Input<'i> = winnow::stream::TokenSlice<'i, toml_parser::parser::Event>;
#[cfg(feature = "debug")]
pub(crate) use super::debug::trace;
#[cfg(feature = "debug")]
pub(crate) use super::debug::TraceScope;
}

147
vendor/toml_edit/src/parser/value.rs vendored Normal file
View File

@@ -0,0 +1,147 @@
use crate::parser::array::on_array;
use crate::parser::inline_table::on_inline_table;
use crate::parser::prelude::*;
use crate::repr::{Formatted, Repr};
use crate::RawString;
use crate::Value;
/// ```bnf
/// val = string / boolean / array / inline-table / date-time / float / integer
/// ```
pub(crate) fn value(
input: &mut Input<'_>,
source: toml_parser::Source<'_>,
errors: &mut dyn ErrorSink,
) -> Value {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("value");
if let Some(event) = input.next_token() {
match event.kind() {
EventKind::StdTableOpen
| EventKind::ArrayTableOpen
| EventKind::InlineTableClose
| EventKind::ArrayClose
| EventKind::ValueSep
| EventKind::Comment
| EventKind::Newline
| EventKind::Error
| EventKind::SimpleKey
| EventKind::KeySep
| EventKind::KeyValSep
| EventKind::StdTableClose
| EventKind::ArrayTableClose => {
#[cfg(feature = "debug")]
trace(
&format!("unexpected {event:?}"),
anstyle::AnsiColor::Red.on_default(),
);
}
EventKind::Whitespace => {
#[cfg(feature = "debug")]
trace(
&format!("unexpected {event:?}"),
anstyle::AnsiColor::Red.on_default(),
);
}
EventKind::InlineTableOpen => {
return on_inline_table(event, input, source, errors);
}
EventKind::ArrayOpen => {
return on_array(event, input, source, errors);
}
EventKind::Scalar => {
return on_scalar(event, source, errors);
}
}
}
Value::from(0)
}
pub(crate) fn on_scalar(
event: &toml_parser::parser::Event,
source: toml_parser::Source<'_>,
errors: &mut dyn ErrorSink,
) -> Value {
#[cfg(feature = "debug")]
let _scope = TraceScope::new("on_scalar");
let value_span = event.span();
let value_raw = RawString::with_span(value_span.start()..value_span.end());
let raw = source.get(event).unwrap();
let mut decoded = std::borrow::Cow::Borrowed("");
let kind = raw.decode_scalar(&mut decoded, errors);
match kind {
toml_parser::decoder::ScalarKind::String => {
let mut f = Formatted::new(decoded.into());
f.set_repr_unchecked(Repr::new_unchecked(value_raw));
Value::String(f)
}
toml_parser::decoder::ScalarKind::Boolean(value) => {
let mut f = Formatted::new(value);
f.set_repr_unchecked(Repr::new_unchecked(value_raw));
Value::Boolean(f)
}
toml_parser::decoder::ScalarKind::DateTime => {
let value = match decoded.parse::<toml_datetime::Datetime>() {
Ok(value) => value,
Err(err) => {
errors.report_error(
ParseError::new(err.to_string()).with_unexpected(event.span()),
);
toml_datetime::Datetime {
date: None,
time: None,
offset: None,
}
}
};
let mut f = Formatted::new(value);
f.set_repr_unchecked(Repr::new_unchecked(value_raw));
Value::Datetime(f)
}
toml_parser::decoder::ScalarKind::Float => {
let value = match decoded.parse::<f64>() {
Ok(value) => {
if value.is_infinite()
&& !(decoded
.strip_prefix(['+', '-'])
.unwrap_or(&decoded)
.chars()
.all(|c| c.is_ascii_alphabetic()))
{
errors.report_error(
ParseError::new("floating-point number overflowed")
.with_unexpected(event.span()),
);
}
value
}
Err(_) => {
errors.report_error(
ParseError::new(kind.invalid_description()).with_unexpected(event.span()),
);
f64::NAN
}
};
let mut f = Formatted::new(value);
f.set_repr_unchecked(Repr::new_unchecked(value_raw));
Value::Float(f)
}
toml_parser::decoder::ScalarKind::Integer(radix) => {
let value = match i64::from_str_radix(&decoded, radix.value()) {
Ok(value) => value,
Err(_) => {
// Assuming the decoder fully validated it, leaving only overflow errors
errors.report_error(
ParseError::new("integer number overflowed").with_unexpected(event.span()),
);
i64::MAX
}
};
let mut f = Formatted::new(value);
f.set_repr_unchecked(Repr::new_unchecked(value_raw));
Value::Integer(f)
}
}
}

168
vendor/toml_edit/src/raw_string.rs vendored Normal file
View File

@@ -0,0 +1,168 @@
/// Opaque string storage for raw TOML; internal to `toml_edit`
#[derive(PartialEq, Eq, Clone, Hash)]
pub struct RawString(RawStringInner);
#[derive(PartialEq, Eq, Clone, Hash)]
enum RawStringInner {
Empty,
Explicit(String),
Spanned(std::ops::Range<usize>),
}
impl RawString {
pub(crate) fn with_span(span: std::ops::Range<usize>) -> Self {
Self(RawStringInner::Spanned(span))
}
/// Access the underlying string
///
/// This generally requires a [`DocumentMut`][crate::DocumentMut].
pub fn as_str(&self) -> Option<&str> {
match &self.0 {
RawStringInner::Empty => Some(""),
RawStringInner::Explicit(s) => Some(s.as_str()),
RawStringInner::Spanned(_) => None,
}
}
/// The location within the original document
///
/// This generally requires a [`Document`][crate::Document].
pub fn span(&self) -> Option<std::ops::Range<usize>> {
match &self.0 {
RawStringInner::Empty => None,
RawStringInner::Explicit(_) => None,
RawStringInner::Spanned(span) => Some(span.clone()),
}
}
pub(crate) fn to_str<'s>(&'s self, input: &'s str) -> &'s str {
match &self.0 {
RawStringInner::Empty => "",
RawStringInner::Explicit(s) => s.as_str(),
RawStringInner::Spanned(span) => input
.get(span.clone())
.unwrap_or_else(|| panic!("span {span:?} should be in input:\n```\n{input}\n```")),
}
}
pub(crate) fn to_str_with_default<'s>(
&'s self,
input: Option<&'s str>,
default: &'s str,
) -> &'s str {
match &self.0 {
RawStringInner::Empty => "",
RawStringInner::Explicit(s) => s.as_str(),
RawStringInner::Spanned(span) => {
if let Some(input) = input {
input.get(span.clone()).unwrap_or_else(|| {
panic!("span {span:?} should be in input:\n```\n{input}\n```")
})
} else {
default
}
}
}
}
pub(crate) fn despan(&mut self, input: &str) {
match &self.0 {
RawStringInner::Empty => {}
RawStringInner::Explicit(_) => {}
RawStringInner::Spanned(span) => {
if span.start == span.end {
*self = Self(RawStringInner::Empty);
} else {
*self = Self::from(input.get(span.clone()).unwrap_or_else(|| {
panic!("span {span:?} should be in input:\n```\n{input}\n```")
}));
}
}
}
}
#[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') {
write!(buf, "{part}")?;
}
Ok(())
}
#[cfg(feature = "display")]
pub(crate) fn encode_with_default(
&self,
buf: &mut dyn std::fmt::Write,
input: Option<&str>,
default: &str,
) -> std::fmt::Result {
let raw = self.to_str_with_default(input, default);
for part in raw.split('\r') {
write!(buf, "{part}")?;
}
Ok(())
}
}
impl Default for RawString {
fn default() -> Self {
Self(RawStringInner::Empty)
}
}
impl std::fmt::Debug for RawString {
#[inline]
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
match &self.0 {
RawStringInner::Empty => write!(formatter, "empty"),
RawStringInner::Explicit(s) => write!(formatter, "{s:?}"),
RawStringInner::Spanned(s) => write!(formatter, "{s:?}"),
}
}
}
impl From<&str> for RawString {
#[inline]
fn from(s: &str) -> Self {
if s.is_empty() {
Self(RawStringInner::Empty)
} else {
String::from(s).into()
}
}
}
impl From<String> for RawString {
#[inline]
fn from(s: String) -> Self {
if s.is_empty() {
Self(RawStringInner::Empty)
} else {
Self(RawStringInner::Explicit(s))
}
}
}
impl From<&String> for RawString {
#[inline]
fn from(s: &String) -> Self {
if s.is_empty() {
Self(RawStringInner::Empty)
} else {
String::from(s).into()
}
}
}
impl From<Box<str>> for RawString {
#[inline]
fn from(s: Box<str>) -> Self {
if s.is_empty() {
Self(RawStringInner::Empty)
} else {
String::from(s).into()
}
}
}

276
vendor/toml_edit/src/repr.rs vendored Normal file
View File

@@ -0,0 +1,276 @@
use std::borrow::Cow;
use crate::RawString;
/// A scalar TOML [`Value`][crate::Value]'s logical value and its representation in a `&str`
///
/// This includes the surrounding whitespace and comments.
#[derive(Eq, PartialEq, Clone, Hash)]
pub struct Formatted<T> {
value: T,
repr: Option<Repr>,
decor: Decor,
}
impl<T> Formatted<T>
where
T: ValueRepr,
{
/// Default-formatted value
pub fn new(value: T) -> Self {
Self {
value,
repr: None,
decor: Default::default(),
}
}
pub(crate) fn set_repr_unchecked(&mut self, repr: Repr) {
self.repr = Some(repr);
}
/// The wrapped value
pub fn value(&self) -> &T {
&self.value
}
/// The wrapped value
pub fn into_value(self) -> T {
self.value
}
/// Returns the raw representation, if available.
pub fn as_repr(&self) -> Option<&Repr> {
self.repr.as_ref()
}
/// 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())
.map(Cow::Borrowed)
.unwrap_or_else(|| {
Cow::Owned(self.default_repr().as_raw().as_str().unwrap().to_owned())
})
}
/// The location within the original document
///
/// This generally requires a [`Document`][crate::Document].
pub fn span(&self) -> Option<std::ops::Range<usize>> {
self.repr.as_ref().and_then(|r| r.span())
}
pub(crate) fn despan(&mut self, input: &str) {
self.decor.despan(input);
if let Some(repr) = &mut self.repr {
repr.despan(input);
}
}
/// Returns the surrounding whitespace
pub fn decor_mut(&mut self) -> &mut Decor {
&mut self.decor
}
/// Returns the surrounding whitespace
pub fn decor(&self) -> &Decor {
&self.decor
}
/// Auto formats the value.
pub fn fmt(&mut self) {
self.repr = None;
}
}
impl<T> std::fmt::Debug for Formatted<T>
where
T: std::fmt::Debug,
{
#[inline]
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
let mut d = formatter.debug_struct("Formatted");
d.field("value", &self.value);
match &self.repr {
Some(r) => d.field("repr", r),
None => d.field("repr", &"default"),
};
d.field("decor", &self.decor);
d.finish()
}
}
#[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_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 {}
}
/// A TOML [`Value`][crate::Value] encoded as a `&str`
#[derive(Eq, PartialEq, Clone, Hash)]
pub struct Repr {
raw_value: RawString,
}
impl Repr {
pub(crate) fn new_unchecked(raw: impl Into<RawString>) -> Self {
Self {
raw_value: raw.into(),
}
}
/// Access the underlying value
pub fn as_raw(&self) -> &RawString {
&self.raw_value
}
/// The location within the original document
///
/// This generally requires a [`Document`][crate::Document].
pub fn span(&self) -> Option<std::ops::Range<usize>> {
self.raw_value.span()
}
pub(crate) fn despan(&mut self, input: &str) {
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)
}
}
impl std::fmt::Debug for Repr {
#[inline]
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
self.raw_value.fmt(formatter)
}
}
/// A prefix and suffix,
///
/// Including comments, whitespaces and newlines.
#[derive(Eq, PartialEq, Clone, Default, Hash)]
pub struct Decor {
prefix: Option<RawString>,
suffix: Option<RawString>,
}
impl Decor {
/// Creates a new decor from the given prefix and suffix.
pub fn new(prefix: impl Into<RawString>, suffix: impl Into<RawString>) -> Self {
Self {
prefix: Some(prefix.into()),
suffix: Some(suffix.into()),
}
}
/// Go back to default decor
pub fn clear(&mut self) {
self.prefix = None;
self.suffix = None;
}
/// Get the prefix.
pub fn prefix(&self) -> Option<&RawString> {
self.prefix.as_ref()
}
#[cfg(feature = "display")]
pub(crate) fn prefix_encode(
&self,
buf: &mut dyn std::fmt::Write,
input: Option<&str>,
default: &str,
) -> std::fmt::Result {
if let Some(prefix) = self.prefix() {
prefix.encode_with_default(buf, input, default)
} else {
write!(buf, "{default}")
}
}
/// Set the prefix.
pub fn set_prefix(&mut self, prefix: impl Into<RawString>) {
self.prefix = Some(prefix.into());
}
/// Get the suffix.
pub fn suffix(&self) -> Option<&RawString> {
self.suffix.as_ref()
}
#[cfg(feature = "display")]
pub(crate) fn suffix_encode(
&self,
buf: &mut dyn std::fmt::Write,
input: Option<&str>,
default: &str,
) -> std::fmt::Result {
if let Some(suffix) = self.suffix() {
suffix.encode_with_default(buf, input, default)
} else {
write!(buf, "{default}")
}
}
/// Set the suffix.
pub fn set_suffix(&mut self, suffix: impl Into<RawString>) {
self.suffix = Some(suffix.into());
}
pub(crate) fn despan(&mut self, input: &str) {
if let Some(prefix) = &mut self.prefix {
prefix.despan(input);
}
if let Some(suffix) = &mut self.suffix {
suffix.despan(input);
}
}
}
impl std::fmt::Debug for Decor {
#[inline]
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
let mut d = formatter.debug_struct("Decor");
match &self.prefix {
Some(r) => d.field("prefix", r),
None => d.field("prefix", &"default"),
};
match &self.suffix {
Some(r) => d.field("suffix", r),
None => d.field("suffix", &"default"),
};
d.finish()
}
}

102
vendor/toml_edit/src/ser/array.rs vendored Normal file
View File

@@ -0,0 +1,102 @@
use super::Error;
#[doc(hidden)]
pub struct SerializeValueArray {
values: Vec<crate::Item>,
}
impl SerializeValueArray {
pub(crate) fn seq(len: Option<usize>) -> Self {
let mut values = Vec::new();
if let Some(len) = len {
values.reserve(len);
}
Self { values }
}
}
impl serde_core::ser::SerializeSeq for SerializeValueArray {
type Ok = crate::Value;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
let value = value.serialize(super::ValueSerializer {})?;
self.values.push(crate::Item::Value(value));
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(crate::Value::Array(crate::Array::with_vec(self.values)))
}
}
impl serde_core::ser::SerializeTuple for SerializeValueArray {
type Ok = crate::Value;
type Error = Error;
fn serialize_element<T>(&mut self, value: &T) -> Result<(), Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
serde_core::ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
serde_core::ser::SerializeSeq::end(self)
}
}
impl serde_core::ser::SerializeTupleStruct for SerializeValueArray {
type Ok = crate::Value;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
serde_core::ser::SerializeSeq::serialize_element(self, value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
serde_core::ser::SerializeSeq::end(self)
}
}
pub struct SerializeTupleVariant {
variant: &'static str,
inner: SerializeValueArray,
}
impl SerializeTupleVariant {
pub(crate) fn tuple(variant: &'static str, len: usize) -> Self {
Self {
variant,
inner: SerializeValueArray::seq(Some(len)),
}
}
}
impl serde_core::ser::SerializeTupleVariant for SerializeTupleVariant {
type Ok = crate::Value;
type Error = Error;
fn serialize_field<T>(&mut self, value: &T) -> Result<(), Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
serde_core::ser::SerializeSeq::serialize_element(&mut self.inner, value)
}
fn end(self) -> Result<Self::Ok, Self::Error> {
let inner = serde_core::ser::SerializeSeq::end(self.inner)?;
let mut items = crate::table::KeyValuePairs::new();
let value = crate::Item::Value(inner);
items.insert(crate::Key::new(self.variant), value);
Ok(crate::Value::InlineTable(crate::InlineTable::with_pairs(
items,
)))
}
}

84
vendor/toml_edit/src/ser/error.rs vendored Normal file
View File

@@ -0,0 +1,84 @@
/// Errors that can occur when deserializing a type.
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
#[non_exhaustive]
pub enum Error {
/// Type could not be serialized to TOML
UnsupportedType(Option<&'static str>),
/// Value was out of range for the given type
OutOfRange(Option<&'static str>),
/// `None` could not be serialized to TOML
UnsupportedNone,
/// Key was not convertible to `String` for serializing to TOML
KeyNotString,
/// A serialized date was invalid
DateInvalid,
/// Other serialization error
Custom(String),
}
impl Error {
pub(crate) fn custom<T>(msg: T) -> Self
where
T: std::fmt::Display,
{
Self::Custom(msg.to_string())
}
pub(crate) fn unsupported_type(t: Option<&'static str>) -> Self {
Self::UnsupportedType(t)
}
pub(crate) fn out_of_range(t: Option<&'static str>) -> Self {
Self::OutOfRange(t)
}
pub(crate) fn unsupported_none() -> Self {
Self::UnsupportedNone
}
pub(crate) fn key_not_string() -> Self {
Self::KeyNotString
}
pub(crate) fn date_invalid() -> Self {
Self::DateInvalid
}
}
impl serde_core::ser::Error for Error {
fn custom<T>(msg: T) -> Self
where
T: std::fmt::Display,
{
Self::custom(msg)
}
}
impl std::fmt::Display for Error {
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::UnsupportedType(Some(t)) => write!(formatter, "unsupported {t} type"),
Self::UnsupportedType(None) => write!(formatter, "unsupported rust type"),
Self::OutOfRange(Some(t)) => write!(formatter, "out-of-range value for {t} type"),
Self::OutOfRange(None) => write!(formatter, "out-of-range value"),
Self::UnsupportedNone => "unsupported None value".fmt(formatter),
Self::KeyNotString => "map key was not a string".fmt(formatter),
Self::DateInvalid => "a serialized date was invalid".fmt(formatter),
Self::Custom(s) => s.fmt(formatter),
}
}
}
impl From<crate::TomlError> for Error {
fn from(e: crate::TomlError) -> Self {
Self::custom(e)
}
}
impl From<Error> for crate::TomlError {
fn from(e: Error) -> Self {
Self::custom(e.to_string(), None)
}
}
impl std::error::Error for Error {}

173
vendor/toml_edit/src/ser/key.rs vendored Normal file
View File

@@ -0,0 +1,173 @@
use crate::Key;
use super::Error;
pub(crate) struct KeySerializer;
impl serde_core::ser::Serializer for KeySerializer {
type Ok = Key;
type Error = Error;
type SerializeSeq = serde_core::ser::Impossible<Self::Ok, Error>;
type SerializeTuple = serde_core::ser::Impossible<Self::Ok, Error>;
type SerializeTupleStruct = serde_core::ser::Impossible<Self::Ok, Error>;
type SerializeTupleVariant = serde_core::ser::Impossible<Self::Ok, Error>;
type SerializeMap = serde_core::ser::Impossible<Self::Ok, Error>;
type SerializeStruct = serde_core::ser::Impossible<Self::Ok, Error>;
type SerializeStructVariant = serde_core::ser::Impossible<Self::Ok, Error>;
fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error> {
Ok(Key::new(value))
}
fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_some<T>(self, _value: &T) -> Result<Self::Ok, Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
Err(Error::key_not_string())
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
Ok(variant.into())
}
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
Err(Error::key_not_string())
}
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_tuple_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_struct(
self,
_name: &'static str,
_len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
Err(Error::key_not_string())
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
_variant: &'static str,
_len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
Err(Error::key_not_string())
}
}

445
vendor/toml_edit/src/ser/map.rs vendored Normal file
View File

@@ -0,0 +1,445 @@
use super::array::SerializeTupleVariant;
use super::array::SerializeValueArray;
use super::key::KeySerializer;
use super::value::ValueSerializer;
use super::Error;
#[doc(hidden)]
#[allow(clippy::large_enum_variant)]
pub enum SerializeMap {
Datetime(SerializeDatetime),
Table(SerializeInlineTable),
}
impl SerializeMap {
pub(crate) fn map(len: Option<usize>) -> Self {
Self::Table(SerializeInlineTable::map(len))
}
pub(crate) fn struct_(name: &'static str, len: Option<usize>) -> Self {
if toml_datetime::ser::is_datetime(name) {
Self::Datetime(SerializeDatetime::new())
} else {
Self::map(len)
}
}
}
impl serde_core::ser::SerializeMap for SerializeMap {
type Ok = crate::Value;
type Error = Error;
fn serialize_key<T>(&mut self, input: &T) -> Result<(), Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
match self {
Self::Datetime(s) => s.serialize_key(input),
Self::Table(s) => s.serialize_key(input),
}
}
fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
match self {
Self::Datetime(s) => s.serialize_value(value),
Self::Table(s) => s.serialize_value(value),
}
}
fn end(self) -> Result<Self::Ok, Self::Error> {
match self {
Self::Datetime(s) => s.end().map(|items| items.into()),
Self::Table(s) => s.end().map(|items| items.into()),
}
}
}
impl serde_core::ser::SerializeStruct for SerializeMap {
type Ok = crate::Value;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
match self {
Self::Datetime(s) => s.serialize_field(key, value),
Self::Table(s) => s.serialize_field(key, value),
}
}
fn end(self) -> Result<Self::Ok, Self::Error> {
match self {
Self::Datetime(s) => s.end().map(|items| items.into()),
Self::Table(s) => s.end().map(|items| items.into()),
}
}
}
#[doc(hidden)]
pub struct SerializeDatetime {
inner: toml_datetime::ser::DatetimeSerializer,
}
impl SerializeDatetime {
pub(crate) fn new() -> Self {
Self {
inner: toml_datetime::ser::DatetimeSerializer::new(),
}
}
}
impl serde_core::ser::SerializeMap for SerializeDatetime {
type Ok = crate::Datetime;
type Error = Error;
fn serialize_key<T>(&mut self, _input: &T) -> Result<(), Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
unreachable!("datetimes should only be serialized as structs, not maps")
}
fn serialize_value<T>(&mut self, _value: &T) -> Result<(), Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
unreachable!("datetimes should only be serialized as structs, not maps")
}
fn end(self) -> Result<Self::Ok, Self::Error> {
unreachable!("datetimes should only be serialized as structs, not maps")
}
}
impl serde_core::ser::SerializeStruct for SerializeDatetime {
type Ok = crate::Datetime;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
self.inner.serialize_field(key, value).map_err(dt_err)?;
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
let value = self.inner.end().map_err(dt_err)?;
Ok(value)
}
}
fn dt_err(err: toml_datetime::ser::SerializerError) -> Error {
match err {
toml_datetime::ser::SerializerError::InvalidFormat(err) => Error::custom(err),
_ => Error::date_invalid(),
}
}
#[doc(hidden)]
pub struct SerializeInlineTable {
items: crate::table::KeyValuePairs,
key: Option<crate::Key>,
}
impl SerializeInlineTable {
pub(crate) fn map(len: Option<usize>) -> Self {
let mut items: crate::table::KeyValuePairs = Default::default();
let key = Default::default();
if let Some(len) = len {
items.reserve(len);
}
Self { items, key }
}
}
impl serde_core::ser::SerializeMap for SerializeInlineTable {
type Ok = crate::InlineTable;
type Error = Error;
fn serialize_key<T>(&mut self, input: &T) -> Result<(), Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
self.key = Some(input.serialize(KeySerializer)?);
Ok(())
}
fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
let mut is_none = false;
let value_serializer = MapValueSerializer::new(&mut is_none);
let res = value.serialize(value_serializer);
match res {
Ok(item) => {
let key = self.key.take().unwrap();
let item = crate::Item::Value(item);
self.items.insert(key, item);
}
Err(e) => {
if !(e == Error::unsupported_none() && is_none) {
return Err(e);
}
}
}
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(crate::InlineTable::with_pairs(self.items))
}
}
impl serde_core::ser::SerializeStruct for SerializeInlineTable {
type Ok = crate::InlineTable;
type Error = Error;
fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
let mut is_none = false;
let value_serializer = MapValueSerializer::new(&mut is_none);
let res = value.serialize(value_serializer);
match res {
Ok(item) => {
let item = crate::Item::Value(item);
self.items.insert(crate::Key::new(key), item);
}
Err(e) => {
if !(e == Error::unsupported_none() && is_none) {
return Err(e);
}
}
};
Ok(())
}
fn end(self) -> Result<Self::Ok, Self::Error> {
Ok(crate::InlineTable::with_pairs(self.items))
}
}
struct MapValueSerializer<'d> {
is_none: &'d mut bool,
}
impl<'d> MapValueSerializer<'d> {
fn new(is_none: &'d mut bool) -> Self {
Self { is_none }
}
}
impl serde_core::ser::Serializer for MapValueSerializer<'_> {
type Ok = crate::Value;
type Error = Error;
type SerializeSeq = SerializeValueArray;
type SerializeTuple = SerializeValueArray;
type SerializeTupleStruct = SerializeValueArray;
type SerializeTupleVariant = SerializeTupleVariant;
type SerializeMap = SerializeMap;
type SerializeStruct = SerializeMap;
type SerializeStructVariant = 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::unsupported_none())
}
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
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>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
name: &'static str,
variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
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 struct SerializeStructVariant {
variant: &'static str,
inner: SerializeInlineTable,
}
impl SerializeStructVariant {
pub(crate) fn struct_(variant: &'static str, len: usize) -> Self {
Self {
variant,
inner: SerializeInlineTable::map(Some(len)),
}
}
}
impl serde_core::ser::SerializeStructVariant for SerializeStructVariant {
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_core::ser::Serialize + ?Sized,
{
serde_core::ser::SerializeStruct::serialize_field(&mut self.inner, key, value)
}
#[inline]
fn end(self) -> Result<Self::Ok, Self::Error> {
let inner = serde_core::ser::SerializeStruct::end(self.inner)?.into();
let mut items = crate::table::KeyValuePairs::new();
let value = crate::Item::Value(inner);
items.insert(crate::Key::new(self.variant), value);
Ok(crate::Value::InlineTable(crate::InlineTable::with_pairs(
items,
)))
}
}

105
vendor/toml_edit/src/ser/mod.rs vendored Normal file
View File

@@ -0,0 +1,105 @@
//! Serializing Rust structures into TOML.
//!
//! This module contains all the Serde support for serializing Rust structures into TOML.
mod array;
mod error;
mod key;
mod map;
mod pretty;
mod value;
use crate::visit_mut::VisitMut as _;
#[allow(clippy::wildcard_imports)]
use array::*;
#[allow(clippy::wildcard_imports)]
use map::*;
pub use error::Error;
pub use value::ValueSerializer;
/// Serialize the given data structure as a TOML byte vector.
///
/// 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>(value: &T) -> Result<Vec<u8>, Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
to_string(value).map(|e| e.into_bytes())
}
/// Serialize the given data structure as a String of TOML.
///
/// Serialization can fail if `T`'s implementation of `Serialize` decides to
/// fail, if `T` contains a map with non-string keys, or if `T` attempts to
/// serialize an unsupported datatype such as an enum, tuple, or tuple struct.
///
/// # Examples
///
/// ```
/// use serde::Serialize;
///
/// #[derive(Serialize)]
/// struct Config {
/// database: Database,
/// }
///
/// #[derive(Serialize)]
/// struct Database {
/// ip: String,
/// port: Vec<u16>,
/// connection_max: u32,
/// enabled: bool,
/// }
///
/// let config = Config {
/// database: Database {
/// ip: "192.168.1.1".to_string(),
/// port: vec![8001, 8002, 8003],
/// connection_max: 5000,
/// enabled: false,
/// },
/// };
///
/// let toml = toml_edit::ser::to_string(&config).unwrap();
/// println!("{}", toml)
/// ```
#[cfg(feature = "display")]
pub fn to_string<T>(value: &T) -> Result<String, Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
to_document(value).map(|e| e.to_string())
}
/// Serialize the given data structure as a "pretty" String of TOML.
///
/// This is identical to `to_string` except the output string has a more
/// "pretty" output. See `ValueSerializer::pretty` for more details.
#[cfg(feature = "display")]
pub fn to_string_pretty<T>(value: &T) -> Result<String, Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
let mut document = to_document(value)?;
pretty::Pretty::new().visit_document_mut(&mut document);
Ok(document.to_string())
}
/// Serialize the given data structure into a TOML document.
///
/// This would allow custom formatting to be applied, mixing with format preserving edits, etc.
pub fn to_document<T>(value: &T) -> Result<crate::DocumentMut, Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
let value = value.serialize(ValueSerializer::new())?;
let item = crate::Item::Value(value);
let root = item
.into_table()
.map_err(|_| Error::UnsupportedType(None))?;
Ok(root.into())
}

58
vendor/toml_edit/src/ser/pretty.rs vendored Normal file
View File

@@ -0,0 +1,58 @@
pub(crate) struct Pretty {
in_value: bool,
}
impl Pretty {
pub(crate) fn new() -> Self {
Self { in_value: false }
}
}
impl crate::visit_mut::VisitMut for Pretty {
fn visit_document_mut(&mut self, node: &mut crate::DocumentMut) {
crate::visit_mut::visit_document_mut(self, node);
}
fn visit_item_mut(&mut self, node: &mut crate::Item) {
if !self.in_value {
node.make_item();
}
crate::visit_mut::visit_item_mut(self, node);
}
fn visit_table_mut(&mut self, node: &mut crate::Table) {
node.decor_mut().clear();
// Empty tables could be semantically meaningful, so make sure they are not implicit
if !node.is_empty() {
node.set_implicit(true);
}
crate::visit_mut::visit_table_mut(self, node);
}
fn visit_value_mut(&mut self, node: &mut crate::Value) {
node.decor_mut().clear();
let old_in_value = self.in_value;
self.in_value = true;
crate::visit_mut::visit_value_mut(self, node);
self.in_value = old_in_value;
}
fn visit_array_mut(&mut self, node: &mut crate::Array) {
crate::visit_mut::visit_array_mut(self, node);
if (0..=1).contains(&node.len()) {
node.set_trailing("");
node.set_trailing_comma(false);
} else {
for item in node.iter_mut() {
item.decor_mut().set_prefix("\n ");
}
node.set_trailing("\n");
node.set_trailing_comma(true);
}
}
}

249
vendor/toml_edit/src/ser/value.rs vendored Normal file
View File

@@ -0,0 +1,249 @@
use super::Error;
use super::SerializeMap;
use super::SerializeStructVariant;
use super::SerializeTupleVariant;
use super::SerializeValueArray;
/// Serialization for TOML [values][crate::Value].
///
/// This structure implements serialization support for TOML to serialize an
/// arbitrary type to TOML. Note that the TOML format does not support all
/// datatypes in Rust, such as enums, tuples, and tuple structs. These types
/// will generate an error when serialized.
///
/// Currently a serializer always writes its output to an in-memory `String`,
/// which is passed in when creating the serializer itself.
///
/// # Examples
///
/// ```
/// # #[cfg(feature = "parse")] {
/// # #[cfg(feature = "display")] {
/// use serde::Serialize;
///
/// #[derive(Serialize)]
/// struct Config {
/// database: Database,
/// }
///
/// #[derive(Serialize)]
/// struct Database {
/// ip: String,
/// port: Vec<u16>,
/// connection_max: u32,
/// enabled: bool,
/// }
///
/// let config = Config {
/// database: Database {
/// ip: "192.168.1.1".to_string(),
/// port: vec![8001, 8002, 8003],
/// connection_max: 5000,
/// enabled: false,
/// },
/// };
///
/// let value = serde::Serialize::serialize(
/// &config,
/// toml_edit::ser::ValueSerializer::new()
/// ).unwrap();
/// println!("{}", value)
/// # }
/// # }
/// ```
#[derive(Default)]
#[non_exhaustive]
pub struct ValueSerializer {}
impl ValueSerializer {
/// Creates a new serializer generate a TOML document.
pub fn new() -> Self {
Self {}
}
}
impl serde_core::ser::Serializer for ValueSerializer {
type Ok = crate::Value;
type Error = Error;
type SerializeSeq = SerializeValueArray;
type SerializeTuple = SerializeValueArray;
type SerializeTupleStruct = SerializeValueArray;
type SerializeTupleVariant = SerializeTupleVariant;
type SerializeMap = SerializeMap;
type SerializeStruct = SerializeMap;
type SerializeStructVariant = SerializeStructVariant;
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
Ok(v.into())
}
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
Ok(v.into())
}
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
self.serialize_i64(v as i64)
}
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
let v: i64 = v
.try_into()
.map_err(|_err| Error::out_of_range(Some("u64")))?;
self.serialize_i64(v)
}
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
self.serialize_f64(v as f64)
}
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())
}
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
let mut buf = [0; 4];
self.serialize_str(v.encode_utf8(&mut buf))
}
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
Ok(v.into())
}
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
use serde_core::ser::Serialize;
value.serialize(self)
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
Err(Error::unsupported_none())
}
fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
value.serialize(self)
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(Error::unsupported_type(Some("unit")))
}
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
Err(Error::unsupported_type(Some(name)))
}
fn serialize_unit_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
self.serialize_str(variant)
}
fn serialize_newtype_struct<T>(
self,
_name: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
value.serialize(self)
}
fn serialize_newtype_variant<T>(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<Self::Ok, Self::Error>
where
T: serde_core::ser::Serialize + ?Sized,
{
let value = value.serialize(self)?;
let mut table = crate::InlineTable::new();
table.insert(variant, value);
Ok(table.into())
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
Ok(SerializeValueArray::seq(len))
}
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_struct(
self,
_name: &'static str,
len: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
self.serialize_seq(Some(len))
}
fn serialize_tuple_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
Ok(SerializeTupleVariant::tuple(variant, len))
}
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
Ok(SerializeMap::map(len))
}
fn serialize_struct(
self,
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
Ok(SerializeMap::struct_(name, Some(len)))
}
fn serialize_struct_variant(
self,
_name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
Ok(SerializeStructVariant::struct_(variant, len))
}
}

815
vendor/toml_edit/src/table.rs vendored Normal file
View File

@@ -0,0 +1,815 @@
use std::iter::FromIterator;
use indexmap::map::IndexMap;
use crate::key::Key;
use crate::repr::Decor;
use crate::value::DEFAULT_VALUE_DECOR;
use crate::{InlineTable, Item, KeyMut, Value};
/// A TOML table, a top-level collection of key/[`Value`] pairs under a header and logical
/// sub-tables
#[derive(Clone, Debug, Default)]
pub struct Table {
// Comments/spaces before and after the header
pub(crate) decor: Decor,
// Whether to hide an empty table
pub(crate) implicit: bool,
// Whether this is a proxy for dotted keys
pub(crate) dotted: bool,
// Used for putting tables back in their original order when serialising.
//
// `None` for user created tables (can be overridden with `set_position`)
doc_position: Option<isize>,
pub(crate) span: Option<std::ops::Range<usize>>,
pub(crate) items: KeyValuePairs,
}
/// Constructors
///
/// See also `FromIterator`
impl Table {
/// Creates an empty table.
pub fn new() -> Self {
Default::default()
}
pub(crate) fn with_pos(doc_position: Option<isize>) -> Self {
Self {
doc_position,
..Default::default()
}
}
pub(crate) fn with_pairs(items: KeyValuePairs) -> Self {
Self {
items,
..Default::default()
}
}
/// Convert to an inline table
pub fn into_inline_table(mut self) -> InlineTable {
for (_, value) in self.items.iter_mut() {
value.make_value();
}
let mut t = InlineTable::with_pairs(self.items);
t.fmt();
t
}
}
/// Formatting
impl Table {
/// Get key/values for values that are visually children of this table
///
/// For example, this will return dotted keys
pub fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
let mut values = Vec::new();
let root = Vec::new();
self.append_values(&root, &mut values);
values
}
fn append_values<'s>(
&'s self,
parent: &[&'s Key],
values: &mut Vec<(Vec<&'s Key>, &'s Value)>,
) {
for (key, value) in self.items.iter() {
let mut path = parent.to_vec();
path.push(key);
match value {
Item::Table(table) if table.is_dotted() => {
table.append_values(&path, values);
}
Item::Value(value) => {
if let Some(table) = value.as_inline_table() {
if table.is_dotted() {
table.append_values(&path, values);
} else {
values.push((path, value));
}
} else {
values.push((path, value));
}
}
_ => {}
}
}
}
pub(crate) fn append_all_values<'s>(
&'s self,
parent: &[&'s Key],
values: &mut Vec<(Vec<&'s Key>, &'s Value)>,
) {
for (key, value) in self.items.iter() {
let mut path = parent.to_vec();
path.push(key);
match value {
Item::Table(table) => {
table.append_all_values(&path, values);
}
Item::Value(value) => {
if let Some(table) = value.as_inline_table() {
if table.is_dotted() {
table.append_values(&path, values);
} else {
values.push((path, value));
}
} else {
values.push((path, value));
}
}
_ => {}
}
}
}
/// Auto formats the table.
pub fn fmt(&mut self) {
decorate_table(self);
}
/// Sorts [Key]/[Value]-pairs of the table
///
/// <div class="warning">
///
/// This sorts the syntactic table (everything under the `[header]`) and not the logical map of
/// key-value pairs.
/// This does not affect the order of [sub-tables][Table] or [sub-arrays][crate::ArrayOfTables].
/// This is not recursive.
///
/// </div>
pub fn sort_values(&mut self) {
// Assuming standard tables have their doc_position set and this won't negatively impact them
self.items.sort_keys();
for value in self.items.values_mut() {
match value {
Item::Table(table) if table.is_dotted() => {
table.sort_values();
}
_ => {}
}
}
}
/// Sort [Key]/[Value]-pairs of the table using the using the comparison function `compare`
///
/// The comparison function receives two key and value pairs to compare (you can sort by keys or
/// values or their combination as needed).
///
/// <div class="warning">
///
/// This sorts the syntactic table (everything under the `[header]`) and not the logical map of
/// key-value pairs.
/// This does not affect the order of [sub-tables][Table] or [sub-arrays][crate::ArrayOfTables].
/// This is not recursive.
///
/// </div>
pub fn sort_values_by<F>(&mut self, mut compare: F)
where
F: FnMut(&Key, &Item, &Key, &Item) -> std::cmp::Ordering,
{
self.sort_values_by_internal(&mut compare);
}
fn sort_values_by_internal<F>(&mut self, compare: &mut F)
where
F: FnMut(&Key, &Item, &Key, &Item) -> std::cmp::Ordering,
{
let modified_cmp =
|key1: &Key, val1: &Item, key2: &Key, val2: &Item| -> std::cmp::Ordering {
compare(key1, val1, key2, val2)
};
self.items.sort_by(modified_cmp);
for value in self.items.values_mut() {
match value {
Item::Table(table) if table.is_dotted() => {
table.sort_values_by_internal(compare);
}
_ => {}
}
}
}
/// 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::DocumentMut;
/// let mut doc = "[a]\n[a.b]\n".parse::<DocumentMut>().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;
}
/// If a table has no key/value pairs and implicit, it will not be displayed.
pub fn is_implicit(&self) -> bool {
self.implicit
}
/// Change this table's dotted status
pub fn set_dotted(&mut self, yes: bool) {
self.dotted = yes;
}
/// Check if this is a wrapper for dotted keys, rather than a standard table
pub fn is_dotted(&self) -> bool {
self.dotted
}
/// Sets the position of the `Table` within the [`DocumentMut`][crate::DocumentMut].
pub fn set_position(&mut self, doc_position: isize) {
self.doc_position = Some(doc_position);
}
/// The position of the `Table` within the [`DocumentMut`][crate::DocumentMut].
///
/// Returns `None` if the `Table` was created manually (i.e. not via parsing)
/// in which case its position is set automatically. This can be overridden with
/// [`Table::set_position`].
pub fn position(&self) -> Option<isize> {
self.doc_position
}
/// Returns the surrounding whitespace
pub fn decor_mut(&mut self) -> &mut Decor {
&mut self.decor
}
/// Returns the decor associated with a given key of the table.
pub fn decor(&self) -> &Decor {
&self.decor
}
/// Returns an accessor to a key's formatting
pub fn key(&self, key: &str) -> Option<&'_ Key> {
self.items.get_full(key).map(|(_, key, _)| key)
}
/// Returns an accessor to a key's formatting
pub fn key_mut(&mut self, key: &str) -> Option<KeyMut<'_>> {
use indexmap::map::MutableKeys;
self.items
.get_full_mut2(key)
.map(|(_, key, _)| key.as_mut())
}
/// The location within the original document
///
/// This generally requires a [`Document`][crate::Document].
pub fn span(&self) -> Option<std::ops::Range<usize>> {
self.span.clone()
}
pub(crate) fn despan(&mut self, input: &str) {
use indexmap::map::MutableKeys;
self.span = None;
self.decor.despan(input);
for (key, value) in self.items.iter_mut2() {
key.despan(input);
value.despan(input);
}
}
}
impl Table {
/// Returns an iterator over all key/value pairs, including empty.
pub fn iter(&self) -> Iter<'_> {
Box::new(
self.items
.iter()
.filter(|(_, value)| !value.is_none())
.map(|(key, value)| (key.get(), value)),
)
}
/// Returns an mutable iterator over all key/value pairs, including empty.
pub fn iter_mut(&mut self) -> IterMut<'_> {
use indexmap::map::MutableKeys;
Box::new(
self.items
.iter_mut2()
.filter(|(_, value)| !value.is_none())
.map(|(key, value)| (key.as_mut(), value)),
)
}
/// Returns the number of non-empty items in the table.
pub fn len(&self) -> usize {
self.iter().count()
}
/// Returns true if the table is empty.
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
pub fn clear(&mut self) {
self.items.clear();
}
/// Gets the given key's corresponding entry in the Table for in-place manipulation.
pub fn entry<'a>(&'a mut self, key: &str) -> Entry<'a> {
// Accept a `&str` rather than an owned type to keep `String`, well, internal
match self.items.entry(key.into()) {
indexmap::map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { entry }),
indexmap::map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { entry }),
}
}
/// Gets the given key's corresponding entry in the Table for in-place manipulation.
pub fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a> {
// Accept a `&Key` to be consistent with `entry`
match self.items.entry(key.clone()) {
indexmap::map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { entry }),
indexmap::map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry { entry }),
}
}
/// Returns an optional reference to an item given the key.
pub fn get<'a>(&'a self, key: &str) -> Option<&'a Item> {
self.items
.get(key)
.and_then(|value| if !value.is_none() { Some(value) } else { None })
}
/// Returns an optional mutable reference to an item given the key.
pub fn get_mut<'a>(&'a mut self, key: &str) -> Option<&'a mut Item> {
self.items
.get_mut(key)
.and_then(|value| if !value.is_none() { Some(value) } else { None })
}
/// Return references to the key-value pair stored for key, if it is present, else None.
pub fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
self.items.get_full(key).and_then(|(_, key, value)| {
if !value.is_none() {
Some((key, value))
} else {
None
}
})
}
/// Return mutable references to the key-value pair stored for key, if it is present, else None.
pub fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
use indexmap::map::MutableKeys;
self.items.get_full_mut2(key).and_then(|(_, key, value)| {
if !value.is_none() {
Some((key.as_mut(), value))
} else {
None
}
})
}
/// Returns true if the table contains an item with the given key.
pub fn contains_key(&self, key: &str) -> bool {
if let Some(value) = self.items.get(key) {
!value.is_none()
} else {
false
}
}
/// Returns true if the table contains a table with the given key.
pub fn contains_table(&self, key: &str) -> bool {
if let Some(value) = self.items.get(key) {
value.is_table()
} else {
false
}
}
/// Returns true if the table contains a value with the given key.
pub fn contains_value(&self, key: &str) -> bool {
if let Some(value) = self.items.get(key) {
value.is_value()
} else {
false
}
}
/// Returns true if the table contains an array of tables with the given key.
pub fn contains_array_of_tables(&self, key: &str) -> bool {
if let Some(value) = self.items.get(key) {
value.is_array_of_tables()
} else {
false
}
}
/// Inserts a key-value pair into the map.
pub fn insert(&mut self, key: &str, item: Item) -> Option<Item> {
use indexmap::map::MutableEntryKey;
let key = Key::new(key);
match self.items.entry(key.clone()) {
indexmap::map::Entry::Occupied(mut entry) => {
entry.key_mut().fmt();
let old = std::mem::replace(entry.get_mut(), item);
Some(old)
}
indexmap::map::Entry::Vacant(entry) => {
entry.insert(item);
None
}
}
}
/// Inserts a key-value pair into the map.
pub fn insert_formatted(&mut self, key: &Key, item: Item) -> Option<Item> {
use indexmap::map::MutableEntryKey;
match self.items.entry(key.clone()) {
indexmap::map::Entry::Occupied(mut entry) => {
*entry.key_mut() = key.clone();
let old = std::mem::replace(entry.get_mut(), item);
Some(old)
}
indexmap::map::Entry::Vacant(entry) => {
entry.insert(item);
None
}
}
}
/// Removes an item given the key.
pub fn remove(&mut self, key: &str) -> Option<Item> {
self.items.shift_remove(key)
}
/// Removes a key from the map, returning the stored key and value if the key was previously in the map.
pub fn remove_entry(&mut self, key: &str) -> Option<(Key, Item)> {
self.items.shift_remove_entry(key)
}
/// Retains only the elements specified by the `keep` predicate.
///
/// In other words, remove all pairs `(key, item)` for which
/// `keep(&key, &mut item)` returns `false`.
///
/// The elements are visited in iteration order.
pub fn retain<F>(&mut self, mut keep: F)
where
F: FnMut(&str, &mut Item) -> bool,
{
self.items.retain(|key, value| keep(key, value));
}
}
#[cfg(feature = "display")]
impl std::fmt::Display for Table {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let children = self.get_values();
// print table body
for (key_path, value) in children {
crate::encode::encode_key_path_ref(&key_path, f, None, DEFAULT_KEY_DECOR)?;
write!(f, "=")?;
crate::encode::encode_value(value, f, None, DEFAULT_VALUE_DECOR)?;
writeln!(f)?;
}
Ok(())
}
}
impl<K: Into<Key>, V: Into<Item>> Extend<(K, V)> for Table {
fn extend<T: IntoIterator<Item = (K, V)>>(&mut self, iter: T) {
for (key, value) in iter {
let key = key.into();
let value = value.into();
self.items.insert(key, value);
}
}
}
impl<K: Into<Key>, V: Into<Item>> FromIterator<(K, V)> for Table {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
{
let mut table = Self::new();
table.extend(iter);
table
}
}
impl IntoIterator for Table {
type Item = (String, Item);
type IntoIter = IntoIter;
fn into_iter(self) -> Self::IntoIter {
Box::new(self.items.into_iter().map(|(k, value)| (k.into(), value)))
}
}
impl<'s> IntoIterator for &'s Table {
type Item = (&'s str, &'s Item);
type IntoIter = Iter<'s>;
fn into_iter(self) -> Self::IntoIter {
self.iter()
}
}
pub(crate) type KeyValuePairs = IndexMap<Key, Item>;
fn decorate_table(table: &mut Table) {
use indexmap::map::MutableKeys;
for (mut key, value) in table
.items
.iter_mut2()
.filter(|(_, value)| value.is_value())
.map(|(key, value)| (key.as_mut(), value.as_value_mut().unwrap()))
{
key.leaf_decor_mut().clear();
key.dotted_decor_mut().clear();
value.decor_mut().clear();
}
}
// `key1 = value1`
pub(crate) const DEFAULT_ROOT_DECOR: (&str, &str) = ("", "");
pub(crate) const DEFAULT_KEY_DECOR: (&str, &str) = ("", " ");
pub(crate) const DEFAULT_TABLE_DECOR: (&str, &str) = ("\n", "");
pub(crate) const DEFAULT_KEY_PATH_DECOR: (&str, &str) = ("", "");
/// An owned iterator type over [`Table`]'s [`Key`]/[`Item`] pairs
pub type IntoIter = Box<dyn Iterator<Item = (String, Item)>>;
/// An iterator type over [`Table`]'s [`Key`]/[`Item`] pairs
pub type Iter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Item)> + 'a>;
/// A mutable iterator type over [`Table`]'s [`Key`]/[`Item`] pairs
pub type IterMut<'a> = Box<dyn Iterator<Item = (KeyMut<'a>, &'a mut Item)> + 'a>;
/// This trait represents either a `Table`, or an `InlineTable`.
pub trait TableLike: crate::private::Sealed {
/// Returns an iterator over key/value pairs.
fn iter(&self) -> Iter<'_>;
/// Returns an mutable iterator over all key/value pairs, including empty.
fn iter_mut(&mut self) -> IterMut<'_>;
/// Returns the number of nonempty items.
fn len(&self) -> usize {
self.iter().filter(|&(_, v)| !v.is_none()).count()
}
/// Returns true if the table is empty.
fn is_empty(&self) -> bool {
self.len() == 0
}
/// Clears the table, removing all key-value pairs. Keeps the allocated memory for reuse.
fn clear(&mut self);
/// Gets the given key's corresponding entry in the Table for in-place manipulation.
fn entry<'a>(&'a mut self, key: &str) -> Entry<'a>;
/// Gets the given key's corresponding entry in the Table for in-place manipulation.
fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a>;
/// Returns an optional reference to an item given the key.
fn get<'s>(&'s self, key: &str) -> Option<&'s Item>;
/// Returns an optional mutable reference to an item given the key.
fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item>;
/// Return references to the key-value pair stored for key, if it is present, else None.
fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)>;
/// Return mutable references to the key-value pair stored for key, if it is present, else None.
fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)>;
/// Returns true if the table contains an item with the given key.
fn contains_key(&self, key: &str) -> bool;
/// Inserts a key-value pair into the map.
fn insert(&mut self, key: &str, value: Item) -> Option<Item>;
/// Removes an item given the key.
fn remove(&mut self, key: &str) -> Option<Item>;
/// Get key/values for values that are visually children of this table
///
/// For example, this will return dotted keys
fn get_values(&self) -> Vec<(Vec<&Key>, &Value)>;
/// Auto formats the table.
fn fmt(&mut self);
/// Sorts [Key]/[Value]-pairs of the table
///
/// <div class="warning">
///
/// This sorts the syntactic table (everything under the `[header]`) and not the logical map of
/// key-value pairs.
/// This does not affect the order of [sub-tables][Table] or [sub-arrays][crate::ArrayOfTables].
/// This is not recursive.
///
/// </div>
fn sort_values(&mut self);
/// Change this table's dotted status
fn set_dotted(&mut self, yes: bool);
/// 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<'_>>;
}
impl TableLike for Table {
fn iter(&self) -> Iter<'_> {
self.iter()
}
fn iter_mut(&mut self) -> IterMut<'_> {
self.iter_mut()
}
fn clear(&mut self) {
self.clear();
}
fn entry<'a>(&'a mut self, key: &str) -> Entry<'a> {
self.entry(key)
}
fn entry_format<'a>(&'a mut self, key: &Key) -> Entry<'a> {
self.entry_format(key)
}
fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
self.get(key)
}
fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
self.get_mut(key)
}
fn get_key_value<'a>(&'a self, key: &str) -> Option<(&'a Key, &'a Item)> {
self.get_key_value(key)
}
fn get_key_value_mut<'a>(&'a mut self, key: &str) -> Option<(KeyMut<'a>, &'a mut Item)> {
self.get_key_value_mut(key)
}
fn contains_key(&self, key: &str) -> bool {
self.contains_key(key)
}
fn insert(&mut self, key: &str, value: Item) -> Option<Item> {
self.insert(key, value)
}
fn remove(&mut self, key: &str) -> Option<Item> {
self.remove(key)
}
fn get_values(&self) -> Vec<(Vec<&Key>, &Value)> {
self.get_values()
}
fn fmt(&mut self) {
self.fmt();
}
fn sort_values(&mut self) {
self.sort_values();
}
fn is_dotted(&self) -> bool {
self.is_dotted()
}
fn set_dotted(&mut self, yes: bool) {
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)
}
}
/// A view into a single location in a [`Table`], which may be vacant or occupied.
pub enum Entry<'a> {
/// An occupied Entry.
Occupied(OccupiedEntry<'a>),
/// A vacant Entry.
Vacant(VacantEntry<'a>),
}
impl<'a> Entry<'a> {
/// Returns the entry key
///
/// # Examples
///
/// ```
/// use toml_edit::Table;
///
/// let mut map = Table::new();
///
/// assert_eq!("hello", map.entry("hello").key());
/// ```
pub fn key(&self) -> &str {
match self {
Entry::Occupied(e) => e.key(),
Entry::Vacant(e) => e.key(),
}
}
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
pub fn or_insert(self, default: Item) -> &'a mut Item {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default),
}
}
/// Ensures a value is in the entry by inserting the result of the default function if empty,
/// and returns a mutable reference to the value in the entry.
pub fn or_insert_with<F: FnOnce() -> Item>(self, default: F) -> &'a mut Item {
match self {
Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => entry.insert(default()),
}
}
}
/// A view into a single occupied location in a [`Table`].
pub struct OccupiedEntry<'a> {
pub(crate) entry: indexmap::map::OccupiedEntry<'a, Key, Item>,
}
impl<'a> OccupiedEntry<'a> {
/// Gets a reference to the entry key
///
/// # Examples
///
/// ```
/// use toml_edit::Table;
///
/// let mut map = Table::new();
///
/// assert_eq!("foo", map.entry("foo").key());
/// ```
pub fn key(&self) -> &str {
self.entry.key().get()
}
/// Gets a mutable reference to the entry key
pub fn key_mut(&mut self) -> KeyMut<'_> {
use indexmap::map::MutableEntryKey;
self.entry.key_mut().as_mut()
}
/// Gets a reference to the value in the entry.
pub fn get(&self) -> &Item {
self.entry.get()
}
/// Gets a mutable reference to the value in the entry.
pub fn get_mut(&mut self) -> &mut Item {
self.entry.get_mut()
}
/// Converts the `OccupiedEntry` into a mutable reference to the value in the entry
/// with a lifetime bound to the map itself
pub fn into_mut(self) -> &'a mut Item {
self.entry.into_mut()
}
/// Sets the value of the entry, and returns the entry's old value
pub fn insert(&mut self, value: Item) -> Item {
self.entry.insert(value)
}
/// Takes the value out of the entry, and returns it
pub fn remove(self) -> Item {
self.entry.shift_remove()
}
}
/// A view into a single empty location in a [`Table`].
pub struct VacantEntry<'a> {
pub(crate) entry: indexmap::map::VacantEntry<'a, Key, Item>,
}
impl<'a> VacantEntry<'a> {
/// Gets a reference to the entry key
///
/// # Examples
///
/// ```
/// use toml_edit::Table;
///
/// let mut map = Table::new();
///
/// assert_eq!("foo", map.entry("foo").key());
/// ```
pub fn key(&self) -> &str {
self.entry.key().get()
}
/// Sets the value of the entry with the `VacantEntry`'s key,
/// and returns a mutable reference to it
pub fn insert(self, value: Item) -> &'a mut Item {
let entry = self.entry;
entry.insert(value)
}
}

386
vendor/toml_edit/src/value.rs vendored Normal file
View File

@@ -0,0 +1,386 @@
use std::iter::FromIterator;
use std::str::FromStr;
use toml_datetime::{Date, Datetime, Time};
use crate::key::Key;
use crate::repr::{Decor, Formatted};
use crate::{Array, InlineTable, RawString};
/// For [`Key`]/Value pairs under a [`Table`][crate::Table] header or inside another
/// Value
#[derive(Debug, Clone)]
pub enum Value {
/// A string value.
String(Formatted<String>),
/// A 64-bit integer value.
Integer(Formatted<i64>),
/// A 64-bit float value.
Float(Formatted<f64>),
/// A boolean value.
Boolean(Formatted<bool>),
/// An RFC 3339 formatted date-time with offset.
Datetime(Formatted<Datetime>),
/// An inline array of values.
Array(Array),
/// An inline table of key/value pairs.
InlineTable(InlineTable),
}
/// Downcasting
impl Value {
/// Text description of value type
pub fn type_name(&self) -> &'static str {
match self {
Self::String(..) => "string",
Self::Integer(..) => "integer",
Self::Float(..) => "float",
Self::Boolean(..) => "boolean",
Self::Datetime(..) => "datetime",
Self::Array(..) => "array",
Self::InlineTable(..) => "inline table",
}
}
/// Casts `self` to str.
pub fn as_str(&self) -> Option<&str> {
match *self {
Self::String(ref value) => Some(value.value()),
_ => None,
}
}
/// Returns true if `self` is a string.
pub fn is_str(&self) -> bool {
self.as_str().is_some()
}
/// Casts `self` to integer.
pub fn as_integer(&self) -> Option<i64> {
match *self {
Self::Integer(ref value) => Some(*value.value()),
_ => None,
}
}
/// Returns true if `self` is an integer.
pub fn is_integer(&self) -> bool {
self.as_integer().is_some()
}
/// Casts `self` to float.
pub fn as_float(&self) -> Option<f64> {
match *self {
Self::Float(ref value) => Some(*value.value()),
_ => None,
}
}
/// Returns true if `self` is a float.
pub fn is_float(&self) -> bool {
self.as_float().is_some()
}
/// Casts `self` to boolean.
pub fn as_bool(&self) -> Option<bool> {
match *self {
Self::Boolean(ref value) => Some(*value.value()),
_ => None,
}
}
/// Returns true if `self` is a boolean.
pub fn is_bool(&self) -> bool {
self.as_bool().is_some()
}
/// Casts `self` to date-time.
pub fn as_datetime(&self) -> Option<&Datetime> {
match *self {
Self::Datetime(ref value) => Some(value.value()),
_ => None,
}
}
/// Returns true if `self` is a date-time.
pub fn is_datetime(&self) -> bool {
self.as_datetime().is_some()
}
/// Casts `self` to array.
pub fn as_array(&self) -> Option<&Array> {
match *self {
Self::Array(ref value) => Some(value),
_ => None,
}
}
/// Casts `self` to mutable array.
pub fn as_array_mut(&mut self) -> Option<&mut Array> {
match *self {
Self::Array(ref mut value) => Some(value),
_ => None,
}
}
/// Returns true if `self` is an array.
pub fn is_array(&self) -> bool {
self.as_array().is_some()
}
/// Casts `self` to inline table.
pub fn as_inline_table(&self) -> Option<&InlineTable> {
match *self {
Self::InlineTable(ref value) => Some(value),
_ => None,
}
}
/// Casts `self` to mutable inline table.
pub fn as_inline_table_mut(&mut self) -> Option<&mut InlineTable> {
match *self {
Self::InlineTable(ref mut value) => Some(value),
_ => None,
}
}
/// Returns true if `self` is an inline table.
pub fn is_inline_table(&self) -> bool {
self.as_inline_table().is_some()
}
}
impl Value {
/// Get the decoration of the value.
/// # Example
/// ```rust
/// let v = toml_edit::Value::from(true);
/// assert_eq!(v.decor().suffix(), None);
///```
pub fn decor_mut(&mut self) -> &mut Decor {
match self {
Self::String(f) => f.decor_mut(),
Self::Integer(f) => f.decor_mut(),
Self::Float(f) => f.decor_mut(),
Self::Boolean(f) => f.decor_mut(),
Self::Datetime(f) => f.decor_mut(),
Self::Array(a) => a.decor_mut(),
Self::InlineTable(t) => t.decor_mut(),
}
}
/// Get the decoration of the value.
/// # Example
/// ```rust
/// let v = toml_edit::Value::from(true);
/// assert_eq!(v.decor().suffix(), None);
///```
pub fn decor(&self) -> &Decor {
match *self {
Self::String(ref f) => f.decor(),
Self::Integer(ref f) => f.decor(),
Self::Float(ref f) => f.decor(),
Self::Boolean(ref f) => f.decor(),
Self::Datetime(ref f) => f.decor(),
Self::Array(ref a) => a.decor(),
Self::InlineTable(ref t) => t.decor(),
}
}
/// 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);
self
}
pub(crate) fn decorate(&mut self, prefix: impl Into<RawString>, suffix: impl Into<RawString>) {
let decor = self.decor_mut();
*decor = Decor::new(prefix, suffix);
}
/// The location within the original document
///
/// This generally requires a [`Document`][crate::Document].
pub fn span(&self) -> Option<std::ops::Range<usize>> {
match self {
Self::String(f) => f.span(),
Self::Integer(f) => f.span(),
Self::Float(f) => f.span(),
Self::Boolean(f) => f.span(),
Self::Datetime(f) => f.span(),
Self::Array(a) => a.span(),
Self::InlineTable(t) => t.span(),
}
}
pub(crate) fn despan(&mut self, input: &str) {
match self {
Self::String(f) => f.despan(input),
Self::Integer(f) => f.despan(input),
Self::Float(f) => f.despan(input),
Self::Boolean(f) => f.despan(input),
Self::Datetime(f) => f.despan(input),
Self::Array(a) => a.despan(input),
Self::InlineTable(t) => t.despan(input),
}
}
}
#[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> {
let source = toml_parser::Source::new(s);
let mut sink = crate::error::TomlSink::<Option<_>>::new(source);
let mut value = crate::parser::parse_value(source, &mut sink);
if let Some(err) = sink.into_inner() {
Err(err)
} else {
// Only take the repr and not decor, as its probably not intended
value.decor_mut().clear();
value.despan(s);
Ok(value)
}
}
}
impl<'b> From<&'b Self> for Value {
fn from(s: &'b Self) -> Self {
s.clone()
}
}
impl<'b> From<&'b str> for Value {
fn from(s: &'b str) -> Self {
s.to_owned().into()
}
}
impl<'b> From<&'b String> for Value {
fn from(s: &'b String) -> Self {
s.to_owned().into()
}
}
impl From<String> for Value {
fn from(s: String) -> Self {
Self::String(Formatted::new(s))
}
}
impl From<i64> for Value {
fn from(i: i64) -> Self {
Self::Integer(Formatted::new(i))
}
}
impl From<f64> for Value {
fn from(f: f64) -> Self {
// Preserve sign of NaN. It may get written to TOML as `-nan`.
Self::Float(Formatted::new(f))
}
}
impl From<bool> for Value {
fn from(b: bool) -> Self {
Self::Boolean(Formatted::new(b))
}
}
impl From<Datetime> for Value {
fn from(d: Datetime) -> Self {
Self::Datetime(Formatted::new(d))
}
}
impl From<Date> for Value {
fn from(d: Date) -> Self {
let d: Datetime = d.into();
d.into()
}
}
impl From<Time> for Value {
fn from(d: Time) -> Self {
let d: Datetime = d.into();
d.into()
}
}
impl From<Array> for Value {
fn from(array: Array) -> Self {
Self::Array(array)
}
}
impl From<InlineTable> for Value {
fn from(table: InlineTable) -> Self {
Self::InlineTable(table)
}
}
impl<V: Into<Self>> FromIterator<V> for Value {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = V>,
{
let array: Array = iter.into_iter().collect();
Self::Array(array)
}
}
impl<K: Into<Key>, V: Into<Self>> FromIterator<(K, V)> for Value {
fn from_iter<I>(iter: I) -> Self
where
I: IntoIterator<Item = (K, V)>,
{
let table: InlineTable = iter.into_iter().collect();
Self::InlineTable(table)
}
}
#[cfg(feature = "display")]
impl std::fmt::Display for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
crate::encode::encode_value(self, f, None, ("", ""))
}
}
// `key1 = value1`
pub(crate) const DEFAULT_VALUE_DECOR: (&str, &str) = (" ", "");
// `{ key = value }`
pub(crate) const DEFAULT_TRAILING_VALUE_DECOR: (&str, &str) = (" ", " ");
// `[value1, value2]`
pub(crate) const DEFAULT_LEADING_VALUE_DECOR: (&str, &str) = ("", "");
#[cfg(test)]
#[cfg(feature = "parse")]
#[cfg(feature = "display")]
mod tests {
use super::*;
#[test]
fn from_iter_formatting() {
let features = ["node".to_owned(), "mouth".to_owned()];
let features: Value = features.iter().cloned().collect();
assert_eq!(features.to_string(), r#"["node", "mouth"]"#);
}
}
#[test]
#[cfg(feature = "parse")]
#[cfg(feature = "display")]
fn string_roundtrip() {
Value::from("hello").to_string().parse::<Value>().unwrap();
}

239
vendor/toml_edit/src/visit.rs vendored Normal file
View File

@@ -0,0 +1,239 @@
#![allow(missing_docs)]
//! Document tree traversal to walk a shared borrow of a document tree.
//!
//! Each method of the [`Visit`] trait is a hook that can be overridden
//! to customize the behavior when mutating the corresponding type of node.
//! By default, every method recursively visits the substructure of the
//! input by invoking the right visitor method of each of its fields.
//!
//! ```
//! # use toml_edit::{Item, ArrayOfTables, Table, Value};
//!
//! pub trait Visit<'doc> {
//! /* ... */
//!
//! fn visit_item(&mut self, i: &'doc Item) {
//! visit_item(self, i);
//! }
//!
//! /* ... */
//! # fn visit_value(&mut self, i: &'doc Value);
//! # fn visit_table(&mut self, i: &'doc Table);
//! # fn visit_array_of_tables(&mut self, i: &'doc ArrayOfTables);
//! }
//!
//! pub fn visit_item<'doc, V>(v: &mut V, node: &'doc Item)
//! where
//! V: Visit<'doc> + ?Sized,
//! {
//! match node {
//! Item::None => {}
//! Item::Value(value) => v.visit_value(value),
//! Item::Table(table) => v.visit_table(table),
//! Item::ArrayOfTables(array) => v.visit_array_of_tables(array),
//! }
//! }
//! ```
//!
//! The API is modeled after [`syn::visit`](https://docs.rs/syn/1/syn/visit).
//!
//! # Examples
//!
//! This visitor stores every string in the document.
//!
//! ```
//! # #[cfg(feature = "parse")] {
//! # use toml_edit::*;
//! use toml_edit::visit::*;
//!
//! #[derive(Default)]
//! struct StringCollector<'doc> {
//! strings: Vec<&'doc str>,
//! }
//!
//! impl<'doc> Visit<'doc> for StringCollector<'doc> {
//! fn visit_string(&mut self, node: &'doc Formatted<String>) {
//! self.strings.push(node.value().as_str());
//! }
//! }
//!
//! let input = r#"
//! laputa = "sky-castle"
//! the-force = { value = "surrounds-you" }
//! "#;
//!
//! let mut document: DocumentMut = input.parse().unwrap();
//! let mut visitor = StringCollector::default();
//! 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/toml-rs/toml/blob/main/crates/toml_edit/examples/visit.rs).
use crate::{
Array, ArrayOfTables, Datetime, DocumentMut, Formatted, InlineTable, Item, Table, TableLike,
Value,
};
/// Document tree traversal to mutate an exclusive borrow of a document tree in-place.
///
/// See the [module documentation](self) for details.
pub trait Visit<'doc> {
fn visit_document(&mut self, node: &'doc DocumentMut) {
visit_document(self, node);
}
fn visit_item(&mut self, node: &'doc Item) {
visit_item(self, node);
}
fn visit_table(&mut self, node: &'doc Table) {
visit_table(self, node);
}
fn visit_inline_table(&mut self, node: &'doc InlineTable) {
visit_inline_table(self, node);
}
fn visit_table_like(&mut self, node: &'doc dyn TableLike) {
visit_table_like(self, node);
}
fn visit_table_like_kv(&mut self, key: &'doc str, node: &'doc Item) {
visit_table_like_kv(self, key, node);
}
fn visit_array(&mut self, node: &'doc Array) {
visit_array(self, node);
}
fn visit_array_of_tables(&mut self, node: &'doc ArrayOfTables) {
visit_array_of_tables(self, node);
}
fn visit_value(&mut self, node: &'doc Value) {
visit_value(self, node);
}
fn visit_boolean(&mut self, node: &'doc Formatted<bool>) {
visit_boolean(self, node);
}
fn visit_datetime(&mut self, node: &'doc Formatted<Datetime>) {
visit_datetime(self, node);
}
fn visit_float(&mut self, node: &'doc Formatted<f64>) {
visit_float(self, node);
}
fn visit_integer(&mut self, node: &'doc Formatted<i64>) {
visit_integer(self, node);
}
fn visit_string(&mut self, node: &'doc Formatted<String>) {
visit_string(self, node);
}
}
pub fn visit_document<'doc, V>(v: &mut V, node: &'doc DocumentMut)
where
V: Visit<'doc> + ?Sized,
{
v.visit_table(node.as_table());
}
pub fn visit_item<'doc, V>(v: &mut V, node: &'doc Item)
where
V: Visit<'doc> + ?Sized,
{
match node {
Item::None => {}
Item::Value(value) => v.visit_value(value),
Item::Table(table) => v.visit_table(table),
Item::ArrayOfTables(array) => v.visit_array_of_tables(array),
}
}
pub fn visit_table<'doc, V>(v: &mut V, node: &'doc Table)
where
V: Visit<'doc> + ?Sized,
{
v.visit_table_like(node);
}
pub fn visit_inline_table<'doc, V>(v: &mut V, node: &'doc InlineTable)
where
V: Visit<'doc> + ?Sized,
{
v.visit_table_like(node);
}
pub fn visit_table_like<'doc, V>(v: &mut V, node: &'doc dyn TableLike)
where
V: Visit<'doc> + ?Sized,
{
for (key, item) in node.iter() {
v.visit_table_like_kv(key, item);
}
}
pub fn visit_table_like_kv<'doc, V>(v: &mut V, _key: &'doc str, node: &'doc Item)
where
V: Visit<'doc> + ?Sized,
{
v.visit_item(node);
}
pub fn visit_array<'doc, V>(v: &mut V, node: &'doc Array)
where
V: Visit<'doc> + ?Sized,
{
for value in node.iter() {
v.visit_value(value);
}
}
pub fn visit_array_of_tables<'doc, V>(v: &mut V, node: &'doc ArrayOfTables)
where
V: Visit<'doc> + ?Sized,
{
for table in node.iter() {
v.visit_table(table);
}
}
pub fn visit_value<'doc, V>(v: &mut V, node: &'doc Value)
where
V: Visit<'doc> + ?Sized,
{
match node {
Value::String(s) => v.visit_string(s),
Value::Integer(i) => v.visit_integer(i),
Value::Float(f) => v.visit_float(f),
Value::Boolean(b) => v.visit_boolean(b),
Value::Datetime(dt) => v.visit_datetime(dt),
Value::Array(array) => v.visit_array(array),
Value::InlineTable(table) => v.visit_inline_table(table),
}
}
macro_rules! empty_visit {
($name: ident, $t: ty) => {
fn $name<'doc, V>(_v: &mut V, _node: &'doc $t)
where
V: Visit<'doc> + ?Sized,
{
}
};
}
empty_visit!(visit_boolean, Formatted<bool>);
empty_visit!(visit_datetime, Formatted<Datetime>);
empty_visit!(visit_float, Formatted<f64>);
empty_visit!(visit_integer, Formatted<i64>);
empty_visit!(visit_string, Formatted<String>);

256
vendor/toml_edit/src/visit_mut.rs vendored Normal file
View File

@@ -0,0 +1,256 @@
#![allow(missing_docs)]
//! Document tree traversal to mutate an exclusive borrow of a document tree in place.
//!
//!
//! Each method of the [`VisitMut`] trait is a hook that can be overridden
//! to customize the behavior when mutating the corresponding type of node.
//! By default, every method recursively visits the substructure of the
//! input by invoking the right visitor method of each of its fields.
//!
//! ```
//! # use toml_edit::{Item, ArrayOfTables, Table, Value};
//!
//! pub trait VisitMut {
//! /* ... */
//!
//! fn visit_item_mut(&mut self, i: &mut Item) {
//! visit_item_mut(self, i);
//! }
//!
//! /* ... */
//! # fn visit_value_mut(&mut self, i: &mut Value);
//! # fn visit_table_mut(&mut self, i: &mut Table);
//! # fn visit_array_of_tables_mut(&mut self, i: &mut ArrayOfTables);
//! }
//!
//! pub fn visit_item_mut<V>(v: &mut V, node: &mut Item)
//! where
//! V: VisitMut + ?Sized,
//! {
//! match node {
//! Item::None => {}
//! Item::Value(value) => v.visit_value_mut(value),
//! Item::Table(table) => v.visit_table_mut(table),
//! Item::ArrayOfTables(array) => v.visit_array_of_tables_mut(array),
//! }
//! }
//! ```
//!
//! The API is modeled after [`syn::visit_mut`](https://docs.rs/syn/1/syn/visit_mut).
//!
//! # Examples
//!
//! This visitor replaces every floating point value with its decimal string representation, to
//! 2 decimal points.
//!
//! ```
//! # #[cfg(feature = "parse")] {
//! # #[cfg(feature = "display")] {
//! # use toml_edit::*;
//! use toml_edit::visit_mut::*;
//!
//! struct FloatToString;
//!
//! impl VisitMut for FloatToString {
//! fn visit_value_mut(&mut self, node: &mut Value) {
//! if let Value::Float(f) = node {
//! // Convert the float to a string.
//! let mut s = Formatted::new(format!("{:.2}", f.value()));
//! // Copy over the formatting.
//! std::mem::swap(s.decor_mut(), f.decor_mut());
//! *node = Value::String(s);
//! }
//! // Most of the time, you will also need to call the default implementation to recurse
//! // further down the document tree.
//! visit_value_mut(self, node);
//! }
//! }
//!
//! let input = r#"
//! banana = 3.26
//! table = { apple = 4.5 }
//! "#;
//!
//! let mut document: DocumentMut = input.parse().unwrap();
//! let mut visitor = FloatToString;
//! visitor.visit_document_mut(&mut document);
//!
//! let output = r#"
//! banana = "3.26"
//! table = { apple = "4.50" }
//! "#;
//!
//! 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/toml-rs/toml/blob/main/crates/toml_edit/examples/visit.rs).
use crate::{
Array, ArrayOfTables, Datetime, DocumentMut, Formatted, InlineTable, Item, KeyMut, Table,
TableLike, Value,
};
/// Document tree traversal to mutate an exclusive borrow of a document tree in-place.
///
/// See the [module documentation](self) for details.
pub trait VisitMut {
fn visit_document_mut(&mut self, node: &mut DocumentMut) {
visit_document_mut(self, node);
}
fn visit_item_mut(&mut self, node: &mut Item) {
visit_item_mut(self, node);
}
fn visit_table_mut(&mut self, node: &mut Table) {
visit_table_mut(self, node);
}
fn visit_inline_table_mut(&mut self, node: &mut InlineTable) {
visit_inline_table_mut(self, node);
}
/// [`visit_table_mut`](Self::visit_table_mut) and
/// [`visit_inline_table_mut`](Self::visit_inline_table_mut) both recurse into this method.
fn visit_table_like_mut(&mut self, node: &mut dyn TableLike) {
visit_table_like_mut(self, node);
}
fn visit_table_like_kv_mut(&mut self, key: KeyMut<'_>, node: &mut Item) {
visit_table_like_kv_mut(self, key, node);
}
fn visit_array_mut(&mut self, node: &mut Array) {
visit_array_mut(self, node);
}
fn visit_array_of_tables_mut(&mut self, node: &mut ArrayOfTables) {
visit_array_of_tables_mut(self, node);
}
fn visit_value_mut(&mut self, node: &mut Value) {
visit_value_mut(self, node);
}
fn visit_boolean_mut(&mut self, node: &mut Formatted<bool>) {
visit_boolean_mut(self, node);
}
fn visit_datetime_mut(&mut self, node: &mut Formatted<Datetime>) {
visit_datetime_mut(self, node);
}
fn visit_float_mut(&mut self, node: &mut Formatted<f64>) {
visit_float_mut(self, node);
}
fn visit_integer_mut(&mut self, node: &mut Formatted<i64>) {
visit_integer_mut(self, node);
}
fn visit_string_mut(&mut self, node: &mut Formatted<String>) {
visit_string_mut(self, node);
}
}
pub fn visit_document_mut<V>(v: &mut V, node: &mut DocumentMut)
where
V: VisitMut + ?Sized,
{
v.visit_table_mut(node.as_table_mut());
}
pub fn visit_item_mut<V>(v: &mut V, node: &mut Item)
where
V: VisitMut + ?Sized,
{
match node {
Item::None => {}
Item::Value(value) => v.visit_value_mut(value),
Item::Table(table) => v.visit_table_mut(table),
Item::ArrayOfTables(array) => v.visit_array_of_tables_mut(array),
}
}
pub fn visit_table_mut<V>(v: &mut V, node: &mut Table)
where
V: VisitMut + ?Sized,
{
v.visit_table_like_mut(node);
}
pub fn visit_inline_table_mut<V>(v: &mut V, node: &mut InlineTable)
where
V: VisitMut + ?Sized,
{
v.visit_table_like_mut(node);
}
pub fn visit_table_like_mut<V>(v: &mut V, node: &mut dyn TableLike)
where
V: VisitMut + ?Sized,
{
for (key, item) in node.iter_mut() {
v.visit_table_like_kv_mut(key, item);
}
}
pub fn visit_table_like_kv_mut<V>(v: &mut V, _key: KeyMut<'_>, node: &mut Item)
where
V: VisitMut + ?Sized,
{
v.visit_item_mut(node);
}
pub fn visit_array_mut<V>(v: &mut V, node: &mut Array)
where
V: VisitMut + ?Sized,
{
for value in node.iter_mut() {
v.visit_value_mut(value);
}
}
pub fn visit_array_of_tables_mut<V>(v: &mut V, node: &mut ArrayOfTables)
where
V: VisitMut + ?Sized,
{
for table in node.iter_mut() {
v.visit_table_mut(table);
}
}
pub fn visit_value_mut<V>(v: &mut V, node: &mut Value)
where
V: VisitMut + ?Sized,
{
match node {
Value::String(s) => v.visit_string_mut(s),
Value::Integer(i) => v.visit_integer_mut(i),
Value::Float(f) => v.visit_float_mut(f),
Value::Boolean(b) => v.visit_boolean_mut(b),
Value::Datetime(dt) => v.visit_datetime_mut(dt),
Value::Array(array) => v.visit_array_mut(array),
Value::InlineTable(table) => v.visit_inline_table_mut(table),
}
}
macro_rules! empty_visit_mut {
($name: ident, $t: ty) => {
fn $name<V>(_v: &mut V, _node: &mut $t)
where
V: VisitMut + ?Sized,
{
}
};
}
empty_visit_mut!(visit_boolean_mut, Formatted<bool>);
empty_visit_mut!(visit_datetime_mut, Formatted<Datetime>);
empty_visit_mut!(visit_float_mut, Formatted<f64>);
empty_visit_mut!(visit_integer_mut, Formatted<i64>);
empty_visit_mut!(visit_string_mut, Formatted<String>);