Vendor things
This commit is contained in:
parent
5deceec006
commit
977e3c17e5
19434 changed files with 10682014 additions and 0 deletions
1
third-party/vendor/toml_edit/.cargo-checksum.json
vendored
Normal file
1
third-party/vendor/toml_edit/.cargo-checksum.json
vendored
Normal file
File diff suppressed because one or more lines are too long
898
third-party/vendor/toml_edit/Cargo.lock
generated
vendored
Normal file
898
third-party/vendor/toml_edit/Cargo.lock
generated
vendored
Normal file
|
|
@ -0,0 +1,898 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6342bd4f5a1205d7f41e94a41a901f5647c938cdfa96036338e8533c9d6c2450"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is-terminal",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41ed9a86bf92ae6580e0a31281f65a1b1d867c0cc68d5346e2ae128dddfa6a7d"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e765fd216e48e067936442276d1d57399e37bce53c264d6fefbe298080cb57ee"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ca11d4be1bab0c8bc8734a9aa7bf4ee8316d462a08c6ac5052f888fef5b494b"
|
||||
dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba3569f383e8f1598449f1a423e72e99569137b47740b1da11ef19af3d5c3223"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bfd4d1b31faaa3a89d7934dbded3111da0d2ef28e3ebccdb4f0179f5929d1ef1"
|
||||
dependencies = [
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.0.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7db700bc935f9e43e88d00b0850dae18a63773cfbec6d8e070fccf7fef89a39"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"is-terminal",
|
||||
"once_cell",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.0.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0177313f9f02afc995627906bbd8967e2be069f5261954222dac78290c2b9014"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.105",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7"
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51887d4adc7b564537b15adcfb307936f8075dfcd5f00dde9a9f1d29383682bc"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "88bffebc5d80432c9b140ee17875ff173a8ab62faad5b257da912bd2f6c1c0a1"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fnv"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "globset"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0a1e17342619edbc21a964c2afbeb6c820c6a2560032872f397bb97ea127bd0a"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"bstr",
|
||||
"fnv",
|
||||
"log",
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a"
|
||||
|
||||
[[package]]
|
||||
name = "heck"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.1.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
|
||||
|
||||
[[package]]
|
||||
name = "ignore"
|
||||
version = "0.4.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "713f1b139373f96a2e0ce3ac931cd01ee973c3c5dd7c40c0c2efe96ad2b6751d"
|
||||
dependencies = [
|
||||
"crossbeam-utils",
|
||||
"globset",
|
||||
"lazy_static",
|
||||
"log",
|
||||
"memchr",
|
||||
"regex",
|
||||
"same-file",
|
||||
"thread_local",
|
||||
"walkdir",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "include_dir"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18762faeff7122e89e0857b02f7ce6fcc0d101d5e9ad2ad7846cc01d61b7f19e"
|
||||
dependencies = [
|
||||
"include_dir_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "include_dir_macros"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b139284b5cf57ecfa712bcc66950bb635b31aff41c188e8a4cfc758eca374a3f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.42.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itoa"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c8af84674fe1f223a982c933a0ee1086ac4d4052aa0fb8060c12c6ad838e754"
|
||||
|
||||
[[package]]
|
||||
name = "kstring"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec3066350882a1cd6d950d055997f379ac37fd39f81cd4d8ed186032eb3c5747"
|
||||
dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.142"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
|
||||
|
||||
[[package]]
|
||||
name = "libtest-mimic"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7b603516767d1ab23d0de09d023e62966c3322f7148297c35cf3d97aa8b37fa"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"termcolor",
|
||||
"threadpool",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b64f40e5e03e0d54f03845c8197d0291253cdbedfb1cb46b13c2c117554a9f4c"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "normalize-line-endings"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be"
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num_cpus"
|
||||
version = "1.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19e64526ebdee182341572e50e9ad03965aa510cd94427a4549448f285e957a1"
|
||||
dependencies = [
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e82dad04139b71a90c080c8463fe0dc7902db5192d939bd0950f074d014339e1"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ff7415e9ae3fff1225851df9e0d9e4e5479f947619774677a63572e55e80eff"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
|
||||
dependencies = [
|
||||
"proc-macro-error-attr",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 1.0.105",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error-attr"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.56"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b63bdb0cd06f1f4dedf69b254734f9b45af66e4a031e42a7480257d9898b435"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c4eb3267174b8c6c2f654116623910a0fef09c4753f8dd83db29c48a0df988b"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3f87b73ce11b1619a3c6332f45341e0047173771e8b8b73f87bfeefb7b56244"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.37.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2aae838e49b3d63e9274e1c01833cc8139d3fec468c3b84688c628f44b1ae11d"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09"
|
||||
|
||||
[[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.160"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb2f3770c8bce3bcda7e149193a069a0f4365bda1fa5cd88e03bca26afc1216c"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.160"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "291a097c63d8497e00160b166a967a4a79c64f3facdd01cbd7502231688d77df"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "057d394a50403bcac12672b2b18fb387ab6d289d957dab67dd201875391e52f1"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96426c9936fd7a0124915f9185ea1d20aa9445cc9821142f0a73bc9207a2e186"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62ac7f900db32bf3fd12e0117dd3dc4da74bc52ebaac97f39668446d89694803"
|
||||
|
||||
[[package]]
|
||||
name = "snapbox"
|
||||
version = "0.4.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6bccd62078347f89a914e3004d94582e13824d4e3d8a816317862884c423835"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"ignore",
|
||||
"libtest-mimic",
|
||||
"normalize-line-endings",
|
||||
"similar",
|
||||
"snapbox-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "snapbox-macros"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eaaf09df9f0eeae82be96290918520214530e738a7fe5a351b0f24cf77c0ca31"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a34fcf3e8b60f57e6a14301a2e916d323af98b0ea63c599441eec8558660c822"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bab24d30b911b2376f3a13cc2cd443142f0c81dda04c118693e35b3835757755"
|
||||
dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thread_local"
|
||||
version = "1.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5516c27b78311c50bf42c071425c560ac799b11c30b31f87e3081965fe5e0180"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "threadpool"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
|
||||
dependencies = [
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml-test"
|
||||
version = "0.3.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "37351256790aa1dbd6d60f4ff08e55e7f372e292f3e9040d6e077463d9a779c3"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml-test-data"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "93f351b6d6005ee802b0d4a53ca1cdf05636f441df4d299e62cba57f1da52646"
|
||||
dependencies = [
|
||||
"include_dir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml-test-harness"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e00fda5710922fe6b3005bf6a5050c303d6f9625249c37b7386e8818f4af675"
|
||||
dependencies = [
|
||||
"ignore",
|
||||
"libtest-mimic",
|
||||
"toml-test",
|
||||
"toml-test-data",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cda73e2f1397b1262d6dfdcef8aafae14d1de7748d66822d3bfeeb6d03e5e4b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.19.15"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"kstring",
|
||||
"libtest-mimic",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_spanned",
|
||||
"snapbox",
|
||||
"toml-test-data",
|
||||
"toml-test-harness",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcc811dc4066ac62f84f11307873c4850cb653bfa9b1719cee2bd2204a4bc5dd"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
|
||||
dependencies = [
|
||||
"winapi-i686-pc-windows-gnu",
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-util"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-x86_64-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.42.1",
|
||||
"windows_aarch64_msvc 0.42.1",
|
||||
"windows_i686_gnu 0.42.1",
|
||||
"windows_i686_msvc 0.42.1",
|
||||
"windows_x86_64_gnu 0.42.1",
|
||||
"windows_x86_64_gnullvm 0.42.1",
|
||||
"windows_x86_64_msvc 0.42.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.45.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0"
|
||||
dependencies = [
|
||||
"windows-targets 0.42.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e2522491fbfcd58cc84d47aeb2958948c4b8982e9a2d8a2a35bbaed431390e7"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.42.1",
|
||||
"windows_aarch64_msvc 0.42.1",
|
||||
"windows_i686_gnu 0.42.1",
|
||||
"windows_i686_msvc 0.42.1",
|
||||
"windows_x86_64_gnu 0.42.1",
|
||||
"windows_x86_64_gnullvm 0.42.1",
|
||||
"windows_x86_64_msvc 0.42.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7b1eb6f0cd7c80c79759c929114ef071b87354ce476d9d94271031c0497adfd5"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.48.0",
|
||||
"windows_aarch64_msvc 0.48.0",
|
||||
"windows_i686_gnu 0.48.0",
|
||||
"windows_i686_msvc 0.48.0",
|
||||
"windows_x86_64_gnu 0.48.0",
|
||||
"windows_x86_64_gnullvm 0.48.0",
|
||||
"windows_x86_64_msvc 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
156
third-party/vendor/toml_edit/Cargo.toml
vendored
Normal file
156
third-party/vendor/toml_edit/Cargo.toml
vendored
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
# 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.66.0"
|
||||
name = "toml_edit"
|
||||
version = "0.19.15"
|
||||
authors = [
|
||||
"Andronik Ordian <write@reusable.software>",
|
||||
"Ed Page <eopage@gmail.com>",
|
||||
]
|
||||
include = [
|
||||
"build.rs",
|
||||
"src/**/*",
|
||||
"Cargo.toml",
|
||||
"Cargo.lock",
|
||||
"LICENSE*",
|
||||
"README.md",
|
||||
"benches/**/*",
|
||||
"examples/**/*",
|
||||
"tests/**/*",
|
||||
]
|
||||
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]
|
||||
features = ["serde"]
|
||||
rustdoc-args = [
|
||||
"--cfg",
|
||||
"docsrs",
|
||||
]
|
||||
|
||||
[package.metadata.release]
|
||||
tag-name = "v{{version}}"
|
||||
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
file = "CHANGELOG.md"
|
||||
min = 1
|
||||
replace = "{{version}}"
|
||||
search = "Unreleased"
|
||||
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
exactly = 1
|
||||
file = "CHANGELOG.md"
|
||||
replace = "...{{tag_name}}"
|
||||
search = '\.\.\.HEAD'
|
||||
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
file = "CHANGELOG.md"
|
||||
min = 1
|
||||
replace = "{{date}}"
|
||||
search = "ReleaseDate"
|
||||
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
exactly = 1
|
||||
file = "CHANGELOG.md"
|
||||
replace = """
|
||||
<!-- next-header -->
|
||||
## [Unreleased] - ReleaseDate
|
||||
"""
|
||||
search = "<!-- next-header -->"
|
||||
|
||||
[[package.metadata.release.pre-release-replacements]]
|
||||
exactly = 1
|
||||
file = "CHANGELOG.md"
|
||||
replace = """
|
||||
<!-- next-url -->
|
||||
[Unreleased]: https://github.com/toml-rs/toml/compare/{{tag_name}}...HEAD"""
|
||||
search = "<!-- next-url -->"
|
||||
|
||||
[[example]]
|
||||
name = "visit"
|
||||
test = true
|
||||
|
||||
[[test]]
|
||||
name = "decoder_compliance"
|
||||
harness = false
|
||||
|
||||
[[test]]
|
||||
name = "encoder_compliance"
|
||||
harness = false
|
||||
|
||||
[[test]]
|
||||
name = "invalid"
|
||||
harness = false
|
||||
|
||||
[dependencies.indexmap]
|
||||
version = "2.0.0"
|
||||
features = ["std"]
|
||||
|
||||
[dependencies.kstring]
|
||||
version = "2.0.0"
|
||||
features = ["max_inline"]
|
||||
optional = true
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.145"
|
||||
optional = true
|
||||
|
||||
[dependencies.serde_spanned]
|
||||
version = "0.6.3"
|
||||
features = ["serde"]
|
||||
optional = true
|
||||
|
||||
[dependencies.toml_datetime]
|
||||
version = "0.6.3"
|
||||
|
||||
[dependencies.winnow]
|
||||
version = "0.5.0"
|
||||
|
||||
[dev-dependencies.libtest-mimic]
|
||||
version = "0.6.0"
|
||||
|
||||
[dev-dependencies.serde_json]
|
||||
version = "1.0.96"
|
||||
|
||||
[dev-dependencies.snapbox]
|
||||
version = "0.4.11"
|
||||
features = ["harness"]
|
||||
|
||||
[dev-dependencies.toml-test-data]
|
||||
version = "1.3.0"
|
||||
|
||||
[dev-dependencies.toml-test-harness]
|
||||
version = "0.4.3"
|
||||
|
||||
[features]
|
||||
default = []
|
||||
perf = ["dep:kstring"]
|
||||
serde = [
|
||||
"dep:serde",
|
||||
"toml_datetime/serde",
|
||||
"dep:serde_spanned",
|
||||
]
|
||||
unbounded = []
|
||||
202
third-party/vendor/toml_edit/LICENSE-APACHE
vendored
Normal file
202
third-party/vendor/toml_edit/LICENSE-APACHE
vendored
Normal 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
third-party/vendor/toml_edit/LICENSE-MIT
vendored
Normal file
19
third-party/vendor/toml_edit/LICENSE-MIT
vendored
Normal 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.
|
||||
59
third-party/vendor/toml_edit/README.md
vendored
Normal file
59
third-party/vendor/toml_edit/README.md
vendored
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# toml_edit
|
||||
|
||||
[](https://github.com/ordian/toml_edit/actions)
|
||||
[](https://codecov.io/gh/ordian/toml_edit)
|
||||
[](https://crates.io/crates/toml_edit)
|
||||
[](https://docs.rs/toml_edit)
|
||||
[](https://gitter.im/toml_edit/Lobby)
|
||||
|
||||
|
||||
This crate allows you to parse and modify toml
|
||||
documents, while preserving comments, spaces *and
|
||||
relative order* or items.
|
||||
|
||||
`toml_edit` is primarily tailored for [cargo-edit](https://github.com/killercup/cargo-edit/) needs.
|
||||
|
||||
## Example
|
||||
|
||||
```rust
|
||||
use toml_edit::{Document, value};
|
||||
|
||||
fn main() {
|
||||
let toml = r#"
|
||||
"hello" = 'toml!' # comment
|
||||
['a'.b]
|
||||
"#;
|
||||
let mut doc = toml.parse::<Document>().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:
|
||||
|
||||
* Scattered array of tables (tables are reordered by default, see [test]).
|
||||
* Order of dotted keys, see [issue](https://github.com/ordian/toml_edit/issues/163).
|
||||
|
||||
## License
|
||||
|
||||
Licensed under either of
|
||||
|
||||
- Apache License, Version 2.0 ([LICENSE-APACHE](LICENSE-APACHE) or http://apache.org/licenses/LICENSE-2.0)
|
||||
- MIT license ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
|
||||
|
||||
### Contribution
|
||||
|
||||
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
|
||||
|
||||
[test]: https://github.com/ordian/toml_edit/blob/f09bd5d075fdb7d2ef8d9bb3270a34506c276753/tests/test_valid.rs#L84
|
||||
284
third-party/vendor/toml_edit/examples/visit.rs
vendored
Normal file
284
third-party/vendor/toml_edit/examples/visit.rs
vendored
Normal file
|
|
@ -0,0 +1,284 @@
|
|||
//! Example for how to use `VisitMut` to iterate over a table.
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
use toml_edit::visit::*;
|
||||
use toml_edit::visit_mut::*;
|
||||
use toml_edit::{Array, Document, 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) {
|
||||
(
|
||||
VisitState::Root | VisitState::TargetWithSpec,
|
||||
"dependencies" | "build-dependencies" | "dev-dependencies",
|
||||
) => VisitState::Dependencies,
|
||||
(VisitState::Root, "target") => VisitState::Target,
|
||||
(VisitState::Root | VisitState::TargetWithSpec, _) => VisitState::Other,
|
||||
(VisitState::Target, _) => VisitState::TargetWithSpec,
|
||||
(VisitState::Dependencies, _) => VisitState::SubDependencies,
|
||||
(VisitState::SubDependencies, _) => VisitState::SubDependencies,
|
||||
(VisitState::Other, _) => VisitState::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: &Document) -> BTreeSet<&str> {
|
||||
let mut visitor = DependencyNameVisitor {
|
||||
state: VisitState::Root,
|
||||
names: BTreeSet::new(),
|
||||
};
|
||||
|
||||
visitor.visit_document(document);
|
||||
|
||||
visitor.names
|
||||
}
|
||||
|
||||
fn visit_mut_example(document: &mut Document) {
|
||||
let mut visitor = NormalizeDependencyTablesVisitor {
|
||||
state: VisitState::Root,
|
||||
};
|
||||
|
||||
visitor.visit_document_mut(document);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let mut document: Document = 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: Document = 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: Document = INPUT.parse().expect("input is valid TOML");
|
||||
|
||||
visit_mut_example(&mut document);
|
||||
assert_eq!(format!("{}", document), VISIT_MUT_OUTPUT);
|
||||
}
|
||||
403
third-party/vendor/toml_edit/src/array.rs
vendored
Normal file
403
third-party/vendor/toml_edit/src/array.rs
vendored
Normal file
|
|
@ -0,0 +1,403 @@
|
|||
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};
|
||||
|
||||
/// Type representing a TOML array,
|
||||
/// payload of the `Value::Array` variant's value
|
||||
#[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 `Table`'s key/value pairs.
|
||||
pub type ArrayIntoIter = Box<dyn Iterator<Item = Value>>;
|
||||
/// An iterator type over `Array`'s values.
|
||||
pub type ArrayIter<'a> = Box<dyn Iterator<Item = &'a Value> + 'a>;
|
||||
/// An iterator type over `Array`'s values.
|
||||
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
|
||||
}
|
||||
|
||||
/// Returns the location within the original document
|
||||
pub(crate) 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 iff `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.value_op(v.into(), true, |items, value| {
|
||||
items.push(Item::Value(value))
|
||||
})
|
||||
}
|
||||
|
||||
/// Appends a new, already formatted value to the end of the array.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// 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.value_op(v.into(), true, |items, value| {
|
||||
items.insert(index, Item::Value(value))
|
||||
})
|
||||
}
|
||||
|
||||
/// 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
|
||||
/// 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
|
||||
/// 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 {:?} in an array", x),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 {:?} in an array", x),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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));
|
||||
}
|
||||
|
||||
fn value_op<T>(
|
||||
&mut self,
|
||||
v: Value,
|
||||
decorate: bool,
|
||||
op: impl FnOnce(&mut Vec<Item>, Value) -> T,
|
||||
) -> T {
|
||||
let mut value = v;
|
||||
if !self.is_empty() && decorate {
|
||||
value.decorate(" ", "");
|
||||
} else if decorate {
|
||||
value.decorate("", "");
|
||||
}
|
||||
op(&mut self.values, value)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Array {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
crate::encode::Encode::encode(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()));
|
||||
Array {
|
||||
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("");
|
||||
}
|
||||
166
third-party/vendor/toml_edit/src/array_of_tables.rs
vendored
Normal file
166
third-party/vendor/toml_edit/src/array_of_tables.rs
vendored
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
use std::iter::FromIterator;
|
||||
|
||||
use crate::{Array, Item, Table};
|
||||
|
||||
/// Type representing a TOML array of tables
|
||||
#[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
|
||||
}
|
||||
|
||||
/// Returns the location within the original document
|
||||
pub(crate) 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 iff `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) {
|
||||
self.values.remove(index);
|
||||
}
|
||||
|
||||
/// 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 values.
|
||||
pub type ArrayOfTablesIter<'a> = Box<dyn Iterator<Item = &'a Table> + 'a>;
|
||||
/// An iterator type over `ArrayOfTables`'s values.
|
||||
pub type ArrayOfTablesIterMut<'a> = Box<dyn Iterator<Item = &'a mut Table> + 'a>;
|
||||
/// An iterator type over `ArrayOfTables`'s values.
|
||||
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);
|
||||
ArrayOfTables {
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
97
third-party/vendor/toml_edit/src/de/array.rs
vendored
Normal file
97
third-party/vendor/toml_edit/src/de/array.rs
vendored
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
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 }
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this is wrapped by `ValueDeserializer` and any trait methods
|
||||
// implemented here need to be wrapped there
|
||||
impl<'de> serde::Deserializer<'de> for ArrayDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::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::de::Visitor<'de>,
|
||||
{
|
||||
if serde_spanned::__unstable::is_spanned(name, fields) {
|
||||
if let Some(span) = self.span.clone() {
|
||||
return visitor.visit_map(super::SpannedDeserializer::new(self, span));
|
||||
}
|
||||
}
|
||||
|
||||
self.deserialize_any(visitor)
|
||||
}
|
||||
|
||||
serde::forward_to_deserialize_any! {
|
||||
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
|
||||
bytes byte_buf map option unit newtype_struct
|
||||
ignored_any unit_struct tuple_struct tuple enum identifier
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for ArrayDeserializer {
|
||||
type Deserializer = Self;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Array {
|
||||
pub(crate) fn into_deserializer(self) -> ArrayDeserializer {
|
||||
ArrayDeserializer::new(self.values, self.span)
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::ArrayOfTables {
|
||||
pub(crate) fn into_deserializer(self) -> ArrayDeserializer {
|
||||
ArrayDeserializer::new(self.values, self.span)
|
||||
}
|
||||
}
|
||||
|
||||
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::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::de::DeserializeSeed<'de>,
|
||||
{
|
||||
match self.iter.next() {
|
||||
Some(v) => seed
|
||||
.deserialize(crate::de::ValueDeserializer::new(v))
|
||||
.map(Some),
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
43
third-party/vendor/toml_edit/src/de/datetime.rs
vendored
Normal file
43
third-party/vendor/toml_edit/src/de/datetime.rs
vendored
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
use serde::de::value::BorrowedStrDeserializer;
|
||||
use serde::de::IntoDeserializer;
|
||||
|
||||
use crate::de::Error;
|
||||
|
||||
pub(crate) struct DatetimeDeserializer {
|
||||
date: Option<crate::Datetime>,
|
||||
}
|
||||
|
||||
impl DatetimeDeserializer {
|
||||
pub(crate) fn new(date: crate::Datetime) -> Self {
|
||||
Self { date: Some(date) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::MapAccess<'de> for DatetimeDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||
where
|
||||
K: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
if self.date.is_some() {
|
||||
seed.deserialize(BorrowedStrDeserializer::new(
|
||||
toml_datetime::__unstable::FIELD,
|
||||
))
|
||||
.map(Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
if let Some(date) = self.date.take() {
|
||||
seed.deserialize(date.to_string().into_deserializer())
|
||||
} else {
|
||||
panic!("next_value_seed called before next_key_seed")
|
||||
}
|
||||
}
|
||||
}
|
||||
140
third-party/vendor/toml_edit/src/de/key.rs
vendored
Normal file
140
third-party/vendor/toml_edit/src/de/key.rs
vendored
Normal file
|
|
@ -0,0 +1,140 @@
|
|||
use serde::de::IntoDeserializer;
|
||||
|
||||
use super::Error;
|
||||
|
||||
pub(crate) struct KeyDeserializer {
|
||||
span: Option<std::ops::Range<usize>>,
|
||||
key: crate::InternalString,
|
||||
}
|
||||
|
||||
impl KeyDeserializer {
|
||||
pub(crate) fn new(key: crate::InternalString, span: Option<std::ops::Range<usize>>) -> Self {
|
||||
KeyDeserializer { span, key }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::IntoDeserializer<'de, Error> for KeyDeserializer {
|
||||
type Deserializer = Self;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::Deserializer<'de> for KeyDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: serde::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::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::de::Visitor<'de>,
|
||||
{
|
||||
if serde_spanned::__unstable::is_spanned(name, fields) {
|
||||
if let Some(span) = self.span.clone() {
|
||||
return visitor.visit_map(super::SpannedDeserializer::new(self.key.as_str(), span));
|
||||
}
|
||||
}
|
||||
self.deserialize_any(visitor)
|
||||
}
|
||||
|
||||
serde::forward_to_deserialize_any! {
|
||||
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
|
||||
bytes byte_buf map option unit newtype_struct
|
||||
ignored_any unit_struct tuple_struct tuple identifier
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::EnumAccess<'de> for KeyDeserializer {
|
||||
type Error = super::Error;
|
||||
type Variant = UnitOnly<Self::Error>;
|
||||
|
||||
fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
|
||||
where
|
||||
T: serde::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::de::VariantAccess<'de> for UnitOnly<E>
|
||||
where
|
||||
E: serde::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::de::DeserializeSeed<'de>,
|
||||
{
|
||||
Err(serde::de::Error::invalid_type(
|
||||
serde::de::Unexpected::UnitVariant,
|
||||
&"newtype variant",
|
||||
))
|
||||
}
|
||||
|
||||
fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(serde::de::Error::invalid_type(
|
||||
serde::de::Unexpected::UnitVariant,
|
||||
&"tuple variant",
|
||||
))
|
||||
}
|
||||
|
||||
fn struct_variant<V>(
|
||||
self,
|
||||
_fields: &'static [&'static str],
|
||||
_visitor: V,
|
||||
) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
Err(serde::de::Error::invalid_type(
|
||||
serde::de::Unexpected::UnitVariant,
|
||||
&"struct variant",
|
||||
))
|
||||
}
|
||||
}
|
||||
289
third-party/vendor/toml_edit/src/de/mod.rs
vendored
Normal file
289
third-party/vendor/toml_edit/src/de/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,289 @@
|
|||
//! Deserializing TOML into Rust structures.
|
||||
//!
|
||||
//! This module contains all the Serde support for deserializing TOML documents into Rust structures.
|
||||
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
mod array;
|
||||
mod datetime;
|
||||
mod key;
|
||||
mod spanned;
|
||||
mod table;
|
||||
mod table_enum;
|
||||
mod value;
|
||||
|
||||
use array::ArrayDeserializer;
|
||||
use datetime::DatetimeDeserializer;
|
||||
use key::KeyDeserializer;
|
||||
use spanned::SpannedDeserializer;
|
||||
use table::TableMapAccess;
|
||||
use table_enum::TableEnumDeserializer;
|
||||
|
||||
pub use value::ValueDeserializer;
|
||||
|
||||
/// Errors that can occur when deserializing a type.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
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,
|
||||
{
|
||||
Error {
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::de::Error for Error {
|
||||
fn custom<T>(msg: T) -> Self
|
||||
where
|
||||
T: std::fmt::Display,
|
||||
{
|
||||
Error::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 From<crate::TomlError> for Error {
|
||||
fn from(e: crate::TomlError) -> Error {
|
||||
Self { inner: e }
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for crate::TomlError {
|
||||
fn from(e: Error) -> crate::TomlError {
|
||||
e.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
/// Convert a value into `T`.
|
||||
pub fn from_str<T>(s: &'_ str) -> Result<T, Error>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
let de = s.parse::<Deserializer>()?;
|
||||
T::deserialize(de)
|
||||
}
|
||||
|
||||
/// Convert a value into `T`.
|
||||
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 document into `T`.
|
||||
pub fn from_document<T>(d: crate::Document) -> Result<T, Error>
|
||||
where
|
||||
T: DeserializeOwned,
|
||||
{
|
||||
let deserializer = Deserializer::new(d);
|
||||
T::deserialize(deserializer)
|
||||
}
|
||||
|
||||
/// Deserialization for TOML [documents][crate::Document].
|
||||
pub struct Deserializer {
|
||||
input: crate::Document,
|
||||
}
|
||||
|
||||
impl Deserializer {
|
||||
/// Deserialization implementation for TOML.
|
||||
pub fn new(input: crate::Document) -> Self {
|
||||
Self { input }
|
||||
}
|
||||
}
|
||||
|
||||
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 d = crate::parser::parse_document(s).map_err(Error::from)?;
|
||||
Ok(Self::new(d))
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this is wrapped by `toml::de::Deserializer` and any trait methods
|
||||
// implemented here need to be wrapped there
|
||||
impl<'de> serde::Deserializer<'de> for Deserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let original = self.input.original;
|
||||
self.input
|
||||
.root
|
||||
.into_deserializer()
|
||||
.deserialize_any(visitor)
|
||||
.map_err(|mut e: Self::Error| {
|
||||
e.inner.set_original(original);
|
||||
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::de::Visitor<'de>,
|
||||
{
|
||||
let original = self.input.original;
|
||||
self.input
|
||||
.root
|
||||
.into_deserializer()
|
||||
.deserialize_option(visitor)
|
||||
.map_err(|mut e: Self::Error| {
|
||||
e.inner.set_original(original);
|
||||
e
|
||||
})
|
||||
}
|
||||
|
||||
fn deserialize_newtype_struct<V>(
|
||||
self,
|
||||
name: &'static str,
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let original = self.input.original;
|
||||
self.input
|
||||
.root
|
||||
.into_deserializer()
|
||||
.deserialize_newtype_struct(name, visitor)
|
||||
.map_err(|mut e: Self::Error| {
|
||||
e.inner.set_original(original);
|
||||
e
|
||||
})
|
||||
}
|
||||
|
||||
fn deserialize_struct<V>(
|
||||
self,
|
||||
name: &'static str,
|
||||
fields: &'static [&'static str],
|
||||
visitor: V,
|
||||
) -> Result<V::Value, Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
let original = self.input.original;
|
||||
self.input
|
||||
.root
|
||||
.into_deserializer()
|
||||
.deserialize_struct(name, fields, visitor)
|
||||
.map_err(|mut e: Self::Error| {
|
||||
e.inner.set_original(original);
|
||||
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::de::Visitor<'de>,
|
||||
{
|
||||
let original = self.input.original;
|
||||
self.input
|
||||
.root
|
||||
.into_deserializer()
|
||||
.deserialize_enum(name, variants, visitor)
|
||||
.map_err(|mut e: Self::Error| {
|
||||
e.inner.set_original(original);
|
||||
e
|
||||
})
|
||||
}
|
||||
|
||||
serde::forward_to_deserialize_any! {
|
||||
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
|
||||
bytes byte_buf map unit
|
||||
ignored_any unit_struct tuple_struct tuple identifier
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for Deserializer {
|
||||
type Deserializer = Deserializer;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::Document {
|
||||
type Deserializer = Deserializer;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
Deserializer::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate_struct_keys(
|
||||
table: &crate::table::KeyValuePairs,
|
||||
fields: &'static [&'static str],
|
||||
) -> Result<(), Error> {
|
||||
let extra_fields = table
|
||||
.iter()
|
||||
.filter_map(|(key, val)| {
|
||||
if !fields.contains(&key.as_str()) {
|
||||
Some(val.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.key.get())
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "),
|
||||
fields.join(", "),
|
||||
),
|
||||
extra_fields[0].key.span(),
|
||||
))
|
||||
}
|
||||
}
|
||||
70
third-party/vendor/toml_edit/src/de/spanned.rs
vendored
Normal file
70
third-party/vendor/toml_edit/src/de/spanned.rs
vendored
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
use serde::de::value::BorrowedStrDeserializer;
|
||||
use serde::de::IntoDeserializer as _;
|
||||
|
||||
use super::Error;
|
||||
|
||||
pub(crate) struct SpannedDeserializer<'de, T: serde::de::IntoDeserializer<'de, Error>> {
|
||||
phantom_data: std::marker::PhantomData<&'de ()>,
|
||||
start: Option<usize>,
|
||||
end: Option<usize>,
|
||||
value: Option<T>,
|
||||
}
|
||||
|
||||
impl<'de, T> SpannedDeserializer<'de, T>
|
||||
where
|
||||
T: serde::de::IntoDeserializer<'de, Error>,
|
||||
{
|
||||
pub(crate) fn new(value: T, span: std::ops::Range<usize>) -> Self {
|
||||
Self {
|
||||
phantom_data: Default::default(),
|
||||
start: Some(span.start),
|
||||
end: Some(span.end),
|
||||
value: Some(value),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de, T> serde::de::MapAccess<'de> for SpannedDeserializer<'de, T>
|
||||
where
|
||||
T: serde::de::IntoDeserializer<'de, Error>,
|
||||
{
|
||||
type Error = Error;
|
||||
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
|
||||
where
|
||||
K: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
if self.start.is_some() {
|
||||
seed.deserialize(BorrowedStrDeserializer::new(
|
||||
serde_spanned::__unstable::START_FIELD,
|
||||
))
|
||||
.map(Some)
|
||||
} else if self.end.is_some() {
|
||||
seed.deserialize(BorrowedStrDeserializer::new(
|
||||
serde_spanned::__unstable::END_FIELD,
|
||||
))
|
||||
.map(Some)
|
||||
} else if self.value.is_some() {
|
||||
seed.deserialize(BorrowedStrDeserializer::new(
|
||||
serde_spanned::__unstable::VALUE_FIELD,
|
||||
))
|
||||
.map(Some)
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
|
||||
where
|
||||
V: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
if let Some(start) = self.start.take() {
|
||||
seed.deserialize(start.into_deserializer())
|
||||
} else if let Some(end) = self.end.take() {
|
||||
seed.deserialize(end.into_deserializer())
|
||||
} else if let Some(value) = self.value.take() {
|
||||
seed.deserialize(value.into_deserializer())
|
||||
} else {
|
||||
panic!("next_value_seed called before next_key_seed")
|
||||
}
|
||||
}
|
||||
}
|
||||
213
third-party/vendor/toml_edit/src/de/table.rs
vendored
Normal file
213
third-party/vendor/toml_edit/src/de/table.rs
vendored
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
use serde::de::IntoDeserializer;
|
||||
|
||||
use crate::de::Error;
|
||||
|
||||
pub(crate) struct TableDeserializer {
|
||||
span: Option<std::ops::Range<usize>>,
|
||||
items: crate::table::KeyValuePairs,
|
||||
}
|
||||
|
||||
// Note: this is wrapped by `Deserializer` and `ValueDeserializer` and any trait methods
|
||||
// implemented here need to be wrapped there
|
||||
impl<'de> serde::Deserializer<'de> for TableDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::Visitor<'de>,
|
||||
{
|
||||
visitor.visit_map(crate::de::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::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::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::de::Visitor<'de>,
|
||||
{
|
||||
if serde_spanned::__unstable::is_spanned(name, fields) {
|
||||
if let Some(span) = self.span.clone() {
|
||||
return visitor.visit_map(super::SpannedDeserializer::new(self, span));
|
||||
}
|
||||
}
|
||||
|
||||
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::de::Visitor<'de>,
|
||||
{
|
||||
if self.items.is_empty() {
|
||||
Err(crate::de::Error::custom(
|
||||
"wanted exactly 1 element, found 0 elements",
|
||||
self.span,
|
||||
))
|
||||
} else if self.items.len() != 1 {
|
||||
Err(crate::de::Error::custom(
|
||||
"wanted exactly 1 element, more than 1 element",
|
||||
self.span,
|
||||
))
|
||||
} else {
|
||||
visitor.visit_enum(crate::de::TableMapAccess::new(self))
|
||||
}
|
||||
}
|
||||
|
||||
serde::forward_to_deserialize_any! {
|
||||
bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string seq
|
||||
bytes byte_buf map unit
|
||||
ignored_any unit_struct tuple_struct tuple identifier
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for TableDeserializer {
|
||||
type Deserializer = TableDeserializer;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Table {
|
||||
pub(crate) fn into_deserializer(self) -> TableDeserializer {
|
||||
TableDeserializer {
|
||||
span: self.span(),
|
||||
items: self.items,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::InlineTable {
|
||||
pub(crate) fn into_deserializer(self) -> TableDeserializer {
|
||||
TableDeserializer {
|
||||
span: self.span(),
|
||||
items: self.items,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) struct TableMapAccess {
|
||||
iter: indexmap::map::IntoIter<crate::InternalString, crate::table::TableKeyValue>,
|
||||
span: Option<std::ops::Range<usize>>,
|
||||
value: Option<(crate::InternalString, crate::Item)>,
|
||||
}
|
||||
|
||||
impl TableMapAccess {
|
||||
pub(crate) fn new(input: TableDeserializer) -> Self {
|
||||
Self {
|
||||
iter: input.items.into_iter(),
|
||||
span: input.span,
|
||||
value: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::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::de::DeserializeSeed<'de>,
|
||||
{
|
||||
match self.iter.next() {
|
||||
Some((k, v)) => {
|
||||
let ret = seed
|
||||
.deserialize(super::KeyDeserializer::new(k, v.key.span()))
|
||||
.map(Some)
|
||||
.map_err(|mut e: Self::Error| {
|
||||
if e.span().is_none() {
|
||||
e.set_span(v.key.span());
|
||||
}
|
||||
e
|
||||
});
|
||||
self.value = Some((v.key.into(), v.value));
|
||||
ret
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::de::DeserializeSeed<'de>,
|
||||
{
|
||||
match self.value.take() {
|
||||
Some((k, v)) => {
|
||||
let span = v.span();
|
||||
seed.deserialize(crate::de::ValueDeserializer::new(v))
|
||||
.map_err(|mut e: Self::Error| {
|
||||
if e.span().is_none() {
|
||||
e.set_span(span);
|
||||
}
|
||||
e.add_key(k.as_str().to_owned());
|
||||
e
|
||||
})
|
||||
}
|
||||
None => {
|
||||
panic!("no more values in next_value_seed, internal error in ValueDeserializer")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::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::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(value.key.span());
|
||||
}
|
||||
e
|
||||
})?;
|
||||
|
||||
let variant = super::TableEnumDeserializer::new(value.value);
|
||||
|
||||
Ok((val, variant))
|
||||
}
|
||||
}
|
||||
160
third-party/vendor/toml_edit/src/de/table_enum.rs
vendored
Normal file
160
third-party/vendor/toml_edit/src/de/table_enum.rs
vendored
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
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 {
|
||||
TableEnumDeserializer { value }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::VariantAccess<'de> for TableEnumDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn unit_variant(self) -> Result<(), Self::Error> {
|
||||
match self.value {
|
||||
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::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::de::Visitor<'de>,
|
||||
{
|
||||
match self.value {
|
||||
crate::Item::Table(values) => {
|
||||
let values_span = values.span();
|
||||
let tuple_values = values
|
||||
.items
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(
|
||||
|(index, (_, value))| match value.key.get().parse::<usize>() {
|
||||
Ok(key_index) if key_index == index => Ok(value.value),
|
||||
Ok(_) | Err(_) => Err(Error::custom(
|
||||
format!(
|
||||
"expected table key `{}`, but was `{}`",
|
||||
index,
|
||||
value.key.get()
|
||||
),
|
||||
value.key.span(),
|
||||
)),
|
||||
},
|
||||
)
|
||||
// Fold all values into a `Vec`, or return the first error.
|
||||
.fold(Ok(Vec::with_capacity(len)), |result, value_result| {
|
||||
result.and_then(move |mut tuple_values| match value_result {
|
||||
Ok(value) => {
|
||||
tuple_values.push(value);
|
||||
Ok(tuple_values)
|
||||
}
|
||||
// `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>`
|
||||
Err(e) => Err(e),
|
||||
})
|
||||
})?;
|
||||
|
||||
if tuple_values.len() == len {
|
||||
serde::de::Deserializer::deserialize_seq(
|
||||
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 = values
|
||||
.items
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(
|
||||
|(index, (_, value))| match value.key.get().parse::<usize>() {
|
||||
Ok(key_index) if key_index == index => Ok(value.value),
|
||||
Ok(_) | Err(_) => Err(Error::custom(
|
||||
format!(
|
||||
"expected table key `{}`, but was `{}`",
|
||||
index,
|
||||
value.key.get()
|
||||
),
|
||||
value.key.span(),
|
||||
)),
|
||||
},
|
||||
)
|
||||
// Fold all values into a `Vec`, or return the first error.
|
||||
.fold(Ok(Vec::with_capacity(len)), |result, value_result| {
|
||||
result.and_then(move |mut tuple_values| match value_result {
|
||||
Ok(value) => {
|
||||
tuple_values.push(value);
|
||||
Ok(tuple_values)
|
||||
}
|
||||
// `Result<de::Value, Self::Error>` to `Result<Vec<_>, Self::Error>`
|
||||
Err(e) => Err(e),
|
||||
})
|
||||
})?;
|
||||
|
||||
if tuple_values.len() == len {
|
||||
serde::de::Deserializer::deserialize_seq(
|
||||
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::de::Visitor<'de>,
|
||||
{
|
||||
serde::de::Deserializer::deserialize_struct(
|
||||
super::ValueDeserializer::new(self.value).with_struct_key_validation(),
|
||||
"", // TODO: this should be the variant name
|
||||
fields,
|
||||
visitor,
|
||||
)
|
||||
}
|
||||
}
|
||||
252
third-party/vendor/toml_edit/src/de/value.rs
vendored
Normal file
252
third-party/vendor/toml_edit/src/de/value.rs
vendored
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
use serde::de::IntoDeserializer as _;
|
||||
|
||||
use crate::de::DatetimeDeserializer;
|
||||
use crate::de::Error;
|
||||
|
||||
/// 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 [`serde::de::IntoDeserializer::into_deserializer`].
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// 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
|
||||
}
|
||||
}
|
||||
|
||||
// Note: this is wrapped by `toml::de::ValueDeserializer` and any trait methods
|
||||
// implemented here need to be wrapped there
|
||||
impl<'de> serde::Deserializer<'de> for ValueDeserializer {
|
||||
type Error = Error;
|
||||
|
||||
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
|
||||
where
|
||||
V: serde::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)) => {
|
||||
v.into_deserializer().deserialize_any(visitor)
|
||||
}
|
||||
crate::Item::Value(crate::Value::InlineTable(v)) => {
|
||||
v.into_deserializer().deserialize_any(visitor)
|
||||
}
|
||||
crate::Item::Table(v) => v.into_deserializer().deserialize_any(visitor),
|
||||
crate::Item::ArrayOfTables(v) => v.into_deserializer().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::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::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::de::Visitor<'de>,
|
||||
{
|
||||
if serde_spanned::__unstable::is_spanned(name, fields) {
|
||||
if let Some(span) = self.input.span() {
|
||||
return visitor.visit_map(super::SpannedDeserializer::new(self, span));
|
||||
}
|
||||
}
|
||||
|
||||
if name == toml_datetime::__unstable::NAME && fields == [toml_datetime::__unstable::FIELD] {
|
||||
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) => super::validate_struct_keys(&values.items, fields),
|
||||
crate::Item::Value(crate::Value::InlineTable(values)) => {
|
||||
super::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::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(crate::de::Error::custom(
|
||||
"wanted exactly 1 element, found 0 elements",
|
||||
v.span(),
|
||||
))
|
||||
} else if v.len() != 1 {
|
||||
Err(crate::de::Error::custom(
|
||||
"wanted exactly 1 element, more than 1 element",
|
||||
v.span(),
|
||||
))
|
||||
} else {
|
||||
v.into_deserializer()
|
||||
.deserialize_enum(name, variants, visitor)
|
||||
}
|
||||
}
|
||||
crate::Item::Table(v) => v
|
||||
.into_deserializer()
|
||||
.deserialize_enum(name, variants, visitor),
|
||||
e => Err(crate::de::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::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<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for ValueDeserializer {
|
||||
type Deserializer = Self;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> serde::de::IntoDeserializer<'de, crate::de::Error> for crate::Value {
|
||||
type Deserializer = ValueDeserializer;
|
||||
|
||||
fn into_deserializer(self) -> Self::Deserializer {
|
||||
ValueDeserializer::new(crate::Item::Value(self))
|
||||
}
|
||||
}
|
||||
|
||||
impl crate::Item {
|
||||
pub(crate) fn into_deserializer(self) -> ValueDeserializer {
|
||||
ValueDeserializer::new(self)
|
||||
}
|
||||
}
|
||||
|
||||
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 v = crate::parser::parse_value(s).map_err(Error::from)?;
|
||||
Ok(v.into_deserializer())
|
||||
}
|
||||
}
|
||||
113
third-party/vendor/toml_edit/src/document.rs
vendored
Normal file
113
third-party/vendor/toml_edit/src/document.rs
vendored
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use crate::parser;
|
||||
use crate::table::Iter;
|
||||
use crate::{Item, RawString, Table};
|
||||
|
||||
/// Type representing a TOML document
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Document {
|
||||
pub(crate) root: Item,
|
||||
// Trailing comments and whitespaces
|
||||
pub(crate) trailing: RawString,
|
||||
pub(crate) original: Option<String>,
|
||||
pub(crate) span: Option<std::ops::Range<usize>>,
|
||||
}
|
||||
|
||||
impl Document {
|
||||
/// 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 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 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
|
||||
}
|
||||
|
||||
/// # Panics
|
||||
///
|
||||
/// If run on on a `Document` not generated by the parser
|
||||
pub(crate) fn despan(&mut self) {
|
||||
self.span = None;
|
||||
self.root.despan(self.original.as_deref().unwrap());
|
||||
self.trailing.despan(self.original.as_deref().unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Document {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
root: Item::Table(Table::with_pos(Some(0))),
|
||||
trailing: Default::default(),
|
||||
original: Default::default(),
|
||||
span: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Document {
|
||||
type Err = crate::TomlError;
|
||||
|
||||
/// Parses a document from a &str
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
let mut d = parser::parse_document(s)?;
|
||||
d.despan();
|
||||
Ok(d)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Document {
|
||||
type Target = Table;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.as_table()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::DerefMut for Document {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.as_table_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Table> for Document {
|
||||
fn from(root: Table) -> Self {
|
||||
Self {
|
||||
root: Item::Table(root),
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
569
third-party/vendor/toml_edit/src/encode.rs
vendored
Normal file
569
third-party/vendor/toml_edit/src/encode.rs
vendored
Normal file
|
|
@ -0,0 +1,569 @@
|
|||
use std::borrow::Cow;
|
||||
use std::fmt::{Display, Formatter, Result, Write};
|
||||
|
||||
use toml_datetime::*;
|
||||
|
||||
use crate::document::Document;
|
||||
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_TABLE_DECOR};
|
||||
use crate::value::{
|
||||
DEFAULT_LEADING_VALUE_DECOR, DEFAULT_TRAILING_VALUE_DECOR, DEFAULT_VALUE_DECOR,
|
||||
};
|
||||
use crate::{Array, InlineTable, Item, Table, Value};
|
||||
|
||||
pub(crate) trait Encode {
|
||||
fn encode(
|
||||
&self,
|
||||
buf: &mut dyn Write,
|
||||
input: Option<&str>,
|
||||
default_decor: (&str, &str),
|
||||
) -> Result;
|
||||
}
|
||||
|
||||
impl Encode for Key {
|
||||
fn encode(
|
||||
&self,
|
||||
buf: &mut dyn Write,
|
||||
input: Option<&str>,
|
||||
default_decor: (&str, &str),
|
||||
) -> Result {
|
||||
let decor = self.decor();
|
||||
decor.prefix_encode(buf, input, default_decor.0)?;
|
||||
|
||||
if let Some(input) = input {
|
||||
let repr = self
|
||||
.as_repr()
|
||||
.map(Cow::Borrowed)
|
||||
.unwrap_or_else(|| Cow::Owned(self.default_repr()));
|
||||
repr.encode(buf, input)?;
|
||||
} else {
|
||||
let repr = self.display_repr();
|
||||
write!(buf, "{}", repr)?;
|
||||
};
|
||||
|
||||
decor.suffix_encode(buf, input, default_decor.1)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'k> Encode for &'k [Key] {
|
||||
fn encode(
|
||||
&self,
|
||||
buf: &mut dyn Write,
|
||||
input: Option<&str>,
|
||||
default_decor: (&str, &str),
|
||||
) -> Result {
|
||||
for (i, key) in self.iter().enumerate() {
|
||||
let first = i == 0;
|
||||
let last = i + 1 == self.len();
|
||||
|
||||
let prefix = if first {
|
||||
default_decor.0
|
||||
} else {
|
||||
DEFAULT_KEY_PATH_DECOR.0
|
||||
};
|
||||
let suffix = if last {
|
||||
default_decor.1
|
||||
} else {
|
||||
DEFAULT_KEY_PATH_DECOR.1
|
||||
};
|
||||
|
||||
if !first {
|
||||
write!(buf, ".")?;
|
||||
}
|
||||
key.encode(buf, input, (prefix, suffix))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'k> Encode for &'k [&'k Key] {
|
||||
fn encode(
|
||||
&self,
|
||||
buf: &mut dyn Write,
|
||||
input: Option<&str>,
|
||||
default_decor: (&str, &str),
|
||||
) -> Result {
|
||||
for (i, key) in self.iter().enumerate() {
|
||||
let first = i == 0;
|
||||
let last = i + 1 == self.len();
|
||||
|
||||
let prefix = if first {
|
||||
default_decor.0
|
||||
} else {
|
||||
DEFAULT_KEY_PATH_DECOR.0
|
||||
};
|
||||
let suffix = if last {
|
||||
default_decor.1
|
||||
} else {
|
||||
DEFAULT_KEY_PATH_DECOR.1
|
||||
};
|
||||
|
||||
if !first {
|
||||
write!(buf, ".")?;
|
||||
}
|
||||
key.encode(buf, input, (prefix, suffix))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Encode for Formatted<T>
|
||||
where
|
||||
T: ValueRepr,
|
||||
{
|
||||
fn encode(
|
||||
&self,
|
||||
buf: &mut dyn Write,
|
||||
input: Option<&str>,
|
||||
default_decor: (&str, &str),
|
||||
) -> Result {
|
||||
let decor = self.decor();
|
||||
decor.prefix_encode(buf, input, default_decor.0)?;
|
||||
|
||||
if let Some(input) = input {
|
||||
let repr = self
|
||||
.as_repr()
|
||||
.map(Cow::Borrowed)
|
||||
.unwrap_or_else(|| Cow::Owned(self.default_repr()));
|
||||
repr.encode(buf, input)?;
|
||||
} else {
|
||||
let repr = self.display_repr();
|
||||
write!(buf, "{}", repr)?;
|
||||
};
|
||||
|
||||
decor.suffix_encode(buf, input, default_decor.1)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Array {
|
||||
fn encode(
|
||||
&self,
|
||||
buf: &mut dyn Write,
|
||||
input: Option<&str>,
|
||||
default_decor: (&str, &str),
|
||||
) -> Result {
|
||||
let decor = self.decor();
|
||||
decor.prefix_encode(buf, input, default_decor.0)?;
|
||||
write!(buf, "[")?;
|
||||
|
||||
for (i, elem) in self.iter().enumerate() {
|
||||
let inner_decor;
|
||||
if i == 0 {
|
||||
inner_decor = DEFAULT_LEADING_VALUE_DECOR;
|
||||
} else {
|
||||
inner_decor = DEFAULT_VALUE_DECOR;
|
||||
write!(buf, ",")?;
|
||||
}
|
||||
elem.encode(buf, input, inner_decor)?;
|
||||
}
|
||||
if self.trailing_comma() && !self.is_empty() {
|
||||
write!(buf, ",")?;
|
||||
}
|
||||
|
||||
self.trailing().encode_with_default(buf, input, "")?;
|
||||
write!(buf, "]")?;
|
||||
decor.suffix_encode(buf, input, default_decor.1)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for InlineTable {
|
||||
fn encode(
|
||||
&self,
|
||||
buf: &mut dyn Write,
|
||||
input: Option<&str>,
|
||||
default_decor: (&str, &str),
|
||||
) -> Result {
|
||||
let decor = self.decor();
|
||||
decor.prefix_encode(buf, input, default_decor.0)?;
|
||||
write!(buf, "{{")?;
|
||||
self.preamble().encode_with_default(buf, input, "")?;
|
||||
|
||||
let children = self.get_values();
|
||||
let len = children.len();
|
||||
for (i, (key_path, value)) in children.into_iter().enumerate() {
|
||||
if i != 0 {
|
||||
write!(buf, ",")?;
|
||||
}
|
||||
let inner_decor = if i == len - 1 {
|
||||
DEFAULT_TRAILING_VALUE_DECOR
|
||||
} else {
|
||||
DEFAULT_VALUE_DECOR
|
||||
};
|
||||
key_path
|
||||
.as_slice()
|
||||
.encode(buf, input, DEFAULT_INLINE_KEY_DECOR)?;
|
||||
write!(buf, "=")?;
|
||||
value.encode(buf, input, inner_decor)?;
|
||||
}
|
||||
|
||||
write!(buf, "}}")?;
|
||||
decor.suffix_encode(buf, input, default_decor.1)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Encode for Value {
|
||||
fn encode(
|
||||
&self,
|
||||
buf: &mut dyn Write,
|
||||
input: Option<&str>,
|
||||
default_decor: (&str, &str),
|
||||
) -> Result {
|
||||
match self {
|
||||
Value::String(repr) => repr.encode(buf, input, default_decor),
|
||||
Value::Integer(repr) => repr.encode(buf, input, default_decor),
|
||||
Value::Float(repr) => repr.encode(buf, input, default_decor),
|
||||
Value::Boolean(repr) => repr.encode(buf, input, default_decor),
|
||||
Value::Datetime(repr) => repr.encode(buf, input, default_decor),
|
||||
Value::Array(array) => array.encode(buf, input, default_decor),
|
||||
Value::InlineTable(table) => table.encode(buf, input, default_decor),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Document {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
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,
|
||||
self.original.as_deref(),
|
||||
table,
|
||||
&path,
|
||||
is_array,
|
||||
&mut first_table,
|
||||
)?;
|
||||
}
|
||||
self.trailing()
|
||||
.encode_with_default(f, self.original.as_deref(), "")
|
||||
}
|
||||
}
|
||||
|
||||
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 kv in table.items.values() {
|
||||
match kv.value {
|
||||
Item::Table(ref t) => {
|
||||
let mut key = kv.key.clone();
|
||||
if t.is_dotted() {
|
||||
// May have newlines and generally isn't written for standard tables
|
||||
key.decor_mut().clear();
|
||||
}
|
||||
path.push(key);
|
||||
visit_nested_tables(t, path, false, callback)?;
|
||||
path.pop();
|
||||
}
|
||||
Item::ArrayOfTables(ref a) => {
|
||||
for t in a.iter() {
|
||||
let key = kv.key.clone();
|
||||
path.push(key);
|
||||
visit_nested_tables(t, path, true, callback)?;
|
||||
path.pop();
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn visit_table(
|
||||
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)?;
|
||||
write!(buf, "[[")?;
|
||||
path.encode(buf, input, DEFAULT_KEY_PATH_DECOR)?;
|
||||
write!(buf, "]]")?;
|
||||
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)?;
|
||||
write!(buf, "[")?;
|
||||
path.encode(buf, input, DEFAULT_KEY_PATH_DECOR)?;
|
||||
write!(buf, "]")?;
|
||||
table.decor.suffix_encode(buf, input, default_decor.1)?;
|
||||
writeln!(buf)?;
|
||||
}
|
||||
// print table body
|
||||
for (key_path, value) in children {
|
||||
key_path.as_slice().encode(buf, input, DEFAULT_KEY_DECOR)?;
|
||||
write!(buf, "=")?;
|
||||
value.encode(buf, input, DEFAULT_VALUE_DECOR)?;
|
||||
writeln!(buf)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
impl ValueRepr for String {
|
||||
fn to_repr(&self) -> Repr {
|
||||
to_string_repr(self, None, None)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn to_string_repr(
|
||||
value: &str,
|
||||
style: Option<StringStyle>,
|
||||
literal: Option<bool>,
|
||||
) -> Repr {
|
||||
let (style, literal) = match (style, literal) {
|
||||
(Some(style), Some(literal)) => (style, literal),
|
||||
(_, Some(literal)) => (infer_style(value).0, literal),
|
||||
(Some(style), _) => (style, infer_style(value).1),
|
||||
(_, _) => infer_style(value),
|
||||
};
|
||||
|
||||
let mut output = String::with_capacity(value.len() * 2);
|
||||
if literal {
|
||||
output.push_str(style.literal_start());
|
||||
output.push_str(value);
|
||||
output.push_str(style.literal_end());
|
||||
} else {
|
||||
output.push_str(style.standard_start());
|
||||
for ch in value.chars() {
|
||||
match ch {
|
||||
'\u{8}' => output.push_str("\\b"),
|
||||
'\u{9}' => output.push_str("\\t"),
|
||||
'\u{a}' => match style {
|
||||
StringStyle::NewlineTriple => output.push('\n'),
|
||||
StringStyle::OnelineSingle => output.push_str("\\n"),
|
||||
_ => unreachable!(),
|
||||
},
|
||||
'\u{c}' => output.push_str("\\f"),
|
||||
'\u{d}' => output.push_str("\\r"),
|
||||
'\u{22}' => output.push_str("\\\""),
|
||||
'\u{5c}' => output.push_str("\\\\"),
|
||||
c if c <= '\u{1f}' || c == '\u{7f}' => {
|
||||
write!(output, "\\u{:04X}", ch as u32).unwrap();
|
||||
}
|
||||
ch => output.push(ch),
|
||||
}
|
||||
}
|
||||
output.push_str(style.standard_end());
|
||||
}
|
||||
|
||||
Repr::new_unchecked(output)
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||
pub(crate) enum StringStyle {
|
||||
NewlineTriple,
|
||||
OnelineTriple,
|
||||
OnelineSingle,
|
||||
}
|
||||
|
||||
impl StringStyle {
|
||||
fn literal_start(self) -> &'static str {
|
||||
match self {
|
||||
Self::NewlineTriple => "'''\n",
|
||||
Self::OnelineTriple => "'''",
|
||||
Self::OnelineSingle => "'",
|
||||
}
|
||||
}
|
||||
fn literal_end(self) -> &'static str {
|
||||
match self {
|
||||
Self::NewlineTriple => "'''",
|
||||
Self::OnelineTriple => "'''",
|
||||
Self::OnelineSingle => "'",
|
||||
}
|
||||
}
|
||||
|
||||
fn standard_start(self) -> &'static str {
|
||||
match self {
|
||||
Self::NewlineTriple => "\"\"\"\n",
|
||||
// note: OnelineTriple can happen if do_pretty wants to do
|
||||
// '''it's one line'''
|
||||
// but literal == false
|
||||
Self::OnelineTriple | Self::OnelineSingle => "\"",
|
||||
}
|
||||
}
|
||||
|
||||
fn standard_end(self) -> &'static str {
|
||||
match self {
|
||||
Self::NewlineTriple => "\"\"\"",
|
||||
// note: OnelineTriple can happen if do_pretty wants to do
|
||||
// '''it's one line'''
|
||||
// but literal == false
|
||||
Self::OnelineTriple | Self::OnelineSingle => "\"",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn infer_style(value: &str) -> (StringStyle, bool) {
|
||||
// For doing pretty prints we store in a new String
|
||||
// because there are too many cases where pretty cannot
|
||||
// work. We need to determine:
|
||||
// - if we are a "multi-line" pretty (if there are \n)
|
||||
// - if ['''] appears if multi or ['] if single
|
||||
// - if there are any invalid control characters
|
||||
//
|
||||
// Doing it any other way would require multiple passes
|
||||
// to determine if a pretty string works or not.
|
||||
let mut out = String::with_capacity(value.len() * 2);
|
||||
let mut ty = StringStyle::OnelineSingle;
|
||||
// found consecutive single quotes
|
||||
let mut max_found_singles = 0;
|
||||
let mut found_singles = 0;
|
||||
let mut prefer_literal = false;
|
||||
let mut can_be_pretty = true;
|
||||
|
||||
for ch in value.chars() {
|
||||
if can_be_pretty {
|
||||
if ch == '\'' {
|
||||
found_singles += 1;
|
||||
if found_singles >= 3 {
|
||||
can_be_pretty = false;
|
||||
}
|
||||
} else {
|
||||
if found_singles > max_found_singles {
|
||||
max_found_singles = found_singles;
|
||||
}
|
||||
found_singles = 0
|
||||
}
|
||||
match ch {
|
||||
'\t' => {}
|
||||
'\\' => {
|
||||
prefer_literal = true;
|
||||
}
|
||||
'\n' => ty = StringStyle::NewlineTriple,
|
||||
// Escape codes are needed if any ascii control
|
||||
// characters are present, including \b \f \r.
|
||||
c if c <= '\u{1f}' || c == '\u{7f}' => can_be_pretty = false,
|
||||
_ => {}
|
||||
}
|
||||
out.push(ch);
|
||||
} else {
|
||||
// the string cannot be represented as pretty,
|
||||
// still check if it should be multiline
|
||||
if ch == '\n' {
|
||||
ty = StringStyle::NewlineTriple;
|
||||
}
|
||||
}
|
||||
}
|
||||
if found_singles > 0 && value.ends_with('\'') {
|
||||
// We cannot escape the ending quote so we must use """
|
||||
can_be_pretty = false;
|
||||
}
|
||||
if !prefer_literal {
|
||||
can_be_pretty = false;
|
||||
}
|
||||
if !can_be_pretty {
|
||||
debug_assert!(ty != StringStyle::OnelineTriple);
|
||||
return (ty, false);
|
||||
}
|
||||
if found_singles > max_found_singles {
|
||||
max_found_singles = found_singles;
|
||||
}
|
||||
debug_assert!(max_found_singles < 3);
|
||||
if ty == StringStyle::OnelineSingle && max_found_singles >= 1 {
|
||||
// no newlines, but must use ''' because it has ' in it
|
||||
ty = StringStyle::OnelineTriple;
|
||||
}
|
||||
(ty, true)
|
||||
}
|
||||
|
||||
impl ValueRepr for i64 {
|
||||
fn to_repr(&self) -> Repr {
|
||||
Repr::new_unchecked(self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl ValueRepr for f64 {
|
||||
fn to_repr(&self) -> Repr {
|
||||
to_f64_repr(*self)
|
||||
}
|
||||
}
|
||||
|
||||
fn to_f64_repr(f: f64) -> Repr {
|
||||
let repr = match (f.is_sign_negative(), f.is_nan(), f == 0.0) {
|
||||
(true, true, _) => "-nan".to_owned(),
|
||||
(false, true, _) => "nan".to_owned(),
|
||||
(true, false, true) => "-0.0".to_owned(),
|
||||
(false, false, true) => "0.0".to_owned(),
|
||||
(_, false, false) => {
|
||||
if f % 1.0 == 0.0 {
|
||||
format!("{}.0", f)
|
||||
} else {
|
||||
format!("{}", f)
|
||||
}
|
||||
}
|
||||
};
|
||||
Repr::new_unchecked(repr)
|
||||
}
|
||||
|
||||
impl ValueRepr for bool {
|
||||
fn to_repr(&self) -> Repr {
|
||||
Repr::new_unchecked(self.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl ValueRepr for Datetime {
|
||||
fn to_repr(&self) -> Repr {
|
||||
Repr::new_unchecked(self.to_string())
|
||||
}
|
||||
}
|
||||
156
third-party/vendor/toml_edit/src/index.rs
vendored
Normal file
156
third-party/vendor/toml_edit/src/index.rs
vendored
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
use std::ops;
|
||||
|
||||
use crate::document::Document;
|
||||
use crate::key::Key;
|
||||
use crate::table::TableKeyValue;
|
||||
use crate::{value, InlineTable, InternalString, 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(|kv| {
|
||||
if !kv.value.is_none() {
|
||||
Some(&kv.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(
|
||||
InternalString::from(self),
|
||||
TableKeyValue::new(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| {
|
||||
&mut t
|
||||
.items
|
||||
.entry(InternalString::from(self))
|
||||
.or_insert_with(|| TableKeyValue::new(Key::new(self), Item::None))
|
||||
.value
|
||||
}),
|
||||
_ => 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<'a, T: ?Sized> Index for &'a 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 = Item;
|
||||
|
||||
fn index(&self, index: I) -> &Item {
|
||||
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 Item {
|
||||
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 Document {
|
||||
type Output = Item;
|
||||
|
||||
fn index(&self, key: &'s str) -> &Item {
|
||||
self.root.index(key)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> ops::IndexMut<&'s str> for Document {
|
||||
fn index_mut(&mut self, key: &'s str) -> &mut Item {
|
||||
self.root.index_mut(key)
|
||||
}
|
||||
}
|
||||
679
third-party/vendor/toml_edit/src/inline_table.rs
vendored
Normal file
679
third-party/vendor/toml_edit/src/inline_table.rs
vendored
Normal file
|
|
@ -0,0 +1,679 @@
|
|||
use std::iter::FromIterator;
|
||||
|
||||
use crate::key::Key;
|
||||
use crate::repr::Decor;
|
||||
use crate::table::{Iter, IterMut, KeyValuePairs, TableKeyValue, TableLike};
|
||||
use crate::{InternalString, Item, KeyMut, RawString, Table, Value};
|
||||
|
||||
/// Type representing a TOML inline table,
|
||||
/// payload of the `Value::InlineTable` variant
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct InlineTable {
|
||||
// `preamble` represents whitespaces in an empty table
|
||||
preamble: RawString,
|
||||
// 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, 'c>(
|
||||
&'s self,
|
||||
parent: &[&'s Key],
|
||||
values: &'c mut Vec<(Vec<&'s Key>, &'s Value)>,
|
||||
) {
|
||||
for value in self.items.values() {
|
||||
let mut path = parent.to_vec();
|
||||
path.push(&value.key);
|
||||
match &value.value {
|
||||
Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
|
||||
table.append_values(&path, values);
|
||||
}
|
||||
Item::Value(value) => {
|
||||
values.push((path, value));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Auto formats the table.
|
||||
pub fn fmt(&mut self) {
|
||||
decorate_inline_table(self);
|
||||
}
|
||||
|
||||
/// Sorts the key/value pairs by key.
|
||||
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 kv in self.items.values_mut() {
|
||||
match &mut kv.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).
|
||||
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 = |_: &InternalString,
|
||||
val1: &TableKeyValue,
|
||||
_: &InternalString,
|
||||
val2: &TableKeyValue|
|
||||
-> std::cmp::Ordering {
|
||||
match (val1.value.as_value(), val2.value.as_value()) {
|
||||
(Some(v1), Some(v2)) => compare(&val1.key, v1, &val2.key, 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 kv in self.items.values_mut() {
|
||||
match &mut kv.value {
|
||||
Item::Value(Value::InlineTable(table)) if table.is_dotted() => {
|
||||
table.sort_values_by_internal(compare);
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 the decor associated with a given key of the table.
|
||||
pub fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
|
||||
self.items.get_mut(key).map(|kv| &mut kv.key.decor)
|
||||
}
|
||||
|
||||
/// Returns the decor associated with a given key of the table.
|
||||
pub fn key_decor(&self, key: &str) -> Option<&Decor> {
|
||||
self.items.get(key).map(|kv| &kv.key.decor)
|
||||
}
|
||||
|
||||
/// 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
|
||||
}
|
||||
|
||||
/// Returns the location within the original document
|
||||
pub(crate) 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.preamble.despan(input);
|
||||
for kv in self.items.values_mut() {
|
||||
kv.key.despan(input);
|
||||
kv.value.despan(input);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl InlineTable {
|
||||
/// Returns an iterator over key/value pairs.
|
||||
pub fn iter(&self) -> InlineTableIter<'_> {
|
||||
Box::new(
|
||||
self.items
|
||||
.iter()
|
||||
.filter(|&(_, kv)| kv.value.is_value())
|
||||
.map(|(k, kv)| (&k[..], kv.value.as_value().unwrap())),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns an iterator over key/value pairs.
|
||||
pub fn iter_mut(&mut self) -> InlineTableIterMut<'_> {
|
||||
Box::new(
|
||||
self.items
|
||||
.iter_mut()
|
||||
.filter(|(_, kv)| kv.value.is_value())
|
||||
.map(|(_, kv)| (kv.key.as_mut(), kv.value.as_value_mut().unwrap())),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns the number of key/value pairs.
|
||||
pub fn len(&self) -> usize {
|
||||
self.iter().count()
|
||||
}
|
||||
|
||||
/// Returns true iff 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<InternalString>) -> InlineEntry<'_> {
|
||||
match self.items.entry(key.into()) {
|
||||
indexmap::map::Entry::Occupied(mut entry) => {
|
||||
// Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code.
|
||||
let scratch = std::mem::take(&mut entry.get_mut().value);
|
||||
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().value = scratch;
|
||||
|
||||
InlineEntry::Occupied(InlineOccupiedEntry { entry })
|
||||
}
|
||||
indexmap::map::Entry::Vacant(entry) => {
|
||||
InlineEntry::Vacant(InlineVacantEntry { entry, key: None })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 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.get().into()) {
|
||||
indexmap::map::Entry::Occupied(mut entry) => {
|
||||
// Ensure it is a `Value` to simplify `InlineOccupiedEntry`'s code.
|
||||
let scratch = std::mem::take(&mut entry.get_mut().value);
|
||||
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().value = scratch;
|
||||
|
||||
InlineEntry::Occupied(InlineOccupiedEntry { entry })
|
||||
}
|
||||
indexmap::map::Entry::Vacant(entry) => InlineEntry::Vacant(InlineVacantEntry {
|
||||
entry,
|
||||
key: Some(key.clone()),
|
||||
}),
|
||||
}
|
||||
}
|
||||
/// 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(|kv| kv.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(|kv| kv.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(key).and_then(|kv| {
|
||||
if !kv.value.is_none() {
|
||||
Some((&kv.key, &kv.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)> {
|
||||
self.items.get_mut(key).and_then(|kv| {
|
||||
if !kv.value.is_none() {
|
||||
Some((kv.key.as_mut(), &mut kv.value))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Returns true iff the table contains given key.
|
||||
pub fn contains_key(&self, key: &str) -> bool {
|
||||
if let Some(kv) = self.items.get(key) {
|
||||
kv.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<InternalString>,
|
||||
value: V,
|
||||
) -> &mut Value {
|
||||
let key = key.into();
|
||||
self.items
|
||||
.entry(key.clone())
|
||||
.or_insert(TableKeyValue::new(Key::new(key), Item::Value(value.into())))
|
||||
.value
|
||||
.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<InternalString>, value: Value) -> Option<Value> {
|
||||
let key = key.into();
|
||||
let kv = TableKeyValue::new(Key::new(key.clone()), Item::Value(value));
|
||||
self.items
|
||||
.insert(key, kv)
|
||||
.and_then(|kv| kv.value.into_value().ok())
|
||||
}
|
||||
|
||||
/// Inserts a key-value pair into the map.
|
||||
pub fn insert_formatted(&mut self, key: &Key, value: Value) -> Option<Value> {
|
||||
let kv = TableKeyValue::new(key.to_owned(), Item::Value(value));
|
||||
self.items
|
||||
.insert(InternalString::from(key.get()), kv)
|
||||
.filter(|kv| kv.value.is_value())
|
||||
.map(|kv| kv.value.into_value().unwrap())
|
||||
}
|
||||
|
||||
/// Removes an item given the key.
|
||||
pub fn remove(&mut self, key: &str) -> Option<Value> {
|
||||
self.items
|
||||
.shift_remove(key)
|
||||
.and_then(|kv| kv.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(key).and_then(|kv| {
|
||||
let key = kv.key;
|
||||
kv.value.into_value().ok().map(|value| (key, value))
|
||||
})
|
||||
}
|
||||
|
||||
/// 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.value
|
||||
.as_value_mut()
|
||||
.map(|value| keep(key, value))
|
||||
.unwrap_or(false)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for InlineTable {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
crate::encode::Encode::encode(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());
|
||||
let value = TableKeyValue::new(key, value);
|
||||
self.items
|
||||
.insert(InternalString::from(value.key.get()), 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 = InlineTable::new();
|
||||
table.extend(iter);
|
||||
table
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for InlineTable {
|
||||
type Item = (InternalString, Value);
|
||||
type IntoIter = InlineTableIntoIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
Box::new(
|
||||
self.items
|
||||
.into_iter()
|
||||
.filter(|(_, kv)| kv.value.is_value())
|
||||
.map(|(k, kv)| (k, kv.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) {
|
||||
for (key_decor, value) in table
|
||||
.items
|
||||
.iter_mut()
|
||||
.filter(|&(_, ref kv)| kv.value.is_value())
|
||||
.map(|(_, kv)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap()))
|
||||
{
|
||||
key_decor.clear();
|
||||
value.decor_mut().clear();
|
||||
}
|
||||
}
|
||||
|
||||
/// An owned iterator type over key/value pairs of an inline table.
|
||||
pub type InlineTableIntoIter = Box<dyn Iterator<Item = (InternalString, Value)>>;
|
||||
/// An iterator type over key/value pairs of an inline table.
|
||||
pub type InlineTableIter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Value)> + 'a>;
|
||||
/// A mutable iterator type over key/value pairs of an inline table.
|
||||
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, kv)| (&key[..], &kv.value)))
|
||||
}
|
||||
fn iter_mut(&mut self) -> IterMut<'_> {
|
||||
Box::new(
|
||||
self.items
|
||||
.iter_mut()
|
||||
.map(|(_, kv)| (kv.key.as_mut(), &mut kv.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 `InternalString`, 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, key: None })
|
||||
}
|
||||
}
|
||||
}
|
||||
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,
|
||||
key: Some(key.to_owned()),
|
||||
}),
|
||||
}
|
||||
}
|
||||
fn get<'s>(&'s self, key: &str) -> Option<&'s Item> {
|
||||
self.items.get(key).map(|kv| &kv.value)
|
||||
}
|
||||
fn get_mut<'s>(&'s mut self, key: &str) -> Option<&'s mut Item> {
|
||||
self.items.get_mut(key).map(|kv| &mut kv.value)
|
||||
}
|
||||
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_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
|
||||
self.key_decor_mut(key)
|
||||
}
|
||||
fn key_decor(&self, key: &str) -> Option<&Decor> {
|
||||
self.key_decor(key)
|
||||
}
|
||||
}
|
||||
|
||||
// `{ key1 = value1, ... }`
|
||||
pub(crate) const DEFAULT_INLINE_KEY_DECOR: (&str, &str) = (" ", " ");
|
||||
|
||||
/// A view into a single location in a map, 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 a `IndexMap`.
|
||||
pub struct InlineOccupiedEntry<'a> {
|
||||
entry: indexmap::map::OccupiedEntry<'a, InternalString, TableKeyValue>,
|
||||
}
|
||||
|
||||
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().as_str()
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the entry key
|
||||
pub fn key_mut(&mut self) -> KeyMut<'_> {
|
||||
self.entry.get_mut().key.as_mut()
|
||||
}
|
||||
|
||||
/// Gets a reference to the value in the entry.
|
||||
pub fn get(&self) -> &Value {
|
||||
self.entry.get().value.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().value.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().value.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 mut value = Item::Value(value);
|
||||
std::mem::swap(&mut value, &mut self.entry.get_mut().value);
|
||||
value.into_value().unwrap()
|
||||
}
|
||||
|
||||
/// Takes the value out of the entry, and returns it
|
||||
pub fn remove(self) -> Value {
|
||||
self.entry.shift_remove().value.into_value().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
/// A view into a single empty location in a `IndexMap`.
|
||||
pub struct InlineVacantEntry<'a> {
|
||||
entry: indexmap::map::VacantEntry<'a, InternalString, TableKeyValue>,
|
||||
key: Option<Key>,
|
||||
}
|
||||
|
||||
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().as_str()
|
||||
}
|
||||
|
||||
/// 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 key = self.key.unwrap_or_else(|| Key::new(entry.key().as_str()));
|
||||
let value = Item::Value(value);
|
||||
entry
|
||||
.insert(TableKeyValue::new(key, value))
|
||||
.value
|
||||
.as_value_mut()
|
||||
.unwrap()
|
||||
}
|
||||
}
|
||||
183
third-party/vendor/toml_edit/src/internal_string.rs
vendored
Normal file
183
third-party/vendor/toml_edit/src/internal_string.rs
vendored
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
use std::borrow::Borrow;
|
||||
use std::str::FromStr;
|
||||
|
||||
/// Opaque string storage internal to `toml_edit`
|
||||
#[derive(Default, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct InternalString(Inner);
|
||||
|
||||
#[cfg(feature = "kstring")]
|
||||
type Inner = kstring::KString;
|
||||
#[cfg(not(feature = "kstring"))]
|
||||
type Inner = String;
|
||||
|
||||
impl InternalString {
|
||||
/// Create an empty string
|
||||
pub fn new() -> Self {
|
||||
InternalString(Inner::new())
|
||||
}
|
||||
|
||||
/// Access the underlying string
|
||||
#[inline]
|
||||
pub fn as_str(&self) -> &str {
|
||||
self.0.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for InternalString {
|
||||
#[inline]
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
self.0.fmt(formatter)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for InternalString {
|
||||
type Target = str;
|
||||
|
||||
#[inline]
|
||||
fn deref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl Borrow<str> for InternalString {
|
||||
#[inline]
|
||||
fn borrow(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl AsRef<str> for InternalString {
|
||||
#[inline]
|
||||
fn as_ref(&self) -> &str {
|
||||
self.as_str()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&str> for InternalString {
|
||||
#[inline]
|
||||
fn from(s: &str) -> Self {
|
||||
#[cfg(feature = "kstring")]
|
||||
let inner = kstring::KString::from_ref(s);
|
||||
#[cfg(not(feature = "kstring"))]
|
||||
let inner = String::from(s);
|
||||
|
||||
InternalString(inner)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for InternalString {
|
||||
#[inline]
|
||||
fn from(s: String) -> Self {
|
||||
#[allow(clippy::useless_conversion)] // handle any string type
|
||||
InternalString(s.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&String> for InternalString {
|
||||
#[inline]
|
||||
fn from(s: &String) -> Self {
|
||||
InternalString(s.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&InternalString> for InternalString {
|
||||
#[inline]
|
||||
fn from(s: &InternalString) -> Self {
|
||||
s.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<str>> for InternalString {
|
||||
#[inline]
|
||||
fn from(s: Box<str>) -> Self {
|
||||
InternalString(s.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for InternalString {
|
||||
type Err = core::convert::Infallible;
|
||||
#[inline]
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
Ok(Self::from(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for InternalString {
|
||||
#[inline]
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
self.as_str().fmt(f)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl serde::Serialize for InternalString {
|
||||
#[inline]
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde::Serializer,
|
||||
{
|
||||
serializer.serialize_str(self.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> serde::Deserialize<'de> for InternalString {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: serde::Deserializer<'de>,
|
||||
{
|
||||
deserializer.deserialize_string(StringVisitor)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
struct StringVisitor;
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de> serde::de::Visitor<'de> for StringVisitor {
|
||||
type Value = InternalString;
|
||||
|
||||
fn expecting(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
formatter.write_str("a string")
|
||||
}
|
||||
|
||||
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(InternalString::from(v))
|
||||
}
|
||||
|
||||
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
Ok(InternalString::from(v))
|
||||
}
|
||||
|
||||
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
match std::str::from_utf8(v) {
|
||||
Ok(s) => Ok(InternalString::from(s)),
|
||||
Err(_) => Err(serde::de::Error::invalid_value(
|
||||
serde::de::Unexpected::Bytes(v),
|
||||
&self,
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
|
||||
where
|
||||
E: serde::de::Error,
|
||||
{
|
||||
match String::from_utf8(v) {
|
||||
Ok(s) => Ok(InternalString::from(s)),
|
||||
Err(e) => Err(serde::de::Error::invalid_value(
|
||||
serde::de::Unexpected::Bytes(&e.into_bytes()),
|
||||
&self,
|
||||
)),
|
||||
}
|
||||
}
|
||||
}
|
||||
393
third-party/vendor/toml_edit/src/item.rs
vendored
Normal file
393
third-party/vendor/toml_edit/src/item.rs
vendored
Normal file
|
|
@ -0,0 +1,393 @@
|
|||
use std::str::FromStr;
|
||||
|
||||
use toml_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)]
|
||||
pub enum Item {
|
||||
/// Type representing none.
|
||||
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 iff `self` is none and
|
||||
/// returns a mutable reference to `self`.
|
||||
pub fn or_insert(&mut self, item: Item) -> &mut Item {
|
||||
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 {
|
||||
Item::None => "none",
|
||||
Item::Value(v) => v.type_name(),
|
||||
Item::Table(..) => "table",
|
||||
Item::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<&Item> {
|
||||
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 Item> {
|
||||
index.index_mut(self)
|
||||
}
|
||||
|
||||
/// Casts `self` to value.
|
||||
pub fn as_value(&self) -> Option<&Value> {
|
||||
match *self {
|
||||
Item::Value(ref v) => Some(v),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
/// Casts `self` to table.
|
||||
pub fn as_table(&self) -> Option<&Table> {
|
||||
match *self {
|
||||
Item::Table(ref t) => Some(t),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
/// Casts `self` to array of tables.
|
||||
pub fn as_array_of_tables(&self) -> Option<&ArrayOfTables> {
|
||||
match *self {
|
||||
Item::ArrayOfTables(ref a) => Some(a),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
/// Casts `self` to mutable value.
|
||||
pub fn as_value_mut(&mut self) -> Option<&mut Value> {
|
||||
match *self {
|
||||
Item::Value(ref mut v) => Some(v),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
/// Casts `self` to mutable table.
|
||||
pub fn as_table_mut(&mut self) -> Option<&mut Table> {
|
||||
match *self {
|
||||
Item::Table(ref mut t) => Some(t),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
/// Casts `self` to mutable array of tables.
|
||||
pub fn as_array_of_tables_mut(&mut self) -> Option<&mut ArrayOfTables> {
|
||||
match *self {
|
||||
Item::ArrayOfTables(ref mut a) => Some(a),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
/// Casts `self` to value.
|
||||
pub fn into_value(self) -> Result<Value, Self> {
|
||||
match self {
|
||||
Item::None => Err(self),
|
||||
Item::Value(v) => Ok(v),
|
||||
Item::Table(v) => {
|
||||
let v = v.into_inline_table();
|
||||
Ok(Value::InlineTable(v))
|
||||
}
|
||||
Item::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(Item::None);
|
||||
*self = other;
|
||||
}
|
||||
/// Casts `self` to table.
|
||||
pub fn into_table(self) -> Result<Table, Self> {
|
||||
match self {
|
||||
Item::Table(t) => Ok(t),
|
||||
Item::Value(Value::InlineTable(t)) => Ok(t.into_table()),
|
||||
_ => Err(self),
|
||||
}
|
||||
}
|
||||
/// Casts `self` to array of tables.
|
||||
pub fn into_array_of_tables(self) -> Result<ArrayOfTables, Self> {
|
||||
match self {
|
||||
Item::ArrayOfTables(a) => Ok(a),
|
||||
Item::Value(Value::Array(a)) => {
|
||||
if a.is_empty() {
|
||||
Err(Item::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(Item::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(crate::Item::Table) {
|
||||
Ok(i) => i,
|
||||
Err(i) => i,
|
||||
};
|
||||
let other = match other.into_array_of_tables().map(crate::Item::ArrayOfTables) {
|
||||
Ok(i) => i,
|
||||
Err(i) => i,
|
||||
};
|
||||
*self = other;
|
||||
}
|
||||
/// Returns true iff `self` is a value.
|
||||
pub fn is_value(&self) -> bool {
|
||||
self.as_value().is_some()
|
||||
}
|
||||
/// Returns true iff `self` is a table.
|
||||
pub fn is_table(&self) -> bool {
|
||||
self.as_table().is_some()
|
||||
}
|
||||
/// Returns true iff `self` is an array of tables.
|
||||
pub fn is_array_of_tables(&self) -> bool {
|
||||
self.as_array_of_tables().is_some()
|
||||
}
|
||||
/// Returns true iff `self` is `None`.
|
||||
pub fn is_none(&self) -> bool {
|
||||
matches!(*self, Item::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 iff `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 iff `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 iff `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 iff `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 iff `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 iff `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 iff `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 {
|
||||
Item::Table(t) => Some(t as &mut dyn TableLike),
|
||||
Item::Value(Value::InlineTable(t)) => Some(t as &mut dyn TableLike),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true iff `self` is either a table, or an inline table.
|
||||
pub fn is_table_like(&self) -> bool {
|
||||
self.as_table_like().is_some()
|
||||
}
|
||||
|
||||
/// Returns the location within the original document
|
||||
pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> {
|
||||
match self {
|
||||
Item::None => None,
|
||||
Item::Value(v) => v.span(),
|
||||
Item::Table(v) => v.span(),
|
||||
Item::ArrayOfTables(v) => v.span(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn despan(&mut self, input: &str) {
|
||||
match self {
|
||||
Item::None => {}
|
||||
Item::Value(v) => v.despan(input),
|
||||
Item::Table(v) => v.despan(input),
|
||||
Item::ArrayOfTables(v) => v.despan(input),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Clone for Item {
|
||||
#[inline(never)]
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
Item::None => Item::None,
|
||||
Item::Value(v) => Item::Value(v.clone()),
|
||||
Item::Table(v) => Item::Table(v.clone()),
|
||||
Item::ArrayOfTables(v) => Item::ArrayOfTables(v.clone()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Item {
|
||||
fn default() -> Self {
|
||||
Item::None
|
||||
}
|
||||
}
|
||||
|
||||
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(Item::Value(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Item {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match &self {
|
||||
Item::None => Ok(()),
|
||||
Item::Value(v) => v.fmt(f),
|
||||
Item::Table(v) => v.fmt(f),
|
||||
Item::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
|
||||
/// # use snapbox::assert_eq;
|
||||
/// # 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())
|
||||
}
|
||||
344
third-party/vendor/toml_edit/src/key.rs
vendored
Normal file
344
third-party/vendor/toml_edit/src/key.rs
vendored
Normal file
|
|
@ -0,0 +1,344 @@
|
|||
use std::borrow::Cow;
|
||||
use std::str::FromStr;
|
||||
|
||||
use crate::encode::{to_string_repr, StringStyle};
|
||||
use crate::parser;
|
||||
use crate::parser::key::is_unquoted_char;
|
||||
use crate::repr::{Decor, Repr};
|
||||
use crate::InternalString;
|
||||
|
||||
/// Key as part of a Key/Value Pair or a table header.
|
||||
///
|
||||
/// # 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: InternalString,
|
||||
pub(crate) repr: Option<Repr>,
|
||||
pub(crate) decor: Decor,
|
||||
}
|
||||
|
||||
impl Key {
|
||||
/// Create a new table key
|
||||
pub fn new(key: impl Into<InternalString>) -> Self {
|
||||
Self {
|
||||
key: key.into(),
|
||||
repr: None,
|
||||
decor: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse a TOML key expression
|
||||
///
|
||||
/// Unlike `"".parse<Key>()`, this supports dotted keys.
|
||||
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
|
||||
pub fn with_decor(mut self, decor: Decor) -> Self {
|
||||
self.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
|
||||
}
|
||||
|
||||
pub(crate) fn get_internal(&self) -> &InternalString {
|
||||
&self.key
|
||||
}
|
||||
|
||||
/// Returns key raw representation, if available.
|
||||
pub fn as_repr(&self) -> Option<&Repr> {
|
||||
self.repr.as_ref()
|
||||
}
|
||||
|
||||
/// Returns the default raw representation.
|
||||
pub fn default_repr(&self) -> Repr {
|
||||
to_key_repr(&self.key)
|
||||
}
|
||||
|
||||
/// Returns a raw representation.
|
||||
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
|
||||
pub fn decor_mut(&mut self) -> &mut Decor {
|
||||
&mut self.decor
|
||||
}
|
||||
|
||||
/// Returns the surrounding whitespace
|
||||
pub fn decor(&self) -> &Decor {
|
||||
&self.decor
|
||||
}
|
||||
|
||||
/// Returns the location within the original document
|
||||
#[cfg(feature = "serde")]
|
||||
pub(crate) 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)
|
||||
}
|
||||
}
|
||||
|
||||
/// Auto formats the key.
|
||||
pub fn fmt(&mut self) {
|
||||
self.repr = Some(to_key_repr(&self.key));
|
||||
self.decor.clear();
|
||||
}
|
||||
|
||||
fn try_parse_simple(s: &str) -> Result<Key, crate::TomlError> {
|
||||
let mut key = parser::parse_key(s)?;
|
||||
key.despan(s);
|
||||
Ok(key)
|
||||
}
|
||||
|
||||
fn try_parse_path(s: &str) -> Result<Vec<Key>, crate::TomlError> {
|
||||
let mut keys = parser::parse_key_path(s)?;
|
||||
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(),
|
||||
decor: self.decor.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl std::ops::Deref for Key {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
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: &Key) -> 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<'s> PartialEq<&'s 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())
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Key {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
crate::encode::Encode::encode(self, f, None, ("", ""))
|
||||
}
|
||||
}
|
||||
|
||||
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> {
|
||||
Key::try_parse_simple(s)
|
||||
}
|
||||
}
|
||||
|
||||
fn to_key_repr(key: &str) -> Repr {
|
||||
if key.as_bytes().iter().copied().all(is_unquoted_char) && !key.is_empty() {
|
||||
Repr::new_unchecked(key)
|
||||
} else {
|
||||
to_string_repr(key, Some(StringStyle::OnelineSingle), Some(false))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> From<&'b str> for Key {
|
||||
fn from(s: &'b str) -> Self {
|
||||
Key::new(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> From<&'b String> for Key {
|
||||
fn from(s: &'b String) -> Self {
|
||||
Key::new(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for Key {
|
||||
fn from(s: String) -> Self {
|
||||
Key::new(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InternalString> for Key {
|
||||
fn from(s: InternalString) -> Self {
|
||||
Key::new(s)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
impl From<Key> for InternalString {
|
||||
fn from(key: Key) -> InternalString {
|
||||
key.key
|
||||
}
|
||||
}
|
||||
|
||||
/// A mutable reference to a `Key`
|
||||
#[derive(Debug, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
||||
pub struct KeyMut<'k> {
|
||||
key: &'k mut Key,
|
||||
}
|
||||
|
||||
impl<'k> KeyMut<'k> {
|
||||
/// 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.
|
||||
pub fn default_repr(&self) -> Repr {
|
||||
self.key.default_repr()
|
||||
}
|
||||
|
||||
/// Returns a raw representation.
|
||||
pub fn display_repr(&self) -> Cow<str> {
|
||||
self.key.display_repr()
|
||||
}
|
||||
|
||||
/// Returns the surrounding whitespace
|
||||
pub fn decor_mut(&mut self) -> &mut Decor {
|
||||
self.key.decor_mut()
|
||||
}
|
||||
|
||||
/// Returns the surrounding whitespace
|
||||
pub fn decor(&self) -> &Decor {
|
||||
self.key.decor()
|
||||
}
|
||||
|
||||
/// Auto formats the key.
|
||||
pub fn fmt(&mut self) {
|
||||
self.key.fmt()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'k> std::ops::Deref for KeyMut<'k> {
|
||||
type Target = str;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.get()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'s> PartialEq<str> for KeyMut<'s> {
|
||||
#[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<'s> PartialEq<String> for KeyMut<'s> {
|
||||
#[inline]
|
||||
fn eq(&self, other: &String) -> bool {
|
||||
PartialEq::eq(self.get(), other.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'k> std::fmt::Display for KeyMut<'k> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
std::fmt::Display::fmt(&self.key, f)
|
||||
}
|
||||
}
|
||||
124
third-party/vendor/toml_edit/src/lib.rs
vendored
Normal file
124
third-party/vendor/toml_edit/src/lib.rs
vendored
Normal file
|
|
@ -0,0 +1,124 @@
|
|||
#![deny(missing_docs)]
|
||||
// https://github.com/Marwes/combine/issues/172
|
||||
#![recursion_limit = "256"]
|
||||
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
|
||||
|
||||
//! # `toml_edit`
|
||||
//!
|
||||
//! This crate allows you to parse and modify toml
|
||||
//! documents, while preserving comments, spaces *and
|
||||
//! relative order* or items.
|
||||
//!
|
||||
//! If you also need the ease of a more traditional API, see the [`toml`] crate.
|
||||
//!
|
||||
//! # Example
|
||||
//!
|
||||
//! ```rust
|
||||
//! use toml_edit::{Document, value};
|
||||
//!
|
||||
//! let toml = r#"
|
||||
//! "hello" = 'toml!' # comment
|
||||
//! ['a'.b]
|
||||
//! "#;
|
||||
//! let mut doc = toml.parse::<Document>().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
|
||||
//! let mut doc = toml_edit::Document::new();
|
||||
//! doc["foo"] = toml_edit::value("bar");
|
||||
//! let expected = r#"foo = "bar"
|
||||
//! "#;
|
||||
//! assert_eq!(doc.to_string(), expected);
|
||||
//! ```
|
||||
//!
|
||||
//! You can choose a custom TOML representation by parsing the value.
|
||||
//! ```rust
|
||||
//! let mut doc = toml_edit::Document::new();
|
||||
//! doc["foo"] = "'bar'".parse::<toml_edit::Item>().unwrap();
|
||||
//! let expected = r#"foo = 'bar'
|
||||
//! "#;
|
||||
//! assert_eq!(doc.to_string(), expected);
|
||||
//! ```
|
||||
//!
|
||||
//! ## Limitations
|
||||
//!
|
||||
//! Things it does not preserve:
|
||||
//!
|
||||
//! * Scattered array of tables (tables are reordered by default, see [test]).
|
||||
//! * Order of dotted keys, see [issue](https://github.com/ordian/toml_edit/issues/163).
|
||||
//!
|
||||
//! [`toml`]: https://docs.rs/toml/latest/toml/
|
||||
//! [test]: https://github.com/ordian/toml_edit/blob/f09bd5d075fdb7d2ef8d9bb3270a34506c276753/tests/test_valid.rs#L84
|
||||
|
||||
mod array;
|
||||
mod array_of_tables;
|
||||
mod document;
|
||||
mod encode;
|
||||
mod index;
|
||||
mod inline_table;
|
||||
mod internal_string;
|
||||
mod item;
|
||||
mod key;
|
||||
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::Document;
|
||||
pub use crate::inline_table::{
|
||||
InlineEntry, InlineOccupiedEntry, InlineTable, InlineTableIntoIter, InlineTableIter,
|
||||
InlineTableIterMut, InlineVacantEntry,
|
||||
};
|
||||
pub use crate::internal_string::InternalString;
|
||||
pub use crate::item::{array, table, value, Item};
|
||||
pub use crate::key::{Key, KeyMut};
|
||||
pub use crate::parser::TomlError;
|
||||
pub use crate::raw_string::RawString;
|
||||
pub use crate::repr::{Decor, Formatted, Repr};
|
||||
pub use crate::table::{
|
||||
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<'a, T: ?Sized> Sealed for &'a T where T: Sealed {}
|
||||
impl Sealed for crate::Table {}
|
||||
impl Sealed for crate::InlineTable {}
|
||||
}
|
||||
146
third-party/vendor/toml_edit/src/parser/array.rs
vendored
Normal file
146
third-party/vendor/toml_edit/src/parser/array.rs
vendored
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
use winnow::combinator::cut_err;
|
||||
use winnow::combinator::delimited;
|
||||
use winnow::combinator::opt;
|
||||
use winnow::combinator::separated1;
|
||||
use winnow::trace::trace;
|
||||
|
||||
use crate::parser::trivia::ws_comment_newline;
|
||||
use crate::parser::value::value;
|
||||
use crate::{Array, Item, RawString, Value};
|
||||
|
||||
use crate::parser::prelude::*;
|
||||
|
||||
// ;; Array
|
||||
|
||||
// array = array-open array-values array-close
|
||||
pub(crate) fn array<'i>(check: RecursionCheck) -> impl Parser<Input<'i>, Array, ContextError> {
|
||||
trace("array", move |input: &mut Input<'i>| {
|
||||
delimited(
|
||||
ARRAY_OPEN,
|
||||
cut_err(array_values(check)),
|
||||
cut_err(ARRAY_CLOSE)
|
||||
.context(StrContext::Label("array"))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral(']'))),
|
||||
)
|
||||
.parse_next(input)
|
||||
})
|
||||
}
|
||||
|
||||
// note: we're omitting ws and newlines here, because
|
||||
// they should be part of the formatted values
|
||||
// array-open = %x5B ws-newline ; [
|
||||
pub(crate) const ARRAY_OPEN: u8 = b'[';
|
||||
// array-close = ws-newline %x5D ; ]
|
||||
const ARRAY_CLOSE: u8 = b']';
|
||||
// array-sep = ws %x2C ws ; , Comma
|
||||
const ARRAY_SEP: u8 = b',';
|
||||
|
||||
// note: this rule is modified
|
||||
// array-values = [ ( array-value array-sep array-values ) /
|
||||
// array-value / ws-comment-newline ]
|
||||
pub(crate) fn array_values<'i>(
|
||||
check: RecursionCheck,
|
||||
) -> impl Parser<Input<'i>, Array, ContextError> {
|
||||
move |input: &mut Input<'i>| {
|
||||
let check = check.recursing(input)?;
|
||||
(
|
||||
opt(
|
||||
(separated1(array_value(check), ARRAY_SEP), opt(ARRAY_SEP)).map(
|
||||
|(v, trailing): (Vec<Value>, Option<u8>)| {
|
||||
(
|
||||
Array::with_vec(v.into_iter().map(Item::Value).collect()),
|
||||
trailing.is_some(),
|
||||
)
|
||||
},
|
||||
),
|
||||
),
|
||||
ws_comment_newline.span(),
|
||||
)
|
||||
.try_map::<_, _, std::str::Utf8Error>(|(array, trailing)| {
|
||||
let (mut array, comma) = array.unwrap_or_default();
|
||||
array.set_trailing_comma(comma);
|
||||
array.set_trailing(RawString::with_span(trailing));
|
||||
Ok(array)
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn array_value<'i>(
|
||||
check: RecursionCheck,
|
||||
) -> impl Parser<Input<'i>, Value, ContextError> {
|
||||
move |input: &mut Input<'i>| {
|
||||
(
|
||||
ws_comment_newline.span(),
|
||||
value(check),
|
||||
ws_comment_newline.span(),
|
||||
)
|
||||
.map(|(ws1, v, ws2)| v.decorated(RawString::with_span(ws1), RawString::with_span(ws2)))
|
||||
.parse_next(input)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn arrays() {
|
||||
let inputs = [
|
||||
r#"[]"#,
|
||||
r#"[ ]"#,
|
||||
r#"[
|
||||
1, 2, 3
|
||||
]"#,
|
||||
r#"[
|
||||
1,
|
||||
2, # this is ok
|
||||
]"#,
|
||||
r#"[# comment
|
||||
# comment2
|
||||
|
||||
|
||||
]"#,
|
||||
r#"[# comment
|
||||
# comment2
|
||||
1
|
||||
|
||||
#sd
|
||||
,
|
||||
# comment3
|
||||
|
||||
]"#,
|
||||
r#"[1]"#,
|
||||
r#"[1,]"#,
|
||||
r#"[ "all", 'strings', """are the same""", '''type''']"#,
|
||||
r#"[ 100, -2,]"#,
|
||||
r#"[1, 2, 3]"#,
|
||||
r#"[1.1, 2.1, 3.1]"#,
|
||||
r#"["a", "b", "c"]"#,
|
||||
r#"[ [ 1, 2 ], [3, 4, 5] ]"#,
|
||||
r#"[ [ 1, 2 ], ["a", "b", "c"] ]"#,
|
||||
r#"[ { x = 1, a = "2" }, {a = "a",b = "b", c = "c"} ]"#,
|
||||
];
|
||||
for input in inputs {
|
||||
dbg!(input);
|
||||
let mut parsed = array(Default::default()).parse(new_input(input));
|
||||
if let Ok(parsed) = &mut parsed {
|
||||
parsed.despan(input);
|
||||
}
|
||||
assert_eq!(parsed.map(|a| a.to_string()), Ok(input.to_owned()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_arrays() {
|
||||
let invalid_inputs = [r#"["#, r#"[,]"#, r#"[,2]"#, r#"[1e165,,]"#];
|
||||
for input in invalid_inputs {
|
||||
dbg!(input);
|
||||
let mut parsed = array(Default::default()).parse(new_input(input));
|
||||
if let Ok(parsed) = &mut parsed {
|
||||
parsed.despan(input);
|
||||
}
|
||||
assert!(parsed.is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
446
third-party/vendor/toml_edit/src/parser/datetime.rs
vendored
Normal file
446
third-party/vendor/toml_edit/src/parser/datetime.rs
vendored
Normal file
|
|
@ -0,0 +1,446 @@
|
|||
use std::ops::RangeInclusive;
|
||||
|
||||
use crate::parser::errors::CustomError;
|
||||
use crate::parser::prelude::*;
|
||||
use crate::parser::trivia::from_utf8_unchecked;
|
||||
|
||||
use toml_datetime::*;
|
||||
use winnow::combinator::alt;
|
||||
use winnow::combinator::cut_err;
|
||||
use winnow::combinator::opt;
|
||||
use winnow::combinator::preceded;
|
||||
use winnow::token::one_of;
|
||||
use winnow::token::take_while;
|
||||
use winnow::trace::trace;
|
||||
|
||||
// ;; Date and Time (as defined in RFC 3339)
|
||||
|
||||
// date-time = offset-date-time / local-date-time / local-date / local-time
|
||||
// offset-date-time = full-date time-delim full-time
|
||||
// local-date-time = full-date time-delim partial-time
|
||||
// local-date = full-date
|
||||
// local-time = partial-time
|
||||
// full-time = partial-time time-offset
|
||||
pub(crate) fn date_time(input: &mut Input<'_>) -> PResult<Datetime> {
|
||||
trace(
|
||||
"date-time",
|
||||
alt((
|
||||
(full_date, opt((time_delim, partial_time, opt(time_offset))))
|
||||
.map(|(date, opt)| {
|
||||
match opt {
|
||||
// Offset Date-Time
|
||||
Some((_, time, offset)) => Datetime {
|
||||
date: Some(date),
|
||||
time: Some(time),
|
||||
offset,
|
||||
},
|
||||
// Local Date
|
||||
None => Datetime {
|
||||
date: Some(date),
|
||||
time: None,
|
||||
offset: None,
|
||||
},
|
||||
}
|
||||
})
|
||||
.context(StrContext::Label("date-time")),
|
||||
partial_time
|
||||
.map(|t| t.into())
|
||||
.context(StrContext::Label("time")),
|
||||
)),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// full-date = date-fullyear "-" date-month "-" date-mday
|
||||
pub(crate) fn full_date(input: &mut Input<'_>) -> PResult<Date> {
|
||||
trace(
|
||||
"full-date",
|
||||
(date_fullyear, b'-', cut_err((date_month, b'-', date_mday)))
|
||||
.map(|(year, _, (month, _, day))| Date { year, month, day }),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// partial-time = time-hour ":" time-minute ":" time-second [time-secfrac]
|
||||
pub(crate) fn partial_time(input: &mut Input<'_>) -> PResult<Time> {
|
||||
trace(
|
||||
"partial-time",
|
||||
(
|
||||
time_hour,
|
||||
b':',
|
||||
cut_err((time_minute, b':', time_second, opt(time_secfrac))),
|
||||
)
|
||||
.map(|(hour, _, (minute, _, second, nanosecond))| Time {
|
||||
hour,
|
||||
minute,
|
||||
second,
|
||||
nanosecond: nanosecond.unwrap_or_default(),
|
||||
}),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// time-offset = "Z" / time-numoffset
|
||||
// time-numoffset = ( "+" / "-" ) time-hour ":" time-minute
|
||||
pub(crate) fn time_offset(input: &mut Input<'_>) -> PResult<Offset> {
|
||||
trace(
|
||||
"time-offset",
|
||||
alt((
|
||||
one_of((b'Z', b'z')).value(Offset::Z),
|
||||
(
|
||||
one_of((b'+', b'-')),
|
||||
cut_err((time_hour, b':', time_minute)),
|
||||
)
|
||||
.map(|(sign, (hours, _, minutes))| {
|
||||
let sign = match sign {
|
||||
b'+' => 1,
|
||||
b'-' => -1,
|
||||
_ => unreachable!("Parser prevents this"),
|
||||
};
|
||||
sign * (hours as i16 * 60 + minutes as i16)
|
||||
})
|
||||
.verify(|minutes| ((-24 * 60)..=(24 * 60)).contains(minutes))
|
||||
.map(|minutes| Offset::Custom { minutes }),
|
||||
))
|
||||
.context(StrContext::Label("time offset")),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// date-fullyear = 4DIGIT
|
||||
pub(crate) fn date_fullyear(input: &mut Input<'_>) -> PResult<u16> {
|
||||
unsigned_digits::<4, 4>
|
||||
.map(|s: &str| s.parse::<u16>().expect("4DIGIT should match u8"))
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// date-month = 2DIGIT ; 01-12
|
||||
pub(crate) fn date_month(input: &mut Input<'_>) -> PResult<u8> {
|
||||
unsigned_digits::<2, 2>
|
||||
.try_map(|s: &str| {
|
||||
let d = s.parse::<u8>().expect("2DIGIT should match u8");
|
||||
if (1..=12).contains(&d) {
|
||||
Ok(d)
|
||||
} else {
|
||||
Err(CustomError::OutOfRange)
|
||||
}
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on month/year
|
||||
pub(crate) fn date_mday(input: &mut Input<'_>) -> PResult<u8> {
|
||||
unsigned_digits::<2, 2>
|
||||
.try_map(|s: &str| {
|
||||
let d = s.parse::<u8>().expect("2DIGIT should match u8");
|
||||
if (1..=31).contains(&d) {
|
||||
Ok(d)
|
||||
} else {
|
||||
Err(CustomError::OutOfRange)
|
||||
}
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// time-delim = "T" / %x20 ; T, t, or space
|
||||
pub(crate) fn time_delim(input: &mut Input<'_>) -> PResult<u8> {
|
||||
one_of(TIME_DELIM).parse_next(input)
|
||||
}
|
||||
|
||||
const TIME_DELIM: (u8, u8, u8) = (b'T', b't', b' ');
|
||||
|
||||
// time-hour = 2DIGIT ; 00-23
|
||||
pub(crate) fn time_hour(input: &mut Input<'_>) -> PResult<u8> {
|
||||
unsigned_digits::<2, 2>
|
||||
.try_map(|s: &str| {
|
||||
let d = s.parse::<u8>().expect("2DIGIT should match u8");
|
||||
if (0..=23).contains(&d) {
|
||||
Ok(d)
|
||||
} else {
|
||||
Err(CustomError::OutOfRange)
|
||||
}
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// time-minute = 2DIGIT ; 00-59
|
||||
pub(crate) fn time_minute(input: &mut Input<'_>) -> PResult<u8> {
|
||||
unsigned_digits::<2, 2>
|
||||
.try_map(|s: &str| {
|
||||
let d = s.parse::<u8>().expect("2DIGIT should match u8");
|
||||
if (0..=59).contains(&d) {
|
||||
Ok(d)
|
||||
} else {
|
||||
Err(CustomError::OutOfRange)
|
||||
}
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second rules
|
||||
pub(crate) fn time_second(input: &mut Input<'_>) -> PResult<u8> {
|
||||
unsigned_digits::<2, 2>
|
||||
.try_map(|s: &str| {
|
||||
let d = s.parse::<u8>().expect("2DIGIT should match u8");
|
||||
if (0..=60).contains(&d) {
|
||||
Ok(d)
|
||||
} else {
|
||||
Err(CustomError::OutOfRange)
|
||||
}
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// time-secfrac = "." 1*DIGIT
|
||||
pub(crate) fn time_secfrac(input: &mut Input<'_>) -> PResult<u32> {
|
||||
static SCALE: [u32; 10] = [
|
||||
0,
|
||||
100_000_000,
|
||||
10_000_000,
|
||||
1_000_000,
|
||||
100_000,
|
||||
10_000,
|
||||
1_000,
|
||||
100,
|
||||
10,
|
||||
1,
|
||||
];
|
||||
const INF: usize = usize::MAX;
|
||||
preceded(b'.', unsigned_digits::<1, INF>)
|
||||
.try_map(|mut repr: &str| -> Result<u32, CustomError> {
|
||||
let max_digits = SCALE.len() - 1;
|
||||
if max_digits < repr.len() {
|
||||
// Millisecond precision is required. Further precision of fractional seconds is
|
||||
// implementation-specific. If the value contains greater precision than the
|
||||
// implementation can support, the additional precision must be truncated, not rounded.
|
||||
repr = &repr[0..max_digits];
|
||||
}
|
||||
|
||||
let v = repr.parse::<u32>().map_err(|_| CustomError::OutOfRange)?;
|
||||
let num_digits = repr.len();
|
||||
|
||||
// scale the number accordingly.
|
||||
let scale = SCALE.get(num_digits).ok_or(CustomError::OutOfRange)?;
|
||||
let v = v.checked_mul(*scale).ok_or(CustomError::OutOfRange)?;
|
||||
Ok(v)
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
pub(crate) fn unsigned_digits<'i, const MIN: usize, const MAX: usize>(
|
||||
input: &mut Input<'i>,
|
||||
) -> PResult<&'i str> {
|
||||
take_while(MIN..=MAX, DIGIT)
|
||||
.map(|b: &[u8]| unsafe { from_utf8_unchecked(b, "`is_ascii_digit` filters out on-ASCII") })
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// DIGIT = %x30-39 ; 0-9
|
||||
const DIGIT: RangeInclusive<u8> = b'0'..=b'9';
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn offset_date_time() {
|
||||
let inputs = [
|
||||
(
|
||||
"1979-05-27T07:32:00Z",
|
||||
Datetime {
|
||||
date: Some(Date {
|
||||
year: 1979,
|
||||
month: 5,
|
||||
day: 27,
|
||||
}),
|
||||
time: Some(Time {
|
||||
hour: 7,
|
||||
minute: 32,
|
||||
second: 0,
|
||||
nanosecond: 0,
|
||||
}),
|
||||
offset: Some(Offset::Z),
|
||||
},
|
||||
),
|
||||
(
|
||||
"1979-05-27T00:32:00-07:00",
|
||||
Datetime {
|
||||
date: Some(Date {
|
||||
year: 1979,
|
||||
month: 5,
|
||||
day: 27,
|
||||
}),
|
||||
time: Some(Time {
|
||||
hour: 0,
|
||||
minute: 32,
|
||||
second: 0,
|
||||
nanosecond: 0,
|
||||
}),
|
||||
offset: Some(Offset::Custom { minutes: -7 * 60 }),
|
||||
},
|
||||
),
|
||||
(
|
||||
"1979-05-27T00:32:00-00:36",
|
||||
Datetime {
|
||||
date: Some(Date {
|
||||
year: 1979,
|
||||
month: 5,
|
||||
day: 27,
|
||||
}),
|
||||
time: Some(Time {
|
||||
hour: 0,
|
||||
minute: 32,
|
||||
second: 0,
|
||||
nanosecond: 0,
|
||||
}),
|
||||
offset: Some(Offset::Custom { minutes: -36 }),
|
||||
},
|
||||
),
|
||||
(
|
||||
"1979-05-27T00:32:00.999999",
|
||||
Datetime {
|
||||
date: Some(Date {
|
||||
year: 1979,
|
||||
month: 5,
|
||||
day: 27,
|
||||
}),
|
||||
time: Some(Time {
|
||||
hour: 0,
|
||||
minute: 32,
|
||||
second: 0,
|
||||
nanosecond: 999999000,
|
||||
}),
|
||||
offset: None,
|
||||
},
|
||||
),
|
||||
];
|
||||
for (input, expected) in inputs {
|
||||
dbg!(input);
|
||||
let actual = date_time.parse(new_input(input)).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_date_time() {
|
||||
let inputs = [
|
||||
(
|
||||
"1979-05-27T07:32:00",
|
||||
Datetime {
|
||||
date: Some(Date {
|
||||
year: 1979,
|
||||
month: 5,
|
||||
day: 27,
|
||||
}),
|
||||
time: Some(Time {
|
||||
hour: 7,
|
||||
minute: 32,
|
||||
second: 0,
|
||||
nanosecond: 0,
|
||||
}),
|
||||
offset: None,
|
||||
},
|
||||
),
|
||||
(
|
||||
"1979-05-27T00:32:00.999999",
|
||||
Datetime {
|
||||
date: Some(Date {
|
||||
year: 1979,
|
||||
month: 5,
|
||||
day: 27,
|
||||
}),
|
||||
time: Some(Time {
|
||||
hour: 0,
|
||||
minute: 32,
|
||||
second: 0,
|
||||
nanosecond: 999999000,
|
||||
}),
|
||||
offset: None,
|
||||
},
|
||||
),
|
||||
];
|
||||
for (input, expected) in inputs {
|
||||
dbg!(input);
|
||||
let actual = date_time.parse(new_input(input)).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_date() {
|
||||
let inputs = [
|
||||
(
|
||||
"1979-05-27",
|
||||
Datetime {
|
||||
date: Some(Date {
|
||||
year: 1979,
|
||||
month: 5,
|
||||
day: 27,
|
||||
}),
|
||||
time: None,
|
||||
offset: None,
|
||||
},
|
||||
),
|
||||
(
|
||||
"2017-07-20",
|
||||
Datetime {
|
||||
date: Some(Date {
|
||||
year: 2017,
|
||||
month: 7,
|
||||
day: 20,
|
||||
}),
|
||||
time: None,
|
||||
offset: None,
|
||||
},
|
||||
),
|
||||
];
|
||||
for (input, expected) in inputs {
|
||||
dbg!(input);
|
||||
let actual = date_time.parse(new_input(input)).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn local_time() {
|
||||
let inputs = [
|
||||
(
|
||||
"07:32:00",
|
||||
Datetime {
|
||||
date: None,
|
||||
time: Some(Time {
|
||||
hour: 7,
|
||||
minute: 32,
|
||||
second: 0,
|
||||
nanosecond: 0,
|
||||
}),
|
||||
offset: None,
|
||||
},
|
||||
),
|
||||
(
|
||||
"00:32:00.999999",
|
||||
Datetime {
|
||||
date: None,
|
||||
time: Some(Time {
|
||||
hour: 0,
|
||||
minute: 32,
|
||||
second: 0,
|
||||
nanosecond: 999999000,
|
||||
}),
|
||||
offset: None,
|
||||
},
|
||||
),
|
||||
];
|
||||
for (input, expected) in inputs {
|
||||
dbg!(input);
|
||||
let actual = date_time.parse(new_input(input)).unwrap();
|
||||
assert_eq!(expected, actual);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn time_fraction_truncated() {
|
||||
let input = "1987-07-05T17:45:00.123456789012345Z";
|
||||
date_time.parse(new_input(input)).unwrap();
|
||||
}
|
||||
}
|
||||
141
third-party/vendor/toml_edit/src/parser/document.rs
vendored
Normal file
141
third-party/vendor/toml_edit/src/parser/document.rs
vendored
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
use std::cell::RefCell;
|
||||
|
||||
use winnow::combinator::cut_err;
|
||||
use winnow::combinator::eof;
|
||||
use winnow::combinator::opt;
|
||||
use winnow::combinator::peek;
|
||||
use winnow::combinator::repeat;
|
||||
use winnow::token::any;
|
||||
use winnow::token::one_of;
|
||||
use winnow::trace::trace;
|
||||
|
||||
use crate::document::Document;
|
||||
use crate::key::Key;
|
||||
use crate::parser::inline_table::KEYVAL_SEP;
|
||||
use crate::parser::key::key;
|
||||
use crate::parser::prelude::*;
|
||||
use crate::parser::state::ParseState;
|
||||
use crate::parser::table::table;
|
||||
use crate::parser::trivia::{comment, line_ending, line_trailing, newline, ws};
|
||||
use crate::parser::value::value;
|
||||
use crate::table::TableKeyValue;
|
||||
use crate::Item;
|
||||
use crate::RawString;
|
||||
|
||||
// ;; TOML
|
||||
|
||||
// toml = expression *( newline expression )
|
||||
|
||||
// expression = ( ( ws comment ) /
|
||||
// ( ws keyval ws [ comment ] ) /
|
||||
// ( ws table ws [ comment ] ) /
|
||||
// ws )
|
||||
pub(crate) fn document(input: &mut Input<'_>) -> PResult<Document> {
|
||||
let state = RefCell::new(ParseState::default());
|
||||
let state_ref = &state;
|
||||
|
||||
let _o = (
|
||||
// Remove BOM if present
|
||||
opt(b"\xEF\xBB\xBF"),
|
||||
parse_ws(state_ref),
|
||||
repeat(0.., (
|
||||
dispatch! {peek(any);
|
||||
crate::parser::trivia::COMMENT_START_SYMBOL => cut_err(parse_comment(state_ref)),
|
||||
crate::parser::table::STD_TABLE_OPEN => cut_err(table(state_ref)),
|
||||
crate::parser::trivia::LF |
|
||||
crate::parser::trivia::CR => parse_newline(state_ref),
|
||||
_ => cut_err(keyval(state_ref)),
|
||||
},
|
||||
parse_ws(state_ref),
|
||||
))
|
||||
.map(|()| ()),
|
||||
eof,
|
||||
)
|
||||
.parse_next(input)?;
|
||||
state.into_inner().into_document().map_err(|err| {
|
||||
winnow::error::ErrMode::from_external_error(input, winnow::error::ErrorKind::Verify, err)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn parse_comment<'s, 'i>(
|
||||
state: &'s RefCell<ParseState>,
|
||||
) -> impl Parser<Input<'i>, (), ContextError> + 's {
|
||||
move |i: &mut Input<'i>| {
|
||||
(comment, line_ending)
|
||||
.span()
|
||||
.map(|span| {
|
||||
state.borrow_mut().on_comment(span);
|
||||
})
|
||||
.parse_next(i)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_ws<'s, 'i>(
|
||||
state: &'s RefCell<ParseState>,
|
||||
) -> impl Parser<Input<'i>, (), ContextError> + 's {
|
||||
move |i: &mut Input<'i>| {
|
||||
ws.span()
|
||||
.map(|span| state.borrow_mut().on_ws(span))
|
||||
.parse_next(i)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_newline<'s, 'i>(
|
||||
state: &'s RefCell<ParseState>,
|
||||
) -> impl Parser<Input<'i>, (), ContextError> + 's {
|
||||
move |i: &mut Input<'i>| {
|
||||
newline
|
||||
.span()
|
||||
.map(|span| state.borrow_mut().on_ws(span))
|
||||
.parse_next(i)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn keyval<'s, 'i>(
|
||||
state: &'s RefCell<ParseState>,
|
||||
) -> impl Parser<Input<'i>, (), ContextError> + 's {
|
||||
move |i: &mut Input<'i>| {
|
||||
parse_keyval
|
||||
.try_map(|(p, kv)| state.borrow_mut().on_keyval(p, kv))
|
||||
.parse_next(i)
|
||||
}
|
||||
}
|
||||
|
||||
// keyval = key keyval-sep val
|
||||
pub(crate) fn parse_keyval(input: &mut Input<'_>) -> PResult<(Vec<Key>, TableKeyValue)> {
|
||||
trace(
|
||||
"keyval",
|
||||
(
|
||||
key,
|
||||
cut_err((
|
||||
one_of(KEYVAL_SEP)
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('.')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('='))),
|
||||
(
|
||||
ws.span(),
|
||||
value(RecursionCheck::default()),
|
||||
line_trailing
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('\n')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('#'))),
|
||||
),
|
||||
)),
|
||||
)
|
||||
.try_map::<_, _, std::str::Utf8Error>(|(key, (_, v))| {
|
||||
let mut path = key;
|
||||
let key = path.pop().expect("grammar ensures at least 1");
|
||||
|
||||
let (pre, v, suf) = v;
|
||||
let pre = RawString::with_span(pre);
|
||||
let suf = RawString::with_span(suf);
|
||||
let v = v.decorated(pre, suf);
|
||||
Ok((
|
||||
path,
|
||||
TableKeyValue {
|
||||
key,
|
||||
value: Item::Value(v),
|
||||
},
|
||||
))
|
||||
}),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
316
third-party/vendor/toml_edit/src/parser/errors.rs
vendored
Normal file
316
third-party/vendor/toml_edit/src/parser/errors.rs
vendored
Normal file
|
|
@ -0,0 +1,316 @@
|
|||
use std::error::Error as StdError;
|
||||
use std::fmt::{Display, Formatter, Result};
|
||||
|
||||
use crate::parser::prelude::*;
|
||||
use crate::Key;
|
||||
|
||||
use winnow::error::ContextError;
|
||||
use winnow::error::ParseError;
|
||||
|
||||
/// Type representing a TOML parse error
|
||||
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
||||
pub struct TomlError {
|
||||
message: String,
|
||||
original: Option<String>,
|
||||
keys: Vec<String>,
|
||||
span: Option<std::ops::Range<usize>>,
|
||||
}
|
||||
|
||||
impl TomlError {
|
||||
pub(crate) fn new(error: ParseError<Input<'_>, ContextError>, mut original: Input<'_>) -> Self {
|
||||
use winnow::stream::Stream;
|
||||
|
||||
let offset = error.offset();
|
||||
let span = if offset == original.len() {
|
||||
offset..offset
|
||||
} else {
|
||||
offset..(offset + 1)
|
||||
};
|
||||
|
||||
let message = error.inner().to_string();
|
||||
let original = original.finish();
|
||||
|
||||
Self {
|
||||
message,
|
||||
original: Some(
|
||||
String::from_utf8(original.to_owned()).expect("original document was utf8"),
|
||||
),
|
||||
keys: Vec::new(),
|
||||
span: Some(span),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
pub(crate) fn custom(message: String, span: Option<std::ops::Range<usize>>) -> Self {
|
||||
Self {
|
||||
message,
|
||||
original: 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_original(&mut self, original: Option<String>) {
|
||||
self.original = original;
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 Display for TomlError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
let mut context = false;
|
||||
if let (Some(original), Some(span)) = (&self.original, self.span()) {
|
||||
context = true;
|
||||
|
||||
let (line, column) = translate_position(original.as_bytes(), span.start);
|
||||
let line_num = line + 1;
|
||||
let col_num = column + 1;
|
||||
let gutter = line_num.to_string().len();
|
||||
let content = original.split('\n').nth(line).expect("valid line number");
|
||||
|
||||
writeln!(
|
||||
f,
|
||||
"TOML parse error at line {}, column {}",
|
||||
line_num, 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 (span.start + 1)..(span.end.min(span.start + content.len())) {
|
||||
write!(f, "^")?;
|
||||
}
|
||||
writeln!(f)?;
|
||||
}
|
||||
writeln!(f, "{}", self.message)?;
|
||||
if !context && !self.keys.is_empty() {
|
||||
writeln!(f, "in `{}`", self.keys.join("."))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for TomlError {
|
||||
fn description(&self) -> &'static str {
|
||||
"TOML parse error"
|
||||
}
|
||||
}
|
||||
|
||||
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 line = line;
|
||||
|
||||
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(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));
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) enum CustomError {
|
||||
DuplicateKey {
|
||||
key: String,
|
||||
table: Option<Vec<Key>>,
|
||||
},
|
||||
DottedKeyExtendWrongType {
|
||||
key: Vec<Key>,
|
||||
actual: &'static str,
|
||||
},
|
||||
OutOfRange,
|
||||
#[cfg_attr(feature = "unbounded", allow(dead_code))]
|
||||
RecursionLimitExceeded,
|
||||
}
|
||||
|
||||
impl CustomError {
|
||||
pub(crate) fn duplicate_key(path: &[Key], i: usize) -> Self {
|
||||
assert!(i < path.len());
|
||||
let key = &path[i];
|
||||
let repr = key.display_repr();
|
||||
Self::DuplicateKey {
|
||||
key: repr.into(),
|
||||
table: Some(path[..i].to_vec()),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn extend_wrong_type(path: &[Key], i: usize, actual: &'static str) -> Self {
|
||||
assert!(i < path.len());
|
||||
Self::DottedKeyExtendWrongType {
|
||||
key: path[..=i].to_vec(),
|
||||
actual,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl StdError for CustomError {
|
||||
fn description(&self) -> &'static str {
|
||||
"TOML parse error"
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for CustomError {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
|
||||
match self {
|
||||
CustomError::DuplicateKey { key, table } => {
|
||||
if let Some(table) = table {
|
||||
if table.is_empty() {
|
||||
write!(f, "duplicate key `{}` in document root", key)
|
||||
} else {
|
||||
let path = table.iter().map(|k| k.get()).collect::<Vec<_>>().join(".");
|
||||
write!(f, "duplicate key `{}` in table `{}`", key, path)
|
||||
}
|
||||
} else {
|
||||
write!(f, "duplicate key `{}`", key)
|
||||
}
|
||||
}
|
||||
CustomError::DottedKeyExtendWrongType { key, actual } => {
|
||||
let path = key.iter().map(|k| k.get()).collect::<Vec<_>>().join(".");
|
||||
write!(
|
||||
f,
|
||||
"dotted key `{}` attempted to extend non-table type ({})",
|
||||
path, actual
|
||||
)
|
||||
}
|
||||
CustomError::OutOfRange => write!(f, "value is out of range"),
|
||||
CustomError::RecursionLimitExceeded => write!(f, "recursion limit exceeded"),
|
||||
}
|
||||
}
|
||||
}
|
||||
181
third-party/vendor/toml_edit/src/parser/inline_table.rs
vendored
Normal file
181
third-party/vendor/toml_edit/src/parser/inline_table.rs
vendored
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
use winnow::combinator::cut_err;
|
||||
use winnow::combinator::delimited;
|
||||
use winnow::combinator::separated0;
|
||||
use winnow::token::one_of;
|
||||
use winnow::trace::trace;
|
||||
|
||||
use crate::key::Key;
|
||||
use crate::parser::errors::CustomError;
|
||||
use crate::parser::key::key;
|
||||
use crate::parser::prelude::*;
|
||||
use crate::parser::trivia::ws;
|
||||
use crate::parser::value::value;
|
||||
use crate::table::TableKeyValue;
|
||||
use crate::{InlineTable, InternalString, Item, RawString, Value};
|
||||
|
||||
use indexmap::map::Entry;
|
||||
|
||||
// ;; Inline Table
|
||||
|
||||
// inline-table = inline-table-open inline-table-keyvals inline-table-close
|
||||
pub(crate) fn inline_table<'i>(
|
||||
check: RecursionCheck,
|
||||
) -> impl Parser<Input<'i>, InlineTable, ContextError> {
|
||||
trace("inline-table", move |input: &mut Input<'i>| {
|
||||
delimited(
|
||||
INLINE_TABLE_OPEN,
|
||||
cut_err(inline_table_keyvals(check).try_map(|(kv, p)| table_from_pairs(kv, p))),
|
||||
cut_err(INLINE_TABLE_CLOSE)
|
||||
.context(StrContext::Label("inline table"))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('}'))),
|
||||
)
|
||||
.parse_next(input)
|
||||
})
|
||||
}
|
||||
|
||||
fn table_from_pairs(
|
||||
v: Vec<(Vec<Key>, TableKeyValue)>,
|
||||
preamble: RawString,
|
||||
) -> Result<InlineTable, CustomError> {
|
||||
let mut root = InlineTable::new();
|
||||
root.set_preamble(preamble);
|
||||
// Assuming almost all pairs will be directly in `root`
|
||||
root.items.reserve(v.len());
|
||||
|
||||
for (path, kv) in v {
|
||||
let table = descend_path(&mut root, &path)?;
|
||||
let key: InternalString = kv.key.get_internal().into();
|
||||
match table.items.entry(key) {
|
||||
Entry::Vacant(o) => {
|
||||
o.insert(kv);
|
||||
}
|
||||
Entry::Occupied(o) => {
|
||||
return Err(CustomError::DuplicateKey {
|
||||
key: o.key().as_str().into(),
|
||||
table: None,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(root)
|
||||
}
|
||||
|
||||
fn descend_path<'a>(
|
||||
mut table: &'a mut InlineTable,
|
||||
path: &'a [Key],
|
||||
) -> Result<&'a mut InlineTable, CustomError> {
|
||||
for (i, key) in path.iter().enumerate() {
|
||||
let entry = table.entry_format(key).or_insert_with(|| {
|
||||
let mut new_table = InlineTable::new();
|
||||
new_table.set_dotted(true);
|
||||
|
||||
Value::InlineTable(new_table)
|
||||
});
|
||||
match *entry {
|
||||
Value::InlineTable(ref mut sweet_child_of_mine) => {
|
||||
table = sweet_child_of_mine;
|
||||
}
|
||||
ref v => {
|
||||
return Err(CustomError::extend_wrong_type(path, i, v.type_name()));
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(table)
|
||||
}
|
||||
|
||||
// inline-table-open = %x7B ws ; {
|
||||
pub(crate) const INLINE_TABLE_OPEN: u8 = b'{';
|
||||
// inline-table-close = ws %x7D ; }
|
||||
const INLINE_TABLE_CLOSE: u8 = b'}';
|
||||
// inline-table-sep = ws %x2C ws ; , Comma
|
||||
const INLINE_TABLE_SEP: u8 = b',';
|
||||
// keyval-sep = ws %x3D ws ; =
|
||||
pub(crate) const KEYVAL_SEP: u8 = b'=';
|
||||
|
||||
// inline-table-keyvals = [ inline-table-keyvals-non-empty ]
|
||||
// inline-table-keyvals-non-empty =
|
||||
// ( key keyval-sep val inline-table-sep inline-table-keyvals-non-empty ) /
|
||||
// ( key keyval-sep val )
|
||||
|
||||
fn inline_table_keyvals<'i>(
|
||||
check: RecursionCheck,
|
||||
) -> impl Parser<Input<'i>, (Vec<(Vec<Key>, TableKeyValue)>, RawString), ContextError> {
|
||||
move |input: &mut Input<'i>| {
|
||||
let check = check.recursing(input)?;
|
||||
(
|
||||
separated0(keyval(check), INLINE_TABLE_SEP),
|
||||
ws.span().map(RawString::with_span),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
}
|
||||
|
||||
fn keyval<'i>(
|
||||
check: RecursionCheck,
|
||||
) -> impl Parser<Input<'i>, (Vec<Key>, TableKeyValue), ContextError> {
|
||||
move |input: &mut Input<'i>| {
|
||||
(
|
||||
key,
|
||||
cut_err((
|
||||
one_of(KEYVAL_SEP)
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('.')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('='))),
|
||||
(ws.span(), value(check), ws.span()),
|
||||
)),
|
||||
)
|
||||
.map(|(key, (_, v))| {
|
||||
let mut path = key;
|
||||
let key = path.pop().expect("grammar ensures at least 1");
|
||||
|
||||
let (pre, v, suf) = v;
|
||||
let pre = RawString::with_span(pre);
|
||||
let suf = RawString::with_span(suf);
|
||||
let v = v.decorated(pre, suf);
|
||||
(
|
||||
path,
|
||||
TableKeyValue {
|
||||
key,
|
||||
value: Item::Value(v),
|
||||
},
|
||||
)
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn inline_tables() {
|
||||
let inputs = [
|
||||
r#"{}"#,
|
||||
r#"{ }"#,
|
||||
r#"{a = 1e165}"#,
|
||||
r#"{ hello = "world", a = 1}"#,
|
||||
r#"{ hello.world = "a" }"#,
|
||||
];
|
||||
for input in inputs {
|
||||
dbg!(input);
|
||||
let mut parsed = inline_table(Default::default()).parse(new_input(input));
|
||||
if let Ok(parsed) = &mut parsed {
|
||||
parsed.despan(input);
|
||||
}
|
||||
assert_eq!(parsed.map(|a| a.to_string()), Ok(input.to_owned()));
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_inline_tables() {
|
||||
let invalid_inputs = [r#"{a = 1e165"#, r#"{ hello = "world", a = 2, hello = 1}"#];
|
||||
for input in invalid_inputs {
|
||||
dbg!(input);
|
||||
let mut parsed = inline_table(Default::default()).parse(new_input(input));
|
||||
if let Ok(parsed) = &mut parsed {
|
||||
parsed.despan(input);
|
||||
}
|
||||
assert!(parsed.is_err());
|
||||
}
|
||||
}
|
||||
}
|
||||
112
third-party/vendor/toml_edit/src/parser/key.rs
vendored
Normal file
112
third-party/vendor/toml_edit/src/parser/key.rs
vendored
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
use std::ops::RangeInclusive;
|
||||
|
||||
use winnow::combinator::peek;
|
||||
use winnow::combinator::separated1;
|
||||
use winnow::token::any;
|
||||
use winnow::token::take_while;
|
||||
use winnow::trace::trace;
|
||||
|
||||
use crate::key::Key;
|
||||
use crate::parser::errors::CustomError;
|
||||
use crate::parser::prelude::*;
|
||||
use crate::parser::strings::{basic_string, literal_string};
|
||||
use crate::parser::trivia::{from_utf8_unchecked, ws};
|
||||
use crate::repr::{Decor, Repr};
|
||||
use crate::InternalString;
|
||||
use crate::RawString;
|
||||
|
||||
// key = simple-key / dotted-key
|
||||
// dotted-key = simple-key 1*( dot-sep simple-key )
|
||||
pub(crate) fn key(input: &mut Input<'_>) -> PResult<Vec<Key>> {
|
||||
trace(
|
||||
"dotted-key",
|
||||
separated1(
|
||||
(ws.span(), simple_key, ws.span()).map(|(pre, (raw, key), suffix)| {
|
||||
Key::new(key)
|
||||
.with_repr_unchecked(Repr::new_unchecked(raw))
|
||||
.with_decor(Decor::new(
|
||||
RawString::with_span(pre),
|
||||
RawString::with_span(suffix),
|
||||
))
|
||||
}),
|
||||
DOT_SEP,
|
||||
)
|
||||
.context(StrContext::Label("key"))
|
||||
.try_map(|k: Vec<_>| {
|
||||
// Inserting the key will require recursion down the line
|
||||
RecursionCheck::check_depth(k.len())?;
|
||||
Ok::<_, CustomError>(k)
|
||||
}),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// simple-key = quoted-key / unquoted-key
|
||||
// quoted-key = basic-string / literal-string
|
||||
pub(crate) fn simple_key(input: &mut Input<'_>) -> PResult<(RawString, InternalString)> {
|
||||
trace(
|
||||
"simple-key",
|
||||
dispatch! {peek(any);
|
||||
crate::parser::strings::QUOTATION_MARK => basic_string
|
||||
.map(|s: std::borrow::Cow<'_, str>| s.as_ref().into()),
|
||||
crate::parser::strings::APOSTROPHE => literal_string.map(|s: &str| s.into()),
|
||||
_ => unquoted_key.map(|s: &str| s.into()),
|
||||
}
|
||||
.with_span()
|
||||
.map(|(k, span)| {
|
||||
let raw = RawString::with_span(span);
|
||||
(raw, k)
|
||||
}),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// unquoted-key = 1*( ALPHA / DIGIT / %x2D / %x5F ) ; A-Z / a-z / 0-9 / - / _
|
||||
fn unquoted_key<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
trace(
|
||||
"unquoted-key",
|
||||
take_while(1.., UNQUOTED_CHAR)
|
||||
.map(|b| unsafe { from_utf8_unchecked(b, "`is_unquoted_char` filters out on-ASCII") }),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
pub(crate) fn is_unquoted_char(c: u8) -> bool {
|
||||
use winnow::stream::ContainsToken;
|
||||
UNQUOTED_CHAR.contains_token(c)
|
||||
}
|
||||
|
||||
const UNQUOTED_CHAR: (
|
||||
RangeInclusive<u8>,
|
||||
RangeInclusive<u8>,
|
||||
RangeInclusive<u8>,
|
||||
u8,
|
||||
u8,
|
||||
) = (b'A'..=b'Z', b'a'..=b'z', b'0'..=b'9', b'-', b'_');
|
||||
|
||||
// dot-sep = ws %x2E ws ; . Period
|
||||
const DOT_SEP: u8 = b'.';
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn keys() {
|
||||
let cases = [
|
||||
("a", "a"),
|
||||
(r#""hello\n ""#, "hello\n "),
|
||||
(r#"'hello\n '"#, "hello\\n "),
|
||||
];
|
||||
|
||||
for (input, expected) in cases {
|
||||
dbg!(input);
|
||||
let parsed = simple_key.parse(new_input(input));
|
||||
assert_eq!(
|
||||
parsed,
|
||||
Ok((RawString::with_span(0..(input.len())), expected.into())),
|
||||
"Parsing {input:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
265
third-party/vendor/toml_edit/src/parser/mod.rs
vendored
Normal file
265
third-party/vendor/toml_edit/src/parser/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
#![allow(clippy::type_complexity)]
|
||||
|
||||
pub(crate) mod array;
|
||||
pub(crate) mod datetime;
|
||||
pub(crate) mod document;
|
||||
pub(crate) mod errors;
|
||||
pub(crate) mod inline_table;
|
||||
pub(crate) mod key;
|
||||
pub(crate) mod numbers;
|
||||
pub(crate) mod state;
|
||||
pub(crate) mod strings;
|
||||
pub(crate) mod table;
|
||||
pub(crate) mod trivia;
|
||||
pub(crate) mod value;
|
||||
|
||||
pub use errors::TomlError;
|
||||
|
||||
pub(crate) fn parse_document(raw: &str) -> Result<crate::Document, TomlError> {
|
||||
use prelude::*;
|
||||
|
||||
let b = new_input(raw);
|
||||
let mut doc = document::document
|
||||
.parse(b)
|
||||
.map_err(|e| TomlError::new(e, b))?;
|
||||
doc.span = Some(0..(raw.len()));
|
||||
doc.original = Some(raw.to_owned());
|
||||
Ok(doc)
|
||||
}
|
||||
|
||||
pub(crate) fn parse_key(raw: &str) -> Result<crate::Key, TomlError> {
|
||||
use prelude::*;
|
||||
|
||||
let b = new_input(raw);
|
||||
let result = key::simple_key.parse(b);
|
||||
match result {
|
||||
Ok((raw, key)) => {
|
||||
Ok(crate::Key::new(key).with_repr_unchecked(crate::Repr::new_unchecked(raw)))
|
||||
}
|
||||
Err(e) => Err(TomlError::new(e, b)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_key_path(raw: &str) -> Result<Vec<crate::Key>, TomlError> {
|
||||
use prelude::*;
|
||||
|
||||
let b = new_input(raw);
|
||||
let result = key::key.parse(b);
|
||||
match result {
|
||||
Ok(mut keys) => {
|
||||
for key in &mut keys {
|
||||
key.despan(raw);
|
||||
}
|
||||
Ok(keys)
|
||||
}
|
||||
Err(e) => Err(TomlError::new(e, b)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn parse_value(raw: &str) -> Result<crate::Value, TomlError> {
|
||||
use prelude::*;
|
||||
|
||||
let b = new_input(raw);
|
||||
let parsed = value::value(RecursionCheck::default()).parse(b);
|
||||
match parsed {
|
||||
Ok(mut value) => {
|
||||
// Only take the repr and not decor, as its probably not intended
|
||||
value.decor_mut().clear();
|
||||
value.despan(raw);
|
||||
Ok(value)
|
||||
}
|
||||
Err(e) => Err(TomlError::new(e, b)),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) mod prelude {
|
||||
pub(crate) use winnow::combinator::dispatch;
|
||||
pub(crate) use winnow::error::ContextError;
|
||||
pub(crate) use winnow::error::FromExternalError;
|
||||
pub(crate) use winnow::error::StrContext;
|
||||
pub(crate) use winnow::error::StrContextValue;
|
||||
pub(crate) use winnow::PResult;
|
||||
pub(crate) use winnow::Parser;
|
||||
|
||||
pub(crate) type Input<'b> = winnow::Located<&'b winnow::BStr>;
|
||||
|
||||
pub(crate) fn new_input(s: &str) -> Input<'_> {
|
||||
winnow::Located::new(winnow::BStr::new(s))
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unbounded"))]
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub(crate) struct RecursionCheck {
|
||||
current: usize,
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "unbounded"))]
|
||||
impl RecursionCheck {
|
||||
pub(crate) fn check_depth(depth: usize) -> Result<(), super::errors::CustomError> {
|
||||
if depth < 128 {
|
||||
Ok(())
|
||||
} else {
|
||||
Err(super::errors::CustomError::RecursionLimitExceeded)
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn recursing(
|
||||
mut self,
|
||||
input: &mut Input<'_>,
|
||||
) -> Result<Self, winnow::error::ErrMode<ContextError>> {
|
||||
self.current += 1;
|
||||
if self.current < 128 {
|
||||
Ok(self)
|
||||
} else {
|
||||
Err(winnow::error::ErrMode::from_external_error(
|
||||
input,
|
||||
winnow::error::ErrorKind::Eof,
|
||||
super::errors::CustomError::RecursionLimitExceeded,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "unbounded")]
|
||||
#[derive(Copy, Clone, Debug, Default)]
|
||||
pub(crate) struct RecursionCheck {}
|
||||
|
||||
#[cfg(feature = "unbounded")]
|
||||
impl RecursionCheck {
|
||||
pub(crate) fn check_depth(_depth: usize) -> Result<(), super::errors::CustomError> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn recursing(
|
||||
self,
|
||||
_input: &mut Input<'_>,
|
||||
) -> Result<Self, winnow::error::ErrMode<ContextError>> {
|
||||
Ok(self)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn documents() {
|
||||
let documents = [
|
||||
"",
|
||||
r#"
|
||||
# This is a TOML document.
|
||||
|
||||
title = "TOML Example"
|
||||
|
||||
[owner]
|
||||
name = "Tom Preston-Werner"
|
||||
dob = 1979-05-27T07:32:00-08:00 # First class dates
|
||||
|
||||
[database]
|
||||
server = "192.168.1.1"
|
||||
ports = [ 8001, 8001, 8002 ]
|
||||
connection_max = 5000
|
||||
enabled = true
|
||||
|
||||
[servers]
|
||||
|
||||
# Indentation (tabs and/or spaces) is allowed but not required
|
||||
[servers.alpha]
|
||||
ip = "10.0.0.1"
|
||||
dc = "eqdc10"
|
||||
|
||||
[servers.beta]
|
||||
ip = "10.0.0.2"
|
||||
dc = "eqdc10"
|
||||
|
||||
[clients]
|
||||
data = [ ["gamma", "delta"], [1, 2] ]
|
||||
|
||||
# Line breaks are OK when inside arrays
|
||||
hosts = [
|
||||
"alpha",
|
||||
"omega"
|
||||
]
|
||||
|
||||
'some.weird .stuff' = """
|
||||
like
|
||||
that
|
||||
# """ # this broke my syntax highlighting
|
||||
" also. like " = '''
|
||||
that
|
||||
'''
|
||||
double = 2e39 # this number looks familiar
|
||||
# trailing comment"#,
|
||||
r#""#,
|
||||
r#" "#,
|
||||
r#" hello = 'darkness' # my old friend
|
||||
"#,
|
||||
r#"[parent . child]
|
||||
key = "value"
|
||||
"#,
|
||||
r#"hello.world = "a"
|
||||
"#,
|
||||
r#"foo = 1979-05-27 # Comment
|
||||
"#,
|
||||
];
|
||||
for input in documents {
|
||||
dbg!(input);
|
||||
let mut parsed = parse_document(input);
|
||||
if let Ok(parsed) = &mut parsed {
|
||||
parsed.despan();
|
||||
}
|
||||
let doc = match parsed {
|
||||
Ok(doc) => doc,
|
||||
Err(err) => {
|
||||
panic!(
|
||||
"Parse error: {:?}\nFailed to parse:\n```\n{}\n```",
|
||||
err, input
|
||||
)
|
||||
}
|
||||
};
|
||||
|
||||
snapbox::assert_eq(input, doc.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn documents_parse_only() {
|
||||
let parse_only = ["\u{FEFF}
|
||||
[package]
|
||||
name = \"foo\"
|
||||
version = \"0.0.1\"
|
||||
authors = []
|
||||
"];
|
||||
for input in parse_only {
|
||||
dbg!(input);
|
||||
let mut parsed = parse_document(input);
|
||||
if let Ok(parsed) = &mut parsed {
|
||||
parsed.despan();
|
||||
}
|
||||
match parsed {
|
||||
Ok(_) => (),
|
||||
Err(err) => {
|
||||
panic!(
|
||||
"Parse error: {:?}\nFailed to parse:\n```\n{}\n```",
|
||||
err, input
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn invalid_documents() {
|
||||
let invalid_inputs = [r#" hello = 'darkness' # my old friend
|
||||
$"#];
|
||||
for input in invalid_inputs {
|
||||
dbg!(input);
|
||||
let mut parsed = parse_document(input);
|
||||
if let Ok(parsed) = &mut parsed {
|
||||
parsed.despan();
|
||||
}
|
||||
assert!(parsed.is_err(), "Input: {:?}", input);
|
||||
}
|
||||
}
|
||||
}
|
||||
397
third-party/vendor/toml_edit/src/parser/numbers.rs
vendored
Normal file
397
third-party/vendor/toml_edit/src/parser/numbers.rs
vendored
Normal file
|
|
@ -0,0 +1,397 @@
|
|||
use std::ops::RangeInclusive;
|
||||
|
||||
use winnow::combinator::alt;
|
||||
use winnow::combinator::cut_err;
|
||||
use winnow::combinator::opt;
|
||||
use winnow::combinator::peek;
|
||||
use winnow::combinator::preceded;
|
||||
use winnow::combinator::repeat;
|
||||
use winnow::combinator::rest;
|
||||
use winnow::token::one_of;
|
||||
use winnow::token::tag;
|
||||
use winnow::token::take;
|
||||
use winnow::trace::trace;
|
||||
|
||||
use crate::parser::prelude::*;
|
||||
use crate::parser::trivia::from_utf8_unchecked;
|
||||
|
||||
// ;; Boolean
|
||||
|
||||
// boolean = true / false
|
||||
#[allow(dead_code)] // directly define in `fn value`
|
||||
pub(crate) fn boolean(input: &mut Input<'_>) -> PResult<bool> {
|
||||
trace("boolean", alt((true_, false_))).parse_next(input)
|
||||
}
|
||||
|
||||
pub(crate) fn true_(input: &mut Input<'_>) -> PResult<bool> {
|
||||
(peek(TRUE[0]), cut_err(TRUE)).value(true).parse_next(input)
|
||||
}
|
||||
const TRUE: &[u8] = b"true";
|
||||
|
||||
pub(crate) fn false_(input: &mut Input<'_>) -> PResult<bool> {
|
||||
(peek(FALSE[0]), cut_err(FALSE))
|
||||
.value(false)
|
||||
.parse_next(input)
|
||||
}
|
||||
const FALSE: &[u8] = b"false";
|
||||
|
||||
// ;; Integer
|
||||
|
||||
// integer = dec-int / hex-int / oct-int / bin-int
|
||||
pub(crate) fn integer(input: &mut Input<'_>) -> PResult<i64> {
|
||||
trace("integer",
|
||||
dispatch! {peek(opt::<_, &[u8], _, _>(take(2usize)));
|
||||
Some(b"0x") => cut_err(hex_int.try_map(|s| i64::from_str_radix(&s.replace('_', ""), 16))),
|
||||
Some(b"0o") => cut_err(oct_int.try_map(|s| i64::from_str_radix(&s.replace('_', ""), 8))),
|
||||
Some(b"0b") => cut_err(bin_int.try_map(|s| i64::from_str_radix(&s.replace('_', ""), 2))),
|
||||
_ => dec_int.and_then(cut_err(rest
|
||||
.try_map(|s: &str| s.replace('_', "").parse())))
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// dec-int = [ minus / plus ] unsigned-dec-int
|
||||
// unsigned-dec-int = DIGIT / digit1-9 1*( DIGIT / underscore DIGIT )
|
||||
pub(crate) fn dec_int<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
trace(
|
||||
"dec-int",
|
||||
(
|
||||
opt(one_of((b'+', b'-'))),
|
||||
alt((
|
||||
(
|
||||
one_of(DIGIT1_9),
|
||||
repeat(
|
||||
0..,
|
||||
alt((
|
||||
digit.value(()),
|
||||
(
|
||||
one_of(b'_'),
|
||||
cut_err(digit).context(StrContext::Expected(
|
||||
StrContextValue::Description("digit"),
|
||||
)),
|
||||
)
|
||||
.value(()),
|
||||
)),
|
||||
)
|
||||
.map(|()| ()),
|
||||
)
|
||||
.value(()),
|
||||
digit.value(()),
|
||||
)),
|
||||
)
|
||||
.recognize()
|
||||
.map(|b: &[u8]| unsafe {
|
||||
from_utf8_unchecked(b, "`digit` and `_` filter out non-ASCII")
|
||||
})
|
||||
.context(StrContext::Label("integer")),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
const DIGIT1_9: RangeInclusive<u8> = b'1'..=b'9';
|
||||
|
||||
// hex-prefix = %x30.78 ; 0x
|
||||
// hex-int = hex-prefix HEXDIG *( HEXDIG / underscore HEXDIG )
|
||||
pub(crate) fn hex_int<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
trace(
|
||||
"hex-int",
|
||||
preceded(
|
||||
HEX_PREFIX,
|
||||
cut_err((
|
||||
hexdig,
|
||||
repeat(
|
||||
0..,
|
||||
alt((
|
||||
hexdig.value(()),
|
||||
(
|
||||
one_of(b'_'),
|
||||
cut_err(hexdig).context(StrContext::Expected(
|
||||
StrContextValue::Description("digit"),
|
||||
)),
|
||||
)
|
||||
.value(()),
|
||||
)),
|
||||
)
|
||||
.map(|()| ()),
|
||||
))
|
||||
.recognize(),
|
||||
)
|
||||
.map(|b| unsafe { from_utf8_unchecked(b, "`hexdig` and `_` filter out non-ASCII") })
|
||||
.context(StrContext::Label("hexadecimal integer")),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
const HEX_PREFIX: &[u8] = b"0x";
|
||||
|
||||
// oct-prefix = %x30.6F ; 0o
|
||||
// oct-int = oct-prefix digit0-7 *( digit0-7 / underscore digit0-7 )
|
||||
pub(crate) fn oct_int<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
trace(
|
||||
"oct-int",
|
||||
preceded(
|
||||
OCT_PREFIX,
|
||||
cut_err((
|
||||
one_of(DIGIT0_7),
|
||||
repeat(
|
||||
0..,
|
||||
alt((
|
||||
one_of(DIGIT0_7).value(()),
|
||||
(
|
||||
one_of(b'_'),
|
||||
cut_err(one_of(DIGIT0_7)).context(StrContext::Expected(
|
||||
StrContextValue::Description("digit"),
|
||||
)),
|
||||
)
|
||||
.value(()),
|
||||
)),
|
||||
)
|
||||
.map(|()| ()),
|
||||
))
|
||||
.recognize(),
|
||||
)
|
||||
.map(|b| unsafe { from_utf8_unchecked(b, "`DIGIT0_7` and `_` filter out non-ASCII") })
|
||||
.context(StrContext::Label("octal integer")),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
const OCT_PREFIX: &[u8] = b"0o";
|
||||
const DIGIT0_7: RangeInclusive<u8> = b'0'..=b'7';
|
||||
|
||||
// bin-prefix = %x30.62 ; 0b
|
||||
// bin-int = bin-prefix digit0-1 *( digit0-1 / underscore digit0-1 )
|
||||
pub(crate) fn bin_int<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
trace(
|
||||
"bin-int",
|
||||
preceded(
|
||||
BIN_PREFIX,
|
||||
cut_err((
|
||||
one_of(DIGIT0_1),
|
||||
repeat(
|
||||
0..,
|
||||
alt((
|
||||
one_of(DIGIT0_1).value(()),
|
||||
(
|
||||
one_of(b'_'),
|
||||
cut_err(one_of(DIGIT0_1)).context(StrContext::Expected(
|
||||
StrContextValue::Description("digit"),
|
||||
)),
|
||||
)
|
||||
.value(()),
|
||||
)),
|
||||
)
|
||||
.map(|()| ()),
|
||||
))
|
||||
.recognize(),
|
||||
)
|
||||
.map(|b| unsafe { from_utf8_unchecked(b, "`DIGIT0_1` and `_` filter out non-ASCII") })
|
||||
.context(StrContext::Label("binary integer")),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
const BIN_PREFIX: &[u8] = b"0b";
|
||||
const DIGIT0_1: RangeInclusive<u8> = b'0'..=b'1';
|
||||
|
||||
// ;; Float
|
||||
|
||||
// float = float-int-part ( exp / frac [ exp ] )
|
||||
// float =/ special-float
|
||||
// float-int-part = dec-int
|
||||
pub(crate) fn float(input: &mut Input<'_>) -> PResult<f64> {
|
||||
trace(
|
||||
"float",
|
||||
alt((
|
||||
float_.and_then(cut_err(
|
||||
rest.try_map(|s: &str| s.replace('_', "").parse())
|
||||
.verify(|f: &f64| *f != f64::INFINITY),
|
||||
)),
|
||||
special_float,
|
||||
))
|
||||
.context(StrContext::Label("floating-point number")),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
pub(crate) fn float_<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
(
|
||||
dec_int,
|
||||
alt((exp.void(), (frac.void(), opt(exp.void())).void())),
|
||||
)
|
||||
.recognize()
|
||||
.map(|b: &[u8]| unsafe {
|
||||
from_utf8_unchecked(
|
||||
b,
|
||||
"`dec_int`, `one_of`, `exp`, and `frac` filter out non-ASCII",
|
||||
)
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// frac = decimal-point zero-prefixable-int
|
||||
// decimal-point = %x2E ; .
|
||||
pub(crate) fn frac<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
(
|
||||
b'.',
|
||||
cut_err(zero_prefixable_int)
|
||||
.context(StrContext::Expected(StrContextValue::Description("digit"))),
|
||||
)
|
||||
.recognize()
|
||||
.map(|b: &[u8]| unsafe {
|
||||
from_utf8_unchecked(
|
||||
b,
|
||||
"`.` and `parse_zero_prefixable_int` filter out non-ASCII",
|
||||
)
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// zero-prefixable-int = DIGIT *( DIGIT / underscore DIGIT )
|
||||
pub(crate) fn zero_prefixable_int<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
(
|
||||
digit,
|
||||
repeat(
|
||||
0..,
|
||||
alt((
|
||||
digit.value(()),
|
||||
(
|
||||
one_of(b'_'),
|
||||
cut_err(digit)
|
||||
.context(StrContext::Expected(StrContextValue::Description("digit"))),
|
||||
)
|
||||
.value(()),
|
||||
)),
|
||||
)
|
||||
.map(|()| ()),
|
||||
)
|
||||
.recognize()
|
||||
.map(|b: &[u8]| unsafe { from_utf8_unchecked(b, "`digit` and `_` filter out non-ASCII") })
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// exp = "e" float-exp-part
|
||||
// float-exp-part = [ minus / plus ] zero-prefixable-int
|
||||
pub(crate) fn exp<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
(
|
||||
one_of((b'e', b'E')),
|
||||
opt(one_of([b'+', b'-'])),
|
||||
cut_err(zero_prefixable_int),
|
||||
)
|
||||
.recognize()
|
||||
.map(|b: &[u8]| unsafe {
|
||||
from_utf8_unchecked(
|
||||
b,
|
||||
"`one_of` and `parse_zero_prefixable_int` filter out non-ASCII",
|
||||
)
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// special-float = [ minus / plus ] ( inf / nan )
|
||||
pub(crate) fn special_float(input: &mut Input<'_>) -> PResult<f64> {
|
||||
(opt(one_of((b'+', b'-'))), alt((inf, nan)))
|
||||
.map(|(s, f)| match s {
|
||||
Some(b'+') | None => f,
|
||||
Some(b'-') => -f,
|
||||
_ => unreachable!("one_of should prevent this"),
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
// inf = %x69.6e.66 ; inf
|
||||
pub(crate) fn inf(input: &mut Input<'_>) -> PResult<f64> {
|
||||
tag(INF).value(f64::INFINITY).parse_next(input)
|
||||
}
|
||||
const INF: &[u8] = b"inf";
|
||||
// nan = %x6e.61.6e ; nan
|
||||
pub(crate) fn nan(input: &mut Input<'_>) -> PResult<f64> {
|
||||
tag(NAN).value(f64::NAN).parse_next(input)
|
||||
}
|
||||
const NAN: &[u8] = b"nan";
|
||||
|
||||
// DIGIT = %x30-39 ; 0-9
|
||||
pub(crate) fn digit(input: &mut Input<'_>) -> PResult<u8> {
|
||||
one_of(DIGIT).parse_next(input)
|
||||
}
|
||||
const DIGIT: RangeInclusive<u8> = b'0'..=b'9';
|
||||
|
||||
// HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F"
|
||||
pub(crate) fn hexdig(input: &mut Input<'_>) -> PResult<u8> {
|
||||
one_of(HEXDIG).parse_next(input)
|
||||
}
|
||||
pub(crate) const HEXDIG: (RangeInclusive<u8>, RangeInclusive<u8>, RangeInclusive<u8>) =
|
||||
(DIGIT, b'A'..=b'F', b'a'..=b'f');
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn integers() {
|
||||
let cases = [
|
||||
("+99", 99),
|
||||
("42", 42),
|
||||
("0", 0),
|
||||
("-17", -17),
|
||||
("1_000", 1_000),
|
||||
("5_349_221", 5_349_221),
|
||||
("1_2_3_4_5", 1_2_3_4_5),
|
||||
("0xF", 15),
|
||||
("0o0_755", 493),
|
||||
("0b1_0_1", 5),
|
||||
(&std::i64::MIN.to_string()[..], std::i64::MIN),
|
||||
(&std::i64::MAX.to_string()[..], std::i64::MAX),
|
||||
];
|
||||
for &(input, expected) in &cases {
|
||||
dbg!(input);
|
||||
let parsed = integer.parse(new_input(input));
|
||||
assert_eq!(parsed, Ok(expected), "Parsing {input:?}");
|
||||
}
|
||||
|
||||
let overflow = "1000000000000000000000000000000000";
|
||||
let parsed = integer.parse(new_input(overflow));
|
||||
assert!(parsed.is_err());
|
||||
}
|
||||
|
||||
#[track_caller]
|
||||
fn assert_float_eq(actual: f64, expected: f64) {
|
||||
if expected.is_nan() {
|
||||
assert!(actual.is_nan());
|
||||
} else if expected.is_infinite() {
|
||||
assert!(actual.is_infinite());
|
||||
assert_eq!(expected.is_sign_positive(), actual.is_sign_positive());
|
||||
} else {
|
||||
dbg!(expected);
|
||||
dbg!(actual);
|
||||
assert!((expected - actual).abs() < std::f64::EPSILON);
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn floats() {
|
||||
let cases = [
|
||||
("+1.0", 1.0),
|
||||
("3.1419", 3.1419),
|
||||
("-0.01", -0.01),
|
||||
("5e+22", 5e+22),
|
||||
("1e6", 1e6),
|
||||
("-2E-2", -2E-2),
|
||||
("6.626e-34", 6.626e-34),
|
||||
("9_224_617.445_991_228_313", 9_224_617.445_991_227),
|
||||
("-1.7976931348623157e+308", std::f64::MIN),
|
||||
("1.7976931348623157e+308", std::f64::MAX),
|
||||
("nan", f64::NAN),
|
||||
("+nan", f64::NAN),
|
||||
("-nan", f64::NAN),
|
||||
("inf", f64::INFINITY),
|
||||
("+inf", f64::INFINITY),
|
||||
("-inf", f64::NEG_INFINITY),
|
||||
// ("1e+400", std::f64::INFINITY),
|
||||
];
|
||||
for &(input, expected) in &cases {
|
||||
dbg!(input);
|
||||
let parsed = float.parse(new_input(input)).unwrap();
|
||||
assert_float_eq(parsed, expected);
|
||||
|
||||
let overflow = "9e99999";
|
||||
let parsed = float.parse(new_input(overflow));
|
||||
assert!(parsed.is_err(), "{:?}", parsed);
|
||||
}
|
||||
}
|
||||
}
|
||||
323
third-party/vendor/toml_edit/src/parser/state.rs
vendored
Normal file
323
third-party/vendor/toml_edit/src/parser/state.rs
vendored
Normal file
|
|
@ -0,0 +1,323 @@
|
|||
use crate::key::Key;
|
||||
use crate::parser::errors::CustomError;
|
||||
use crate::repr::Decor;
|
||||
use crate::table::TableKeyValue;
|
||||
use crate::{ArrayOfTables, Document, InternalString, Item, RawString, Table};
|
||||
|
||||
pub(crate) struct ParseState {
|
||||
document: Document,
|
||||
trailing: Option<std::ops::Range<usize>>,
|
||||
current_table_position: usize,
|
||||
current_table: Table,
|
||||
current_is_array: bool,
|
||||
current_table_path: Vec<Key>,
|
||||
}
|
||||
|
||||
impl ParseState {
|
||||
pub(crate) fn into_document(mut self) -> Result<Document, CustomError> {
|
||||
self.finalize_table()?;
|
||||
let trailing = self.trailing.map(RawString::with_span);
|
||||
self.document.trailing = trailing.unwrap_or_default();
|
||||
Ok(self.document)
|
||||
}
|
||||
|
||||
pub(crate) fn on_ws(&mut self, span: std::ops::Range<usize>) {
|
||||
if let Some(old) = self.trailing.take() {
|
||||
self.trailing = Some(old.start..span.end);
|
||||
} else {
|
||||
self.trailing = Some(span);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn on_comment(&mut self, span: std::ops::Range<usize>) {
|
||||
if let Some(old) = self.trailing.take() {
|
||||
self.trailing = Some(old.start..span.end);
|
||||
} else {
|
||||
self.trailing = Some(span);
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn on_keyval(
|
||||
&mut self,
|
||||
mut path: Vec<Key>,
|
||||
mut kv: TableKeyValue,
|
||||
) -> Result<(), CustomError> {
|
||||
{
|
||||
let mut prefix = self.trailing.take();
|
||||
let first_key = if path.is_empty() {
|
||||
&mut kv.key
|
||||
} else {
|
||||
&mut path[0]
|
||||
};
|
||||
let prefix = match (
|
||||
prefix.take(),
|
||||
first_key.decor.prefix().and_then(|d| d.span()),
|
||||
) {
|
||||
(Some(p), Some(k)) => Some(p.start..k.end),
|
||||
(Some(p), None) | (None, Some(p)) => Some(p),
|
||||
(None, None) => None,
|
||||
};
|
||||
first_key
|
||||
.decor
|
||||
.set_prefix(prefix.map(RawString::with_span).unwrap_or_default());
|
||||
}
|
||||
|
||||
if let (Some(existing), Some(value)) = (self.current_table.span(), kv.value.span()) {
|
||||
self.current_table.span = Some((existing.start)..(value.end));
|
||||
}
|
||||
let table = &mut self.current_table;
|
||||
let table = Self::descend_path(table, &path, true)?;
|
||||
|
||||
// "Likewise, using dotted keys to redefine tables already defined in [table] form is not allowed"
|
||||
let mixed_table_types = table.is_dotted() == path.is_empty();
|
||||
if mixed_table_types {
|
||||
return Err(CustomError::DuplicateKey {
|
||||
key: kv.key.get().into(),
|
||||
table: None,
|
||||
});
|
||||
}
|
||||
|
||||
let key: InternalString = kv.key.get_internal().into();
|
||||
match table.items.entry(key) {
|
||||
indexmap::map::Entry::Vacant(o) => {
|
||||
o.insert(kv);
|
||||
}
|
||||
indexmap::map::Entry::Occupied(o) => {
|
||||
// "Since tables cannot be defined more than once, redefining such tables using a [table] header is not allowed"
|
||||
return Err(CustomError::DuplicateKey {
|
||||
key: o.key().as_str().into(),
|
||||
table: Some(self.current_table_path.clone()),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn start_array_table(
|
||||
&mut self,
|
||||
path: Vec<Key>,
|
||||
decor: Decor,
|
||||
span: std::ops::Range<usize>,
|
||||
) -> Result<(), CustomError> {
|
||||
debug_assert!(!path.is_empty());
|
||||
debug_assert!(self.current_table.is_empty());
|
||||
debug_assert!(self.current_table_path.is_empty());
|
||||
|
||||
// Look up the table on start to ensure the duplicate_key error points to the right line
|
||||
let root = self.document.as_table_mut();
|
||||
let parent_table = Self::descend_path(root, &path[..path.len() - 1], false)?;
|
||||
let key = &path[path.len() - 1];
|
||||
let entry = parent_table
|
||||
.entry_format(key)
|
||||
.or_insert(Item::ArrayOfTables(ArrayOfTables::new()));
|
||||
entry
|
||||
.as_array_of_tables()
|
||||
.ok_or_else(|| CustomError::duplicate_key(&path, path.len() - 1))?;
|
||||
|
||||
self.current_table_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_table_position);
|
||||
self.current_table.span = Some(span);
|
||||
self.current_is_array = true;
|
||||
self.current_table_path = path;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn start_table(
|
||||
&mut self,
|
||||
path: Vec<Key>,
|
||||
decor: Decor,
|
||||
span: std::ops::Range<usize>,
|
||||
) -> Result<(), CustomError> {
|
||||
debug_assert!(!path.is_empty());
|
||||
debug_assert!(self.current_table.is_empty());
|
||||
debug_assert!(self.current_table_path.is_empty());
|
||||
|
||||
// 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 = self.document.as_table_mut();
|
||||
let parent_table = Self::descend_path(root, &path[..path.len() - 1], false)?;
|
||||
let key = &path[path.len() - 1];
|
||||
if let Some(entry) = parent_table.remove(key.get()) {
|
||||
match entry {
|
||||
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.
|
||||
_ => return Err(CustomError::duplicate_key(&path, path.len() - 1)),
|
||||
}
|
||||
}
|
||||
|
||||
self.current_table_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_table_position);
|
||||
self.current_table.span = Some(span);
|
||||
self.current_is_array = false;
|
||||
self.current_table_path = path;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn finalize_table(&mut self) -> Result<(), CustomError> {
|
||||
let mut table = std::mem::take(&mut self.current_table);
|
||||
let path = std::mem::take(&mut self.current_table_path);
|
||||
|
||||
let root = self.document.as_table_mut();
|
||||
if path.is_empty() {
|
||||
assert!(root.is_empty());
|
||||
std::mem::swap(&mut table, root);
|
||||
} else if self.current_is_array {
|
||||
let parent_table = Self::descend_path(root, &path[..path.len() - 1], false)?;
|
||||
let key = &path[path.len() - 1];
|
||||
|
||||
let entry = parent_table
|
||||
.entry_format(key)
|
||||
.or_insert(Item::ArrayOfTables(ArrayOfTables::new()));
|
||||
let array = entry
|
||||
.as_array_of_tables_mut()
|
||||
.ok_or_else(|| CustomError::duplicate_key(&path, path.len() - 1))?;
|
||||
array.push(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 parent_table = Self::descend_path(root, &path[..path.len() - 1], false)?;
|
||||
let key = &path[path.len() - 1];
|
||||
|
||||
let entry = parent_table.entry_format(key);
|
||||
match entry {
|
||||
crate::Entry::Occupied(entry) => {
|
||||
match entry.into_mut() {
|
||||
// if [a.b.c] header preceded [a.b]
|
||||
Item::Table(ref mut t) if t.implicit => {
|
||||
std::mem::swap(t, &mut table);
|
||||
}
|
||||
_ => return Err(CustomError::duplicate_key(&path, path.len() - 1)),
|
||||
}
|
||||
}
|
||||
crate::Entry::Vacant(entry) => {
|
||||
let item = Item::Table(table);
|
||||
entry.insert(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn descend_path<'t, 'k>(
|
||||
mut table: &'t mut Table,
|
||||
path: &'k [Key],
|
||||
dotted: bool,
|
||||
) -> Result<&'t mut Table, CustomError> {
|
||||
for (i, key) in path.iter().enumerate() {
|
||||
let entry = table.entry_format(key).or_insert_with(|| {
|
||||
let mut new_table = Table::new();
|
||||
new_table.set_implicit(true);
|
||||
new_table.set_dotted(dotted);
|
||||
|
||||
Item::Table(new_table)
|
||||
});
|
||||
match *entry {
|
||||
Item::Value(ref v) => {
|
||||
return Err(CustomError::extend_wrong_type(path, i, v.type_name()));
|
||||
}
|
||||
Item::ArrayOfTables(ref mut array) => {
|
||||
debug_assert!(!array.is_empty());
|
||||
|
||||
let index = array.len() - 1;
|
||||
let last_child = array.get_mut(index).unwrap();
|
||||
|
||||
table = 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() {
|
||||
return Err(CustomError::DuplicateKey {
|
||||
key: key.get().into(),
|
||||
table: None,
|
||||
});
|
||||
}
|
||||
table = sweet_child_of_mine;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
Ok(table)
|
||||
}
|
||||
|
||||
pub(crate) fn on_std_header(
|
||||
&mut self,
|
||||
path: Vec<Key>,
|
||||
trailing: std::ops::Range<usize>,
|
||||
span: std::ops::Range<usize>,
|
||||
) -> Result<(), CustomError> {
|
||||
debug_assert!(!path.is_empty());
|
||||
|
||||
self.finalize_table()?;
|
||||
let leading = self
|
||||
.trailing
|
||||
.take()
|
||||
.map(RawString::with_span)
|
||||
.unwrap_or_default();
|
||||
self.start_table(
|
||||
path,
|
||||
Decor::new(leading, RawString::with_span(trailing)),
|
||||
span,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn on_array_header(
|
||||
&mut self,
|
||||
path: Vec<Key>,
|
||||
trailing: std::ops::Range<usize>,
|
||||
span: std::ops::Range<usize>,
|
||||
) -> Result<(), CustomError> {
|
||||
debug_assert!(!path.is_empty());
|
||||
|
||||
self.finalize_table()?;
|
||||
let leading = self
|
||||
.trailing
|
||||
.take()
|
||||
.map(RawString::with_span)
|
||||
.unwrap_or_default();
|
||||
self.start_array_table(
|
||||
path,
|
||||
Decor::new(leading, RawString::with_span(trailing)),
|
||||
span,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for ParseState {
|
||||
fn default() -> Self {
|
||||
let mut root = Table::new();
|
||||
root.span = Some(0..0);
|
||||
Self {
|
||||
document: Document::new(),
|
||||
trailing: None,
|
||||
current_table_position: 0,
|
||||
current_table: root,
|
||||
current_is_array: false,
|
||||
current_table_path: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
478
third-party/vendor/toml_edit/src/parser/strings.rs
vendored
Normal file
478
third-party/vendor/toml_edit/src/parser/strings.rs
vendored
Normal file
|
|
@ -0,0 +1,478 @@
|
|||
use std::borrow::Cow;
|
||||
use std::char;
|
||||
use std::ops::RangeInclusive;
|
||||
|
||||
use winnow::combinator::alt;
|
||||
use winnow::combinator::cut_err;
|
||||
use winnow::combinator::delimited;
|
||||
use winnow::combinator::fail;
|
||||
use winnow::combinator::opt;
|
||||
use winnow::combinator::peek;
|
||||
use winnow::combinator::preceded;
|
||||
use winnow::combinator::repeat;
|
||||
use winnow::combinator::success;
|
||||
use winnow::combinator::terminated;
|
||||
use winnow::prelude::*;
|
||||
use winnow::stream::Stream;
|
||||
use winnow::token::any;
|
||||
use winnow::token::none_of;
|
||||
use winnow::token::one_of;
|
||||
use winnow::token::tag;
|
||||
use winnow::token::take_while;
|
||||
use winnow::trace::trace;
|
||||
|
||||
use crate::parser::errors::CustomError;
|
||||
use crate::parser::numbers::HEXDIG;
|
||||
use crate::parser::prelude::*;
|
||||
use crate::parser::trivia::{from_utf8_unchecked, newline, ws, ws_newlines, NON_ASCII, WSCHAR};
|
||||
|
||||
// ;; String
|
||||
|
||||
// string = ml-basic-string / basic-string / ml-literal-string / literal-string
|
||||
pub(crate) fn string<'i>(input: &mut Input<'i>) -> PResult<Cow<'i, str>> {
|
||||
trace(
|
||||
"string",
|
||||
alt((
|
||||
ml_basic_string,
|
||||
basic_string,
|
||||
ml_literal_string,
|
||||
literal_string.map(Cow::Borrowed),
|
||||
)),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// ;; Basic String
|
||||
|
||||
// basic-string = quotation-mark *basic-char quotation-mark
|
||||
pub(crate) fn basic_string<'i>(input: &mut Input<'i>) -> PResult<Cow<'i, str>> {
|
||||
trace("basic-string", |input: &mut Input<'i>| {
|
||||
let _ = one_of(QUOTATION_MARK).parse_next(input)?;
|
||||
|
||||
let mut c = Cow::Borrowed("");
|
||||
if let Some(ci) = opt(basic_chars).parse_next(input)? {
|
||||
c = ci;
|
||||
}
|
||||
while let Some(ci) = opt(basic_chars).parse_next(input)? {
|
||||
c.to_mut().push_str(&ci);
|
||||
}
|
||||
|
||||
let _ = cut_err(one_of(QUOTATION_MARK))
|
||||
.context(StrContext::Label("basic string"))
|
||||
.parse_next(input)?;
|
||||
|
||||
Ok(c)
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// quotation-mark = %x22 ; "
|
||||
pub(crate) const QUOTATION_MARK: u8 = b'"';
|
||||
|
||||
// basic-char = basic-unescaped / escaped
|
||||
fn basic_chars<'i>(input: &mut Input<'i>) -> PResult<Cow<'i, str>> {
|
||||
alt((
|
||||
// Deviate from the official grammar by batching the unescaped chars so we build a string a
|
||||
// chunk at a time, rather than a `char` at a time.
|
||||
take_while(1.., BASIC_UNESCAPED)
|
||||
.try_map(std::str::from_utf8)
|
||||
.map(Cow::Borrowed),
|
||||
escaped.map(|c| Cow::Owned(String::from(c))),
|
||||
))
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// basic-unescaped = wschar / %x21 / %x23-5B / %x5D-7E / non-ascii
|
||||
pub(crate) const BASIC_UNESCAPED: (
|
||||
(u8, u8),
|
||||
u8,
|
||||
RangeInclusive<u8>,
|
||||
RangeInclusive<u8>,
|
||||
RangeInclusive<u8>,
|
||||
) = (WSCHAR, 0x21, 0x23..=0x5B, 0x5D..=0x7E, NON_ASCII);
|
||||
|
||||
// escaped = escape escape-seq-char
|
||||
fn escaped(input: &mut Input<'_>) -> PResult<char> {
|
||||
preceded(ESCAPE, escape_seq_char).parse_next(input)
|
||||
}
|
||||
|
||||
// escape = %x5C ; \
|
||||
pub(crate) const ESCAPE: u8 = b'\\';
|
||||
|
||||
// escape-seq-char = %x22 ; " quotation mark U+0022
|
||||
// escape-seq-char =/ %x5C ; \ reverse solidus U+005C
|
||||
// escape-seq-char =/ %x62 ; b backspace U+0008
|
||||
// escape-seq-char =/ %x66 ; f form feed U+000C
|
||||
// escape-seq-char =/ %x6E ; n line feed U+000A
|
||||
// escape-seq-char =/ %x72 ; r carriage return U+000D
|
||||
// escape-seq-char =/ %x74 ; t tab U+0009
|
||||
// escape-seq-char =/ %x75 4HEXDIG ; uXXXX U+XXXX
|
||||
// escape-seq-char =/ %x55 8HEXDIG ; UXXXXXXXX U+XXXXXXXX
|
||||
fn escape_seq_char(input: &mut Input<'_>) -> PResult<char> {
|
||||
dispatch! {any;
|
||||
b'b' => success('\u{8}'),
|
||||
b'f' => success('\u{c}'),
|
||||
b'n' => success('\n'),
|
||||
b'r' => success('\r'),
|
||||
b't' => success('\t'),
|
||||
b'u' => cut_err(hexescape::<4>).context(StrContext::Label("unicode 4-digit hex code")),
|
||||
b'U' => cut_err(hexescape::<8>).context(StrContext::Label("unicode 8-digit hex code")),
|
||||
b'\\' => success('\\'),
|
||||
b'"' => success('"'),
|
||||
_ => {
|
||||
cut_err(fail::<_, char, _>)
|
||||
.context(StrContext::Label("escape sequence"))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('b')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('f')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('n')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('r')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('t')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('u')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('U')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('\\')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('"')))
|
||||
}
|
||||
}
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
pub(crate) fn hexescape<const N: usize>(input: &mut Input<'_>) -> PResult<char> {
|
||||
take_while(0..=N, HEXDIG)
|
||||
.verify(|b: &[u8]| b.len() == N)
|
||||
.map(|b: &[u8]| unsafe { from_utf8_unchecked(b, "`is_ascii_digit` filters out on-ASCII") })
|
||||
.verify_map(|s| u32::from_str_radix(s, 16).ok())
|
||||
.try_map(|h| char::from_u32(h).ok_or(CustomError::OutOfRange))
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// ;; Multiline Basic String
|
||||
|
||||
// ml-basic-string = ml-basic-string-delim [ newline ] ml-basic-body
|
||||
// ml-basic-string-delim
|
||||
fn ml_basic_string<'i>(input: &mut Input<'i>) -> PResult<Cow<'i, str>> {
|
||||
trace(
|
||||
"ml-basic-string",
|
||||
delimited(
|
||||
ML_BASIC_STRING_DELIM,
|
||||
preceded(opt(newline), cut_err(ml_basic_body)),
|
||||
cut_err(ML_BASIC_STRING_DELIM),
|
||||
)
|
||||
.context(StrContext::Label("multiline basic string")),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// ml-basic-string-delim = 3quotation-mark
|
||||
pub(crate) const ML_BASIC_STRING_DELIM: &[u8] = b"\"\"\"";
|
||||
|
||||
// ml-basic-body = *mlb-content *( mlb-quotes 1*mlb-content ) [ mlb-quotes ]
|
||||
fn ml_basic_body<'i>(input: &mut Input<'i>) -> PResult<Cow<'i, str>> {
|
||||
let mut c = Cow::Borrowed("");
|
||||
if let Some(ci) = opt(mlb_content).parse_next(input)? {
|
||||
c = ci;
|
||||
}
|
||||
while let Some(ci) = opt(mlb_content).parse_next(input)? {
|
||||
c.to_mut().push_str(&ci);
|
||||
}
|
||||
|
||||
while let Some(qi) = opt(mlb_quotes(none_of(b'\"').value(()))).parse_next(input)? {
|
||||
if let Some(ci) = opt(mlb_content).parse_next(input)? {
|
||||
c.to_mut().push_str(qi);
|
||||
c.to_mut().push_str(&ci);
|
||||
while let Some(ci) = opt(mlb_content).parse_next(input)? {
|
||||
c.to_mut().push_str(&ci);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(qi) = opt(mlb_quotes(tag(ML_BASIC_STRING_DELIM).value(()))).parse_next(input)? {
|
||||
c.to_mut().push_str(qi);
|
||||
}
|
||||
|
||||
Ok(c)
|
||||
}
|
||||
|
||||
// mlb-content = mlb-char / newline / mlb-escaped-nl
|
||||
// mlb-char = mlb-unescaped / escaped
|
||||
fn mlb_content<'i>(input: &mut Input<'i>) -> PResult<Cow<'i, str>> {
|
||||
alt((
|
||||
// Deviate from the official grammar by batching the unescaped chars so we build a string a
|
||||
// chunk at a time, rather than a `char` at a time.
|
||||
take_while(1.., MLB_UNESCAPED)
|
||||
.try_map(std::str::from_utf8)
|
||||
.map(Cow::Borrowed),
|
||||
// Order changed fromg grammar so `escaped` can more easily `cut_err` on bad escape sequences
|
||||
mlb_escaped_nl.map(|_| Cow::Borrowed("")),
|
||||
escaped.map(|c| Cow::Owned(String::from(c))),
|
||||
newline.map(|_| Cow::Borrowed("\n")),
|
||||
))
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// mlb-quotes = 1*2quotation-mark
|
||||
fn mlb_quotes<'i>(
|
||||
mut term: impl winnow::Parser<Input<'i>, (), ContextError>,
|
||||
) -> impl Parser<Input<'i>, &'i str, ContextError> {
|
||||
move |input: &mut Input<'i>| {
|
||||
let start = input.checkpoint();
|
||||
let res = terminated(b"\"\"", peek(term.by_ref()))
|
||||
.map(|b| unsafe { from_utf8_unchecked(b, "`bytes` out non-ASCII") })
|
||||
.parse_next(input);
|
||||
|
||||
match res {
|
||||
Err(winnow::error::ErrMode::Backtrack(_)) => {
|
||||
input.reset(start);
|
||||
terminated(b"\"", peek(term.by_ref()))
|
||||
.map(|b| unsafe { from_utf8_unchecked(b, "`bytes` out non-ASCII") })
|
||||
.parse_next(input)
|
||||
}
|
||||
res => res,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// mlb-unescaped = wschar / %x21 / %x23-5B / %x5D-7E / non-ascii
|
||||
pub(crate) const MLB_UNESCAPED: (
|
||||
(u8, u8),
|
||||
u8,
|
||||
RangeInclusive<u8>,
|
||||
RangeInclusive<u8>,
|
||||
RangeInclusive<u8>,
|
||||
) = (WSCHAR, 0x21, 0x23..=0x5B, 0x5D..=0x7E, NON_ASCII);
|
||||
|
||||
// mlb-escaped-nl = escape ws newline *( wschar / newline
|
||||
// When the last non-whitespace character on a line is a \,
|
||||
// it will be trimmed along with all whitespace
|
||||
// (including newlines) up to the next non-whitespace
|
||||
// character or closing delimiter.
|
||||
fn mlb_escaped_nl(input: &mut Input<'_>) -> PResult<()> {
|
||||
repeat(1.., (ESCAPE, ws, ws_newlines))
|
||||
.map(|()| ())
|
||||
.value(())
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// ;; Literal String
|
||||
|
||||
// literal-string = apostrophe *literal-char apostrophe
|
||||
pub(crate) fn literal_string<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
trace(
|
||||
"literal-string",
|
||||
delimited(
|
||||
APOSTROPHE,
|
||||
cut_err(take_while(0.., LITERAL_CHAR)),
|
||||
cut_err(APOSTROPHE),
|
||||
)
|
||||
.try_map(std::str::from_utf8)
|
||||
.context(StrContext::Label("literal string")),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// apostrophe = %x27 ; ' apostrophe
|
||||
pub(crate) const APOSTROPHE: u8 = b'\'';
|
||||
|
||||
// literal-char = %x09 / %x20-26 / %x28-7E / non-ascii
|
||||
pub(crate) const LITERAL_CHAR: (
|
||||
u8,
|
||||
RangeInclusive<u8>,
|
||||
RangeInclusive<u8>,
|
||||
RangeInclusive<u8>,
|
||||
) = (0x9, 0x20..=0x26, 0x28..=0x7E, NON_ASCII);
|
||||
|
||||
// ;; Multiline Literal String
|
||||
|
||||
// ml-literal-string = ml-literal-string-delim [ newline ] ml-literal-body
|
||||
// ml-literal-string-delim
|
||||
fn ml_literal_string<'i>(input: &mut Input<'i>) -> PResult<Cow<'i, str>> {
|
||||
trace(
|
||||
"ml-literal-string",
|
||||
delimited(
|
||||
(ML_LITERAL_STRING_DELIM, opt(newline)),
|
||||
cut_err(ml_literal_body.map(|t| {
|
||||
if t.contains("\r\n") {
|
||||
Cow::Owned(t.replace("\r\n", "\n"))
|
||||
} else {
|
||||
Cow::Borrowed(t)
|
||||
}
|
||||
})),
|
||||
cut_err(ML_LITERAL_STRING_DELIM),
|
||||
)
|
||||
.context(StrContext::Label("multiline literal string")),
|
||||
)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// ml-literal-string-delim = 3apostrophe
|
||||
pub(crate) const ML_LITERAL_STRING_DELIM: &[u8] = b"'''";
|
||||
|
||||
// ml-literal-body = *mll-content *( mll-quotes 1*mll-content ) [ mll-quotes ]
|
||||
fn ml_literal_body<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
(
|
||||
repeat(0.., mll_content).map(|()| ()),
|
||||
repeat(
|
||||
0..,
|
||||
(
|
||||
mll_quotes(none_of(APOSTROPHE).value(())),
|
||||
repeat(1.., mll_content).map(|()| ()),
|
||||
),
|
||||
)
|
||||
.map(|()| ()),
|
||||
opt(mll_quotes(tag(ML_LITERAL_STRING_DELIM).value(()))),
|
||||
)
|
||||
.recognize()
|
||||
.try_map(std::str::from_utf8)
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// mll-content = mll-char / newline
|
||||
fn mll_content(input: &mut Input<'_>) -> PResult<u8> {
|
||||
alt((one_of(MLL_CHAR), newline)).parse_next(input)
|
||||
}
|
||||
|
||||
// mll-char = %x09 / %x20-26 / %x28-7E / non-ascii
|
||||
const MLL_CHAR: (
|
||||
u8,
|
||||
RangeInclusive<u8>,
|
||||
RangeInclusive<u8>,
|
||||
RangeInclusive<u8>,
|
||||
) = (0x9, 0x20..=0x26, 0x28..=0x7E, NON_ASCII);
|
||||
|
||||
// mll-quotes = 1*2apostrophe
|
||||
fn mll_quotes<'i>(
|
||||
mut term: impl winnow::Parser<Input<'i>, (), ContextError>,
|
||||
) -> impl Parser<Input<'i>, &'i str, ContextError> {
|
||||
move |input: &mut Input<'i>| {
|
||||
let start = input.checkpoint();
|
||||
let res = terminated(b"''", peek(term.by_ref()))
|
||||
.map(|b| unsafe { from_utf8_unchecked(b, "`bytes` out non-ASCII") })
|
||||
.parse_next(input);
|
||||
|
||||
match res {
|
||||
Err(winnow::error::ErrMode::Backtrack(_)) => {
|
||||
input.reset(start);
|
||||
terminated(b"'", peek(term.by_ref()))
|
||||
.map(|b| unsafe { from_utf8_unchecked(b, "`bytes` out non-ASCII") })
|
||||
.parse_next(input)
|
||||
}
|
||||
res => res,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn basic_string() {
|
||||
let input =
|
||||
r#""I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF. \U0002070E""#;
|
||||
let expected = "I\'m a string. \"You can quote me\". Name\tJosé\nLocation\tSF. \u{2070E}";
|
||||
let parsed = string.parse(new_input(input));
|
||||
assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ml_basic_string() {
|
||||
let cases = [
|
||||
(
|
||||
r#""""
|
||||
Roses are red
|
||||
Violets are blue""""#,
|
||||
r#"Roses are red
|
||||
Violets are blue"#,
|
||||
),
|
||||
(r#"""" \""" """"#, " \"\"\" "),
|
||||
(r#"""" \\""""#, " \\"),
|
||||
];
|
||||
|
||||
for &(input, expected) in &cases {
|
||||
let parsed = string.parse(new_input(input));
|
||||
assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}");
|
||||
}
|
||||
|
||||
let invalid_cases = [r#"""" """#, r#"""" \""""#];
|
||||
|
||||
for input in &invalid_cases {
|
||||
let parsed = string.parse(new_input(input));
|
||||
assert!(parsed.is_err());
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ml_basic_string_escape_ws() {
|
||||
let inputs = [
|
||||
r#""""
|
||||
The quick brown \
|
||||
|
||||
|
||||
fox jumps over \
|
||||
the lazy dog.""""#,
|
||||
r#""""\
|
||||
The quick brown \
|
||||
fox jumps over \
|
||||
the lazy dog.\
|
||||
""""#,
|
||||
];
|
||||
for input in &inputs {
|
||||
let expected = "The quick brown fox jumps over the lazy dog.";
|
||||
let parsed = string.parse(new_input(input));
|
||||
assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}");
|
||||
}
|
||||
let empties = [
|
||||
r#""""\
|
||||
""""#,
|
||||
r#""""
|
||||
\
|
||||
\
|
||||
""""#,
|
||||
];
|
||||
for input in &empties {
|
||||
let expected = "";
|
||||
let parsed = string.parse(new_input(input));
|
||||
assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn literal_string() {
|
||||
let inputs = [
|
||||
r#"'C:\Users\nodejs\templates'"#,
|
||||
r#"'\\ServerX\admin$\system32\'"#,
|
||||
r#"'Tom "Dubs" Preston-Werner'"#,
|
||||
r#"'<\i\c*\s*>'"#,
|
||||
];
|
||||
|
||||
for input in &inputs {
|
||||
let expected = &input[1..input.len() - 1];
|
||||
let parsed = string.parse(new_input(input));
|
||||
assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn ml_literal_string() {
|
||||
let inputs = [
|
||||
r#"'''I [dw]on't need \d{2} apples'''"#,
|
||||
r#"''''one_quote''''"#,
|
||||
];
|
||||
for input in &inputs {
|
||||
let expected = &input[3..input.len() - 3];
|
||||
let parsed = string.parse(new_input(input));
|
||||
assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}");
|
||||
}
|
||||
|
||||
let input = r#"'''
|
||||
The first newline is
|
||||
trimmed in raw strings.
|
||||
All other whitespace
|
||||
is preserved.
|
||||
'''"#;
|
||||
let expected = &input[4..input.len() - 3];
|
||||
let parsed = string.parse(new_input(input));
|
||||
assert_eq!(parsed.as_deref(), Ok(expected), "Parsing {input:?}");
|
||||
}
|
||||
}
|
||||
89
third-party/vendor/toml_edit/src/parser/table.rs
vendored
Normal file
89
third-party/vendor/toml_edit/src/parser/table.rs
vendored
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
use std::cell::RefCell;
|
||||
#[allow(unused_imports)]
|
||||
use std::ops::DerefMut;
|
||||
|
||||
use winnow::combinator::cut_err;
|
||||
use winnow::combinator::delimited;
|
||||
use winnow::combinator::peek;
|
||||
use winnow::token::take;
|
||||
|
||||
// https://github.com/rust-lang/rust/issues/41358
|
||||
use crate::parser::key::key;
|
||||
use crate::parser::prelude::*;
|
||||
use crate::parser::state::ParseState;
|
||||
use crate::parser::trivia::line_trailing;
|
||||
|
||||
// std-table-open = %x5B ws ; [ Left square bracket
|
||||
pub(crate) const STD_TABLE_OPEN: u8 = b'[';
|
||||
// std-table-close = ws %x5D ; ] Right square bracket
|
||||
const STD_TABLE_CLOSE: u8 = b']';
|
||||
// array-table-open = %x5B.5B ws ; [[ Double left square bracket
|
||||
const ARRAY_TABLE_OPEN: &[u8] = b"[[";
|
||||
// array-table-close = ws %x5D.5D ; ]] Double right quare bracket
|
||||
const ARRAY_TABLE_CLOSE: &[u8] = b"]]";
|
||||
|
||||
// ;; Standard Table
|
||||
|
||||
// std-table = std-table-open key *( table-key-sep key) std-table-close
|
||||
pub(crate) fn std_table<'s, 'i>(
|
||||
state: &'s RefCell<ParseState>,
|
||||
) -> impl Parser<Input<'i>, (), ContextError> + 's {
|
||||
move |i: &mut Input<'i>| {
|
||||
(
|
||||
delimited(
|
||||
STD_TABLE_OPEN,
|
||||
cut_err(key),
|
||||
cut_err(STD_TABLE_CLOSE)
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('.')))
|
||||
.context(StrContext::Expected(StrContextValue::StringLiteral("]"))),
|
||||
)
|
||||
.with_span(),
|
||||
cut_err(line_trailing)
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('\n')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('#'))),
|
||||
)
|
||||
.try_map(|((h, span), t)| state.borrow_mut().deref_mut().on_std_header(h, t, span))
|
||||
.parse_next(i)
|
||||
}
|
||||
}
|
||||
|
||||
// ;; Array Table
|
||||
|
||||
// array-table = array-table-open key *( table-key-sep key) array-table-close
|
||||
pub(crate) fn array_table<'s, 'i>(
|
||||
state: &'s RefCell<ParseState>,
|
||||
) -> impl Parser<Input<'i>, (), ContextError> + 's {
|
||||
move |i: &mut Input<'i>| {
|
||||
(
|
||||
delimited(
|
||||
ARRAY_TABLE_OPEN,
|
||||
cut_err(key),
|
||||
cut_err(ARRAY_TABLE_CLOSE)
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('.')))
|
||||
.context(StrContext::Expected(StrContextValue::StringLiteral("]]"))),
|
||||
)
|
||||
.with_span(),
|
||||
cut_err(line_trailing)
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('\n')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('#'))),
|
||||
)
|
||||
.try_map(|((h, span), t)| state.borrow_mut().deref_mut().on_array_header(h, t, span))
|
||||
.parse_next(i)
|
||||
}
|
||||
}
|
||||
|
||||
// ;; Table
|
||||
|
||||
// table = std-table / array-table
|
||||
pub(crate) fn table<'s, 'i>(
|
||||
state: &'s RefCell<ParseState>,
|
||||
) -> impl Parser<Input<'i>, (), ContextError> + 's {
|
||||
move |i: &mut Input<'i>| {
|
||||
dispatch!(peek::<_, &[u8],_,_>(take(2usize));
|
||||
b"[[" => array_table(state),
|
||||
_ => std_table(state),
|
||||
)
|
||||
.context(StrContext::Label("table header"))
|
||||
.parse_next(i)
|
||||
}
|
||||
}
|
||||
156
third-party/vendor/toml_edit/src/parser/trivia.rs
vendored
Normal file
156
third-party/vendor/toml_edit/src/parser/trivia.rs
vendored
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
use std::ops::RangeInclusive;
|
||||
|
||||
use winnow::combinator::alt;
|
||||
use winnow::combinator::eof;
|
||||
use winnow::combinator::opt;
|
||||
use winnow::combinator::repeat;
|
||||
use winnow::combinator::terminated;
|
||||
use winnow::prelude::*;
|
||||
use winnow::token::one_of;
|
||||
use winnow::token::take_while;
|
||||
|
||||
use crate::parser::prelude::*;
|
||||
|
||||
pub(crate) unsafe fn from_utf8_unchecked<'b>(
|
||||
bytes: &'b [u8],
|
||||
safety_justification: &'static str,
|
||||
) -> &'b str {
|
||||
if cfg!(debug_assertions) {
|
||||
// Catch problems more quickly when testing
|
||||
std::str::from_utf8(bytes).expect(safety_justification)
|
||||
} else {
|
||||
std::str::from_utf8_unchecked(bytes)
|
||||
}
|
||||
}
|
||||
|
||||
// wschar = ( %x20 / ; Space
|
||||
// %x09 ) ; Horizontal tab
|
||||
pub(crate) const WSCHAR: (u8, u8) = (b' ', b'\t');
|
||||
|
||||
// ws = *wschar
|
||||
pub(crate) fn ws<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
take_while(0.., WSCHAR)
|
||||
.map(|b| unsafe { from_utf8_unchecked(b, "`is_wschar` filters out on-ASCII") })
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// non-ascii = %x80-D7FF / %xE000-10FFFF
|
||||
// - ASCII is 0xxxxxxx
|
||||
// - First byte for UTF-8 is 11xxxxxx
|
||||
// - Subsequent UTF-8 bytes are 10xxxxxx
|
||||
pub(crate) const NON_ASCII: RangeInclusive<u8> = 0x80..=0xff;
|
||||
|
||||
// non-eol = %x09 / %x20-7E / non-ascii
|
||||
pub(crate) const NON_EOL: (u8, RangeInclusive<u8>, RangeInclusive<u8>) =
|
||||
(0x09, 0x20..=0x7E, NON_ASCII);
|
||||
|
||||
// comment-start-symbol = %x23 ; #
|
||||
pub(crate) const COMMENT_START_SYMBOL: u8 = b'#';
|
||||
|
||||
// comment = comment-start-symbol *non-eol
|
||||
pub(crate) fn comment<'i>(input: &mut Input<'i>) -> PResult<&'i [u8]> {
|
||||
(COMMENT_START_SYMBOL, take_while(0.., NON_EOL))
|
||||
.recognize()
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// newline = ( %x0A / ; LF
|
||||
// %x0D.0A ) ; CRLF
|
||||
pub(crate) fn newline(input: &mut Input<'_>) -> PResult<u8> {
|
||||
alt((
|
||||
one_of(LF).value(b'\n'),
|
||||
(one_of(CR), one_of(LF)).value(b'\n'),
|
||||
))
|
||||
.parse_next(input)
|
||||
}
|
||||
pub(crate) const LF: u8 = b'\n';
|
||||
pub(crate) const CR: u8 = b'\r';
|
||||
|
||||
// ws-newline = *( wschar / newline )
|
||||
pub(crate) fn ws_newline<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
repeat(
|
||||
0..,
|
||||
alt((newline.value(&b"\n"[..]), take_while(1.., WSCHAR))),
|
||||
)
|
||||
.map(|()| ())
|
||||
.recognize()
|
||||
.map(|b| unsafe { from_utf8_unchecked(b, "`is_wschar` and `newline` filters out on-ASCII") })
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// ws-newlines = newline *( wschar / newline )
|
||||
pub(crate) fn ws_newlines<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
(newline, ws_newline)
|
||||
.recognize()
|
||||
.map(|b| unsafe {
|
||||
from_utf8_unchecked(b, "`is_wschar` and `newline` filters out on-ASCII")
|
||||
})
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// note: this rule is not present in the original grammar
|
||||
// ws-comment-newline = *( ws-newline-nonempty / comment )
|
||||
pub(crate) fn ws_comment_newline<'i>(input: &mut Input<'i>) -> PResult<&'i [u8]> {
|
||||
repeat(
|
||||
0..,
|
||||
alt((
|
||||
repeat(
|
||||
1..,
|
||||
alt((take_while(1.., WSCHAR), newline.value(&b"\n"[..]))),
|
||||
)
|
||||
.map(|()| ()),
|
||||
comment.value(()),
|
||||
)),
|
||||
)
|
||||
.map(|()| ())
|
||||
.recognize()
|
||||
.parse_next(input)
|
||||
}
|
||||
|
||||
// note: this rule is not present in the original grammar
|
||||
// line-ending = newline / eof
|
||||
pub(crate) fn line_ending<'i>(input: &mut Input<'i>) -> PResult<&'i str> {
|
||||
alt((newline.value("\n"), eof.value(""))).parse_next(input)
|
||||
}
|
||||
|
||||
// note: this rule is not present in the original grammar
|
||||
// line-trailing = ws [comment] skip-line-ending
|
||||
pub(crate) fn line_trailing(input: &mut Input<'_>) -> PResult<std::ops::Range<usize>> {
|
||||
terminated((ws, opt(comment)).span(), line_ending).parse_next(input)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn trivia() {
|
||||
let inputs = [
|
||||
"",
|
||||
r#" "#,
|
||||
r#"
|
||||
"#,
|
||||
r#"
|
||||
# comment
|
||||
|
||||
# comment2
|
||||
|
||||
|
||||
"#,
|
||||
r#"
|
||||
"#,
|
||||
r#"# comment
|
||||
# comment2
|
||||
|
||||
|
||||
"#,
|
||||
];
|
||||
for input in inputs {
|
||||
dbg!(input);
|
||||
let parsed = ws_comment_newline.parse(new_input(input));
|
||||
assert!(parsed.is_ok(), "{:?}", parsed);
|
||||
let parsed = parsed.unwrap();
|
||||
assert_eq!(parsed, input.as_bytes());
|
||||
}
|
||||
}
|
||||
}
|
||||
155
third-party/vendor/toml_edit/src/parser/value.rs
vendored
Normal file
155
third-party/vendor/toml_edit/src/parser/value.rs
vendored
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
use winnow::combinator::alt;
|
||||
use winnow::combinator::fail;
|
||||
use winnow::combinator::peek;
|
||||
use winnow::token::any;
|
||||
|
||||
use crate::parser::array::array;
|
||||
use crate::parser::datetime::date_time;
|
||||
use crate::parser::inline_table::inline_table;
|
||||
use crate::parser::numbers::{float, integer};
|
||||
use crate::parser::prelude::*;
|
||||
use crate::parser::strings::string;
|
||||
use crate::repr::{Formatted, Repr};
|
||||
use crate::value as v;
|
||||
use crate::RawString;
|
||||
use crate::Value;
|
||||
|
||||
// val = string / boolean / array / inline-table / date-time / float / integer
|
||||
pub(crate) fn value<'i>(check: RecursionCheck) -> impl Parser<Input<'i>, v::Value, ContextError> {
|
||||
move |input: &mut Input<'i>| {
|
||||
dispatch!{peek(any);
|
||||
crate::parser::strings::QUOTATION_MARK |
|
||||
crate::parser::strings::APOSTROPHE => string.map(|s| {
|
||||
v::Value::String(Formatted::new(
|
||||
s.into_owned()
|
||||
))
|
||||
}),
|
||||
crate::parser::array::ARRAY_OPEN => array(check).map(v::Value::Array),
|
||||
crate::parser::inline_table::INLINE_TABLE_OPEN => inline_table(check).map(v::Value::InlineTable),
|
||||
// Date/number starts
|
||||
b'+' | b'-' | b'0'..=b'9' => {
|
||||
// Uncommon enough not to be worth optimizing at this time
|
||||
alt((
|
||||
date_time
|
||||
.map(v::Value::from),
|
||||
float
|
||||
.map(v::Value::from),
|
||||
integer
|
||||
.map(v::Value::from),
|
||||
))
|
||||
},
|
||||
// Report as if they were numbers because its most likely a typo
|
||||
b'_' => {
|
||||
integer
|
||||
.map(v::Value::from)
|
||||
.context(StrContext::Expected(StrContextValue::Description("leading digit")))
|
||||
},
|
||||
// Report as if they were numbers because its most likely a typo
|
||||
b'.' => {
|
||||
float
|
||||
.map(v::Value::from)
|
||||
.context(StrContext::Expected(StrContextValue::Description("leading digit")))
|
||||
},
|
||||
b't' => {
|
||||
crate::parser::numbers::true_.map(v::Value::from)
|
||||
.context(StrContext::Label("string"))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('"')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('\'')))
|
||||
},
|
||||
b'f' => {
|
||||
crate::parser::numbers::false_.map(v::Value::from)
|
||||
.context(StrContext::Label("string"))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('"')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('\'')))
|
||||
},
|
||||
b'i' => {
|
||||
crate::parser::numbers::inf.map(v::Value::from)
|
||||
.context(StrContext::Label("string"))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('"')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('\'')))
|
||||
},
|
||||
b'n' => {
|
||||
crate::parser::numbers::nan.map(v::Value::from)
|
||||
.context(StrContext::Label("string"))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('"')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('\'')))
|
||||
},
|
||||
_ => {
|
||||
fail
|
||||
.context(StrContext::Label("string"))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('"')))
|
||||
.context(StrContext::Expected(StrContextValue::CharLiteral('\'')))
|
||||
},
|
||||
}
|
||||
.with_span()
|
||||
.try_map(|(value, span)| apply_raw(value, span))
|
||||
.parse_next(input)
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_raw(mut val: Value, span: std::ops::Range<usize>) -> Result<Value, std::str::Utf8Error> {
|
||||
match val {
|
||||
Value::String(ref mut f) => {
|
||||
let raw = RawString::with_span(span);
|
||||
f.set_repr_unchecked(Repr::new_unchecked(raw));
|
||||
}
|
||||
Value::Integer(ref mut f) => {
|
||||
let raw = RawString::with_span(span);
|
||||
f.set_repr_unchecked(Repr::new_unchecked(raw));
|
||||
}
|
||||
Value::Float(ref mut f) => {
|
||||
let raw = RawString::with_span(span);
|
||||
f.set_repr_unchecked(Repr::new_unchecked(raw));
|
||||
}
|
||||
Value::Boolean(ref mut f) => {
|
||||
let raw = RawString::with_span(span);
|
||||
f.set_repr_unchecked(Repr::new_unchecked(raw));
|
||||
}
|
||||
Value::Datetime(ref mut f) => {
|
||||
let raw = RawString::with_span(span);
|
||||
f.set_repr_unchecked(Repr::new_unchecked(raw));
|
||||
}
|
||||
Value::Array(ref mut arr) => {
|
||||
arr.span = Some(span);
|
||||
}
|
||||
Value::InlineTable(ref mut table) => {
|
||||
table.span = Some(span);
|
||||
}
|
||||
};
|
||||
val.decorate("", "");
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn values() {
|
||||
let inputs = [
|
||||
"1979-05-27T00:32:00.999999",
|
||||
"-239",
|
||||
"1e200",
|
||||
"9_224_617.445_991_228_313",
|
||||
r#"'''I [dw]on't need \d{2} apples'''"#,
|
||||
r#"'''
|
||||
The first newline is
|
||||
trimmed in raw strings.
|
||||
All other whitespace
|
||||
is preserved.
|
||||
'''"#,
|
||||
r#""Jos\u00E9\n""#,
|
||||
r#""\\\"\b/\f\n\r\t\u00E9\U000A0000""#,
|
||||
r#"{ hello = "world", a = 1}"#,
|
||||
r#"[ { x = 1, a = "2" }, {a = "a",b = "b", c = "c"} ]"#,
|
||||
];
|
||||
for input in inputs {
|
||||
dbg!(input);
|
||||
let mut parsed = value(Default::default()).parse(new_input(input));
|
||||
if let Ok(parsed) = &mut parsed {
|
||||
parsed.despan(input);
|
||||
}
|
||||
assert_eq!(parsed.map(|a| a.to_string()), Ok(input.to_owned()));
|
||||
}
|
||||
}
|
||||
}
|
||||
182
third-party/vendor/toml_edit/src/raw_string.rs
vendored
Normal file
182
third-party/vendor/toml_edit/src/raw_string.rs
vendored
Normal file
|
|
@ -0,0 +1,182 @@
|
|||
use crate::InternalString;
|
||||
|
||||
/// 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(InternalString),
|
||||
Spanned(std::ops::Range<usize>),
|
||||
}
|
||||
|
||||
impl RawString {
|
||||
pub(crate) fn with_span(span: std::ops::Range<usize>) -> Self {
|
||||
if span.start == span.end {
|
||||
RawString(RawStringInner::Empty)
|
||||
} else {
|
||||
RawString(RawStringInner::Spanned(span))
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the underlying string
|
||||
pub fn as_str(&self) -> Option<&str> {
|
||||
match &self.0 {
|
||||
RawStringInner::Empty => Some(""),
|
||||
RawStringInner::Explicit(s) => Some(s.as_str()),
|
||||
RawStringInner::Spanned(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
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 {:?} should be in input:\n```\n{}\n```", span, input)
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
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 {:?} should be in input:\n```\n{}\n```", span, input)
|
||||
})
|
||||
} else {
|
||||
default
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the underlying span
|
||||
pub(crate) 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 despan(&mut self, input: &str) {
|
||||
match &self.0 {
|
||||
RawStringInner::Empty => {}
|
||||
RawStringInner::Explicit(_) => {}
|
||||
RawStringInner::Spanned(span) => {
|
||||
*self = Self::from(input.get(span.clone()).unwrap_or_else(|| {
|
||||
panic!("span {:?} should be in input:\n```\n{}\n```", span, input)
|
||||
}))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
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 {
|
||||
InternalString::from(s).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<String> for RawString {
|
||||
#[inline]
|
||||
fn from(s: String) -> Self {
|
||||
if s.is_empty() {
|
||||
Self(RawStringInner::Empty)
|
||||
} else {
|
||||
InternalString::from(s).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&String> for RawString {
|
||||
#[inline]
|
||||
fn from(s: &String) -> Self {
|
||||
if s.is_empty() {
|
||||
Self(RawStringInner::Empty)
|
||||
} else {
|
||||
InternalString::from(s).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InternalString> for RawString {
|
||||
#[inline]
|
||||
fn from(inner: InternalString) -> Self {
|
||||
Self(RawStringInner::Explicit(inner))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&InternalString> for RawString {
|
||||
#[inline]
|
||||
fn from(s: &InternalString) -> Self {
|
||||
if s.is_empty() {
|
||||
Self(RawStringInner::Empty)
|
||||
} else {
|
||||
InternalString::from(s).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Box<str>> for RawString {
|
||||
#[inline]
|
||||
fn from(s: Box<str>) -> Self {
|
||||
if s.is_empty() {
|
||||
Self(RawStringInner::Empty)
|
||||
} else {
|
||||
InternalString::from(s).into()
|
||||
}
|
||||
}
|
||||
}
|
||||
253
third-party/vendor/toml_edit/src/repr.rs
vendored
Normal file
253
third-party/vendor/toml_edit/src/repr.rs
vendored
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
use std::borrow::Cow;
|
||||
|
||||
use crate::RawString;
|
||||
|
||||
/// A value together with its `to_string` representation,
|
||||
/// including surrounding it whitespaces 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.
|
||||
pub fn default_repr(&self) -> Repr {
|
||||
self.value.to_repr()
|
||||
}
|
||||
|
||||
/// Returns a raw representation.
|
||||
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 location within the original document
|
||||
pub(crate) 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 = Some(self.value.to_repr());
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> std::fmt::Display for Formatted<T>
|
||||
where
|
||||
T: ValueRepr,
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
crate::encode::Encode::encode(self, f, None, ("", ""))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ValueRepr: crate::private::Sealed {
|
||||
/// The TOML representation of the value
|
||||
fn to_repr(&self) -> Repr;
|
||||
}
|
||||
|
||||
/// TOML-encoded value
|
||||
#[derive(Eq, PartialEq, Clone, Hash)]
|
||||
pub struct Repr {
|
||||
raw_value: RawString,
|
||||
}
|
||||
|
||||
impl Repr {
|
||||
pub(crate) fn new_unchecked(raw: impl Into<RawString>) -> Self {
|
||||
Repr {
|
||||
raw_value: raw.into(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Access the underlying value
|
||||
pub fn as_raw(&self) -> &RawString {
|
||||
&self.raw_value
|
||||
}
|
||||
|
||||
/// Returns the location within the original document
|
||||
pub(crate) 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)
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
84
third-party/vendor/toml_edit/src/ser/array.rs
vendored
Normal file
84
third-party/vendor/toml_edit/src/ser/array.rs
vendored
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
use super::Error;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct SerializeValueArray {
|
||||
values: Vec<crate::Item>,
|
||||
}
|
||||
|
||||
impl SerializeValueArray {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { values: Vec::new() }
|
||||
}
|
||||
|
||||
pub(crate) fn with_capacity(len: usize) -> Self {
|
||||
Self {
|
||||
values: Vec::with_capacity(len),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::SerializeSeq for SerializeValueArray {
|
||||
type Ok = crate::Value;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
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::ser::SerializeTuple for SerializeValueArray {
|
||||
type Ok = crate::Value;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
serde::ser::SerializeSeq::serialize_element(self, value)
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
serde::ser::SerializeSeq::end(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::SerializeTupleVariant for SerializeValueArray {
|
||||
type Ok = crate::Value;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
serde::ser::SerializeSeq::serialize_element(self, value)
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
serde::ser::SerializeSeq::end(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::SerializeTupleStruct for SerializeValueArray {
|
||||
type Ok = crate::Value;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
serde::ser::SerializeSeq::serialize_element(self, value)
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
serde::ser::SerializeSeq::end(self)
|
||||
}
|
||||
}
|
||||
173
third-party/vendor/toml_edit/src/ser/key.rs
vendored
Normal file
173
third-party/vendor/toml_edit/src/ser/key.rs
vendored
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
use crate::InternalString;
|
||||
|
||||
use super::Error;
|
||||
|
||||
pub(crate) struct KeySerializer;
|
||||
|
||||
impl serde::ser::Serializer for KeySerializer {
|
||||
type Ok = InternalString;
|
||||
type Error = Error;
|
||||
type SerializeSeq = serde::ser::Impossible<InternalString, Error>;
|
||||
type SerializeTuple = serde::ser::Impossible<InternalString, Error>;
|
||||
type SerializeTupleStruct = serde::ser::Impossible<InternalString, Error>;
|
||||
type SerializeTupleVariant = serde::ser::Impossible<InternalString, Error>;
|
||||
type SerializeMap = serde::ser::Impossible<InternalString, Error>;
|
||||
type SerializeStruct = serde::ser::Impossible<InternalString, Error>;
|
||||
type SerializeStructVariant = serde::ser::Impossible<InternalString, Error>;
|
||||
|
||||
fn serialize_bool(self, _v: bool) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_i8(self, _v: i8) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_i16(self, _v: i16) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_i32(self, _v: i32) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_i64(self, _v: i64) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_u8(self, _v: u8) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_u16(self, _v: u16) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_u32(self, _v: u32) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_u64(self, _v: u64) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_f32(self, _v: f32) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_f64(self, _v: f64) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_char(self, _v: char) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_str(self, value: &str) -> Result<InternalString, Self::Error> {
|
||||
Ok(InternalString::from(value))
|
||||
}
|
||||
|
||||
fn serialize_bytes(self, _value: &[u8]) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_none(self) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<InternalString, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, _name: &'static str) -> Result<InternalString, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_unit_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
variant: &'static str,
|
||||
) -> Result<InternalString, Self::Error> {
|
||||
Ok(variant.into())
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
value: &T,
|
||||
) -> Result<InternalString, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_newtype_variant<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_value: &T,
|
||||
) -> Result<InternalString, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeTupleStruct, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeTupleVariant, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStruct, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
|
||||
fn serialize_struct_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStructVariant, Self::Error> {
|
||||
Err(Error::KeyNotString)
|
||||
}
|
||||
}
|
||||
587
third-party/vendor/toml_edit/src/ser/map.rs
vendored
Normal file
587
third-party/vendor/toml_edit/src/ser/map.rs
vendored
Normal file
|
|
@ -0,0 +1,587 @@
|
|||
use super::{Error, KeySerializer, ValueSerializer};
|
||||
|
||||
#[doc(hidden)]
|
||||
pub enum SerializeMap {
|
||||
Datetime(SerializeDatetime),
|
||||
Table(SerializeInlineTable),
|
||||
}
|
||||
|
||||
impl SerializeMap {
|
||||
pub(crate) fn table() -> Self {
|
||||
Self::Table(SerializeInlineTable::new())
|
||||
}
|
||||
|
||||
pub(crate) fn table_with_capacity(len: usize) -> Self {
|
||||
Self::Table(SerializeInlineTable::with_capacity(len))
|
||||
}
|
||||
|
||||
pub(crate) fn datetime() -> Self {
|
||||
Self::Datetime(SerializeDatetime::new())
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::SerializeMap for SerializeMap {
|
||||
type Ok = crate::Value;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_key<T: ?Sized>(&mut self, input: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
match self {
|
||||
Self::Datetime(s) => s.serialize_key(input),
|
||||
Self::Table(s) => s.serialize_key(input),
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
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::ser::SerializeStruct for SerializeMap {
|
||||
type Ok = crate::Value;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_field<T: ?Sized>(
|
||||
&mut self,
|
||||
key: &'static str,
|
||||
value: &T,
|
||||
) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
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 {
|
||||
value: Option<crate::Datetime>,
|
||||
}
|
||||
|
||||
impl SerializeDatetime {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self { value: None }
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::SerializeMap for SerializeDatetime {
|
||||
type Ok = crate::Datetime;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_key<T: ?Sized>(&mut self, _input: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
unreachable!("datetimes should only be serialized as structs, not maps")
|
||||
}
|
||||
|
||||
fn serialize_value<T: ?Sized>(&mut self, _value: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
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::ser::SerializeStruct for SerializeDatetime {
|
||||
type Ok = crate::Datetime;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_field<T: ?Sized>(
|
||||
&mut self,
|
||||
key: &'static str,
|
||||
value: &T,
|
||||
) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
if key == toml_datetime::__unstable::FIELD {
|
||||
self.value = Some(value.serialize(DatetimeFieldSerializer::default())?);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
self.value.ok_or(Error::UnsupportedNone)
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct SerializeInlineTable {
|
||||
items: crate::table::KeyValuePairs,
|
||||
key: Option<crate::InternalString>,
|
||||
}
|
||||
|
||||
impl SerializeInlineTable {
|
||||
pub(crate) fn new() -> Self {
|
||||
Self {
|
||||
items: Default::default(),
|
||||
key: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn with_capacity(len: usize) -> Self {
|
||||
let mut s = Self::new();
|
||||
s.items.reserve(len);
|
||||
s
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::SerializeMap for SerializeInlineTable {
|
||||
type Ok = crate::InlineTable;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_key<T: ?Sized>(&mut self, input: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
self.key = None;
|
||||
self.key = Some(input.serialize(KeySerializer)?);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
let mut value_serializer = MapValueSerializer::new();
|
||||
let res = value.serialize(&mut value_serializer);
|
||||
match res {
|
||||
Ok(item) => {
|
||||
let key = self.key.take().unwrap();
|
||||
let kv = crate::table::TableKeyValue::new(
|
||||
crate::Key::new(&key),
|
||||
crate::Item::Value(item),
|
||||
);
|
||||
self.items.insert(key, kv);
|
||||
}
|
||||
Err(e) => {
|
||||
if !(e == Error::UnsupportedNone && value_serializer.is_none) {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
Ok(crate::InlineTable::with_pairs(self.items))
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::SerializeStruct for SerializeInlineTable {
|
||||
type Ok = crate::InlineTable;
|
||||
type Error = Error;
|
||||
|
||||
fn serialize_field<T: ?Sized>(
|
||||
&mut self,
|
||||
key: &'static str,
|
||||
value: &T,
|
||||
) -> Result<(), Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
let mut value_serializer = MapValueSerializer::new();
|
||||
let res = value.serialize(&mut value_serializer);
|
||||
match res {
|
||||
Ok(item) => {
|
||||
let kv = crate::table::TableKeyValue::new(
|
||||
crate::Key::new(key),
|
||||
crate::Item::Value(item),
|
||||
);
|
||||
self.items.insert(crate::InternalString::from(key), kv);
|
||||
}
|
||||
Err(e) => {
|
||||
if !(e == Error::UnsupportedNone && value_serializer.is_none) {
|
||||
return Err(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn end(self) -> Result<Self::Ok, Self::Error> {
|
||||
Ok(crate::InlineTable::with_pairs(self.items))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct DatetimeFieldSerializer {}
|
||||
|
||||
impl serde::ser::Serializer for DatetimeFieldSerializer {
|
||||
type Ok = toml_datetime::Datetime;
|
||||
type Error = Error;
|
||||
type SerializeSeq = serde::ser::Impossible<Self::Ok, Self::Error>;
|
||||
type SerializeTuple = serde::ser::Impossible<Self::Ok, Self::Error>;
|
||||
type SerializeTupleStruct = serde::ser::Impossible<Self::Ok, Self::Error>;
|
||||
type SerializeTupleVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
|
||||
type SerializeMap = serde::ser::Impossible<Self::Ok, Self::Error>;
|
||||
type SerializeStruct = serde::ser::Impossible<Self::Ok, Self::Error>;
|
||||
type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
|
||||
|
||||
fn serialize_bool(self, _value: bool) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_i8(self, _value: i8) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_i16(self, _value: i16) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_i32(self, _value: i32) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_i64(self, _value: i64) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_u8(self, _value: u8) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_u16(self, _value: u16) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_u32(self, _value: u32) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_u64(self, _value: u64) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_f32(self, _value: f32) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_f64(self, _value: f64) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_char(self, _value: char) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
|
||||
v.parse::<toml_datetime::Datetime>().map_err(Error::custom)
|
||||
}
|
||||
|
||||
fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_unit_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_value: &T,
|
||||
) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_newtype_variant<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_value: &T,
|
||||
) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeTupleStruct, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeTupleVariant, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStruct, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
|
||||
fn serialize_struct_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStructVariant, Self::Error> {
|
||||
Err(Error::DateInvalid)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct MapValueSerializer {
|
||||
is_none: bool,
|
||||
}
|
||||
|
||||
impl MapValueSerializer {
|
||||
fn new() -> Self {
|
||||
Self { is_none: false }
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::Serializer for &mut MapValueSerializer {
|
||||
type Ok = crate::Value;
|
||||
type Error = Error;
|
||||
type SerializeSeq = super::SerializeValueArray;
|
||||
type SerializeTuple = super::SerializeValueArray;
|
||||
type SerializeTupleStruct = super::SerializeValueArray;
|
||||
type SerializeTupleVariant = super::SerializeValueArray;
|
||||
type SerializeMap = super::SerializeMap;
|
||||
type SerializeStruct = super::SerializeMap;
|
||||
type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
|
||||
|
||||
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_bool(v)
|
||||
}
|
||||
|
||||
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_i8(v)
|
||||
}
|
||||
|
||||
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_i16(v)
|
||||
}
|
||||
|
||||
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_i32(v)
|
||||
}
|
||||
|
||||
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_i64(v)
|
||||
}
|
||||
|
||||
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_u8(v)
|
||||
}
|
||||
|
||||
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_u16(v)
|
||||
}
|
||||
|
||||
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_u32(v)
|
||||
}
|
||||
|
||||
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_u64(v)
|
||||
}
|
||||
|
||||
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_f32(v)
|
||||
}
|
||||
|
||||
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_f64(v)
|
||||
}
|
||||
|
||||
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_char(v)
|
||||
}
|
||||
|
||||
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_str(v)
|
||||
}
|
||||
|
||||
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_bytes(value)
|
||||
}
|
||||
|
||||
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
|
||||
self.is_none = true;
|
||||
Err(Error::UnsupportedNone)
|
||||
}
|
||||
|
||||
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
ValueSerializer::new().serialize_some(value)
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_unit()
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_unit_struct(name)
|
||||
}
|
||||
|
||||
fn serialize_unit_variant(
|
||||
self,
|
||||
name: &'static str,
|
||||
variant_index: u32,
|
||||
variant: &'static str,
|
||||
) -> Result<Self::Ok, Self::Error> {
|
||||
ValueSerializer::new().serialize_unit_variant(name, variant_index, variant)
|
||||
}
|
||||
|
||||
fn serialize_newtype_struct<T: ?Sized>(
|
||||
self,
|
||||
name: &'static str,
|
||||
value: &T,
|
||||
) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
ValueSerializer::new().serialize_newtype_struct(name, value)
|
||||
}
|
||||
|
||||
fn serialize_newtype_variant<T: ?Sized>(
|
||||
self,
|
||||
name: &'static str,
|
||||
variant_index: u32,
|
||||
variant: &'static str,
|
||||
value: &T,
|
||||
) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
ValueSerializer::new().serialize_newtype_variant(name, variant_index, variant, value)
|
||||
}
|
||||
|
||||
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
|
||||
ValueSerializer::new().serialize_seq(len)
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
|
||||
ValueSerializer::new().serialize_tuple(len)
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct(
|
||||
self,
|
||||
name: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeTupleStruct, Self::Error> {
|
||||
ValueSerializer::new().serialize_tuple_struct(name, len)
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant(
|
||||
self,
|
||||
name: &'static str,
|
||||
variant_index: u32,
|
||||
variant: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeTupleVariant, Self::Error> {
|
||||
ValueSerializer::new().serialize_tuple_variant(name, variant_index, variant, len)
|
||||
}
|
||||
|
||||
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
||||
ValueSerializer::new().serialize_map(len)
|
||||
}
|
||||
|
||||
fn serialize_struct(
|
||||
self,
|
||||
name: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeStruct, Self::Error> {
|
||||
ValueSerializer::new().serialize_struct(name, len)
|
||||
}
|
||||
|
||||
fn serialize_struct_variant(
|
||||
self,
|
||||
name: &'static str,
|
||||
variant_index: u32,
|
||||
variant: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeStructVariant, Self::Error> {
|
||||
ValueSerializer::new().serialize_struct_variant(name, variant_index, variant, len)
|
||||
}
|
||||
}
|
||||
165
third-party/vendor/toml_edit/src/ser/mod.rs
vendored
Normal file
165
third-party/vendor/toml_edit/src/ser/mod.rs
vendored
Normal file
|
|
@ -0,0 +1,165 @@
|
|||
//! Serializing Rust structures into TOML.
|
||||
//!
|
||||
//! This module contains all the Serde support for serializing Rust structures into TOML.
|
||||
|
||||
mod array;
|
||||
mod key;
|
||||
mod map;
|
||||
mod pretty;
|
||||
mod value;
|
||||
|
||||
pub(crate) use array::*;
|
||||
pub(crate) use key::*;
|
||||
pub(crate) use map::*;
|
||||
|
||||
use crate::visit_mut::VisitMut;
|
||||
|
||||
/// Errors that can occur when deserializing a type.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
#[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,
|
||||
{
|
||||
Error::Custom(msg.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
impl serde::ser::Error for Error {
|
||||
fn custom<T>(msg: T) -> Self
|
||||
where
|
||||
T: std::fmt::Display,
|
||||
{
|
||||
Self::custom(msg)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Error {
|
||||
fn fmt(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
|
||||
match self {
|
||||
Self::UnsupportedType(Some(t)) => write!(formatter, "unsupported {t} type"),
|
||||
Self::UnsupportedType(None) => write!(formatter, "unsupported rust type"),
|
||||
Self::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) -> Error {
|
||||
Self::custom(e)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Error> for crate::TomlError {
|
||||
fn from(e: Error) -> crate::TomlError {
|
||||
Self::custom(e.to_string(), None)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::error::Error for Error {}
|
||||
|
||||
/// 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.
|
||||
pub fn to_vec<T: ?Sized>(value: &T) -> Result<Vec<u8>, Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
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)
|
||||
/// ```
|
||||
pub fn to_string<T: ?Sized>(value: &T) -> Result<String, Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
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.
|
||||
pub fn to_string_pretty<T: ?Sized>(value: &T) -> Result<String, Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
let mut document = to_document(value)?;
|
||||
pretty::Pretty.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: ?Sized>(value: &T) -> Result<crate::Document, Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
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())
|
||||
}
|
||||
|
||||
pub use value::ValueSerializer;
|
||||
45
third-party/vendor/toml_edit/src/ser/pretty.rs
vendored
Normal file
45
third-party/vendor/toml_edit/src/ser/pretty.rs
vendored
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
pub(crate) struct Pretty;
|
||||
|
||||
impl crate::visit_mut::VisitMut for Pretty {
|
||||
fn visit_document_mut(&mut self, node: &mut crate::Document) {
|
||||
crate::visit_mut::visit_document_mut(self, node);
|
||||
}
|
||||
|
||||
fn visit_item_mut(&mut self, node: &mut crate::Item) {
|
||||
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();
|
||||
|
||||
crate::visit_mut::visit_value_mut(self, node);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
243
third-party/vendor/toml_edit/src/ser/value.rs
vendored
Normal file
243
third-party/vendor/toml_edit/src/ser/value.rs
vendored
Normal file
|
|
@ -0,0 +1,243 @@
|
|||
use super::Error;
|
||||
|
||||
/// Serialization for TOML [values][crate::Value].
|
||||
///
|
||||
/// This structure implements serialization support for TOML to serialize an
|
||||
/// arbitrary type to TOML. Note that the TOML format does not support all
|
||||
/// datatypes in Rust, such as enums, tuples, and tuple structs. These types
|
||||
/// will generate an error when serialized.
|
||||
///
|
||||
/// Currently a serializer always writes its output to an in-memory `String`,
|
||||
/// which is passed in when creating the serializer itself.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```
|
||||
/// use serde::Serialize;
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
/// struct Config {
|
||||
/// database: Database,
|
||||
/// }
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
/// struct Database {
|
||||
/// ip: String,
|
||||
/// port: Vec<u16>,
|
||||
/// connection_max: u32,
|
||||
/// enabled: bool,
|
||||
/// }
|
||||
///
|
||||
/// let config = Config {
|
||||
/// database: Database {
|
||||
/// ip: "192.168.1.1".to_string(),
|
||||
/// port: vec![8001, 8002, 8003],
|
||||
/// connection_max: 5000,
|
||||
/// enabled: false,
|
||||
/// },
|
||||
/// };
|
||||
///
|
||||
/// let 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::ser::Serializer for ValueSerializer {
|
||||
type Ok = crate::Value;
|
||||
type Error = Error;
|
||||
type SerializeSeq = super::SerializeValueArray;
|
||||
type SerializeTuple = super::SerializeValueArray;
|
||||
type SerializeTupleStruct = super::SerializeValueArray;
|
||||
type SerializeTupleVariant = super::SerializeValueArray;
|
||||
type SerializeMap = super::SerializeMap;
|
||||
type SerializeStruct = super::SerializeMap;
|
||||
type SerializeStructVariant = serde::ser::Impossible<Self::Ok, Self::Error>;
|
||||
|
||||
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::OutOfRange(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, v: f64) -> Result<Self::Ok, Self::Error> {
|
||||
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::ser::Serialize;
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::UnsupportedNone)
|
||||
}
|
||||
|
||||
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::UnsupportedType(Some("unit")))
|
||||
}
|
||||
|
||||
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error> {
|
||||
Err(Error::UnsupportedType(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: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
value: &T,
|
||||
) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
value.serialize(self)
|
||||
}
|
||||
|
||||
fn serialize_newtype_variant<T: ?Sized>(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
variant: &'static str,
|
||||
value: &T,
|
||||
) -> Result<Self::Ok, Self::Error>
|
||||
where
|
||||
T: serde::ser::Serialize,
|
||||
{
|
||||
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> {
|
||||
let serializer = match len {
|
||||
Some(len) => super::SerializeValueArray::with_capacity(len),
|
||||
None => super::SerializeValueArray::new(),
|
||||
};
|
||||
Ok(serializer)
|
||||
}
|
||||
|
||||
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
|
||||
self.serialize_seq(Some(len))
|
||||
}
|
||||
|
||||
fn serialize_tuple_struct(
|
||||
self,
|
||||
_name: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeTupleStruct, Self::Error> {
|
||||
self.serialize_seq(Some(len))
|
||||
}
|
||||
|
||||
fn serialize_tuple_variant(
|
||||
self,
|
||||
_name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeTupleVariant, Self::Error> {
|
||||
self.serialize_seq(Some(len))
|
||||
}
|
||||
|
||||
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
|
||||
let serializer = match len {
|
||||
Some(len) => super::SerializeMap::table_with_capacity(len),
|
||||
None => super::SerializeMap::table(),
|
||||
};
|
||||
Ok(serializer)
|
||||
}
|
||||
|
||||
fn serialize_struct(
|
||||
self,
|
||||
name: &'static str,
|
||||
len: usize,
|
||||
) -> Result<Self::SerializeStruct, Self::Error> {
|
||||
if name == toml_datetime::__unstable::NAME {
|
||||
Ok(super::SerializeMap::datetime())
|
||||
} else {
|
||||
self.serialize_map(Some(len))
|
||||
}
|
||||
}
|
||||
|
||||
fn serialize_struct_variant(
|
||||
self,
|
||||
name: &'static str,
|
||||
_variant_index: u32,
|
||||
_variant: &'static str,
|
||||
_len: usize,
|
||||
) -> Result<Self::SerializeStructVariant, Self::Error> {
|
||||
Err(Error::UnsupportedType(Some(name)))
|
||||
}
|
||||
}
|
||||
757
third-party/vendor/toml_edit/src/table.rs
vendored
Normal file
757
third-party/vendor/toml_edit/src/table.rs
vendored
Normal file
|
|
@ -0,0 +1,757 @@
|
|||
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, InternalString, Item, KeyMut, Value};
|
||||
|
||||
/// Type representing a TOML non-inline table
|
||||
#[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<usize>,
|
||||
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<usize>) -> 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 (_, kv) in self.items.iter_mut() {
|
||||
kv.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, 'c>(
|
||||
&'s self,
|
||||
parent: &[&'s Key],
|
||||
values: &'c mut Vec<(Vec<&'s Key>, &'s Value)>,
|
||||
) {
|
||||
for value in self.items.values() {
|
||||
let mut path = parent.to_vec();
|
||||
path.push(&value.key);
|
||||
match &value.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));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Auto formats the table.
|
||||
pub fn fmt(&mut self) {
|
||||
decorate_table(self);
|
||||
}
|
||||
|
||||
/// Sorts Key/Value Pairs of the table.
|
||||
///
|
||||
/// Doesn't affect subtables or subarrays.
|
||||
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 kv in self.items.values_mut() {
|
||||
match &mut kv.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).
|
||||
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 = |_: &InternalString,
|
||||
val1: &TableKeyValue,
|
||||
_: &InternalString,
|
||||
val2: &TableKeyValue|
|
||||
-> std::cmp::Ordering {
|
||||
compare(&val1.key, &val1.value, &val2.key, &val2.value)
|
||||
};
|
||||
|
||||
self.items.sort_by(modified_cmp);
|
||||
|
||||
for kv in self.items.values_mut() {
|
||||
match &mut kv.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.
|
||||
///
|
||||
/// ```
|
||||
/// use toml_edit::Document;
|
||||
/// let mut doc = "[a]\n[a.b]\n".parse::<Document>().expect("invalid toml");
|
||||
///
|
||||
/// doc["a"].as_table_mut().unwrap().set_implicit(true);
|
||||
/// assert_eq!(doc.to_string(), "[a.b]\n");
|
||||
/// ```
|
||||
pub fn set_implicit(&mut self, implicit: bool) {
|
||||
self.implicit = implicit;
|
||||
}
|
||||
|
||||
/// 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 `Document`.
|
||||
pub fn set_position(&mut self, doc_position: usize) {
|
||||
self.doc_position = Some(doc_position);
|
||||
}
|
||||
|
||||
/// The position of the `Table` within the `Document`.
|
||||
///
|
||||
/// 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<usize> {
|
||||
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 the decor associated with a given key of the table.
|
||||
pub fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
|
||||
self.items.get_mut(key).map(|kv| &mut kv.key.decor)
|
||||
}
|
||||
|
||||
/// Returns the decor associated with a given key of the table.
|
||||
pub fn key_decor(&self, key: &str) -> Option<&Decor> {
|
||||
self.items.get(key).map(|kv| &kv.key.decor)
|
||||
}
|
||||
|
||||
/// Returns the location within the original document
|
||||
pub(crate) 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);
|
||||
for kv in self.items.values_mut() {
|
||||
kv.key.despan(input);
|
||||
kv.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(|(_, kv)| !kv.value.is_none())
|
||||
.map(|(key, kv)| (&key[..], &kv.value)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns an mutable iterator over all key/value pairs, including empty.
|
||||
pub fn iter_mut(&mut self) -> IterMut<'_> {
|
||||
Box::new(
|
||||
self.items
|
||||
.iter_mut()
|
||||
.filter(|(_, kv)| !kv.value.is_none())
|
||||
.map(|(_, kv)| (kv.key.as_mut(), &mut kv.value)),
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns the number of non-empty items in the table.
|
||||
pub fn len(&self) -> usize {
|
||||
self.items.iter().filter(|i| !(i.1).value.is_none()).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 `InternalString`, 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, key: None }),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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.get().into()) {
|
||||
indexmap::map::Entry::Occupied(entry) => Entry::Occupied(OccupiedEntry { entry }),
|
||||
indexmap::map::Entry::Vacant(entry) => Entry::Vacant(VacantEntry {
|
||||
entry,
|
||||
key: Some(key.to_owned()),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
/// 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(|kv| {
|
||||
if !kv.value.is_none() {
|
||||
Some(&kv.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(|kv| {
|
||||
if !kv.value.is_none() {
|
||||
Some(&mut kv.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(key).and_then(|kv| {
|
||||
if !kv.value.is_none() {
|
||||
Some((&kv.key, &kv.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)> {
|
||||
self.items.get_mut(key).and_then(|kv| {
|
||||
if !kv.value.is_none() {
|
||||
Some((kv.key.as_mut(), &mut kv.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(kv) = self.items.get(key) {
|
||||
!kv.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(kv) = self.items.get(key) {
|
||||
kv.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(kv) = self.items.get(key) {
|
||||
kv.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(kv) = self.items.get(key) {
|
||||
kv.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> {
|
||||
let kv = TableKeyValue::new(Key::new(key), item);
|
||||
self.items.insert(key.into(), kv).map(|kv| kv.value)
|
||||
}
|
||||
|
||||
/// Inserts a key-value pair into the map.
|
||||
pub fn insert_formatted(&mut self, key: &Key, item: Item) -> Option<Item> {
|
||||
let kv = TableKeyValue::new(key.to_owned(), item);
|
||||
self.items.insert(key.get().into(), kv).map(|kv| kv.value)
|
||||
}
|
||||
|
||||
/// Removes an item given the key.
|
||||
pub fn remove(&mut self, key: &str) -> Option<Item> {
|
||||
self.items.shift_remove(key).map(|kv| kv.value)
|
||||
}
|
||||
|
||||
/// 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(key).map(|kv| (kv.key, kv.value))
|
||||
}
|
||||
|
||||
/// 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, key_value| keep(key, &mut key_value.value));
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Table {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
use crate::encode::Encode;
|
||||
let children = self.get_values();
|
||||
// print table body
|
||||
for (key_path, value) in children {
|
||||
key_path.as_slice().encode(f, None, DEFAULT_KEY_DECOR)?;
|
||||
write!(f, "=")?;
|
||||
value.encode(f, None, DEFAULT_VALUE_DECOR)?;
|
||||
writeln!(f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Into<Key>, V: Into<Value>> 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 = Item::Value(value.into());
|
||||
let value = TableKeyValue::new(key, value);
|
||||
self.items.insert(value.key.get().into(), value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Into<Key>, V: Into<Value>> FromIterator<(K, V)> for Table {
|
||||
fn from_iter<I>(iter: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = (K, V)>,
|
||||
{
|
||||
let mut table = Table::new();
|
||||
table.extend(iter);
|
||||
table
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoIterator for Table {
|
||||
type Item = (InternalString, Item);
|
||||
type IntoIter = IntoIter;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
Box::new(self.items.into_iter().map(|(k, kv)| (k, kv.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<InternalString, TableKeyValue>;
|
||||
|
||||
fn decorate_table(table: &mut Table) {
|
||||
for (key_decor, value) in table
|
||||
.items
|
||||
.iter_mut()
|
||||
.filter(|&(_, ref kv)| kv.value.is_value())
|
||||
.map(|(_, kv)| (&mut kv.key.decor, kv.value.as_value_mut().unwrap()))
|
||||
{
|
||||
key_decor.clear();
|
||||
value.decor_mut().clear();
|
||||
}
|
||||
}
|
||||
|
||||
// `key1 = value1`
|
||||
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) = ("", "");
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub(crate) struct TableKeyValue {
|
||||
pub(crate) key: Key,
|
||||
pub(crate) value: Item,
|
||||
}
|
||||
|
||||
impl TableKeyValue {
|
||||
pub(crate) fn new(key: Key, value: Item) -> Self {
|
||||
TableKeyValue { key, value }
|
||||
}
|
||||
}
|
||||
|
||||
/// An owned iterator type over `Table`'s key/value pairs.
|
||||
pub type IntoIter = Box<dyn Iterator<Item = (InternalString, Item)>>;
|
||||
/// An iterator type over `Table`'s key/value pairs.
|
||||
pub type Iter<'a> = Box<dyn Iterator<Item = (&'a str, &'a Item)> + 'a>;
|
||||
/// A mutable iterator type over `Table`'s key/value 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.
|
||||
///
|
||||
/// Doesn't affect subtables or subarrays.
|
||||
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 the decor associated with a given key of the table.
|
||||
fn key_decor_mut(&mut self, key: &str) -> Option<&mut Decor>;
|
||||
/// Returns the decor associated with a given key of the table.
|
||||
fn key_decor(&self, key: &str) -> Option<&Decor>;
|
||||
}
|
||||
|
||||
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_decor_mut(&mut self, key: &str) -> Option<&mut Decor> {
|
||||
self.key_decor_mut(key)
|
||||
}
|
||||
fn key_decor(&self, key: &str) -> Option<&Decor> {
|
||||
self.key_decor(key)
|
||||
}
|
||||
}
|
||||
|
||||
/// A view into a single location in a map, 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 `IndexMap`.
|
||||
pub struct OccupiedEntry<'a> {
|
||||
pub(crate) entry: indexmap::map::OccupiedEntry<'a, InternalString, TableKeyValue>,
|
||||
}
|
||||
|
||||
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().as_str()
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the entry key
|
||||
pub fn key_mut(&mut self) -> KeyMut<'_> {
|
||||
self.entry.get_mut().key.as_mut()
|
||||
}
|
||||
|
||||
/// Gets a reference to the value in the entry.
|
||||
pub fn get(&self) -> &Item {
|
||||
&self.entry.get().value
|
||||
}
|
||||
|
||||
/// Gets a mutable reference to the value in the entry.
|
||||
pub fn get_mut(&mut self) -> &mut Item {
|
||||
&mut self.entry.get_mut().value
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
&mut self.entry.into_mut().value
|
||||
}
|
||||
|
||||
/// Sets the value of the entry, and returns the entry's old value
|
||||
pub fn insert(&mut self, mut value: Item) -> Item {
|
||||
std::mem::swap(&mut value, &mut self.entry.get_mut().value);
|
||||
value
|
||||
}
|
||||
|
||||
/// Takes the value out of the entry, and returns it
|
||||
pub fn remove(self) -> Item {
|
||||
self.entry.shift_remove().value
|
||||
}
|
||||
}
|
||||
|
||||
/// A view into a single empty location in a `IndexMap`.
|
||||
pub struct VacantEntry<'a> {
|
||||
pub(crate) entry: indexmap::map::VacantEntry<'a, InternalString, TableKeyValue>,
|
||||
pub(crate) key: Option<Key>,
|
||||
}
|
||||
|
||||
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().as_str()
|
||||
}
|
||||
|
||||
/// 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;
|
||||
let key = self.key.unwrap_or_else(|| Key::new(entry.key().as_str()));
|
||||
&mut entry.insert(TableKeyValue::new(key, value)).value
|
||||
}
|
||||
}
|
||||
372
third-party/vendor/toml_edit/src/value.rs
vendored
Normal file
372
third-party/vendor/toml_edit/src/value.rs
vendored
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
use std::iter::FromIterator;
|
||||
use std::str::FromStr;
|
||||
|
||||
use toml_datetime::*;
|
||||
|
||||
use crate::key::Key;
|
||||
use crate::parser;
|
||||
use crate::repr::{Decor, Formatted};
|
||||
use crate::{Array, InlineTable, InternalString, RawString};
|
||||
|
||||
/// Representation of a TOML Value (as part of a Key/Value Pair).
|
||||
#[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 {
|
||||
Value::String(..) => "string",
|
||||
Value::Integer(..) => "integer",
|
||||
Value::Float(..) => "float",
|
||||
Value::Boolean(..) => "boolean",
|
||||
Value::Datetime(..) => "datetime",
|
||||
Value::Array(..) => "array",
|
||||
Value::InlineTable(..) => "inline table",
|
||||
}
|
||||
}
|
||||
|
||||
/// Casts `self` to str.
|
||||
pub fn as_str(&self) -> Option<&str> {
|
||||
match *self {
|
||||
Value::String(ref value) => Some(value.value()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true iff `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 {
|
||||
Value::Integer(ref value) => Some(*value.value()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true iff `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 {
|
||||
Value::Float(ref value) => Some(*value.value()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true iff `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 {
|
||||
Value::Boolean(ref value) => Some(*value.value()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true iff `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 {
|
||||
Value::Datetime(ref value) => Some(value.value()),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true iff `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 {
|
||||
Value::Array(ref value) => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Casts `self` to mutable array.
|
||||
pub fn as_array_mut(&mut self) -> Option<&mut Array> {
|
||||
match *self {
|
||||
Value::Array(ref mut value) => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true iff `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 {
|
||||
Value::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 {
|
||||
Value::InlineTable(ref mut value) => Some(value),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true iff `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 {
|
||||
Value::String(f) => f.decor_mut(),
|
||||
Value::Integer(f) => f.decor_mut(),
|
||||
Value::Float(f) => f.decor_mut(),
|
||||
Value::Boolean(f) => f.decor_mut(),
|
||||
Value::Datetime(f) => f.decor_mut(),
|
||||
Value::Array(a) => a.decor_mut(),
|
||||
Value::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 {
|
||||
Value::String(ref f) => f.decor(),
|
||||
Value::Integer(ref f) => f.decor(),
|
||||
Value::Float(ref f) => f.decor(),
|
||||
Value::Boolean(ref f) => f.decor(),
|
||||
Value::Datetime(ref f) => f.decor(),
|
||||
Value::Array(ref a) => a.decor(),
|
||||
Value::InlineTable(ref t) => t.decor(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets the prefix and the suffix for value.
|
||||
/// # Example
|
||||
/// ```rust
|
||||
/// 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);
|
||||
}
|
||||
|
||||
/// Returns the location within the original document
|
||||
pub(crate) fn span(&self) -> Option<std::ops::Range<usize>> {
|
||||
match self {
|
||||
Value::String(f) => f.span(),
|
||||
Value::Integer(f) => f.span(),
|
||||
Value::Float(f) => f.span(),
|
||||
Value::Boolean(f) => f.span(),
|
||||
Value::Datetime(f) => f.span(),
|
||||
Value::Array(a) => a.span(),
|
||||
Value::InlineTable(t) => t.span(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn despan(&mut self, input: &str) {
|
||||
match self {
|
||||
Value::String(f) => f.despan(input),
|
||||
Value::Integer(f) => f.despan(input),
|
||||
Value::Float(f) => f.despan(input),
|
||||
Value::Boolean(f) => f.despan(input),
|
||||
Value::Datetime(f) => f.despan(input),
|
||||
Value::Array(a) => a.despan(input),
|
||||
Value::InlineTable(t) => t.despan(input),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for Value {
|
||||
type Err = crate::TomlError;
|
||||
|
||||
/// Parses a value from a &str
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
parser::parse_value(s)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> From<&'b Value> for Value {
|
||||
fn from(s: &'b Value) -> 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 {
|
||||
Value::String(Formatted::new(s))
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> From<&'b InternalString> for Value {
|
||||
fn from(s: &'b InternalString) -> Self {
|
||||
s.as_str().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InternalString> for Value {
|
||||
fn from(s: InternalString) -> Self {
|
||||
s.as_str().into()
|
||||
}
|
||||
}
|
||||
|
||||
impl From<i64> for Value {
|
||||
fn from(i: i64) -> Self {
|
||||
Value::Integer(Formatted::new(i))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f64> for Value {
|
||||
fn from(f: f64) -> Self {
|
||||
Value::Float(Formatted::new(f))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<bool> for Value {
|
||||
fn from(b: bool) -> Self {
|
||||
Value::Boolean(Formatted::new(b))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Datetime> for Value {
|
||||
fn from(d: Datetime) -> Self {
|
||||
Value::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 {
|
||||
Value::Array(array)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<InlineTable> for Value {
|
||||
fn from(table: InlineTable) -> Self {
|
||||
Value::InlineTable(table)
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Into<Value>> FromIterator<V> for Value {
|
||||
fn from_iter<I>(iter: I) -> Self
|
||||
where
|
||||
I: IntoIterator<Item = V>,
|
||||
{
|
||||
let array: Array = iter.into_iter().collect();
|
||||
Value::Array(array)
|
||||
}
|
||||
}
|
||||
|
||||
impl<K: Into<Key>, V: Into<Value>> 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();
|
||||
Value::InlineTable(table)
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for Value {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
crate::encode::Encode::encode(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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn from_iter_formatting() {
|
||||
let features = vec!["node".to_owned(), "mouth".to_owned()];
|
||||
let features: Value = features.iter().cloned().collect();
|
||||
assert_eq!(features.to_string(), r#"["node", "mouth"]"#);
|
||||
}
|
||||
}
|
||||
236
third-party/vendor/toml_edit/src/visit.rs
vendored
Normal file
236
third-party/vendor/toml_edit/src/visit.rs
vendored
Normal file
|
|
@ -0,0 +1,236 @@
|
|||
#![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.
|
||||
//!
|
||||
//! ```
|
||||
//! # 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: Document = 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/ordian/toml_edit/blob/master/examples/visit.rs).
|
||||
|
||||
use crate::{
|
||||
Array, ArrayOfTables, Datetime, Document, 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 Document) {
|
||||
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 Document)
|
||||
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>);
|
||||
252
third-party/vendor/toml_edit/src/visit_mut.rs
vendored
Normal file
252
third-party/vendor/toml_edit/src/visit_mut.rs
vendored
Normal file
|
|
@ -0,0 +1,252 @@
|
|||
#![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.
|
||||
//!
|
||||
//! ```
|
||||
//! # 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: Document = 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/ordian/toml_edit/blob/master/examples/visit.rs).
|
||||
|
||||
use crate::{
|
||||
Array, ArrayOfTables, Datetime, Document, 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 Document) {
|
||||
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 Document)
|
||||
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>);
|
||||
100
third-party/vendor/toml_edit/tests/decoder.rs
vendored
Normal file
100
third-party/vendor/toml_edit/tests/decoder.rs
vendored
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
#[derive(Copy, Clone)]
|
||||
pub struct Decoder;
|
||||
|
||||
impl toml_test_harness::Decoder for Decoder {
|
||||
fn name(&self) -> &str {
|
||||
"toml_edit"
|
||||
}
|
||||
|
||||
fn decode(&self, data: &[u8]) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> {
|
||||
let data = std::str::from_utf8(data).map_err(toml_test_harness::Error::new)?;
|
||||
let document = data
|
||||
.parse::<toml_edit::Document>()
|
||||
.map_err(toml_test_harness::Error::new)?;
|
||||
document_to_decoded(&document)
|
||||
}
|
||||
}
|
||||
|
||||
fn document_to_decoded(
|
||||
value: &toml_edit::Document,
|
||||
) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> {
|
||||
table_to_decoded(value)
|
||||
}
|
||||
|
||||
fn item_to_decoded(
|
||||
value: &toml_edit::Item,
|
||||
) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> {
|
||||
match value {
|
||||
toml_edit::Item::None => unreachable!("No nones"),
|
||||
toml_edit::Item::Value(v) => value_to_decoded(v),
|
||||
toml_edit::Item::Table(v) => table_to_decoded(v),
|
||||
toml_edit::Item::ArrayOfTables(v) => {
|
||||
let v: Result<_, toml_test_harness::Error> = v.iter().map(table_to_decoded).collect();
|
||||
Ok(toml_test_harness::Decoded::Array(v?))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn value_to_decoded(
|
||||
value: &toml_edit::Value,
|
||||
) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> {
|
||||
match value {
|
||||
toml_edit::Value::Integer(v) => Ok(toml_test_harness::Decoded::Value(
|
||||
toml_test_harness::DecodedValue::from(*v.value()),
|
||||
)),
|
||||
toml_edit::Value::String(v) => Ok(toml_test_harness::Decoded::Value(
|
||||
toml_test_harness::DecodedValue::from(v.value()),
|
||||
)),
|
||||
toml_edit::Value::Float(v) => Ok(toml_test_harness::Decoded::Value(
|
||||
toml_test_harness::DecodedValue::from(*v.value()),
|
||||
)),
|
||||
toml_edit::Value::Datetime(v) => {
|
||||
let v = v.value();
|
||||
let value = v.to_string();
|
||||
let value = match (v.date.is_some(), v.time.is_some(), v.offset.is_some()) {
|
||||
(true, true, true) => toml_test_harness::DecodedValue::Datetime(value),
|
||||
(true, true, false) => toml_test_harness::DecodedValue::DatetimeLocal(value),
|
||||
(true, false, false) => toml_test_harness::DecodedValue::DateLocal(value),
|
||||
(false, true, false) => toml_test_harness::DecodedValue::TimeLocal(value),
|
||||
_ => unreachable!("Unsupported case"),
|
||||
};
|
||||
Ok(toml_test_harness::Decoded::Value(value))
|
||||
}
|
||||
toml_edit::Value::Boolean(v) => Ok(toml_test_harness::Decoded::Value(
|
||||
toml_test_harness::DecodedValue::from(*v.value()),
|
||||
)),
|
||||
toml_edit::Value::Array(v) => {
|
||||
let v: Result<_, toml_test_harness::Error> = v.iter().map(value_to_decoded).collect();
|
||||
Ok(toml_test_harness::Decoded::Array(v?))
|
||||
}
|
||||
toml_edit::Value::InlineTable(v) => inline_table_to_decoded(v),
|
||||
}
|
||||
}
|
||||
|
||||
fn table_to_decoded(
|
||||
value: &toml_edit::Table,
|
||||
) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> {
|
||||
let table: Result<_, toml_test_harness::Error> = value
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
let k = k.to_owned();
|
||||
let v = item_to_decoded(v)?;
|
||||
Ok((k, v))
|
||||
})
|
||||
.collect();
|
||||
Ok(toml_test_harness::Decoded::Table(table?))
|
||||
}
|
||||
|
||||
fn inline_table_to_decoded(
|
||||
value: &toml_edit::InlineTable,
|
||||
) -> Result<toml_test_harness::Decoded, toml_test_harness::Error> {
|
||||
let table: Result<_, toml_test_harness::Error> = value
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
let k = k.to_owned();
|
||||
let v = value_to_decoded(v)?;
|
||||
Ok((k, v))
|
||||
})
|
||||
.collect();
|
||||
Ok(toml_test_harness::Decoded::Table(table?))
|
||||
}
|
||||
17
third-party/vendor/toml_edit/tests/decoder_compliance.rs
vendored
Normal file
17
third-party/vendor/toml_edit/tests/decoder_compliance.rs
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
mod decoder;
|
||||
|
||||
fn main() {
|
||||
let decoder = decoder::Decoder;
|
||||
let mut harness = toml_test_harness::DecoderHarness::new(decoder);
|
||||
harness
|
||||
.ignore([
|
||||
"valid/spec/float-0.toml", // Test issue; `Decoder` turns `6.626e-34` into `0.0`
|
||||
// Unreleased
|
||||
"valid/string/escape-esc.toml",
|
||||
"valid/string/hex-escape.toml",
|
||||
"valid/datetime/no-seconds.toml",
|
||||
"valid/inline-table/newline.toml",
|
||||
])
|
||||
.unwrap();
|
||||
harness.test();
|
||||
}
|
||||
111
third-party/vendor/toml_edit/tests/encoder.rs
vendored
Normal file
111
third-party/vendor/toml_edit/tests/encoder.rs
vendored
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
#[derive(Copy, Clone)]
|
||||
pub struct Encoder;
|
||||
|
||||
impl toml_test_harness::Encoder for Encoder {
|
||||
fn name(&self) -> &str {
|
||||
"toml_edit"
|
||||
}
|
||||
|
||||
fn encode(&self, data: toml_test_harness::Decoded) -> Result<String, toml_test_harness::Error> {
|
||||
let doc = decoded_to_document(&data)?;
|
||||
Ok(doc.to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn decoded_to_document(
|
||||
decoded: &toml_test_harness::Decoded,
|
||||
) -> Result<toml_edit::Document, toml_test_harness::Error> {
|
||||
let item = root_from_decoded(decoded)?;
|
||||
let mut doc = toml_edit::Document::new();
|
||||
*doc = item;
|
||||
Ok(doc)
|
||||
}
|
||||
|
||||
fn root_from_decoded(
|
||||
decoded: &toml_test_harness::Decoded,
|
||||
) -> Result<toml_edit::Table, toml_test_harness::Error> {
|
||||
match decoded {
|
||||
toml_test_harness::Decoded::Value(_) => {
|
||||
Err(toml_test_harness::Error::new("Root cannot be a value"))
|
||||
}
|
||||
toml_test_harness::Decoded::Table(value) => value
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
let k = k.as_str();
|
||||
let v = from_decoded(v)?;
|
||||
Ok((k, v))
|
||||
})
|
||||
.collect(),
|
||||
toml_test_harness::Decoded::Array(_) => {
|
||||
Err(toml_test_harness::Error::new("Root cannot be an array"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn from_decoded(
|
||||
decoded: &toml_test_harness::Decoded,
|
||||
) -> Result<toml_edit::Value, toml_test_harness::Error> {
|
||||
let value = match decoded {
|
||||
toml_test_harness::Decoded::Value(value) => from_decoded_value(value)?,
|
||||
toml_test_harness::Decoded::Table(value) => {
|
||||
toml_edit::Value::InlineTable(from_table(value)?)
|
||||
}
|
||||
toml_test_harness::Decoded::Array(value) => toml_edit::Value::Array(from_array(value)?),
|
||||
};
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn from_decoded_value(
|
||||
decoded: &toml_test_harness::DecodedValue,
|
||||
) -> Result<toml_edit::Value, toml_test_harness::Error> {
|
||||
let value: toml_edit::Value = match decoded {
|
||||
toml_test_harness::DecodedValue::String(value) => value.into(),
|
||||
toml_test_harness::DecodedValue::Integer(value) => value
|
||||
.parse::<i64>()
|
||||
.map_err(toml_test_harness::Error::new)?
|
||||
.into(),
|
||||
toml_test_harness::DecodedValue::Float(value) => value
|
||||
.parse::<f64>()
|
||||
.map_err(toml_test_harness::Error::new)?
|
||||
.into(),
|
||||
toml_test_harness::DecodedValue::Bool(value) => value
|
||||
.parse::<bool>()
|
||||
.map_err(toml_test_harness::Error::new)?
|
||||
.into(),
|
||||
toml_test_harness::DecodedValue::Datetime(value) => value
|
||||
.parse::<toml_edit::Datetime>()
|
||||
.map_err(toml_test_harness::Error::new)?
|
||||
.into(),
|
||||
toml_test_harness::DecodedValue::DatetimeLocal(value) => value
|
||||
.parse::<toml_edit::Datetime>()
|
||||
.map_err(toml_test_harness::Error::new)?
|
||||
.into(),
|
||||
toml_test_harness::DecodedValue::DateLocal(value) => value
|
||||
.parse::<toml_edit::Datetime>()
|
||||
.map_err(toml_test_harness::Error::new)?
|
||||
.into(),
|
||||
toml_test_harness::DecodedValue::TimeLocal(value) => value
|
||||
.parse::<toml_edit::Datetime>()
|
||||
.map_err(toml_test_harness::Error::new)?
|
||||
.into(),
|
||||
};
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
fn from_table(
|
||||
decoded: &std::collections::HashMap<String, toml_test_harness::Decoded>,
|
||||
) -> Result<toml_edit::InlineTable, toml_test_harness::Error> {
|
||||
decoded
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
let v = from_decoded(v)?;
|
||||
Ok((k, v))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn from_array(
|
||||
decoded: &[toml_test_harness::Decoded],
|
||||
) -> Result<toml_edit::Array, toml_test_harness::Error> {
|
||||
decoded.iter().map(from_decoded).collect()
|
||||
}
|
||||
14
third-party/vendor/toml_edit/tests/encoder_compliance.rs
vendored
Normal file
14
third-party/vendor/toml_edit/tests/encoder_compliance.rs
vendored
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
mod decoder;
|
||||
mod encoder;
|
||||
|
||||
fn main() {
|
||||
let encoder = encoder::Encoder;
|
||||
let decoder = decoder::Decoder;
|
||||
let mut harness = toml_test_harness::EncoderHarness::new(encoder, decoder);
|
||||
harness
|
||||
.ignore([
|
||||
"valid/spec/float-0.toml", // Test issue; `Decoder` turns `6.626e-34` into `0.0`
|
||||
])
|
||||
.unwrap();
|
||||
harness.test();
|
||||
}
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/double-comma-1.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/double-comma-1.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 12
|
||||
|
|
||||
1 | array = [1,,2]
|
||||
| ^
|
||||
invalid array
|
||||
expected `]`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/double-comma-2.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/double-comma-2.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 14
|
||||
|
|
||||
1 | array = [1,2,,]
|
||||
| ^
|
||||
invalid array
|
||||
expected `]`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/extending-table.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/extending-table.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 5, column 1
|
||||
|
|
||||
5 | [a.c]
|
||||
| ^
|
||||
invalid table header
|
||||
dotted key `a` attempted to extend non-table type (array)
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/missing-separator.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/missing-separator.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 13
|
||||
|
|
||||
1 | wrong = [ 1 2 3 ]
|
||||
| ^
|
||||
invalid array
|
||||
expected `]`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/no-close-2.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/no-close-2.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 11
|
||||
|
|
||||
1 | x = [42 #
|
||||
| ^
|
||||
invalid array
|
||||
expected `]`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/no-close-table-2.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/no-close-table-2.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 17
|
||||
|
|
||||
1 | x = [{ key = 42 #
|
||||
| ^
|
||||
invalid inline table
|
||||
expected `}`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/no-close-table.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/no-close-table.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 16
|
||||
|
|
||||
1 | x = [{ key = 42
|
||||
| ^
|
||||
invalid inline table
|
||||
expected `}`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/no-close.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/no-close.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 24
|
||||
|
|
||||
1 | long_array = [ 1, 2, 3
|
||||
| ^
|
||||
invalid array
|
||||
expected `]`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/tables-1.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/tables-1.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 4, column 1
|
||||
|
|
||||
4 | [[fruit]] # Not allowed
|
||||
| ^
|
||||
invalid table header
|
||||
duplicate key `fruit` in document root
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/tables-2.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/tables-2.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 9, column 3
|
||||
|
|
||||
9 | [fruit.variety]
|
||||
| ^
|
||||
invalid table header
|
||||
duplicate key `variety` in table `fruit`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/text-after-array-entries.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/text-after-array-entries.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 2, column 46
|
||||
|
|
||||
2 | "Is there life after an array separator?", No
|
||||
| ^
|
||||
invalid array
|
||||
expected `]`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/text-before-array-separator.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/text-before-array-separator.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 2, column 46
|
||||
|
|
||||
2 | "Is there life before an array separator?" No,
|
||||
| ^
|
||||
invalid array
|
||||
expected `]`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/text-in-array.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/array/text-in-array.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 3, column 3
|
||||
|
|
||||
3 | I don't belong,
|
||||
| ^
|
||||
invalid array
|
||||
expected `]`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/almost-false-with-extra.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/almost-false-with-extra.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 5
|
||||
|
|
||||
1 | a = falsify
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/almost-false.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/almost-false.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 5
|
||||
|
|
||||
1 | a = fals
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/almost-true-with-extra.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/almost-true-with-extra.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 5
|
||||
|
|
||||
1 | a = truthy
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/almost-true.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/almost-true.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 5
|
||||
|
|
||||
1 | a = tru
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/just-f.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/just-f.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 5
|
||||
|
|
||||
1 | a = f
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/just-t.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/just-t.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 5
|
||||
|
|
||||
1 | a = t
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/mixed-case.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/mixed-case.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 9
|
||||
|
|
||||
1 | valid = False
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/starting-same-false.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/starting-same-false.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 10
|
||||
|
|
||||
1 | a = falsey
|
||||
| ^
|
||||
expected newline, `#`
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/starting-same-true.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/starting-same-true.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 9
|
||||
|
|
||||
1 | a = truer
|
||||
| ^
|
||||
expected newline, `#`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/wrong-case-false.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/wrong-case-false.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 5
|
||||
|
|
||||
1 | b = FALSE
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/wrong-case-true.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/bool/wrong-case-true.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 5
|
||||
|
|
||||
1 | a = TRUE
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/bare-cr.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/bare-cr.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 2, column 1
|
||||
|
|
||||
2 |
|
||||
| ^
|
||||
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/control/bare-formfeed.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/control/bare-formfeed.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 17
|
||||
|
|
||||
1 | bare-formfeed =
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
BIN
third-party/vendor/toml_edit/tests/fixtures/invalid/control/bare-null.stderr
vendored
Normal file
BIN
third-party/vendor/toml_edit/tests/fixtures/invalid/control/bare-null.stderr
vendored
Normal file
Binary file not shown.
6
third-party/vendor/toml_edit/tests/fixtures/invalid/control/bare-vertical-tab.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/control/bare-vertical-tab.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 21
|
||||
|
|
||||
1 | bare-vertical-tab =
|
||||
| ^
|
||||
invalid string
|
||||
expected `"`, `'`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/control/comment-cr.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/control/comment-cr.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 1, column 45
|
||||
|
|
||||
1 | comment-cr = "Carriage return in comment" #
|
||||
a=1
|
||||
| ^
|
||||
expected newline, `#`
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/comment-del.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/comment-del.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 24
|
||||
|
|
||||
1 | comment-del = "0x7f" #
|
||||
| ^
|
||||
expected newline, `#`
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/comment-lf.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/comment-lf.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 25
|
||||
|
|
||||
1 | comment-lf = "ctrl-P" #
|
||||
| ^
|
||||
expected newline, `#`
|
||||
BIN
third-party/vendor/toml_edit/tests/fixtures/invalid/control/comment-null.stderr
vendored
Normal file
BIN
third-party/vendor/toml_edit/tests/fixtures/invalid/control/comment-null.stderr
vendored
Normal file
Binary file not shown.
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/comment-us.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/comment-us.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 25
|
||||
|
|
||||
1 | comment-us = "ctrl-_" #
|
||||
| ^
|
||||
expected newline, `#`
|
||||
6
third-party/vendor/toml_edit/tests/fixtures/invalid/control/control.stderr
vendored
Normal file
6
third-party/vendor/toml_edit/tests/fixtures/invalid/control/control.stderr
vendored
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
TOML parse error at line 9, column 22
|
||||
|
|
||||
9 | string-null = "null\x00"
|
||||
| ^
|
||||
invalid escape sequence
|
||||
expected `b`, `f`, `n`, `r`, `t`, `u`, `U`, `\`, `"`
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/multi-del.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/multi-del.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 20
|
||||
|
|
||||
1 | multi-del = """null"""
|
||||
| ^
|
||||
invalid multiline basic string
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/multi-lf.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/multi-lf.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 19
|
||||
|
|
||||
1 | multi-lf = """null"""
|
||||
| ^
|
||||
invalid multiline basic string
|
||||
BIN
third-party/vendor/toml_edit/tests/fixtures/invalid/control/multi-null.stderr
vendored
Normal file
BIN
third-party/vendor/toml_edit/tests/fixtures/invalid/control/multi-null.stderr
vendored
Normal file
Binary file not shown.
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/multi-us.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/multi-us.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 19
|
||||
|
|
||||
1 | multi-us = """null"""
|
||||
| ^
|
||||
invalid multiline basic string
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-del.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-del.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 23
|
||||
|
|
||||
1 | rawmulti-del = '''null'''
|
||||
| ^
|
||||
invalid multiline literal string
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-lf.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-lf.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 22
|
||||
|
|
||||
1 | rawmulti-lf = '''null'''
|
||||
| ^
|
||||
invalid multiline literal string
|
||||
BIN
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-null.stderr
vendored
Normal file
BIN
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-null.stderr
vendored
Normal file
Binary file not shown.
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-us.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawmulti-us.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 22
|
||||
|
|
||||
1 | rawmulti-us = '''null'''
|
||||
| ^
|
||||
invalid multiline literal string
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-del.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-del.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 22
|
||||
|
|
||||
1 | rawstring-del = 'null'
|
||||
| ^
|
||||
invalid literal string
|
||||
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-lf.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-lf.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 21
|
||||
|
|
||||
1 | rawstring-lf = 'null'
|
||||
| ^
|
||||
invalid literal string
|
||||
BIN
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-null.stderr
vendored
Normal file
BIN
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-null.stderr
vendored
Normal file
Binary file not shown.
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-us.stderr
vendored
Normal file
5
third-party/vendor/toml_edit/tests/fixtures/invalid/control/rawstring-us.stderr
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
TOML parse error at line 1, column 21
|
||||
|
|
||||
1 | rawstring-us = 'null'
|
||||
| ^
|
||||
invalid literal string
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue