summaryrefslogtreecommitdiffstats
path: root/vendor/valuable
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-17 12:02:58 +0000
commit698f8c2f01ea549d77d7dc3338a12e04c11057b9 (patch)
tree173a775858bd501c378080a10dca74132f05bc50 /vendor/valuable
parentInitial commit. (diff)
downloadrustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.tar.xz
rustc-698f8c2f01ea549d77d7dc3338a12e04c11057b9.zip
Adding upstream version 1.64.0+dfsg1.upstream/1.64.0+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/valuable')
-rw-r--r--vendor/valuable/.cargo-checksum.json1
-rw-r--r--vendor/valuable/Cargo.lock617
-rw-r--r--vendor/valuable/Cargo.toml41
-rw-r--r--vendor/valuable/benches/structable.rs128
-rw-r--r--vendor/valuable/build.rs39
-rw-r--r--vendor/valuable/examples/derive.rs26
-rw-r--r--vendor/valuable/examples/hello_world.rs68
-rw-r--r--vendor/valuable/examples/print.rs106
-rw-r--r--vendor/valuable/no_atomic.rs63
-rw-r--r--vendor/valuable/src/enumerable.rs682
-rw-r--r--vendor/valuable/src/field.rs166
-rw-r--r--vendor/valuable/src/lib.rs146
-rw-r--r--vendor/valuable/src/listable.rs257
-rw-r--r--vendor/valuable/src/mappable.rs191
-rw-r--r--vendor/valuable/src/named_values.rs222
-rw-r--r--vendor/valuable/src/slice.rs428
-rw-r--r--vendor/valuable/src/structable.rs496
-rw-r--r--vendor/valuable/src/tuplable.rs339
-rw-r--r--vendor/valuable/src/valuable.rs339
-rw-r--r--vendor/valuable/src/value.rs877
-rw-r--r--vendor/valuable/src/visit.rs459
21 files changed, 5691 insertions, 0 deletions
diff --git a/vendor/valuable/.cargo-checksum.json b/vendor/valuable/.cargo-checksum.json
new file mode 100644
index 000000000..79ed9d549
--- /dev/null
+++ b/vendor/valuable/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.lock":"fea5e41d2befef0b42734010a85f95548b5255ff1e4ee2dd2e6827adb8fe5f3e","Cargo.toml":"995a2454b4e3e583124d60b694e106ebd193b9742df3e050a6f49e5801b3597b","benches/structable.rs":"1baad763d1b0900004682b139efd58b17c974dc2068ede2229f8786e4a21372e","build.rs":"4ad508d818c27ee58bf7da2b9b4b425dae3e2656850327b3080fe2ad38767928","examples/derive.rs":"238473e63c0647cdb6652f1613575e24b323d40db5c8f3e5c32d64a3ea6b4048","examples/hello_world.rs":"75e48360e53b37e077e574d9c1aa2754b197f551ac5d604b03ebec9d31bab5cf","examples/print.rs":"924c55402b18e518317acc013a6cf407fcc13532c1eca8d9cd5f5631e79df960","no_atomic.rs":"b1c5cb0bd10733eb20516d10edc047b45aa67943f3347ae44fb779ed7fc7aff2","src/enumerable.rs":"008fe833c558f7e956ba0238a9d66947a671f66c5762905ed79d48a428c0ad44","src/field.rs":"c3d96f215c4bfc2a3910d0616fb335332d17f7dcf93ca739c933d88e1f98d229","src/lib.rs":"6954630c4c7c389192f3f8b5097076bbba6e43b5c4cd4ec68b4ffc18bff0a5b4","src/listable.rs":"f1a0743ed650604634972c19b66505a5727a6a6e2d7b54861e65cdcf10949432","src/mappable.rs":"ef7d334ef00d6b34cbff45b73b13935de6659933abafff9ad3d5d2a16d7ccac1","src/named_values.rs":"df5009074379ea59b02ebaf730890d0a4b6fa5c67c4057cc60f84d3652ca2bc5","src/slice.rs":"e382f56eb14ea7848276a4c8bda537f5207a4a6ed7a4b2ee4d2dde7feebce3b4","src/structable.rs":"369b17701d59bab138eac22ec043d434a052f49976236cc5ee680e72ca23ed6e","src/tuplable.rs":"e8b64a0761263666d984257109b5d54337cd97be59f08b08ec153e68ec1636c5","src/valuable.rs":"f8fdef201d3181935330fb86b27c455a5c86079f9f2cad363cda765801d7dd50","src/value.rs":"479d2c5b9d84c930e3abfe0032734ad92b243cf095f5fea6226a9da5eec81484","src/visit.rs":"060bacd3e1c0b333692f96c3ca970ca47a859cc28700713630996d9f0dc1668e"},"package":"830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"} \ No newline at end of file
diff --git a/vendor/valuable/Cargo.lock b/vendor/valuable/Cargo.lock
new file mode 100644
index 000000000..f7715f999
--- /dev/null
+++ b/vendor/valuable/Cargo.lock
@@ -0,0 +1,617 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "atty"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+dependencies = [
+ "hermit-abi",
+ "libc",
+ "winapi",
+]
+
+[[package]]
+name = "autocfg"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
+
+[[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 = [
+ "lazy_static",
+ "memchr",
+ "regex-automata",
+ "serde",
+]
+
+[[package]]
+name = "bumpalo"
+version = "3.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
+
+[[package]]
+name = "cast"
+version = "0.2.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4c24dab4283a142afa2fdca129b80ad2c6284e073930f964c3a1293c225ee39a"
+dependencies = [
+ "rustc_version",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
+name = "clap"
+version = "2.34.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
+dependencies = [
+ "bitflags",
+ "textwrap",
+ "unicode-width",
+]
+
+[[package]]
+name = "criterion"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1604dafd25fba2fe2d5895a9da139f8dc9b319a5fe5354ca137cbbce4e178d10"
+dependencies = [
+ "atty",
+ "cast",
+ "clap",
+ "criterion-plot",
+ "csv",
+ "itertools",
+ "lazy_static",
+ "num-traits",
+ "oorandom",
+ "plotters",
+ "rayon",
+ "regex",
+ "serde",
+ "serde_cbor",
+ "serde_derive",
+ "serde_json",
+ "tinytemplate",
+ "walkdir",
+]
+
+[[package]]
+name = "criterion-plot"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d00996de9f2f7559f7f4dc286073197f83e92256a59ed395f9aac01fe717da57"
+dependencies = [
+ "cast",
+ "itertools",
+]
+
+[[package]]
+name = "crossbeam-channel"
+version = "0.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06ed27e177f16d65f0f0c22a213e17c696ace5dd64b14258b52f9417ccb52db4"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-deque"
+version = "0.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6455c0ca19f0d2fbf751b908d5c55c1f5cbc65e03c4225427254b46890bdde1e"
+dependencies = [
+ "cfg-if",
+ "crossbeam-epoch",
+ "crossbeam-utils",
+]
+
+[[package]]
+name = "crossbeam-epoch"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ec02e091aa634e2c3ada4a392989e7c3116673ef0ac5b72232439094d73b7fd"
+dependencies = [
+ "cfg-if",
+ "crossbeam-utils",
+ "lazy_static",
+ "memoffset",
+ "scopeguard",
+]
+
+[[package]]
+name = "crossbeam-utils"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d82cfc11ce7f2c3faef78d8a684447b40d503d9681acebed6cb728d45940c4db"
+dependencies = [
+ "cfg-if",
+ "lazy_static",
+]
+
+[[package]]
+name = "csv"
+version = "1.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "22813a6dc45b335f9bade10bf7271dc477e81113e89eb251a0bc2a8a81c536e1"
+dependencies = [
+ "bstr",
+ "csv-core",
+ "itoa 0.4.8",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "csv-core"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2b2466559f260f48ad25fe6317b3c8dac77b5bdb5763ac7d9d6103530663bc90"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "either"
+version = "1.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
+
+[[package]]
+name = "half"
+version = "1.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "eabb4a44450da02c90444cf74558da904edde8fb4e9035a9a6a4e15445af0bd7"
+
+[[package]]
+name = "hermit-abi"
+version = "0.1.19"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
+dependencies = [
+ "libc",
+]
+
+[[package]]
+name = "itertools"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
+dependencies = [
+ "either",
+]
+
+[[package]]
+name = "itoa"
+version = "0.4.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
+
+[[package]]
+name = "itoa"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1aab8fc367588b89dcee83ab0fd66b72b50b72fa1904d7095045ace2b0c81c35"
+
+[[package]]
+name = "js-sys"
+version = "0.3.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
+dependencies = [
+ "wasm-bindgen",
+]
+
+[[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.112"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
+
+[[package]]
+name = "log"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "memchr"
+version = "2.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
+
+[[package]]
+name = "memoffset"
+version = "0.6.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
+dependencies = [
+ "autocfg",
+]
+
+[[package]]
+name = "num-traits"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
+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",
+ "libc",
+]
+
+[[package]]
+name = "oorandom"
+version = "11.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
+
+[[package]]
+name = "plotters"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32a3fd9ec30b9749ce28cd91f255d569591cdf937fe280c312143e3c4bad6f2a"
+dependencies = [
+ "num-traits",
+ "plotters-backend",
+ "plotters-svg",
+ "wasm-bindgen",
+ "web-sys",
+]
+
+[[package]]
+name = "plotters-backend"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d88417318da0eaf0fdcdb51a0ee6c3bed624333bff8f946733049380be67ac1c"
+
+[[package]]
+name = "plotters-svg"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "521fa9638fa597e1dc53e9412a4f9cefb01187ee1f7413076f9e6749e2885ba9"
+dependencies = [
+ "plotters-backend",
+]
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.36"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "rayon"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
+dependencies = [
+ "autocfg",
+ "crossbeam-deque",
+ "either",
+ "rayon-core",
+]
+
+[[package]]
+name = "rayon-core"
+version = "1.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
+dependencies = [
+ "crossbeam-channel",
+ "crossbeam-deque",
+ "crossbeam-utils",
+ "lazy_static",
+ "num_cpus",
+]
+
+[[package]]
+name = "regex"
+version = "1.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
+dependencies = [
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.25"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
+
+[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver",
+]
+
+[[package]]
+name = "ryu"
+version = "1.0.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73b4b750c782965c211b42f022f59af1fbceabdd026623714f104152f1ec149f"
+
+[[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 = "scopeguard"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
+
+[[package]]
+name = "semver"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "568a8e6258aa33c13358f81fd834adb854c6f7c9468520910a9b1e8fac068012"
+
+[[package]]
+name = "serde"
+version = "1.0.133"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"
+
+[[package]]
+name = "serde_cbor"
+version = "0.11.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"
+dependencies = [
+ "half",
+ "serde",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.133"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "serde_json"
+version = "1.0.74"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee2bb9cd061c5865d345bb02ca49fcef1391741b672b54a0bf7b679badec3142"
+dependencies = [
+ "itoa 1.0.1",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.84"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecb2e6da8ee5eb9a61068762a32fa9619cc591ceb055b3687f4cd4051ec2e06b"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "textwrap"
+version = "0.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
+dependencies = [
+ "unicode-width",
+]
+
+[[package]]
+name = "tinytemplate"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc"
+dependencies = [
+ "serde",
+ "serde_json",
+]
+
+[[package]]
+name = "unicode-width"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
+
+[[package]]
+name = "valuable"
+version = "0.1.0"
+dependencies = [
+ "criterion",
+ "valuable-derive",
+]
+
+[[package]]
+name = "valuable-derive"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9d44690c645190cfce32f91a1582281654b2338c6073fa250b0949fd25c55b32"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[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 = "wasm-bindgen"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
+dependencies = [
+ "cfg-if",
+ "wasm-bindgen-macro",
+]
+
+[[package]]
+name = "wasm-bindgen-backend"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
+dependencies = [
+ "bumpalo",
+ "lazy_static",
+ "log",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-macro"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
+dependencies = [
+ "quote",
+ "wasm-bindgen-macro-support",
+]
+
+[[package]]
+name = "wasm-bindgen-macro-support"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "wasm-bindgen-backend",
+ "wasm-bindgen-shared",
+]
+
+[[package]]
+name = "wasm-bindgen-shared"
+version = "0.2.78"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
+
+[[package]]
+name = "web-sys"
+version = "0.3.55"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
+dependencies = [
+ "js-sys",
+ "wasm-bindgen",
+]
+
+[[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"
diff --git a/vendor/valuable/Cargo.toml b/vendor/valuable/Cargo.toml
new file mode 100644
index 000000000..408651897
--- /dev/null
+++ b/vendor/valuable/Cargo.toml
@@ -0,0 +1,41 @@
+# 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 = "2018"
+rust-version = "1.51.0"
+name = "valuable"
+version = "0.1.0"
+description = "Object-safe value inspection, used to pass un-typed structured data across trait-object boundaries.\n"
+readme = "../README.md"
+keywords = ["valuable", "serialization", "debugging", "no_std"]
+categories = ["development-tools::debugging", "encoding"]
+license = "MIT"
+repository = "https://github.com/tokio-rs/valuable"
+resolver = "2"
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = ["--cfg", "docsrs"]
+
+[[bench]]
+name = "structable"
+harness = false
+[dependencies.valuable-derive]
+version = "0.1.0"
+optional = true
+[dev-dependencies.criterion]
+version = "0.3"
+
+[features]
+alloc = []
+default = ["std"]
+derive = ["valuable-derive"]
+std = ["alloc"]
diff --git a/vendor/valuable/benches/structable.rs b/vendor/valuable/benches/structable.rs
new file mode 100644
index 000000000..3d00cd754
--- /dev/null
+++ b/vendor/valuable/benches/structable.rs
@@ -0,0 +1,128 @@
+use valuable::*;
+
+use criterion::{black_box, criterion_group, criterion_main, Criterion};
+
+#[derive(Default)]
+struct HelloWorld {
+ one: usize,
+ two: usize,
+ three: usize,
+ four: usize,
+ five: usize,
+ six: usize,
+}
+
+static FIELDS: &[NamedField<'static>] = &[
+ NamedField::new("one"),
+ NamedField::new("two"),
+ NamedField::new("three"),
+ NamedField::new("four"),
+ NamedField::new("five"),
+ NamedField::new("six"),
+];
+
+impl Structable for HelloWorld {
+ fn definition(&self) -> StructDef<'_> {
+ StructDef::new_static("HelloWorld", Fields::Named(FIELDS))
+ }
+}
+
+impl Valuable for HelloWorld {
+ fn as_value(&self) -> Value<'_> {
+ Value::Structable(self)
+ }
+
+ fn visit(&self, v: &mut dyn Visit) {
+ v.visit_named_fields(&NamedValues::new(
+ FIELDS,
+ &[
+ Value::Usize(self.one),
+ Value::Usize(self.two),
+ Value::Usize(self.three),
+ Value::Usize(self.four),
+ Value::Usize(self.five),
+ Value::Usize(self.six),
+ ],
+ ));
+ }
+}
+
+fn criterion_benchmark(c: &mut Criterion) {
+ const NUM: usize = 50;
+
+ let hello_world = black_box(HelloWorld::default());
+ let structable = &hello_world as &dyn Structable;
+ let f = match structable.definition() {
+ StructDef::Static {
+ fields: Fields::Named(fields),
+ ..
+ } => &fields[5],
+ _ => unreachable!(),
+ };
+
+ struct Sum(usize, &'static NamedField<'static>);
+
+ impl Visit for Sum {
+ fn visit_named_fields(&mut self, record: &NamedValues<'_>) {
+ self.0 += match record.get(self.1) {
+ Some(Value::Usize(v)) => v,
+ _ => return,
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unimplemented!()
+ }
+ }
+
+ c.bench_function("struct", |b| {
+ b.iter(|| {
+ let mut num = 0;
+ for _ in 0..NUM {
+ let hello_world = black_box(HelloWorld::default());
+ num += hello_world.six;
+ }
+
+ black_box(num);
+ })
+ });
+
+ c.bench_function("valuable", |b| {
+ b.iter(|| {
+ let mut v = Sum(black_box(0), f);
+
+ for _ in 0..NUM {
+ v.visit_named_fields(&NamedValues::new(
+ FIELDS,
+ &[
+ Value::Usize(0),
+ Value::Usize(0),
+ Value::Usize(0),
+ Value::Usize(0),
+ Value::Usize(0),
+ Value::Usize(0),
+ ],
+ ));
+ /*
+ v.visit_struct(&Record::new(
+ &definition,
+ &[
+ Value::Usize(hello_world.one),
+ Value::Usize(hello_world.two),
+ Value::Usize(hello_world.three),
+ Value::Usize(hello_world.four),
+ Value::Usize(hello_world.five),
+ Value::Usize(hello_world.six),
+ ]
+ ));
+ */
+ // hello_world.visit(&mut v);
+ }
+
+ black_box(v.0);
+ })
+ });
+}
+
+criterion_group!(benches, criterion_benchmark);
+criterion_main!(benches);
diff --git a/vendor/valuable/build.rs b/vendor/valuable/build.rs
new file mode 100644
index 000000000..ad0dd06ae
--- /dev/null
+++ b/vendor/valuable/build.rs
@@ -0,0 +1,39 @@
+#![warn(rust_2018_idioms, single_use_lifetimes)]
+
+use std::env;
+
+include!("no_atomic.rs");
+
+// The rustc-cfg strings below are *not* public API. Please let us know by
+// opening a GitHub issue if your build environment requires some way to enable
+// these cfgs other than by executing our build script.
+fn main() {
+ let target = match env::var("TARGET") {
+ Ok(target) => target,
+ Err(e) => {
+ println!(
+ "cargo:warning=valuable: unable to get TARGET environment variable: {}",
+ e
+ );
+ return;
+ }
+ };
+
+ // Note that this is `no_*`, not `has_*`. This allows treating
+ // `cfg(target_has_atomic = "ptr")` as true when the build script doesn't
+ // run. This is needed for compatibility with non-cargo build systems that
+ // don't run the build script.
+ if NO_ATOMIC_CAS.contains(&&*target) {
+ println!("cargo:rustc-cfg=valuable_no_atomic_cas");
+ }
+ if NO_ATOMIC.contains(&&*target) {
+ println!("cargo:rustc-cfg=valuable_no_atomic");
+ println!("cargo:rustc-cfg=valuable_no_atomic_64");
+ } else if NO_ATOMIC_64.contains(&&*target) {
+ println!("cargo:rustc-cfg=valuable_no_atomic_64");
+ } else {
+ // Otherwise, assuming `"max-atomic-width" == 64`.
+ }
+
+ println!("cargo:rerun-if-changed=no_atomic.rs");
+}
diff --git a/vendor/valuable/examples/derive.rs b/vendor/valuable/examples/derive.rs
new file mode 100644
index 000000000..b67aaf3a7
--- /dev/null
+++ b/vendor/valuable/examples/derive.rs
@@ -0,0 +1,26 @@
+use valuable::Valuable;
+
+use std::collections::HashMap;
+
+// `Debug` not implemented for struct, the debug implementation is going via
+// valuable.
+#[derive(Valuable)]
+struct Person {
+ name: String,
+ age: u8,
+ phones: Vec<String>,
+ favorites: HashMap<String, String>,
+}
+
+fn main() {
+ let mut p = Person {
+ name: "John Doe".to_string(),
+ age: 42,
+ phones: vec!["876-5309".to_string()],
+ favorites: HashMap::new(),
+ };
+
+ p.favorites.insert("color".to_string(), "blue".to_string());
+
+ println!("{:#?}", p.as_value());
+}
diff --git a/vendor/valuable/examples/hello_world.rs b/vendor/valuable/examples/hello_world.rs
new file mode 100644
index 000000000..7c3d173f0
--- /dev/null
+++ b/vendor/valuable/examples/hello_world.rs
@@ -0,0 +1,68 @@
+use valuable::*;
+
+struct HelloWorld {
+ hello: &'static str,
+ world: World,
+}
+
+struct World {
+ answer: usize,
+}
+
+static HELLO_WORLD_FIELDS: &[NamedField<'static>] =
+ &[NamedField::new("hello"), NamedField::new("world")];
+
+impl Structable for HelloWorld {
+ fn definition(&self) -> StructDef<'_> {
+ StructDef::new_static("HelloWorld", Fields::Named(HELLO_WORLD_FIELDS))
+ }
+}
+
+impl Valuable for HelloWorld {
+ fn as_value(&self) -> Value<'_> {
+ Value::Structable(self)
+ }
+
+ fn visit(&self, v: &mut dyn Visit) {
+ v.visit_named_fields(&NamedValues::new(
+ HELLO_WORLD_FIELDS,
+ &[Value::String(self.hello), Value::Structable(&self.world)],
+ ));
+ }
+}
+
+static WORLD_FIELDS: &[NamedField<'static>] = &[NamedField::new("answer")];
+
+impl Valuable for World {
+ fn as_value(&self) -> Value<'_> {
+ Value::Structable(self)
+ }
+
+ fn visit(&self, v: &mut dyn Visit) {
+ v.visit_named_fields(&NamedValues::new(
+ WORLD_FIELDS,
+ &[Value::Usize(self.answer)],
+ ));
+ }
+}
+
+impl Structable for World {
+ fn definition(&self) -> StructDef<'_> {
+ StructDef::new_static("World", Fields::Named(WORLD_FIELDS))
+ }
+}
+
+fn main() {
+ let hello_world = HelloWorld {
+ hello: "wut",
+ world: World { answer: 42 },
+ };
+
+ let value = Value::Structable(&hello_world);
+ println!("{:#?}", value);
+
+ let slice = &[1, 2, 3][..];
+
+ let value = &slice as &dyn Valuable;
+ println!("{:?}", value);
+}
diff --git a/vendor/valuable/examples/print.rs b/vendor/valuable/examples/print.rs
new file mode 100644
index 000000000..b6998d37a
--- /dev/null
+++ b/vendor/valuable/examples/print.rs
@@ -0,0 +1,106 @@
+use valuable::{NamedValues, Valuable, Value, Visit};
+
+struct Print(String);
+
+impl Print {
+ fn indent(&self) -> Print {
+ Print(format!("{} ", self.0))
+ }
+}
+
+impl Visit for Print {
+ fn visit_value(&mut self, value: Value<'_>) {
+ match value {
+ Value::Structable(v) => {
+ let def = v.definition();
+ // Print the struct name
+ println!("{}{}:", self.0, def.name());
+
+ // Visit fields
+ let mut visit = self.indent();
+ v.visit(&mut visit);
+ }
+ Value::Enumerable(v) => {
+ let def = v.definition();
+ let variant = v.variant();
+ // Print the enum name
+ println!("{}{}::{}:", self.0, def.name(), variant.name());
+
+ // Visit fields
+ let mut visit = self.indent();
+ v.visit(&mut visit);
+ }
+ Value::Listable(v) => {
+ println!("{}", self.0);
+
+ // Visit fields
+ let mut visit = self.indent();
+ v.visit(&mut visit);
+ }
+ Value::Mappable(v) => {
+ println!("{}", self.0);
+
+ // Visit fields
+ let mut visit = self.indent();
+ v.visit(&mut visit);
+ }
+ // Primitive or unknown type, just render Debug
+ v => println!("{:?}", v),
+ }
+ }
+
+ fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ for (field, value) in named_values {
+ print!("{}- {}: ", self.0, field.name());
+ value.visit(self);
+ }
+ }
+
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ for value in values {
+ print!("{}- ", self.0);
+ value.visit(self);
+ }
+ }
+
+ fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+ print!("{}- {:?}: ", self.0, key);
+ value.visit(self);
+ }
+}
+
+#[derive(Valuable)]
+struct Person {
+ name: String,
+ age: u32,
+ addresses: Vec<Address>,
+}
+
+#[derive(Valuable)]
+struct Address {
+ street: String,
+ city: String,
+ zip: String,
+}
+
+fn main() {
+ let person = Person {
+ name: "Angela Ashton".to_string(),
+ age: 31,
+ addresses: vec![
+ Address {
+ street: "123 1st Ave".to_string(),
+ city: "Townsville".to_string(),
+ zip: "12345".to_string(),
+ },
+ Address {
+ street: "555 Main St.".to_string(),
+ city: "New Old Town".to_string(),
+ zip: "55555".to_string(),
+ },
+ ],
+ };
+
+ let mut print = Print("".to_string());
+ valuable::visit(&person, &mut print);
+}
diff --git a/vendor/valuable/no_atomic.rs b/vendor/valuable/no_atomic.rs
new file mode 100644
index 000000000..3c2515560
--- /dev/null
+++ b/vendor/valuable/no_atomic.rs
@@ -0,0 +1,63 @@
+// This file is @generated by no_atomic.sh.
+// It is not intended for manual editing.
+
+const NO_ATOMIC_CAS: &[&str] = &[
+ "avr-unknown-gnu-atmega328",
+ "bpfeb-unknown-none",
+ "bpfel-unknown-none",
+ "msp430-none-elf",
+ "riscv32i-unknown-none-elf",
+ "riscv32imc-unknown-none-elf",
+ "thumbv4t-none-eabi",
+ "thumbv6m-none-eabi",
+];
+const NO_ATOMIC_64: &[&str] = &[
+ "arm-linux-androideabi",
+ "armebv7r-none-eabi",
+ "armebv7r-none-eabihf",
+ "armv4t-unknown-linux-gnueabi",
+ "armv5te-unknown-linux-gnueabi",
+ "armv5te-unknown-linux-musleabi",
+ "armv5te-unknown-linux-uclibceabi",
+ "armv7r-none-eabi",
+ "armv7r-none-eabihf",
+ "hexagon-unknown-linux-musl",
+ "m68k-unknown-linux-gnu",
+ "mips-unknown-linux-gnu",
+ "mips-unknown-linux-musl",
+ "mips-unknown-linux-uclibc",
+ "mipsel-unknown-linux-gnu",
+ "mipsel-unknown-linux-musl",
+ "mipsel-unknown-linux-uclibc",
+ "mipsel-unknown-none",
+ "mipsisa32r6-unknown-linux-gnu",
+ "mipsisa32r6el-unknown-linux-gnu",
+ "powerpc-unknown-freebsd",
+ "powerpc-unknown-linux-gnu",
+ "powerpc-unknown-linux-gnuspe",
+ "powerpc-unknown-linux-musl",
+ "powerpc-unknown-netbsd",
+ "powerpc-unknown-openbsd",
+ "powerpc-wrs-vxworks",
+ "powerpc-wrs-vxworks-spe",
+ "riscv32gc-unknown-linux-gnu",
+ "riscv32gc-unknown-linux-musl",
+ "riscv32imac-unknown-none-elf",
+ "riscv32imc-esp-espidf",
+ "thumbv7em-none-eabi",
+ "thumbv7em-none-eabihf",
+ "thumbv7m-none-eabi",
+ "thumbv8m.base-none-eabi",
+ "thumbv8m.main-none-eabi",
+ "thumbv8m.main-none-eabihf",
+ "armv6k-nintendo-3ds",
+ "mipsel-sony-psp",
+ "thumbv4t-none-eabi",
+ "thumbv6m-none-eabi",
+];
+const NO_ATOMIC: &[&str] = &[
+ "avr-unknown-gnu-atmega328",
+ "msp430-none-elf",
+ "riscv32i-unknown-none-elf",
+ "riscv32imc-unknown-none-elf",
+];
diff --git a/vendor/valuable/src/enumerable.rs b/vendor/valuable/src/enumerable.rs
new file mode 100644
index 000000000..3161f19f0
--- /dev/null
+++ b/vendor/valuable/src/enumerable.rs
@@ -0,0 +1,682 @@
+use crate::field::*;
+use crate::*;
+
+#[cfg(feature = "alloc")]
+use alloc::format;
+use core::fmt;
+
+/// An enum-like [`Valuable`] sub-type.
+///
+/// Implemented by [`Valuable`] types that have an enum-like shape. Fields may
+/// be named or unnamed (tuple). Values that implement `Enumerable` must return
+/// [`Value::Enumerable`] from their [`Valuable::as_value`] implementation.
+///
+/// # Inspecting
+///
+/// The [`variant()`] method returns the `Enumerable` instance's variant. The
+/// `Enumerable` may also have unnamed fields (tuple) or named fields.
+/// Inspecting the field values is done by visiting the enum. When visiting an
+/// `Enumerable`, either the [`visit_named_fields()`] or the
+/// [`visit_unnamed_fields()`] methods of [`Visit`] are called. Each method may
+/// be called multiple times per `Enumerable`, but the two methods are never
+/// mixed.
+///
+/// [`variant()`]: Enumerable::variant
+/// [`visit_named_fields()`]: Visit::visit_named_fields
+/// [`visit_unnamed_fields()`]: Visit::visit_unnamed_fields
+///
+/// ```
+/// use valuable::{Valuable, Value, Visit};
+///
+/// #[derive(Valuable)]
+/// enum MyEnum {
+/// Foo,
+/// Bar(u32),
+/// }
+///
+/// struct PrintVariant;
+///
+/// impl Visit for PrintVariant {
+/// fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+/// for value in values {
+/// println!(" - {:?}", value);
+/// }
+/// }
+///
+/// fn visit_value(&mut self, value: Value<'_>) {
+/// match value {
+/// Value::Enumerable(v) => {
+/// println!("{}", v.variant().name());
+/// v.visit(self)
+/// }
+/// _ => {}
+/// }
+/// }
+/// }
+///
+/// let my_enum = MyEnum::Bar(123);
+///
+/// valuable::visit(&my_enum, &mut PrintVariant);
+/// ```
+///
+/// If the enum is **statically** defined, then all variants, and variant fields
+/// are known ahead of time and may be accessed via the [`EnumDef`] instance
+/// returned by [`definition()`].
+///
+/// [`definition()`]: Enumerable::definition
+///
+/// # Implementing
+///
+/// Implementing `Enumerable` is usually done by adding `#[derive(Valuable)]` to
+/// a Rust `enum` definition.
+///
+/// ```
+/// use valuable::{Valuable, Enumerable, EnumDef};
+///
+/// #[derive(Valuable)]
+/// enum MyEnum {
+/// Foo,
+/// Bar(u32),
+/// }
+///
+/// let my_enum = MyEnum::Bar(123);
+///
+/// let variants = match my_enum.definition() {
+/// EnumDef::Static { name, variants, .. } => {
+/// assert_eq!("MyEnum", name);
+/// variants
+/// }
+/// _ => unreachable!(),
+/// };
+///
+/// assert_eq!(2, variants.len());
+/// assert_eq!("Foo", variants[0].name());
+/// assert!(variants[0].fields().is_unnamed());
+/// ```
+pub trait Enumerable: Valuable {
+ /// Returns the enum's definition.
+ ///
+ /// See [`EnumDef`] documentation for more details.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum MyEnum {
+ /// Foo,
+ /// Bar(u32),
+ /// }
+ ///
+ /// let my_enum = MyEnum::Bar(123);
+ ///
+ /// assert_eq!("MyEnum", my_enum.definition().name());
+ /// ```
+ fn definition(&self) -> EnumDef<'_>;
+
+ /// Returns the `enum`'s current variant.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum MyEnum {
+ /// Foo,
+ /// Bar(u32),
+ /// }
+ ///
+ /// let my_enum = MyEnum::Foo;
+ /// assert_eq!("Foo", my_enum.variant().name());
+ /// ```
+ fn variant(&self) -> Variant<'_>;
+}
+
+/// An enum's variants, variant fields, and other enum-level information.
+///
+/// Returned by [`Enumerable::definition()`], `EnumDef` provides the caller with
+/// information about the enum's definition.
+#[non_exhaustive]
+#[derive(Debug)]
+pub enum EnumDef<'a> {
+ /// The enum is statically-defined, all variants and variant-level fields
+ /// are known ahead of time.
+ ///
+ /// Most `Enumerable` definitions for Rust enum types will be
+ /// `EnumDef::Static`.
+ ///
+ /// # Examples
+ ///
+ /// A statically defined enum
+ ///
+ /// ```
+ /// use valuable::{Valuable, Enumerable, EnumDef};
+ ///
+ /// #[derive(Valuable)]
+ /// enum MyEnum {
+ /// Foo,
+ /// Bar(u32),
+ /// }
+ ///
+ /// let my_enum = MyEnum::Bar(123);
+ ///
+ /// let variants = match my_enum.definition() {
+ /// EnumDef::Static { name, variants, .. } => {
+ /// assert_eq!("MyEnum", name);
+ /// variants
+ /// }
+ /// _ => unreachable!(),
+ /// };
+ ///
+ /// assert_eq!(2, variants.len());
+ /// assert_eq!("Foo", variants[0].name());
+ /// assert_eq!("Bar", variants[1].name());
+ /// ```
+ #[non_exhaustive]
+ Static {
+ /// The enum's name
+ name: &'static str,
+
+ /// The enum's variants
+ variants: &'static [VariantDef<'static>],
+ },
+
+ /// The enum is dynamically-defined, not all variants and fields are known
+ /// ahead of time.
+ ///
+ /// # Examples
+ ///
+ /// The enum variant is tracked as a string
+ ///
+ /// ```
+ /// use valuable::{Enumerable, EnumDef, Fields, VariantDef, Valuable, Value, Variant, Visit};
+ ///
+ /// /// A dynamic enum
+ /// struct DynEnum {
+ /// // The enum name
+ /// name: String,
+ ///
+ /// // The current variant
+ /// variant: String,
+ /// }
+ ///
+ /// impl Valuable for DynEnum {
+ /// fn as_value(&self) -> Value<'_> {
+ /// Value::Enumerable(self)
+ /// }
+ ///
+ /// fn visit(&self, _visit: &mut dyn Visit) {
+ /// // No variant fields, so there is nothing to call here.
+ /// }
+ /// }
+ ///
+ /// impl Enumerable for DynEnum {
+ /// fn definition(&self) -> EnumDef<'_> {
+ /// EnumDef::new_dynamic(&self.name, &[])
+ /// }
+ ///
+ /// fn variant(&self) -> Variant<'_> {
+ /// Variant::Dynamic(VariantDef::new(&self.variant, Fields::Unnamed(0)))
+ /// }
+ /// }
+ /// ```
+ #[non_exhaustive]
+ Dynamic {
+ /// The enum's name
+ name: &'a str,
+
+ /// The enum's variants
+ variants: &'a [VariantDef<'a>],
+ },
+}
+
+/// An enum variant definition.
+///
+/// Included with [`EnumDef`] returned by [`Enumerable::definition()`],
+/// `VariantDef` provides the caller with information about a specific variant.
+#[derive(Debug)]
+pub struct VariantDef<'a> {
+ /// Variant name
+ name: &'a str,
+
+ /// Variant fields
+ fields: Fields<'a>,
+}
+
+/// An enum variant
+///
+/// Returned by [`Enumerable::variant()`], `Variant` represents a single enum
+/// variant.
+#[derive(Debug)]
+pub enum Variant<'a> {
+ /// The variant is statically defined by the associated enum.
+ Static(&'static VariantDef<'static>),
+
+ /// The variant is dynamically defined and not included as part of
+ /// [`Enumerable::definition()`].
+ Dynamic(VariantDef<'a>),
+}
+
+impl<'a> EnumDef<'a> {
+ /// Create a new [`EnumDef::Static`] instance.
+ ///
+ /// This should be used when an enum's variants are fixed and known ahead of
+ /// time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{EnumDef, Fields, VariantDef};
+ ///
+ /// static VARIANTS: &[VariantDef<'static>] = &[
+ /// VariantDef::new("Bar", Fields::Unnamed(1)),
+ /// ];
+ ///
+ /// let def = EnumDef::new_static( "Foo", VARIANTS);
+ /// ```
+ pub const fn new_static(
+ name: &'static str,
+ variants: &'static [VariantDef<'static>],
+ ) -> EnumDef<'a> {
+ EnumDef::Static { name, variants }
+ }
+
+ /// Create a new [`EnumDef::Dynamic`] instance.
+ ///
+ /// This is used when the enum's variants may vary at runtime.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{EnumDef, Fields, VariantDef};
+ ///
+ /// let def = EnumDef::new_dynamic(
+ /// "Foo",
+ /// &[VariantDef::new("Bar", Fields::Unnamed(1))]
+ /// );
+ /// ```
+ pub const fn new_dynamic(name: &'a str, variants: &'a [VariantDef<'a>]) -> EnumDef<'a> {
+ EnumDef::Dynamic { name, variants }
+ }
+
+ /// Returns the enum's name
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum Foo {
+ /// Bar,
+ /// Baz,
+ /// }
+ ///
+ /// let def = Foo::Bar.definition();
+ /// assert_eq!("Foo", def.name());
+ /// ```
+ pub fn name(&self) -> &str {
+ match self {
+ EnumDef::Static { name, .. } => name,
+ EnumDef::Dynamic { name, .. } => name,
+ }
+ }
+
+ /// Returns the enum's variants
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum Foo {
+ /// Bar,
+ /// Baz,
+ /// }
+ ///
+ /// let def = Foo::Bar.definition();
+ /// let variants = def.variants();
+ ///
+ /// assert_eq!(2, variants.len());
+ /// assert_eq!("Bar", variants[0].name());
+ /// ```
+ pub fn variants(&self) -> &[VariantDef<'_>] {
+ match self {
+ EnumDef::Static { variants, .. } => variants,
+ EnumDef::Dynamic { variants, .. } => variants,
+ }
+ }
+
+ /// Returns `true` if the enum is [statically defined](EnumDef::Static).
+ ///
+ /// # Examples
+ ///
+ /// With a static enum
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum Foo {
+ /// Bar,
+ /// Baz,
+ /// }
+ ///
+ /// let def = Foo::Bar.definition();
+ /// assert!(def.is_static());
+ /// ```
+ ///
+ /// With a dynamic enum
+ ///
+ /// ```
+ /// use valuable::{EnumDef, Fields, VariantDef};
+ ///
+ /// let def = EnumDef::new_dynamic("Foo", &[]);
+ /// assert!(!def.is_static());
+ /// ```
+ pub fn is_static(&self) -> bool {
+ matches!(self, EnumDef::Static { .. })
+ }
+
+ /// Returns `true` if the enum is [dynamically defined](EnumDef::Dynamic).
+ ///
+ /// # Examples
+ ///
+ /// With a static enum
+ ///
+ /// ```
+ /// use valuable::{Enumerable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum Foo {
+ /// Bar,
+ /// Baz,
+ /// }
+ ///
+ /// let def = Foo::Bar.definition();
+ /// assert!(!def.is_dynamic());
+ /// ```
+ ///
+ /// With a dynamic enum
+ ///
+ /// ```
+ /// use valuable::{EnumDef, Fields, VariantDef};
+ ///
+ /// let def = EnumDef::new_dynamic("Foo", &[]);
+ /// assert!(def.is_dynamic());
+ /// ```
+ pub fn is_dynamic(&self) -> bool {
+ matches!(self, EnumDef::Dynamic { .. })
+ }
+}
+
+impl<'a> VariantDef<'a> {
+ /// Creates a new `VariantDef` instance.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Fields, VariantDef};
+ ///
+ /// let def = VariantDef::new("Foo", Fields::Unnamed(2));
+ /// ```
+ pub const fn new(name: &'a str, fields: Fields<'a>) -> VariantDef<'a> {
+ VariantDef { name, fields }
+ }
+
+ /// Returns the variant's name
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Fields, VariantDef};
+ ///
+ /// let def = VariantDef::new("Foo", Fields::Unnamed(2));
+ /// assert_eq!("Foo", def.name());
+ /// ```
+ pub fn name(&self) -> &str {
+ self.name
+ }
+
+ /// Returns the variant's fields
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Fields, VariantDef};
+ ///
+ /// let def = VariantDef::new("Foo", Fields::Unnamed(3));
+ /// assert!(matches!(def.fields(), Fields::Unnamed(_)));
+ /// ```
+ pub fn fields(&self) -> &Fields<'_> {
+ &self.fields
+ }
+}
+
+impl Variant<'_> {
+ /// Returns the variant's name
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Fields, Variant, VariantDef};
+ ///
+ /// static VARIANT: &VariantDef<'static> = &VariantDef::new(
+ /// "Foo", Fields::Unnamed(2));
+ ///
+ /// let variant = Variant::Static(VARIANT);
+ /// assert_eq!("Foo", variant.name());
+ /// ```
+ pub fn name(&self) -> &str {
+ match self {
+ Variant::Static(v) => v.name(),
+ Variant::Dynamic(v) => v.name(),
+ }
+ }
+
+ /// Returns the variant's fields
+ pub fn fields(&self) -> &Fields<'_> {
+ match self {
+ Variant::Static(v) => v.fields(),
+ Variant::Dynamic(v) => v.fields(),
+ }
+ }
+
+ /// Returns `true` if the variant has associated named fields.
+ ///
+ /// # Examples
+ ///
+ /// With named fields
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField, Variant, VariantDef};
+ ///
+ /// static VARIANT: &VariantDef<'static> = &VariantDef::new(
+ /// "Foo", Fields::Named(&[NamedField::new("hello")]));
+ ///
+ /// let variant = Variant::Static(VARIANT);
+ /// assert!(variant.is_named_fields());
+ /// ```
+ ///
+ /// With unnamed fields
+ ///
+ /// ```
+ /// use valuable::{Fields, Variant, VariantDef};
+ ///
+ /// static VARIANT: &VariantDef<'static> = &VariantDef::new(
+ /// "Foo", Fields::Unnamed(1));
+ ///
+ /// let variant = Variant::Static(VARIANT);
+ /// assert!(!variant.is_named_fields());
+ /// ```
+ pub fn is_named_fields(&self) -> bool {
+ self.fields().is_named()
+ }
+
+ /// Returns `true` if the variant has associated unnamed fields.
+ ///
+ /// # Examples
+ ///
+ /// With named fields
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField, Variant, VariantDef};
+ ///
+ /// static VARIANT: &VariantDef<'static> = &VariantDef::new(
+ /// "Foo", Fields::Named(&[NamedField::new("hello")]));
+ ///
+ /// let variant = Variant::Static(VARIANT);
+ /// assert!(!variant.is_unnamed_fields());
+ /// ```
+ ///
+ /// With unnamed fields
+ ///
+ /// ```
+ /// use valuable::{Fields, Variant, VariantDef};
+ ///
+ /// static VARIANT: &VariantDef<'static> = &VariantDef::new(
+ /// "Foo", Fields::Unnamed(1));
+ ///
+ /// let variant = Variant::Static(VARIANT);
+ /// assert!(variant.is_unnamed_fields());
+ /// ```
+ pub fn is_unnamed_fields(&self) -> bool {
+ !self.is_named_fields()
+ }
+}
+
+impl fmt::Debug for dyn Enumerable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let variant = self.variant();
+ #[cfg(feature = "alloc")]
+ let name = format!("{}::{}", self.definition().name(), variant.name());
+ #[cfg(not(feature = "alloc"))]
+ let name = variant.name();
+
+ if variant.is_named_fields() {
+ struct DebugEnum<'a, 'b> {
+ fmt: fmt::DebugStruct<'a, 'b>,
+ }
+
+ let mut debug = DebugEnum {
+ fmt: fmt.debug_struct(&name),
+ };
+
+ impl Visit for DebugEnum<'_, '_> {
+ fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ for (field, value) in named_values {
+ self.fmt.field(field.name(), value);
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unreachable!();
+ }
+ }
+
+ self.visit(&mut debug);
+
+ debug.fmt.finish()
+ } else {
+ struct DebugEnum<'a, 'b> {
+ fmt: fmt::DebugTuple<'a, 'b>,
+ }
+
+ let mut debug = DebugEnum {
+ fmt: fmt.debug_tuple(&name),
+ };
+
+ impl Visit for DebugEnum<'_, '_> {
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ for value in values {
+ self.fmt.field(value);
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unreachable!();
+ }
+ }
+
+ self.visit(&mut debug);
+
+ debug.fmt.finish()
+ }
+ }
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Enumerable> Enumerable for $ty {
+ fn definition(&self) -> EnumDef<'_> {
+ T::definition(&**self)
+ }
+
+ fn variant(&self) -> Variant<'_> {
+ T::variant(&**self)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
+
+static RESULT_VARIANTS: &[VariantDef<'static>] = &[
+ VariantDef::new("Ok", Fields::Unnamed(1)),
+ VariantDef::new("Err", Fields::Unnamed(1)),
+];
+
+impl<T, E> Enumerable for Result<T, E>
+where
+ T: Valuable,
+ E: Valuable,
+{
+ fn definition(&self) -> EnumDef<'_> {
+ EnumDef::new_static("Result", RESULT_VARIANTS)
+ }
+
+ fn variant(&self) -> Variant<'_> {
+ match self {
+ Ok(_) => Variant::Static(&RESULT_VARIANTS[0]),
+ Err(_) => Variant::Static(&RESULT_VARIANTS[1]),
+ }
+ }
+}
+
+impl<T, E> Valuable for Result<T, E>
+where
+ T: Valuable,
+ E: Valuable,
+{
+ fn as_value(&self) -> Value<'_> {
+ Value::Enumerable(self)
+ }
+
+ fn visit(&self, visitor: &mut dyn Visit) {
+ match self {
+ Ok(val) => visitor.visit_unnamed_fields(&[val.as_value()]),
+ Err(val) => visitor.visit_unnamed_fields(&[val.as_value()]),
+ }
+ }
+}
diff --git a/vendor/valuable/src/field.rs b/vendor/valuable/src/field.rs
new file mode 100644
index 000000000..faa00f420
--- /dev/null
+++ b/vendor/valuable/src/field.rs
@@ -0,0 +1,166 @@
+/// Data stored within a `Structable` or an `Enumerable`.
+#[derive(Debug)]
+pub enum Fields<'a> {
+ /// Named fields
+ Named(&'a [NamedField<'a>]),
+
+ /// Unnamed (positional) fields or unit
+ ///
+ /// The `usize` value represents the number of fields.
+ Unnamed(usize),
+}
+
+/// A named field
+#[derive(Debug, Clone, Copy)]
+pub struct NamedField<'a>(&'a str);
+
+impl Fields<'_> {
+ /// Returns `true` if the fields are named.
+ ///
+ /// # Examples
+ ///
+ /// Named fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let fields = Fields::Named(&[]);
+ /// assert!(fields.is_named());
+ /// ```
+ ///
+ /// Unnamed fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let fields = Fields::Unnamed(2);
+ /// assert!(!fields.is_named());
+ /// ```
+ pub const fn is_named(&self) -> bool {
+ matches!(self, Fields::Named(..))
+ }
+
+ /// Returns `true` if the fields are unnamed.
+ ///
+ /// # Examples
+ ///
+ /// Named fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let fields = Fields::Named(&[]);
+ /// assert!(!fields.is_unnamed());
+ /// ```
+ ///
+ /// Unnamed fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let fields = Fields::Unnamed(3);
+ /// assert!(fields.is_unnamed());
+ /// ```
+ pub const fn is_unnamed(&self) -> bool {
+ matches!(self, Fields::Unnamed(_))
+ }
+
+ /// Returns the number of fields.
+ ///
+ /// # Examples
+ ///
+ /// Named fields
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField};
+ ///
+ /// let fields = &[
+ /// NamedField::new("alice"),
+ /// NamedField::new("bob"),
+ /// ];
+ /// let fields = Fields::Named(fields);
+ ///
+ /// assert_eq!(fields.len(), 2);
+ /// ```
+ ///
+ /// Unnamed fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let fields = Fields::Unnamed(2);
+ /// assert_eq!(fields.len(), 2);
+ /// ```
+ pub const fn len(&self) -> usize {
+ match self {
+ Self::Named(names) => names.len(),
+ Self::Unnamed(len) => *len,
+ }
+ }
+
+ /// Returns `true` if this set of fields defines no fields.
+ ///
+ /// # Examples
+ ///
+ /// Named fields
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField};
+ ///
+ /// let fields = &[
+ /// NamedField::new("alice"),
+ /// NamedField::new("bob"),
+ /// ];
+ /// let non_empty = Fields::Named(fields);
+ ///
+ /// let empty = Fields::Named(&[]);
+ ///
+ /// assert!(!non_empty.is_empty());
+ /// assert!(empty.is_empty());
+ /// ```
+ ///
+ /// Unnamed fields
+ ///
+ /// ```
+ /// use valuable::Fields;
+ ///
+ /// let non_empty = Fields::Unnamed(2);
+ /// let empty = Fields::Unnamed(0);
+ ///
+ /// assert!(!non_empty.is_empty());
+ /// assert!(empty.is_empty());
+ /// ```
+ pub const fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+}
+
+impl<'a> NamedField<'a> {
+ /// Create a new `NamedField` instance with the given name.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::NamedField;
+ ///
+ /// let field = NamedField::new("hello");
+ /// assert_eq!("hello", field.name());
+ /// ```
+ pub const fn new(name: &'a str) -> NamedField<'a> {
+ NamedField(name)
+ }
+
+ /// Returns the field name
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::NamedField;
+ ///
+ /// let field = NamedField::new("hello");
+ /// assert_eq!("hello", field.name());
+ /// ```
+ pub const fn name(&self) -> &str {
+ self.0
+ }
+}
diff --git a/vendor/valuable/src/lib.rs b/vendor/valuable/src/lib.rs
new file mode 100644
index 000000000..5ba6341a0
--- /dev/null
+++ b/vendor/valuable/src/lib.rs
@@ -0,0 +1,146 @@
+#![warn(
+ missing_debug_implementations,
+ missing_docs,
+ rust_2018_idioms,
+ unreachable_pub
+)]
+//! Valuable provides object-safe value inspection. Use cases include passing
+//! structured data to trait objects and object-safe serialization.
+//!
+//! # Getting started
+//!
+//! First, derive [`Valuable`][macro@crate::Valuable] on your types.
+//!
+//! ```
+//! use valuable::Valuable;
+//!
+//! #[derive(Valuable)]
+//! struct HelloWorld {
+//! message: Message,
+//! }
+//!
+//! #[derive(Valuable)]
+//! enum Message {
+//! HelloWorld,
+//! Custom(String),
+//! }
+//! ```
+//!
+//! Then, implement a [visitor][Visit] to inspect the data.
+//!
+//! ```
+//! use valuable::{NamedValues, Value, Valuable, Visit};
+//!
+//! struct Print;
+//!
+//! impl Visit for Print {
+//! fn visit_value(&mut self, value: Value<'_>) {
+//! match value {
+//! Value::Structable(v) => {
+//! println!("struct {}", v.definition().name());
+//! v.visit(self);
+//! }
+//! Value::Enumerable(v) => {
+//! println!("enum {}::{}", v.definition().name(), v.variant().name());
+//! v.visit(self);
+//! }
+//! Value::Listable(v) => {
+//! println!("list");
+//! v.visit(self);
+//! }
+//! Value::Mappable(v) => {
+//! println!("map");
+//! v.visit(self);
+//! }
+//! _ => {
+//! println!("value {:?}", value);
+//! }
+//! }
+//! }
+//!
+//! fn visit_named_fields(&mut self, named_fields: &NamedValues<'_>) {
+//! for (field, value) in named_fields.iter() {
+//! println!("named field {}", field.name());
+//! value.visit(self);
+//! }
+//! }
+//!
+//! fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+//! for value in values {
+//! value.visit(self);
+//! }
+//! }
+//!
+//! fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+//! println!("key / value");
+//! key.visit(self);
+//! value.visit(self);
+//! }
+//! }
+//! ```
+//!
+//! Then, use the visitor to visit the value.
+//!
+//! ```
+//! # use valuable::*;
+//! # #[derive(Valuable)]
+//! # struct HelloWorld { message: Message }
+//! # #[derive(Valuable)]
+//! # enum Message { HelloWorld }
+//! # struct Print;
+//! # impl Visit for Print {
+//! # fn visit_value(&mut self, _: Value<'_>) {}
+//! # }
+//! let hello_world = HelloWorld { message: Message::HelloWorld };
+//! hello_world.visit(&mut Print);
+//! ```
+
+#![cfg_attr(not(feature = "std"), no_std)]
+#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg, doc_cfg_hide))]
+#![cfg_attr(
+ docsrs,
+ doc(cfg_hide(
+ not(valuable_no_atomic_cas),
+ not(valuable_no_atomic),
+ not(valuable_no_atomic_64)
+ ))
+)]
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+mod enumerable;
+pub use enumerable::{EnumDef, Enumerable, Variant, VariantDef};
+
+mod field;
+pub use field::{Fields, NamedField};
+
+mod listable;
+pub use listable::Listable;
+
+mod mappable;
+pub use mappable::Mappable;
+
+mod named_values;
+pub use named_values::NamedValues;
+
+mod slice;
+pub use slice::Slice;
+
+mod structable;
+pub use structable::{StructDef, Structable};
+
+mod tuplable;
+pub use tuplable::{Tuplable, TupleDef};
+
+mod valuable;
+pub use crate::valuable::Valuable;
+
+mod value;
+pub use value::Value;
+
+mod visit;
+pub use visit::{visit, Visit};
+
+#[cfg(feature = "derive")]
+pub use valuable_derive::Valuable;
diff --git a/vendor/valuable/src/listable.rs b/vendor/valuable/src/listable.rs
new file mode 100644
index 000000000..b79317f9c
--- /dev/null
+++ b/vendor/valuable/src/listable.rs
@@ -0,0 +1,257 @@
+use crate::*;
+
+use core::fmt;
+
+/// A list-like [`Valuable`] sub-type.
+///
+/// Implemented by [`Valuable`] types that have a list-like shape. This includes
+/// [`Vec`] and other Rust [collection] types. `Listable` types may or may not
+/// store items in contiguous memory. Any type that implements [`IntoIterator`]
+/// may implement `Listable`. Values that implement `Listable` must return
+/// [`Value::Listable`] from their [`Valuable::as_value`] implementation.
+///
+/// [collection]: https://doc.rust-lang.org/stable/std/collections/index.html
+///
+/// # Inspecting
+///
+/// Inspecting `Listable` items is done by visiting the collection. When
+/// visiting a `Listable`, contained values are either passed one-by-one by
+/// repeatedly calling [`visit_value()`] or all at once by calling
+/// [`visit_primitive_slice()`]. The [`visit_primitive_slice()`] method has
+/// lower overhead but can only be used when the `Listable` type contains
+/// primitive values.
+///
+/// See [`Visit`] documentation for more details.
+///
+/// # Implementing
+///
+/// If the type stores values in slices internally, then those slices are passed
+/// to [`Valuable::visit_slice`], which handles calling
+/// [`visit_primitive_slice()`] if possible.
+///
+/// [`visit_value()`]: Visit::visit_value
+/// [`visit_primitive_slice()`]: Visit::visit_primitive_slice
+///
+/// ```
+/// use valuable::{Listable, Valuable, Value, Visit};
+///
+/// struct MyCollection<T> {
+/// chunks: Vec<Vec<T>>,
+/// }
+///
+/// impl<T: Valuable> Valuable for MyCollection<T> {
+/// fn as_value(&self) -> Value<'_> {
+/// Value::Listable(self)
+/// }
+///
+/// fn visit(&self, visit: &mut dyn Visit) {
+/// for chunk in &self.chunks {
+/// // Handles visiting the slice
+/// Valuable::visit_slice(chunk, visit);
+/// }
+/// }
+/// }
+///
+/// impl<T: Valuable> Listable for MyCollection<T> {
+/// fn size_hint(&self) -> (usize, Option<usize>) {
+/// let len = self.chunks.iter().map(|chunk| chunk.len()).sum();
+/// (len, Some(len))
+/// }
+/// }
+/// ```
+pub trait Listable: Valuable {
+ /// Returns the bounds on the remaining length of the `Listable`.
+ ///
+ /// Specifically, `size_hint()` returns a tuple where the first element
+ /// is the lower bound, and the second element is the upper bound.
+ ///
+ /// The second half of the tuple that is returned is an [`Option`]`<`[`usize`]`>`.
+ /// A [`None`] here means that either there is no known upper bound, or the
+ /// upper bound is larger than [`usize`].
+ ///
+ /// # Implementation notes
+ ///
+ /// It is not enforced that a `Listable` implementation yields the declared
+ /// number of elements. A buggy iterator may yield less than the lower bound
+ /// or more than the upper bound of elements.
+ ///
+ /// `size_hint()` is primarily intended to be used for optimizations such as
+ /// reserving space for the elements of the `Listable`, but must not be
+ /// trusted to e.g., omit bounds checks in unsafe code. An incorrect
+ /// implementation of `size_hint()` should not lead to memory safety
+ /// violations.
+ ///
+ /// That said, the implementation should provide a correct estimation,
+ /// because otherwise it would be a violation of the trait's protocol.
+ ///
+ /// [`usize`]: type@usize
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// use valuable::Listable;
+ ///
+ /// let a = vec![1, 2, 3];
+ ///
+ /// assert_eq!((3, Some(3)), a.size_hint());
+ /// ```
+ fn size_hint(&self) -> (usize, Option<usize>);
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Listable> Listable for $ty {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ T::size_hint(&**self)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
+
+macro_rules! slice {
+ (
+ $(
+ $(#[$attrs:meta])*
+ ($($generics:tt)*) $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<$($generics)*> Valuable for $ty {
+ fn as_value(&self) -> Value<'_> {
+ Value::Listable(self as &dyn Listable)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ T::visit_slice(self, visit);
+ }
+ }
+
+ $(#[$attrs])*
+ impl<$($generics)*> Listable for $ty {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+ }
+ )*
+ };
+}
+
+slice! {
+ (T: Valuable) &'_ [T],
+ #[cfg(feature = "alloc")]
+ (T: Valuable) alloc::boxed::Box<[T]>,
+ #[cfg(feature = "alloc")]
+ (T: Valuable) alloc::rc::Rc<[T]>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ (T: Valuable) alloc::sync::Arc<[T]>,
+ (T: Valuable, const N: usize) [T; N],
+ #[cfg(feature = "alloc")]
+ (T: Valuable) alloc::vec::Vec<T>,
+}
+
+macro_rules! collection {
+ (
+ $(
+ $(#[$attrs:meta])*
+ ($($generics:tt)*) $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<$($generics)*> Valuable for $ty {
+ fn as_value(&self) -> Value<'_> {
+ Value::Listable(self as &dyn Listable)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ for value in self.iter() {
+ visit.visit_value(value.as_value());
+ }
+ }
+ }
+
+ $(#[$attrs])*
+ impl<$($generics)*> Listable for $ty {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+ }
+ )*
+ };
+}
+
+collection! {
+ #[cfg(feature = "alloc")]
+ (T: Valuable) alloc::collections::LinkedList<T>,
+ #[cfg(feature = "alloc")]
+ (T: Valuable + Ord) alloc::collections::BinaryHeap<T>,
+ #[cfg(feature = "alloc")]
+ (T: Valuable + Ord) alloc::collections::BTreeSet<T>,
+ #[cfg(feature = "std")]
+ (T: Valuable + Eq + std::hash::Hash, H: std::hash::BuildHasher) std::collections::HashSet<T, H>,
+}
+
+#[cfg(feature = "alloc")]
+impl<T: Valuable> Valuable for alloc::collections::VecDeque<T> {
+ fn as_value(&self) -> Value<'_> {
+ Value::Listable(self as &dyn Listable)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ let (first, second) = self.as_slices();
+ T::visit_slice(first, visit);
+ T::visit_slice(second, visit);
+ }
+}
+
+#[cfg(feature = "alloc")]
+impl<T: Valuable> Listable for alloc::collections::VecDeque<T> {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ (self.len(), Some(self.len()))
+ }
+}
+
+impl fmt::Debug for dyn Listable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ struct DebugListable<'a, 'b> {
+ fmt: fmt::DebugList<'a, 'b>,
+ }
+
+ impl Visit for DebugListable<'_, '_> {
+ fn visit_value(&mut self, value: Value<'_>) {
+ self.fmt.entry(&value);
+ }
+ }
+
+ let mut debug = DebugListable {
+ fmt: fmt.debug_list(),
+ };
+
+ self.visit(&mut debug);
+ debug.fmt.finish()
+ }
+}
diff --git a/vendor/valuable/src/mappable.rs b/vendor/valuable/src/mappable.rs
new file mode 100644
index 000000000..c7c30bf0b
--- /dev/null
+++ b/vendor/valuable/src/mappable.rs
@@ -0,0 +1,191 @@
+use crate::*;
+
+use core::fmt;
+
+/// A map-like [`Valuable`] sub-type.
+///
+/// Implemented by [`Valuable`] types that have a map-like shape. This includes
+/// [`HashMap`] and other Rust [collection] types. Values that implement
+/// `Mappable` must return [`Value::Mappable`] from their [`Value::as_value`]
+/// implementation.
+///
+/// [collection]: https://doc.rust-lang.org/stable/std/collections/index.html
+///
+/// # Inspecting
+///
+/// Inspecting `Mappable` entries is done by visiting the value. When visiting a
+/// `Mappable`, contained entries are passed one-by-one to the visitor by
+/// repeatedly calling [`visit_entry()`].
+///
+/// See [`Visit`] documentation for more details.
+///
+/// [`visit_entry()`]: Visit::visit_entry
+/// [`HashMap`]: std::collections::HashMap
+///
+/// # Implementing
+///
+/// Implementing `Mappable` for a custom map type. The map is represented using
+/// a `Vec` of key/value pairs.
+///
+/// ```
+/// use valuable::{Mappable, Valuable, Value, Visit};
+///
+/// struct MyMap<K, V> {
+/// entries: Vec<(K, V)>,
+/// }
+///
+/// impl<K: Valuable, V: Valuable> Valuable for MyMap<K, V> {
+/// fn as_value(&self) -> Value<'_> {
+/// Value::Mappable(self)
+/// }
+///
+/// fn visit(&self, visit: &mut dyn Visit) {
+/// for (k, v) in &self.entries {
+/// visit.visit_entry(k.as_value(), v.as_value());
+/// }
+/// }
+/// }
+///
+/// impl<K: Valuable, V: Valuable> Mappable for MyMap<K, V> {
+/// fn size_hint(&self) -> (usize, Option<usize>) {
+/// let len = self.entries.len();
+/// (len, Some(len))
+/// }
+/// }
+/// ```
+pub trait Mappable: Valuable {
+ /// Returns the bounds on the remaining length of the `Mappable`.
+ ///
+ /// Specifically, `size_hint()` returns a tuple where the first element is
+ /// the lower bound, and the second element is the upper bound.
+ ///
+ /// The second half of the tuple that is returned is an
+ /// [`Option`]`<`[`usize`]`>`. A [`None`] here means that either there is no
+ /// known upper bound, or the upper bound is larger than [`usize`].
+ ///
+ /// # Implementation notes
+ ///
+ /// It is not enforced that a `Mappable` implementation yields the declared
+ /// number of elements. A buggy implementation may yield less than the lower
+ /// bound or more than the upper bound of elements.
+ ///
+ /// `size_hint()` is primarily intended to be used for optimizations such as
+ /// reserving space for the elements of the `Mappable`, but must not be
+ /// trusted to e.g., omit bounds checks in unsafe code. An incorrect
+ /// implementation of `size_hint()` should not lead to memory safety
+ /// violations.
+ ///
+ /// That said, the implementation should provide a correct estimation,
+ /// because otherwise it would be a violation of the trait's protocol.
+ ///
+ /// [`usize`]: type@usize
+ ///
+ /// # Examples
+ ///
+ /// Basic usage:
+ ///
+ /// ```
+ /// use valuable::Mappable;
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("one", 1);
+ /// map.insert("two", 2);
+ /// map.insert("three", 3);
+ ///
+ /// assert_eq!((3, Some(3)), map.size_hint());
+ /// ```
+ fn size_hint(&self) -> (usize, Option<usize>);
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Mappable> Mappable for $ty {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ T::size_hint(&**self)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
+
+#[cfg(feature = "std")]
+impl<K: Valuable, V: Valuable> Valuable for std::collections::HashMap<K, V> {
+ fn as_value(&self) -> Value<'_> {
+ Value::Mappable(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ for (key, value) in self.iter() {
+ visit.visit_entry(key.as_value(), value.as_value());
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<K: Valuable, V: Valuable> Mappable for std::collections::HashMap<K, V> {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter().size_hint()
+ }
+}
+
+#[cfg(feature = "alloc")]
+impl<K: Valuable, V: Valuable> Valuable for alloc::collections::BTreeMap<K, V> {
+ fn as_value(&self) -> Value<'_> {
+ Value::Mappable(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ for (key, value) in self.iter() {
+ visit.visit_entry(key.as_value(), value.as_value());
+ }
+ }
+}
+
+#[cfg(feature = "alloc")]
+impl<K: Valuable, V: Valuable> Mappable for alloc::collections::BTreeMap<K, V> {
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter().size_hint()
+ }
+}
+
+impl fmt::Debug for dyn Mappable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ struct DebugMappable<'a, 'b> {
+ fmt: fmt::DebugMap<'a, 'b>,
+ }
+
+ impl Visit for DebugMappable<'_, '_> {
+ fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+ self.fmt.entry(&key, &value);
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {}
+ }
+
+ let mut debug = DebugMappable {
+ fmt: fmt.debug_map(),
+ };
+ self.visit(&mut debug);
+ debug.fmt.finish()
+ }
+}
diff --git a/vendor/valuable/src/named_values.rs b/vendor/valuable/src/named_values.rs
new file mode 100644
index 000000000..4f436522a
--- /dev/null
+++ b/vendor/valuable/src/named_values.rs
@@ -0,0 +1,222 @@
+use core::iter::{self, FusedIterator};
+
+use crate::field::*;
+use crate::*;
+
+/// Set of values from a `Structable` or `Enumerable` with named fields.
+#[derive(Debug)]
+pub struct NamedValues<'a> {
+ fields: &'a [NamedField<'a>],
+ values: &'a [Value<'a>],
+}
+
+impl<'a> NamedValues<'a> {
+ /// Create a new `NamedValues` instance.
+ ///
+ /// Both `fields` and `values` must be the same length.
+ ///
+ /// # Panics
+ ///
+ /// The method panics if `fields` and `values` are different lengths.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{NamedField, NamedValues, Value};
+ ///
+ /// let fields = [
+ /// NamedField::new("foo"),
+ /// NamedField::new("bar")
+ /// ];
+ /// let values = [
+ /// Value::U32(123),
+ /// Value::U32(456),
+ /// ];
+ ///
+ /// let named_values = NamedValues::new(&fields, &values);
+ ///
+ /// assert_eq!(
+ /// named_values.get(&fields[0]).unwrap().as_u32(),
+ /// Some(123));
+ /// ```
+ pub fn new(fields: &'a [NamedField<'a>], values: &'a [Value<'a>]) -> NamedValues<'a> {
+ assert!(
+ fields.len() == values.len(),
+ "`fields` and `values` must be the same length"
+ );
+ NamedValues { fields, values }
+ }
+
+ /// Get a value using a `NamedField` reference.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{NamedField, NamedValues, Value};
+ ///
+ /// let fields = [
+ /// NamedField::new("foo"),
+ /// NamedField::new("bar")
+ /// ];
+ /// let values = [
+ /// Value::U32(123),
+ /// Value::U32(456),
+ /// ];
+ ///
+ /// let named_values = NamedValues::new(&fields, &values);
+ ///
+ /// assert_eq!(
+ /// named_values.get(&fields[0]).unwrap().as_u32(),
+ /// Some(123));
+ /// ```
+ pub fn get(&self, field: &NamedField<'_>) -> Option<&Value<'_>> {
+ use core::mem;
+
+ let idx = (field as *const _ as usize - &self.fields[0] as *const _ as usize)
+ / mem::size_of::<NamedField<'_>>();
+ self.values.get(idx)
+ }
+
+ /// Get a value using string.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{NamedField, NamedValues, Value};
+ ///
+ /// let fields = [
+ /// NamedField::new("foo"),
+ /// NamedField::new("bar")
+ /// ];
+ /// let values = [
+ /// Value::U32(123),
+ /// Value::U32(456),
+ /// ];
+ ///
+ /// let named_values = NamedValues::new(&fields, &values);
+ ///
+ /// assert_eq!(
+ /// named_values.get_by_name("foo").unwrap().as_u32(),
+ /// Some(123));
+ /// ```
+ pub fn get_by_name(&self, name: impl AsRef<str>) -> Option<&Value<'_>> {
+ let name = name.as_ref();
+
+ for (index, field) in self.fields.iter().enumerate() {
+ if field.name() == name {
+ return Some(&self.values[index]);
+ }
+ }
+
+ None
+ }
+
+ /// Iterate all name-value pairs.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{NamedField, NamedValues, Value};
+ ///
+ /// let fields = [
+ /// NamedField::new("foo"),
+ /// NamedField::new("bar")
+ /// ];
+ /// let values = [
+ /// Value::U32(123),
+ /// Value::U32(456),
+ /// ];
+ ///
+ /// let named_values = NamedValues::new(&fields, &values);
+ ///
+ /// for (field, value) in named_values.iter() {
+ /// println!("{:?}: {:?}", field, value);
+ /// }
+ /// ```
+ pub fn iter<'b>(&'b self) -> Iter<'a, 'b> {
+ Iter {
+ iter: self.fields.iter().enumerate(),
+ values: self.values,
+ }
+ }
+
+ /// Returns the length of fields.
+ pub fn len(&self) -> usize {
+ self.fields.len()
+ }
+
+ /// Returns `true` if fields have a length of 0.
+ pub fn is_empty(&self) -> bool {
+ self.fields.is_empty()
+ }
+}
+
+impl<'a, 'b> IntoIterator for &'b NamedValues<'a> {
+ type Item = (&'b NamedField<'a>, &'b Value<'a>);
+ type IntoIter = Iter<'a, 'b>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.iter()
+ }
+}
+
+/// An iterator of name-value pairs contained by [`NamedValues`].
+///
+/// Instances are created by the [`iter()`][NamedValues::iter] method on
+/// [`NamedValues`]. See its documentation for more.
+///
+/// # Examples
+///
+/// ```
+/// use valuable::{NamedField, NamedValues, Value};
+///
+/// let fields = [
+/// NamedField::new("foo"),
+/// NamedField::new("bar")
+/// ];
+/// let values = [
+/// Value::U32(123),
+/// Value::U32(456),
+/// ];
+///
+/// let named_values = NamedValues::new(&fields, &values);
+///
+/// for (field, value) in named_values.iter() {
+/// println!("{:?}: {:?}", field, value);
+/// }
+/// ```
+#[derive(Debug)]
+pub struct Iter<'a, 'b> {
+ iter: iter::Enumerate<core::slice::Iter<'b, NamedField<'a>>>,
+ values: &'a [Value<'a>],
+}
+
+impl<'a, 'b> Iterator for Iter<'a, 'b> {
+ type Item = (&'b NamedField<'a>, &'b Value<'a>);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter
+ .next()
+ .map(move |(i, field)| (field, &self.values[i]))
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+}
+
+impl DoubleEndedIterator for Iter<'_, '_> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter
+ .next_back()
+ .map(move |(i, field)| (field, &self.values[i]))
+ }
+}
+
+impl ExactSizeIterator for Iter<'_, '_> {
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+}
+
+impl FusedIterator for Iter<'_, '_> {}
diff --git a/vendor/valuable/src/slice.rs b/vendor/valuable/src/slice.rs
new file mode 100644
index 000000000..a6ada6e67
--- /dev/null
+++ b/vendor/valuable/src/slice.rs
@@ -0,0 +1,428 @@
+use crate::*;
+
+use core::fmt;
+use core::iter::FusedIterator;
+
+macro_rules! slice {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $variant:ident($ty:ty),
+ )*
+ ) => {
+ /// A slice containing primitive values.
+ ///
+ /// The `Slice` enum is used to pass multiple primitive-values to the
+ /// [visitor][`Visit`]. This is used as an optimization when visiting
+ /// [`Listable`] types to avoid a dynamic dispatch call to [`Visit`] for
+ /// each element in the collection.
+ ///
+ /// `Slice` instances are usually not created explicitly. Instead, they
+ /// are created when calling [`Valuable::visit_slice()`].
+ #[non_exhaustive]
+ pub enum Slice<'a> {
+ $(
+ $(#[$attrs])*
+ $variant(&'a [$ty]),
+ )*
+ }
+
+ /// [`Slice`] iterator
+ ///
+ /// Instances are created by the [`iter()`][Slice::iter] method on
+ /// [`Slice`]. See its documentation for more.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
+ ///
+ /// for value in slice.iter() {
+ /// println!("{:?}", value);
+ /// }
+ /// ```
+ #[derive(Debug)]
+ pub struct Iter<'a>(IterKind<'a>);
+
+ #[derive(Debug)]
+ enum IterKind<'a> {
+ $(
+ $(#[$attrs])*
+ $variant(core::slice::Iter<'a, $ty>),
+ )*
+ }
+
+ impl<'a> Slice<'a> {
+ /// Returns the number of elements in the slice
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
+ /// assert_eq!(5, slice.len());
+ /// ```
+ pub fn len(&self) -> usize {
+ #[allow(unused_doc_comments)]
+ match self {
+ $(
+ $(#[$attrs])*
+ Slice::$variant(s) => s.len(),
+ )*
+ }
+ }
+
+
+ /// Returns `true` if the slice is not empty.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
+ /// assert!(!slice.is_empty());
+ /// ```
+ /// ```
+ /// # use valuable::Slice;
+ /// let slice = Slice::U32(&[]);
+ /// assert!(slice.is_empty());
+ /// ```
+ pub fn is_empty(&self) -> bool {
+ self.len() == 0
+ }
+
+ /// Returns an iterator over the slice.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let slice = Slice::U32(&[1, 1, 2, 3, 5]);
+ ///
+ /// for value in slice.iter() {
+ /// println!("{:?}", value);
+ /// }
+ /// ```
+ pub fn iter(&self) -> Iter<'a> {
+ self.into_iter()
+ }
+ }
+
+ impl<'a> IntoIterator for Slice<'a> {
+ type Item = Value<'a>;
+ type IntoIter = Iter<'a>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ (&self).into_iter()
+ }
+ }
+
+ impl<'a> IntoIterator for &'_ Slice<'a> {
+ type Item = Value<'a>;
+ type IntoIter = Iter<'a>;
+
+ fn into_iter(self) -> Self::IntoIter {
+ #[allow(unused_doc_comments)]
+ Iter(match self {
+ $(
+ $(#[$attrs])*
+ Slice::$variant(s) => IterKind::$variant(s.iter()),
+ )*
+ })
+ }
+ }
+
+ impl fmt::Debug for Slice<'_> {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use Slice::*;
+
+ let mut d = fmt.debug_list();
+
+ #[allow(unused_doc_comments)]
+ match *self {
+ $(
+ $(#[$attrs])*
+ $variant(v) => d.entries(v),
+ )*
+ };
+
+ d.finish()
+ }
+ }
+
+ impl<'a> Iterator for Iter<'a> {
+ type Item = Value<'a>;
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ use IterKind::*;
+
+ #[allow(unused_doc_comments)]
+ match &self.0 {
+ $(
+ $(#[$attrs])*
+ $variant(v) => v.size_hint(),
+ )*
+ }
+ }
+
+ fn next(&mut self) -> Option<Value<'a>> {
+ use IterKind::*;
+
+ #[allow(unused_doc_comments)]
+ match &mut self.0 {
+ $(
+ $(#[$attrs])*
+ $variant(v) => v.next().map(Valuable::as_value),
+ )*
+ }
+ }
+ }
+
+ impl DoubleEndedIterator for Iter<'_> {
+ fn next_back(&mut self) -> Option<Self::Item> {
+ use IterKind::*;
+
+ #[allow(unused_doc_comments)]
+ match &mut self.0 {
+ $(
+ $(#[$attrs])*
+ $variant(v) => v.next_back().map(Valuable::as_value),
+ )*
+ }
+ }
+ }
+
+ impl ExactSizeIterator for Iter<'_> {
+ fn len(&self) -> usize {
+ use IterKind::*;
+
+ #[allow(unused_doc_comments)]
+ match &self.0 {
+ $(
+ $(#[$attrs])*
+ $variant(v) => v.len(),
+ )*
+ }
+ }
+ }
+
+ impl FusedIterator for Iter<'_> {}
+ }
+}
+
+slice! {
+ /// A slice containing `bool` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Bool(&[true, true, false]);
+ /// ```
+ Bool(bool),
+
+ /// A slice containing `char` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Char(&['a', 'b', 'c']);
+ /// ```
+ Char(char),
+
+ /// A slice containing `f32` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::F32(&[3.1415, 2.71828]);
+ /// ```
+ F32(f32),
+
+ /// A slice containing `f64` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::F64(&[3.1415, 2.71828]);
+ /// ```
+ F64(f64),
+
+ /// A slice containing `i8` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::I8(&[1, 1, 2, 3, 5]);
+ /// ```
+ I8(i8),
+
+ /// A slice containing `i16` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::I16(&[1, 1, 2, 3, 5]);
+ /// ```
+ I16(i16),
+
+ /// A slice containing `I32` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::I32(&[1, 1, 2, 3, 5]);
+ /// ```
+ I32(i32),
+
+ /// A slice containing `I64` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::I64(&[1, 1, 2, 3, 5]);
+ /// ```
+ I64(i64),
+
+ /// A slice containing `I128` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::I128(&[1, 1, 2, 3, 5]);
+ /// ```
+ I128(i128),
+
+ /// A slice containing `isize` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Isize(&[1, 1, 2, 3, 5]);
+ /// ```
+ Isize(isize),
+
+ /// A slice containing `str` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Str(&["foo", "bar", "baz"]);
+ /// ```
+ Str(&'a str),
+
+ /// A slice containing `String` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::String(&["foo".to_string(), "bar".to_string()]);
+ /// ```
+ #[cfg(feature = "alloc")]
+ String(alloc::string::String),
+
+ /// A slice containing `u8` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::U8(&[1, 1, 2, 3, 5]);
+ /// ```
+ U8(u8),
+
+ /// A slice containing `u16` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::U16(&[1, 1, 2, 3, 5]);
+ /// ```
+ U16(u16),
+
+ /// A slice containing `u32` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::U32(&[1, 1, 2, 3, 5]);
+ /// ```
+ U32(u32),
+
+ /// A slice containing `u64` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::U64(&[1, 1, 2, 3, 5]);
+ /// ```
+ U64(u64),
+
+ /// A slice containing `u128` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::U128(&[1, 1, 2, 3, 5]);
+ /// ```
+ U128(u128),
+
+ /// A slice containing `usize` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Usize(&[1, 1, 2, 3, 5]);
+ /// ```
+ Usize(usize),
+
+ /// A slice containing `()` values.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Slice;
+ ///
+ /// let v = Slice::Unit(&[(), (), ()]);
+ /// ```
+ Unit(()),
+}
diff --git a/vendor/valuable/src/structable.rs b/vendor/valuable/src/structable.rs
new file mode 100644
index 000000000..611a7e58b
--- /dev/null
+++ b/vendor/valuable/src/structable.rs
@@ -0,0 +1,496 @@
+use crate::field::*;
+use crate::*;
+
+use core::fmt;
+
+/// A struct-like [`Valuable`] sub-type.
+///
+/// Implemented by [`Valuable`] types that have a struct-like shape. Fields may
+/// be named or unnamed (tuple). Values that implement `Structable` must return
+/// [`Value::Structable`] from their [`Valuable::as_value`] implementation.
+///
+/// # Inspecting
+///
+/// Inspecting fields contained by a `Structable` instance is done by visiting
+/// the struct. When visiting a `Structable`, either the `visit_named_fields()`
+/// or the `visit_unnamed_fields()` methods of `Visit` are called. Each method
+/// may be called multiple times per `Structable`, but the two methods are never
+/// mixed.
+///
+/// ```
+/// use valuable::{NamedValues, Valuable, Value, Visit};
+///
+/// #[derive(Valuable)]
+/// struct MyStruct {
+/// foo: u32,
+/// bar: u32,
+/// }
+///
+/// struct PrintFields;
+///
+/// impl Visit for PrintFields {
+/// fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+/// for (field, value) in named_values.iter() {
+/// println!("{}: {:?}", field.name(), value);
+/// }
+/// }
+///
+/// fn visit_value(&mut self, value: Value<'_>) {
+/// match value {
+/// Value::Structable(v) => v.visit(self),
+/// _ => {} // do nothing for other types
+/// }
+/// }
+/// }
+///
+/// let my_struct = MyStruct {
+/// foo: 123,
+/// bar: 456,
+/// };
+///
+/// valuable::visit(&my_struct, &mut PrintFields);
+/// ```
+///
+/// If the struct is **statically** defined, then all fields are known ahead of
+/// time and may be accessed via the [`StructDef`] instance returned by
+/// [`definition()`]. [`NamedField`] instances returned by [`definition()`]
+/// maybe used to efficiently extract specific field values.
+///
+/// # Implementing
+///
+/// Implementing `Structable` is usually done by adding `#[derive(Valuable)]` to
+/// a Rust `struct` definition.
+///
+/// ```
+/// use valuable::{Fields, Valuable, Structable, StructDef};
+///
+/// #[derive(Valuable)]
+/// struct MyStruct {
+/// foo: &'static str,
+/// }
+///
+/// let my_struct = MyStruct { foo: "Hello" };
+/// let fields = match my_struct.definition() {
+/// StructDef::Static { name, fields, .. } => {
+/// assert_eq!("MyStruct", name);
+/// fields
+/// }
+/// _ => unreachable!(),
+/// };
+///
+/// match fields {
+/// Fields::Named(named_fields) => {
+/// assert_eq!(1, named_fields.len());
+/// assert_eq!("foo", named_fields[0].name());
+/// }
+/// _ => unreachable!(),
+/// }
+/// ```
+///
+/// [`definition()`]: Structable::definition()
+pub trait Structable: Valuable {
+ /// Returns the struct's definition.
+ ///
+ /// See [`StructDef`] documentation for more details.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Structable, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// struct MyStruct {
+ /// foo: u32,
+ /// }
+ ///
+ /// let my_struct = MyStruct {
+ /// foo: 123,
+ /// };
+ ///
+ /// assert_eq!("MyStruct", my_struct.definition().name());
+ fn definition(&self) -> StructDef<'_>;
+}
+
+/// A struct's name, fields, and other struct-level information.
+///
+/// Returned by [`Structable::definition()`], `StructDef` provides the caller
+/// with information about the struct's definition.
+///
+/// [`Structable::definition()`]: Structable::definition
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum StructDef<'a> {
+ /// The struct is statically-defined, all fields are known ahead of time.
+ ///
+ /// Most `Structable` definitions for Rust struct types will be
+ /// `StructDef::Static`.
+ ///
+ /// # Examples
+ ///
+ /// A statically defined struct
+ ///
+ /// ```
+ /// use valuable::{Fields, Valuable, Structable, StructDef};
+ ///
+ /// #[derive(Valuable)]
+ /// struct MyStruct {
+ /// foo: &'static str,
+ /// }
+ ///
+ /// let my_struct = MyStruct { foo: "Hello" };
+ /// let fields = match my_struct.definition() {
+ /// StructDef::Static { name, fields, ..} => {
+ /// assert_eq!("MyStruct", name);
+ /// fields
+ /// }
+ /// _ => unreachable!(),
+ /// };
+ ///
+ /// match fields {
+ /// Fields::Named(named_fields) => {
+ /// assert_eq!(1, named_fields.len());
+ /// assert_eq!("foo", named_fields[0].name());
+ /// }
+ /// _ => unreachable!(),
+ /// }
+ /// ```
+ #[non_exhaustive]
+ Static {
+ /// The struct's name.
+ name: &'static str,
+
+ /// The struct's fields.
+ fields: Fields<'static>,
+ },
+
+ /// The struct is dynamically-defined, not all fields are known ahead of
+ /// time.
+ ///
+ /// A dynamically-defined struct **could** be represented using
+ /// [`Mappable`], though, using `Structable` offers benefits in a couple of
+ /// cases. For example, when serializing a `Value`, some formats will
+ /// serialize maps and structs differently. In this case, differentiating
+ /// the two is required. There also are times when **some** struct fields
+ /// are known statically, but not all of them (see second example).
+ ///
+ /// # Examples
+ ///
+ /// The struct stores field values in a `HashMap`.
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField, NamedValues, Structable, StructDef, Value, Valuable, Visit};
+ /// use std::collections::HashMap;
+ ///
+ /// /// A dynamic struct
+ /// struct Dyn {
+ /// // The struct name
+ /// name: String,
+ ///
+ /// // Named values.
+ /// values: HashMap<String, Box<dyn Valuable>>,
+ /// }
+ ///
+ /// impl Valuable for Dyn {
+ /// fn as_value(&self) -> Value<'_> {
+ /// Value::Structable(self)
+ /// }
+ ///
+ /// fn visit(&self, visit: &mut dyn Visit) {
+ /// // This could be optimized to batch some.
+ /// for (field, value) in self.values.iter() {
+ /// visit.visit_named_fields(&NamedValues::new(
+ /// &[NamedField::new(field)],
+ /// &[value.as_value()],
+ /// ));
+ /// }
+ /// }
+ /// }
+ ///
+ /// impl Structable for Dyn {
+ /// fn definition(&self) -> StructDef<'_> {
+ /// StructDef::new_dynamic(&self.name, Fields::Named(&[]))
+ /// }
+ /// }
+ /// ```
+ ///
+ /// Some fields are known statically.
+ ///
+ /// ```
+ /// use valuable::{Fields, NamedField, NamedValues, Structable, StructDef, Value, Valuable, Visit};
+ /// use std::collections::HashMap;
+ ///
+ /// struct HalfStatic {
+ /// foo: u32,
+ /// bar: u32,
+ /// extra_values: HashMap<String, Box<dyn Valuable>>,
+ /// }
+ ///
+ /// impl Valuable for HalfStatic {
+ /// fn as_value(&self) -> Value<'_> {
+ /// Value::Structable(self)
+ /// }
+ ///
+ /// fn visit(&self, visit: &mut dyn Visit) {
+ /// // First, visit static fields
+ /// visit.visit_named_fields(&NamedValues::new(
+ /// FIELDS,
+ /// &[self.foo.as_value(), self.bar.as_value()],
+ /// ));
+ ///
+ /// // This could be optimized to batch some.
+ /// for (field, value) in self.extra_values.iter() {
+ /// visit.visit_named_fields(&NamedValues::new(
+ /// &[NamedField::new(field)],
+ /// &[value.as_value()],
+ /// ));
+ /// }
+ /// }
+ /// }
+ ///
+ /// static FIELDS: &[NamedField<'static>] = &[
+ /// NamedField::new("foo"),
+ /// NamedField::new("bar"),
+ /// ];
+ ///
+ /// impl Structable for HalfStatic {
+ /// fn definition(&self) -> StructDef<'_> {
+ /// // Include known fields.
+ /// StructDef::new_dynamic(
+ /// "HalfStatic",
+ /// Fields::Named(FIELDS))
+ /// }
+ /// }
+ /// ```
+ #[non_exhaustive]
+ Dynamic {
+ /// The struct's name
+ name: &'a str,
+
+ /// The struct's fields.
+ fields: Fields<'a>,
+ },
+}
+
+impl fmt::Debug for dyn Structable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let def = self.definition();
+
+ if def.fields().is_named() {
+ struct DebugStruct<'a, 'b> {
+ fmt: fmt::DebugStruct<'a, 'b>,
+ }
+
+ let mut debug = DebugStruct {
+ fmt: fmt.debug_struct(def.name()),
+ };
+
+ impl Visit for DebugStruct<'_, '_> {
+ fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ for (field, value) in named_values {
+ self.fmt.field(field.name(), value);
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unreachable!()
+ }
+ }
+
+ self.visit(&mut debug);
+
+ debug.fmt.finish()
+ } else {
+ struct DebugStruct<'a, 'b> {
+ fmt: fmt::DebugTuple<'a, 'b>,
+ }
+
+ let mut debug = DebugStruct {
+ fmt: fmt.debug_tuple(def.name()),
+ };
+
+ impl Visit for DebugStruct<'_, '_> {
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ for value in values {
+ self.fmt.field(value);
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unreachable!();
+ }
+ }
+
+ self.visit(&mut debug);
+
+ debug.fmt.finish()
+ }
+ }
+}
+
+impl<'a> StructDef<'a> {
+ /// Create a new [`StructDef::Static`] instance.
+ ///
+ /// This should be used when a struct's fields are fixed and known ahead of time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_static("Foo", Fields::Unnamed(2));
+ /// ```
+ pub const fn new_static(name: &'static str, fields: Fields<'static>) -> StructDef<'a> {
+ StructDef::Static { name, fields }
+ }
+
+ /// Create a new [`StructDef::Dynamic`] instance.
+ ///
+ /// This is used when the struct's fields may vary at runtime.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_dynamic("Foo", Fields::Unnamed(3));
+ /// ```
+ pub const fn new_dynamic(name: &'a str, fields: Fields<'a>) -> StructDef<'a> {
+ StructDef::Dynamic { name, fields }
+ }
+
+ /// Returns the struct's name
+ ///
+ /// # Examples
+ ///
+ /// With a static struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_static("Foo", Fields::Unnamed(1));
+ /// assert_eq!("Foo", def.name());
+ /// ```
+ ///
+ /// With a dynamic struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_dynamic("Foo", Fields::Unnamed(2));
+ /// assert_eq!("Foo", def.name());
+ /// ```
+ pub const fn name(&self) -> &'a str {
+ match self {
+ StructDef::Static { name, .. } => name,
+ StructDef::Dynamic { name, .. } => name,
+ }
+ }
+
+ /// Returns the struct's fields
+ ///
+ /// # Examples
+ ///
+ /// With a static struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_static("Foo", Fields::Unnamed(3));
+ /// assert!(matches!(def.fields(), Fields::Unnamed(_)));
+ /// ```
+ ///
+ /// With a dynamic struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_dynamic("Foo", Fields::Unnamed(1));
+ /// assert!(matches!(def.fields(), Fields::Unnamed(_)));
+ /// ```
+ pub const fn fields(&self) -> &Fields<'a> {
+ match self {
+ StructDef::Static { fields, .. } => fields,
+ StructDef::Dynamic { fields, .. } => fields,
+ }
+ }
+
+ /// Returns `true` if the struct is [statically defined](StructDef::Static).
+ ///
+ /// # Examples
+ ///
+ /// With a static struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_static("Foo", Fields::Unnamed(2));
+ /// assert!(def.is_static());
+ /// ```
+ ///
+ /// With a dynamic struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_dynamic("Foo", Fields::Unnamed(4));
+ /// assert!(!def.is_static());
+ /// ```
+ pub const fn is_static(&self) -> bool {
+ matches!(self, StructDef::Static { .. })
+ }
+
+ /// Returns `true` if the struct is [dynamically defined](StructDef::Dynamic).
+ ///
+ /// # Examples
+ ///
+ /// With a static struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_static("Foo", Fields::Unnamed(1));
+ /// assert!(!def.is_dynamic());
+ /// ```
+ ///
+ /// With a dynamic struct
+ ///
+ /// ```
+ /// use valuable::{StructDef, Fields};
+ ///
+ /// let def = StructDef::new_dynamic("Foo", Fields::Unnamed(1));
+ /// assert!(def.is_dynamic());
+ /// ```
+ pub const fn is_dynamic(&self) -> bool {
+ matches!(self, StructDef::Dynamic { .. })
+ }
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Structable> Structable for $ty {
+ fn definition(&self) -> StructDef<'_> {
+ T::definition(&**self)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
diff --git a/vendor/valuable/src/tuplable.rs b/vendor/valuable/src/tuplable.rs
new file mode 100644
index 000000000..8c7169ff2
--- /dev/null
+++ b/vendor/valuable/src/tuplable.rs
@@ -0,0 +1,339 @@
+use crate::{Valuable, Value, Visit};
+
+use core::fmt;
+
+/// A tuple-like [`Valuable`] sub-type.
+///
+/// Implemented by [`Valuable`] types that have a tuple-like shape. Fields are
+/// always unnamed. Values that implement `Tuplable` must return
+/// [`Value::Tuplable`] from their [`Valuable::as_value`] implementation.
+///
+/// It is uncommon for users to implement this type as the crate provides
+/// implementations of `Tuplable` for Rust tuples.
+///
+/// # Inspecting
+///
+/// Inspecting fields contained by a `Tuplable` instance is done by visiting the
+/// tuple. When visiting a `Tuple`, the `visit_unnamed_fields()` method is
+/// called. When the tuple is statically defined, `visit_unnamed_fields()` is
+/// called once with the values of all the fields. A dynamic tuple
+/// implementation may call `visit_unnamed_fields()` multiple times.
+pub trait Tuplable: Valuable {
+ /// Returns the tuple's definition.
+ ///
+ /// See [`TupleDef`] documentation for more details.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Tuplable, TupleDef};
+ ///
+ /// let tuple = (123, "hello");
+ ///
+ /// if let TupleDef::Static { fields, .. } = tuple.definition() {
+ /// assert_eq!(2, fields);
+ /// }
+ /// ```
+ fn definition(&self) -> TupleDef;
+}
+
+/// The number of fields and other tuple-level information.
+///
+/// Returned by [`Tuplable::definition()`], `TupleDef` provides the caller with
+/// information about the tuple's definition.
+///
+/// This includes the number of fields contained by the tuple.
+#[derive(Debug)]
+#[non_exhaustive]
+pub enum TupleDef {
+ /// The tuple is statically-defined, all fields are known ahead of time.
+ ///
+ /// Static tuple implementations are provided by the crate.
+ ///
+ /// # Examples
+ ///
+ /// A statically defined tuple.
+ ///
+ /// ```
+ /// use valuable::{Tuplable, TupleDef};
+ ///
+ /// let tuple = (123, "hello");
+ ///
+ /// match tuple.definition() {
+ /// TupleDef::Static { fields, .. } => {
+ /// assert_eq!(2, fields);
+ /// }
+ /// _ => unreachable!(),
+ /// };
+ /// ```
+ #[non_exhaustive]
+ Static {
+ /// The number of fields contained by the tuple.
+ fields: usize,
+ },
+ /// The tuple is dynamically-defined, not all fields are known ahead of
+ /// time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Tuplable, TupleDef, Valuable, Value, Visit};
+ ///
+ /// struct MyTuple;
+ ///
+ /// impl Valuable for MyTuple {
+ /// fn as_value(&self) -> Value<'_> {
+ /// Value::Tuplable(self)
+ /// }
+ ///
+ /// fn visit(&self, visit: &mut dyn Visit) {
+ /// visit.visit_unnamed_fields(&[Value::I32(123)]);
+ /// visit.visit_unnamed_fields(&[Value::String("hello world")]);
+ /// }
+ /// }
+ ///
+ /// impl Tuplable for MyTuple {
+ /// fn definition(&self) -> TupleDef {
+ /// TupleDef::new_dynamic((1, Some(3)))
+ /// }
+ /// }
+ /// ```
+ #[non_exhaustive]
+ Dynamic {
+ /// Returns the bounds on the number of tuple fields.
+ ///
+ /// Specifically, the first element is the lower bound, and the second
+ /// element is the upper bound.
+ fields: (usize, Option<usize>),
+ },
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Tuplable> Tuplable for $ty {
+ fn definition(&self) -> TupleDef {
+ T::definition(&**self)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
+
+impl Tuplable for () {
+ fn definition(&self) -> TupleDef {
+ TupleDef::Static { fields: 0 }
+ }
+}
+
+macro_rules! tuple_impls {
+ (
+ $( $len:expr => ( $($n:tt $name:ident)+ ) )+
+ ) => {
+ $(
+ impl<$($name),+> Valuable for ($($name,)+)
+ where
+ $($name: Valuable,)+
+ {
+ fn as_value(&self) -> Value<'_> {
+ Value::Tuplable(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_unnamed_fields(&[
+ $(
+ self.$n.as_value(),
+ )+
+ ]);
+ }
+ }
+
+ impl<$($name),+> Tuplable for ($($name,)+)
+ where
+ $($name: Valuable,)+
+ {
+ fn definition(&self) -> TupleDef {
+ TupleDef::Static { fields: $len }
+ }
+ }
+ )+
+ }
+}
+
+tuple_impls! {
+ 1 => (0 T0)
+ 2 => (0 T0 1 T1)
+ 3 => (0 T0 1 T1 2 T2)
+ 4 => (0 T0 1 T1 2 T2 3 T3)
+ 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
+ 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
+ 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
+ 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
+ 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
+ 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
+ 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
+ 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
+ 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
+ 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
+ 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
+ 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
+}
+
+impl fmt::Debug for dyn Tuplable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ if self.definition().is_unit() {
+ ().fmt(fmt)
+ } else {
+ struct DebugTuple<'a, 'b> {
+ fmt: fmt::DebugTuple<'a, 'b>,
+ }
+
+ impl Visit for DebugTuple<'_, '_> {
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ for value in values {
+ self.fmt.field(value);
+ }
+ }
+
+ fn visit_value(&mut self, _: Value<'_>) {
+ unimplemented!()
+ }
+ }
+
+ let mut debug = DebugTuple {
+ fmt: fmt.debug_tuple(""),
+ };
+
+ self.visit(&mut debug);
+ debug.fmt.finish()
+ }
+ }
+}
+
+impl TupleDef {
+ /// Create a new [`TupleDef::Static`] instance
+ ///
+ /// This should be used when the tuple's fields are fixed and known ahead of time.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_static(2);
+ /// ```
+ pub const fn new_static(fields: usize) -> TupleDef {
+ TupleDef::Static { fields }
+ }
+
+ /// Create a new [`TupleDef::Dynamic`] instance.
+ ///
+ /// This is used when the tuple's fields may vary at runtime.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_dynamic((2, Some(10)));
+ /// ```
+ pub const fn new_dynamic(fields: (usize, Option<usize>)) -> TupleDef {
+ TupleDef::Dynamic { fields }
+ }
+
+ /// Returns `true` if `self` represents the [unit][primitive@unit] tuple.
+ ///
+ /// # Examples
+ ///
+ /// With the unit tuple
+ ///
+ /// ```
+ /// use valuable::Tuplable;
+ ///
+ /// let tuple: &dyn Tuplable = &();
+ /// assert!(tuple.definition().is_unit());
+ /// ```
+ ///
+ /// When not the unit tuple.
+ ///
+ /// ```
+ /// use valuable::Tuplable;
+ ///
+ /// let tuple: &dyn Tuplable = &(123,456);
+ /// assert!(!tuple.definition().is_unit());
+ /// ```
+ pub fn is_unit(&self) -> bool {
+ match *self {
+ TupleDef::Static { fields } => fields == 0,
+ TupleDef::Dynamic { fields } => fields == (0, Some(0)),
+ }
+ }
+
+ /// Returns `true` if the tuple is [statically defined](TupleDef::Static).
+ ///
+ /// # Examples
+ ///
+ /// With a static tuple
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_static(2);
+ /// assert!(def.is_static());
+ /// ```
+ ///
+ /// With a dynamic tuple
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_dynamic((2, None));
+ /// assert!(!def.is_static());
+ /// ```
+ pub fn is_static(&self) -> bool {
+ matches!(self, TupleDef::Static { .. })
+ }
+
+ /// Returns `true` if the tuple is [dynamically defined](TupleDef::Dynamic).
+ ///
+ /// # Examples
+ ///
+ /// With a static tuple
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_static(2);
+ /// assert!(!def.is_dynamic());
+ /// ```
+ ///
+ /// With a dynamic tuple
+ ///
+ /// ```
+ /// use valuable::TupleDef;
+ ///
+ /// let def = TupleDef::new_dynamic((2, None));
+ /// assert!(def.is_dynamic());
+ /// ```
+ pub fn is_dynamic(&self) -> bool {
+ matches!(self, TupleDef::Dynamic { .. })
+ }
+}
diff --git a/vendor/valuable/src/valuable.rs b/vendor/valuable/src/valuable.rs
new file mode 100644
index 000000000..e8fa5ddcf
--- /dev/null
+++ b/vendor/valuable/src/valuable.rs
@@ -0,0 +1,339 @@
+use crate::{Slice, Value, Visit};
+
+use core::fmt;
+use core::num::Wrapping;
+
+/// A type that can be converted to a [`Value`].
+///
+/// `Valuable` types are inspected by defining a [`Visit`] implementation and
+/// using it when calling [`Valuable::visit`]. See [`Visit`] documentation for
+/// more details.
+///
+/// The `Valuable` procedural macro makes implementing `Valuable` easy. Users
+/// can add add [`#[derive(Valuable)]`][macro] to their types.
+///
+/// `Valuable` provides implementations for many Rust primitives and standard
+/// library types.
+///
+/// Types implementing `Valuable` may also implement one of the more specific
+/// traits: [`Structable`], [`Enumerable`], [`Listable`], and [`Mappable`]. These traits
+/// should be implemented when the type is a nested container of other `Valuable` types.
+///
+/// [`Value`]: Value
+/// [`Visit`]: Visit
+/// [`Valuable::visit`]: Valuable::visit
+/// [`Structable`]: crate::Structable
+/// [`Enumerable`]: crate::Enumerable
+/// [`Listable`]: crate::Listable
+/// [`Mappable`]: crate::Mappable
+/// [macro]: macro@crate::Valuable
+pub trait Valuable {
+ /// Converts self into a [`Value`] instance.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Valuable;
+ ///
+ /// let _ = "hello".as_value();
+ /// ```
+ fn as_value(&self) -> Value<'_>;
+
+ /// Calls the relevant method on [`Visit`] to extract data from `self`.
+ ///
+ /// This method is used to extract type-specific data from the value and is
+ /// intended to be an implementation detail. For example, `Vec` implements
+ /// `visit` by calling [`visit_value()`] on each of its elements. Structs
+ /// implement `visit` by calling [`visit_named_fields()`] or
+ /// [`visit_unnamed_fields()`].
+ ///
+ /// Usually, users will call the [`visit`] function instead.
+ ///
+ /// [`Visit`]: Visit
+ /// [`visit`]: visit()
+ /// [`visit_value()`]: Visit::visit_value()
+ /// [`visit_named_fields()`]: Visit::visit_named_fields()
+ /// [`visit_unnamed_fields()`]: Visit::visit_unnamed_fields()
+ fn visit(&self, visit: &mut dyn Visit);
+
+ /// Calls [`Visit::visit_primitive_slice()`] with `self`.
+ ///
+ /// This method is an implementation detail used to optimize visiting
+ /// primitive slices.
+ ///
+ /// [`Visit::visit_primitive_slice()`]: Visit::visit_primitive_slice
+ fn visit_slice(slice: &[Self], visit: &mut dyn Visit)
+ where
+ Self: Sized,
+ {
+ for item in slice {
+ visit.visit_value(item.as_value());
+ }
+ }
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Valuable> Valuable for $ty {
+ fn as_value(&self) -> Value<'_> {
+ T::as_value(&**self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ T::visit(&**self, visit);
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &T,
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+ #[cfg(feature = "alloc")]
+ alloc::rc::Rc<T>,
+ #[cfg(not(valuable_no_atomic_cas))]
+ #[cfg(feature = "alloc")]
+ alloc::sync::Arc<T>,
+}
+
+macro_rules! valuable {
+ (
+ $(
+ $variant:ident($ty:ty),
+ )*
+ ) => {
+ $(
+ impl Valuable for $ty {
+ fn as_value(&self) -> Value<'_> {
+ Value::$variant(*self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(self.as_value());
+ }
+
+ fn visit_slice(slice: &[Self], visit: &mut dyn Visit)
+ where
+ Self: Sized,
+ {
+ visit.visit_primitive_slice(Slice::$variant(slice));
+ }
+ }
+ )*
+ };
+}
+
+valuable! {
+ Bool(bool),
+ Char(char),
+ F32(f32),
+ F64(f64),
+ I8(i8),
+ I16(i16),
+ I32(i32),
+ I64(i64),
+ I128(i128),
+ Isize(isize),
+ U8(u8),
+ U16(u16),
+ U32(u32),
+ U64(u64),
+ U128(u128),
+ Usize(usize),
+}
+
+macro_rules! nonzero {
+ (
+ $(
+ $variant:ident($ty:ident),
+ )*
+ ) => {
+ $(
+ impl Valuable for core::num::$ty {
+ fn as_value(&self) -> Value<'_> {
+ Value::$variant(self.get())
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(self.as_value());
+ }
+ }
+ )*
+ };
+}
+
+nonzero! {
+ I8(NonZeroI8),
+ I16(NonZeroI16),
+ I32(NonZeroI32),
+ I64(NonZeroI64),
+ I128(NonZeroI128),
+ Isize(NonZeroIsize),
+ U8(NonZeroU8),
+ U16(NonZeroU16),
+ U32(NonZeroU32),
+ U64(NonZeroU64),
+ U128(NonZeroU128),
+ Usize(NonZeroUsize),
+}
+
+#[cfg(not(valuable_no_atomic))]
+macro_rules! atomic {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $variant:ident($ty:ident),
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl Valuable for core::sync::atomic::$ty {
+ fn as_value(&self) -> Value<'_> {
+ // Use SeqCst to match Debug and serde which use SeqCst.
+ // https://github.com/rust-lang/rust/blob/1.52.1/library/core/src/sync/atomic.rs#L1361-L1366
+ // https://github.com/serde-rs/serde/issues/1496
+ Value::$variant(self.load(core::sync::atomic::Ordering::SeqCst))
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(self.as_value());
+ }
+ }
+ )*
+ };
+}
+
+#[cfg(not(valuable_no_atomic))]
+atomic! {
+ Bool(AtomicBool),
+ I8(AtomicI8),
+ I16(AtomicI16),
+ I32(AtomicI32),
+ #[cfg(not(valuable_no_atomic_64))]
+ I64(AtomicI64),
+ Isize(AtomicIsize),
+ U8(AtomicU8),
+ U16(AtomicU16),
+ U32(AtomicU32),
+ #[cfg(not(valuable_no_atomic_64))]
+ U64(AtomicU64),
+ Usize(AtomicUsize),
+}
+
+impl<T: Valuable> Valuable for Wrapping<T> {
+ fn as_value(&self) -> Value<'_> {
+ self.0.as_value()
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ self.0.visit(visit);
+ }
+}
+
+impl Valuable for () {
+ fn as_value(&self) -> Value<'_> {
+ Value::Tuplable(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_unnamed_fields(&[]);
+ }
+}
+
+impl<T: Valuable> Valuable for Option<T> {
+ fn as_value(&self) -> Value<'_> {
+ match self {
+ Some(v) => v.as_value(),
+ None => Value::Unit,
+ }
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(self.as_value());
+ }
+}
+
+impl Valuable for &'_ str {
+ fn as_value(&self) -> Value<'_> {
+ Value::String(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(Value::String(self));
+ }
+
+ fn visit_slice(slice: &[Self], visit: &mut dyn Visit)
+ where
+ Self: Sized,
+ {
+ visit.visit_primitive_slice(Slice::Str(slice));
+ }
+}
+
+#[cfg(feature = "alloc")]
+impl Valuable for alloc::string::String {
+ fn as_value(&self) -> Value<'_> {
+ Value::String(&self[..])
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(Value::String(self));
+ }
+
+ fn visit_slice(slice: &[Self], visit: &mut dyn Visit)
+ where
+ Self: Sized,
+ {
+ visit.visit_primitive_slice(Slice::String(slice));
+ }
+}
+
+#[cfg(feature = "std")]
+impl Valuable for &std::path::Path {
+ fn as_value(&self) -> Value<'_> {
+ Value::Path(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(Value::Path(self));
+ }
+}
+
+#[cfg(feature = "std")]
+impl Valuable for std::path::PathBuf {
+ fn as_value(&self) -> Value<'_> {
+ Value::Path(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(Value::Path(self));
+ }
+}
+
+#[cfg(feature = "std")]
+impl Valuable for dyn std::error::Error + 'static {
+ fn as_value(&self) -> Value<'_> {
+ Value::Error(self)
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(self.as_value());
+ }
+}
+
+impl fmt::Debug for dyn Valuable + '_ {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ let value = self.as_value();
+ value.fmt(fmt)
+ }
+}
diff --git a/vendor/valuable/src/value.rs b/vendor/valuable/src/value.rs
new file mode 100644
index 000000000..2db9cd10a
--- /dev/null
+++ b/vendor/valuable/src/value.rs
@@ -0,0 +1,877 @@
+use crate::{Enumerable, Listable, Mappable, Structable, Tuplable, Valuable, Visit};
+
+use core::fmt;
+
+macro_rules! value {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $variant:ident($ty:ty),
+ )*
+ ) => {
+ /// Any Rust value
+ ///
+ /// The `Value` enum is used to pass single values to the
+ /// [visitor][`Visit`]. Primitive types are enumerated and other types
+ /// are represented at trait objects.
+ ///
+ /// Values are converted to `Value` instances using
+ /// [`Valuable::as_value()`].
+ ///
+ /// # Examples
+ ///
+ /// Convert a primitive type
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// let num = 123;
+ /// let val = num.as_value();
+ ///
+ /// assert!(matches!(val, Value::I32(v) if v == 123));
+ /// ```
+ ///
+ /// Converting a struct
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// #[derive(Valuable, Debug)]
+ /// struct HelloWorld {
+ /// message: String,
+ /// }
+ ///
+ /// let hello = HelloWorld {
+ /// message: "greetings".to_string(),
+ /// };
+ ///
+ /// let val = hello.as_value();
+ ///
+ /// assert!(matches!(val, Value::Structable(_v)));
+ ///
+ /// // The Value `Debug` output matches the struct's
+ /// assert_eq!(
+ /// format!("{:?}", val),
+ /// format!("{:?}", hello),
+ /// );
+ /// ```
+ ///
+ /// [visitor]: Visit
+ #[non_exhaustive]
+ #[derive(Clone, Copy)]
+ pub enum Value<'a> {
+ $(
+ $(#[$attrs])*
+ $variant($ty),
+ )*
+
+ /// A Rust `()` or `None` value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::Unit;
+ /// ```
+ Unit,
+ }
+
+ $(
+ $(#[$attrs])*
+ impl<'a> From<$ty> for Value<'a> {
+ fn from(src: $ty) -> Value<'a> {
+ Value::$variant(src)
+ }
+ }
+ )*
+
+ impl<'a> From<()> for Value<'a> {
+ fn from(_: ()) -> Value<'a> {
+ Value::Tuplable(&())
+ }
+ }
+
+ impl fmt::Debug for Value<'_> {
+ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ use Value::*;
+
+ // Doc comments are expanded into the branch arms, which results
+ // in a warning. It isn't a big deal, so silence it.
+ #[allow(unused_doc_comments)]
+ match self {
+ $(
+ $(#[$attrs])*
+ $variant(v) => fmt::Debug::fmt(v, fmt),
+ )*
+ Unit => ().fmt(fmt),
+ }
+ }
+ }
+ }
+}
+
+value! {
+ /// A Rust `bool` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::Bool(true);
+ /// ```
+ Bool(bool),
+
+ /// A Rust `char` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::Char('h');
+ /// ```
+ Char(char),
+
+ /// A Rust `f32` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::F32(3.1415);
+ /// ```
+ F32(f32),
+
+ /// A Rust `f64` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::F64(3.1415);
+ /// ```
+ F64(f64),
+
+ /// A Rust `i8` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::I8(42);
+ /// ```
+ I8(i8),
+
+ /// A Rust `i16` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::I16(42);
+ /// ```
+ I16(i16),
+
+ /// A Rust `i32` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::I32(42);
+ /// ```
+ I32(i32),
+
+ /// A Rust `i64` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::I64(42);
+ /// ```
+ I64(i64),
+
+ /// A Rust `i128` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::I128(42);
+ /// ```
+ I128(i128),
+
+ /// A Rust `isize` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::Isize(42);
+ /// ```
+ Isize(isize),
+
+ /// A Rust `&str` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::String("hello");
+ /// ```
+ String(&'a str),
+
+ /// A Rust `u8` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::U8(42);
+ /// ```
+ U8(u8),
+
+ /// A Rust `u16` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::U16(42);
+ /// ```
+ U16(u16),
+
+ /// A Rust `u32` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::U32(42);
+ /// ```
+ U32(u32),
+
+ /// A Rust `u64` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::U64(42);
+ /// ```
+ U64(u64),
+
+ /// A Rust `u128` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::U128(42);
+ /// ```
+ U128(u128),
+
+ /// A Rust `usize` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let v = Value::Usize(42);
+ /// ```
+ Usize(usize),
+
+ /// A Rust `&Path` value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::path::Path;
+ ///
+ /// let path = Path::new("a.txt");
+ /// let v = Value::Path(path);
+ /// ```
+ #[cfg(feature = "std")]
+ Path(&'a std::path::Path),
+
+ /// A Rust error value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::io;
+ ///
+ /// let err: io::Error = io::ErrorKind::Other.into();
+ /// let v = Value::Error(&err);
+ /// ```
+ #[cfg(feature = "std")]
+ Error(&'a (dyn std::error::Error +'static)),
+
+ /// A Rust list value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let vals = vec![1, 2, 3, 4, 5];
+ /// let v = Value::Listable(&vals);
+ /// ```
+ Listable(&'a dyn Listable),
+
+ /// A Rust map value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("foo", 1);
+ /// map.insert("bar", 2);
+ ///
+ /// let v = Value::Mappable(&map);
+ /// ```
+ Mappable(&'a dyn Mappable),
+
+ /// A Rust struct value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// struct MyStruct {
+ /// field: u32,
+ /// }
+ ///
+ /// let my_struct = MyStruct {
+ /// field: 123,
+ /// };
+ ///
+ /// let v = Value::Structable(&my_struct);
+ /// ```
+ Structable(&'a dyn Structable),
+
+ /// A Rust enum value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum MyEnum {
+ /// Foo,
+ /// Bar,
+ /// }
+ ///
+ /// let my_enum = MyEnum::Foo;
+ /// let v = Value::Enumerable(&my_enum);
+ /// ```
+ Enumerable(&'a dyn Enumerable),
+
+ /// A tuple value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// let my_tuple = (123, 456);
+ /// let v = Value::Tuplable(&my_tuple);
+ /// ```
+ Tuplable(&'a dyn Tuplable),
+}
+
+impl Valuable for Value<'_> {
+ fn as_value(&self) -> Value<'_> {
+ *self
+ }
+
+ fn visit(&self, visit: &mut dyn Visit) {
+ visit.visit_value(*self);
+ }
+}
+
+impl Default for Value<'_> {
+ fn default() -> Self {
+ Value::Unit
+ }
+}
+
+macro_rules! convert {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty => $as:ident,
+ )*
+ ) => {
+ impl<'a> Value<'a> {
+ /// Return a `bool` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::Bool(true).as_bool(), Some(true));
+ /// assert_eq!(Value::Char('c').as_bool(), None);
+ /// ```
+ pub fn as_bool(&self) -> Option<bool> {
+ match *self {
+ Value::Bool(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `char` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::Char('c').as_char(), Some('c'));
+ /// assert_eq!(Value::Bool(true).as_char(), None);
+ /// ```
+ pub fn as_char(&self) -> Option<char> {
+ match *self {
+ Value::Char(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `f32` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::F32(3.1415).as_f32(), Some(3.1415));
+ /// assert_eq!(Value::Bool(true).as_f32(), None);
+ /// ```
+ pub fn as_f32(&self) -> Option<f32> {
+ match *self {
+ Value::F32(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `f64` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::F64(3.1415).as_f64(), Some(3.1415));
+ /// assert_eq!(Value::Bool(true).as_f64(), None);
+ /// ```
+ pub fn as_f64(&self) -> Option<f64> {
+ match *self {
+ Value::F64(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ $(
+ $(#[$attrs])*
+ pub fn $as(&self) -> Option<$ty> {
+ use Value::*;
+ use core::convert::TryInto;
+
+ match *self {
+ I8(v) => v.try_into().ok(),
+ I16(v) => v.try_into().ok(),
+ I32(v) => v.try_into().ok(),
+ I64(v) => v.try_into().ok(),
+ I128(v) => v.try_into().ok(),
+ Isize(v) => v.try_into().ok(),
+ U8(v) => v.try_into().ok(),
+ U16(v) => v.try_into().ok(),
+ U32(v) => v.try_into().ok(),
+ U64(v) => v.try_into().ok(),
+ U128(v) => v.try_into().ok(),
+ Usize(v) => v.try_into().ok(),
+ _ => None,
+ }
+ }
+ )*
+
+ /// Return a `&str` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::String("hello").as_str(), Some("hello"));
+ /// assert_eq!(Value::Bool(true).as_str(), None);
+ /// ```
+ pub fn as_str(&self) -> Option<&str> {
+ match *self {
+ Value::String(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&Path` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::path::Path;
+ ///
+ /// let path = Path::new("a.txt");
+ ///
+ /// assert!(Value::Path(path).as_path().is_some());
+ /// assert!(Value::Bool(true).as_path().is_none());
+ /// ```
+ #[cfg(feature = "std")]
+ pub fn as_path(&self) -> Option<&std::path::Path> {
+ match *self {
+ Value::Path(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&dyn Error` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::io;
+ ///
+ /// let err: io::Error = io::ErrorKind::Other.into();
+ ///
+ /// assert!(Value::Error(&err).as_error().is_some());
+ /// assert!(Value::Bool(true).as_error().is_none());
+ /// ```
+ #[cfg(feature = "std")]
+ pub fn as_error(&self) -> Option<&(dyn std::error::Error + 'static)> {
+ match *self {
+ Value::Error(v) => Some(v),
+ _ => None,
+ }
+ }
+
+
+ /// Return a `&dyn Listable` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let list = vec![1, 2, 3, 4];
+ ///
+ /// assert!(Value::Listable(&list).as_listable().is_some());
+ /// assert!(Value::Bool(true).as_listable().is_none());
+ /// ```
+ pub fn as_listable(&self) -> Option<&dyn Listable> {
+ match *self {
+ Value::Listable(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&dyn Mappable` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("foo", 123);
+ /// map.insert("bar", 456);
+ ///
+ /// assert!(Value::Mappable(&map).as_mappable().is_some());
+ /// assert!(Value::Bool(true).as_mappable().is_none());
+ /// ```
+ pub fn as_mappable(&self) -> Option<&dyn Mappable> {
+ match *self {
+ Value::Mappable(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&dyn Structable` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// struct Hello {
+ /// message: &'static str,
+ /// }
+ ///
+ /// let hello = Hello { message: "Hello world" };
+ ///
+ /// assert!(Value::Structable(&hello).as_structable().is_some());
+ /// assert!(Value::Bool(true).as_structable().is_none());
+ /// ```
+ pub fn as_structable(&self) -> Option<&dyn Structable> {
+ match *self {
+ Value::Structable(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&dyn Enumerable` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::{Value, Valuable};
+ ///
+ /// #[derive(Valuable)]
+ /// enum Greet {
+ /// Hello,
+ /// World,
+ /// }
+ ///
+ /// let greet = Greet::Hello;
+ ///
+ /// assert!(Value::Enumerable(&greet).as_enumerable().is_some());
+ /// assert!(Value::Bool(true).as_enumerable().is_none());
+ /// ```
+ pub fn as_enumerable(&self) -> Option<&dyn Enumerable> {
+ match *self {
+ Value::Enumerable(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// Return a `&dyn Tuplable` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// let my_tuple = (123, 456);
+ ///
+ /// assert!(Value::Tuplable(&my_tuple).as_tuplable().is_some());
+ /// assert!(Value::Bool(true).as_tuplable().is_none());
+ /// ```
+ pub fn as_tuplable(&self) -> Option<&dyn Tuplable> {
+ match *self {
+ Value::Tuplable(v) => Some(v),
+ _ => None,
+ }
+ }
+ }
+ }
+}
+
+convert! {
+ /// Return a `i8` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::I8(42).as_i8(), Some(42));
+ /// assert_eq!(Value::I32(42).as_i8(), Some(42));
+ ///
+ /// assert_eq!(Value::I64(i64::MAX).as_i8(), None);
+ /// assert_eq!(Value::Bool(true).as_i8(), None);
+ /// ```
+ i8 => as_i8,
+
+ /// Return a `i16` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::I16(42).as_i16(), Some(42));
+ /// assert_eq!(Value::I32(42).as_i16(), Some(42));
+ ///
+ /// assert_eq!(Value::I64(i64::MAX).as_i16(), None);
+ /// assert_eq!(Value::Bool(true).as_i16(), None);
+ /// ```
+ i16 => as_i16,
+
+ /// Return a `i32` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::I32(42).as_i32(), Some(42));
+ /// assert_eq!(Value::I64(42).as_i32(), Some(42));
+ ///
+ /// assert_eq!(Value::I64(i64::MAX).as_i32(), None);
+ /// assert_eq!(Value::Bool(true).as_i32(), None);
+ /// ```
+ i32 => as_i32,
+
+ /// Return a `i64` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::I64(42).as_i64(), Some(42));
+ /// assert_eq!(Value::I128(42).as_i64(), Some(42));
+ ///
+ /// assert_eq!(Value::I128(i128::MAX).as_i64(), None);
+ /// assert_eq!(Value::Bool(true).as_i64(), None);
+ /// ```
+ i64 => as_i64,
+
+ /// Return a `i128` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::I128(42).as_i128(), Some(42));
+ /// assert_eq!(Value::U128(42).as_i128(), Some(42));
+ ///
+ /// assert_eq!(Value::U128(u128::MAX).as_i128(), None);
+ /// assert_eq!(Value::Bool(true).as_i128(), None);
+ /// ```
+ i128 => as_i128,
+
+ /// Return a `isize` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::Isize(42).as_isize(), Some(42));
+ /// assert_eq!(Value::Usize(42).as_isize(), Some(42));
+ ///
+ /// assert_eq!(Value::Usize(usize::MAX).as_isize(), None);
+ /// assert_eq!(Value::Bool(true).as_isize(), None);
+ /// ```
+ isize => as_isize,
+
+ /// Return a `u8` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::U8(42).as_u8(), Some(42));
+ /// assert_eq!(Value::U32(42).as_u8(), Some(42));
+ ///
+ /// assert_eq!(Value::U32(u32::MAX).as_u8(), None);
+ /// assert_eq!(Value::Bool(true).as_u8(), None);
+ /// ```
+ u8 => as_u8,
+
+ /// Return a `u16` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::U16(42).as_u16(), Some(42));
+ /// assert_eq!(Value::U32(42).as_u16(), Some(42));
+ ///
+ /// assert_eq!(Value::U32(u32::MAX).as_u16(), None);
+ /// assert_eq!(Value::Bool(true).as_u16(), None);
+ /// ```
+ u16 => as_u16,
+
+ /// Return a `u32` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::U32(42).as_u32(), Some(42));
+ /// assert_eq!(Value::U64(42).as_u32(), Some(42));
+ ///
+ /// assert_eq!(Value::U64(u64::MAX).as_u32(), None);
+ /// assert_eq!(Value::Bool(true).as_u32(), None);
+ /// ```
+ u32 => as_u32,
+
+ /// Return a `u64` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::U64(42).as_u64(), Some(42));
+ /// assert_eq!(Value::U128(42).as_u64(), Some(42));
+ ///
+ /// assert_eq!(Value::U128(u128::MAX).as_u64(), None);
+ /// assert_eq!(Value::Bool(true).as_u64(), None);
+ /// ```
+ u64 => as_u64,
+
+ /// Return a `u128` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::U128(42).as_u128(), Some(42));
+ /// assert_eq!(Value::I32(42).as_u128(), Some(42));
+ ///
+ /// assert_eq!(Value::I32(-5).as_u128(), None);
+ /// assert_eq!(Value::Bool(true).as_u128(), None);
+ /// ```
+ u128 => as_u128,
+
+ /// Return a `usize` representation of `self`, if possible.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use valuable::Value;
+ ///
+ /// assert_eq!(Value::Usize(42).as_usize(), Some(42));
+ /// assert_eq!(Value::I8(42).as_usize(), Some(42));
+ ///
+ /// assert_eq!(Value::I8(-5).as_usize(), None);
+ /// assert_eq!(Value::Bool(true).as_usize(), None);
+ /// ```
+ usize => as_usize,
+}
diff --git a/vendor/valuable/src/visit.rs b/vendor/valuable/src/visit.rs
new file mode 100644
index 000000000..f91a04cad
--- /dev/null
+++ b/vendor/valuable/src/visit.rs
@@ -0,0 +1,459 @@
+use crate::*;
+
+/// Traverse a value's fields and variants.
+///
+/// Each method of the `Visit` trait is a hook that enables the implementor to
+/// observe value fields. By default, most methods are implemented as a no-op.
+/// The `visit_primitive_slice` default implementation will iterate the slice,
+/// calling `visit_value` with each item.
+///
+/// To recurse, the implementor must implement methods to visit the arguments.
+///
+/// # Examples
+///
+/// Recursively printing a Rust value.
+///
+/// ```
+/// use valuable::{NamedValues, Valuable, Value, Visit};
+///
+/// struct Print(String);
+///
+/// impl Print {
+/// fn indent(&self) -> Print {
+/// Print(format!("{} ", self.0))
+/// }
+/// }
+///
+/// impl Visit for Print {
+/// fn visit_value(&mut self, value: Value<'_>) {
+/// match value {
+/// Value::Structable(v) => {
+/// let def = v.definition();
+/// // Print the struct name
+/// println!("{}{}:", self.0, def.name());
+///
+/// // Visit fields
+/// let mut visit = self.indent();
+/// v.visit(&mut visit);
+/// }
+/// Value::Enumerable(v) => {
+/// let def = v.definition();
+/// let variant = v.variant();
+/// // Print the enum name
+/// println!("{}{}::{}:", self.0, def.name(), variant.name());
+///
+/// // Visit fields
+/// let mut visit = self.indent();
+/// v.visit(&mut visit);
+/// }
+/// Value::Listable(v) => {
+/// println!("{}", self.0);
+///
+/// // Visit fields
+/// let mut visit = self.indent();
+/// v.visit(&mut visit);
+/// }
+/// Value::Mappable(v) => {
+/// println!("{}", self.0);
+///
+/// // Visit fields
+/// let mut visit = self.indent();
+/// v.visit(&mut visit);
+/// }
+/// // Primitive or unknown type, just render Debug
+/// v => println!("{:?}", v),
+/// }
+/// }
+///
+/// fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+/// for (field, value) in named_values {
+/// print!("{}- {}: ", self.0, field.name());
+/// value.visit(self);
+/// }
+/// }
+///
+/// fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+/// for value in values {
+/// print!("{}- ", self.0);
+/// value.visit(self);
+/// }
+/// }
+///
+/// fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+/// print!("{}- {:?}: ", self.0, key);
+/// value.visit(self);
+/// }
+/// }
+///
+/// #[derive(Valuable)]
+/// struct Person {
+/// name: String,
+/// age: u32,
+/// addresses: Vec<Address>,
+/// }
+///
+/// #[derive(Valuable)]
+/// struct Address {
+/// street: String,
+/// city: String,
+/// zip: String,
+/// }
+///
+/// let person = Person {
+/// name: "Angela Ashton".to_string(),
+/// age: 31,
+/// addresses: vec![
+/// Address {
+/// street: "123 1st Ave".to_string(),
+/// city: "Townsville".to_string(),
+/// zip: "12345".to_string(),
+/// },
+/// Address {
+/// street: "555 Main St.".to_string(),
+/// city: "New Old Town".to_string(),
+/// zip: "55555".to_string(),
+/// },
+/// ],
+/// };
+///
+/// let mut print = Print("".to_string());
+/// valuable::visit(&person, &mut print);
+/// ```
+pub trait Visit {
+ /// Visit a single value.
+ ///
+ /// The `visit_value` method is called once when visiting single primitive
+ /// values. When visiting `Listable` types, the `visit_value` method is
+ /// called once per item in the listable type.
+ ///
+ /// Note, in the case of Listable types containing primitive types,
+ /// `visit_primitive_slice` can be implemented instead for less overhead.
+ ///
+ /// # Examples
+ ///
+ /// Visiting a single value.
+ ///
+ /// ```
+ /// use valuable::{Valuable, Visit, Value};
+ ///
+ /// struct Print;
+ ///
+ /// impl Visit for Print {
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// println!("{:?}", value);
+ /// }
+ /// }
+ ///
+ /// let my_val = 123;
+ /// my_val.visit(&mut Print);
+ /// ```
+ ///
+ /// Visiting multiple values in a list.
+ ///
+ /// ```
+ /// use valuable::{Valuable, Value, Visit};
+ ///
+ /// struct PrintList { comma: bool };
+ ///
+ /// impl Visit for PrintList {
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// match value {
+ /// Value::Listable(v) => v.visit(self),
+ /// value => {
+ /// if self.comma {
+ /// println!(", {:?}", value);
+ /// } else {
+ /// print!("{:?}", value);
+ /// self.comma = true;
+ /// }
+ /// }
+ /// }
+ /// }
+ /// }
+ ///
+ /// let my_list = vec![1, 2, 3, 4, 5];
+ /// valuable::visit(&my_list, &mut PrintList { comma: false });
+ /// ```
+ fn visit_value(&mut self, value: Value<'_>);
+
+ /// Visit a struct or enum's named fields.
+ ///
+ /// When the struct/enum is statically defined, all fields are known ahead
+ /// of time and `visit_named_fields` is called once with all field values.
+ /// When the struct/enum is dynamic, then the `visit_named_fields` method
+ /// may be called multiple times.
+ ///
+ /// See [`Structable`] and [`Enumerable`] for static vs. dynamic details.
+ ///
+ /// # Examples
+ ///
+ /// Visiting all fields in a struct.
+ ///
+ /// ```
+ /// use valuable::{NamedValues, Valuable, Value, Visit};
+ ///
+ /// #[derive(Valuable)]
+ /// struct MyStruct {
+ /// hello: String,
+ /// world: u32,
+ /// }
+ ///
+ /// struct Print;
+ ///
+ /// impl Visit for Print {
+ /// fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ /// for (field, value) in named_values {
+ /// println!("{:?}: {:?}", field, value);
+ /// }
+ /// }
+ ///
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// match value {
+ /// Value::Structable(v) => v.visit(self),
+ /// _ => {} // do nothing for other types
+ /// }
+ /// }
+ /// }
+ ///
+ /// let my_struct = MyStruct {
+ /// hello: "Hello world".to_string(),
+ /// world: 42,
+ /// };
+ ///
+ /// valuable::visit(&my_struct, &mut Print);
+ /// ```
+ fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ let _ = named_values;
+ }
+
+ /// Visit a struct or enum's unnamed fields.
+ ///
+ /// When the struct/enum is statically defined, all fields are known ahead
+ /// of time and `visit_unnamed_fields` is called once with all field values.
+ /// When the struct/enum is dynamic, then the `visit_unnamed_fields` method
+ /// may be called multiple times.
+ ///
+ /// See [`Structable`] and [`Enumerable`] for static vs. dynamic details.
+ ///
+ /// # Examples
+ ///
+ /// Visiting all fields in a struct.
+ ///
+ /// ```
+ /// use valuable::{Valuable, Value, Visit};
+ ///
+ /// #[derive(Valuable)]
+ /// struct MyStruct(String, u32);
+ ///
+ /// struct Print;
+ ///
+ /// impl Visit for Print {
+ /// fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ /// for value in values {
+ /// println!("{:?}", value);
+ /// }
+ /// }
+ ///
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// match value {
+ /// Value::Structable(v) => v.visit(self),
+ /// _ => {} // do nothing for other types
+ /// }
+ /// }
+ /// }
+ ///
+ /// let my_struct = MyStruct("Hello world".to_string(), 42);
+ ///
+ /// valuable::visit(&my_struct, &mut Print);
+ /// ```
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ let _ = values;
+ }
+
+ /// Visit a primitive slice.
+ ///
+ /// This method exists as an optimization when visiting [`Listable`] types.
+ /// By default, `Listable` types are visited by passing each item to
+ /// `visit_value`. However, if the listable stores a **primitive** type
+ /// within contiguous memory, then `visit_primitive_slice` is called
+ /// instead.
+ ///
+ /// When implementing `visit_primitive_slice`, be aware that the method may
+ /// be called multiple times for a single `Listable` type.
+ ///
+ /// # Examples
+ ///
+ /// A vec calls `visit_primitive_slice` one time, but a `VecDeque` will call
+ /// `visit_primitive_slice` twice.
+ ///
+ /// ```
+ /// use valuable::{Valuable, Value, Visit, Slice};
+ /// use std::collections::VecDeque;
+ ///
+ /// struct Count(u32);
+ ///
+ /// impl Visit for Count {
+ /// fn visit_primitive_slice(&mut self, slice: Slice<'_>) {
+ /// self.0 += 1;
+ /// }
+ ///
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// match value {
+ /// Value::Listable(v) => v.visit(self),
+ /// _ => {} // do nothing for other types
+ /// }
+ /// }
+ /// }
+ ///
+ /// let vec = vec![1, 2, 3, 4, 5];
+ ///
+ /// let mut count = Count(0);
+ /// valuable::visit(&vec, &mut count);
+ /// assert_eq!(1, count.0);
+ ///
+ /// let mut vec_deque = VecDeque::from(vec);
+ ///
+ /// let mut count = Count(0);
+ /// valuable::visit(&vec_deque, &mut count);
+ ///
+ /// assert_eq!(2, count.0);
+ /// ```
+ fn visit_primitive_slice(&mut self, slice: Slice<'_>) {
+ for value in slice {
+ self.visit_value(value);
+ }
+ }
+
+ /// Visit a `Mappable`'s entries.
+ ///
+ /// The `visit_entry` method is called once for each entry contained by a
+ /// `Mappable.`
+ ///
+ /// # Examples
+ ///
+ /// Visit a map's entries
+ ///
+ /// ```
+ /// use valuable::{Valuable, Value, Visit};
+ /// use std::collections::HashMap;
+ ///
+ /// let mut map = HashMap::new();
+ /// map.insert("hello", 123);
+ /// map.insert("world", 456);
+ ///
+ /// struct Print;
+ ///
+ /// impl Visit for Print {
+ /// fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+ /// println!("{:?} => {:?}", key, value);
+ /// }
+ ///
+ /// fn visit_value(&mut self, value: Value<'_>) {
+ /// match value {
+ /// Value::Mappable(v) => v.visit(self),
+ /// _ => {} // do nothing for other types
+ /// }
+ /// }
+ /// }
+ ///
+ /// valuable::visit(&map, &mut Print);
+ /// ```
+ fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+ let _ = (key, value);
+ }
+}
+
+macro_rules! deref {
+ (
+ $(
+ $(#[$attrs:meta])*
+ $ty:ty,
+ )*
+ ) => {
+ $(
+ $(#[$attrs])*
+ impl<T: ?Sized + Visit> Visit for $ty {
+ fn visit_value(&mut self, value: Value<'_>) {
+ T::visit_value(&mut **self, value)
+ }
+
+ fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+ T::visit_named_fields(&mut **self, named_values)
+ }
+
+ fn visit_unnamed_fields(&mut self, values: &[Value<'_>]) {
+ T::visit_unnamed_fields(&mut **self, values)
+ }
+
+ fn visit_primitive_slice(&mut self, slice: Slice<'_>) {
+ T::visit_primitive_slice(&mut **self, slice)
+ }
+
+ fn visit_entry(&mut self, key: Value<'_>, value: Value<'_>) {
+ T::visit_entry(&mut **self, key, value)
+ }
+ }
+ )*
+ };
+}
+
+deref! {
+ &mut T,
+ #[cfg(feature = "alloc")]
+ alloc::boxed::Box<T>,
+}
+
+/// Inspects a value by calling the relevant [`Visit`] methods with `value`'s
+/// data.
+///
+/// This method calls [`Visit::visit_value()`] with the provided [`Valuable`]
+/// instance. See [`Visit`] documentation for more details.
+///
+/// # Examples
+///
+/// Extract a single field from a struct. Note: if the same field is repeatedly
+/// extracted from a struct, it is preferable to obtain the associated
+/// [`NamedField`] once and use it repeatedly.
+///
+/// ```
+/// use valuable::{NamedValues, Valuable, Value, Visit};
+///
+/// #[derive(Valuable)]
+/// struct MyStruct {
+/// foo: usize,
+/// bar: usize,
+/// }
+///
+/// struct GetFoo(usize);
+///
+/// impl Visit for GetFoo {
+/// fn visit_named_fields(&mut self, named_values: &NamedValues<'_>) {
+/// if let Some(foo) = named_values.get_by_name("foo") {
+/// if let Some(val) = foo.as_usize() {
+/// self.0 = val;
+/// }
+/// }
+/// }
+///
+/// fn visit_value(&mut self, value: Value<'_>) {
+/// if let Value::Structable(v) = value {
+/// v.visit(self);
+/// }
+/// }
+/// }
+///
+/// let my_struct = MyStruct {
+/// foo: 123,
+/// bar: 456,
+/// };
+///
+/// let mut get_foo = GetFoo(0);
+/// valuable::visit(&my_struct, &mut get_foo);
+///
+/// assert_eq!(123, get_foo.0);
+/// ```
+///
+/// [`Visit`]: Visit [`NamedField`]: crate::NamedField
+pub fn visit(value: &impl Valuable, visit: &mut dyn Visit) {
+ visit.visit_value(value.as_value());
+}