--- a/.cargo/config.in
+++ b/.cargo/config.in
@@ -4,15 +4,15 @@
# taskcluster/scripts/builder/build-sm-rust-bindings.sh
[source.crates-io]
registry = 'https://github.com/rust-lang/crates.io-index'
replace-with = 'vendored-sources'
[source."https://github.com/servo/serde"]
git = "https://github.com/servo/serde"
-branch = "deserialize_from_enums6"
+branch = "deserialize_from_enums7"
replace-with = "vendored-sources"
[source.vendored-sources]
directory = '@top_srcdir@/third_party/rust'
@WIN64_CARGO_LINKER_CONFIG@
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -26,17 +26,17 @@ version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "app_units"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayvec"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -84,18 +84,18 @@ dependencies = [
"cubeb 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"error-chain 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
"futures 0.1.18 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.37 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.58 (git+https://github.com/servo/serde?branch=deserialize_from_enums7)",
"tokio-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"tokio-uds 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "audioipc-client"
version = "0.4.0"
@@ -143,17 +143,17 @@ version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bincode"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bindgen"
version = "0.33.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -573,18 +573,18 @@ source = "registry+https://github.com/ru
[[package]]
name = "docopt"
version = "0.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.37 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.58 (git+https://github.com/servo/serde?branch=deserialize_from_enums7)",
"strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "dtoa"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -600,18 +600,18 @@ dependencies = [
name = "dwrote"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.39 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.37 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.58 (git+https://github.com/servo/serde?branch=deserialize_from_enums7)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -664,17 +664,17 @@ version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "euclid"
version = "0.17.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "fallible"
version = "0.0.1"
dependencies = [
"hashglobe 0.1.0",
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1008,18 +1008,18 @@ dependencies = [
"docopt 0.8.3 (registry+https://github.com/rust-lang/crates.io-index)",
"ena 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"itertools 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop-snap 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lalrpop-util 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
"petgraph 0.4.11 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.37 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.58 (git+https://github.com/servo/serde?branch=deserialize_from_enums7)",
"string_cache 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lalrpop-intern"
version = "0.15.1"
@@ -1619,17 +1619,17 @@ name = "quote"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "quote"
-version = "0.5.1"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
version = "0.3.18"
@@ -1702,17 +1702,17 @@ dependencies = [
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "ron"
version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rsdparsa"
version = "0.1.0"
[[package]]
name = "rsdparsa_capi"
@@ -1791,47 +1791,37 @@ dependencies = [
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
-version = "1.0.37"
+version = "1.0.58"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde_derive 1.0.37 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)",
+ "serde_derive 1.0.58 (git+https://github.com/servo/serde?branch=deserialize_from_enums7)",
]
[[package]]
name = "serde_bytes"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive"
-version = "1.0.37"
-source = "git+https://github.com/servo/serde?branch=deserialize_from_enums6#b8d39b013bec85b6146dfb1061e0e8fc55e99b5e"
+version = "1.0.58"
+source = "git+https://github.com/servo/serde?branch=deserialize_from_enums7#884e8078a9c74314fa4a5a2e6ce4ac67ab8fa415"
dependencies = [
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.23.0 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)",
- "syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "serde_derive_internals"
-version = "0.23.0"
-source = "git+https://github.com/servo/serde?branch=deserialize_from_enums6#b8d39b013bec85b6146dfb1061e0e8fc55e99b5e"
-dependencies = [
- "proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "servo_arc"
version = "0.1.1"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1876,17 +1866,17 @@ source = "registry+https://github.com/ru
name = "string_cache"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"debug_unreachable 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
"precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "string_cache_codegen"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2013,17 +2003,17 @@ dependencies = [
]
[[package]]
name = "syn"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "synstructure"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
@@ -2143,17 +2133,17 @@ dependencies = [
"tokio-io 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "toml"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "traitobject"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -2336,17 +2326,17 @@ dependencies = [
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
"plane-split 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"ron 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
"webrender_api 0.57.2",
]
[[package]]
name = "webrender_api"
@@ -2355,19 +2345,19 @@ dependencies = [
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.13.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
"euclid 0.17.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.37 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)",
+ "serde_derive 1.0.58 (git+https://github.com/servo/serde?branch=deserialize_from_enums7)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "webrender_bindings"
version = "0.1.0"
dependencies = [
"app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2472,17 +2462,17 @@ dependencies = [
"xpcom 0.1.0",
]
[[package]]
name = "xpcom_macros"
version = "0.1.0"
dependencies = [
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"syn 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "yaml-rust"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
@@ -2654,17 +2644,17 @@ dependencies = [
"checksum podio 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e5422a1ee1bc57cc47ae717b0137314258138f38fd5f3cea083f43a9725383a0"
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
"checksum proc-macro2 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d1cb7aaaa4bf022ec2b14ff2f2ba1643a22f3cee88df014a85e14b392282c61d"
"checksum proc-macro2 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "49b6a521dc81b643e9a51e0d1cf05df46d5a2f3c0280ea72bcb68276ba64a118"
"checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
"checksum quick-error 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eda5fe9b71976e62bc81b781206aaa076401769b2143379d3eb2118388babac4"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum quote 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1eca14c727ad12702eb4b6bfb5a232287dcf8385cb8ca83a3eeaf6519c44c408"
-"checksum quote 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"
+"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
"checksum rayon 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "485541959c8ecc49865526fe6c4de9653dd6e60d829d6edf0be228167b60372d"
"checksum rayon-core 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9d24ad214285a7729b174ed6d3bcfcb80177807f959d95fafd5bfc5c4f201ac8"
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "75ecf88252dce580404a22444fc7d626c01815debba56a7f4f536772a5ff19d3"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum regex-syntax 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8f1ac0f60d675cc6cf13a20ec076568254472551051ad5dd050364d70671bf6b"
@@ -2673,20 +2663,19 @@ dependencies = [
"checksum rust-ini 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "22dab655e8122ccb15db25a56852ce62506f1486cdefd37e86371bf34ea8f601"
"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
"checksum scoped-tls 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f417c22df063e9450888a7561788e9bd46d3bb3c1466435b4eccb903807f147d"
"checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
-"checksum serde 1.0.37 (registry+https://github.com/rust-lang/crates.io-index)" = "d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645"
+"checksum serde 1.0.58 (registry+https://github.com/rust-lang/crates.io-index)" = "34e9df8efbe7a2c12ceec1fc8744d56ae3374d8ae325f4a0028949d16433d554"
"checksum serde_bytes 0.10.4 (registry+https://github.com/rust-lang/crates.io-index)" = "adb6e51a6b3696b301bc221d785f898b4457c619b51d7ce195a6d20baecb37b3"
-"checksum serde_derive 1.0.37 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)" = "<none>"
-"checksum serde_derive_internals 0.23.0 (git+https://github.com/servo/serde?branch=deserialize_from_enums6)" = "<none>"
+"checksum serde_derive 1.0.58 (git+https://github.com/servo/serde?branch=deserialize_from_enums7)" = "<none>"
"checksum simd 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3dd0805c7363ab51a829a1511ad24b6ed0349feaa756c4bc2f977f9f496e6673"
"checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
"checksum smallbitvec 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "665fbc8384f961eb55c548daa2a4b1efff1f9d03b7a10f162ac6ad6a781ca966"
"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
"checksum string_cache 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39cb4173bcbd1319da31faa5468a7e3870683d7a237150b0b0aaafd546f6ad12"
"checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7"
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -54,9 +54,9 @@ panic = "abort"
opt-level = 2
rpath = false
debug-assertions = false
panic = "abort"
codegen-units = 1
[patch.crates-io]
libudev-sys = { path = "dom/webauthn/libudev-sys" }
-serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums6" }
+serde_derive = { git = "https://github.com/servo/serde", branch = "deserialize_from_enums7" }
--- a/third_party/rust/quote/.cargo-checksum.json
+++ b/third_party/rust/quote/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"693459089a22ff7249a6bc2e6e9a7fd0b2413a67d91872b4d635159f6da0f998","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"bdb5b5375e8cd37b75b4e0269b8fa9fb22776df9762c1df11ec88eb4cd2dc097","src/lib.rs":"05bc9cac79ba5e0084876e37b49178e7147b351786552e464d2beafd1ee84243","src/to_tokens.rs":"77287ca901b02f988b208f5138dc70bea03473cca37e3014f901320a34e8974b","src/tokens.rs":"a4939fc092d6466d5a2e75474886152e880586b12e057c0d7bf7b3f22428b2de","tests/test.rs":"35bac59a637a8dc3919df51bfa0957b6f964f408cc63c7a81a3e759ab8557f55"},"package":"7b0ff51282f28dc1b53fd154298feaa2e77c5ea0dba68e1fd8b03b72fbe13d2a"}
\ No newline at end of file
+{"files":{"Cargo.toml":"8078663280ca2bbda17459a3c2629b84aee2b9904a83f83b87f1bf60e096692f","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"c9a75f18b9ab2927829a208fc6aa2cf4e63b8420887ba29cdb265d6619ae82d5","README.md":"bdb5b5375e8cd37b75b4e0269b8fa9fb22776df9762c1df11ec88eb4cd2dc097","src/lib.rs":"7f72accca88679bc49cc8aedf7d96c922288e66a3d63bf1d06f5da262f02a4ad","src/to_tokens.rs":"6eb18c100701d1f9556cd21b1f2faca3316e85029345274dcfe7691e7ffa254d","src/tokens.rs":"a4939fc092d6466d5a2e75474886152e880586b12e057c0d7bf7b3f22428b2de","tests/test.rs":"35bac59a637a8dc3919df51bfa0957b6f964f408cc63c7a81a3e759ab8557f55"},"package":"9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"}
\ No newline at end of file
--- a/third_party/rust/quote/Cargo.toml
+++ b/third_party/rust/quote/Cargo.toml
@@ -7,17 +7,17 @@
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "quote"
-version = "0.5.1"
+version = "0.5.2"
authors = ["David Tolnay <dtolnay@gmail.com>"]
include = ["Cargo.toml", "src/**/*.rs", "tests/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
description = "Quasi-quoting macro quote!(...)"
documentation = "https://docs.rs/quote/"
readme = "README.md"
keywords = ["syn"]
license = "MIT/Apache-2.0"
repository = "https://github.com/dtolnay/quote"
--- a/third_party/rust/quote/src/lib.rs
+++ b/third_party/rust/quote/src/lib.rs
@@ -86,17 +86,17 @@
//! ## Recursion limit
//!
//! The `quote!` macro relies on deep recursion so some large invocations may
//! fail with "recursion limit reached" when you compile. If it fails, bump up
//! the recursion limit by adding `#![recursion_limit = "128"]` to your crate.
//! An even higher limit may be necessary for especially large invocations.
// Quote types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/quote/0.5.1")]
+#![doc(html_root_url = "https://docs.rs/quote/0.5.2")]
#[cfg(feature = "proc-macro")]
extern crate proc_macro;
extern crate proc_macro2;
mod tokens;
pub use tokens::Tokens;
--- a/third_party/rust/quote/src/to_tokens.rs
+++ b/third_party/rust/quote/src/to_tokens.rs
@@ -1,13 +1,13 @@
use super::Tokens;
use std::borrow::Cow;
-use proc_macro2::{Literal, Span, Term, TokenStream, TokenTree};
+use proc_macro2::{Group, Literal, Op, Span, Term, TokenStream, TokenTree};
/// Types that can be interpolated inside a [`quote!`] invocation.
///
/// [`quote!`]: macro.quote.html
pub trait ToTokens {
/// Write `self` to the given `Tokens`.
///
/// Example implementation for a struct representing Rust paths like
@@ -137,22 +137,34 @@ impl ToTokens for char {
impl ToTokens for bool {
fn to_tokens(&self, tokens: &mut Tokens) {
let word = if *self { "true" } else { "false" };
tokens.append(Term::new(word, Span::call_site()));
}
}
+impl ToTokens for Group {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append(self.clone());
+ }
+}
+
impl ToTokens for Term {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append(self.clone());
}
}
+impl ToTokens for Op {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ tokens.append(self.clone());
+ }
+}
+
impl ToTokens for Literal {
fn to_tokens(&self, tokens: &mut Tokens) {
tokens.append(self.clone());
}
}
impl ToTokens for TokenTree {
fn to_tokens(&self, dst: &mut Tokens) {
--- a/third_party/rust/serde/.cargo-checksum.json
+++ b/third_party/rust/serde/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"9f887308fedf41ae7ebb25832a4d47e8a231f7eb0f84abf2bc395de82b7194d5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"16de77b2d10fac8c70219ba183ad083ae12d4553c6f3213dec39d9936622b371","src/de/from_primitive.rs":"b254035b88fdfe97c22198b7ce7c1a0e27a539fff723205d405146a3fb8d10c4","src/de/ignored_any.rs":"864eaefef0aaae36daf0c2bdee08165dabbf60710f3217142d5e280c0a35c1fe","src/de/impls.rs":"ff23fa9da794debd1ec245f6af2b0c695c54683b02e4b4048642299722009aa5","src/de/mod.rs":"e020b1f027d9e552ff024b44379e87969decf96e4c6cef0e2e7827e2dc4f56c3","src/de/utf8.rs":"956b124b7ce98353cb781b56e43a6fed2e67f1389d35b7a468d5be75b1485853","src/de/value.rs":"d59160ab42411da0e125cb40e05453612f9733684199c4b100ab7af7042dd7ad","src/export.rs":"dd08253f225862aa5009b27900e04187480c96562c35205b71b36b2ac64c4cce","src/lib.rs":"77489f97b4d2fb2ea62c3aba7450a407211a6fa342d1066268b473d9c708762c","src/macros.rs":"e1d542b1dac2c1d1f9d5ada7cc5b6639767fc67851421cc3adfb942a7cf750b6","src/private/de.rs":"3602a9d56d72543108c6da106301c3da99968deac3163b86cd9b89f7e5e8b4a3","src/private/macros.rs":"6861a4f332ea24d0ed5db1c28fe3105d2716523902f045c0bbbd439ebf9e44de","src/private/mod.rs":"0c774d86042cefdb447857070a1d4d2c0b9f519a7f5db588a1e7fcc16ca5a511","src/private/ser.rs":"a45b683bc438741644c454fdad637dc62fff6c4e7516ab877609b81bc74e24a7","src/ser/impls.rs":"a7a958b3d5644dff059a7797521a788db3ae5777621ba5ebc791ed092bfecf9d","src/ser/impossible.rs":"009dce92e20bd25335db7d747c595111f5eb8d21dda0f6c75bccf0d0608c5751","src/ser/mod.rs":"97c36fa5b8da27f1f95be9af54c441c8e59437e9533cdd90e376691737fc3d0f"},"package":"d3bcee660dcde8f52c3765dd9ca5ee36b4bf35470a738eb0bd5a8752b0389645"}
\ No newline at end of file
+{"files":{"Cargo.toml":"cf6e0bc93d4aa0e3a918240d385ecd9f97e2811c3a408d1acd5d31a3da23df15","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"16de77b2d10fac8c70219ba183ad083ae12d4553c6f3213dec39d9936622b371","build.rs":"c441b6b782f4962671f74d86db0442ae8e93aced058dac2d4c17044e1740af4c","src/de/from_primitive.rs":"46b635d939b10163a01739b082cff4b7f2635579920f8160aeadc03f33ad2b51","src/de/ignored_any.rs":"ea47caa53548c394a70bb512afd75b2de7fc9937b33518606282e4084dc70a77","src/de/impls.rs":"072a58dc9c33cc021ecbfc91626d5ea403b263fff0bbfa4516db585719ccc646","src/de/mod.rs":"2df8b3522b03e4bab5a5e0aa6ad45638c8bd21ea048aab5852f8cde5da405268","src/de/utf8.rs":"956b124b7ce98353cb781b56e43a6fed2e67f1389d35b7a468d5be75b1485853","src/de/value.rs":"004a5892e75fdfe015399027429da0ad4ee4ac3db50a980a38339f20bdbdd8e3","src/export.rs":"4e3ed8aa2b0e5d9c18f462183dff7fa4772a30e88e6b3cc0fb9712282ecbe0c5","src/lib.rs":"91df096c81fd3a478d337d29249d0f25eedb872ea00a261eb993df1897386fff","src/macros.rs":"a563019118ab3b1d408fb5fb9f2f80ec64cb53fe7af0fc0e0f35c2cf503b92f8","src/private/de.rs":"283c690c87db77f5adc6d03d62a9731a77b2c79a4d10ec5884d7872d80d573d0","src/private/macros.rs":"6861a4f332ea24d0ed5db1c28fe3105d2716523902f045c0bbbd439ebf9e44de","src/private/mod.rs":"0c774d86042cefdb447857070a1d4d2c0b9f519a7f5db588a1e7fcc16ca5a511","src/private/ser.rs":"189a091e1e77354c7859f34dc564879ad0116bb9fc340b55c3a718ae3126b36a","src/ser/impls.rs":"d5434a4eed1d82b040dc8a73a566a3bc4c085d99a20585654057461088fe0bb8","src/ser/impossible.rs":"91da408362284ec567b2316050900251ff66a1134413963720154fb70f3919c0","src/ser/mod.rs":"cc6c6155139df6e7270d880ad9e5aafb60542a6e0c2230620e0e6315858f82be"},"package":"34e9df8efbe7a2c12ceec1fc8744d56ae3374d8ae325f4a0028949d16433d554"}
\ No newline at end of file
--- a/third_party/rust/serde/Cargo.toml
+++ b/third_party/rust/serde/Cargo.toml
@@ -7,19 +7,20 @@
#
# If you believe there's an error in this file please file an
# issue against the rust-lang/cargo repository. If you're
# editing this file be aware that the upstream Cargo.toml
# will likely look very different (and much more reasonable)
[package]
name = "serde"
-version = "1.0.37"
+version = "1.0.58"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
-include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+build = "build.rs"
+include = ["Cargo.toml", "build.rs", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
description = "A generic serialization/deserialization framework"
homepage = "https://serde.rs"
documentation = "https://docs.serde.rs/serde/"
readme = "README.md"
keywords = ["serde", "serialization", "no_std"]
categories = ["encoding"]
license = "MIT/Apache-2.0"
repository = "https://github.com/serde-rs/serde"
@@ -28,17 +29,16 @@ version = "1.0"
optional = true
[dev-dependencies.serde_derive]
version = "1.0"
[features]
alloc = ["unstable"]
default = ["std"]
derive = ["serde_derive"]
-playground = ["serde_derive"]
rc = []
std = []
unstable = []
[badges.appveyor]
repository = "serde-rs/serde"
[badges.travis-ci]
repository = "serde-rs/serde"
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde/build.rs
@@ -0,0 +1,41 @@
+use std::env;
+use std::process::Command;
+use std::str::{self, FromStr};
+
+fn main() {
+ let rustc = match env::var_os("RUSTC") {
+ Some(rustc) => rustc,
+ None => return,
+ };
+
+ let output = match Command::new(rustc).arg("--version").output() {
+ Ok(output) => output,
+ Err(_) => return,
+ };
+
+ let version = match str::from_utf8(&output.stdout) {
+ Ok(version) => version,
+ Err(_) => return,
+ };
+
+ let mut pieces = version.split('.');
+ if pieces.next() != Some("rustc 1") {
+ return;
+ }
+
+ let next = match pieces.next() {
+ Some(next) => next,
+ None => return,
+ };
+
+ let minor = match u32::from_str(next) {
+ Ok(minor) => minor,
+ Err(_) => return,
+ };
+
+ // 128-bit integers stabilized in Rust 1.26:
+ // https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
+ if minor >= 26 {
+ println!("cargo:rustc-cfg=integer128");
+ }
+}
--- a/third_party/rust/serde/src/de/from_primitive.rs
+++ b/third_party/rust/serde/src/de/from_primitive.rs
@@ -34,56 +34,46 @@ macro_rules! uint_to {
Some($n as $dst)
} else {
None
}
};
}
pub trait FromPrimitive: Sized {
- fn from_isize(n: isize) -> Option<Self>;
fn from_i8(n: i8) -> Option<Self>;
fn from_i16(n: i16) -> Option<Self>;
fn from_i32(n: i32) -> Option<Self>;
fn from_i64(n: i64) -> Option<Self>;
- fn from_usize(n: usize) -> Option<Self>;
fn from_u8(n: u8) -> Option<Self>;
fn from_u16(n: u16) -> Option<Self>;
fn from_u32(n: u32) -> Option<Self>;
fn from_u64(n: u64) -> Option<Self>;
}
macro_rules! impl_from_primitive_for_int {
($t:ident) => {
impl FromPrimitive for $t {
#[inline]
- fn from_isize(n: isize) -> Option<Self> {
- int_to_int!($t, n)
- }
- #[inline]
fn from_i8(n: i8) -> Option<Self> {
int_to_int!($t, n)
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
int_to_int!($t, n)
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
int_to_int!($t, n)
}
#[inline]
fn from_i64(n: i64) -> Option<Self> {
int_to_int!($t, n)
}
#[inline]
- fn from_usize(n: usize) -> Option<Self> {
- uint_to!($t, n)
- }
- #[inline]
fn from_u8(n: u8) -> Option<Self> {
uint_to!($t, n)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
uint_to!($t, n)
}
#[inline]
@@ -97,40 +87,32 @@ macro_rules! impl_from_primitive_for_int
}
};
}
macro_rules! impl_from_primitive_for_uint {
($t:ident) => {
impl FromPrimitive for $t {
#[inline]
- fn from_isize(n: isize) -> Option<Self> {
- int_to_uint!($t, n)
- }
- #[inline]
fn from_i8(n: i8) -> Option<Self> {
int_to_uint!($t, n)
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
int_to_uint!($t, n)
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
int_to_uint!($t, n)
}
#[inline]
fn from_i64(n: i64) -> Option<Self> {
int_to_uint!($t, n)
}
#[inline]
- fn from_usize(n: usize) -> Option<Self> {
- uint_to!($t, n)
- }
- #[inline]
fn from_u8(n: u8) -> Option<Self> {
uint_to!($t, n)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
uint_to!($t, n)
}
#[inline]
@@ -144,40 +126,32 @@ macro_rules! impl_from_primitive_for_uin
}
};
}
macro_rules! impl_from_primitive_for_float {
($t:ident) => {
impl FromPrimitive for $t {
#[inline]
- fn from_isize(n: isize) -> Option<Self> {
- Some(n as Self)
- }
- #[inline]
fn from_i8(n: i8) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_i64(n: i64) -> Option<Self> {
Some(n as Self)
}
#[inline]
- fn from_usize(n: usize) -> Option<Self> {
- Some(n as Self)
- }
- #[inline]
fn from_u8(n: u8) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
Some(n as Self)
}
#[inline]
--- a/third_party/rust/serde/src/de/ignored_any.rs
+++ b/third_party/rust/serde/src/de/ignored_any.rs
@@ -40,26 +40,28 @@ use de::{Deserialize, Deserializer, Erro
/// NthElement {
/// n: n,
/// marker: PhantomData,
/// }
/// }
/// }
///
/// impl<'de, T> Visitor<'de> for NthElement<T>
-/// where T: Deserialize<'de>
+/// where
+/// T: Deserialize<'de>,
/// {
/// type Value = T;
///
/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// write!(formatter, "a sequence in which we care about element {}", self.n)
/// }
///
/// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
-/// where A: SeqAccess<'de>
+/// where
+/// A: SeqAccess<'de>,
/// {
/// // Skip over the first `n` elements.
/// for i in 0..self.n {
/// // It is an error if the sequence ends before we get to element `n`.
/// if seq.next_element::<IgnoredAny>()?.is_none() {
/// return Err(de::Error::invalid_length(i, &self));
/// }
/// }
@@ -77,29 +79,32 @@ use de::{Deserialize, Deserializer, Erro
/// // ignore
/// }
///
/// Ok(nth)
/// }
/// }
///
/// impl<'de, T> DeserializeSeed<'de> for NthElement<T>
-/// where T: Deserialize<'de>
+/// where
+/// T: Deserialize<'de>,
/// {
/// type Value = T;
///
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
-/// where D: Deserializer<'de>
+/// where
+/// D: Deserializer<'de>,
/// {
/// deserializer.deserialize_seq(self)
/// }
/// }
///
/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error>
-/// # where D: Deserializer<'de>
+/// # where
+/// # D: Deserializer<'de>,
/// # {
/// // Deserialize only the sequence element at index 3 from this deserializer.
/// // The element at index 3 is required to be a string. Elements before and
/// // after index 3 are allowed to be of any type.
/// let s: String = NthElement::new(3).deserialize(deserializer)?;
/// # Ok(())
/// # }
/// ```
--- a/third_party/rust/serde/src/de/impls.rs
+++ b/third_party/rust/serde/src/de/impls.rs
@@ -3,18 +3,19 @@
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
-use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess,
- Visitor};
+use de::{
+ Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor,
+};
#[cfg(any(feature = "std", feature = "alloc"))]
use de::MapAccess;
use de::from_primitive::FromPrimitive;
use private::de::InPlaceSeed;
#[cfg(any(feature = "std", feature = "alloc"))]
@@ -26,26 +27,26 @@ struct UnitVisitor;
impl<'de> Visitor<'de> for UnitVisitor {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("unit")
}
- fn visit_unit<E>(self) -> Result<(), E>
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: Error,
{
Ok(())
}
}
impl<'de> Deserialize<'de> for () {
- fn deserialize<D>(deserializer: D) -> Result<(), D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_unit(UnitVisitor)
}
}
////////////////////////////////////////////////////////////////////////////////
@@ -54,26 +55,26 @@ struct BoolVisitor;
impl<'de> Visitor<'de> for BoolVisitor {
type Value = bool;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a boolean")
}
- fn visit_bool<E>(self, v: bool) -> Result<bool, E>
+ fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v)
}
}
impl<'de> Deserialize<'de> for bool {
- fn deserialize<D>(deserializer: D) -> Result<bool, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_bool(BoolVisitor)
}
}
////////////////////////////////////////////////////////////////////////////////
@@ -104,17 +105,17 @@ macro_rules! visit_float_method {
}
}
}
macro_rules! impl_deserialize_num {
($ty:ident, $method:ident, $($visit:ident),*) => {
impl<'de> Deserialize<'de> for $ty {
#[inline]
- fn deserialize<D>(deserializer: D) -> Result<$ty, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct PrimitiveVisitor;
impl<'de> Visitor<'de> for PrimitiveVisitor {
type Value = $ty;
@@ -172,39 +173,39 @@ struct CharVisitor;
impl<'de> Visitor<'de> for CharVisitor {
type Value = char;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a character")
}
#[inline]
- fn visit_char<E>(self, v: char) -> Result<char, E>
+ fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v)
}
#[inline]
- fn visit_str<E>(self, v: &str) -> Result<char, E>
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
let mut iter = v.chars();
match (iter.next(), iter.next()) {
(Some(c), None) => Ok(c),
_ => Err(Error::invalid_value(Unexpected::Str(v), &self)),
}
}
}
impl<'de> Deserialize<'de> for char {
#[inline]
- fn deserialize<D>(deserializer: D) -> Result<char, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_char(CharVisitor)
}
}
////////////////////////////////////////////////////////////////////////////////
@@ -217,41 +218,41 @@ struct StringInPlaceVisitor<'a>(&'a mut
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Visitor<'de> for StringVisitor {
type Value = String;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string")
}
- fn visit_str<E>(self, v: &str) -> Result<String, E>
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v.to_owned())
}
- fn visit_string<E>(self, v: String) -> Result<String, E>
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v)
}
- fn visit_bytes<E>(self, v: &[u8]) -> Result<String, E>
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match str::from_utf8(v) {
Ok(s) => Ok(s.to_owned()),
Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
}
}
- fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<String, E>
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: Error,
{
match String::from_utf8(v) {
Ok(s) => Ok(s),
Err(e) => Err(Error::invalid_value(
Unexpected::Bytes(&e.into_bytes()),
&self,
@@ -263,48 +264,48 @@ impl<'de> Visitor<'de> for StringVisitor
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de> Visitor<'de> for StringInPlaceVisitor<'a> {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string")
}
- fn visit_str<E>(self, v: &str) -> Result<(), E>
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
self.0.clear();
self.0.push_str(v);
Ok(())
}
- fn visit_string<E>(self, v: String) -> Result<(), E>
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
*self.0 = v;
Ok(())
}
- fn visit_bytes<E>(self, v: &[u8]) -> Result<(), E>
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match str::from_utf8(v) {
Ok(s) => {
self.0.clear();
self.0.push_str(s);
Ok(())
}
Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
}
}
- fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<(), E>
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: Error,
{
match String::from_utf8(v) {
Ok(s) => {
*self.0 = s;
Ok(())
}
@@ -313,17 +314,17 @@ impl<'a, 'de> Visitor<'de> for StringInP
&self,
)),
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for String {
- fn deserialize<D>(deserializer: D) -> Result<String, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_string(StringVisitor)
}
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
where
@@ -411,62 +412,62 @@ struct CStringVisitor;
#[cfg(feature = "std")]
impl<'de> Visitor<'de> for CStringVisitor {
type Value = CString;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("byte array")
}
- fn visit_seq<A>(self, mut seq: A) -> Result<CString, A::Error>
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let len = size_hint::cautious(seq.size_hint());
let mut values = Vec::with_capacity(len);
while let Some(value) = try!(seq.next_element()) {
values.push(value);
}
CString::new(values).map_err(Error::custom)
}
- fn visit_bytes<E>(self, v: &[u8]) -> Result<CString, E>
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
CString::new(v).map_err(Error::custom)
}
- fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<CString, E>
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: Error,
{
CString::new(v).map_err(Error::custom)
}
- fn visit_str<E>(self, v: &str) -> Result<CString, E>
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
CString::new(v).map_err(Error::custom)
}
- fn visit_string<E>(self, v: String) -> Result<CString, E>
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
CString::new(v).map_err(Error::custom)
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for CString {
- fn deserialize<D>(deserializer: D) -> Result<CString, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_byte_buf(CStringVisitor)
}
}
macro_rules! forwarded_impl {
@@ -501,45 +502,53 @@ where
{
type Value = Option<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("option")
}
#[inline]
- fn visit_unit<E>(self) -> Result<Option<T>, E>
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(None)
+ }
+
+ #[inline]
+ fn visit_none<E>(self) -> Result<Self::Value, E>
where
E: Error,
{
Ok(None)
}
#[inline]
- fn visit_none<E>(self) -> Result<Option<T>, E>
- where
- E: Error,
- {
- Ok(None)
- }
-
- #[inline]
- fn visit_some<D>(self, deserializer: D) -> Result<Option<T>, D::Error>
+ fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(Some)
}
+
+ #[doc(hidden)]
+ fn __private_visit_untagged_option<D>(self, deserializer: D) -> Result<Self::Value, ()>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(T::deserialize(deserializer).ok())
+ }
}
impl<'de, T> Deserialize<'de> for Option<T>
where
T: Deserialize<'de>,
{
- fn deserialize<D>(deserializer: D) -> Result<Option<T>, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_option(OptionVisitor {
marker: PhantomData,
})
}
@@ -559,26 +568,26 @@ struct PhantomDataVisitor<T: ?Sized> {
impl<'de, T: ?Sized> Visitor<'de> for PhantomDataVisitor<T> {
type Value = PhantomData<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("unit")
}
#[inline]
- fn visit_unit<E>(self) -> Result<PhantomData<T>, E>
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
where
E: Error,
{
Ok(PhantomData)
}
}
impl<'de, T: ?Sized> Deserialize<'de> for PhantomData<T> {
- fn deserialize<D>(deserializer: D) -> Result<PhantomData<T>, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let visitor = PhantomDataVisitor {
marker: PhantomData,
};
deserializer.deserialize_unit_struct("PhantomData", visitor)
}
@@ -653,17 +662,17 @@ macro_rules! seq_impl {
{
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
#[inline]
- fn visit_seq<A>(mut self, mut $access: A) -> Result<(), A::Error>
+ fn visit_seq<A>(mut self, mut $access: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
$clear(&mut self.0);
$reserve(&mut self.0, size_hint::cautious($access.size_hint()));
// FIXME: try to overwrite old values here? (Vec, VecDeque, LinkedList)
while let Some(value) = try!($access.next_element()) {
@@ -765,27 +774,27 @@ impl<A> ArrayVisitor<A> {
impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> {
type Value = [T; 0];
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("an empty array")
}
#[inline]
- fn visit_seq<A>(self, _: A) -> Result<[T; 0], A::Error>
+ fn visit_seq<A>(self, _: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
Ok([])
}
}
// Does not require T: Deserialize<'de>.
impl<'de, T> Deserialize<'de> for [T; 0] {
- fn deserialize<D>(deserializer: D) -> Result<[T; 0], D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_tuple(0, ArrayVisitor::<[T; 0]>::new())
}
}
macro_rules! array_impls {
@@ -797,17 +806,17 @@ macro_rules! array_impls {
{
type Value = [T; $len];
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("an array of length ", $len))
}
#[inline]
- fn visit_seq<A>(self, mut seq: A) -> Result<[T; $len], A::Error>
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
$(
let $name = match try!(seq.next_element()) {
Some(val) => val,
None => return Err(Error::invalid_length($n, &self)),
};
@@ -823,17 +832,17 @@ macro_rules! array_impls {
{
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("an array of length ", $len))
}
#[inline]
- fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut fail_idx = None;
for (idx, dest) in self.0[..].iter_mut().enumerate() {
if try!(seq.next_element_seed(InPlaceSeed(dest))).is_none() {
fail_idx = Some(idx);
break;
@@ -845,17 +854,17 @@ macro_rules! array_impls {
Ok(())
}
}
impl<'de, T> Deserialize<'de> for [T; $len]
where
T: Deserialize<'de>,
{
- fn deserialize<D>(deserializer: D) -> Result<[T; $len], D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_tuple($len, ArrayVisitor::<[T; $len]>::new())
}
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
where
@@ -905,34 +914,34 @@ array_impls! {
////////////////////////////////////////////////////////////////////////////////
macro_rules! tuple_impls {
($($len:tt => ($($n:tt $name:ident)+))+) => {
$(
impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) {
#[inline]
- fn deserialize<D>(deserializer: D) -> Result<($($name,)+), D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct TupleVisitor<$($name,)+> {
marker: PhantomData<($($name,)+)>,
}
impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<$($name,)+> {
type Value = ($($name,)+);
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("a tuple of size ", $len))
}
#[inline]
#[allow(non_snake_case)]
- fn visit_seq<A>(self, mut seq: A) -> Result<($($name,)+), A::Error>
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
$(
let $name = match try!(seq.next_element()) {
Some(value) => value,
None => return Err(Error::invalid_length($n, &self)),
};
@@ -956,17 +965,17 @@ macro_rules! tuple_impls {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(concat!("a tuple of size ", $len))
}
#[inline]
#[allow(non_snake_case)]
- fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
$(
if try!(seq.next_element_seed(InPlaceSeed(&mut (self.0).$n))).is_none() {
return Err(Error::invalid_length($n, &self));
}
)+
@@ -1271,20 +1280,17 @@ impl<'de> Deserialize<'de> for net::Sock
}
}
#[cfg(feature = "std")]
parse_socket_impl!(net::SocketAddrV4, net::SocketAddrV4::new);
#[cfg(feature = "std")]
parse_socket_impl!(net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(
- ip,
- port,
- 0,
- 0
+ ip, port, 0, 0
));
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
struct PathVisitor;
#[cfg(feature = "std")]
@@ -1328,34 +1334,34 @@ struct PathBufVisitor;
#[cfg(feature = "std")]
impl<'de> Visitor<'de> for PathBufVisitor {
type Value = PathBuf;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("path string")
}
- fn visit_str<E>(self, v: &str) -> Result<PathBuf, E>
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(From::from(v))
}
- fn visit_string<E>(self, v: String) -> Result<PathBuf, E>
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
Ok(From::from(v))
}
}
#[cfg(feature = "std")]
impl<'de> Deserialize<'de> for PathBuf {
- fn deserialize<D>(deserializer: D) -> Result<PathBuf, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_string(PathBufVisitor)
}
}
////////////////////////////////////////////////////////////////////////////////
@@ -1378,32 +1384,32 @@ struct OsStringVisitor;
impl<'de> Visitor<'de> for OsStringVisitor {
type Value = OsString;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("os string")
}
#[cfg(unix)]
- fn visit_enum<A>(self, data: A) -> Result<OsString, A::Error>
+ fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: EnumAccess<'de>,
{
use std::os::unix::ffi::OsStringExt;
match try!(data.variant()) {
(OsStringKind::Unix, v) => v.newtype_variant().map(OsString::from_vec),
(OsStringKind::Windows, _) => Err(Error::custom(
"cannot deserialize Windows OS string on Unix",
)),
}
}
#[cfg(windows)]
- fn visit_enum<A>(self, data: A) -> Result<OsString, A::Error>
+ fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: EnumAccess<'de>,
{
use std::os::windows::ffi::OsStringExt;
match try!(data.variant()) {
(OsStringKind::Windows, v) => v.newtype_variant::<Vec<u16>>()
.map(|vec| OsString::from_wide(&vec)),
@@ -1411,17 +1417,17 @@ impl<'de> Visitor<'de> for OsStringVisit
"cannot deserialize Unix OS string on Windows",
)),
}
}
}
#[cfg(all(feature = "std", any(unix, windows)))]
impl<'de> Deserialize<'de> for OsString {
- fn deserialize<D>(deserializer: D) -> Result<OsString, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_enum("OsString", OSSTR_VARIANTS, OsStringVisitor)
}
}
////////////////////////////////////////////////////////////////////////////////
@@ -1461,26 +1467,64 @@ forwarded_impl! {
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
where
T: ToOwned,
T::Owned: Deserialize<'de>,
{
#[inline]
- fn deserialize<D>(deserializer: D) -> Result<Cow<'a, T>, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
T::Owned::deserialize(deserializer).map(Cow::Owned)
}
}
////////////////////////////////////////////////////////////////////////////////
+/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting
+/// `Weak<T>` has a reference count of 0 and cannot be upgraded.
+///
+/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
+#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
+impl<'de, T: ?Sized> Deserialize<'de> for RcWeak<T>
+where
+ T: Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ try!(Option::<T>::deserialize(deserializer));
+ Ok(RcWeak::new())
+ }
+}
+
+/// This impl requires the [`"rc"`] Cargo feature of Serde. The resulting
+/// `Weak<T>` has a reference count of 0 and cannot be upgraded.
+///
+/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
+#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
+impl<'de, T: ?Sized> Deserialize<'de> for ArcWeak<T>
+where
+ T: Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ try!(Option::<T>::deserialize(deserializer));
+ Ok(ArcWeak::new())
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
macro_rules! box_forwarded_impl {
(
$(#[doc = $doc:tt])*
$t:ident
) => {
$(#[doc = $doc])*
impl<'de, T: ?Sized> Deserialize<'de> for $t<T>
@@ -1522,17 +1566,17 @@ box_forwarded_impl! {
}
////////////////////////////////////////////////////////////////////////////////
impl<'de, T> Deserialize<'de> for Cell<T>
where
T: Deserialize<'de> + Copy,
{
- fn deserialize<D>(deserializer: D) -> Result<Cell<T>, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(Cell::new)
}
}
forwarded_impl!((T), RefCell<T>, RefCell::new);
@@ -1564,41 +1608,41 @@ impl<'de> Deserialize<'de> for Duration
// #[derive(Deserialize)]
// #[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Secs,
Nanos,
};
impl<'de> Deserialize<'de> for Field {
- fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`secs` or `nanos`")
}
- fn visit_str<E>(self, value: &str) -> Result<Field, E>
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"secs" => Ok(Field::Secs),
"nanos" => Ok(Field::Nanos),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}
- fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
+ fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"secs" => Ok(Field::Secs),
b"nanos" => Ok(Field::Nanos),
_ => {
let value = String::from_utf8_lossy(value);
@@ -1616,17 +1660,17 @@ impl<'de> Deserialize<'de> for Duration
impl<'de> Visitor<'de> for DurationVisitor {
type Value = Duration;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Duration")
}
- fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let secs: u64 = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
@@ -1635,17 +1679,17 @@ impl<'de> Deserialize<'de> for Duration
Some(value) => value,
None => {
return Err(Error::invalid_length(1, &self));
}
};
Ok(Duration::new(secs, nanos))
}
- fn visit_map<A>(self, mut map: A) -> Result<Duration, A::Error>
+ fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut secs: Option<u64> = None;
let mut nanos: Option<u32> = None;
while let Some(key) = try!(map.next_key()) {
match key {
Field::Secs => {
@@ -1689,41 +1733,41 @@ impl<'de> Deserialize<'de> for SystemTim
{
// Reuse duration
enum Field {
Secs,
Nanos,
};
impl<'de> Deserialize<'de> for Field {
- fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`")
}
- fn visit_str<E>(self, value: &str) -> Result<Field, E>
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"secs_since_epoch" => Ok(Field::Secs),
"nanos_since_epoch" => Ok(Field::Nanos),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}
- fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
+ fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"secs_since_epoch" => Ok(Field::Secs),
b"nanos_since_epoch" => Ok(Field::Nanos),
_ => {
let value = String::from_utf8_lossy(value);
@@ -1741,17 +1785,17 @@ impl<'de> Deserialize<'de> for SystemTim
impl<'de> Visitor<'de> for DurationVisitor {
type Value = Duration;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct SystemTime")
}
- fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let secs: u64 = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
@@ -1760,17 +1804,17 @@ impl<'de> Deserialize<'de> for SystemTim
Some(value) => value,
None => {
return Err(Error::invalid_length(1, &self));
}
};
Ok(Duration::new(secs, nanos))
}
- fn visit_map<A>(self, mut map: A) -> Result<Duration, A::Error>
+ fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut secs: Option<u64> = None;
let mut nanos: Option<u32> = None;
while let Some(key) = try!(map.next_key()) {
match key {
Field::Secs => {
@@ -1833,41 +1877,41 @@ where
// #[derive(Deserialize)]
// #[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Start,
End,
};
impl<'de> Deserialize<'de> for Field {
- fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`start` or `end`")
}
- fn visit_str<E>(self, value: &str) -> Result<Field, E>
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"start" => Ok(Field::Start),
"end" => Ok(Field::End),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}
- fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
+ fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"start" => Ok(Field::Start),
b"end" => Ok(Field::End),
_ => {
let value = String::from_utf8_lossy(value);
@@ -1890,17 +1934,17 @@ where
Idx: Deserialize<'de>,
{
type Value = ops::Range<Idx>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Range")
}
- fn visit_seq<A>(self, mut seq: A) -> Result<ops::Range<Idx>, A::Error>
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let start: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
@@ -1909,17 +1953,17 @@ where
Some(value) => value,
None => {
return Err(Error::invalid_length(1, &self));
}
};
Ok(start..end)
}
- fn visit_map<A>(self, mut map: A) -> Result<ops::Range<Idx>, A::Error>
+ fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut start: Option<Idx> = None;
let mut end: Option<Idx> = None;
while let Some(key) = try!(map.next_key()) {
match key {
Field::Start => {
@@ -1956,40 +2000,22 @@ where
phantom: PhantomData,
},
)
}
}
////////////////////////////////////////////////////////////////////////////////
-#[cfg(feature = "unstable")]
-#[allow(deprecated)]
-impl<'de, T> Deserialize<'de> for NonZero<T>
-where
- T: Deserialize<'de> + Zeroable,
-{
- fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error>
- where
- D: Deserializer<'de>,
- {
- let value = try!(Deserialize::deserialize(deserializer));
- match NonZero::new(value) {
- Some(nonzero) => Ok(nonzero),
- None => Err(Error::custom("expected a non-zero value")),
- }
- }
-}
-
macro_rules! nonzero_integers {
( $( $T: ty, )+ ) => {
$(
#[cfg(feature = "unstable")]
impl<'de> Deserialize<'de> for $T {
- fn deserialize<D>(deserializer: D) -> Result<$T, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let value = try!(Deserialize::deserialize(deserializer));
match <$T>::new(value) {
Some(nonzero) => Ok(nonzero),
None => Err(Error::custom("expected a non-zero value")),
}
@@ -2011,70 +2037,70 @@ nonzero_integers! {
////////////////////////////////////////////////////////////////////////////////
impl<'de, T, E> Deserialize<'de> for Result<T, E>
where
T: Deserialize<'de>,
E: Deserialize<'de>,
{
- fn deserialize<D>(deserializer: D) -> Result<Result<T, E>, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
// If this were outside of the serde crate, it would just use:
//
// #[derive(Deserialize)]
// #[serde(variant_identifier)]
enum Field {
Ok,
Err,
}
impl<'de> Deserialize<'de> for Field {
#[inline]
- fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`Ok` or `Err`")
}
- fn visit_u32<E>(self, value: u32) -> Result<Field, E>
+ fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
where
E: Error,
{
match value {
0 => Ok(Field::Ok),
1 => Ok(Field::Err),
_ => Err(Error::invalid_value(
Unexpected::Unsigned(value as u64),
&self,
)),
}
}
- fn visit_str<E>(self, value: &str) -> Result<Field, E>
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"Ok" => Ok(Field::Ok),
"Err" => Ok(Field::Err),
_ => Err(Error::unknown_variant(value, VARIANTS)),
}
}
- fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
+ fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"Ok" => Ok(Field::Ok),
b"Err" => Ok(Field::Err),
_ => match str::from_utf8(value) {
Ok(value) => Err(Error::unknown_variant(value, VARIANTS)),
@@ -2098,17 +2124,17 @@ where
E: Deserialize<'de>,
{
type Value = Result<T, E>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("enum Result")
}
- fn visit_enum<A>(self, data: A) -> Result<Result<T, E>, A::Error>
+ fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: EnumAccess<'de>,
{
match try!(data.variant()) {
(Field::Ok, v) => v.newtype_variant().map(Ok),
(Field::Err, v) => v.newtype_variant().map(Err),
}
}
@@ -2122,15 +2148,15 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl<'de, T> Deserialize<'de> for Wrapping<T>
where
T: Deserialize<'de>,
{
- fn deserialize<D>(deserializer: D) -> Result<Wrapping<T>, D::Error>
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Deserialize::deserialize(deserializer).map(Wrapping)
}
}
--- a/third_party/rust/serde/src/de/mod.rs
+++ b/third_party/rust/serde/src/de/mod.rs
@@ -79,31 +79,29 @@
//! - BTreeMap\<K, V\>
//! - BTreeSet\<T\>
//! - BinaryHeap\<T\>
//! - HashMap\<K, V, H\>
//! - HashSet\<T, H\>
//! - LinkedList\<T\>
//! - VecDeque\<T\>
//! - Vec\<T\>
-//! - EnumSet\<T\> (unstable)
//! - **Zero-copy types**:
//! - &str
//! - &[u8]
//! - **FFI types**:
//! - CString
//! - Box\<CStr\>
//! - OsString
//! - **Miscellaneous standard library types**:
//! - Duration
//! - SystemTime
//! - Path
//! - PathBuf
//! - Range\<T\>
-//! - NonZero\<T\> (unstable, deprecated)
//! - num::NonZero* (unstable)
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
//! - Ipv6Addr
//! - SocketAddr
//! - SocketAddrV4
//! - SocketAddrV6
@@ -167,17 +165,18 @@ macro_rules! declare_error_trait {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::de::{self, Deserialize, Deserializer};
///
/// impl<'de> Deserialize<'de> for IpAddr {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- /// where D: Deserializer<'de>
+ /// where
+ /// D: Deserializer<'de>,
/// {
/// let s = try!(String::deserialize(deserializer));
/// s.parse().map_err(de::Error::custom)
/// }
/// }
/// ```
fn custom<T>(msg: T) -> Self
where
@@ -191,16 +190,17 @@ macro_rules! declare_error_trait {
/// of the Deserializer.
///
/// The `exp` argument provides information about what type was being
/// expected. This is the type that is written in the program.
///
/// For example if we try to deserialize a String out of a JSON file
/// containing an integer, the unexpected type is the integer and the
/// expected type is the string.
+ #[cold]
fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self {
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
}
/// Raised when a `Deserialize` receives a value of the right type but that
/// is wrong for some other reason.
///
/// The `unexp` argument provides information about what value was received.
@@ -208,68 +208,74 @@ macro_rules! declare_error_trait {
/// data of the Deserializer.
///
/// The `exp` argument provides information about what value was being
/// expected. This is the type that is written in the program.
///
/// For example if we try to deserialize a String out of some binary data
/// that is not valid UTF-8, the unexpected value is the bytes and the
/// expected value is a string.
+ #[cold]
fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self {
Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
}
/// Raised when deserializing a sequence or map and the input data contains
/// too many or too few elements.
///
/// The `len` argument is the number of elements encountered. The sequence
/// or map may have expected more arguments or fewer arguments.
///
/// The `exp` argument provides information about what data was being
/// expected. For example `exp` might say that a tuple of size 6 was
/// expected.
+ #[cold]
fn invalid_length(len: usize, exp: &Expected) -> Self {
Error::custom(format_args!("invalid length {}, expected {}", len, exp))
}
/// Raised when a `Deserialize` enum type received a variant with an
/// unrecognized name.
+ #[cold]
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() {
Error::custom(format_args!("unknown variant `{}`, there are no variants",
variant))
} else {
Error::custom(format_args!("unknown variant `{}`, expected {}",
variant,
OneOf { names: expected }))
}
}
/// Raised when a `Deserialize` struct type received a field with an
/// unrecognized name.
+ #[cold]
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() {
Error::custom(format_args!("unknown field `{}`, there are no fields",
field))
} else {
Error::custom(format_args!("unknown field `{}`, expected {}",
field,
OneOf { names: expected }))
}
}
/// Raised when a `Deserialize` struct type expected to receive a required
/// field with a particular name but that field was not present in the
/// input.
+ #[cold]
fn missing_field(field: &'static str) -> Self {
Error::custom(format_args!("missing field `{}`", field))
}
/// Raised when a `Deserialize` struct type received more than one of the
/// same field.
+ #[cold]
fn duplicate_field(field: &'static str) -> Self {
Error::custom(format_args!("duplicate field `{}`", field))
}
}
}
}
#[cfg(feature = "std")]
@@ -294,17 +300,18 @@ declare_error_trait!(Error: Sized + Debu
/// # impl<'de> Visitor<'de> for Example {
/// # type Value = ();
/// #
/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// # write!(formatter, "definitely not a boolean")
/// # }
/// #
/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
-/// where E: de::Error
+/// where
+/// E: de::Error,
/// {
/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self))
/// }
/// # }
/// ```
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Unexpected<'a> {
/// The input contained a boolean value that was not expected.
@@ -418,30 +425,32 @@ impl<'a> fmt::Display for Unexpected<'a>
/// # impl<'de> Visitor<'de> for Example {
/// # type Value = ();
/// #
/// # fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// # write!(formatter, "definitely not a boolean")
/// # }
/// #
/// fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
-/// where E: de::Error
+/// where
+/// E: de::Error,
/// {
/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self))
/// }
/// # }
/// ```
///
/// Outside of a `Visitor`, `&"..."` can be used.
///
/// ```rust
/// # use serde::de::{self, Unexpected};
/// #
/// # fn example<E>() -> Result<(), E>
-/// # where E: de::Error
+/// # where
+/// # E: de::Error,
/// # {
/// # let v = true;
/// return Err(de::Error::invalid_type(Unexpected::Bool(v), &"a negative integer"));
/// # }
/// ```
pub trait Expected {
/// Format an explanation of what data was being expected. Same signature as
/// the `Display` and `Debug` traits.
@@ -545,21 +554,23 @@ pub trait Deserialize<'de>: Sized {
/// owned data.
///
/// ```rust
/// # use serde::de::{Deserialize, DeserializeOwned};
/// # use std::io::{Read, Result};
/// #
/// # trait Ignore {
/// fn from_str<'a, T>(s: &'a str) -> Result<T>
-/// where T: Deserialize<'a>;
+/// where
+/// T: Deserialize<'a>;
///
/// fn from_reader<R, T>(rdr: R) -> Result<T>
-/// where R: Read,
-/// T: DeserializeOwned;
+/// where
+/// R: Read,
+/// T: DeserializeOwned;
/// # }
/// ```
pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
impl<T> DeserializeOwned for T
where
T: for<'de> Deserialize<'de>,
{
}
@@ -625,41 +636,45 @@ where
/// // A DeserializeSeed implementation that uses stateful deserialization to
/// // append array elements onto the end of an existing vector. The preexisting
/// // state ("seed") in this case is the Vec<T>. The `deserialize` method of
/// // `ExtendVec` will be traversing the inner arrays of the JSON input and
/// // appending each integer into the existing Vec.
/// struct ExtendVec<'a, T: 'a>(&'a mut Vec<T>);
///
/// impl<'de, 'a, T> DeserializeSeed<'de> for ExtendVec<'a, T>
-/// where T: Deserialize<'de>
+/// where
+/// T: Deserialize<'de>,
/// {
/// // The return type of the `deserialize` method. This implementation
/// // appends onto an existing vector but does not create any new data
/// // structure, so the return type is ().
/// type Value = ();
///
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
-/// where D: Deserializer<'de>
+/// where
+/// D: Deserializer<'de>,
/// {
/// // Visitor implementation that will walk an inner array of the JSON
/// // input.
/// struct ExtendVecVisitor<'a, T: 'a>(&'a mut Vec<T>);
///
/// impl<'de, 'a, T> Visitor<'de> for ExtendVecVisitor<'a, T>
-/// where T: Deserialize<'de>
+/// where
+/// T: Deserialize<'de>,
/// {
/// type Value = ();
///
/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// write!(formatter, "an array of integers")
/// }
///
/// fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
-/// where A: SeqAccess<'de>
+/// where
+/// A: SeqAccess<'de>,
/// {
/// // Visit each element in the inner array and push it onto
/// // the existing vector.
/// while let Some(elem) = seq.next_element()? {
/// self.0.push(elem);
/// }
/// Ok(())
/// }
@@ -668,44 +683,47 @@ where
/// deserializer.deserialize_seq(ExtendVecVisitor(self.0))
/// }
/// }
///
/// // Visitor implementation that will walk the outer array of the JSON input.
/// struct FlattenedVecVisitor<T>(PhantomData<T>);
///
/// impl<'de, T> Visitor<'de> for FlattenedVecVisitor<T>
-/// where T: Deserialize<'de>
+/// where
+/// T: Deserialize<'de>,
/// {
/// // This Visitor constructs a single Vec<T> to hold the flattened
/// // contents of the inner arrays.
/// type Value = Vec<T>;
///
/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// write!(formatter, "an array of arrays")
/// }
///
/// fn visit_seq<A>(self, mut seq: A) -> Result<Vec<T>, A::Error>
-/// where A: SeqAccess<'de>
+/// where
+/// A: SeqAccess<'de>,
/// {
/// // Create a single Vec to hold the flattened contents.
/// let mut vec = Vec::new();
///
/// // Each iteration through this loop is one inner array.
/// while let Some(()) = seq.next_element_seed(ExtendVec(&mut vec))? {
/// // Nothing to do; inner array has been appended into `vec`.
/// }
///
/// // Return the finished vec.
/// Ok(vec)
/// }
/// }
///
/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error>
-/// # where D: Deserializer<'de>
+/// # where
+/// # D: Deserializer<'de>,
/// # {
/// let visitor = FlattenedVecVisitor(PhantomData);
/// let flattened: Vec<u64> = deserializer.deserialize_seq(visitor)?;
/// # Ok(())
/// # }
/// ```
pub trait DeserializeSeed<'de>: Sized {
/// The type produced by using this seed.
@@ -1080,17 +1098,18 @@ pub trait Deserializer<'de>: Sized {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::de::{self, Deserialize, Deserializer};
///
/// impl<'de> Deserialize<'de> for Timestamp {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- /// where D: Deserializer<'de>
+ /// where
+ /// D: Deserializer<'de>,
/// {
/// if deserializer.is_human_readable() {
/// // Deserialize from a human-readable string like "2015-05-15T17:01:00Z".
/// let s = String::deserialize(deserializer)?;
/// Timestamp::from_str(&s).map_err(de::Error::custom)
/// } else {
/// // Deserialize from a compact binary representation, seconds since
/// // the Unix epoch.
@@ -1131,17 +1150,18 @@ pub trait Deserializer<'de>: Sized {
/// impl<'de> Visitor<'de> for LongString {
/// type Value = String;
///
/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// write!(formatter, "a string containing at least {} bytes", self.min)
/// }
///
/// fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
-/// where E: de::Error
+/// where
+/// E: de::Error,
/// {
/// if s.len() >= self.min {
/// Ok(s.to_owned())
/// } else {
/// Err(de::Error::invalid_value(Unexpected::Str(s), &self))
/// }
/// }
/// }
@@ -1502,16 +1522,25 @@ pub trait Visitor<'de>: Sized {
/// The default implementation fails with a type error.
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: EnumAccess<'de>,
{
let _ = data;
Err(Error::invalid_type(Unexpected::Enum, &self))
}
+
+ // Used when deserializing a flattened Option field. Not public API.
+ #[doc(hidden)]
+ fn __private_visit_untagged_option<D>(self, _: D) -> Result<Self::Value, ()>
+ where
+ D: Deserializer<'de>,
+ {
+ Err(())
+ }
}
////////////////////////////////////////////////////////////////////////////////
/// Provides a `Visitor` access to each element of a sequence in the input.
///
/// This is a trait that a `Deserializer` passes to a `Visitor` implementation,
/// which deserializes each item in a sequence.
@@ -1811,25 +1840,28 @@ pub trait VariantAccess<'de>: Sized {
/// #
/// fn unit_variant(self) -> Result<(), Self::Error> {
/// // What the data actually contained; suppose it is a tuple variant.
/// let unexp = Unexpected::TupleVariant;
/// Err(de::Error::invalid_type(unexp, &"unit variant"))
/// }
/// #
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
- /// # where T: DeserializeSeed<'de>
+ /// # where
+ /// # T: DeserializeSeed<'de>,
/// # { unimplemented!() }
/// #
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
- /// # where V: Visitor<'de>
+ /// # where
+ /// # V: Visitor<'de>,
/// # { unimplemented!() }
/// #
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
- /// # where V: Visitor<'de>
+ /// # where
+ /// # V: Visitor<'de>,
/// # { unimplemented!() }
/// # }
/// ```
fn unit_variant(self) -> Result<(), Self::Error>;
/// Called when deserializing a variant with a single value.
///
/// `Deserialize` implementations should typically use
@@ -1846,29 +1878,32 @@ pub trait VariantAccess<'de>: Sized {
/// # impl<'de> VariantAccess<'de> for X {
/// # type Error = value::Error;
/// #
/// # fn unit_variant(self) -> Result<(), Self::Error> {
/// # unimplemented!()
/// # }
/// #
/// fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
- /// where T: DeserializeSeed<'de>
+ /// where
+ /// T: DeserializeSeed<'de>,
/// {
/// // What the data actually contained; suppose it is a unit variant.
/// let unexp = Unexpected::UnitVariant;
/// Err(de::Error::invalid_type(unexp, &"newtype variant"))
/// }
/// #
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
- /// # where V: Visitor<'de>
+ /// # where
+ /// # V: Visitor<'de>,
/// # { unimplemented!() }
/// #
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
- /// # where V: Visitor<'de>
+ /// # where
+ /// # V: Visitor<'de>,
/// # { unimplemented!() }
/// # }
/// ```
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeSeed<'de>;
/// Called when deserializing a variant with a single value.
@@ -1899,31 +1934,36 @@ pub trait VariantAccess<'de>: Sized {
/// # impl<'de> VariantAccess<'de> for X {
/// # type Error = value::Error;
/// #
/// # fn unit_variant(self) -> Result<(), Self::Error> {
/// # unimplemented!()
/// # }
/// #
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
- /// # where T: DeserializeSeed<'de>
+ /// # where
+ /// # T: DeserializeSeed<'de>,
/// # { unimplemented!() }
/// #
- /// fn tuple_variant<V>(self,
- /// _len: usize,
- /// _visitor: V) -> Result<V::Value, Self::Error>
- /// where V: Visitor<'de>
+ /// fn tuple_variant<V>(
+ /// self,
+ /// _len: usize,
+ /// _visitor: V,
+ /// ) -> Result<V::Value, Self::Error>
+ /// where
+ /// V: Visitor<'de>,
/// {
/// // What the data actually contained; suppose it is a unit variant.
/// let unexp = Unexpected::UnitVariant;
/// Err(de::Error::invalid_type(unexp, &"tuple variant"))
/// }
/// #
/// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
- /// # where V: Visitor<'de>
+ /// # where
+ /// # V: Visitor<'de>,
/// # { unimplemented!() }
/// # }
/// ```
fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>;
/// Called when deserializing a struct-like variant.
@@ -1941,27 +1981,32 @@ pub trait VariantAccess<'de>: Sized {
/// # impl<'de> VariantAccess<'de> for X {
/// # type Error = value::Error;
/// #
/// # fn unit_variant(self) -> Result<(), Self::Error> {
/// # unimplemented!()
/// # }
/// #
/// # fn newtype_variant_seed<T>(self, _: T) -> Result<T::Value, Self::Error>
- /// # where T: DeserializeSeed<'de>
+ /// # where
+ /// # T: DeserializeSeed<'de>,
/// # { unimplemented!() }
/// #
/// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
- /// # where V: Visitor<'de>
+ /// # where
+ /// # V: Visitor<'de>,
/// # { unimplemented!() }
/// #
- /// fn struct_variant<V>(self,
- /// _fields: &'static [&'static str],
- /// _visitor: V) -> Result<V::Value, Self::Error>
- /// where V: Visitor<'de>
+ /// fn struct_variant<V>(
+ /// self,
+ /// _fields: &'static [&'static str],
+ /// _visitor: V,
+ /// ) -> Result<V::Value, Self::Error>
+ /// where
+ /// V: Visitor<'de>,
/// {
/// // What the data actually contained; suppose it is a unit variant.
/// let unexp = Unexpected::UnitVariant;
/// Err(de::Error::invalid_type(unexp, &"struct variant"))
/// }
/// # }
/// ```
fn struct_variant<V>(
--- a/third_party/rust/serde/src/de/value.rs
+++ b/third_party/rust/serde/src/de/value.rs
@@ -53,36 +53,39 @@ pub struct Error {
#[cfg(any(feature = "std", feature = "alloc"))]
type ErrorImpl = Box<str>;
#[cfg(not(any(feature = "std", feature = "alloc")))]
type ErrorImpl = ();
impl de::Error for Error {
#[cfg(any(feature = "std", feature = "alloc"))]
+ #[cold]
fn custom<T>(msg: T) -> Self
where
T: Display,
{
Error {
err: msg.to_string().into_boxed_str(),
}
}
#[cfg(not(any(feature = "std", feature = "alloc")))]
+ #[cold]
fn custom<T>(msg: T) -> Self
where
T: Display,
{
let _ = msg;
Error { err: () }
}
}
impl ser::Error for Error {
+ #[cold]
fn custom<T>(msg: T) -> Self
where
T: Display,
{
de::Error::custom(msg)
}
}
@@ -647,21 +650,18 @@ where
impl<I, E> SeqDeserializer<I, E>
where
I: Iterator,
E: de::Error,
{
/// Check for remaining elements after passing a `SeqDeserializer` to
/// `Visitor::visit_seq`.
- pub fn end(mut self) -> Result<(), E> {
- let mut remaining = 0;
- while self.iter.next().is_some() {
- remaining += 1;
- }
+ pub fn end(self) -> Result<(), E> {
+ let remaining = self.iter.count();
if remaining == 0 {
Ok(())
} else {
// First argument is the number of elements in the data, second
// argument is the number of elements expected by the Deserialize.
Err(de::Error::invalid_length(
self.count + remaining,
&ExpectedInSeq(self.count),
@@ -844,21 +844,18 @@ where
impl<'de, I, E> MapDeserializer<'de, I, E>
where
I: Iterator,
I::Item: private::Pair,
E: de::Error,
{
/// Check for remaining elements after passing a `MapDeserializer` to
/// `Visitor::visit_map`.
- pub fn end(mut self) -> Result<(), E> {
- let mut remaining = 0;
- while self.iter.next().is_some() {
- remaining += 1;
- }
+ pub fn end(self) -> Result<(), E> {
+ let remaining = self.iter.count();
if remaining == 0 {
Ok(())
} else {
// First argument is the number of elements in the data, second
// argument is the number of elements expected by the Deserialize.
Err(de::Error::invalid_length(
self.count + remaining,
&ExpectedInMap(self.count),
--- a/third_party/rust/serde/src/export.rs
+++ b/third_party/rust/serde/src/export.rs
@@ -11,16 +11,19 @@ pub use lib::convert::{From, Into};
pub use lib::default::Default;
pub use lib::fmt::{self, Formatter};
pub use lib::marker::PhantomData;
pub use lib::option::Option::{self, None, Some};
pub use lib::result::Result::{self, Err, Ok};
pub use self::string::from_utf8_lossy;
+#[cfg(any(feature = "alloc", feature = "std"))]
+pub use lib::Vec;
+
mod string {
use lib::*;
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
String::from_utf8_lossy(bytes)
}
--- a/third_party/rust/serde/src/lib.rs
+++ b/third_party/rust/serde/src/lib.rs
@@ -74,31 +74,34 @@
//! [Envy]: https://github.com/softprops/envy
//! [Redis]: https://github.com/OneSignal/serde-redis
//! [Cargo]: http://doc.crates.io/manifest.html
//! [redis-rs]: https://crates.io/crates/redis
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/serde/1.0.37")]
+#![doc(html_root_url = "https://docs.rs/serde/1.0.58")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
// https://github.com/serde-rs/serde/issues/812
-#![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
+#![cfg_attr(feature = "unstable", feature(specialization))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
-#![cfg_attr(feature = "cargo-clippy",
- allow(cast_lossless, const_static_lifetime, doc_markdown, linkedlist,
- needless_pass_by_value, redundant_field_names, type_complexity,
- unreadable_literal, zero_prefixed_literal))]
+#![cfg_attr(
+ feature = "cargo-clippy",
+ allow(
+ cast_lossless, const_static_lifetime, doc_markdown, linkedlist, needless_pass_by_value,
+ redundant_field_names, type_complexity, unreadable_literal, zero_prefixed_literal
+ )
+)]
// Whitelisted clippy_pedantic lints
#![cfg_attr(feature = "cargo-clippy", allow(
// integer and float ser/de requires these sorts of casts
cast_possible_truncation,
cast_possible_wrap,
cast_precision_loss,
cast_sign_loss,
// simplifies some macros
@@ -138,18 +141,18 @@ mod lib {
#[cfg(not(feature = "std"))]
pub use core::*;
#[cfg(feature = "std")]
pub use std::*;
}
pub use self::core::{cmp, iter, mem, ops, slice, str};
pub use self::core::{f32, f64};
- pub use self::core::{isize, i16, i32, i64, i8};
- pub use self::core::{usize, u16, u32, u64, u8};
+ pub use self::core::{i16, i32, i64, i8, isize};
+ pub use self::core::{u16, u32, u64, u8, usize};
pub use self::core::cell::{Cell, RefCell};
pub use self::core::clone::{self, Clone};
pub use self::core::convert::{self, From, Into};
pub use self::core::default::{self, Default};
pub use self::core::fmt::{self, Debug, Display};
pub use self::core::marker::{self, PhantomData};
pub use self::core::option::{self, Option};
@@ -171,24 +174,24 @@ mod lib {
pub use std::vec::Vec;
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::boxed::Box;
#[cfg(feature = "std")]
pub use std::boxed::Box;
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
- pub use alloc::rc::Rc;
+ pub use alloc::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
- pub use std::rc::Rc;
+ pub use std::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
- pub use alloc::arc::Arc;
+ pub use alloc::arc::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
- pub use std::sync::Arc;
+ pub use std::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
#[cfg(feature = "std")]
pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
#[cfg(feature = "std")]
pub use std::{error, net};
@@ -206,20 +209,16 @@ mod lib {
#[cfg(feature = "std")]
pub use std::path::{Path, PathBuf};
#[cfg(feature = "std")]
pub use std::sync::{Mutex, RwLock};
#[cfg(feature = "std")]
pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
#[cfg(feature = "unstable")]
- #[allow(deprecated)]
- pub use core::nonzero::{NonZero, Zeroable};
-
- #[cfg(feature = "unstable")]
pub use core::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
}
////////////////////////////////////////////////////////////////////////////////
#[macro_use]
mod macros;
--- a/third_party/rust/serde/src/macros.rs
+++ b/third_party/rust/serde/src/macros.rs
@@ -26,24 +26,26 @@
/// # use serde::de::{value, Deserializer, Visitor};
/// #
/// # struct MyDeserializer;
/// #
/// # impl<'de> Deserializer<'de> for MyDeserializer {
/// # type Error = value::Error;
/// #
/// # fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
-/// # where V: Visitor<'de>
+/// # where
+/// # V: Visitor<'de>,
/// # {
/// # unimplemented!()
/// # }
/// #
/// #[inline]
/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-/// where V: Visitor<'de>
+/// where
+/// V: Visitor<'de>,
/// {
/// self.deserialize_any(visitor)
/// }
/// #
/// # forward_to_deserialize_any! {
/// # i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
/// # byte_buf option unit unit_struct newtype_struct seq tuple
/// # tuple_struct map struct enum identifier ignored_any
@@ -64,17 +66,18 @@
/// # use serde::de::{value, Deserializer, Visitor};
/// #
/// # struct MyDeserializer;
/// #
/// impl<'de> Deserializer<'de> for MyDeserializer {
/// # type Error = value::Error;
/// #
/// fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
-/// where V: Visitor<'de>
+/// where
+/// V: Visitor<'de>,
/// {
/// /* ... */
/// # let _ = visitor;
/// # unimplemented!()
/// }
///
/// forward_to_deserialize_any! {
/// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
@@ -100,17 +103,18 @@
/// # use serde::de::{value, Deserializer, Visitor};
/// #
/// # struct MyDeserializer<V>(PhantomData<V>);
/// #
/// # impl<'q, V> Deserializer<'q> for MyDeserializer<V> {
/// # type Error = value::Error;
/// #
/// # fn deserialize_any<W>(self, visitor: W) -> Result<W::Value, Self::Error>
-/// # where W: Visitor<'q>
+/// # where
+/// # W: Visitor<'q>,
/// # {
/// # unimplemented!()
/// # }
/// #
/// forward_to_deserialize_any! {
/// <W: Visitor<'q>>
/// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
/// byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
--- a/third_party/rust/serde/src/private/de.rs
+++ b/third_party/rust/serde/src/private/de.rs
@@ -9,20 +9,21 @@
use lib::*;
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
#[cfg(any(feature = "std", feature = "alloc"))]
use de::{MapAccess, Unexpected};
#[cfg(any(feature = "std", feature = "alloc"))]
-pub use self::content::{Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer,
- InternallyTaggedUnitVisitor, TagContentOtherField,
- TagContentOtherFieldVisitor, TagOrContentField, TagOrContentFieldVisitor,
- TaggedContentVisitor, UntaggedUnitVisitor};
+pub use self::content::{
+ Content, ContentDeserializer, ContentRefDeserializer, EnumDeserializer,
+ InternallyTaggedUnitVisitor, TagContentOtherField, TagContentOtherFieldVisitor,
+ TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor,
+};
/// If the missing field is of type `Option<T>` then treat is as `None`,
/// otherwise it is an error.
pub fn missing_field<'de, V, E>(field: &'static str) -> Result<V, E>
where
V: Deserialize<'de>,
E: Error,
{
@@ -224,18 +225,20 @@ mod content {
// rather than for this entire mechanism.
//
// This issue is tracking making some of this stuff public:
// https://github.com/serde-rs/serde/issues/741
use lib::*;
use super::size_hint;
- use de::{self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, MapAccess, SeqAccess,
- Unexpected, Visitor};
+ use de::{
+ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess,
+ SeqAccess, Unexpected, Visitor,
+ };
/// Used from generated code to buffer the contents of the Deserializer when
/// deserializing untagged enums and internally tagged enums.
///
/// Not public API. Use serde-value instead.
#[derive(Debug)]
pub enum Content<'de> {
Bool(bool),
@@ -268,20 +271,23 @@ mod content {
Map(Vec<(Content<'de>, Content<'de>)>),
}
impl<'de> Content<'de> {
pub fn as_str(&self) -> Option<&str> {
match *self {
Content::Str(x) => Some(x),
Content::String(ref x) => Some(x),
+ Content::Bytes(x) => str::from_utf8(x).ok(),
+ Content::ByteBuf(ref x) => str::from_utf8(x).ok(),
_ => None,
}
}
+ #[cold]
fn unexpected(&self) -> Unexpected {
match *self {
Content::Bool(b) => Unexpected::Bool(b),
Content::U8(n) => Unexpected::Unsigned(n as u64),
Content::U16(n) => Unexpected::Unsigned(n as u64),
Content::U32(n) => Unexpected::Unsigned(n as u64),
Content::U64(n) => Unexpected::Unsigned(n),
Content::I8(n) => Unexpected::Signed(n as i64),
@@ -1008,16 +1014,72 @@ mod content {
}
/// Not public API
pub struct ContentDeserializer<'de, E> {
content: Content<'de>,
err: PhantomData<E>,
}
+ impl<'de, E> ContentDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ #[cold]
+ fn invalid_type(self, exp: &Expected) -> E {
+ de::Error::invalid_type(self.content.unexpected(), exp)
+ }
+
+ fn deserialize_integer<V>(self, visitor: V) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::U8(v) => visitor.visit_u8(v),
+ Content::U16(v) => visitor.visit_u16(v),
+ Content::U32(v) => visitor.visit_u32(v),
+ Content::U64(v) => visitor.visit_u64(v),
+ Content::I8(v) => visitor.visit_i8(v),
+ Content::I16(v) => visitor.visit_i16(v),
+ Content::I32(v) => visitor.visit_i32(v),
+ Content::I64(v) => visitor.visit_i64(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+ }
+
+ fn visit_content_seq<'de, V, E>(content: Vec<Content<'de>>, visitor: V) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ E: de::Error,
+ {
+ let seq = content.into_iter().map(ContentDeserializer::new);
+ let mut seq_visitor = de::value::SeqDeserializer::new(seq);
+ let value = try!(visitor.visit_seq(&mut seq_visitor));
+ try!(seq_visitor.end());
+ Ok(value)
+ }
+
+ fn visit_content_map<'de, V, E>(
+ content: Vec<(Content<'de>, Content<'de>)>,
+ visitor: V,
+ ) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ E: de::Error,
+ {
+ let map = content
+ .into_iter()
+ .map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
+ let mut map_visitor = de::value::MapDeserializer::new(map);
+ let value = try!(visitor.visit_map(&mut map_visitor));
+ try!(map_visitor.end());
+ Ok(value)
+ }
+
/// Used when deserializing an internally tagged enum because the content will
/// be used exactly once.
impl<'de, E> Deserializer<'de> for ContentDeserializer<'de, E>
where
E: de::Error,
{
type Error = E;
@@ -1041,55 +1103,282 @@ mod content {
Content::String(v) => visitor.visit_string(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(v) => visitor.visit_byte_buf(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::Unit => visitor.visit_unit(),
Content::None => visitor.visit_none(),
Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)),
Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)),
- Content::Seq(v) => {
- let seq = v.into_iter().map(ContentDeserializer::new);
- let mut seq_visitor = de::value::SeqDeserializer::new(seq);
- let value = try!(visitor.visit_seq(&mut seq_visitor));
- try!(seq_visitor.end());
- Ok(value)
- }
- Content::Map(v) => {
- let map = v.into_iter()
- .map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
- let mut map_visitor = de::value::MapDeserializer::new(map);
- let value = try!(visitor.visit_map(&mut map_visitor));
- try!(map_visitor.end());
- Ok(value)
- }
+ Content::Seq(v) => visit_content_seq(v, visitor),
+ Content::Map(v) => visit_content_map(v, visitor),
+ }
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::Bool(v) => visitor.visit_bool(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::F32(v) => visitor.visit_f32(v),
+ Content::F64(v) => visitor.visit_f64(v),
+ Content::U64(v) => visitor.visit_u64(v),
+ Content::I64(v) => visitor.visit_i64(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::F64(v) => visitor.visit_f64(v),
+ Content::U64(v) => visitor.visit_u64(v),
+ Content::I64(v) => visitor.visit_i64(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::Char(v) => visitor.visit_char(v),
+ Content::String(v) => visitor.visit_string(v),
+ Content::Str(v) => visitor.visit_borrowed_str(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_string(visitor)
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::String(v) => visitor.visit_string(v),
+ Content::Str(v) => visitor.visit_borrowed_str(v),
+ Content::ByteBuf(v) => visitor.visit_byte_buf(v),
+ Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_byte_buf(visitor)
+ }
+
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::String(v) => visitor.visit_string(v),
+ Content::Str(v) => visitor.visit_borrowed_str(v),
+ Content::ByteBuf(v) => visitor.visit_byte_buf(v),
+ Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
+ Content::Seq(v) => visit_content_seq(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::None => visitor.visit_none(),
Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)),
Content::Unit => visitor.visit_unit(),
_ => visitor.visit_some(self),
}
}
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::Unit => visitor.visit_unit(),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_unit_struct<V>(
+ self,
+ _name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ // As a special case, allow deserializing untagged newtype
+ // variant containing unit struct.
+ //
+ // #[derive(Deserialize)]
+ // struct Info;
+ //
+ // #[derive(Deserialize)]
+ // #[serde(tag = "topic")]
+ // enum Message {
+ // Info(Info),
+ // }
+ //
+ // We want {"topic":"Info"} to deserialize even though
+ // ordinarily unit structs do not deserialize from empty map.
+ Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
+ _ => self.deserialize_any(visitor),
+ }
+ }
+
fn deserialize_newtype_struct<V>(
self,
_name: &str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
- visitor.visit_newtype_struct(self)
+ match self.content {
+ Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)),
+ _ => visitor.visit_newtype_struct(self),
+ }
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::Seq(v) => visit_content_seq(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_tuple_struct<V>(
+ self,
+ _name: &'static str,
+ _len: usize,
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::Map(v) => visit_content_map(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ _name: &'static str,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::Seq(v) => visit_content_seq(v, visitor),
+ Content::Map(v) => visit_content_map(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
}
fn deserialize_enum<V>(
self,
_name: &str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
@@ -1124,48 +1413,35 @@ mod content {
&"string or map",
));
}
};
visitor.visit_enum(EnumDeserializer::new(variant, value))
}
- fn deserialize_unit_struct<V>(
- self,
- _name: &'static str,
- visitor: V,
- ) -> Result<V::Value, Self::Error>
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
- // As a special case, allow deserializing untagged newtype
- // variant containing unit struct.
- //
- // #[derive(Deserialize)]
- // struct Info;
- //
- // #[derive(Deserialize)]
- // #[serde(tag = "topic")]
- // enum Message {
- // Info(Info),
- // }
- //
- // We want {"topic":"Info"} to deserialize even though
- // ordinarily unit structs do not deserialize from empty map.
- Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
- _ => self.deserialize_any(visitor),
+ Content::String(v) => visitor.visit_string(v),
+ Content::Str(v) => visitor.visit_borrowed_str(v),
+ Content::ByteBuf(v) => visitor.visit_byte_buf(v),
+ Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
+ _ => Err(self.invalid_type(&visitor)),
}
}
- forward_to_deserialize_any! {
- bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
- byte_buf unit seq tuple tuple_struct map struct identifier
- ignored_any
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ drop(self);
+ visitor.visit_unit()
}
}
impl<'de, E> ContentDeserializer<'de, E> {
/// private API, don't use
pub fn new(content: Content<'de>) -> Self {
ContentDeserializer {
content: content,
@@ -1447,16 +1723,78 @@ mod content {
}
/// Not public API.
pub struct ContentRefDeserializer<'a, 'de: 'a, E> {
content: &'a Content<'de>,
err: PhantomData<E>,
}
+ impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E>
+ where
+ E: de::Error,
+ {
+ #[cold]
+ fn invalid_type(self, exp: &Expected) -> E {
+ de::Error::invalid_type(self.content.unexpected(), exp)
+ }
+
+ fn deserialize_integer<V>(self, visitor: V) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::U8(v) => visitor.visit_u8(v),
+ Content::U16(v) => visitor.visit_u16(v),
+ Content::U32(v) => visitor.visit_u32(v),
+ Content::U64(v) => visitor.visit_u64(v),
+ Content::I8(v) => visitor.visit_i8(v),
+ Content::I16(v) => visitor.visit_i16(v),
+ Content::I32(v) => visitor.visit_i32(v),
+ Content::I64(v) => visitor.visit_i64(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+ }
+
+ fn visit_content_seq_ref<'a, 'de, V, E>(
+ content: &'a [Content<'de>],
+ visitor: V,
+ ) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ E: de::Error,
+ {
+ let seq = content.into_iter().map(ContentRefDeserializer::new);
+ let mut seq_visitor = de::value::SeqDeserializer::new(seq);
+ let value = try!(visitor.visit_seq(&mut seq_visitor));
+ try!(seq_visitor.end());
+ Ok(value)
+ }
+
+ fn visit_content_map_ref<'a, 'de, V, E>(
+ content: &'a [(Content<'de>, Content<'de>)],
+ visitor: V,
+ ) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ E: de::Error,
+ {
+ let map = content.into_iter().map(|&(ref k, ref v)| {
+ (
+ ContentRefDeserializer::new(k),
+ ContentRefDeserializer::new(v),
+ )
+ });
+ let mut map_visitor = de::value::MapDeserializer::new(map);
+ let value = try!(visitor.visit_map(&mut map_visitor));
+ try!(map_visitor.end());
+ Ok(value)
+ }
+
/// Used when deserializing an untagged enum because the content may need to be
/// used more than once.
impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, 'de, E>
where
E: de::Error,
{
type Error = E;
@@ -1482,55 +1820,263 @@ mod content {
Content::ByteBuf(ref v) => visitor.visit_bytes(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::Unit => visitor.visit_unit(),
Content::None => visitor.visit_none(),
Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)),
Content::Newtype(ref v) => {
visitor.visit_newtype_struct(ContentRefDeserializer::new(v))
}
- Content::Seq(ref v) => {
- let seq = v.into_iter().map(ContentRefDeserializer::new);
- let mut seq_visitor = de::value::SeqDeserializer::new(seq);
- let value = try!(visitor.visit_seq(&mut seq_visitor));
- try!(seq_visitor.end());
- Ok(value)
- }
- Content::Map(ref v) => {
- let map = v.into_iter().map(|&(ref k, ref v)| {
- (
- ContentRefDeserializer::new(k),
- ContentRefDeserializer::new(v),
- )
- });
- let mut map_visitor = de::value::MapDeserializer::new(map);
- let value = try!(visitor.visit_map(&mut map_visitor));
- try!(map_visitor.end());
- Ok(value)
- }
+ Content::Seq(ref v) => visit_content_seq_ref(v, visitor),
+ Content::Map(ref v) => visit_content_map_ref(v, visitor),
+ }
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::Bool(v) => visitor.visit_bool(v),
+ _ => Err(self.invalid_type(&visitor)),
}
}
+ fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_integer(visitor)
+ }
+
+ fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::F32(v) => visitor.visit_f32(v),
+ Content::F64(v) => visitor.visit_f64(v),
+ Content::U64(v) => visitor.visit_u64(v),
+ Content::I64(v) => visitor.visit_i64(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::F64(v) => visitor.visit_f64(v),
+ Content::U64(v) => visitor.visit_u64(v),
+ Content::I64(v) => visitor.visit_i64(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::Char(v) => visitor.visit_char(v),
+ Content::String(ref v) => visitor.visit_str(v),
+ Content::Str(v) => visitor.visit_borrowed_str(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::String(ref v) => visitor.visit_str(v),
+ Content::Str(v) => visitor.visit_borrowed_str(v),
+ Content::ByteBuf(ref v) => visitor.visit_bytes(v),
+ Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::String(ref v) => visitor.visit_str(v),
+ Content::Str(v) => visitor.visit_borrowed_str(v),
+ Content::ByteBuf(ref v) => visitor.visit_bytes(v),
+ Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
+ Content::Seq(ref v) => visit_content_seq_ref(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_bytes(visitor)
+ }
+
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E>
where
V: Visitor<'de>,
{
match *self.content {
Content::None => visitor.visit_none(),
Content::Some(ref v) => visitor.visit_some(ContentRefDeserializer::new(v)),
Content::Unit => visitor.visit_unit(),
_ => visitor.visit_some(self),
}
}
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::Unit => visitor.visit_unit(),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_unit_struct<V>(
+ self,
+ _name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_unit(visitor)
+ }
+
fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, E>
where
V: Visitor<'de>,
{
- visitor.visit_newtype_struct(self)
+ match *self.content {
+ Content::Newtype(ref v) => {
+ visitor.visit_newtype_struct(ContentRefDeserializer::new(v))
+ }
+ _ => visitor.visit_newtype_struct(self),
+ }
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::Seq(ref v) => visit_content_seq_ref(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_tuple_struct<V>(
+ self,
+ _name: &'static str,
+ _len: usize,
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::Map(ref v) => visit_content_map_ref(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ _name: &'static str,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::Seq(ref v) => visit_content_seq_ref(v, visitor),
+ Content::Map(ref v) => visit_content_map_ref(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
}
fn deserialize_enum<V>(
self,
_name: &str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
@@ -1569,20 +2115,34 @@ mod content {
visitor.visit_enum(EnumRefDeserializer {
variant: variant,
value: value,
err: PhantomData,
})
}
- forward_to_deserialize_any! {
- bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
- byte_buf unit unit_struct seq tuple tuple_struct map struct
- identifier ignored_any
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::String(ref v) => visitor.visit_str(v),
+ Content::Str(v) => visitor.visit_borrowed_str(v),
+ Content::ByteBuf(ref v) => visitor.visit_bytes(v),
+ Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_unit()
}
}
impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> {
/// private API, don't use
pub fn new(content: &'a Content<'de>) -> Self {
ContentRefDeserializer {
content: content,
@@ -2082,27 +2642,55 @@ where
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatMapDeserializer<'a, 'de: 'a, E>(
pub &'a mut Vec<Option<(Content<'de>, Content<'de>)>>,
pub PhantomData<E>,
);
#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de, E> FlatMapDeserializer<'a, 'de, E>
+where
+ E: Error,
+{
+ fn deserialize_other<V>() -> Result<V, E> {
+ Err(Error::custom("can only flatten structs and maps"))
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+macro_rules! forward_to_deserialize_other {
+ ($($func:ident ( $($arg:ty),* ))*) => {
+ $(
+ fn $func<V>(self, $(_: $arg,)* _visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ Self::deserialize_other()
+ }
+ )*
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> Deserializer<'de> for FlatMapDeserializer<'a, 'de, E>
where
E: Error,
{
type Error = E;
- fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
- Err(Error::custom("can only flatten structs and maps"))
+ visitor.visit_map(FlatInternallyTaggedAccess {
+ iter: self.0.iter_mut(),
+ pending: None,
+ _marker: PhantomData,
+ })
}
fn deserialize_enum<V>(
self,
name: &'static str,
variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
@@ -2151,20 +2739,50 @@ where
fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
}
- forward_to_deserialize_any! {
- bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
- byte_buf option unit unit_struct seq tuple tuple_struct identifier
- ignored_any
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match visitor.__private_visit_untagged_option(self) {
+ Ok(value) => Ok(value),
+ Err(()) => Self::deserialize_other(),
+ }
+ }
+
+ forward_to_deserialize_other! {
+ deserialize_bool()
+ deserialize_i8()
+ deserialize_i16()
+ deserialize_i32()
+ deserialize_i64()
+ deserialize_u8()
+ deserialize_u16()
+ deserialize_u32()
+ deserialize_u64()
+ deserialize_f32()
+ deserialize_f64()
+ deserialize_char()
+ deserialize_str()
+ deserialize_string()
+ deserialize_bytes()
+ deserialize_byte_buf()
+ deserialize_unit()
+ deserialize_unit_struct(&'static str)
+ deserialize_seq()
+ deserialize_tuple(usize)
+ deserialize_tuple_struct(&'static str, usize)
+ deserialize_identifier()
+ deserialize_ignored_any()
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatMapAccess<'a, 'de: 'a, E> {
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
pending_content: Option<Content<'de>>,
fields: Option<&'static [&'static str]>,
@@ -2227,8 +2845,51 @@ where
T: DeserializeSeed<'de>,
{
match self.pending_content.take() {
Some(value) => seed.deserialize(ContentDeserializer::new(value)),
None => Err(Error::custom("value is missing")),
}
}
}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatInternallyTaggedAccess<'a, 'de: 'a, E> {
+ iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
+ pending: Option<&'a Content<'de>>,
+ _marker: PhantomData<E>,
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de, E> MapAccess<'de> for FlatInternallyTaggedAccess<'a, 'de, E>
+where
+ E: Error,
+{
+ type Error = E;
+
+ fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some(item) => {
+ // Do not take(), instead borrow this entry. The internally tagged
+ // enum does its own buffering so we can't tell whether this entry
+ // is going to be consumed. Borrowing here leaves the entry
+ // available for later flattened fields.
+ let (ref key, ref content) = *item.as_ref().unwrap();
+ self.pending = Some(content);
+ seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.pending.take() {
+ Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
+ None => panic!("value is missing"),
+ }
+ }
+}
--- a/third_party/rust/serde/src/private/ser.rs
+++ b/third_party/rust/serde/src/private/ser.rs
@@ -6,18 +6,19 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
#[cfg(any(feature = "std", feature = "alloc"))]
-use self::content::{Content, ContentSerializer, SerializeStructVariantAsMapValue,
- SerializeTupleVariantAsMapValue};
+use self::content::{
+ Content, ContentSerializer, SerializeStructVariantAsMapValue, SerializeTupleVariantAsMapValue,
+};
/// Used to check that serde(getter) attributes return the expected type.
/// Not public API.
pub fn constrain<T: ?Sized>(t: &T) -> &T {
t
}
/// Not public API.
@@ -1116,24 +1117,24 @@ where
Err(self.bad_type(Unsupported::String))
}
fn serialize_bytes(self, _: &[u8]) -> Result<Self::Ok, Self::Error> {
Err(self.bad_type(Unsupported::ByteArray))
}
fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
- Err(self.bad_type(Unsupported::Optional))
+ Ok(())
}
- fn serialize_some<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error>
+ fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Serialize,
{
- Err(self.bad_type(Unsupported::Optional))
+ value.serialize(self)
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(self.bad_type(Unsupported::Unit))
}
fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
Err(self.bad_type(Unsupported::UnitStruct))
--- a/third_party/rust/serde/src/ser/impls.rs
+++ b/third_party/rust/serde/src/ser/impls.rs
@@ -369,30 +369,50 @@ deref_impl! {
<T: ?Sized> Serialize for Arc<T> where T: Serialize
}
#[cfg(any(feature = "std", feature = "alloc"))]
deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned);
////////////////////////////////////////////////////////////////////////////////
-#[cfg(feature = "unstable")]
-#[allow(deprecated)]
-impl<T> Serialize for NonZero<T>
+/// This impl requires the [`"rc"`] Cargo feature of Serde.
+///
+/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
+#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
+impl<T: ?Sized> Serialize for RcWeak<T>
where
- T: Serialize + Zeroable + Clone,
+ T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
- self.clone().get().serialize(serializer)
+ self.upgrade().serialize(serializer)
}
}
+/// This impl requires the [`"rc"`] Cargo feature of Serde.
+///
+/// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
+#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
+impl<T: ?Sized> Serialize for ArcWeak<T>
+where
+ T: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.upgrade().serialize(serializer)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
macro_rules! nonzero_integers {
( $( $T: ident, )+ ) => {
$(
#[cfg(feature = "unstable")]
impl Serialize for $T {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
--- a/third_party/rust/serde/src/ser/impossible.rs
+++ b/third_party/rust/serde/src/ser/impossible.rs
@@ -5,18 +5,20 @@
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! This module contains `Impossible` serializer and its implementations.
use lib::*;
-use ser::{self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
- SerializeTuple, SerializeTupleStruct, SerializeTupleVariant};
+use ser::{
+ self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
+ SerializeTuple, SerializeTupleStruct, SerializeTupleVariant,
+};
/// Helper type for implementing a `Serializer` that does not support
/// serializing one of the compound types.
///
/// This type cannot be instantiated, but implements every one of the traits
/// corresponding to the [`Serializer`] compound types: [`SerializeSeq`],
/// [`SerializeTuple`], [`SerializeTupleStruct`], [`SerializeTupleVariant`],
/// [`SerializeMap`], [`SerializeStruct`], and [`SerializeStructVariant`].
--- a/third_party/rust/serde/src/ser/mod.rs
+++ b/third_party/rust/serde/src/ser/mod.rs
@@ -76,29 +76,27 @@
//! - BTreeMap\<K, V\>
//! - BTreeSet\<T\>
//! - BinaryHeap\<T\>
//! - HashMap\<K, V, H\>
//! - HashSet\<T, H\>
//! - LinkedList\<T\>
//! - VecDeque\<T\>
//! - Vec\<T\>
-//! - EnumSet\<T\> (unstable)
//! - **FFI types**:
//! - CStr
//! - CString
//! - OsStr
//! - OsString
//! - **Miscellaneous standard library types**:
//! - Duration
//! - SystemTime
//! - Path
//! - PathBuf
//! - Range\<T\>
-//! - NonZero\<T\> (unstable, deprecated)
//! - num::NonZero* (unstable)
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
//! - Ipv6Addr
//! - SocketAddr
//! - SocketAddrV4
//! - SocketAddrV6
@@ -147,17 +145,18 @@ macro_rules! declare_error_trait {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::ser::{self, Serialize, Serializer};
///
/// impl Serialize for Path {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// match self.to_str() {
/// Some(s) => serializer.serialize_str(s),
/// None => Err(ser::Error::custom("path contains invalid UTF-8 characters")),
/// }
/// }
/// }
/// ```
@@ -218,17 +217,18 @@ pub trait Serialize {
/// name: String,
/// age: u8,
/// phones: Vec<String>,
/// }
///
/// // This is what #[derive(Serialize)] would generate.
/// impl Serialize for Person {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// let mut s = serializer.serialize_struct("Person", 3)?;
/// s.serialize_field("name", &self.name)?;
/// s.serialize_field("age", &self.age)?;
/// s.serialize_field("phones", &self.phones)?;
/// s.end()
/// }
/// }
@@ -372,17 +372,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for bool {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_bool(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;
@@ -398,17 +399,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for i8 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_i8(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>;
@@ -424,17 +426,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for i16 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_i16(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>;
@@ -450,17 +453,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for i32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_i32(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>;
@@ -472,17 +476,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for i64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_i64(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>;
@@ -498,17 +503,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for u8 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_u8(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>;
@@ -524,17 +530,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for u16 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_u16(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>;
@@ -550,17 +557,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for u32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_u32(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>;
@@ -572,17 +580,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for u64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_u64(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>;
@@ -598,17 +607,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for f32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_f32(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>;
@@ -620,17 +630,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for f64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_f64(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>;
@@ -645,17 +656,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for char {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_char(*self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>;
@@ -667,17 +679,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for str {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_str(self)
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error>;
@@ -732,20 +745,22 @@ pub trait Serializer: Sized {
/// # enum Option<T> {
/// # Some(T),
/// # None,
/// # }
/// #
/// # use Option::{Some, None};
/// #
/// impl<T> Serialize for Option<T>
- /// where T: Serialize
+ /// where
+ /// T: Serialize,
/// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// match *self {
/// Some(ref value) => serializer.serialize_some(value),
/// None => serializer.serialize_none(),
/// }
/// }
/// }
/// #
@@ -765,20 +780,22 @@ pub trait Serializer: Sized {
/// # enum Option<T> {
/// # Some(T),
/// # None,
/// # }
/// #
/// # use Option::{Some, None};
/// #
/// impl<T> Serialize for Option<T>
- /// where T: Serialize
+ /// where
+ /// T: Serialize,
/// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// match *self {
/// Some(ref value) => serializer.serialize_some(value),
/// None => serializer.serialize_none(),
/// }
/// }
/// }
/// #
@@ -797,17 +814,18 @@ pub trait Serializer: Sized {
/// # extern crate serde;
/// #
/// # use serde::Serializer;
/// #
/// # __private_serialize!();
/// #
/// impl Serialize for () {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_unit()
/// }
/// }
/// #
/// # fn main() {}
/// ```
fn serialize_unit(self) -> Result<Self::Ok, Self::Error>;
@@ -818,17 +836,18 @@ pub trait Serializer: Sized {
///
/// ```rust
/// use serde::{Serialize, Serializer};
///
/// struct Nothing;
///
/// impl Serialize for Nothing {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_unit_struct("Nothing")
/// }
/// }
/// ```
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error>;
/// Serialize a unit variant like `E::A` in `enum E { A, B }`.
@@ -842,17 +861,18 @@ pub trait Serializer: Sized {
///
/// enum E {
/// A,
/// B,
/// }
///
/// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// match *self {
/// E::A => serializer.serialize_unit_variant("E", 0, "A"),
/// E::B => serializer.serialize_unit_variant("E", 1, "B"),
/// }
/// }
/// }
/// ```
@@ -871,17 +891,18 @@ pub trait Serializer: Sized {
///
/// ```rust
/// use serde::{Serialize, Serializer};
///
/// struct Millimeters(u8);
///
/// impl Serialize for Millimeters {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.serialize_newtype_struct("Millimeters", &self.0)
/// }
/// }
/// ```
fn serialize_newtype_struct<T: ?Sized>(
self,
name: &'static str,
@@ -901,17 +922,18 @@ pub trait Serializer: Sized {
///
/// enum E {
/// M(String),
/// N(u8),
/// }
///
/// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// match *self {
/// E::M(ref s) => serializer.serialize_newtype_variant("E", 0, "M", s),
/// E::N(n) => serializer.serialize_newtype_variant("E", 1, "N", &n),
/// }
/// }
/// }
/// ```
@@ -951,20 +973,22 @@ pub trait Serializer: Sized {
/// # fn into_iter(self) -> Self::IntoIter {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::ser::{Serialize, Serializer, SerializeSeq};
///
/// impl<T> Serialize for Vec<T>
- /// where T: Serialize
+ /// where
+ /// T: Serialize,
/// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// }
/// }
@@ -983,22 +1007,24 @@ pub trait Serializer: Sized {
/// # trait Serialize {}
/// impl<A, B, C> Serialize for (A, B, C)
/// # {}
/// # }
/// #
/// # struct Tuple3<A, B, C>(A, B, C);
/// #
/// # impl<A, B, C> Serialize for Tuple3<A, B, C>
- /// where A: Serialize,
- /// B: Serialize,
- /// C: Serialize
+ /// where
+ /// A: Serialize,
+ /// B: Serialize,
+ /// C: Serialize,
/// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// let mut tup = serializer.serialize_tuple(3)?;
/// tup.serialize_element(&self.0)?;
/// tup.serialize_element(&self.1)?;
/// tup.serialize_element(&self.2)?;
/// tup.end()
/// }
/// }
@@ -1007,17 +1033,18 @@ pub trait Serializer: Sized {
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTuple};
///
/// const VRAM_SIZE: usize = 386;
/// struct Vram([u16; VRAM_SIZE]);
///
/// impl Serialize for Vram {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// let mut seq = serializer.serialize_tuple(VRAM_SIZE)?;
/// for element in &self.0[..] {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// }
/// }
@@ -1033,17 +1060,18 @@ pub trait Serializer: Sized {
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleStruct};
///
/// struct Rgb(u8, u8, u8);
///
/// impl Serialize for Rgb {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
/// ts.serialize_field(&self.0)?;
/// ts.serialize_field(&self.1)?;
/// ts.serialize_field(&self.2)?;
/// ts.end()
/// }
/// }
@@ -1067,17 +1095,18 @@ pub trait Serializer: Sized {
///
/// enum E {
/// T(u8, u8),
/// U(String, u32, u32),
/// }
///
/// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// match *self {
/// E::T(ref a, ref b) => {
/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?;
/// tv.serialize_field(a)?;
/// tv.serialize_field(b)?;
/// tv.end()
/// }
@@ -1125,21 +1154,23 @@ pub trait Serializer: Sized {
/// # fn into_iter(self) -> Self::IntoIter {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::ser::{Serialize, Serializer, SerializeMap};
///
/// impl<K, V> Serialize for HashMap<K, V>
- /// where K: Serialize,
- /// V: Serialize
+ /// where
+ /// K: Serialize,
+ /// V: Serialize,
/// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// let mut map = serializer.serialize_map(Some(self.len()))?;
/// for (k, v) in self {
/// map.serialize_entry(k, v)?;
/// }
/// map.end()
/// }
/// }
@@ -1159,17 +1190,18 @@ pub trait Serializer: Sized {
/// struct Rgb {
/// r: u8,
/// g: u8,
/// b: u8,
/// }
///
/// impl Serialize for Rgb {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// let mut rgb = serializer.serialize_struct("Rgb", 3)?;
/// rgb.serialize_field("r", &self.r)?;
/// rgb.serialize_field("g", &self.g)?;
/// rgb.serialize_field("b", &self.b)?;
/// rgb.end()
/// }
/// }
@@ -1192,17 +1224,18 @@ pub trait Serializer: Sized {
/// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
///
/// enum E {
/// S { r: u8, g: u8, b: u8 }
/// }
///
/// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
/// sv.serialize_field("b", b)?;
/// sv.end()
@@ -1229,17 +1262,18 @@ pub trait Serializer: Sized {
/// use serde::{Serialize, Serializer};
///
/// struct SecretlyOneHigher {
/// data: Vec<i32>,
/// }
///
/// impl Serialize for SecretlyOneHigher {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.collect_seq(self.data.iter().map(|x| x + 1))
/// }
/// }
/// ```
///
/// [`serialize_seq`]: #tymethod.serialize_seq
fn collect_seq<I>(self, iter: I) -> Result<Self::Ok, Self::Error>
@@ -1267,17 +1301,18 @@ pub trait Serializer: Sized {
///
/// struct MapToUnit {
/// keys: BTreeSet<i32>,
/// }
///
/// // Serializes as a map in which the values are all unit.
/// impl Serialize for MapToUnit {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.collect_map(self.keys.iter().map(|k| (k, ())))
/// }
/// }
/// ```
///
/// [`serialize_map`]: #tymethod.serialize_map
fn collect_map<K, V, I>(self, iter: I) -> Result<Self::Ok, Self::Error>
@@ -1307,17 +1342,18 @@ pub trait Serializer: Sized {
/// # fn naive_local(&self) -> () { () }
/// # fn offset(&self) -> () { () }
/// # }
/// #
/// use serde::{Serialize, Serializer};
///
/// impl Serialize for DateTime {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.collect_str(&format_args!("{:?}{:?}",
/// self.naive_local(),
/// self.offset()))
/// }
/// }
/// ```
///
@@ -1347,17 +1383,18 @@ pub trait Serializer: Sized {
/// # fn naive_local(&self) -> () { () }
/// # fn offset(&self) -> () { () }
/// # }
/// #
/// use serde::{Serialize, Serializer};
///
/// impl Serialize for DateTime {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// serializer.collect_str(&format_args!("{:?}{:?}",
/// self.naive_local(),
/// self.offset()))
/// }
/// }
/// ```
#[cfg(not(any(feature = "std", feature = "alloc")))]
@@ -1388,17 +1425,18 @@ pub trait Serializer: Sized {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::{Serialize, Serializer};
///
/// impl Serialize for Timestamp {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- /// where S: Serializer
+ /// where
+ /// S: Serializer,
/// {
/// if serializer.is_human_readable() {
/// // Serialize to a human-readable string "2015-05-15T17:01:00Z".
/// self.to_string().serialize(serializer)
/// } else {
/// // Serialize to a compact binary representation.
/// self.seconds_since_epoch().serialize(serializer)
/// }
@@ -1437,20 +1475,22 @@ pub trait Serializer: Sized {
/// # fn into_iter(self) -> Self::IntoIter {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::ser::{Serialize, Serializer, SerializeSeq};
///
/// impl<T> Serialize for Vec<T>
-/// where T: Serialize
+/// where
+/// T: Serialize,
/// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-/// where S: Serializer
+/// where
+/// S: Serializer,
/// {
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// }
/// }
@@ -1480,22 +1520,24 @@ pub trait SerializeSeq {
/// # trait Serialize {}
/// impl<A, B, C> Serialize for (A, B, C)
/// # {}
/// # }
/// #
/// # struct Tuple3<A, B, C>(A, B, C);
/// #
/// # impl<A, B, C> Serialize for Tuple3<A, B, C>
-/// where A: Serialize,
-/// B: Serialize,
-/// C: Serialize
+/// where
+/// A: Serialize,
+/// B: Serialize,
+/// C: Serialize,
/// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-/// where S: Serializer
+/// where
+/// S: Serializer,
/// {
/// let mut tup = serializer.serialize_tuple(3)?;
/// tup.serialize_element(&self.0)?;
/// tup.serialize_element(&self.1)?;
/// tup.serialize_element(&self.2)?;
/// tup.end()
/// }
/// }
@@ -1524,20 +1566,22 @@ pub trait SerializeSeq {
///
/// # mod fool {
/// # trait Serialize {}
/// impl<T> Serialize for [T; 16]
/// # {}
/// # }
/// #
/// # impl<T> Serialize for Array<T>
-/// where T: Serialize
+/// where
+/// T: Serialize,
/// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-/// where S: Serializer
+/// where
+/// S: Serializer,
/// {
/// let mut seq = serializer.serialize_tuple(16)?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// }
/// }
@@ -1562,17 +1606,18 @@ pub trait SerializeTuple {
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleStruct};
///
/// struct Rgb(u8, u8, u8);
///
/// impl Serialize for Rgb {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-/// where S: Serializer
+/// where
+/// S: Serializer,
/// {
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
/// ts.serialize_field(&self.0)?;
/// ts.serialize_field(&self.1)?;
/// ts.serialize_field(&self.2)?;
/// ts.end()
/// }
/// }
@@ -1600,17 +1645,18 @@ pub trait SerializeTupleStruct {
///
/// enum E {
/// T(u8, u8),
/// U(String, u32, u32),
/// }
///
/// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-/// where S: Serializer
+/// where
+/// S: Serializer,
/// {
/// match *self {
/// E::T(ref a, ref b) => {
/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?;
/// tv.serialize_field(a)?;
/// tv.serialize_field(b)?;
/// tv.end()
/// }
@@ -1661,21 +1707,23 @@ pub trait SerializeTupleVariant {
/// # fn into_iter(self) -> Self::IntoIter {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::ser::{Serialize, Serializer, SerializeMap};
///
/// impl<K, V> Serialize for HashMap<K, V>
-/// where K: Serialize,
-/// V: Serialize
+/// where
+/// K: Serialize,
+/// V: Serialize,
/// {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-/// where S: Serializer
+/// where
+/// S: Serializer,
/// {
/// let mut map = serializer.serialize_map(Some(self.len()))?;
/// for (k, v) in self {
/// map.serialize_entry(k, v)?;
/// }
/// map.end()
/// }
/// }
@@ -1749,17 +1797,18 @@ pub trait SerializeMap {
/// struct Rgb {
/// r: u8,
/// g: u8,
/// b: u8,
/// }
///
/// impl Serialize for Rgb {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-/// where S: Serializer
+/// where
+/// S: Serializer,
/// {
/// let mut rgb = serializer.serialize_struct("Rgb", 3)?;
/// rgb.serialize_field("r", &self.r)?;
/// rgb.serialize_field("g", &self.g)?;
/// rgb.serialize_field("b", &self.b)?;
/// rgb.end()
/// }
/// }
@@ -1797,17 +1846,18 @@ pub trait SerializeStruct {
/// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
///
/// enum E {
/// S { r: u8, g: u8, b: u8 }
/// }
///
/// impl Serialize for E {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
-/// where S: Serializer
+/// where
+/// S: Serializer,
/// {
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
/// sv.serialize_field("b", b)?;
/// sv.end()
--- a/third_party/rust/serde_derive/.cargo-checksum.json
+++ b/third_party/rust/serde_derive/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"c987a2cf69dc2e3ad028ba1175e908c839861c7661211fd3c754a389518145d5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"16de77b2d10fac8c70219ba183ad083ae12d4553c6f3213dec39d9936622b371","src/bound.rs":"a0c2e547828d0e40c7f8998cdb13c051edc69cadf9e87e3d7e4c1058ae30898f","src/de.rs":"d4b7988a0b2bb970fb4d4c0345f53278ca3ebdee1140ad54e805a8cfe53d14df","src/fragment.rs":"4e34eca12e6ac4bd89f55e85786cfb677e98182f21ce1f51c0573bca5a8bcd27","src/lib.rs":"c02319fb2021036b21768c36925e79bc50b63cab18e263f9c7ee1358d55330c4","src/ser.rs":"f841abfbaab2286836bda12b2e0cac8c588640949c50bb85c6e9525d3f72fa6c"},"package":null}
\ No newline at end of file
+{"files":{"Cargo.toml":"c89d9663763b180430561da049809839332300df1fb69d544fded497f06eaab3","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"16de77b2d10fac8c70219ba183ad083ae12d4553c6f3213dec39d9936622b371","src/bound.rs":"4f8453ecfa0b6231abd35985bc0bfe64d42df613102ff6c8357425666392572b","src/de.rs":"2651f6cb8851b5fc7c1cd8d5d1ab9806064775bd33d31d4d2f056000ef561b93","src/fragment.rs":"4e34eca12e6ac4bd89f55e85786cfb677e98182f21ce1f51c0573bca5a8bcd27","src/internals/ast.rs":"2aea7bead7503c799320ad03ab03f1460e08445bc8234fbb9def99fdbebadfa5","src/internals/attr.rs":"ab3b80b8374b98d44a2fe363cbd967d94064d38ac4802d13a70ba4ab61aac4a2","src/internals/case.rs":"a07abcf7e2b7e4d72eaa1b3ce97d82b17c94533ed0ea88ea5d13d3cbf4394520","src/internals/check.rs":"72c3e01ba8adabcc9530235d0d317c54392a7fae156763022c8fd812aea86791","src/internals/ctxt.rs":"f541083477396a13cf7abd3dab448907112f900a6395ddd42ed0a6717ada1016","src/internals/mod.rs":"853f91744e77cb54222092225bc61a02b42b83ee25cb99079f7c55fbc868d481","src/lib.rs":"5ec1c796b697c55f285080db930ddaad852097763dddf11ddb05ad12eaabd32a","src/pretend.rs":"18cbafe2c936e831fe41b03562c0e8f49abfd27d29d6d31cb54e5adff39ec606","src/ser.rs":"b2c58b05fcb5aba689af722121a5db40b1d247b0d875f390769a6d98413af22f","src/try.rs":"93d3d832168f1df37852bca5e8ebfd8b77982379ecd68bb361669cae413491f8"},"package":null}
\ No newline at end of file
--- a/third_party/rust/serde_derive/Cargo.toml
+++ b/third_party/rust/serde_derive/Cargo.toml
@@ -1,11 +1,11 @@
[package]
name = "serde_derive"
-version = "1.0.37" # remember to update html_root_url
+version = "1.0.58" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://serde.rs/codegen.html"
keywords = ["serde", "serialization", "no_std"]
readme = "README.md"
@@ -19,14 +19,13 @@ default = []
deserialize_in_place = []
[lib]
name = "serde_derive"
proc-macro = true
[dependencies]
proc-macro2 = "0.3"
-quote = "0.5"
-serde_derive_internals = { version = "=0.23.0", default-features = false, path = "../serde_derive_internals" }
-syn = { version = "0.13", features = ["visit"] }
+quote = "0.5.2"
+syn = { version = "0.13", features = ["visit", "extra-traits"] }
[dev-dependencies]
serde = { version = "1.0", path = "../serde" }
--- a/third_party/rust/serde_derive/src/bound.rs
+++ b/third_party/rust/serde_derive/src/bound.rs
@@ -3,290 +3,310 @@
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::collections::HashSet;
-use syn::{self, visit};
-use syn::punctuated::Punctuated;
+use syn;
+use syn::punctuated::{Pair, Punctuated};
+use syn::visit::{self, Visit};
-use internals::ast::{Data, Container};
+use internals::ast::{Container, Data};
use internals::attr;
use proc_macro2::Span;
// Remove the default from every type parameter because in the generated impls
// they look like associated types: "error: associated type bindings are not
// allowed here".
pub fn without_defaults(generics: &syn::Generics) -> syn::Generics {
syn::Generics {
params: generics
.params
.iter()
.map(|param| match *param {
- syn::GenericParam::Type(ref param) => {
- syn::GenericParam::Type(syn::TypeParam {
- eq_token: None,
- default: None,
- ..param.clone()
- })
- }
+ syn::GenericParam::Type(ref param) => syn::GenericParam::Type(syn::TypeParam {
+ eq_token: None,
+ default: None,
+ ..param.clone()
+ }),
_ => param.clone(),
})
.collect(),
..generics.clone()
}
}
pub fn with_where_predicates(
generics: &syn::Generics,
predicates: &[syn::WherePredicate],
) -> syn::Generics {
let mut generics = generics.clone();
- generics.make_where_clause()
+ generics
+ .make_where_clause()
.predicates
.extend(predicates.into_iter().cloned());
generics
}
-pub fn with_where_predicates_from_fields<F>(
+pub fn with_where_predicates_from_fields(
cont: &Container,
generics: &syn::Generics,
- from_field: F,
-) -> syn::Generics
-where
- F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]>,
-{
+ from_field: fn(&attr::Field) -> Option<&[syn::WherePredicate]>,
+) -> syn::Generics {
let predicates = cont.data
.all_fields()
.flat_map(|field| from_field(&field.attrs))
.flat_map(|predicates| predicates.to_vec());
let mut generics = generics.clone();
- generics.make_where_clause()
- .predicates
- .extend(predicates);
+ generics.make_where_clause().predicates.extend(predicates);
+ generics
+}
+
+pub fn with_where_predicates_from_variants(
+ cont: &Container,
+ generics: &syn::Generics,
+ from_variant: fn(&attr::Variant) -> Option<&[syn::WherePredicate]>,
+) -> syn::Generics {
+ let variants = match cont.data {
+ Data::Enum(_, ref variants) => variants,
+ Data::Struct(_, _) => {
+ return generics.clone();
+ }
+ };
+
+ let predicates = variants
+ .iter()
+ .flat_map(|variant| from_variant(&variant.attrs))
+ .flat_map(|predicates| predicates.to_vec());
+
+ let mut generics = generics.clone();
+ generics.make_where_clause().predicates.extend(predicates);
generics
}
// Puts the given bound on any generic type parameters that are used in fields
// for which filter returns true.
//
// For example, the following struct needs the bound `A: Serialize, B: Serialize`.
//
// struct S<'b, A, B: 'b, C> {
// a: A,
// b: Option<&'b B>
// #[serde(skip_serializing)]
// c: C,
// }
-pub fn with_bound<F>(
+pub fn with_bound(
cont: &Container,
generics: &syn::Generics,
- filter: F,
+ filter: fn(&attr::Field, Option<&attr::Variant>) -> bool,
bound: &syn::Path,
-) -> syn::Generics
-where
- F: Fn(&attr::Field, Option<&attr::Variant>) -> bool,
-{
- struct FindTyParams {
+) -> syn::Generics {
+ struct FindTyParams<'ast> {
// Set of all generic type parameters on the current struct (A, B, C in
// the example). Initialized up front.
- all_ty_params: HashSet<syn::Ident>,
+ all_type_params: HashSet<syn::Ident>,
+
// Set of generic type parameters used in fields for which filter
// returns true (A and B in the example). Filled in as the visitor sees
// them.
- relevant_ty_params: HashSet<syn::Ident>,
+ relevant_type_params: HashSet<syn::Ident>,
+
+ // Fields whose type is an associated type of one of the generic type
+ // parameters.
+ associated_type_usage: Vec<&'ast syn::TypePath>,
}
- impl<'ast> visit::Visit<'ast> for FindTyParams {
- fn visit_path(&mut self, path: &syn::Path) {
+ impl<'ast> Visit<'ast> for FindTyParams<'ast> {
+ fn visit_field(&mut self, field: &'ast syn::Field) {
+ if let syn::Type::Path(ref ty) = field.ty {
+ if let Some(Pair::Punctuated(ref t, _)) = ty.path.segments.first() {
+ if self.all_type_params.contains(&t.ident) {
+ self.associated_type_usage.push(ty);
+ }
+ }
+ }
+ self.visit_type(&field.ty);
+ }
+
+ fn visit_path(&mut self, path: &'ast syn::Path) {
if let Some(seg) = path.segments.last() {
if seg.into_value().ident == "PhantomData" {
// Hardcoded exception, because PhantomData<T> implements
// Serialize and Deserialize whether or not T implements it.
return;
}
}
if path.leading_colon.is_none() && path.segments.len() == 1 {
let id = path.segments[0].ident;
- if self.all_ty_params.contains(&id) {
- self.relevant_ty_params.insert(id);
+ if self.all_type_params.contains(&id) {
+ self.relevant_type_params.insert(id);
}
}
visit::visit_path(self, path);
}
// Type parameter should not be considered used by a macro path.
//
// struct TypeMacro<T> {
// mac: T!(),
// marker: PhantomData<T>,
// }
- fn visit_macro(&mut self, _mac: &syn::Macro) {}
+ fn visit_macro(&mut self, _mac: &'ast syn::Macro) {}
}
- let all_ty_params: HashSet<_> = generics
- .params
- .iter()
- .filter_map(|param| match *param {
- syn::GenericParam::Type(ref param) => Some(param.ident),
- _ => None,
- })
- .collect();
+ let all_type_params = generics.type_params().map(|param| param.ident).collect();
let mut visitor = FindTyParams {
- all_ty_params: all_ty_params,
- relevant_ty_params: HashSet::new(),
+ all_type_params: all_type_params,
+ relevant_type_params: HashSet::new(),
+ associated_type_usage: Vec::new(),
};
match cont.data {
Data::Enum(_, ref variants) => for variant in variants.iter() {
let relevant_fields = variant
.fields
.iter()
.filter(|field| filter(&field.attrs, Some(&variant.attrs)));
for field in relevant_fields {
- visit::visit_type(&mut visitor, field.ty);
+ visitor.visit_field(field.original);
}
},
Data::Struct(_, ref fields) => {
for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
- visit::visit_type(&mut visitor, field.ty);
+ visitor.visit_field(field.original);
}
}
}
+ let relevant_type_params = visitor.relevant_type_params;
+ let associated_type_usage = visitor.associated_type_usage;
let new_predicates = generics
- .params
- .iter()
- .filter_map(|param| match *param {
- syn::GenericParam::Type(ref param) => Some(param.ident),
- _ => None,
+ .type_params()
+ .map(|param| param.ident)
+ .filter(|id| relevant_type_params.contains(id))
+ .map(|id| syn::TypePath {
+ qself: None,
+ path: id.into(),
})
- .filter(|id| visitor.relevant_ty_params.contains(id))
- .map(|id| {
+ .chain(associated_type_usage.into_iter().cloned())
+ .map(|bounded_ty| {
syn::WherePredicate::Type(syn::PredicateType {
lifetimes: None,
// the type parameter that is being bounded e.g. T
- bounded_ty: syn::Type::Path(syn::TypePath {
- qself: None,
- path: id.into(),
- }),
+ bounded_ty: syn::Type::Path(bounded_ty),
colon_token: Default::default(),
// the bound e.g. Serialize
- bounds: vec![
- syn::TypeParamBound::Trait(syn::TraitBound {
- paren_token: None,
- modifier: syn::TraitBoundModifier::None,
- lifetimes: None,
- path: bound.clone(),
- }),
- ].into_iter().collect(),
+ bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound {
+ paren_token: None,
+ modifier: syn::TraitBoundModifier::None,
+ lifetimes: None,
+ path: bound.clone(),
+ })].into_iter()
+ .collect(),
})
});
let mut generics = generics.clone();
- generics.make_where_clause()
+ generics
+ .make_where_clause()
.predicates
.extend(new_predicates);
generics
}
pub fn with_self_bound(
cont: &Container,
generics: &syn::Generics,
bound: &syn::Path,
) -> syn::Generics {
let mut generics = generics.clone();
- generics.make_where_clause()
+ generics
+ .make_where_clause()
.predicates
.push(syn::WherePredicate::Type(syn::PredicateType {
lifetimes: None,
// the type that is being bounded e.g. MyStruct<'a, T>
bounded_ty: type_of_item(cont),
colon_token: Default::default(),
// the bound e.g. Default
- bounds: vec![
- syn::TypeParamBound::Trait(syn::TraitBound {
- paren_token: None,
- modifier: syn::TraitBoundModifier::None,
- lifetimes: None,
- path: bound.clone(),
- }),
- ].into_iter().collect(),
+ bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound {
+ paren_token: None,
+ modifier: syn::TraitBoundModifier::None,
+ lifetimes: None,
+ path: bound.clone(),
+ })].into_iter()
+ .collect(),
}));
generics
}
pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Generics {
let bound = syn::Lifetime::new(lifetime, Span::call_site());
let def = syn::LifetimeDef {
attrs: Vec::new(),
lifetime: bound,
colon_token: None,
bounds: Punctuated::new(),
};
let params = Some(syn::GenericParam::Lifetime(def))
.into_iter()
- .chain(generics.params
- .iter()
- .cloned()
- .map(|mut param| {
- match param {
- syn::GenericParam::Lifetime(ref mut param) => {
- param.bounds.push(bound);
- }
- syn::GenericParam::Type(ref mut param) => {
- param.bounds.push(syn::TypeParamBound::Lifetime(bound));
- }
- syn::GenericParam::Const(_) => {}
+ .chain(generics.params.iter().cloned().map(|mut param| {
+ match param {
+ syn::GenericParam::Lifetime(ref mut param) => {
+ param.bounds.push(bound);
}
- param
- }))
+ syn::GenericParam::Type(ref mut param) => {
+ param.bounds.push(syn::TypeParamBound::Lifetime(bound));
+ }
+ syn::GenericParam::Const(_) => {}
+ }
+ param
+ }))
.collect();
syn::Generics {
params: params,
..generics.clone()
}
}
fn type_of_item(cont: &Container) -> syn::Type {
syn::Type::Path(syn::TypePath {
qself: None,
path: syn::Path {
leading_colon: None,
- segments: vec![
- syn::PathSegment {
- ident: cont.ident,
- arguments: syn::PathArguments::AngleBracketed(
- syn::AngleBracketedGenericArguments {
- colon2_token: None,
- lt_token: Default::default(),
- args: cont.generics
- .params
- .iter()
- .map(|param| match *param {
- syn::GenericParam::Type(ref param) => {
- syn::GenericArgument::Type(syn::Type::Path(syn::TypePath {
- qself: None,
- path: param.ident.into(),
- }))
- }
- syn::GenericParam::Lifetime(ref param) => {
- syn::GenericArgument::Lifetime(param.lifetime)
- }
- syn::GenericParam::Const(_) => {
- panic!("Serde does not support const generics yet");
- }
- })
- .collect(),
- gt_token: Default::default(),
- },
- ),
- },
- ].into_iter().collect(),
+ segments: vec![syn::PathSegment {
+ ident: cont.ident,
+ arguments: syn::PathArguments::AngleBracketed(
+ syn::AngleBracketedGenericArguments {
+ colon2_token: None,
+ lt_token: Default::default(),
+ args: cont.generics
+ .params
+ .iter()
+ .map(|param| match *param {
+ syn::GenericParam::Type(ref param) => {
+ syn::GenericArgument::Type(syn::Type::Path(syn::TypePath {
+ qself: None,
+ path: param.ident.into(),
+ }))
+ }
+ syn::GenericParam::Lifetime(ref param) => {
+ syn::GenericArgument::Lifetime(param.lifetime)
+ }
+ syn::GenericParam::Const(_) => {
+ panic!("Serde does not support const generics yet");
+ }
+ })
+ .collect(),
+ gt_token: Default::default(),
+ },
+ ),
+ }].into_iter()
+ .collect(),
},
})
}
--- a/third_party/rust/serde_derive/src/de.rs
+++ b/third_party/rust/serde_derive/src/de.rs
@@ -1,84 +1,121 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use syn::{self, Ident, Index, Member};
+use proc_macro2::{Literal, Span};
+use quote::{ToTokens, Tokens};
use syn::punctuated::Punctuated;
use syn::spanned::Spanned;
-use quote::{ToTokens, Tokens};
-use proc_macro2::{Literal, Span};
+use syn::{self, Ident, Index, Member};
use bound;
use fragment::{Expr, Fragment, Match, Stmts};
-use internals::ast::{Data, Container, Field, Style, Variant};
-use internals::{self, attr};
+use internals::ast::{Container, Data, Field, Style, Variant};
+use internals::{attr, Ctxt};
+use pretend;
+use try;
#[cfg(feature = "deserialize_in_place")]
use internals::ast::Repr;
use std::collections::BTreeSet;
pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, String> {
- let ctxt = internals::Ctxt::new();
+ let ctxt = Ctxt::new();
let cont = Container::from_ast(&ctxt, input);
+ precondition(&ctxt, &cont);
try!(ctxt.check());
- let ident = &cont.ident;
+ let ident = cont.ident;
let params = Parameters::new(&cont);
let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(¶ms);
- let dummy_const = Ident::new(&format!("_IMPL_DESERIALIZE_FOR_{}", ident), Span::call_site());
+ let dummy_const = Ident::new(
+ &format!("_IMPL_DESERIALIZE_FOR_{}", ident),
+ Span::call_site(),
+ );
let body = Stmts(deserialize_body(&cont, ¶ms));
let delife = params.borrowed.de_lifetime();
let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis;
- let fun = quote_spanned!(Span::call_site()=> deserialize);
+ let used = pretend::pretend_used(&cont);
quote! {
impl #de_impl_generics #ident #ty_generics #where_clause {
- #vis fn #fun<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
- where __D: _serde::Deserializer<#delife>
+ #vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
+ where
+ __D: _serde::Deserializer<#delife>,
{
+ #used
#body
}
}
}
} else {
let fn_deserialize_in_place = deserialize_in_place_body(&cont, ¶ms);
quote! {
#[automatically_derived]
impl #de_impl_generics _serde::Deserialize<#delife> for #ident #ty_generics #where_clause {
fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
- where __D: _serde::Deserializer<#delife>
+ where
+ __D: _serde::Deserializer<#delife>,
{
#body
}
#fn_deserialize_in_place
}
}
};
+ let try_replacement = try::replacement();
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
extern crate serde as _serde;
+ #try_replacement
#impl_block
};
};
Ok(generated)
}
+fn precondition(cx: &Ctxt, cont: &Container) {
+ precondition_sized(cx, cont);
+ precondition_no_de_lifetime(cx, cont);
+}
+
+fn precondition_sized(cx: &Ctxt, cont: &Container) {
+ if let Data::Struct(_, ref fields) = cont.data {
+ if let Some(last) = fields.last() {
+ if let syn::Type::Slice(_) = *last.ty {
+ cx.error("cannot deserialize a dynamically sized struct");
+ }
+ }
+ }
+}
+
+fn precondition_no_de_lifetime(cx: &Ctxt, cont: &Container) {
+ if let BorrowedLifetimes::Borrowed(_) = borrowed_lifetimes(cont) {
+ for param in cont.generics.lifetimes() {
+ if param.lifetime.to_string() == "'de" {
+ cx.error("cannot deserialize when there is a lifetime parameter called 'de");
+ return;
+ }
+ }
+ }
+}
+
#[derive(Clone)]
struct Parameters {
/// Name of the type the `derive` is on.
local: syn::Ident,
/// Path to the type the impl is for. Either a single `Ident` for local
/// types or `some::remote::Ident` for remote types. Does not include
/// generic parameters.
@@ -126,16 +163,19 @@ impl Parameters {
// All the generics in the input, plus a bound `T: Deserialize` for each generic
// field type that will be deserialized by us, plus a bound `T: Default` for
// each generic field type that will be set to a default value.
fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generics {
let generics = bound::without_defaults(cont.generics);
let generics = bound::with_where_predicates_from_fields(cont, &generics, attr::Field::de_bound);
+ let generics =
+ bound::with_where_predicates_from_variants(cont, &generics, attr::Variant::de_bound);
+
match cont.attrs.de_bound() {
Some(predicates) => bound::with_where_predicates(&generics, predicates),
None => {
let generics = match *cont.attrs.default() {
attr::Default::Default => {
bound::with_self_bound(cont, &generics, &parse_quote!(_serde::export::Default))
}
attr::Default::None | attr::Default::Path(_) => generics,
@@ -154,23 +194,28 @@ fn build_generics(cont: &Container, borr
&generics,
requires_default,
&parse_quote!(_serde::export::Default),
)
}
}
}
-// Fields with a `skip_deserializing` or `deserialize_with` attribute are not
-// deserialized by us so we do not generate a bound. Fields with a `bound`
-// attribute specify their own bound so we do not generate one. All other fields
-// may need a `T: Deserialize` bound where T is the type of the field.
+// Fields with a `skip_deserializing` or `deserialize_with` attribute, or which
+// belong to a variant with a `skip_deserializing` or `deserialize_with`
+// attribute, are not deserialized by us so we do not generate a bound. Fields
+// with a `bound` attribute specify their own bound so we do not generate one.
+// All other fields may need a `T: Deserialize` bound where T is the type of the
+// field.
fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
!field.skip_deserializing() && field.deserialize_with().is_none() && field.de_bound().is_none()
- && variant.map_or(true, |variant| variant.deserialize_with().is_none())
+ && variant.map_or(true, |variant| {
+ !variant.skip_deserializing() && variant.deserialize_with().is_none()
+ && variant.de_bound().is_none()
+ })
}
// Fields with a `default` attribute (not `default=...`), and fields with a
// `skip_deserializing` attribute that do not also have `default=...`.
fn requires_default(field: &attr::Field, _variant: Option<&attr::Variant>) -> bool {
if let attr::Default::Default = *field.default() {
true
} else {
@@ -269,17 +314,18 @@ fn deserialize_in_place_body(cont: &Cont
.all_fields()
.all(|f| f.attrs.deserialize_with().is_some())
{
return None;
}
let code = match cont.data {
Data::Struct(Style::Struct, ref fields) => {
- if let Some(code) = deserialize_struct_in_place(None, params, fields, &cont.attrs, None) {
+ if let Some(code) = deserialize_struct_in_place(None, params, fields, &cont.attrs, None)
+ {
code
} else {
return None;
}
}
Data::Struct(Style::Tuple, ref fields) | Data::Struct(Style::Newtype, ref fields) => {
deserialize_tuple_in_place(None, params, fields, &cont.attrs, None)
}
@@ -295,17 +341,18 @@ fn deserialize_in_place_body(cont: &Cont
}
};
let delife = params.borrowed.de_lifetime();
let stmts = Stmts(code);
let fn_deserialize_in_place = quote_block! {
fn deserialize_in_place<__D>(__deserializer: __D, __place: &mut Self) -> _serde::export::Result<(), __D::Error>
- where __D: _serde::Deserializer<#delife>
+ where
+ __D: _serde::Deserializer<#delife>,
{
#stmts
}
};
Some(Stmts(fn_deserialize_in_place))
}
@@ -329,51 +376,52 @@ fn deserialize_unit_struct(params: &Para
let expecting = format!("unit struct {}", params.type_name());
quote_block! {
struct __Visitor;
impl<'de> _serde::de::Visitor<'de> for __Visitor {
type Value = #this;
- fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
- _serde::export::Formatter::write_str(formatter, #expecting)
+ fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(__formatter, #expecting)
}
#[inline]
fn visit_unit<__E>(self) -> _serde::export::Result<Self::Value, __E>
- where __E: _serde::de::Error
+ where
+ __E: _serde::de::Error,
{
_serde::export::Ok(#this)
}
}
_serde::Deserializer::deserialize_unit_struct(__deserializer, #type_name, __Visitor)
}
}
fn deserialize_tuple(
- variant_ident: Option<&syn::Ident>,
+ variant_ident: Option<syn::Ident>,
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
deserializer: Option<Tokens>,
) -> Fragment {
let this = ¶ms.this;
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
split_with_de_lifetime(params);
let delife = params.borrowed.de_lifetime();
assert!(!cattrs.has_flatten());
// If there are getters (implying private fields), construct the local type
// and use an `Into` conversion to get the remote type. If there are no
// getters then construct the target type directly.
let construct = if params.has_getter {
- let local = ¶ms.local;
+ let local = params.local;
quote!(#local)
} else {
quote!(#this)
};
let is_enum = variant_ident.is_some();
let type_path = match variant_ident {
Some(variant_ident) => quote!(#construct::#variant_ident),
@@ -387,17 +435,19 @@ fn deserialize_tuple(
let nfields = fields.len();
let visit_newtype_struct = if !is_enum && nfields == 1 {
Some(deserialize_newtype_struct(&type_path, params, &fields[0]))
} else {
None
};
- let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, false, cattrs));
+ let visit_seq = Stmts(deserialize_seq(
+ &type_path, params, fields, false, cattrs, &expecting,
+ ));
let visitor_expr = quote! {
__Visitor {
marker: _serde::export::PhantomData::<#this #ty_generics>,
lifetime: _serde::export::PhantomData,
}
};
let dispatch = if let Some(deserializer) = deserializer {
@@ -423,37 +473,38 @@ fn deserialize_tuple(
struct __Visitor #de_impl_generics #where_clause {
marker: _serde::export::PhantomData<#this #ty_generics>,
lifetime: _serde::export::PhantomData<&#delife ()>,
}
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
type Value = #this #ty_generics;
- fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
- _serde::export::Formatter::write_str(formatter, #expecting)
+ fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(__formatter, #expecting)
}
#visit_newtype_struct
#[inline]
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::SeqAccess<#delife>
+ where
+ __A: _serde::de::SeqAccess<#delife>,
{
#visit_seq
}
}
#dispatch
}
}
#[cfg(feature = "deserialize_in_place")]
fn deserialize_tuple_in_place(
- variant_ident: Option<&syn::Ident>,
+ variant_ident: Option<syn::Ident>,
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
deserializer: Option<Tokens>,
) -> Fragment {
let this = ¶ms.this;
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
split_with_de_lifetime(params);
@@ -470,17 +521,17 @@ fn deserialize_tuple_in_place(
let nfields = fields.len();
let visit_newtype_struct = if !is_enum && nfields == 1 {
Some(deserialize_newtype_struct_in_place(params, &fields[0]))
} else {
None
};
- let visit_seq = Stmts(deserialize_seq_in_place(params, fields, is_enum, cattrs));
+ let visit_seq = Stmts(deserialize_seq_in_place(params, fields, is_enum, cattrs, &expecting));
let visitor_expr = if is_enum {
quote! {
__Visitor {
place: this,
lifetime: _serde::export::PhantomData,
}
}
@@ -520,64 +571,71 @@ fn deserialize_tuple_in_place(
struct __Visitor #in_place_impl_generics #where_clause {
place: &#place_life mut #this #ty_generics,
lifetime: _serde::export::PhantomData<&#delife ()>,
}
impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause {
type Value = ();
- fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
- _serde::export::Formatter::write_str(formatter, #expecting)
+ fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(__formatter, #expecting)
}
#visit_newtype_struct
#[inline]
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::SeqAccess<#delife>
+ where
+ __A: _serde::de::SeqAccess<#delife>,
{
#visit_seq
}
}
#dispatch
}
}
fn deserialize_seq(
type_path: &Tokens,
params: &Parameters,
fields: &[Field],
is_struct: bool,
cattrs: &attr::Container,
+ expecting: &str,
) -> Fragment {
let vars = (0..fields.len()).map(field_i as fn(_) -> _);
// XXX: do we need an error for flattening here?
let deserialized_count = fields
.iter()
.filter(|field| !field.attrs.skip_deserializing())
.count();
- let expecting = format!("tuple of {} elements", deserialized_count);
-
- let mut index_in_seq = 0usize;
+ let expecting = if deserialized_count == 1 {
+ format!("{} with 1 element", expecting)
+ } else {
+ format!("{} with {} elements", expecting, deserialized_count)
+ };
+
+ let mut index_in_seq = 0_usize;
let let_values = vars.clone().zip(fields).map(|(var, field)| {
if field.attrs.skip_deserializing() {
let default = Expr(expr_is_missing(field, cattrs));
quote! {
let #var = #default;
}
} else {
let visit = match field.attrs.deserialize_with() {
None => {
- let field_ty = &field.ty;
+ let field_ty = field.ty;
let span = field.original.span();
- let func = quote_spanned!(span=> _serde::de::SeqAccess::next_element::<#field_ty>);
+ let func =
+ quote_spanned!(span=> _serde::de::SeqAccess::next_element::<#field_ty>);
quote!(try!(#func(&mut __seq)))
}
Some(path) => {
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
quote!({
#wrapper
_serde::export::Option::map(
try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)),
@@ -595,21 +653,21 @@ fn deserialize_seq(
};
index_in_seq += 1;
assign
}
});
let mut result = if is_struct {
let names = fields.iter().map(|f| &f.ident);
- quote_spanned! {Span::call_site()=>
+ quote! {
#type_path { #( #names: #vars ),* }
}
} else {
- quote_spanned! {Span::call_site()=>
+ quote! {
#type_path ( #(#vars),* )
}
};
if params.has_getter {
let this = ¶ms.this;
result = quote! {
_serde::export::Into::<#this>::into(#result)
@@ -638,76 +696,79 @@ fn deserialize_seq(
}
#[cfg(feature = "deserialize_in_place")]
fn deserialize_seq_in_place(
params: &Parameters,
fields: &[Field],
increment_fields: bool,
cattrs: &attr::Container,
+ expecting: &str,
) -> Fragment {
// For enums there's a secret `tag` field at the start which we shouldn't touch,
// so we need to bump all the indices up by 1.
let index_names = if increment_fields {
(0..fields.len())
} else {
(1..fields.len() + 1)
};
let vars = index_names.map(field_i as fn(_) -> _);
// XXX: do we need an error for flattening here?
let deserialized_count = fields
.iter()
.filter(|field| !field.attrs.skip_deserializing())
.count();
- let expecting = format!("tuple of {} elements", deserialized_count);
+ let expecting = if deserialized_count == 1 {
+ format!("{} with 1 element", expecting)
+ } else {
+ format!("{} with {} elements", expecting, deserialized_count)
+ };
let mut index_in_seq = 0usize;
let write_values = vars.clone()
.zip(fields)
.enumerate()
.map(|(field_index, (_, field))| {
// If there's no field name, assume we're a tuple-struct and use a numeric index
- let field_name = field
- .ident
- .map(Member::Named)
- .unwrap_or_else(|| Member::Unnamed(Index {
+ let field_name = field.ident.map(Member::Named).unwrap_or_else(|| {
+ Member::Unnamed(Index {
index: field_index as u32,
span: Span::call_site(),
- }));
-
- let dot = quote_spanned!(Span::call_site()=> .);
+ })
+ });
+
if field.attrs.skip_deserializing() {
let default = Expr(expr_is_missing(field, cattrs));
quote! {
- self.place #dot #field_name = #default;
+ self.place.#field_name = #default;
}
} else {
let return_invalid_length = quote! {
return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
};
let write = match field.attrs.deserialize_with() {
None => {
quote! {
if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
- _serde::private::de::InPlaceSeed(&mut self.place #dot #field_name)))
+ _serde::private::de::InPlaceSeed(&mut self.place.#field_name)))
{
#return_invalid_length
}
}
}
Some(path) => {
let (wrapper, wrapper_ty) =
wrap_deserialize_field_with(params, field.ty, path);
quote!({
#wrapper
match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
_serde::export::Some(__wrap) => {
- self.place #dot #field_name = __wrap.value;
+ self.place.#field_name = __wrap.value;
}
_serde::export::None => {
#return_invalid_length
}
}
})
}
};
@@ -736,76 +797,76 @@ fn deserialize_seq_in_place(
#let_default
#(#write_values)*
_serde::export::Ok(())
}
}
fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &Field) -> Tokens {
let delife = params.borrowed.de_lifetime();
+ let field_ty = field.ty;
let value = match field.attrs.deserialize_with() {
None => {
- let field_ty = &field.ty;
quote! {
try!(<#field_ty as _serde::Deserialize>::deserialize(__e))
}
}
Some(path) => {
- let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
- quote!({
- #wrapper
- try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value
- })
+ quote! {
+ try!(#path(__e))
+ }
}
};
- let mut result = quote_spanned!(Span::call_site()=> #type_path(#value));
+ let mut result = quote!(#type_path(__field0));
if params.has_getter {
let this = ¶ms.this;
result = quote! {
_serde::export::Into::<#this>::into(#result)
};
}
quote! {
#[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
- where __E: _serde::Deserializer<#delife>
+ where
+ __E: _serde::Deserializer<#delife>,
{
+ let __field0: #field_ty = #value;
_serde::export::Ok(#result)
}
}
}
#[cfg(feature = "deserialize_in_place")]
fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> Tokens {
// We do not generate deserialize_in_place if every field has a deserialize_with.
assert!(field.attrs.deserialize_with().is_none());
let delife = params.borrowed.de_lifetime();
- let elem = quote_spanned!(Span::call_site()=> .0);
quote! {
#[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
- where __E: _serde::Deserializer<#delife>
+ where
+ __E: _serde::Deserializer<#delife>,
{
- _serde::Deserialize::deserialize_in_place(__e, &mut self.place #elem)
+ _serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
}
}
}
enum Untagged {
Yes,
No,
}
fn deserialize_struct(
- variant_ident: Option<&syn::Ident>,
+ variant_ident: Option<syn::Ident>,
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
deserializer: Option<Tokens>,
untagged: &Untagged,
) -> Fragment {
let is_enum = variant_ident.is_some();
@@ -813,32 +874,34 @@ fn deserialize_struct(
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
split_with_de_lifetime(params);
let delife = params.borrowed.de_lifetime();
// If there are getters (implying private fields), construct the local type
// and use an `Into` conversion to get the remote type. If there are no
// getters then construct the target type directly.
let construct = if params.has_getter {
- let local = ¶ms.local;
+ let local = params.local;
quote!(#local)
} else {
quote!(#this)
};
let type_path = match variant_ident {
Some(variant_ident) => quote!(#construct::#variant_ident),
None => construct,
};
let expecting = match variant_ident {
Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident),
None => format!("struct {}", params.type_name()),
};
- let visit_seq = Stmts(deserialize_seq(&type_path, params, fields, true, cattrs));
+ let visit_seq = Stmts(deserialize_seq(
+ &type_path, params, fields, true, cattrs, &expecting,
+ ));
let (field_visitor, fields_stmt, visit_map) = if cattrs.has_flatten() {
deserialize_struct_as_map_visitor(&type_path, params, fields, cattrs)
} else {
deserialize_struct_as_struct_visitor(&type_path, params, fields, cattrs)
};
let field_visitor = Stmts(field_visitor);
let fields_stmt = fields_stmt.map(Stmts);
@@ -849,16 +912,20 @@ fn deserialize_struct(
marker: _serde::export::PhantomData::<#this #ty_generics>,
lifetime: _serde::export::PhantomData,
}
};
let dispatch = if let Some(deserializer) = deserializer {
quote! {
_serde::Deserializer::deserialize_any(#deserializer, #visitor_expr)
}
+ } else if is_enum && cattrs.has_flatten() {
+ quote! {
+ _serde::de::VariantAccess::newtype_variant_seed(__variant, #visitor_expr)
+ }
} else if is_enum {
quote! {
_serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr)
}
} else if cattrs.has_flatten() {
quote! {
_serde::Deserializer::deserialize_map(__deserializer, #visitor_expr)
}
@@ -877,58 +944,79 @@ fn deserialize_struct(
};
// untagged struct variants do not get a visit_seq method. The same applies to structs that
// only have a map representation.
let visit_seq = match *untagged {
Untagged::No if !cattrs.has_flatten() => Some(quote! {
#[inline]
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::SeqAccess<#delife>
+ where
+ __A: _serde::de::SeqAccess<#delife>,
{
#visit_seq
}
}),
_ => None,
};
+ let visitor_seed = if is_enum && cattrs.has_flatten() {
+ Some(quote! {
+ impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Visitor #de_ty_generics #where_clause {
+ type Value = #this #ty_generics;
+
+ fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result<Self::Value, __D::Error>
+ where
+ __D: _serde::Deserializer<'de>,
+ {
+ _serde::Deserializer::deserialize_map(__deserializer, self)
+ }
+ }
+ })
+ } else {
+ None
+ };
+
quote_block! {
#field_visitor
struct __Visitor #de_impl_generics #where_clause {
marker: _serde::export::PhantomData<#this #ty_generics>,
lifetime: _serde::export::PhantomData<&#delife ()>,
}
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
type Value = #this #ty_generics;
- fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
- _serde::export::Formatter::write_str(formatter, #expecting)
+ fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(__formatter, #expecting)
}
#visit_seq
#[inline]
fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::MapAccess<#delife>
+ where
+ __A: _serde::de::MapAccess<#delife>,
{
#visit_map
}
}
+ #visitor_seed
+
#fields_stmt
#dispatch
}
}
#[cfg(feature = "deserialize_in_place")]
fn deserialize_struct_in_place(
- variant_ident: Option<&syn::Ident>,
+ variant_ident: Option<syn::Ident>,
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
deserializer: Option<Tokens>,
) -> Option<Fragment> {
let is_enum = variant_ident.is_some();
// for now we do not support in_place deserialization for structs that
@@ -942,20 +1030,20 @@ fn deserialize_struct_in_place(
split_with_de_lifetime(params);
let delife = params.borrowed.de_lifetime();
let expecting = match variant_ident {
Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident),
None => format!("struct {}", params.type_name()),
};
- let visit_seq = Stmts(deserialize_seq_in_place(params, fields, false, cattrs));
-
- let (field_visitor, fields_stmt, visit_map) = deserialize_struct_as_struct_in_place_visitor(
- params, fields, cattrs);
+ let visit_seq = Stmts(deserialize_seq_in_place(params, fields, false, cattrs, &expecting));
+
+ let (field_visitor, fields_stmt, visit_map) =
+ deserialize_struct_as_struct_in_place_visitor(params, fields, cattrs);
let field_visitor = Stmts(field_visitor);
let fields_stmt = Stmts(fields_stmt);
let visit_map = Stmts(visit_map);
let visitor_expr = quote! {
__Visitor {
place: __place,
@@ -982,17 +1070,18 @@ fn deserialize_struct_in_place(
quote!(_)
} else {
quote!(mut __seq)
};
let visit_seq = quote! {
#[inline]
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::SeqAccess<#delife>
+ where
+ __A: _serde::de::SeqAccess<#delife>,
{
#visit_seq
}
};
let in_place_impl_generics = de_impl_generics.in_place();
let in_place_ty_generics = de_ty_generics.in_place();
let place_life = place_lifetime();
@@ -1003,25 +1092,26 @@ fn deserialize_struct_in_place(
struct __Visitor #in_place_impl_generics #where_clause {
place: &#place_life mut #this #ty_generics,
lifetime: _serde::export::PhantomData<&#delife ()>,
}
impl #in_place_impl_generics _serde::de::Visitor<#delife> for __Visitor #in_place_ty_generics #where_clause {
type Value = ();
- fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
- _serde::export::Formatter::write_str(formatter, #expecting)
+ fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(__formatter, #expecting)
}
#visit_seq
#[inline]
fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::MapAccess<#delife>
+ where
+ __A: _serde::de::MapAccess<#delife>,
{
#visit_map
}
}
#fields_stmt
#dispatch
@@ -1097,19 +1187,17 @@ fn deserialize_externally_tagged_enum(
let variant_arms = variants
.iter()
.enumerate()
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
.map(|(i, variant)| {
let variant_name = field_i(i);
let block = Match(deserialize_externally_tagged_variant(
- params,
- variant,
- cattrs,
+ params, variant, cattrs,
));
quote! {
(__Field::#variant_name, __variant) => #block
}
});
let all_skipped = variants
@@ -1140,22 +1228,23 @@ fn deserialize_externally_tagged_enum(
struct __Visitor #de_impl_generics #where_clause {
marker: _serde::export::PhantomData<#this #ty_generics>,
lifetime: _serde::export::PhantomData<&#delife ()>,
}
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
type Value = #this #ty_generics;
- fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
- _serde::export::Formatter::write_str(formatter, #expecting)
+ fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(__formatter, #expecting)
}
fn visit_enum<__A>(self, __data: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::EnumAccess<#delife>
+ where
+ __A: _serde::de::EnumAccess<#delife>,
{
#match_variant
}
}
#variants_stmt
_serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS,
@@ -1446,19 +1535,19 @@ fn deserialize_internally_tagged_enum(
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
.map(|(i, variant)| {
let variant_name = field_i(i);
let block = Match(deserialize_internally_tagged_variant(
params,
variant,
cattrs,
- quote!(
+ quote! {
_serde::private::de::ContentDeserializer::<__D::Error>::new(__tagged.content)
- ),
+ },
));
quote! {
__Field::#variant_name => #block
}
});
quote_block! {
@@ -1559,17 +1648,17 @@ fn deserialize_adjacently_tagged_enum(
})
};
let arms = variants
.iter()
.enumerate()
.filter(|&(_, variant)| !variant.attrs.skip_deserializing() && is_unit(variant))
.map(|(i, variant)| {
let variant_index = field_i(i);
- let variant_ident = &variant.ident;
+ let variant_ident = variant.ident;
quote! {
__Field::#variant_index => _serde::export::Ok(#this::#variant_ident),
}
});
missing_content = quote! {
match __field {
#(#arms)*
#fallthrough
@@ -1620,53 +1709,70 @@ fn deserialize_adjacently_tagged_enum(
}
_serde::export::Some(_serde::private::de::TagOrContentField::Content) => {
_serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content))
}
_serde::export::None => _serde::export::Ok(__ret),
}
};
+ let finish_content_then_tag = if variant_arms.is_empty() {
+ quote! {
+ match try!(_serde::de::MapAccess::next_value::<__Field>(&mut __map)) {}
+ }
+ } else {
+ quote! {
+ let __ret = try!(match try!(_serde::de::MapAccess::next_value(&mut __map)) {
+ // Deserialize the buffered content now that we know the variant.
+ #(#variant_arms)*
+ });
+ // Visit remaining keys, looking for duplicates.
+ #visit_remaining_keys
+ }
+ };
+
quote_block! {
#variant_visitor
#variants_stmt
struct __Seed #de_impl_generics #where_clause {
field: __Field,
marker: _serde::export::PhantomData<#this #ty_generics>,
lifetime: _serde::export::PhantomData<&#delife ()>,
}
impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause {
type Value = #this #ty_generics;
fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result<Self::Value, __D::Error>
- where __D: _serde::Deserializer<#delife>
+ where
+ __D: _serde::Deserializer<#delife>,
{
match self.field {
#(#variant_arms)*
}
}
}
struct __Visitor #de_impl_generics #where_clause {
marker: _serde::export::PhantomData<#this #ty_generics>,
lifetime: _serde::export::PhantomData<&#delife ()>,
}
impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
type Value = #this #ty_generics;
- fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
- _serde::export::Formatter::write_str(formatter, #expecting)
+ fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(__formatter, #expecting)
}
fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::MapAccess<#delife>
+ where
+ __A: _serde::de::MapAccess<#delife>,
{
// Visit the first relevant key.
match #next_relevant_key {
// First key is the tag.
_serde::export::Some(_serde::private::de::TagOrContentField::Tag) => {
// Parse the tag.
let __field = try!(_serde::de::MapAccess::next_value(&mut __map));
// Visit the second key.
@@ -1694,23 +1800,17 @@ fn deserialize_adjacently_tagged_enum(
_serde::export::Some(_serde::private::de::TagOrContentField::Content) => {
// Buffer up the content.
let __content = try!(_serde::de::MapAccess::next_value::<_serde::private::de::Content>(&mut __map));
// Visit the second key.
match #next_relevant_key {
// Second key is the tag.
_serde::export::Some(_serde::private::de::TagOrContentField::Tag) => {
let __deserializer = _serde::private::de::ContentDeserializer::<__A::Error>::new(__content);
- // Parse the tag.
- let __ret = try!(match try!(_serde::de::MapAccess::next_value(&mut __map)) {
- // Deserialize the buffered content now that we know the variant.
- #(#variant_arms)*
- });
- // Visit remaining keys, looking for duplicates.
- #visit_remaining_keys
+ #finish_content_then_tag
}
// Second key is a duplicate of the content.
_serde::export::Some(_serde::private::de::TagOrContentField::Content) => {
_serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content))
}
// There is no second key.
_serde::export::None => {
_serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#tag))
@@ -1720,17 +1820,18 @@ fn deserialize_adjacently_tagged_enum(
// There is no first key.
_serde::export::None => {
_serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#tag))
}
}
}
fn visit_seq<__A>(self, mut __seq: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::SeqAccess<#delife>
+ where
+ __A: _serde::de::SeqAccess<#delife>,
{
// Visit the first element - the tag.
match try!(_serde::de::SeqAccess::next_element(&mut __seq)) {
_serde::export::Some(__field) => {
// Visit the second element - the content.
match try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
__Seed {
field: __field,
@@ -1803,26 +1904,25 @@ fn deserialize_untagged_enum(
}
fn deserialize_externally_tagged_variant(
params: &Parameters,
variant: &Variant,
cattrs: &attr::Container,
) -> Fragment {
if let Some(path) = variant.attrs.deserialize_with() {
- let (wrapper, wrapper_ty, unwrap_fn) =
- wrap_deserialize_variant_with(params, variant, path);
+ let (wrapper, wrapper_ty, unwrap_fn) = wrap_deserialize_variant_with(params, variant, path);
return quote_block! {
#wrapper
_serde::export::Result::map(
_serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn)
};
}
- let variant_ident = &variant.ident;
+ let variant_ident = variant.ident;
match variant.style {
Style::Unit => {
let this = ¶ms.this;
quote_block! {
try!(_serde::de::VariantAccess::unit_variant(__variant));
_serde::export::Ok(#this::#variant_ident)
}
@@ -1870,17 +1970,17 @@ fn deserialize_externally_tagged_variant
quote_block! {
try!(_serde::de::VariantAccess::unit_variant(__variant));
}
}
Style::Newtype => {
deserialize_externally_tagged_newtype_variant_in_place(variant_ident, params, &variant.fields[0])
}
Style::Tuple => {
- deserialize_tuple_in_place(Some(variant_ident), params, &variant.fields, cattrs, None)
+ deserialize_tuple_in_place(Some(*variant_ident), params, &variant.fields, cattrs, None)
}
Style::Struct => {
unimplemented!()
// deserialize_struct(None, params, &variant.fields, cattrs, None, Untagged::No).0
}
}
}
@@ -1889,17 +1989,17 @@ fn deserialize_internally_tagged_variant
variant: &Variant,
cattrs: &attr::Container,
deserializer: Tokens,
) -> Fragment {
if variant.attrs.deserialize_with().is_some() {
return deserialize_untagged_variant(params, variant, cattrs, deserializer);
}
- let variant_ident = &variant.ident;
+ let variant_ident = variant.ident;
match variant.style {
Style::Unit => {
let this = ¶ms.this;
let type_name = params.type_name();
let variant_name = variant.ident.as_ref();
quote_block! {
try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name)));
@@ -1926,39 +2026,39 @@ fn deserialize_internally_tagged_variant
fn deserialize_untagged_variant(
params: &Parameters,
variant: &Variant,
cattrs: &attr::Container,
deserializer: Tokens,
) -> Fragment {
if let Some(path) = variant.attrs.deserialize_with() {
- let (wrapper, wrapper_ty, unwrap_fn) =
- wrap_deserialize_variant_with(params, variant, path);
+ let (wrapper, wrapper_ty, unwrap_fn) = wrap_deserialize_variant_with(params, variant, path);
return quote_block! {
#wrapper
_serde::export::Result::map(
<#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), #unwrap_fn)
};
}
- let variant_ident = &variant.ident;
+ let variant_ident = variant.ident;
match variant.style {
Style::Unit => {
let this = ¶ms.this;
let type_name = params.type_name();
let variant_name = variant.ident.as_ref();
quote_expr! {
- _serde::export::Result::map(
- _serde::Deserializer::deserialize_any(
- #deserializer,
- _serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
- ),
- |()| #this::#variant_ident)
+ match _serde::Deserializer::deserialize_any(
+ #deserializer,
+ _serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
+ ) {
+ _serde::export::Ok(()) => _serde::export::Ok(#this::#variant_ident),
+ _serde::export::Err(__err) => _serde::export::Err(__err),
+ }
}
}
Style::Newtype => deserialize_untagged_newtype_variant(
variant_ident,
params,
&variant.fields[0],
&deserializer,
),
@@ -1976,24 +2076,24 @@ fn deserialize_untagged_variant(
cattrs,
Some(deserializer),
&Untagged::Yes,
),
}
}
fn deserialize_externally_tagged_newtype_variant(
- variant_ident: &syn::Ident,
+ variant_ident: syn::Ident,
params: &Parameters,
field: &Field,
) -> Fragment {
let this = ¶ms.this;
match field.attrs.deserialize_with() {
None => {
- let field_ty = &field.ty;
+ let field_ty = field.ty;
quote_expr! {
_serde::export::Result::map(
_serde::de::VariantAccess::newtype_variant::<#field_ty>(__variant),
#this::#variant_ident)
}
}
Some(path) => {
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
@@ -2031,72 +2131,69 @@ fn deserialize_externally_tagged_newtype
|__wrapper| #this::#variant_ident(__wrapper.value))
}
*/
}
}
}
fn deserialize_untagged_newtype_variant(
- variant_ident: &syn::Ident,
+ variant_ident: syn::Ident,
params: &Parameters,
field: &Field,
deserializer: &Tokens,
) -> Fragment {
let this = ¶ms.this;
+ let field_ty = field.ty;
match field.attrs.deserialize_with() {
None => {
- let field_ty = &field.ty;
quote_expr! {
_serde::export::Result::map(
<#field_ty as _serde::Deserialize>::deserialize(#deserializer),
#this::#variant_ident)
}
}
Some(path) => {
- let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
quote_block! {
- #wrapper
- _serde::export::Result::map(
- <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer),
- |__wrapper| #this::#variant_ident(__wrapper.value))
+ let __value: _serde::export::Result<#field_ty, _> = #path(#deserializer);
+ _serde::export::Result::map(__value, #this::#variant_ident)
}
}
}
}
fn deserialize_generated_identifier(
fields: &[(String, Ident)],
cattrs: &attr::Container,
- is_variant: bool
+ is_variant: bool,
) -> Fragment {
let this = quote!(__Field);
let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect();
- let (ignore_variant, fallthrough) = if cattrs.has_flatten() {
+ let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() {
let ignore_variant = quote!(__other(_serde::private::de::Content<'de>),);
let fallthrough = quote!(_serde::export::Ok(__Field::__other(__value)));
(Some(ignore_variant), Some(fallthrough))
} else if is_variant || cattrs.deny_unknown_fields() {
(None, None)
} else {
let ignore_variant = quote!(__ignore,);
let fallthrough = quote!(_serde::export::Ok(__Field::__ignore));
(Some(ignore_variant), Some(fallthrough))
};
let visitor_impl = Stmts(deserialize_identifier(
&this,
fields,
is_variant,
fallthrough,
- cattrs.has_flatten(),
+ !is_variant && cattrs.has_flatten(),
));
- let lifetime = if cattrs.has_flatten() {
+ let lifetime = if !is_variant && cattrs.has_flatten() {
Some(quote!(<'de>))
} else {
None
};
quote_block! {
#[allow(non_camel_case_types)]
enum __Field #lifetime {
@@ -2110,17 +2207,18 @@ fn deserialize_generated_identifier(
type Value = __Field #lifetime;
#visitor_impl
}
impl<'de> _serde::Deserialize<'de> for __Field #lifetime {
#[inline]
fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
- where __D: _serde::Deserializer<'de>
+ where
+ __D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
}
}
fn deserialize_custom_identifier(
@@ -2133,17 +2231,17 @@ fn deserialize_custom_identifier(
attr::Identifier::Field => false,
attr::Identifier::No => unreachable!(),
};
let this = ¶ms.this;
let this = quote!(#this);
let (ordinary, fallthrough) = if let Some(last) = variants.last() {
- let last_ident = &last.ident;
+ let last_ident = last.ident;
if last.attrs.other() {
let ordinary = &variants[..variants.len() - 1];
let fallthrough = quote!(_serde::export::Ok(#this::#last_ident));
(ordinary, Some(fallthrough))
} else if let Style::Newtype = last.style {
let ordinary = &variants[..variants.len() - 1];
let deserializer = quote!(_serde::private::de::IdentifierDeserializer::from(__value));
let fallthrough = quote! {
@@ -2156,22 +2254,17 @@ fn deserialize_custom_identifier(
(variants, None)
}
} else {
(variants, None)
};
let names_idents: Vec<_> = ordinary
.iter()
- .map(|variant| {
- (
- variant.attrs.name().deserialize_name(),
- variant.ident,
- )
- })
+ .map(|variant| (variant.attrs.name().deserialize_name(), variant.ident))
.collect();
let names = names_idents.iter().map(|&(ref name, _)| name);
let names_const = if fallthrough.is_some() {
None
} else if is_variant {
let variants = quote! {
@@ -2218,227 +2311,253 @@ fn deserialize_custom_identifier(
}
}
fn deserialize_identifier(
this: &Tokens,
fields: &[(String, Ident)],
is_variant: bool,
fallthrough: Option<Tokens>,
- collect_other_fields: bool
+ collect_other_fields: bool,
) -> Fragment {
let field_strs = fields.iter().map(|&(ref name, _)| name);
let field_borrowed_strs = fields.iter().map(|&(ref name, _)| name);
- let field_bytes = fields.iter().map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
- let field_borrowed_bytes = fields.iter().map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
+ let field_bytes = fields
+ .iter()
+ .map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
+ let field_borrowed_bytes = fields
+ .iter()
+ .map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
let constructors: &Vec<_> = &fields
.iter()
.map(|&(_, ref ident)| quote!(#this::#ident))
.collect();
let expecting = if is_variant {
"variant identifier"
} else {
"field identifier"
};
let index_expecting = if is_variant { "variant" } else { "field" };
- let variant_indices = 0u64..;
- let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
- let visit_other = if collect_other_fields {
- Some(quote! {
- fn visit_bool<__E>(self, __value: bool) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::Bool(__value)))
- }
-
- fn visit_i8<__E>(self, __value: i8) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::I8(__value)))
- }
-
- fn visit_i16<__E>(self, __value: i16) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::I16(__value)))
- }
-
- fn visit_i32<__E>(self, __value: i32) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::I32(__value)))
- }
-
- fn visit_i64<__E>(self, __value: i64) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::I64(__value)))
- }
-
- fn visit_u8<__E>(self, __value: u8) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::U8(__value)))
- }
-
- fn visit_u16<__E>(self, __value: u16) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::U16(__value)))
- }
-
- fn visit_u32<__E>(self, __value: u32) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::U32(__value)))
- }
-
- fn visit_u64<__E>(self, __value: u64) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::U64(__value)))
- }
-
- fn visit_f32<__E>(self, __value: f32) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::F32(__value)))
- }
-
- fn visit_f64<__E>(self, __value: f64) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::F64(__value)))
- }
-
- fn visit_char<__E>(self, __value: char) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::Char(__value)))
- }
-
- fn visit_unit<__E>(self) -> Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- Ok(__Field::__other(_serde::private::de::Content::Unit))
- }
- })
- } else {
- Some(quote! {
- fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- match __value {
- #(
- #variant_indices => _serde::export::Ok(#constructors),
- )*
- _ => _serde::export::Err(_serde::de::Error::invalid_value(
- _serde::de::Unexpected::Unsigned(__value),
- &#fallthrough_msg))
- }
- }
- })
- };
-
let bytes_to_str = if fallthrough.is_some() || collect_other_fields {
None
} else {
Some(quote! {
let __value = &_serde::export::from_utf8_lossy(__value);
})
};
- let (value_as_str_content, value_as_borrowed_str_content,
- value_as_bytes_content, value_as_borrowed_bytes_content) = if !collect_other_fields {
- (None, None, None, None)
- } else {
+ let (
+ value_as_str_content,
+ value_as_borrowed_str_content,
+ value_as_bytes_content,
+ value_as_borrowed_bytes_content,
+ ) = if collect_other_fields {
(
Some(quote! {
let __value = _serde::private::de::Content::String(__value.to_string());
}),
Some(quote! {
let __value = _serde::private::de::Content::Str(__value);
}),
Some(quote! {
let __value = _serde::private::de::Content::ByteBuf(__value.to_vec());
}),
Some(quote! {
let __value = _serde::private::de::Content::Bytes(__value);
- })
+ }),
)
+ } else {
+ (None, None, None, None)
};
let fallthrough_arm = if let Some(fallthrough) = fallthrough {
fallthrough
} else if is_variant {
quote! {
_serde::export::Err(_serde::de::Error::unknown_variant(__value, VARIANTS))
}
} else {
quote! {
_serde::export::Err(_serde::de::Error::unknown_field(__value, FIELDS))
}
};
+ let variant_indices = 0_u64..;
+ let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
+ let visit_other = if collect_other_fields {
+ quote! {
+ fn visit_bool<__E>(self, __value: bool) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::Bool(__value)))
+ }
+
+ fn visit_i8<__E>(self, __value: i8) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::I8(__value)))
+ }
+
+ fn visit_i16<__E>(self, __value: i16) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::I16(__value)))
+ }
+
+ fn visit_i32<__E>(self, __value: i32) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::I32(__value)))
+ }
+
+ fn visit_i64<__E>(self, __value: i64) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::I64(__value)))
+ }
+
+ fn visit_u8<__E>(self, __value: u8) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::U8(__value)))
+ }
+
+ fn visit_u16<__E>(self, __value: u16) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::U16(__value)))
+ }
+
+ fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::U32(__value)))
+ }
+
+ fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::U64(__value)))
+ }
+
+ fn visit_f32<__E>(self, __value: f32) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::F32(__value)))
+ }
+
+ fn visit_f64<__E>(self, __value: f64) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::F64(__value)))
+ }
+
+ fn visit_char<__E>(self, __value: char) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::Char(__value)))
+ }
+
+ fn visit_unit<__E>(self) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::export::Ok(__Field::__other(_serde::private::de::Content::Unit))
+ }
+
+ fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ match __value {
+ #(
+ #field_borrowed_strs => _serde::export::Ok(#constructors),
+ )*
+ _ => {
+ #value_as_borrowed_str_content
+ #fallthrough_arm
+ }
+ }
+ }
+
+ fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ match __value {
+ #(
+ #field_borrowed_bytes => _serde::export::Ok(#constructors),
+ )*
+ _ => {
+ #bytes_to_str
+ #value_as_borrowed_bytes_content
+ #fallthrough_arm
+ }
+ }
+ }
+ }
+ } else {
+ quote! {
+ fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ match __value {
+ #(
+ #variant_indices => _serde::export::Ok(#constructors),
+ )*
+ _ => _serde::export::Err(_serde::de::Error::invalid_value(
+ _serde::de::Unexpected::Unsigned(__value),
+ &#fallthrough_msg))
+ }
+ }
+ }
+ };
+
quote_block! {
- fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
- _serde::export::Formatter::write_str(formatter, #expecting)
+ fn expecting(&self, __formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(__formatter, #expecting)
}
#visit_other
fn visit_str<__E>(self, __value: &str) -> _serde::export::Result<Self::Value, __E>
- where __E: _serde::de::Error
+ where
+ __E: _serde::de::Error,
{
match __value {
#(
#field_strs => _serde::export::Ok(#constructors),
)*
_ => {
#value_as_str_content
#fallthrough_arm
}
}
}
- fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- match __value {
- #(
- #field_borrowed_strs => _serde::export::Ok(#constructors),
- )*
- _ => {
- #value_as_borrowed_str_content
- #fallthrough_arm
- }
- }
- }
-
- fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::export::Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- match __value {
- #(
- #field_borrowed_bytes => _serde::export::Ok(#constructors),
- )*
- _ => {
- #bytes_to_str
- #value_as_borrowed_bytes_content
- #fallthrough_arm
- }
- }
- }
-
fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::export::Result<Self::Value, __E>
- where __E: _serde::de::Error
+ where
+ __E: _serde::de::Error,
{
match __value {
#(
#field_bytes => _serde::export::Ok(#constructors),
)*
_ => {
#bytes_to_str
#value_as_bytes_content
@@ -2511,26 +2630,26 @@ fn deserialize_map(
.map(|(i, field)| (field, field_i(i)))
.collect();
// Declare each field that will be deserialized.
let let_values = fields_names
.iter()
.filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
.map(|&(field, ref name)| {
- let field_ty = &field.ty;
+ let field_ty = field.ty;
quote! {
let mut #name: _serde::export::Option<#field_ty> = _serde::export::None;
}
});
// Collect contents for flatten fields into a buffer
let let_collect = if cattrs.has_flatten() {
Some(quote! {
- let mut __collect = Vec::<Option<(
+ let mut __collect = _serde::export::Vec::<_serde::export::Option<(
_serde::private::de::Content,
_serde::private::de::Content
)>>::new();
})
} else {
None
};
@@ -2538,19 +2657,20 @@ fn deserialize_map(
let value_arms = fields_names
.iter()
.filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
.map(|&(field, ref name)| {
let deser_name = field.attrs.name().deserialize_name();
let visit = match field.attrs.deserialize_with() {
None => {
- let field_ty = &field.ty;
+ let field_ty = field.ty;
let span = field.original.span();
- let func = quote_spanned!(span=> _serde::de::MapAccess::next_value::<#field_ty>);
+ let func =
+ quote_spanned!(span=> _serde::de::MapAccess::next_value::<#field_ty>);
quote! {
try!(#func(&mut __map))
}
}
Some(path) => {
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
quote!({
#wrapper
@@ -2567,17 +2687,17 @@ fn deserialize_map(
}
}
});
// Visit ignored values to consume them
let ignored_arm = if cattrs.has_flatten() {
Some(quote! {
__Field::__other(__name) => {
- __collect.push(Some((
+ __collect.push(_serde::export::Some((
__name,
try!(_serde::de::MapAccess::next_value(&mut __map)))));
}
})
} else if cattrs.deny_unknown_fields() {
None
} else {
Some(quote! {
@@ -2619,47 +2739,51 @@ fn deserialize_map(
}
});
let extract_collected = fields_names
.iter()
.filter(|&&(field, _)| field.attrs.flatten())
.map(|&(field, ref name)| {
let field_ty = field.ty;
+ let func = match field.attrs.deserialize_with() {
+ None => quote!(_serde::de::Deserialize::deserialize),
+ Some(path) => quote!(#path),
+ };
quote! {
- let #name: #field_ty = try!(_serde::de::Deserialize::deserialize(
+ let #name: #field_ty = try!(#func(
_serde::private::de::FlatMapDeserializer(
&mut __collect,
_serde::export::PhantomData)));
}
});
let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() {
Some(quote! {
- if let Some(Some((__key, _))) = __collect.into_iter().filter(|x| x.is_some()).next() {
- if let Some(__key) = __key.as_str() {
+ if let _serde::export::Some(_serde::export::Some((__key, _))) = __collect.into_iter().filter(|x| x.is_some()).next() {
+ if let _serde::export::Some(__key) = __key.as_str() {
return _serde::export::Err(
_serde::de::Error::custom(format_args!("unknown field `{}`", &__key)));
} else {
return _serde::export::Err(
_serde::de::Error::custom(format_args!("unexpected map key")));
}
}
})
} else {
None
};
let result = fields_names.iter().map(|&(field, ref name)| {
let ident = field.ident.expect("struct contains unnamed fields");
if field.attrs.skip_deserializing() {
let value = Expr(expr_is_missing(field, cattrs));
- quote_spanned!(Span::call_site()=> #ident: #value)
+ quote!(#ident: #value)
} else {
- quote_spanned!(Span::call_site()=> #ident: #name)
+ quote!(#ident: #name)
}
});
let let_default = match *cattrs.default() {
attr::Default::Default => Some(quote!(
let __default: Self::Value = _serde::export::Default::default();
)),
attr::Default::Path(ref path) => Some(quote!(
@@ -2667,17 +2791,17 @@ fn deserialize_map(
)),
attr::Default::None => {
// We don't need the default value, to prevent an unused variable warning
// we'll leave the line empty.
None
}
};
- let mut result = quote_spanned!(Span::call_site()=> #struct_path { #(#result),* });
+ let mut result = quote!(#struct_path { #(#result),* });
if params.has_getter {
let this = ¶ms.this;
result = quote! {
_serde::export::Into::<#this>::into(#result)
};
}
quote_block! {
@@ -2754,17 +2878,17 @@ fn deserialize_map_in_place(
});
// Match arms to extract a value for a field.
let value_arms_from = fields_names
.iter()
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
.map(|&(field, ref name)| {
let deser_name = field.attrs.name().deserialize_name();
- let field_name = &field.ident;
+ let field_name = field.ident;
let visit = match field.attrs.deserialize_with() {
None => {
quote! {
try!(_serde::de::MapAccess::next_value_seed(&mut __map, _serde::private::de::InPlaceSeed(&mut self.place.#field_name)))
}
}
Some(path) => {
@@ -2817,27 +2941,28 @@ fn deserialize_map_in_place(
};
let check_flags = fields_names
.iter()
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
.map(|&(field, ref name)| {
let missing_expr = expr_is_missing(field, cattrs);
// If missing_expr unconditionally returns an error, don't try
- // to assign its value to self.place. Maybe this could be handled
- // more elegantly.
- if missing_expr.as_ref().into_tokens().to_string().starts_with("return ") {
+ // to assign its value to self.place.
+ if field.attrs.default().is_none() && cattrs.default().is_none()
+ && field.attrs.deserialize_with().is_some()
+ {
let missing_expr = Stmts(missing_expr);
quote! {
if !#name {
#missing_expr;
}
}
} else {
- let field_name = &field.ident;
+ let field_name = field.ident;
let missing_expr = Expr(missing_expr);
quote! {
if !#name {
self.place.#field_name = #missing_expr;
};
}
}
});
@@ -2892,17 +3017,18 @@ fn wrap_deserialize_with(
struct __DeserializeWith #de_impl_generics #where_clause {
value: #value_ty,
phantom: _serde::export::PhantomData<#this #ty_generics>,
lifetime: _serde::export::PhantomData<&#delife ()>,
}
impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause {
fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
- where __D: _serde::Deserializer<#delife>
+ where
+ __D: _serde::Deserializer<#delife>,
{
_serde::export::Ok(__DeserializeWith {
value: try!(#deserialize_with(__deserializer)),
phantom: _serde::export::PhantomData,
lifetime: _serde::export::PhantomData,
})
}
}
@@ -2922,51 +3048,53 @@ fn wrap_deserialize_field_with(
}
fn wrap_deserialize_variant_with(
params: &Parameters,
variant: &Variant,
deserialize_with: &syn::ExprPath,
) -> (Tokens, Tokens, Tokens) {
let this = ¶ms.this;
- let variant_ident = &variant.ident;
+ let variant_ident = variant.ident;
let field_tys = variant.fields.iter().map(|field| field.ty);
let (wrapper, wrapper_ty) =
wrap_deserialize_with(params, "e!((#(#field_tys),*)), deserialize_with);
- let field_access = (0..variant.fields.len()).map(|n| Member::Unnamed(Index {
- index: n as u32,
- span: Span::call_site(),
- }));
+ let field_access = (0..variant.fields.len()).map(|n| {
+ Member::Unnamed(Index {
+ index: n as u32,
+ span: Span::call_site(),
+ })
+ });
let unwrap_fn = match variant.style {
+ Style::Struct if variant.fields.len() == 1 => {
+ let field_ident = variant.fields[0].ident.unwrap();
+ quote! {
+ |__wrap| #this::#variant_ident { #field_ident: __wrap.value }
+ }
+ }
Style::Struct => {
let field_idents = variant
.fields
.iter()
.map(|field| field.ident.as_ref().unwrap());
- quote!({
- |__wrap| {
- #this::#variant_ident { #(#field_idents: __wrap.value.#field_access),* }
- }
- })
- }
- Style::Tuple => quote!({
- |__wrap| {
- #this::#variant_ident(#(__wrap.value.#field_access),*)
+ quote! {
+ |__wrap| #this::#variant_ident { #(#field_idents: __wrap.value.#field_access),* }
}
- }),
- Style::Newtype => quote!({
- |__wrap| {
- #this::#variant_ident(__wrap.value)
- }
- }),
- Style::Unit => quote!({
- |__wrap| { #this::#variant_ident }
- }),
+ }
+ Style::Tuple => quote! {
+ |__wrap| #this::#variant_ident(#(__wrap.value.#field_access),*)
+ },
+ Style::Newtype => quote! {
+ |__wrap| #this::#variant_ident(__wrap.value)
+ },
+ Style::Unit => quote! {
+ |__wrap| #this::#variant_ident
+ },
};
(wrapper, wrapper_ty, unwrap_fn)
}
fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
match *field.attrs.default() {
attr::Default::Default => {
@@ -2975,17 +3103,17 @@ fn expr_is_missing(field: &Field, cattrs
attr::Default::Path(ref path) => {
return quote_expr!(#path());
}
attr::Default::None => { /* below */ }
}
match *cattrs.default() {
attr::Default::Default | attr::Default::Path(_) => {
- let ident = &field.ident;
+ let ident = field.ident;
return quote_expr!(__default.#ident);
}
attr::Default::None => { /* below */ }
}
let name = field.attrs.name().deserialize_name();
match field.attrs.deserialize_with() {
None => {
@@ -3029,17 +3157,18 @@ impl<'a> ToTokens for InPlaceImplGeneric
// Add lifetime for `&'place mut Self, and `'a: 'place`
for param in &mut generics.params {
match *param {
syn::GenericParam::Lifetime(ref mut param) => {
param.bounds.push(place_lifetime.lifetime);
}
syn::GenericParam::Type(ref mut param) => {
- param.bounds
+ param
+ .bounds
.push(syn::TypeParamBound::Lifetime(place_lifetime.lifetime));
}
syn::GenericParam::Const(_) => {}
}
}
generics.params = Some(syn::GenericParam::Lifetime(place_lifetime))
.into_iter()
.chain(generics.params)
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/ast.rs
@@ -0,0 +1,246 @@
+// Copyright 2017 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use internals::attr;
+use internals::check;
+use internals::Ctxt;
+use syn;
+use syn::punctuated::Punctuated;
+
+pub struct Container<'a> {
+ pub ident: syn::Ident,
+ pub attrs: attr::Container,
+ pub data: Data<'a>,
+ pub generics: &'a syn::Generics,
+}
+
+pub enum Data<'a> {
+ Enum(Repr, Vec<Variant<'a>>),
+ Struct(Style, Vec<Field<'a>>),
+}
+
+pub struct Variant<'a> {
+ pub ident: syn::Ident,
+ pub attrs: attr::Variant,
+ pub style: Style,
+ pub fields: Vec<Field<'a>>,
+}
+
+pub struct Field<'a> {
+ pub ident: Option<syn::Ident>,
+ pub attrs: attr::Field,
+ pub ty: &'a syn::Type,
+ pub original: &'a syn::Field,
+}
+
+pub struct Repr {
+ pub int_repr: Option<&'static str>,
+ pub c_repr: bool,
+ pub other_repr: bool,
+}
+
+#[derive(Copy, Clone)]
+pub enum Style {
+ Struct,
+ Tuple,
+ Newtype,
+ Unit,
+}
+
+impl<'a> Container<'a> {
+ pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput) -> Container<'a> {
+ let mut attrs = attr::Container::from_ast(cx, item);
+
+ let mut data = match item.data {
+ syn::Data::Enum(ref data) => {
+ let (repr, variants) = enum_from_ast(cx, item, &data.variants, attrs.default());
+ Data::Enum(repr, variants)
+ }
+ syn::Data::Struct(ref data) => {
+ let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default());
+ Data::Struct(style, fields)
+ }
+ syn::Data::Union(_) => {
+ panic!("Serde does not support derive for unions");
+ }
+ };
+
+ let mut has_flatten = false;
+ match data {
+ Data::Enum(_, ref mut variants) => for variant in variants {
+ variant.attrs.rename_by_rule(attrs.rename_all());
+ for field in &mut variant.fields {
+ if field.attrs.flatten() {
+ has_flatten = true;
+ }
+ field.attrs.rename_by_rule(variant.attrs.rename_all());
+ }
+ },
+ Data::Struct(_, ref mut fields) => for field in fields {
+ if field.attrs.flatten() {
+ has_flatten = true;
+ }
+ field.attrs.rename_by_rule(attrs.rename_all());
+ },
+ }
+
+ if has_flatten {
+ attrs.mark_has_flatten();
+ }
+
+ let item = Container {
+ ident: item.ident,
+ attrs: attrs,
+ data: data,
+ generics: &item.generics,
+ };
+ check::check(cx, &item);
+ item
+ }
+}
+
+impl<'a> Data<'a> {
+ pub fn all_fields(&'a self) -> Box<Iterator<Item = &'a Field<'a>> + 'a> {
+ match *self {
+ Data::Enum(_, ref variants) => {
+ Box::new(variants.iter().flat_map(|variant| variant.fields.iter()))
+ }
+ Data::Struct(_, ref fields) => Box::new(fields.iter()),
+ }
+ }
+
+ pub fn has_getter(&self) -> bool {
+ self.all_fields().any(|f| f.attrs.getter().is_some())
+ }
+}
+
+impl Repr {
+ /// Gives the int type to use for the `repr(int)` enum layout
+ pub fn get_stable_rust_enum_layout(&self) -> Option<&'static str> {
+ if self.c_repr || self.other_repr {
+ None
+ } else {
+ self.int_repr
+ }
+ }
+
+ /// Gives the int type to use for the `repr(C, int)` enum layout
+ pub fn get_stable_c_enum_layout(&self) -> Option<&'static str> {
+ if !self.c_repr && self.other_repr {
+ None
+ } else {
+ self.int_repr
+ }
+ }
+}
+
+fn enum_from_ast<'a>(
+ cx: &Ctxt,
+ item: &'a syn::DeriveInput,
+ variants: &'a Punctuated<syn::Variant, Token![,]>,
+ container_default: &attr::Default
+) -> (Repr, Vec<Variant<'a>>) {
+ let variants = variants
+ .iter()
+ .map(
+ |variant| {
+ let attrs = attr::Variant::from_ast(cx, variant);
+ let (style, fields) =
+ struct_from_ast(cx, &variant.fields, Some(&attrs), container_default);
+ Variant {
+ ident: variant.ident,
+ attrs: attrs,
+ style: style,
+ fields: fields,
+ }
+ },
+ )
+ .collect();
+
+ // Compute repr info for enum optimizations
+ static INT_TYPES: [&'static str; 12] = [
+ "u8", "u16", "u32", "u64", "u128", "usize",
+ "i8", "i16", "i32", "i64", "i128", "isize",
+ ];
+
+ let mut int_repr = None;
+ let mut c_repr = false;
+ let mut other_repr = false;
+
+ for attr in &item.attrs {
+ if let Some(syn::Meta::List(ref list)) = attr.interpret_meta() {
+ if list.ident == "repr" {
+ // has_repr = true;
+ for repr in &list.nested {
+ if let syn::NestedMeta::Meta(syn::Meta::Word(ref repr)) = *repr {
+ if repr == "C" {
+ c_repr = true;
+ } else if let Some(int_type) = INT_TYPES.iter().cloned().find(|int_type| repr == int_type) {
+ if int_repr.is_some() {
+ // This shouldn't happen, but we shouldn't crash if we see it.
+ // So just treat the enum as having a mysterious other repr,
+ // which makes us discard any attempt to optimize based on layout.
+ other_repr = true;
+ }
+ int_repr = Some(int_type);
+ } else {
+ other_repr = true;
+ }
+ } else {
+ panic!("impossible repr? {:?}", repr);
+ }
+ }
+ }
+ }
+ }
+
+ let repr = Repr { int_repr, c_repr, other_repr };
+
+ (repr, variants)
+}
+
+fn struct_from_ast<'a>(
+ cx: &Ctxt,
+ fields: &'a syn::Fields,
+ attrs: Option<&attr::Variant>,
+ container_default: &attr::Default,
+) -> (Style, Vec<Field<'a>>) {
+ match *fields {
+ syn::Fields::Named(ref fields) => (
+ Style::Struct,
+ fields_from_ast(cx, &fields.named, attrs, container_default),
+ ),
+ syn::Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => (
+ Style::Newtype,
+ fields_from_ast(cx, &fields.unnamed, attrs, container_default),
+ ),
+ syn::Fields::Unnamed(ref fields) => (
+ Style::Tuple,
+ fields_from_ast(cx, &fields.unnamed, attrs, container_default),
+ ),
+ syn::Fields::Unit => (Style::Unit, Vec::new()),
+ }
+}
+
+fn fields_from_ast<'a>(
+ cx: &Ctxt,
+ fields: &'a Punctuated<syn::Field, Token![,]>,
+ attrs: Option<&attr::Variant>,
+ container_default: &attr::Default,
+) -> Vec<Field<'a>> {
+ fields
+ .iter()
+ .enumerate()
+ .map(|(i, field)| Field {
+ ident: field.ident,
+ attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
+ ty: &field.ty,
+ original: field,
+ })
+ .collect()
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/attr.rs
@@ -0,0 +1,1538 @@
+// Copyright 2017 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use internals::Ctxt;
+use proc_macro2::{Group, Span, TokenStream, TokenTree};
+use std::collections::BTreeSet;
+use std::str::FromStr;
+use syn;
+use syn::punctuated::Punctuated;
+use syn::synom::{ParseError, Synom};
+use syn::Ident;
+use syn::Meta::{List, NameValue, Word};
+use syn::NestedMeta::{Literal, Meta};
+
+// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
+// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
+// `attr::Field::from_ast`. Each returns an instance of the corresponding
+// struct. Note that none of them return a Result. Unrecognized, malformed, or
+// duplicated attributes result in a span_err but otherwise are ignored. The
+// user will see errors simultaneously for all bad attributes in the crate
+// rather than just the first.
+
+pub use internals::case::RenameRule;
+
+#[derive(Copy, Clone)]
+struct Attr<'c, T> {
+ cx: &'c Ctxt,
+ name: &'static str,
+ value: Option<T>,
+}
+
+impl<'c, T> Attr<'c, T> {
+ fn none(cx: &'c Ctxt, name: &'static str) -> Self {
+ Attr {
+ cx: cx,
+ name: name,
+ value: None,
+ }
+ }
+
+ fn set(&mut self, value: T) {
+ if self.value.is_some() {
+ self.cx
+ .error(format!("duplicate serde attribute `{}`", self.name));
+ } else {
+ self.value = Some(value);
+ }
+ }
+
+ fn set_opt(&mut self, value: Option<T>) {
+ if let Some(value) = value {
+ self.set(value);
+ }
+ }
+
+ fn set_if_none(&mut self, value: T) {
+ if self.value.is_none() {
+ self.value = Some(value);
+ }
+ }
+
+ fn get(self) -> Option<T> {
+ self.value
+ }
+}
+
+struct BoolAttr<'c>(Attr<'c, ()>);
+
+impl<'c> BoolAttr<'c> {
+ fn none(cx: &'c Ctxt, name: &'static str) -> Self {
+ BoolAttr(Attr::none(cx, name))
+ }
+
+ fn set_true(&mut self) {
+ self.0.set(());
+ }
+
+ fn get(&self) -> bool {
+ self.0.value.is_some()
+ }
+}
+
+pub struct Name {
+ serialize: String,
+ deserialize: String,
+}
+
+impl Name {
+ /// Return the container name for the container when serializing.
+ pub fn serialize_name(&self) -> String {
+ self.serialize.clone()
+ }
+
+ /// Return the container name for the container when deserializing.
+ pub fn deserialize_name(&self) -> String {
+ self.deserialize.clone()
+ }
+}
+
+/// Represents container (e.g. struct) attribute information
+pub struct Container {
+ name: Name,
+ deny_unknown_fields: bool,
+ default: Default,
+ rename_all: RenameRule,
+ ser_bound: Option<Vec<syn::WherePredicate>>,
+ de_bound: Option<Vec<syn::WherePredicate>>,
+ tag: EnumTag,
+ type_from: Option<syn::Type>,
+ type_into: Option<syn::Type>,
+ remote: Option<syn::Path>,
+ identifier: Identifier,
+ has_flatten: bool,
+}
+
+/// Styles of representing an enum.
+pub enum EnumTag {
+ /// The default.
+ ///
+ /// ```json
+ /// {"variant1": {"key1": "value1", "key2": "value2"}}
+ /// ```
+ External,
+
+ /// `#[serde(tag = "type")]`
+ ///
+ /// ```json
+ /// {"type": "variant1", "key1": "value1", "key2": "value2"}
+ /// ```
+ Internal { tag: String },
+
+ /// `#[serde(tag = "t", content = "c")]`
+ ///
+ /// ```json
+ /// {"t": "variant1", "c": {"key1": "value1", "key2": "value2"}}
+ /// ```
+ Adjacent { tag: String, content: String },
+
+ /// `#[serde(untagged)]`
+ ///
+ /// ```json
+ /// {"key1": "value1", "key2": "value2"}
+ /// ```
+ None,
+}
+
+/// Whether this enum represents the fields of a struct or the variants of an
+/// enum.
+#[derive(Copy, Clone)]
+pub enum Identifier {
+ /// It does not.
+ No,
+
+ /// This enum represents the fields of a struct. All of the variants must be
+ /// unit variants, except possibly one which is annotated with
+ /// `#[serde(other)]` and is a newtype variant.
+ Field,
+
+ /// This enum represents the variants of an enum. All of the variants must
+ /// be unit variants.
+ Variant,
+}
+
+impl Identifier {
+ #[cfg(feature = "deserialize_in_place")]
+ pub fn is_some(self) -> bool {
+ match self {
+ Identifier::No => false,
+ Identifier::Field | Identifier::Variant => true,
+ }
+ }
+}
+
+impl Container {
+ /// Extract out the `#[serde(...)]` attributes from an item.
+ pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self {
+ let mut ser_name = Attr::none(cx, "rename");
+ let mut de_name = Attr::none(cx, "rename");
+ let mut deny_unknown_fields = BoolAttr::none(cx, "deny_unknown_fields");
+ let mut default = Attr::none(cx, "default");
+ let mut rename_all = Attr::none(cx, "rename_all");
+ let mut ser_bound = Attr::none(cx, "bound");
+ let mut de_bound = Attr::none(cx, "bound");
+ let mut untagged = BoolAttr::none(cx, "untagged");
+ let mut internal_tag = Attr::none(cx, "tag");
+ let mut content = Attr::none(cx, "content");
+ let mut type_from = Attr::none(cx, "from");
+ let mut type_into = Attr::none(cx, "into");
+ let mut remote = Attr::none(cx, "remote");
+ let mut field_identifier = BoolAttr::none(cx, "field_identifier");
+ let mut variant_identifier = BoolAttr::none(cx, "variant_identifier");
+
+ for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) {
+ for meta_item in meta_items {
+ match meta_item {
+ // Parse `#[serde(rename = "foo")]`
+ Meta(NameValue(ref m)) if m.ident == "rename" => {
+ if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+ ser_name.set(s.value());
+ de_name.set(s.value());
+ }
+ }
+
+ // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
+ Meta(List(ref m)) if m.ident == "rename" => {
+ if let Ok((ser, de)) = get_renames(cx, &m.nested) {
+ ser_name.set_opt(ser.map(syn::LitStr::value));
+ de_name.set_opt(de.map(syn::LitStr::value));
+ }
+ }
+
+ // Parse `#[serde(rename_all = "foo")]`
+ Meta(NameValue(ref m)) if m.ident == "rename_all" => {
+ if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+ match RenameRule::from_str(&s.value()) {
+ Ok(rename_rule) => rename_all.set(rename_rule),
+ Err(()) => cx.error(format!(
+ "unknown rename rule for #[serde(rename_all \
+ = {:?})]",
+ s.value()
+ )),
+ }
+ }
+ }
+
+ // Parse `#[serde(deny_unknown_fields)]`
+ Meta(Word(word)) if word == "deny_unknown_fields" => {
+ deny_unknown_fields.set_true();
+ }
+
+ // Parse `#[serde(default)]`
+ Meta(Word(word)) if word == "default" => match item.data {
+ syn::Data::Struct(syn::DataStruct {
+ fields: syn::Fields::Named(_),
+ ..
+ }) => {
+ default.set(Default::Default);
+ }
+ _ => cx.error(
+ "#[serde(default)] can only be used on structs \
+ with named fields",
+ ),
+ },
+
+ // Parse `#[serde(default = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "default" => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+ match item.data {
+ syn::Data::Struct(syn::DataStruct {
+ fields: syn::Fields::Named(_),
+ ..
+ }) => {
+ default.set(Default::Path(path));
+ }
+ _ => cx.error(
+ "#[serde(default = \"...\")] can only be used \
+ on structs with named fields",
+ ),
+ }
+ }
+ }
+
+ // Parse `#[serde(bound = "D: Serialize")]`
+ Meta(NameValue(ref m)) if m.ident == "bound" => {
+ if let Ok(where_predicates) =
+ parse_lit_into_where(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit)
+ {
+ ser_bound.set(where_predicates.clone());
+ de_bound.set(where_predicates);
+ }
+ }
+
+ // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
+ Meta(List(ref m)) if m.ident == "bound" => {
+ if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
+ ser_bound.set_opt(ser);
+ de_bound.set_opt(de);
+ }
+ }
+
+ // Parse `#[serde(untagged)]`
+ Meta(Word(word)) if word == "untagged" => match item.data {
+ syn::Data::Enum(_) => {
+ untagged.set_true();
+ }
+ syn::Data::Struct(_) | syn::Data::Union(_) => {
+ cx.error("#[serde(untagged)] can only be used on enums")
+ }
+ },
+
+ // Parse `#[serde(tag = "type")]`
+ Meta(NameValue(ref m)) if m.ident == "tag" => {
+ if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+ match item.data {
+ syn::Data::Enum(_) => {
+ internal_tag.set(s.value());
+ }
+ syn::Data::Struct(_) | syn::Data::Union(_) => {
+ cx.error("#[serde(tag = \"...\")] can only be used on enums")
+ }
+ }
+ }
+ }
+
+ // Parse `#[serde(content = "c")]`
+ Meta(NameValue(ref m)) if m.ident == "content" => {
+ if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+ match item.data {
+ syn::Data::Enum(_) => {
+ content.set(s.value());
+ }
+ syn::Data::Struct(_) | syn::Data::Union(_) => cx.error(
+ "#[serde(content = \"...\")] can only be used on \
+ enums",
+ ),
+ }
+ }
+ }
+
+ // Parse `#[serde(from = "Type")]
+ Meta(NameValue(ref m)) if m.ident == "from" => {
+ if let Ok(from_ty) = parse_lit_into_ty(cx, m.ident.as_ref(), &m.lit) {
+ type_from.set_opt(Some(from_ty));
+ }
+ }
+
+ // Parse `#[serde(into = "Type")]
+ Meta(NameValue(ref m)) if m.ident == "into" => {
+ if let Ok(into_ty) = parse_lit_into_ty(cx, m.ident.as_ref(), &m.lit) {
+ type_into.set_opt(Some(into_ty));
+ }
+ }
+
+ // Parse `#[serde(remote = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "remote" => {
+ if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
+ if is_primitive_path(&path, "Self") {
+ remote.set(item.ident.into());
+ } else {
+ remote.set(path);
+ }
+ }
+ }
+
+ // Parse `#[serde(field_identifier)]`
+ Meta(Word(word)) if word == "field_identifier" => {
+ field_identifier.set_true();
+ }
+
+ // Parse `#[serde(variant_identifier)]`
+ Meta(Word(word)) if word == "variant_identifier" => {
+ variant_identifier.set_true();
+ }
+
+ Meta(ref meta_item) => {
+ cx.error(format!(
+ "unknown serde container attribute `{}`",
+ meta_item.name()
+ ));
+ }
+
+ Literal(_) => {
+ cx.error("unexpected literal in serde container attribute");
+ }
+ }
+ }
+ }
+
+ Container {
+ name: Name {
+ serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()),
+ deserialize: de_name.get().unwrap_or_else(|| item.ident.to_string()),
+ },
+ deny_unknown_fields: deny_unknown_fields.get(),
+ default: default.get().unwrap_or(Default::None),
+ rename_all: rename_all.get().unwrap_or(RenameRule::None),
+ ser_bound: ser_bound.get(),
+ de_bound: de_bound.get(),
+ tag: decide_tag(cx, item, &untagged, internal_tag, content),
+ type_from: type_from.get(),
+ type_into: type_into.get(),
+ remote: remote.get(),
+ identifier: decide_identifier(cx, item, &field_identifier, &variant_identifier),
+ has_flatten: false,
+ }
+ }
+
+ pub fn name(&self) -> &Name {
+ &self.name
+ }
+
+ pub fn rename_all(&self) -> &RenameRule {
+ &self.rename_all
+ }
+
+ pub fn deny_unknown_fields(&self) -> bool {
+ self.deny_unknown_fields
+ }
+
+ pub fn default(&self) -> &Default {
+ &self.default
+ }
+
+ pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
+ self.ser_bound.as_ref().map(|vec| &vec[..])
+ }
+
+ pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
+ self.de_bound.as_ref().map(|vec| &vec[..])
+ }
+
+ pub fn tag(&self) -> &EnumTag {
+ &self.tag
+ }
+
+ pub fn type_from(&self) -> Option<&syn::Type> {
+ self.type_from.as_ref()
+ }
+
+ pub fn type_into(&self) -> Option<&syn::Type> {
+ self.type_into.as_ref()
+ }
+
+ pub fn remote(&self) -> Option<&syn::Path> {
+ self.remote.as_ref()
+ }
+
+ pub fn identifier(&self) -> Identifier {
+ self.identifier
+ }
+
+ pub fn has_flatten(&self) -> bool {
+ self.has_flatten
+ }
+
+ pub fn mark_has_flatten(&mut self) {
+ self.has_flatten = true;
+ }
+}
+
+fn decide_tag(
+ cx: &Ctxt,
+ item: &syn::DeriveInput,
+ untagged: &BoolAttr,
+ internal_tag: Attr<String>,
+ content: Attr<String>,
+) -> EnumTag {
+ match (untagged.get(), internal_tag.get(), content.get()) {
+ (false, None, None) => EnumTag::External,
+ (true, None, None) => EnumTag::None,
+ (false, Some(tag), None) => {
+ // Check that there are no tuple variants.
+ if let syn::Data::Enum(ref data) = item.data {
+ for variant in &data.variants {
+ match variant.fields {
+ syn::Fields::Named(_) | syn::Fields::Unit => {}
+ syn::Fields::Unnamed(ref fields) => {
+ if fields.unnamed.len() != 1 {
+ cx.error(
+ "#[serde(tag = \"...\")] cannot be used with tuple \
+ variants",
+ );
+ break;
+ }
+ }
+ }
+ }
+ }
+ EnumTag::Internal { tag: tag }
+ }
+ (true, Some(_), None) => {
+ cx.error("enum cannot be both untagged and internally tagged");
+ EnumTag::External // doesn't matter, will error
+ }
+ (false, None, Some(_)) => {
+ cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together");
+ EnumTag::External
+ }
+ (true, None, Some(_)) => {
+ cx.error("untagged enum cannot have #[serde(content = \"...\")]");
+ EnumTag::External
+ }
+ (false, Some(tag), Some(content)) => EnumTag::Adjacent {
+ tag: tag,
+ content: content,
+ },
+ (true, Some(_), Some(_)) => {
+ cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]");
+ EnumTag::External
+ }
+ }
+}
+
+fn decide_identifier(
+ cx: &Ctxt,
+ item: &syn::DeriveInput,
+ field_identifier: &BoolAttr,
+ variant_identifier: &BoolAttr,
+) -> Identifier {
+ match (&item.data, field_identifier.get(), variant_identifier.get()) {
+ (_, false, false) => Identifier::No,
+ (_, true, true) => {
+ cx.error("`field_identifier` and `variant_identifier` cannot both be set");
+ Identifier::No
+ }
+ (&syn::Data::Enum(_), true, false) => Identifier::Field,
+ (&syn::Data::Enum(_), false, true) => Identifier::Variant,
+ (&syn::Data::Struct(_), true, false) | (&syn::Data::Union(_), true, false) => {
+ cx.error("`field_identifier` can only be used on an enum");
+ Identifier::No
+ }
+ (&syn::Data::Struct(_), false, true) | (&syn::Data::Union(_), false, true) => {
+ cx.error("`variant_identifier` can only be used on an enum");
+ Identifier::No
+ }
+ }
+}
+
+/// Represents variant attribute information
+pub struct Variant {
+ name: Name,
+ ser_renamed: bool,
+ de_renamed: bool,
+ rename_all: RenameRule,
+ ser_bound: Option<Vec<syn::WherePredicate>>,
+ de_bound: Option<Vec<syn::WherePredicate>>,
+ skip_deserializing: bool,
+ skip_serializing: bool,
+ other: bool,
+ serialize_with: Option<syn::ExprPath>,
+ deserialize_with: Option<syn::ExprPath>,
+ borrow: Option<syn::Meta>,
+}
+
+impl Variant {
+ pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
+ let mut ser_name = Attr::none(cx, "rename");
+ let mut de_name = Attr::none(cx, "rename");
+ let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
+ let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
+ let mut rename_all = Attr::none(cx, "rename_all");
+ let mut ser_bound = Attr::none(cx, "bound");
+ let mut de_bound = Attr::none(cx, "bound");
+ let mut other = BoolAttr::none(cx, "other");
+ let mut serialize_with = Attr::none(cx, "serialize_with");
+ let mut deserialize_with = Attr::none(cx, "deserialize_with");
+ let mut borrow = Attr::none(cx, "borrow");
+
+ for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
+ for meta_item in meta_items {
+ match meta_item {
+ // Parse `#[serde(rename = "foo")]`
+ Meta(NameValue(ref m)) if m.ident == "rename" => {
+ if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+ ser_name.set(s.value());
+ de_name.set(s.value());
+ }
+ }
+
+ // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
+ Meta(List(ref m)) if m.ident == "rename" => {
+ if let Ok((ser, de)) = get_renames(cx, &m.nested) {
+ ser_name.set_opt(ser.map(syn::LitStr::value));
+ de_name.set_opt(de.map(syn::LitStr::value));
+ }
+ }
+
+ // Parse `#[serde(rename_all = "foo")]`
+ Meta(NameValue(ref m)) if m.ident == "rename_all" => {
+ if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+ match RenameRule::from_str(&s.value()) {
+ Ok(rename_rule) => rename_all.set(rename_rule),
+ Err(()) => cx.error(format!(
+ "unknown rename rule for #[serde(rename_all \
+ = {:?})]",
+ s.value()
+ )),
+ }
+ }
+ }
+
+ // Parse `#[serde(skip)]`
+ Meta(Word(word)) if word == "skip" => {
+ skip_serializing.set_true();
+ skip_deserializing.set_true();
+ }
+
+ // Parse `#[serde(skip_deserializing)]`
+ Meta(Word(word)) if word == "skip_deserializing" => {
+ skip_deserializing.set_true();
+ }
+
+ // Parse `#[serde(skip_serializing)]`
+ Meta(Word(word)) if word == "skip_serializing" => {
+ skip_serializing.set_true();
+ }
+
+ // Parse `#[serde(other)]`
+ Meta(Word(word)) if word == "other" => {
+ other.set_true();
+ }
+
+ // Parse `#[serde(bound = "D: Serialize")]`
+ Meta(NameValue(ref m)) if m.ident == "bound" => {
+ if let Ok(where_predicates) =
+ parse_lit_into_where(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit)
+ {
+ ser_bound.set(where_predicates.clone());
+ de_bound.set(where_predicates);
+ }
+ }
+
+ // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
+ Meta(List(ref m)) if m.ident == "bound" => {
+ if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
+ ser_bound.set_opt(ser);
+ de_bound.set_opt(de);
+ }
+ }
+
+ // Parse `#[serde(with = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "with" => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+ let mut ser_path = path.clone();
+ ser_path
+ .path
+ .segments
+ .push(Ident::new("serialize", Span::call_site()).into());
+ serialize_with.set(ser_path);
+ let mut de_path = path;
+ de_path
+ .path
+ .segments
+ .push(Ident::new("deserialize", Span::call_site()).into());
+ deserialize_with.set(de_path);
+ }
+ }
+
+ // Parse `#[serde(serialize_with = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "serialize_with" => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+ serialize_with.set(path);
+ }
+ }
+
+ // Parse `#[serde(deserialize_with = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "deserialize_with" => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+ deserialize_with.set(path);
+ }
+ }
+
+ // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
+ Meta(ref m) if m.name() == "borrow" => match variant.fields {
+ syn::Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => {
+ borrow.set(m.clone());
+ }
+ _ => {
+ cx.error("#[serde(borrow)] may only be used on newtype variants");
+ }
+ },
+
+ Meta(ref meta_item) => {
+ cx.error(format!(
+ "unknown serde variant attribute `{}`",
+ meta_item.name()
+ ));
+ }
+
+ Literal(_) => {
+ cx.error("unexpected literal in serde variant attribute");
+ }
+ }
+ }
+ }
+
+ let ser_name = ser_name.get();
+ let ser_renamed = ser_name.is_some();
+ let de_name = de_name.get();
+ let de_renamed = de_name.is_some();
+ Variant {
+ name: Name {
+ serialize: ser_name.unwrap_or_else(|| variant.ident.to_string()),
+ deserialize: de_name.unwrap_or_else(|| variant.ident.to_string()),
+ },
+ ser_renamed: ser_renamed,
+ de_renamed: de_renamed,
+ rename_all: rename_all.get().unwrap_or(RenameRule::None),
+ ser_bound: ser_bound.get(),
+ de_bound: de_bound.get(),
+ skip_deserializing: skip_deserializing.get(),
+ skip_serializing: skip_serializing.get(),
+ other: other.get(),
+ serialize_with: serialize_with.get(),
+ deserialize_with: deserialize_with.get(),
+ borrow: borrow.get(),
+ }
+ }
+
+ pub fn name(&self) -> &Name {
+ &self.name
+ }
+
+ pub fn rename_by_rule(&mut self, rule: &RenameRule) {
+ if !self.ser_renamed {
+ self.name.serialize = rule.apply_to_variant(&self.name.serialize);
+ }
+ if !self.de_renamed {
+ self.name.deserialize = rule.apply_to_variant(&self.name.deserialize);
+ }
+ }
+
+ pub fn rename_all(&self) -> &RenameRule {
+ &self.rename_all
+ }
+
+ pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
+ self.ser_bound.as_ref().map(|vec| &vec[..])
+ }
+
+ pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
+ self.de_bound.as_ref().map(|vec| &vec[..])
+ }
+
+ pub fn skip_deserializing(&self) -> bool {
+ self.skip_deserializing
+ }
+
+ pub fn skip_serializing(&self) -> bool {
+ self.skip_serializing
+ }
+
+ pub fn other(&self) -> bool {
+ self.other
+ }
+
+ pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
+ self.serialize_with.as_ref()
+ }
+
+ pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
+ self.deserialize_with.as_ref()
+ }
+}
+
+/// Represents field attribute information
+pub struct Field {
+ name: Name,
+ ser_renamed: bool,
+ de_renamed: bool,
+ skip_serializing: bool,
+ skip_deserializing: bool,
+ skip_serializing_if: Option<syn::ExprPath>,
+ default: Default,
+ serialize_with: Option<syn::ExprPath>,
+ deserialize_with: Option<syn::ExprPath>,
+ ser_bound: Option<Vec<syn::WherePredicate>>,
+ de_bound: Option<Vec<syn::WherePredicate>>,
+ borrowed_lifetimes: BTreeSet<syn::Lifetime>,
+ getter: Option<syn::ExprPath>,
+ flatten: bool,
+}
+
+/// Represents the default to use for a field when deserializing.
+pub enum Default {
+ /// Field must always be specified because it does not have a default.
+ None,
+ /// The default is given by `std::default::Default::default()`.
+ Default,
+ /// The default is given by this function.
+ Path(syn::ExprPath),
+}
+
+impl Default {
+ #[cfg(feature = "deserialize_in_place")]
+ pub fn is_none(&self) -> bool {
+ match *self {
+ Default::None => true,
+ Default::Default | Default::Path(_) => false,
+ }
+ }
+}
+
+impl Field {
+ /// Extract out the `#[serde(...)]` attributes from a struct field.
+ pub fn from_ast(
+ cx: &Ctxt,
+ index: usize,
+ field: &syn::Field,
+ attrs: Option<&Variant>,
+ container_default: &Default,
+ ) -> Self {
+ let mut ser_name = Attr::none(cx, "rename");
+ let mut de_name = Attr::none(cx, "rename");
+ let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
+ let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
+ let mut skip_serializing_if = Attr::none(cx, "skip_serializing_if");
+ let mut default = Attr::none(cx, "default");
+ let mut serialize_with = Attr::none(cx, "serialize_with");
+ let mut deserialize_with = Attr::none(cx, "deserialize_with");
+ let mut ser_bound = Attr::none(cx, "bound");
+ let mut de_bound = Attr::none(cx, "bound");
+ let mut borrowed_lifetimes = Attr::none(cx, "borrow");
+ let mut getter = Attr::none(cx, "getter");
+ let mut flatten = BoolAttr::none(cx, "flatten");
+
+ let ident = match field.ident {
+ Some(ref ident) => ident.to_string(),
+ None => index.to_string(),
+ };
+
+ let variant_borrow = attrs
+ .and_then(|variant| variant.borrow.as_ref())
+ .map(|borrow| vec![Meta(borrow.clone())]);
+
+ for meta_items in field
+ .attrs
+ .iter()
+ .filter_map(get_serde_meta_items)
+ .chain(variant_borrow)
+ {
+ for meta_item in meta_items {
+ match meta_item {
+ // Parse `#[serde(rename = "foo")]`
+ Meta(NameValue(ref m)) if m.ident == "rename" => {
+ if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
+ ser_name.set(s.value());
+ de_name.set(s.value());
+ }
+ }
+
+ // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
+ Meta(List(ref m)) if m.ident == "rename" => {
+ if let Ok((ser, de)) = get_renames(cx, &m.nested) {
+ ser_name.set_opt(ser.map(syn::LitStr::value));
+ de_name.set_opt(de.map(syn::LitStr::value));
+ }
+ }
+
+ // Parse `#[serde(default)]`
+ Meta(Word(word)) if word == "default" => {
+ default.set(Default::Default);
+ }
+
+ // Parse `#[serde(default = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "default" => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+ default.set(Default::Path(path));
+ }
+ }
+
+ // Parse `#[serde(skip_serializing)]`
+ Meta(Word(word)) if word == "skip_serializing" => {
+ skip_serializing.set_true();
+ }
+
+ // Parse `#[serde(skip_deserializing)]`
+ Meta(Word(word)) if word == "skip_deserializing" => {
+ skip_deserializing.set_true();
+ }
+
+ // Parse `#[serde(skip)]`
+ Meta(Word(word)) if word == "skip" => {
+ skip_serializing.set_true();
+ skip_deserializing.set_true();
+ }
+
+ // Parse `#[serde(skip_serializing_if = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "skip_serializing_if" => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+ skip_serializing_if.set(path);
+ }
+ }
+
+ // Parse `#[serde(serialize_with = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "serialize_with" => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+ serialize_with.set(path);
+ }
+ }
+
+ // Parse `#[serde(deserialize_with = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "deserialize_with" => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+ deserialize_with.set(path);
+ }
+ }
+
+ // Parse `#[serde(with = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "with" => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+ let mut ser_path = path.clone();
+ ser_path
+ .path
+ .segments
+ .push(Ident::new("serialize", Span::call_site()).into());
+ serialize_with.set(ser_path);
+ let mut de_path = path;
+ de_path
+ .path
+ .segments
+ .push(Ident::new("deserialize", Span::call_site()).into());
+ deserialize_with.set(de_path);
+ }
+ }
+
+ // Parse `#[serde(bound = "D: Serialize")]`
+ Meta(NameValue(ref m)) if m.ident == "bound" => {
+ if let Ok(where_predicates) =
+ parse_lit_into_where(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit)
+ {
+ ser_bound.set(where_predicates.clone());
+ de_bound.set(where_predicates);
+ }
+ }
+
+ // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
+ Meta(List(ref m)) if m.ident == "bound" => {
+ if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
+ ser_bound.set_opt(ser);
+ de_bound.set_opt(de);
+ }
+ }
+
+ // Parse `#[serde(borrow)]`
+ Meta(Word(word)) if word == "borrow" => {
+ if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
+ borrowed_lifetimes.set(borrowable);
+ }
+ }
+
+ // Parse `#[serde(borrow = "'a + 'b")]`
+ Meta(NameValue(ref m)) if m.ident == "borrow" => {
+ if let Ok(lifetimes) =
+ parse_lit_into_lifetimes(cx, m.ident.as_ref(), &m.lit)
+ {
+ if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
+ for lifetime in &lifetimes {
+ if !borrowable.contains(lifetime) {
+ cx.error(format!(
+ "field `{}` does not have lifetime {}",
+ ident, lifetime
+ ));
+ }
+ }
+ borrowed_lifetimes.set(lifetimes);
+ }
+ }
+ }
+
+ // Parse `#[serde(getter = "...")]`
+ Meta(NameValue(ref m)) if m.ident == "getter" => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
+ getter.set(path);
+ }
+ }
+
+ // Parse `#[serde(flatten)]`
+ Meta(Word(word)) if word == "flatten" => {
+ flatten.set_true();
+ }
+
+ Meta(ref meta_item) => {
+ cx.error(format!(
+ "unknown serde field attribute `{}`",
+ meta_item.name()
+ ));
+ }
+
+ Literal(_) => {
+ cx.error("unexpected literal in serde field attribute");
+ }
+ }
+ }
+ }
+
+ // Is skip_deserializing, initialize the field to Default::default() unless a different
+ // default is specified by `#[serde(default = "...")]` on ourselves or our container (e.g.
+ // the struct we are in).
+ if let Default::None = *container_default {
+ if skip_deserializing.0.value.is_some() {
+ default.set_if_none(Default::Default);
+ }
+ }
+
+ let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default();
+ if !borrowed_lifetimes.is_empty() {
+ // Cow<str> and Cow<[u8]> never borrow by default:
+ //
+ // impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
+ //
+ // A #[serde(borrow)] attribute enables borrowing that corresponds
+ // roughly to these impls:
+ //
+ // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str>
+ // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]>
+ if is_cow(&field.ty, is_str) {
+ let mut path = syn::Path {
+ leading_colon: None,
+ segments: Punctuated::new(),
+ };
+ path.segments
+ .push(Ident::new("_serde", Span::call_site()).into());
+ path.segments
+ .push(Ident::new("private", Span::call_site()).into());
+ path.segments
+ .push(Ident::new("de", Span::call_site()).into());
+ path.segments
+ .push(Ident::new("borrow_cow_str", Span::call_site()).into());
+ let expr = syn::ExprPath {
+ attrs: Vec::new(),
+ qself: None,
+ path: path,
+ };
+ deserialize_with.set_if_none(expr);
+ } else if is_cow(&field.ty, is_slice_u8) {
+ let mut path = syn::Path {
+ leading_colon: None,
+ segments: Punctuated::new(),
+ };
+ path.segments
+ .push(Ident::new("_serde", Span::call_site()).into());
+ path.segments
+ .push(Ident::new("private", Span::call_site()).into());
+ path.segments
+ .push(Ident::new("de", Span::call_site()).into());
+ path.segments
+ .push(Ident::new("borrow_cow_bytes", Span::call_site()).into());
+ let expr = syn::ExprPath {
+ attrs: Vec::new(),
+ qself: None,
+ path: path,
+ };
+ deserialize_with.set_if_none(expr);
+ }
+ } else if is_implicitly_borrowed(&field.ty) {
+ // Types &str and &[u8] are always implicitly borrowed. No need for
+ // a #[serde(borrow)].
+ collect_lifetimes(&field.ty, &mut borrowed_lifetimes);
+ }
+
+ let ser_name = ser_name.get();
+ let ser_renamed = ser_name.is_some();
+ let de_name = de_name.get();
+ let de_renamed = de_name.is_some();
+ Field {
+ name: Name {
+ serialize: ser_name.unwrap_or_else(|| ident.clone()),
+ deserialize: de_name.unwrap_or(ident),
+ },
+ ser_renamed: ser_renamed,
+ de_renamed: de_renamed,
+ skip_serializing: skip_serializing.get(),
+ skip_deserializing: skip_deserializing.get(),
+ skip_serializing_if: skip_serializing_if.get(),
+ default: default.get().unwrap_or(Default::None),
+ serialize_with: serialize_with.get(),
+ deserialize_with: deserialize_with.get(),
+ ser_bound: ser_bound.get(),
+ de_bound: de_bound.get(),
+ borrowed_lifetimes: borrowed_lifetimes,
+ getter: getter.get(),
+ flatten: flatten.get(),
+ }
+ }
+
+ pub fn name(&self) -> &Name {
+ &self.name
+ }
+
+ pub fn rename_by_rule(&mut self, rule: &RenameRule) {
+ if !self.ser_renamed {
+ self.name.serialize = rule.apply_to_field(&self.name.serialize);
+ }
+ if !self.de_renamed {
+ self.name.deserialize = rule.apply_to_field(&self.name.deserialize);
+ }
+ }
+
+ pub fn skip_serializing(&self) -> bool {
+ self.skip_serializing
+ }
+
+ pub fn skip_deserializing(&self) -> bool {
+ self.skip_deserializing
+ }
+
+ pub fn skip_serializing_if(&self) -> Option<&syn::ExprPath> {
+ self.skip_serializing_if.as_ref()
+ }
+
+ pub fn default(&self) -> &Default {
+ &self.default
+ }
+
+ pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
+ self.serialize_with.as_ref()
+ }
+
+ pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
+ self.deserialize_with.as_ref()
+ }
+
+ pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
+ self.ser_bound.as_ref().map(|vec| &vec[..])
+ }
+
+ pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
+ self.de_bound.as_ref().map(|vec| &vec[..])
+ }
+
+ pub fn borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime> {
+ &self.borrowed_lifetimes
+ }
+
+ pub fn getter(&self) -> Option<&syn::ExprPath> {
+ self.getter.as_ref()
+ }
+
+ pub fn flatten(&self) -> bool {
+ self.flatten
+ }
+}
+
+type SerAndDe<T> = (Option<T>, Option<T>);
+
+fn get_ser_and_de<'a, T, F>(
+ cx: &Ctxt,
+ attr_name: &'static str,
+ metas: &'a Punctuated<syn::NestedMeta, Token![,]>,
+ f: F,
+) -> Result<SerAndDe<T>, ()>
+where
+ T: 'a,
+ F: Fn(&Ctxt, &str, &str, &'a syn::Lit) -> Result<T, ()>,
+{
+ let mut ser_meta = Attr::none(cx, attr_name);
+ let mut de_meta = Attr::none(cx, attr_name);
+
+ for meta in metas {
+ match *meta {
+ Meta(NameValue(ref meta)) if meta.ident == "serialize" => {
+ if let Ok(v) = f(cx, attr_name, meta.ident.as_ref(), &meta.lit) {
+ ser_meta.set(v);
+ }
+ }
+
+ Meta(NameValue(ref meta)) if meta.ident == "deserialize" => {
+ if let Ok(v) = f(cx, attr_name, meta.ident.as_ref(), &meta.lit) {
+ de_meta.set(v);
+ }
+ }
+
+ _ => {
+ cx.error(format!(
+ "malformed {0} attribute, expected `{0}(serialize = ..., \
+ deserialize = ...)`",
+ attr_name
+ ));
+ return Err(());
+ }
+ }
+ }
+
+ Ok((ser_meta.get(), de_meta.get()))
+}
+
+fn get_renames<'a>(
+ cx: &Ctxt,
+ items: &'a Punctuated<syn::NestedMeta, Token![,]>,
+) -> Result<SerAndDe<&'a syn::LitStr>, ()> {
+ get_ser_and_de(cx, "rename", items, get_lit_str)
+}
+
+fn get_where_predicates(
+ cx: &Ctxt,
+ items: &Punctuated<syn::NestedMeta, Token![,]>,
+) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
+ get_ser_and_de(cx, "bound", items, parse_lit_into_where)
+}
+
+pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMeta>> {
+ if attr.path.segments.len() == 1 && attr.path.segments[0].ident == "serde" {
+ match attr.interpret_meta() {
+ Some(List(ref meta)) => Some(meta.nested.iter().cloned().collect()),
+ _ => {
+ // TODO: produce an error
+ None
+ }
+ }
+ } else {
+ None
+ }
+}
+
+fn get_lit_str<'a>(
+ cx: &Ctxt,
+ attr_name: &str,
+ meta_item_name: &str,
+ lit: &'a syn::Lit,
+) -> Result<&'a syn::LitStr, ()> {
+ if let syn::Lit::Str(ref lit) = *lit {
+ Ok(lit)
+ } else {
+ cx.error(format!(
+ "expected serde {} attribute to be a string: `{} = \"...\"`",
+ attr_name, meta_item_name
+ ));
+ Err(())
+ }
+}
+
+fn parse_lit_into_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Path, ()> {
+ let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
+ parse_lit_str(string)
+ .map_err(|_| cx.error(format!("failed to parse path: {:?}", string.value())))
+}
+
+fn parse_lit_into_expr_path(
+ cx: &Ctxt,
+ attr_name: &str,
+ lit: &syn::Lit,
+) -> Result<syn::ExprPath, ()> {
+ let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
+ parse_lit_str(string)
+ .map_err(|_| cx.error(format!("failed to parse path: {:?}", string.value())))
+}
+
+fn parse_lit_into_where(
+ cx: &Ctxt,
+ attr_name: &str,
+ meta_item_name: &str,
+ lit: &syn::Lit,
+) -> Result<Vec<syn::WherePredicate>, ()> {
+ let string = try!(get_lit_str(cx, attr_name, meta_item_name, lit));
+ if string.value().is_empty() {
+ return Ok(Vec::new());
+ }
+
+ let where_string = syn::LitStr::new(&format!("where {}", string.value()), string.span());
+
+ parse_lit_str::<syn::WhereClause>(&where_string)
+ .map(|wh| wh.predicates.into_iter().collect())
+ .map_err(|err| cx.error(err))
+}
+
+fn parse_lit_into_ty(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Type, ()> {
+ let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
+
+ parse_lit_str(string).map_err(|_| {
+ cx.error(format!(
+ "failed to parse type: {} = {:?}",
+ attr_name,
+ string.value()
+ ))
+ })
+}
+
+// Parses a string literal like "'a + 'b + 'c" containing a nonempty list of
+// lifetimes separated by `+`.
+fn parse_lit_into_lifetimes(
+ cx: &Ctxt,
+ attr_name: &str,
+ lit: &syn::Lit,
+) -> Result<BTreeSet<syn::Lifetime>, ()> {
+ let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
+ if string.value().is_empty() {
+ cx.error("at least one lifetime must be borrowed");
+ return Err(());
+ }
+
+ struct BorrowedLifetimes(Punctuated<syn::Lifetime, Token![+]>);
+
+ impl Synom for BorrowedLifetimes {
+ named!(parse -> Self, map!(
+ call!(Punctuated::parse_separated_nonempty),
+ BorrowedLifetimes
+ ));
+ }
+
+ if let Ok(BorrowedLifetimes(lifetimes)) = parse_lit_str(string) {
+ let mut set = BTreeSet::new();
+ for lifetime in lifetimes {
+ if !set.insert(lifetime) {
+ cx.error(format!("duplicate borrowed lifetime `{}`", lifetime));
+ }
+ }
+ return Ok(set);
+ }
+
+ cx.error(format!(
+ "failed to parse borrowed lifetimes: {:?}",
+ string.value()
+ ));
+ Err(())
+}
+
+fn is_implicitly_borrowed(ty: &syn::Type) -> bool {
+ is_implicitly_borrowed_reference(ty) || is_option(ty, is_implicitly_borrowed_reference)
+}
+
+fn is_implicitly_borrowed_reference(ty: &syn::Type) -> bool {
+ is_reference(ty, is_str) || is_reference(ty, is_slice_u8)
+}
+
+// Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
+// This can have false negatives and false positives.
+//
+// False negative:
+//
+// use std::borrow::Cow as Pig;
+//
+// #[derive(Deserialize)]
+// struct S<'a> {
+// #[serde(borrow)]
+// pig: Pig<'a, str>,
+// }
+//
+// False positive:
+//
+// type str = [i16];
+//
+// #[derive(Deserialize)]
+// struct S<'a> {
+// #[serde(borrow)]
+// cow: Cow<'a, str>,
+// }
+fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
+ let path = match *ty {
+ syn::Type::Path(ref ty) => &ty.path,
+ _ => {
+ return false;
+ }
+ };
+ let seg = match path.segments.last() {
+ Some(seg) => seg.into_value(),
+ None => {
+ return false;
+ }
+ };
+ let args = match seg.arguments {
+ syn::PathArguments::AngleBracketed(ref bracketed) => &bracketed.args,
+ _ => {
+ return false;
+ }
+ };
+ seg.ident == "Cow" && args.len() == 2 && match (&args[0], &args[1]) {
+ (&syn::GenericArgument::Lifetime(_), &syn::GenericArgument::Type(ref arg)) => elem(arg),
+ _ => false,
+ }
+}
+
+fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
+ let path = match *ty {
+ syn::Type::Path(ref ty) => &ty.path,
+ _ => {
+ return false;
+ }
+ };
+ let seg = match path.segments.last() {
+ Some(seg) => seg.into_value(),
+ None => {
+ return false;
+ }
+ };
+ let args = match seg.arguments {
+ syn::PathArguments::AngleBracketed(ref bracketed) => &bracketed.args,
+ _ => {
+ return false;
+ }
+ };
+ seg.ident == "Option" && args.len() == 1 && match args[0] {
+ syn::GenericArgument::Type(ref arg) => elem(arg),
+ _ => false,
+ }
+}
+
+// Whether the type looks like it might be `&T` where elem="T". This can have
+// false negatives and false positives.
+//
+// False negative:
+//
+// type Yarn = str;
+//
+// #[derive(Deserialize)]
+// struct S<'a> {
+// r: &'a Yarn,
+// }
+//
+// False positive:
+//
+// type str = [i16];
+//
+// #[derive(Deserialize)]
+// struct S<'a> {
+// r: &'a str,
+// }
+fn is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
+ match *ty {
+ syn::Type::Reference(ref ty) => ty.mutability.is_none() && elem(&ty.elem),
+ _ => false,
+ }
+}
+
+fn is_str(ty: &syn::Type) -> bool {
+ is_primitive_type(ty, "str")
+}
+
+fn is_slice_u8(ty: &syn::Type) -> bool {
+ match *ty {
+ syn::Type::Slice(ref ty) => is_primitive_type(&ty.elem, "u8"),
+ _ => false,
+ }
+}
+
+fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool {
+ match *ty {
+ syn::Type::Path(ref ty) => ty.qself.is_none() && is_primitive_path(&ty.path, primitive),
+ _ => false,
+ }
+}
+
+fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool {
+ path.leading_colon.is_none() && path.segments.len() == 1 && path.segments[0].ident == primitive
+ && path.segments[0].arguments.is_empty()
+}
+
+// All lifetimes that this type could borrow from a Deserializer.
+//
+// For example a type `S<'a, 'b>` could borrow `'a` and `'b`. On the other hand
+// a type `for<'a> fn(&'a str)` could not borrow `'a` from the Deserializer.
+//
+// This is used when there is an explicit or implicit `#[serde(borrow)]`
+// attribute on the field so there must be at least one borrowable lifetime.
+fn borrowable_lifetimes(
+ cx: &Ctxt,
+ name: &str,
+ ty: &syn::Type,
+) -> Result<BTreeSet<syn::Lifetime>, ()> {
+ let mut lifetimes = BTreeSet::new();
+ collect_lifetimes(ty, &mut lifetimes);
+ if lifetimes.is_empty() {
+ cx.error(format!("field `{}` has no lifetimes to borrow", name));
+ Err(())
+ } else {
+ Ok(lifetimes)
+ }
+}
+
+fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
+ match *ty {
+ syn::Type::Slice(ref ty) => {
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Array(ref ty) => {
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Ptr(ref ty) => {
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Reference(ref ty) => {
+ out.extend(ty.lifetime.iter().cloned());
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Tuple(ref ty) => for elem in &ty.elems {
+ collect_lifetimes(elem, out);
+ },
+ syn::Type::Path(ref ty) => {
+ if let Some(ref qself) = ty.qself {
+ collect_lifetimes(&qself.ty, out);
+ }
+ for seg in &ty.path.segments {
+ if let syn::PathArguments::AngleBracketed(ref bracketed) = seg.arguments {
+ for arg in &bracketed.args {
+ match *arg {
+ syn::GenericArgument::Lifetime(ref lifetime) => {
+ out.insert(lifetime.clone());
+ }
+ syn::GenericArgument::Type(ref ty) => {
+ collect_lifetimes(ty, out);
+ }
+ syn::GenericArgument::Binding(ref binding) => {
+ collect_lifetimes(&binding.ty, out);
+ }
+ syn::GenericArgument::Const(_) => {}
+ }
+ }
+ }
+ }
+ }
+ syn::Type::Paren(ref ty) => {
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Group(ref ty) => {
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::BareFn(_)
+ | syn::Type::Never(_)
+ | syn::Type::TraitObject(_)
+ | syn::Type::ImplTrait(_)
+ | syn::Type::Infer(_)
+ | syn::Type::Macro(_)
+ | syn::Type::Verbatim(_) => {}
+ }
+}
+
+fn parse_lit_str<T>(s: &syn::LitStr) -> Result<T, ParseError>
+where
+ T: Synom,
+{
+ let tokens = try!(spanned_tokens(s));
+ syn::parse2(tokens)
+}
+
+fn spanned_tokens(s: &syn::LitStr) -> Result<TokenStream, ParseError> {
+ let stream = try!(syn::parse_str(&s.value()));
+ Ok(respan_token_stream(stream, s.span()))
+}
+
+fn respan_token_stream(stream: TokenStream, span: Span) -> TokenStream {
+ stream
+ .into_iter()
+ .map(|token| respan_token_tree(token, span))
+ .collect()
+}
+
+fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree {
+ if let TokenTree::Group(ref mut g) = token {
+ *g = Group::new(g.delimiter(), respan_token_stream(g.stream().clone(), span));
+ }
+ token.set_span(span);
+ token
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/case.rs
@@ -0,0 +1,173 @@
+// Copyright 2017 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
+#[allow(deprecated, unused_imports)]
+use std::ascii::AsciiExt;
+
+use std::str::FromStr;
+
+use self::RenameRule::*;
+
+#[derive(PartialEq)]
+pub enum RenameRule {
+ /// Don't apply a default rename rule.
+ None,
+ /// Rename direct children to "lowercase" style.
+ LowerCase,
+ /// Rename direct children to "UPPERCASE" style.
+ UPPERCASE,
+ /// Rename direct children to "PascalCase" style, as typically used for enum variants.
+ PascalCase,
+ /// Rename direct children to "camelCase" style.
+ CamelCase,
+ /// Rename direct children to "snake_case" style, as commonly used for fields.
+ SnakeCase,
+ /// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly used for constants.
+ ScreamingSnakeCase,
+ /// Rename direct children to "kebab-case" style.
+ KebabCase,
+ /// Rename direct children to "SCREAMING-KEBAB-CASE" style.
+ ScreamingKebabCase,
+}
+
+impl RenameRule {
+ pub fn apply_to_variant(&self, variant: &str) -> String {
+ match *self {
+ None | PascalCase => variant.to_owned(),
+ LowerCase => variant.to_ascii_lowercase(),
+ UPPERCASE => variant.to_ascii_uppercase(),
+ CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..],
+ SnakeCase => {
+ let mut snake = String::new();
+ for (i, ch) in variant.char_indices() {
+ if i > 0 && ch.is_uppercase() {
+ snake.push('_');
+ }
+ snake.push(ch.to_ascii_lowercase());
+ }
+ snake
+ }
+ ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(),
+ KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"),
+ ScreamingKebabCase => ScreamingSnakeCase
+ .apply_to_variant(variant)
+ .replace('_', "-"),
+ }
+ }
+
+ pub fn apply_to_field(&self, field: &str) -> String {
+ match *self {
+ None | LowerCase | SnakeCase => field.to_owned(),
+ UPPERCASE => field.to_ascii_uppercase(),
+ PascalCase => {
+ let mut pascal = String::new();
+ let mut capitalize = true;
+ for ch in field.chars() {
+ if ch == '_' {
+ capitalize = true;
+ } else if capitalize {
+ pascal.push(ch.to_ascii_uppercase());
+ capitalize = false;
+ } else {
+ pascal.push(ch);
+ }
+ }
+ pascal
+ }
+ CamelCase => {
+ let pascal = PascalCase.apply_to_field(field);
+ pascal[..1].to_ascii_lowercase() + &pascal[1..]
+ }
+ ScreamingSnakeCase => field.to_ascii_uppercase(),
+ KebabCase => field.replace('_', "-"),
+ ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-"),
+ }
+ }
+}
+
+impl FromStr for RenameRule {
+ type Err = ();
+
+ fn from_str(rename_all_str: &str) -> Result<Self, Self::Err> {
+ match rename_all_str {
+ "lowercase" => Ok(LowerCase),
+ "UPPERCASE" => Ok(UPPERCASE),
+ "PascalCase" => Ok(PascalCase),
+ "camelCase" => Ok(CamelCase),
+ "snake_case" => Ok(SnakeCase),
+ "SCREAMING_SNAKE_CASE" => Ok(ScreamingSnakeCase),
+ "kebab-case" => Ok(KebabCase),
+ "SCREAMING-KEBAB-CASE" => Ok(ScreamingKebabCase),
+ _ => Err(()),
+ }
+ }
+}
+
+#[test]
+fn rename_variants() {
+ for &(original, lower, upper, camel, snake, screaming, kebab, screaming_kebab) in &[
+ (
+ "Outcome", "outcome", "OUTCOME", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
+ ),
+ (
+ "VeryTasty",
+ "verytasty",
+ "VERYTASTY",
+ "veryTasty",
+ "very_tasty",
+ "VERY_TASTY",
+ "very-tasty",
+ "VERY-TASTY",
+ ),
+ ("A", "a", "A", "a", "a", "A", "a", "A"),
+ ("Z42", "z42", "Z42", "z42", "z42", "Z42", "z42", "Z42"),
+ ] {
+ assert_eq!(None.apply_to_variant(original), original);
+ assert_eq!(LowerCase.apply_to_variant(original), lower);
+ assert_eq!(UPPERCASE.apply_to_variant(original), upper);
+ assert_eq!(PascalCase.apply_to_variant(original), original);
+ assert_eq!(CamelCase.apply_to_variant(original), camel);
+ assert_eq!(SnakeCase.apply_to_variant(original), snake);
+ assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming);
+ assert_eq!(KebabCase.apply_to_variant(original), kebab);
+ assert_eq!(
+ ScreamingKebabCase.apply_to_variant(original),
+ screaming_kebab
+ );
+ }
+}
+
+#[test]
+fn rename_fields() {
+ for &(original, upper, pascal, camel, screaming, kebab, screaming_kebab) in &[
+ (
+ "outcome", "OUTCOME", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME",
+ ),
+ (
+ "very_tasty",
+ "VERY_TASTY",
+ "VeryTasty",
+ "veryTasty",
+ "VERY_TASTY",
+ "very-tasty",
+ "VERY-TASTY",
+ ),
+ ("a", "A", "A", "a", "A", "a", "A"),
+ ("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"),
+ ] {
+ assert_eq!(None.apply_to_field(original), original);
+ assert_eq!(UPPERCASE.apply_to_field(original), upper);
+ assert_eq!(PascalCase.apply_to_field(original), pascal);
+ assert_eq!(CamelCase.apply_to_field(original), camel);
+ assert_eq!(SnakeCase.apply_to_field(original), original);
+ assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming);
+ assert_eq!(KebabCase.apply_to_field(original), kebab);
+ assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/check.rs
@@ -0,0 +1,284 @@
+// Copyright 2017 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use internals::ast::{Container, Data, Field, Style};
+use internals::attr::{EnumTag, Identifier};
+use internals::Ctxt;
+
+/// Cross-cutting checks that require looking at more than a single attrs
+/// object. Simpler checks should happen when parsing and building the attrs.
+pub fn check(cx: &Ctxt, cont: &Container) {
+ check_getter(cx, cont);
+ check_flatten(cx, cont);
+ check_identifier(cx, cont);
+ check_variant_skip_attrs(cx, cont);
+ check_internal_tag_field_name_conflict(cx, cont);
+ check_adjacent_tag_conflict(cx, cont);
+}
+
+/// Getters are only allowed inside structs (not enums) with the `remote`
+/// attribute.
+fn check_getter(cx: &Ctxt, cont: &Container) {
+ match cont.data {
+ Data::Enum(_, _) => {
+ if cont.data.has_getter() {
+ cx.error("#[serde(getter = \"...\")] is not allowed in an enum");
+ }
+ }
+ Data::Struct(_, _) => {
+ if cont.data.has_getter() && cont.attrs.remote().is_none() {
+ cx.error(
+ "#[serde(getter = \"...\")] can only be used in structs \
+ that have #[serde(remote = \"...\")]",
+ );
+ }
+ }
+ }
+}
+
+/// Flattening has some restrictions we can test.
+fn check_flatten(cx: &Ctxt, cont: &Container) {
+ match cont.data {
+ Data::Enum(_, ref variants) => {
+ for variant in variants {
+ for field in &variant.fields {
+ check_flatten_field(cx, variant.style, field);
+ }
+ }
+ }
+ Data::Struct(style, ref fields) => {
+ for field in fields {
+ check_flatten_field(cx, style, field);
+ }
+ }
+ }
+}
+
+fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
+ if !field.attrs.flatten() {
+ return;
+ }
+ match style {
+ Style::Tuple => {
+ cx.error("#[serde(flatten)] cannot be used on tuple structs");
+ }
+ Style::Newtype => {
+ cx.error("#[serde(flatten)] cannot be used on newtype structs");
+ }
+ _ => {}
+ }
+ if field.attrs.skip_serializing() {
+ cx.error(
+ "#[serde(flatten] can not be combined with \
+ #[serde(skip_serializing)]",
+ );
+ } else if field.attrs.skip_serializing_if().is_some() {
+ cx.error(
+ "#[serde(flatten] can not be combined with \
+ #[serde(skip_serializing_if = \"...\")]",
+ );
+ } else if field.attrs.skip_deserializing() {
+ cx.error(
+ "#[serde(flatten] can not be combined with \
+ #[serde(skip_deserializing)]",
+ );
+ }
+}
+
+/// The `other` attribute must be used at most once and it must be the last
+/// variant of an enum that has the `field_identifier` attribute.
+///
+/// Inside a `variant_identifier` all variants must be unit variants. Inside a
+/// `field_identifier` all but possibly one variant must be unit variants. The
+/// last variant may be a newtype variant which is an implicit "other" case.
+fn check_identifier(cx: &Ctxt, cont: &Container) {
+ let variants = match cont.data {
+ Data::Enum(_, ref variants) => variants,
+ Data::Struct(_, _) => {
+ return;
+ }
+ };
+
+ for (i, variant) in variants.iter().enumerate() {
+ match (
+ variant.style,
+ cont.attrs.identifier(),
+ variant.attrs.other(),
+ ) {
+ // The `other` attribute may only be used in a field_identifier.
+ (_, Identifier::Variant, true) | (_, Identifier::No, true) => {
+ cx.error("#[serde(other)] may only be used inside a field_identifier");
+ }
+
+ // Variant with `other` attribute must be the last one.
+ (Style::Unit, Identifier::Field, true) => {
+ if i < variants.len() - 1 {
+ cx.error("#[serde(other)] must be the last variant");
+ }
+ }
+
+ // Variant with `other` attribute must be a unit variant.
+ (_, Identifier::Field, true) => {
+ cx.error("#[serde(other)] must be on a unit variant");
+ }
+
+ // Any sort of variant is allowed if this is not an identifier.
+ (_, Identifier::No, false) => {}
+
+ // Unit variant without `other` attribute is always fine.
+ (Style::Unit, _, false) => {}
+
+ // The last field is allowed to be a newtype catch-all.
+ (Style::Newtype, Identifier::Field, false) => {
+ if i < variants.len() - 1 {
+ cx.error(format!("`{}` must be the last variant", variant.ident));
+ }
+ }
+
+ (_, Identifier::Field, false) => {
+ cx.error("field_identifier may only contain unit variants");
+ }
+
+ (_, Identifier::Variant, false) => {
+ cx.error("variant_identifier may only contain unit variants");
+ }
+ }
+ }
+}
+
+/// Skip-(de)serializing attributes are not allowed on variants marked
+/// (de)serialize_with.
+fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
+ let variants = match cont.data {
+ Data::Enum(_, ref variants) => variants,
+ Data::Struct(_, _) => {
+ return;
+ }
+ };
+
+ for variant in variants.iter() {
+ if variant.attrs.serialize_with().is_some() {
+ if variant.attrs.skip_serializing() {
+ cx.error(format!(
+ "variant `{}` cannot have both #[serde(serialize_with)] and \
+ #[serde(skip_serializing)]",
+ variant.ident
+ ));
+ }
+
+ for (i, field) in variant.fields.iter().enumerate() {
+ let ident = field
+ .ident
+ .as_ref()
+ .map_or_else(|| format!("{}", i), |ident| format!("`{}`", ident));
+
+ if field.attrs.skip_serializing() {
+ cx.error(format!(
+ "variant `{}` cannot have both #[serde(serialize_with)] and \
+ a field {} marked with #[serde(skip_serializing)]",
+ variant.ident, ident
+ ));
+ }
+
+ if field.attrs.skip_serializing_if().is_some() {
+ cx.error(format!(
+ "variant `{}` cannot have both #[serde(serialize_with)] and \
+ a field {} marked with #[serde(skip_serializing_if)]",
+ variant.ident, ident
+ ));
+ }
+ }
+ }
+
+ if variant.attrs.deserialize_with().is_some() {
+ if variant.attrs.skip_deserializing() {
+ cx.error(format!(
+ "variant `{}` cannot have both #[serde(deserialize_with)] and \
+ #[serde(skip_deserializing)]",
+ variant.ident
+ ));
+ }
+
+ for (i, field) in variant.fields.iter().enumerate() {
+ if field.attrs.skip_deserializing() {
+ let ident = field
+ .ident
+ .as_ref()
+ .map_or_else(|| format!("{}", i), |ident| format!("`{}`", ident));
+
+ cx.error(format!(
+ "variant `{}` cannot have both #[serde(deserialize_with)] \
+ and a field {} marked with #[serde(skip_deserializing)]",
+ variant.ident, ident
+ ));
+ }
+ }
+ }
+ }
+}
+
+/// The tag of an internally-tagged struct variant must not be
+/// the same as either one of its fields, as this would result in
+/// duplicate keys in the serialized output and/or ambiguity in
+/// the to-be-deserialized input.
+fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
+ let variants = match cont.data {
+ Data::Enum(_, ref variants) => variants,
+ Data::Struct(_, _) => return,
+ };
+
+ let tag = match *cont.attrs.tag() {
+ EnumTag::Internal { ref tag } => tag.as_str(),
+ EnumTag::External | EnumTag::Adjacent { .. } | EnumTag::None => return,
+ };
+
+ let diagnose_conflict = || {
+ let message = format!("variant field name `{}` conflicts with internal tag", tag);
+ cx.error(message);
+ };
+
+ for variant in variants {
+ match variant.style {
+ Style::Struct => {
+ for field in &variant.fields {
+ let check_ser = !field.attrs.skip_serializing();
+ let check_de = !field.attrs.skip_deserializing();
+ let name = field.attrs.name();
+ let ser_name = name.serialize_name();
+ let de_name = name.deserialize_name();
+
+ if check_ser && ser_name == tag || check_de && de_name == tag {
+ diagnose_conflict();
+ return;
+ }
+ }
+ }
+ Style::Unit | Style::Newtype | Style::Tuple => {}
+ }
+ }
+}
+
+/// In the case of adjacently-tagged enums, the type and the
+/// contents tag must differ, for the same reason.
+fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
+ let (type_tag, content_tag) = match *cont.attrs.tag() {
+ EnumTag::Adjacent {
+ ref tag,
+ ref content,
+ } => (tag, content),
+ EnumTag::Internal { .. } | EnumTag::External | EnumTag::None => return,
+ };
+
+ if type_tag == content_tag {
+ let message = format!(
+ "enum tags `{}` for type and content conflict with each other",
+ type_tag
+ );
+ cx.error(message);
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/ctxt.rs
@@ -0,0 +1,56 @@
+// Copyright 2017 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use std::cell::RefCell;
+use std::fmt::Display;
+use std::thread;
+
+#[derive(Default)]
+pub struct Ctxt {
+ errors: RefCell<Option<Vec<String>>>,
+}
+
+impl Ctxt {
+ pub fn new() -> Self {
+ Ctxt {
+ errors: RefCell::new(Some(Vec::new())),
+ }
+ }
+
+ pub fn error<T: Display>(&self, msg: T) {
+ self.errors
+ .borrow_mut()
+ .as_mut()
+ .unwrap()
+ .push(msg.to_string());
+ }
+
+ pub fn check(self) -> Result<(), String> {
+ let mut errors = self.errors.borrow_mut().take().unwrap();
+ match errors.len() {
+ 0 => Ok(()),
+ 1 => Err(errors.pop().unwrap()),
+ n => {
+ let mut msg = format!("{} errors:", n);
+ for err in errors {
+ msg.push_str("\n\t# ");
+ msg.push_str(&err);
+ }
+ Err(msg)
+ }
+ }
+ }
+}
+
+impl Drop for Ctxt {
+ fn drop(&mut self) {
+ if !thread::panicking() && self.errors.borrow().is_some() {
+ panic!("forgot to check for errors");
+ }
+ }
+}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/mod.rs
@@ -0,0 +1,16 @@
+// Copyright 2017 Serde Developers
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+pub mod ast;
+pub mod attr;
+
+mod ctxt;
+pub use self::ctxt::Ctxt;
+
+mod case;
+mod check;
--- a/third_party/rust/serde_derive/src/lib.rs
+++ b/third_party/rust/serde_derive/src/lib.rs
@@ -17,50 +17,59 @@
//! #
//! # fn main() {}
//! ```
//!
//! Please refer to [https://serde.rs/derive.html] for how to set this up.
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
-#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.37")]
-#![cfg_attr(feature = "cargo-clippy", allow(enum_variant_names, redundant_field_names,
- too_many_arguments, used_underscore_binding))]
+#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.58")]
+#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
+// Whitelisted clippy lints
+#![cfg_attr(
+ feature = "cargo-clippy",
+ allow(
+ enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding,
+ cyclomatic_complexity
+ )
+)]
+// Whitelisted clippy_pedantic lints
+#![cfg_attr(
+ feature = "cargo-clippy",
+ allow(
+ items_after_statements, doc_markdown, stutter, similar_names, use_self, single_match_else,
+ enum_glob_use, match_same_arms, filter_map, cast_possible_truncation
+ )
+)]
// The `quote!` macro requires deep recursion.
#![recursion_limit = "512"]
#[macro_use]
extern crate quote;
#[macro_use]
extern crate syn;
-extern crate serde_derive_internals as internals;
-
extern crate proc_macro;
extern crate proc_macro2;
+mod internals;
+
use proc_macro::TokenStream;
use syn::DeriveInput;
-// Quote's default is def_site but it appears call_site is likely to stabilize
-// before def_site. Thus we try to use only call_site.
-macro_rules! quote {
- ($($tt:tt)*) => {
- quote_spanned!($crate::proc_macro2::Span::call_site()=> $($tt)*)
- }
-}
-
#[macro_use]
mod bound;
#[macro_use]
mod fragment;
+mod de;
+mod pretend;
mod ser;
-mod de;
+mod try;
#[proc_macro_derive(Serialize, attributes(serde))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
let input: DeriveInput = syn::parse(input).unwrap();
match ser::expand_derive_serialize(&input) {
Ok(expanded) => expanded.into(),
Err(msg) => panic!(msg),
}
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde_derive/src/pretend.rs
@@ -0,0 +1,141 @@
+use proc_macro2::Span;
+use quote::Tokens;
+use syn::Ident;
+
+use internals::ast::{Container, Data, Field, Style};
+
+// Suppress dead_code warnings that would otherwise appear when using a remote
+// derive. Other than this pretend code, a struct annotated with remote derive
+// never has its fields referenced and an enum annotated with remote derive
+// never has its variants constructed.
+//
+// warning: field is never used: `i`
+// --> src/main.rs:4:20
+// |
+// 4 | struct StructDef { i: i32 }
+// | ^^^^^^
+//
+// warning: variant is never constructed: `V`
+// --> src/main.rs:8:16
+// |
+// 8 | enum EnumDef { V }
+// | ^
+//
+pub fn pretend_used(cont: &Container) -> Tokens {
+ let pretend_fields = pretend_fields_used(cont);
+ let pretend_variants = pretend_variants_used(cont);
+
+ quote! {
+ #pretend_fields
+ #pretend_variants
+ }
+}
+
+// For structs with named fields, expands to:
+//
+// match None::<T> {
+// Some(T { a: ref __v0, b: ref __v1 }) => {}
+// _ => {}
+// }
+//
+// For enums, expands to the following but only including struct variants:
+//
+// match None::<T> {
+// Some(T::A { a: ref __v0 }) => {}
+// Some(T::B { b: ref __v0 }) => {}
+// _ => {}
+// }
+//
+// The `ref` is important in case the user has written a Drop impl on their
+// type. Rust does not allow destructuring a struct or enum that has a Drop
+// impl.
+fn pretend_fields_used(cont: &Container) -> Tokens {
+ let type_ident = cont.ident;
+ let (_, ty_generics, _) = cont.generics.split_for_impl();
+
+ let patterns = match cont.data {
+ Data::Enum(_, ref variants) => variants
+ .iter()
+ .filter_map(|variant| match variant.style {
+ Style::Struct => {
+ let variant_ident = variant.ident;
+ let pat = struct_pattern(&variant.fields);
+ Some(quote!(#type_ident::#variant_ident #pat))
+ }
+ _ => None,
+ })
+ .collect::<Vec<_>>(),
+ Data::Struct(Style::Struct, ref fields) => {
+ let pat = struct_pattern(fields);
+ vec![quote!(#type_ident #pat)]
+ }
+ Data::Struct(_, _) => {
+ return quote!();
+ }
+ };
+
+ quote! {
+ match _serde::export::None::<#type_ident #ty_generics> {
+ #(
+ _serde::export::Some(#patterns) => {}
+ )*
+ _ => {}
+ }
+ }
+}
+
+// Expands to one of these per enum variant:
+//
+// match None {
+// Some((__v0, __v1,)) => {
+// let _ = E::V { a: __v0, b: __v1 };
+// }
+// _ => {}
+// }
+//
+fn pretend_variants_used(cont: &Container) -> Tokens {
+ let variants = match cont.data {
+ Data::Enum(_, ref variants) => variants,
+ Data::Struct(_, _) => {
+ return quote!();
+ }
+ };
+
+ let type_ident = cont.ident;
+ let (_, ty_generics, _) = cont.generics.split_for_impl();
+ let turbofish = ty_generics.as_turbofish();
+
+ let cases = variants.iter().map(|variant| {
+ let variant_ident = variant.ident;
+ let placeholders = &(0..variant.fields.len())
+ .map(|i| Ident::new(&format!("__v{}", i), Span::call_site()))
+ .collect::<Vec<_>>();
+
+ let pat = match variant.style {
+ Style::Struct => {
+ let names = variant.fields.iter().map(|field| field.ident);
+ quote!({ #(#names: #placeholders),* })
+ }
+ Style::Tuple | Style::Newtype => quote!(( #(#placeholders),* )),
+ Style::Unit => quote!(),
+ };
+
+ quote! {
+ match _serde::export::None {
+ _serde::export::Some((#(#placeholders,)*)) => {
+ let _ = #type_ident::#variant_ident #turbofish #pat;
+ }
+ _ => {}
+ }
+ }
+ });
+
+ quote!(#(#cases)*)
+}
+
+fn struct_pattern(fields: &[Field]) -> Tokens {
+ let names = fields.iter().map(|field| field.ident);
+ let placeholders =
+ (0..fields.len()).map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
+ quote!({ #(#names: ref #placeholders),* })
+}
--- a/third_party/rust/serde_derive/src/ser.rs
+++ b/third_party/rust/serde_derive/src/ser.rs
@@ -1,69 +1,74 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
-use syn::{self, Ident, Index, Member};
+use proc_macro2::Span;
+use quote::Tokens;
use syn::spanned::Spanned;
-use quote::Tokens;
-use proc_macro2::Span;
+use syn::{self, Ident, Index, Member};
use bound;
use fragment::{Fragment, Match, Stmts};
-use internals::ast::{Data, Container, Field, Style, Variant};
+use internals::ast::{Container, Data, Field, Style, Variant};
use internals::{attr, Ctxt};
-
-use std::u32;
+use pretend;
+use try;
pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, String> {
let ctxt = Ctxt::new();
let cont = Container::from_ast(&ctxt, input);
precondition(&ctxt, &cont);
try!(ctxt.check());
- let ident = &cont.ident;
+ let ident = cont.ident;
let params = Parameters::new(&cont);
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
let dummy_const = Ident::new(&format!("_IMPL_SERIALIZE_FOR_{}", ident), Span::call_site());
let body = Stmts(serialize_body(&cont, ¶ms));
let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis;
- let fun = quote_spanned!(Span::call_site()=> serialize);
+ let used = pretend::pretend_used(&cont);
quote! {
impl #impl_generics #ident #ty_generics #where_clause {
- #vis fn #fun<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
- where __S: _serde::Serializer
+ #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
+ where
+ __S: _serde::Serializer,
{
+ #used
#body
}
}
}
} else {
quote! {
#[automatically_derived]
impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
- where __S: _serde::Serializer
+ where
+ __S: _serde::Serializer,
{
#body
}
}
}
};
+ let try_replacement = try::replacement();
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
extern crate serde as _serde;
+ #try_replacement
#impl_block
};
};
Ok(generated)
}
fn precondition(cx: &Ctxt, cont: &Container) {
match cont.attrs.identifier() {
@@ -128,35 +133,41 @@ impl Parameters {
// All the generics in the input, plus a bound `T: Serialize` for each generic
// field type that will be serialized by us.
fn build_generics(cont: &Container) -> syn::Generics {
let generics = bound::without_defaults(cont.generics);
let generics =
bound::with_where_predicates_from_fields(cont, &generics, attr::Field::ser_bound);
+ let generics =
+ bound::with_where_predicates_from_variants(cont, &generics, attr::Variant::ser_bound);
+
match cont.attrs.ser_bound() {
Some(predicates) => bound::with_where_predicates(&generics, predicates),
None => bound::with_bound(
cont,
&generics,
needs_serialize_bound,
&parse_quote!(_serde::Serialize),
),
}
}
// Fields with a `skip_serializing` or `serialize_with` attribute, or which
-// belong to a variant with a `serialize_with` attribute, are not serialized by
-// us so we do not generate a bound. Fields with a `bound` attribute specify
-// their own bound so we do not generate one. All other fields may need a `T:
-// Serialize` bound where T is the type of the field.
+// belong to a variant with a 'skip_serializing` or `serialize_with` attribute,
+// are not serialized by us so we do not generate a bound. Fields with a `bound`
+// attribute specify their own bound so we do not generate one. All other fields
+// may need a `T: Serialize` bound where T is the type of the field.
fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
!field.skip_serializing() && field.serialize_with().is_none() && field.ser_bound().is_none()
- && variant.map_or(true, |variant| variant.serialize_with().is_none())
+ && variant.map_or(true, |variant| {
+ !variant.skip_serializing() && variant.serialize_with().is_none()
+ && variant.ser_bound().is_none()
+ })
}
fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
if let Some(type_into) = cont.attrs.type_into() {
serialize_into(params, type_into)
} else {
match cont.data {
Data::Enum(_, ref variants) => serialize_enum(params, variants, &cont.attrs),
@@ -176,17 +187,17 @@ fn serialize_body(cont: &Container, para
serialize_newtype_struct(params, &fields[0], &cont.attrs)
}
Data::Struct(Style::Unit, _) => serialize_unit_struct(&cont.attrs),
}
}
}
fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
- let self_var = ¶ms.self_var;
+ let self_var = params.self_var;
quote_block! {
_serde::Serialize::serialize(
&_serde::export::Into::<#type_into>::into(_serde::export::Clone::clone(#self_var)),
__serializer)
}
}
fn serialize_unit_struct(cattrs: &attr::Container) -> Fragment {
@@ -199,71 +210,91 @@ fn serialize_unit_struct(cattrs: &attr::
fn serialize_newtype_struct(
params: &Parameters,
field: &Field,
cattrs: &attr::Container,
) -> Fragment {
let type_name = cattrs.name().serialize_name();
- let mut field_expr = get_member(params, field, &Member::Unnamed(Index {
- index: 0,
- span: Span::call_site(),
- }));
+ let mut field_expr = get_member(
+ params,
+ field,
+ &Member::Unnamed(Index {
+ index: 0,
+ span: Span::call_site(),
+ }),
+ );
if let Some(path) = field.attrs.serialize_with() {
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
}
let span = field.original.span();
let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_struct);
quote_expr! {
#func(__serializer, #type_name, #field_expr)
}
}
fn serialize_tuple_struct(
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
) -> Fragment {
- let serialize_stmts = serialize_tuple_struct_visitor(
- fields,
- params,
- false,
- &TupleTrait::SerializeTupleStruct,
- );
+ let serialize_stmts =
+ serialize_tuple_struct_visitor(fields, params, false, &TupleTrait::SerializeTupleStruct);
let type_name = cattrs.name().serialize_name();
- let len = serialize_stmts.len();
- let let_mut = mut_if(len > 0);
+
+ let mut serialized_fields = fields
+ .iter()
+ .enumerate()
+ .filter(|&(_, ref field)| !field.attrs.skip_serializing())
+ .peekable();
+
+ let let_mut = mut_if(serialized_fields.peek().is_some());
+
+ let len = serialized_fields
+ .map(|(i, field)| match field.attrs.skip_serializing_if() {
+ None => quote!(1),
+ Some(path) => {
+ let index = syn::Index {
+ index: i as u32,
+ span: Span::call_site(),
+ };
+ let field_expr = get_member(params, field, &Member::Unnamed(index));
+ quote!(if #path(#field_expr) { 0 } else { 1 })
+ }
+ })
+ .fold(quote!(0), |sum, expr| quote!(#sum + #expr));
quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len));
#(#serialize_stmts)*
_serde::ser::SerializeTupleStruct::end(__serde_state)
}
}
fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
- assert!(fields.len() as u64 <= u64::from(u32::MAX));
+ assert!(fields.len() as u64 <= u64::from(u32::max_value()));
if cattrs.has_flatten() {
serialize_struct_as_map(params, fields, cattrs)
} else {
serialize_struct_as_struct(params, fields, cattrs)
}
}
-fn serialize_struct_as_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
- let serialize_fields = serialize_struct_visitor(
- fields,
- params,
- false,
- &StructTrait::SerializeStruct,
- );
+fn serialize_struct_as_struct(
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+) -> Fragment {
+ let serialize_fields =
+ serialize_struct_visitor(fields, params, false, &StructTrait::SerializeStruct);
let type_name = cattrs.name().serialize_name();
let mut serialized_fields = fields
.iter()
.filter(|&field| !field.attrs.skip_serializing())
.peekable();
@@ -282,23 +313,23 @@ fn serialize_struct_as_struct(params: &P
quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len));
#(#serialize_fields)*
_serde::ser::SerializeStruct::end(__serde_state)
}
}
-fn serialize_struct_as_map(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
- let serialize_fields = serialize_struct_visitor(
- fields,
- params,
- false,
- &StructTrait::SerializeMap,
- );
+fn serialize_struct_as_map(
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+) -> Fragment {
+ let serialize_fields =
+ serialize_struct_visitor(fields, params, false, &StructTrait::SerializeMap);
let mut serialized_fields = fields
.iter()
.filter(|&field| !field.attrs.skip_serializing())
.peekable();
let let_mut = mut_if(serialized_fields.peek().is_some());
@@ -321,19 +352,19 @@ fn serialize_struct_as_map(params: &Para
quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(__serializer, #len));
#(#serialize_fields)*
_serde::ser::SerializeMap::end(__serde_state)
}
}
fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Container) -> Fragment {
- assert!(variants.len() as u64 <= u64::from(u32::MAX));
+ assert!(variants.len() as u64 <= u64::from(u32::max_value()));
- let self_var = ¶ms.self_var;
+ let self_var = params.self_var;
let arms: Vec<_> = variants
.iter()
.enumerate()
.map(|(variant_index, variant)| {
serialize_variant(params, variant, variant_index as u32, cattrs)
})
.collect();
@@ -380,18 +411,18 @@ fn serialize_variant(
}
}
Style::Newtype => {
quote! {
#this::#variant_ident(ref __field0)
}
}
Style::Tuple => {
- let field_names =
- (0..variant.fields.len()).map(|i| Ident::new(&format!("__field{}", i), Span::call_site()));
+ let field_names = (0..variant.fields.len())
+ .map(|i| Ident::new(&format!("__field{}", i), Span::call_site()));
quote! {
#this::#variant_ident(#(ref #field_names),*)
}
}
Style::Struct => {
let fields = variant
.fields
.iter()
@@ -589,19 +620,25 @@ fn serialize_adjacently_tagged_variant(
}
Style::Newtype => {
let field = &variant.fields[0];
let mut field_expr = quote!(__field0);
if let Some(path) = field.attrs.serialize_with() {
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
}
- quote_expr! {
- _serde::Serialize::serialize(#field_expr, __serializer)
- }
+ return quote_block! {
+ let mut __struct = try!(_serde::Serializer::serialize_struct(
+ __serializer, #type_name, 2));
+ try!(_serde::ser::SerializeStruct::serialize_field(
+ &mut __struct, #tag, #variant_name));
+ try!(_serde::ser::SerializeStruct::serialize_field(
+ &mut __struct, #content, #field_expr));
+ _serde::ser::SerializeStruct::end(__struct)
+ };
}
Style::Tuple => {
serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
}
Style::Struct => serialize_struct_variant(
StructVariant::Untagged,
params,
&variant.fields,
@@ -627,32 +664,33 @@ fn serialize_adjacently_tagged_variant(
.fields
.iter()
.map(|f| f.ident.expect("struct variant has unnamed fields"))
.collect(),
};
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
- let wrapper_generics = if let Style::Unit = variant.style {
+ let wrapper_generics = if fields_ident.is_empty() {
params.generics.clone()
} else {
bound::with_lifetime_bound(¶ms.generics, "'__a")
};
let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
quote_block! {
struct __AdjacentlyTagged #wrapper_generics #where_clause {
data: (#(&'__a #fields_ty,)*),
phantom: _serde::export::PhantomData<#this #ty_generics>,
}
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
- where __S: _serde::Serializer
+ where
+ __S: _serde::Serializer,
{
let (#(#fields_ident,)*) = self.data;
#inner
}
}
let mut __struct = try!(_serde::Serializer::serialize_struct(
__serializer, #type_name, 2));
@@ -720,18 +758,33 @@ fn serialize_tuple_variant(
) -> Fragment {
let tuple_trait = match context {
TupleVariant::ExternallyTagged { .. } => TupleTrait::SerializeTupleVariant,
TupleVariant::Untagged => TupleTrait::SerializeTuple,
};
let serialize_stmts = serialize_tuple_struct_visitor(fields, params, true, &tuple_trait);
- let len = serialize_stmts.len();
- let let_mut = mut_if(len > 0);
+ let mut serialized_fields = fields
+ .iter()
+ .enumerate()
+ .filter(|&(_, ref field)| !field.attrs.skip_serializing())
+ .peekable();
+
+ let let_mut = mut_if(serialized_fields.peek().is_some());
+
+ let len = serialized_fields
+ .map(|(i, field)| match field.attrs.skip_serializing_if() {
+ None => quote!(1),
+ Some(path) => {
+ let field_expr = Ident::new(&format!("__field{}", i), Span::call_site());
+ quote!(if #path(#field_expr) { 0 } else { 1 })
+ }
+ })
+ .fold(quote!(0), |sum, expr| quote!(#sum + #expr));
match context {
TupleVariant::ExternallyTagged {
type_name,
variant_index,
variant_name,
} => {
quote_block! {
@@ -770,23 +823,25 @@ enum StructVariant<'a> {
}
fn serialize_struct_variant<'a>(
context: StructVariant<'a>,
params: &Parameters,
fields: &[Field],
name: &str,
) -> Fragment {
+ if fields.iter().any(|field| field.attrs.flatten()) {
+ return serialize_struct_variant_with_flatten(context, params, fields, name);
+ }
+
let struct_trait = match context {
- StructVariant::ExternallyTagged { .. } => (
- StructTrait::SerializeStructVariant
- ),
- StructVariant::InternallyTagged { .. } | StructVariant::Untagged => (
- StructTrait::SerializeStruct
- ),
+ StructVariant::ExternallyTagged { .. } => (StructTrait::SerializeStructVariant),
+ StructVariant::InternallyTagged { .. } | StructVariant::Untagged => {
+ (StructTrait::SerializeStruct)
+ }
};
let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);
let mut serialized_fields = fields
.iter()
.filter(|&field| !field.attrs.skip_serializing())
.peekable();
@@ -846,34 +901,125 @@ fn serialize_struct_variant<'a>(
));
#(#serialize_fields)*
_serde::ser::SerializeStruct::end(__serde_state)
}
}
}
}
+fn serialize_struct_variant_with_flatten<'a>(
+ context: StructVariant<'a>,
+ params: &Parameters,
+ fields: &[Field],
+ name: &str,
+) -> Fragment {
+ let struct_trait = StructTrait::SerializeMap;
+ let serialize_fields = serialize_struct_visitor(fields, params, true, &struct_trait);
+
+ let mut serialized_fields = fields
+ .iter()
+ .filter(|&field| !field.attrs.skip_serializing())
+ .peekable();
+
+ let let_mut = mut_if(serialized_fields.peek().is_some());
+
+ match context {
+ StructVariant::ExternallyTagged {
+ variant_index,
+ variant_name,
+ } => {
+ let this = ¶ms.this;
+ let fields_ty = fields.iter().map(|f| &f.ty);
+ let fields_ident = &fields.iter().map(|f| f.ident).collect::<Vec<_>>();
+
+ let (_, ty_generics, where_clause) = params.generics.split_for_impl();
+ let wrapper_generics = bound::with_lifetime_bound(¶ms.generics, "'__a");
+ let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
+
+ quote_block! {
+ struct __EnumFlatten #wrapper_generics #where_clause {
+ data: (#(&'__a #fields_ty,)*),
+ phantom: _serde::export::PhantomData<#this #ty_generics>,
+ }
+
+ impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
+ fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
+ where
+ __S: _serde::Serializer,
+ {
+ let (#(#fields_ident,)*) = self.data;
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
+ __serializer,
+ _serde::export::None));
+ #(#serialize_fields)*
+ _serde::ser::SerializeMap::end(__serde_state)
+ }
+ }
+
+ _serde::Serializer::serialize_newtype_variant(
+ __serializer,
+ #name,
+ #variant_index,
+ #variant_name,
+ &__EnumFlatten {
+ data: (#(#fields_ident,)*),
+ phantom: _serde::export::PhantomData::<#this #ty_generics>,
+ })
+ }
+ }
+ StructVariant::InternallyTagged { tag, variant_name } => {
+ quote_block! {
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
+ __serializer,
+ _serde::export::None));
+ try!(_serde::ser::SerializeMap::serialize_entry(
+ &mut __serde_state,
+ #tag,
+ #variant_name,
+ ));
+ #(#serialize_fields)*
+ _serde::ser::SerializeMap::end(__serde_state)
+ }
+ }
+ StructVariant::Untagged => {
+ quote_block! {
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
+ __serializer,
+ _serde::export::None));
+ #(#serialize_fields)*
+ _serde::ser::SerializeMap::end(__serde_state)
+ }
+ }
+ }
+}
+
fn serialize_tuple_struct_visitor(
fields: &[Field],
params: &Parameters,
is_enum: bool,
tuple_trait: &TupleTrait,
) -> Vec<Tokens> {
fields
.iter()
.enumerate()
+ .filter(|&(_, ref field)| !field.attrs.skip_serializing())
.map(|(i, field)| {
let mut field_expr = if is_enum {
let id = Ident::new(&format!("__field{}", i), Span::call_site());
quote!(#id)
} else {
- get_member(params, field, &Member::Unnamed(Index {
- index: i as u32,
- span: Span::call_site(),
- }))
+ get_member(
+ params,
+ field,
+ &Member::Unnamed(Index {
+ index: i as u32,
+ span: Span::call_site(),
+ }),
+ )
};
let skip = field
.attrs
.skip_serializing_if()
.map(|path| quote!(#path(#field_expr)));
if let Some(path) = field.attrs.serialize_with() {
@@ -1004,30 +1150,33 @@ fn wrap_serialize_with(
let wrapper_generics = if field_exprs.is_empty() {
params.generics.clone()
} else {
bound::with_lifetime_bound(¶ms.generics, "'__a")
};
let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
- let field_access = (0..field_exprs.len()).map(|n| Member::Unnamed(Index {
- index: n as u32,
- span: Span::call_site(),
- }));
+ let field_access = (0..field_exprs.len()).map(|n| {
+ Member::Unnamed(Index {
+ index: n as u32,
+ span: Span::call_site(),
+ })
+ });
quote!({
struct __SerializeWith #wrapper_impl_generics #where_clause {
values: (#(&'__a #field_tys, )*),
phantom: _serde::export::PhantomData<#this #ty_generics>,
}
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error>
- where __S: _serde::Serializer
+ where
+ __S: _serde::Serializer,
{
#serialize_with(#(self.values.#field_access, )* __s)
}
}
&__SerializeWith {
values: (#(#field_exprs, )*),
phantom: _serde::export::PhantomData::<#this #ty_generics>,
@@ -1045,23 +1194,21 @@ fn mut_if(is_mut: bool) -> Option<Tokens
if is_mut {
Some(quote!(mut))
} else {
None
}
}
fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens {
- let self_var = ¶ms.self_var;
+ let self_var = params.self_var;
match (params.is_remote, field.attrs.getter()) {
- (false, None) => {
- quote_spanned!(Span::call_site()=> &#self_var.#member)
- }
+ (false, None) => quote!(&#self_var.#member),
(true, None) => {
- let inner = quote_spanned!(Span::call_site()=> &#self_var.#member);
+ let inner = quote!(&#self_var.#member);
let ty = field.ty;
quote!(_serde::private::ser::constrain::<#ty>(#inner))
}
(true, Some(getter)) => {
let ty = field.ty;
quote!(_serde::private::ser::constrain::<#ty>(&#getter(#self_var)))
}
(false, Some(_)) => {
@@ -1089,22 +1236,22 @@ impl StructTrait {
quote_spanned!(span=> _serde::ser::SerializeStructVariant::serialize_field)
}
}
}
fn skip_field(&self, span: Span) -> Option<Tokens> {
match *self {
StructTrait::SerializeMap => None,
- StructTrait::SerializeStruct => Some({
- quote_spanned!(span=> _serde::ser::SerializeStruct::skip_field)
- }),
- StructTrait::SerializeStructVariant => Some({
- quote_spanned!(span=> _serde::ser::SerializeStructVariant::skip_field)
- })
+ StructTrait::SerializeStruct => {
+ Some(quote_spanned!(span=> _serde::ser::SerializeStruct::skip_field))
+ }
+ StructTrait::SerializeStructVariant => {
+ Some(quote_spanned!(span=> _serde::ser::SerializeStructVariant::skip_field))
+ }
}
}
}
enum TupleTrait {
SerializeTuple,
SerializeTupleStruct,
SerializeTupleVariant,
new file mode 100644
--- /dev/null
+++ b/third_party/rust/serde_derive/src/try.rs
@@ -0,0 +1,25 @@
+use proc_macro2::{Op, Spacing};
+use quote::Tokens;
+
+// None of our generated code requires the `From::from` error conversion
+// performed by the standard library's `try!` macro. With this simplified macro
+// we see a significant improvement in type checking and borrow checking time of
+// the generated code and a slight improvement in binary size.
+pub fn replacement() -> Tokens {
+ // Cannot pass `$expr` to `quote!` prior to Rust 1.17.0 so interpolate it.
+ let dollar = Op::new('$', Spacing::Alone);
+
+ quote! {
+ #[allow(unused_macros)]
+ macro_rules! try {
+ (#dollar __expr:expr) => {
+ match #dollar __expr {
+ _serde::export::Ok(__val) => __val,
+ _serde::export::Err(__err) => {
+ return _serde::export::Err(__err);
+ }
+ }
+ }
+ }
+ }
+}
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{"Cargo.toml":"b6181854cc079edf36f860a097eeb30d5c11ebeb2ff50b0fc66b31dc9759f591","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"16de77b2d10fac8c70219ba183ad083ae12d4553c6f3213dec39d9936622b371","src/ast.rs":"797fa3bf82c221c2ba945d090a0f82fe0aec18f93dc63e7aec6dadf53349d184","src/attr.rs":"37ddb86938cafd37b6a8a0bdea1c4da41ae2b2d545913af1202854af1381092d","src/case.rs":"03a97fc3996614153cc5bbd33b5df9d55954407c4d37c5a656f70cbc76817708","src/check.rs":"9aa9943532a13fb54a18a45dc7dfd353c19e1a0b7b5b7efc419ebe5f4b2b4e91","src/ctxt.rs":"30b38bc10c9d90ec1186ad4ab2159339d65bfaa5a1a51b5900b0ca52fbe526d1","src/lib.rs":"65fee3b69b94e4b810dfe1ae970889bbd948725c4f6b9e0568b30e69f0fcaae4"},"package":null}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/Cargo.toml
+++ /dev/null
@@ -1,19 +0,0 @@
-[package]
-name = "serde_derive_internals"
-version = "0.23.0" # remember to update html_root_url
-authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
-license = "MIT/Apache-2.0"
-description = "AST representation used by Serde derive macros. Unstable."
-homepage = "https://serde.rs"
-repository = "https://github.com/serde-rs/serde"
-documentation = "https://docs.serde.rs/serde_derive_internals/"
-keywords = ["serde", "serialization"]
-readme = "README.md"
-include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
-
-[dependencies]
-proc-macro2 = "0.3"
-syn = { version = "0.13", default-features = false, features = ["derive", "parsing", "clone-impls", "extra-traits"] }
-
-[badges]
-travis-ci = { repository = "serde-rs/serde" }
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
-TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
-1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
-2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
-3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
-4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
-5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
-6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
-7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
-8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
-9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
-END OF TERMS AND CONDITIONS
-
-APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
-Copyright [yyyy] [name of copyright owner]
-
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2014 The Rust Project Developers
-
-Permission is hereby granted, free of charge, to any
-person obtaining a copy of this software and associated
-documentation files (the "Software"), to deal in the
-Software without restriction, including without
-limitation the rights to use, copy, modify, merge,
-publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software
-is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice
-shall be included in all copies or substantial portions
-of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
-ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
-TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
-PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
-SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
-CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
-IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
-DEALINGS IN THE SOFTWARE.
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/README.md
+++ /dev/null
@@ -1,104 +0,0 @@
-# Serde   [![Build Status]][travis] [![Latest Version]][crates.io] [![Rustc Version 1.13+]][rustc]
-
-[Build Status]: https://api.travis-ci.org/serde-rs/serde.svg?branch=master
-[travis]: https://travis-ci.org/serde-rs/serde
-[Latest Version]: https://img.shields.io/crates/v/serde.svg
-[crates.io]: https://crates.io/crates/serde
-[Rustc Version 1.13+]: https://img.shields.io/badge/rustc-1.13+-lightgray.svg
-[rustc]: https://blog.rust-lang.org/2016/11/10/Rust-1.13.html
-
-**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
-
----
-
-You may be looking for:
-
-- [An overview of Serde](https://serde.rs/)
-- [Data formats supported by Serde](https://serde.rs/#data-formats)
-- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
-- [Examples](https://serde.rs/examples.html)
-- [API documentation](https://docs.serde.rs/serde/)
-- [Release notes](https://github.com/serde-rs/serde/releases)
-
-## Serde in action
-
-<details>
-<summary>
-Click to show Cargo.toml.
-<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
-</summary>
-
-```toml
-[dependencies]
-
-# The core APIs, including the Serialize and Deserialize traits. Always
-# required when using Serde.
-serde = "1.0"
-
-# Support for #[derive(Serialize, Deserialize)]. Required if you want Serde
-# to work for structs and enums defined in your crate.
-serde_derive = "1.0"
-
-# Each data format lives in its own crate; the sample code below uses JSON
-# but you may be using a different one.
-serde_json = "1.0"
-```
-
-</details>
-<p></p>
-
-```rust
-#[macro_use]
-extern crate serde_derive;
-
-extern crate serde;
-extern crate serde_json;
-
-#[derive(Serialize, Deserialize, Debug)]
-struct Point {
- x: i32,
- y: i32,
-}
-
-fn main() {
- let point = Point { x: 1, y: 2 };
-
- // Convert the Point to a JSON string.
- let serialized = serde_json::to_string(&point).unwrap();
-
- // Prints serialized = {"x":1,"y":2}
- println!("serialized = {}", serialized);
-
- // Convert the JSON string back to a Point.
- let deserialized: Point = serde_json::from_str(&serialized).unwrap();
-
- // Prints deserialized = Point { x: 1, y: 2 }
- println!("deserialized = {:?}", deserialized);
-}
-```
-
-## Getting help
-
-Serde developers live in the #serde channel on
-[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a
-good resource with generally faster response time but less specific knowledge
-about Serde. If IRC is not your thing or you don't get a good response, we are
-happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new)
-as well.
-
-## License
-
-Serde is licensed under either of
-
- * Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or
- http://www.apache.org/licenses/LICENSE-2.0)
- * MIT license ([LICENSE-MIT](LICENSE-MIT) or
- http://opensource.org/licenses/MIT)
-
-at your option.
-
-### Contribution
-
-Unless you explicitly state otherwise, any contribution intentionally submitted
-for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be
-dual licensed as above, without any additional terms or conditions.
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/src/ast.rs
+++ /dev/null
@@ -1,246 +0,0 @@
-// Copyright 2017 Serde Developers
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use syn;
-use attr;
-use check;
-use Ctxt;
-use syn::punctuated::Punctuated;
-
-pub struct Container<'a> {
- pub ident: syn::Ident,
- pub attrs: attr::Container,
- pub data: Data<'a>,
- pub generics: &'a syn::Generics,
-}
-
-pub enum Data<'a> {
- Enum(Repr, Vec<Variant<'a>>),
- Struct(Style, Vec<Field<'a>>),
-}
-
-pub struct Variant<'a> {
- pub ident: syn::Ident,
- pub attrs: attr::Variant,
- pub style: Style,
- pub fields: Vec<Field<'a>>,
-}
-
-pub struct Field<'a> {
- pub ident: Option<syn::Ident>,
- pub attrs: attr::Field,
- pub ty: &'a syn::Type,
- pub original: &'a syn::Field,
-}
-
-pub struct Repr {
- pub int_repr: Option<&'static str>,
- pub c_repr: bool,
- pub other_repr: bool,
-}
-
-#[derive(Copy, Clone)]
-pub enum Style {
- Struct,
- Tuple,
- Newtype,
- Unit,
-}
-
-impl<'a> Container<'a> {
- pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput) -> Container<'a> {
- let mut attrs = attr::Container::from_ast(cx, item);
-
- let mut data = match item.data {
- syn::Data::Enum(ref data) => {
- let (repr, variants) = enum_from_ast(cx, item, &data.variants, attrs.default());
- Data::Enum(repr, variants)
- }
- syn::Data::Struct(ref data) => {
- let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default());
- Data::Struct(style, fields)
- }
- syn::Data::Union(_) => {
- panic!("Serde does not support derive for unions");
- }
- };
-
- let mut has_flatten = false;
- match data {
- Data::Enum(_, ref mut variants) => for variant in variants {
- variant.attrs.rename_by_rule(attrs.rename_all());
- for field in &mut variant.fields {
- if field.attrs.flatten() {
- has_flatten = true;
- }
- field.attrs.rename_by_rule(variant.attrs.rename_all());
- }
- },
- Data::Struct(_, ref mut fields) => for field in fields {
- if field.attrs.flatten() {
- has_flatten = true;
- }
- field.attrs.rename_by_rule(attrs.rename_all());
- },
- }
-
- if has_flatten {
- attrs.mark_has_flatten();
- }
-
- let item = Container {
- ident: item.ident,
- attrs: attrs,
- data: data,
- generics: &item.generics,
- };
- check::check(cx, &item);
- item
- }
-}
-
-impl<'a> Data<'a> {
- pub fn all_fields(&'a self) -> Box<Iterator<Item = &'a Field<'a>> + 'a> {
- match *self {
- Data::Enum(_, ref variants) => {
- Box::new(variants.iter().flat_map(|variant| variant.fields.iter()))
- }
- Data::Struct(_, ref fields) => Box::new(fields.iter()),
- }
- }
-
- pub fn has_getter(&self) -> bool {
- self.all_fields().any(|f| f.attrs.getter().is_some())
- }
-}
-
-impl Repr {
- /// Gives the int type to use for the `repr(int)` enum layout
- pub fn get_stable_rust_enum_layout(&self) -> Option<&'static str> {
- if self.c_repr || self.other_repr {
- None
- } else {
- self.int_repr
- }
- }
-
- /// Gives the int type to use for the `repr(C, int)` enum layout
- pub fn get_stable_c_enum_layout(&self) -> Option<&'static str> {
- if !self.c_repr && self.other_repr {
- None
- } else {
- self.int_repr
- }
- }
-}
-
-fn enum_from_ast<'a>(
- cx: &Ctxt,
- item: &'a syn::DeriveInput,
- variants: &'a Punctuated<syn::Variant, Token![,]>,
- container_default: &attr::Default
-) -> (Repr, Vec<Variant<'a>>) {
- let variants = variants
- .iter()
- .map(
- |variant| {
- let attrs = attr::Variant::from_ast(cx, variant);
- let (style, fields) =
- struct_from_ast(cx, &variant.fields, Some(&attrs), container_default);
- Variant {
- ident: variant.ident,
- attrs: attrs,
- style: style,
- fields: fields,
- }
- },
- )
- .collect();
-
- // Compute repr info for enum optimizations
- static INT_TYPES: [&'static str; 12] = [
- "u8", "u16", "u32", "u64", "u128", "usize",
- "i8", "i16", "i32", "i64", "i128", "isize",
- ];
-
- let mut int_repr = None;
- let mut c_repr = false;
- let mut other_repr = false;
-
- for attr in &item.attrs {
- if let Some(syn::Meta::List(ref list)) = attr.interpret_meta() {
- if list.ident == "repr" {
- // has_repr = true;
- for repr in &list.nested {
- if let syn::NestedMeta::Meta(syn::Meta::Word(ref repr)) = *repr {
- if repr == "C" {
- c_repr = true;
- } else if let Some(int_type) = INT_TYPES.iter().cloned().find(|int_type| repr == int_type) {
- if int_repr.is_some() {
- // This shouldn't happen, but we shouldn't crash if we see it.
- // So just treat the enum as having a mysterious other repr,
- // which makes us discard any attempt to optimize based on layout.
- other_repr = true;
- }
- int_repr = Some(int_type);
- } else {
- other_repr = true;
- }
- } else {
- panic!("impossible repr? {:?}", repr);
- }
- }
- }
- }
- }
-
- let repr = Repr { int_repr, c_repr, other_repr };
-
- (repr, variants)
-}
-
-fn struct_from_ast<'a>(
- cx: &Ctxt,
- fields: &'a syn::Fields,
- attrs: Option<&attr::Variant>,
- container_default: &attr::Default,
-) -> (Style, Vec<Field<'a>>) {
- match *fields {
- syn::Fields::Named(ref fields) => (
- Style::Struct,
- fields_from_ast(cx, &fields.named, attrs, container_default),
- ),
- syn::Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => (
- Style::Newtype,
- fields_from_ast(cx, &fields.unnamed, attrs, container_default),
- ),
- syn::Fields::Unnamed(ref fields) => (
- Style::Tuple,
- fields_from_ast(cx, &fields.unnamed, attrs, container_default),
- ),
- syn::Fields::Unit => (Style::Unit, Vec::new()),
- }
-}
-
-fn fields_from_ast<'a>(
- cx: &Ctxt,
- fields: &'a Punctuated<syn::Field, Token![,]>,
- attrs: Option<&attr::Variant>,
- container_default: &attr::Default,
-) -> Vec<Field<'a>> {
- fields
- .iter()
- .enumerate()
- .map(|(i, field)| Field {
- ident: field.ident,
- attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
- ty: &field.ty,
- original: field,
- })
- .collect()
-}
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/src/attr.rs
+++ /dev/null
@@ -1,1426 +0,0 @@
-// Copyright 2017 Serde Developers
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use Ctxt;
-use syn;
-use syn::Ident;
-use syn::Meta::{List, NameValue, Word};
-use syn::NestedMeta::{Literal, Meta};
-use syn::punctuated::Punctuated;
-use syn::synom::{Synom, ParseError};
-use std::collections::BTreeSet;
-use std::str::FromStr;
-use proc_macro2::{Span, TokenStream, TokenTree, Group};
-
-// This module handles parsing of `#[serde(...)]` attributes. The entrypoints
-// are `attr::Container::from_ast`, `attr::Variant::from_ast`, and
-// `attr::Field::from_ast`. Each returns an instance of the corresponding
-// struct. Note that none of them return a Result. Unrecognized, malformed, or
-// duplicated attributes result in a span_err but otherwise are ignored. The
-// user will see errors simultaneously for all bad attributes in the crate
-// rather than just the first.
-
-pub use case::RenameRule;
-
-#[derive(Copy, Clone)]
-struct Attr<'c, T> {
- cx: &'c Ctxt,
- name: &'static str,
- value: Option<T>,
-}
-
-impl<'c, T> Attr<'c, T> {
- fn none(cx: &'c Ctxt, name: &'static str) -> Self {
- Attr {
- cx: cx,
- name: name,
- value: None,
- }
- }
-
- fn set(&mut self, value: T) {
- if self.value.is_some() {
- self.cx
- .error(format!("duplicate serde attribute `{}`", self.name));
- } else {
- self.value = Some(value);
- }
- }
-
- fn set_opt(&mut self, value: Option<T>) {
- if let Some(value) = value {
- self.set(value);
- }
- }
-
- fn set_if_none(&mut self, value: T) {
- if self.value.is_none() {
- self.value = Some(value);
- }
- }
-
- fn get(self) -> Option<T> {
- self.value
- }
-}
-
-struct BoolAttr<'c>(Attr<'c, ()>);
-
-impl<'c> BoolAttr<'c> {
- fn none(cx: &'c Ctxt, name: &'static str) -> Self {
- BoolAttr(Attr::none(cx, name))
- }
-
- fn set_true(&mut self) {
- self.0.set(());
- }
-
- fn get(&self) -> bool {
- self.0.value.is_some()
- }
-}
-
-pub struct Name {
- serialize: String,
- deserialize: String,
-}
-
-impl Name {
- /// Return the container name for the container when serializing.
- pub fn serialize_name(&self) -> String {
- self.serialize.clone()
- }
-
- /// Return the container name for the container when deserializing.
- pub fn deserialize_name(&self) -> String {
- self.deserialize.clone()
- }
-}
-
-/// Represents container (e.g. struct) attribute information
-pub struct Container {
- name: Name,
- deny_unknown_fields: bool,
- default: Default,
- rename_all: RenameRule,
- ser_bound: Option<Vec<syn::WherePredicate>>,
- de_bound: Option<Vec<syn::WherePredicate>>,
- tag: EnumTag,
- type_from: Option<syn::Type>,
- type_into: Option<syn::Type>,
- remote: Option<syn::Path>,
- identifier: Identifier,
- has_flatten: bool,
-}
-
-/// Styles of representing an enum.
-pub enum EnumTag {
- /// The default.
- ///
- /// ```json
- /// {"variant1": {"key1": "value1", "key2": "value2"}}
- /// ```
- External,
-
- /// `#[serde(tag = "type")]`
- ///
- /// ```json
- /// {"type": "variant1", "key1": "value1", "key2": "value2"}
- /// ```
- Internal { tag: String },
-
- /// `#[serde(tag = "t", content = "c")]`
- ///
- /// ```json
- /// {"t": "variant1", "c": {"key1": "value1", "key2": "value2"}}
- /// ```
- Adjacent { tag: String, content: String },
-
- /// `#[serde(untagged)]`
- ///
- /// ```json
- /// {"key1": "value1", "key2": "value2"}
- /// ```
- None,
-}
-
-/// Whether this enum represents the fields of a struct or the variants of an
-/// enum.
-#[derive(Copy, Clone)]
-pub enum Identifier {
- /// It does not.
- No,
-
- /// This enum represents the fields of a struct. All of the variants must be
- /// unit variants, except possibly one which is annotated with
- /// `#[serde(other)]` and is a newtype variant.
- Field,
-
- /// This enum represents the variants of an enum. All of the variants must
- /// be unit variants.
- Variant,
-}
-
-impl Identifier {
- pub fn is_some(self) -> bool {
- match self {
- Identifier::No => false,
- Identifier::Field | Identifier::Variant => true,
- }
- }
-}
-
-impl Container {
- /// Extract out the `#[serde(...)]` attributes from an item.
- pub fn from_ast(cx: &Ctxt, item: &syn::DeriveInput) -> Self {
- let mut ser_name = Attr::none(cx, "rename");
- let mut de_name = Attr::none(cx, "rename");
- let mut deny_unknown_fields = BoolAttr::none(cx, "deny_unknown_fields");
- let mut default = Attr::none(cx, "default");
- let mut rename_all = Attr::none(cx, "rename_all");
- let mut ser_bound = Attr::none(cx, "bound");
- let mut de_bound = Attr::none(cx, "bound");
- let mut untagged = BoolAttr::none(cx, "untagged");
- let mut internal_tag = Attr::none(cx, "tag");
- let mut content = Attr::none(cx, "content");
- let mut type_from = Attr::none(cx, "from");
- let mut type_into = Attr::none(cx, "into");
- let mut remote = Attr::none(cx, "remote");
- let mut field_identifier = BoolAttr::none(cx, "field_identifier");
- let mut variant_identifier = BoolAttr::none(cx, "variant_identifier");
-
- for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) {
- for meta_item in meta_items {
- match meta_item {
- // Parse `#[serde(rename = "foo")]`
- Meta(NameValue(ref m)) if m.ident == "rename" => {
- if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
- ser_name.set(s.value());
- de_name.set(s.value());
- }
- }
-
- // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
- Meta(List(ref m)) if m.ident == "rename" => {
- if let Ok((ser, de)) = get_renames(cx, &m.nested) {
- ser_name.set_opt(ser.map(syn::LitStr::value));
- de_name.set_opt(de.map(syn::LitStr::value));
- }
- }
-
- // Parse `#[serde(rename_all = "foo")]`
- Meta(NameValue(ref m)) if m.ident == "rename_all" => {
- if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
- match RenameRule::from_str(&s.value()) {
- Ok(rename_rule) => rename_all.set(rename_rule),
- Err(()) => cx.error(format!(
- "unknown rename rule for #[serde(rename_all \
- = {:?})]",
- s.value()
- )),
- }
- }
- }
-
- // Parse `#[serde(deny_unknown_fields)]`
- Meta(Word(word)) if word == "deny_unknown_fields" => {
- deny_unknown_fields.set_true();
- }
-
- // Parse `#[serde(default)]`
- Meta(Word(word)) if word == "default" => match item.data {
- syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Named(_), .. }) => {
- default.set(Default::Default);
- }
- _ => cx.error(
- "#[serde(default)] can only be used on structs \
- with named fields",
- ),
- },
-
- // Parse `#[serde(default = "...")]`
- Meta(NameValue(ref m)) if m.ident == "default" => {
- if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
- match item.data {
- syn::Data::Struct(syn::DataStruct { fields: syn::Fields::Named(_), .. }) => {
- default.set(Default::Path(path));
- }
- _ => cx.error(
- "#[serde(default = \"...\")] can only be used \
- on structs with named fields",
- ),
- }
- }
- }
-
- // Parse `#[serde(bound = "D: Serialize")]`
- Meta(NameValue(ref m)) if m.ident == "bound" => {
- if let Ok(where_predicates) =
- parse_lit_into_where(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit)
- {
- ser_bound.set(where_predicates.clone());
- de_bound.set(where_predicates);
- }
- }
-
- // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
- Meta(List(ref m)) if m.ident == "bound" => {
- if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
- ser_bound.set_opt(ser);
- de_bound.set_opt(de);
- }
- }
-
- // Parse `#[serde(untagged)]`
- Meta(Word(word)) if word == "untagged" => match item.data {
- syn::Data::Enum(_) => {
- untagged.set_true();
- }
- syn::Data::Struct(_) | syn::Data::Union(_) => {
- cx.error("#[serde(untagged)] can only be used on enums")
- }
- },
-
- // Parse `#[serde(tag = "type")]`
- Meta(NameValue(ref m)) if m.ident == "tag" => {
- if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
- match item.data {
- syn::Data::Enum(_) => {
- internal_tag.set(s.value());
- }
- syn::Data::Struct(_) | syn::Data::Union(_) => {
- cx.error("#[serde(tag = \"...\")] can only be used on enums")
- }
- }
- }
- }
-
- // Parse `#[serde(content = "c")]`
- Meta(NameValue(ref m)) if m.ident == "content" => {
- if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
- match item.data {
- syn::Data::Enum(_) => {
- content.set(s.value());
- }
- syn::Data::Struct(_) | syn::Data::Union(_) => cx.error(
- "#[serde(content = \"...\")] can only be used on \
- enums",
- ),
- }
- }
- }
-
- // Parse `#[serde(from = "Type")]
- Meta(NameValue(ref m)) if m.ident == "from" => {
- if let Ok(from_ty) = parse_lit_into_ty(cx, m.ident.as_ref(), &m.lit) {
- type_from.set_opt(Some(from_ty));
- }
- }
-
- // Parse `#[serde(into = "Type")]
- Meta(NameValue(ref m)) if m.ident == "into" => {
- if let Ok(into_ty) = parse_lit_into_ty(cx, m.ident.as_ref(), &m.lit) {
- type_into.set_opt(Some(into_ty));
- }
- }
-
- // Parse `#[serde(remote = "...")]`
- Meta(NameValue(ref m)) if m.ident == "remote" => {
- if let Ok(path) = parse_lit_into_path(cx, m.ident.as_ref(), &m.lit) {
- if is_primitive_path(&path, "Self") {
- remote.set(item.ident.into());
- } else {
- remote.set(path);
- }
- }
- }
-
- // Parse `#[serde(field_identifier)]`
- Meta(Word(word)) if word == "field_identifier" => {
- field_identifier.set_true();
- }
-
- // Parse `#[serde(variant_identifier)]`
- Meta(Word(word)) if word == "variant_identifier" => {
- variant_identifier.set_true();
- }
-
- Meta(ref meta_item) => {
- cx.error(format!(
- "unknown serde container attribute `{}`",
- meta_item.name()
- ));
- }
-
- Literal(_) => {
- cx.error("unexpected literal in serde container attribute");
- }
- }
- }
- }
-
- Container {
- name: Name {
- serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()),
- deserialize: de_name.get().unwrap_or_else(|| item.ident.to_string()),
- },
- deny_unknown_fields: deny_unknown_fields.get(),
- default: default.get().unwrap_or(Default::None),
- rename_all: rename_all.get().unwrap_or(RenameRule::None),
- ser_bound: ser_bound.get(),
- de_bound: de_bound.get(),
- tag: decide_tag(cx, item, &untagged, internal_tag, content),
- type_from: type_from.get(),
- type_into: type_into.get(),
- remote: remote.get(),
- identifier: decide_identifier(cx, item, &field_identifier, &variant_identifier),
- has_flatten: false,
- }
- }
-
- pub fn name(&self) -> &Name {
- &self.name
- }
-
- pub fn rename_all(&self) -> &RenameRule {
- &self.rename_all
- }
-
- pub fn deny_unknown_fields(&self) -> bool {
- self.deny_unknown_fields
- }
-
- pub fn default(&self) -> &Default {
- &self.default
- }
-
- pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
- self.ser_bound.as_ref().map(|vec| &vec[..])
- }
-
- pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
- self.de_bound.as_ref().map(|vec| &vec[..])
- }
-
- pub fn tag(&self) -> &EnumTag {
- &self.tag
- }
-
- pub fn type_from(&self) -> Option<&syn::Type> {
- self.type_from.as_ref()
- }
-
- pub fn type_into(&self) -> Option<&syn::Type> {
- self.type_into.as_ref()
- }
-
- pub fn remote(&self) -> Option<&syn::Path> {
- self.remote.as_ref()
- }
-
- pub fn identifier(&self) -> Identifier {
- self.identifier
- }
-
- pub fn has_flatten(&self) -> bool {
- self.has_flatten
- }
-
- pub fn mark_has_flatten(&mut self) {
- self.has_flatten = true;
- }
-}
-
-fn decide_tag(
- cx: &Ctxt,
- item: &syn::DeriveInput,
- untagged: &BoolAttr,
- internal_tag: Attr<String>,
- content: Attr<String>,
-) -> EnumTag {
- match (untagged.get(), internal_tag.get(), content.get()) {
- (false, None, None) => EnumTag::External,
- (true, None, None) => EnumTag::None,
- (false, Some(tag), None) => {
- // Check that there are no tuple variants.
- if let syn::Data::Enum(ref data) = item.data {
- for variant in &data.variants {
- match variant.fields {
- syn::Fields::Named(_) | syn::Fields::Unit => {}
- syn::Fields::Unnamed(ref fields) => {
- if fields.unnamed.len() != 1 {
- cx.error(
- "#[serde(tag = \"...\")] cannot be used with tuple \
- variants",
- );
- break;
- }
- }
- }
- }
- }
- EnumTag::Internal { tag: tag }
- }
- (true, Some(_), None) => {
- cx.error("enum cannot be both untagged and internally tagged");
- EnumTag::External // doesn't matter, will error
- }
- (false, None, Some(_)) => {
- cx.error("#[serde(tag = \"...\", content = \"...\")] must be used together");
- EnumTag::External
- }
- (true, None, Some(_)) => {
- cx.error("untagged enum cannot have #[serde(content = \"...\")]");
- EnumTag::External
- }
- (false, Some(tag), Some(content)) => EnumTag::Adjacent {
- tag: tag,
- content: content,
- },
- (true, Some(_), Some(_)) => {
- cx.error("untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]");
- EnumTag::External
- }
- }
-}
-
-fn decide_identifier(
- cx: &Ctxt,
- item: &syn::DeriveInput,
- field_identifier: &BoolAttr,
- variant_identifier: &BoolAttr,
-) -> Identifier {
- match (&item.data, field_identifier.get(), variant_identifier.get()) {
- (_, false, false) => Identifier::No,
- (_, true, true) => {
- cx.error("`field_identifier` and `variant_identifier` cannot both be set");
- Identifier::No
- }
- (&syn::Data::Enum(_), true, false) => Identifier::Field,
- (&syn::Data::Enum(_), false, true) => Identifier::Variant,
- (&syn::Data::Struct(_), true, false)
- | (&syn::Data::Union(_), true, false) => {
- cx.error("`field_identifier` can only be used on an enum");
- Identifier::No
- }
- (&syn::Data::Struct(_), false, true)
- | (&syn::Data::Union(_), false, true) => {
- cx.error("`variant_identifier` can only be used on an enum");
- Identifier::No
- }
- }
-}
-
-/// Represents variant attribute information
-pub struct Variant {
- name: Name,
- ser_renamed: bool,
- de_renamed: bool,
- rename_all: RenameRule,
- skip_deserializing: bool,
- skip_serializing: bool,
- other: bool,
- serialize_with: Option<syn::ExprPath>,
- deserialize_with: Option<syn::ExprPath>,
- borrow: Option<syn::Meta>,
-}
-
-impl Variant {
- pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
- let mut ser_name = Attr::none(cx, "rename");
- let mut de_name = Attr::none(cx, "rename");
- let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
- let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
- let mut rename_all = Attr::none(cx, "rename_all");
- let mut other = BoolAttr::none(cx, "other");
- let mut serialize_with = Attr::none(cx, "serialize_with");
- let mut deserialize_with = Attr::none(cx, "deserialize_with");
- let mut borrow = Attr::none(cx, "borrow");
-
- for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
- for meta_item in meta_items {
- match meta_item {
- // Parse `#[serde(rename = "foo")]`
- Meta(NameValue(ref m)) if m.ident == "rename" => {
- if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
- ser_name.set(s.value());
- de_name.set(s.value());
- }
- }
-
- // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
- Meta(List(ref m)) if m.ident == "rename" => {
- if let Ok((ser, de)) = get_renames(cx, &m.nested) {
- ser_name.set_opt(ser.map(syn::LitStr::value));
- de_name.set_opt(de.map(syn::LitStr::value));
- }
- }
-
- // Parse `#[serde(rename_all = "foo")]`
- Meta(NameValue(ref m)) if m.ident == "rename_all" => {
- if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
- match RenameRule::from_str(&s.value()) {
- Ok(rename_rule) => rename_all.set(rename_rule),
- Err(()) => cx.error(format!(
- "unknown rename rule for #[serde(rename_all \
- = {:?})]",
- s.value()
- )),
- }
- }
- }
-
- // Parse `#[serde(skip_deserializing)]`
- Meta(Word(word)) if word == "skip_deserializing" => {
- skip_deserializing.set_true();
- }
-
- // Parse `#[serde(skip_serializing)]`
- Meta(Word(word)) if word == "skip_serializing" => {
- skip_serializing.set_true();
- }
-
- // Parse `#[serde(other)]`
- Meta(Word(word)) if word == "other" => {
- other.set_true();
- }
-
- // Parse `#[serde(with = "...")]`
- Meta(NameValue(ref m)) if m.ident == "with" => {
- if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
- let mut ser_path = path.clone();
- ser_path.path.segments.push(Ident::new("serialize", Span::call_site()).into());
- serialize_with.set(ser_path);
- let mut de_path = path;
- de_path.path.segments.push(Ident::new("deserialize", Span::call_site()).into());
- deserialize_with.set(de_path);
- }
- }
-
- // Parse `#[serde(serialize_with = "...")]`
- Meta(NameValue(ref m)) if m.ident == "serialize_with" => {
- if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
- serialize_with.set(path);
- }
- }
-
- // Parse `#[serde(deserialize_with = "...")]`
- Meta(NameValue(ref m)) if m.ident == "deserialize_with" => {
- if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
- deserialize_with.set(path);
- }
- }
-
- // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
- Meta(ref m) if m.name() == "borrow" => match variant.fields {
- syn::Fields::Unnamed(ref fields) if fields.unnamed.len() == 1 => {
- borrow.set(m.clone());
- }
- _ => {
- cx.error("#[serde(borrow)] may only be used on newtype variants");
- }
- },
-
- Meta(ref meta_item) => {
- cx.error(format!(
- "unknown serde variant attribute `{}`",
- meta_item.name()
- ));
- }
-
- Literal(_) => {
- cx.error("unexpected literal in serde variant attribute");
- }
- }
- }
- }
-
- let ser_name = ser_name.get();
- let ser_renamed = ser_name.is_some();
- let de_name = de_name.get();
- let de_renamed = de_name.is_some();
- Variant {
- name: Name {
- serialize: ser_name.unwrap_or_else(|| variant.ident.to_string()),
- deserialize: de_name.unwrap_or_else(|| variant.ident.to_string()),
- },
- ser_renamed: ser_renamed,
- de_renamed: de_renamed,
- rename_all: rename_all.get().unwrap_or(RenameRule::None),
- skip_deserializing: skip_deserializing.get(),
- skip_serializing: skip_serializing.get(),
- other: other.get(),
- serialize_with: serialize_with.get(),
- deserialize_with: deserialize_with.get(),
- borrow: borrow.get(),
- }
- }
-
- pub fn name(&self) -> &Name {
- &self.name
- }
-
- pub fn rename_by_rule(&mut self, rule: &RenameRule) {
- if !self.ser_renamed {
- self.name.serialize = rule.apply_to_variant(&self.name.serialize);
- }
- if !self.de_renamed {
- self.name.deserialize = rule.apply_to_variant(&self.name.deserialize);
- }
- }
-
- pub fn rename_all(&self) -> &RenameRule {
- &self.rename_all
- }
-
- pub fn skip_deserializing(&self) -> bool {
- self.skip_deserializing
- }
-
- pub fn skip_serializing(&self) -> bool {
- self.skip_serializing
- }
-
- pub fn other(&self) -> bool {
- self.other
- }
-
- pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
- self.serialize_with.as_ref()
- }
-
- pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
- self.deserialize_with.as_ref()
- }
-}
-
-/// Represents field attribute information
-pub struct Field {
- name: Name,
- ser_renamed: bool,
- de_renamed: bool,
- skip_serializing: bool,
- skip_deserializing: bool,
- skip_serializing_if: Option<syn::ExprPath>,
- default: Default,
- serialize_with: Option<syn::ExprPath>,
- deserialize_with: Option<syn::ExprPath>,
- ser_bound: Option<Vec<syn::WherePredicate>>,
- de_bound: Option<Vec<syn::WherePredicate>>,
- borrowed_lifetimes: BTreeSet<syn::Lifetime>,
- getter: Option<syn::ExprPath>,
- flatten: bool,
-}
-
-/// Represents the default to use for a field when deserializing.
-pub enum Default {
- /// Field must always be specified because it does not have a default.
- None,
- /// The default is given by `std::default::Default::default()`.
- Default,
- /// The default is given by this function.
- Path(syn::ExprPath),
-}
-
-impl Field {
- /// Extract out the `#[serde(...)]` attributes from a struct field.
- pub fn from_ast(
- cx: &Ctxt,
- index: usize,
- field: &syn::Field,
- attrs: Option<&Variant>,
- container_default: &Default,
- ) -> Self {
- let mut ser_name = Attr::none(cx, "rename");
- let mut de_name = Attr::none(cx, "rename");
- let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
- let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
- let mut skip_serializing_if = Attr::none(cx, "skip_serializing_if");
- let mut default = Attr::none(cx, "default");
- let mut serialize_with = Attr::none(cx, "serialize_with");
- let mut deserialize_with = Attr::none(cx, "deserialize_with");
- let mut ser_bound = Attr::none(cx, "bound");
- let mut de_bound = Attr::none(cx, "bound");
- let mut borrowed_lifetimes = Attr::none(cx, "borrow");
- let mut getter = Attr::none(cx, "getter");
- let mut flatten = BoolAttr::none(cx, "flatten");
-
- let ident = match field.ident {
- Some(ref ident) => ident.to_string(),
- None => index.to_string(),
- };
-
- let variant_borrow = attrs
- .map(|variant| &variant.borrow)
- .unwrap_or(&None)
- .as_ref()
- .map(|borrow| vec![Meta(borrow.clone())]);
-
- for meta_items in field
- .attrs
- .iter()
- .filter_map(get_serde_meta_items)
- .chain(variant_borrow)
- {
- for meta_item in meta_items {
- match meta_item {
- // Parse `#[serde(rename = "foo")]`
- Meta(NameValue(ref m)) if m.ident == "rename" => {
- if let Ok(s) = get_lit_str(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit) {
- ser_name.set(s.value());
- de_name.set(s.value());
- }
- }
-
- // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
- Meta(List(ref m)) if m.ident == "rename" => {
- if let Ok((ser, de)) = get_renames(cx, &m.nested) {
- ser_name.set_opt(ser.map(syn::LitStr::value));
- de_name.set_opt(de.map(syn::LitStr::value));
- }
- }
-
- // Parse `#[serde(default)]`
- Meta(Word(word)) if word == "default" => {
- default.set(Default::Default);
- }
-
- // Parse `#[serde(default = "...")]`
- Meta(NameValue(ref m)) if m.ident == "default" => {
- if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
- default.set(Default::Path(path));
- }
- }
-
- // Parse `#[serde(skip_serializing)]`
- Meta(Word(word)) if word == "skip_serializing" => {
- skip_serializing.set_true();
- }
-
- // Parse `#[serde(skip_deserializing)]`
- Meta(Word(word)) if word == "skip_deserializing" => {
- skip_deserializing.set_true();
- }
-
- // Parse `#[serde(skip)]`
- Meta(Word(word)) if word == "skip" => {
- skip_serializing.set_true();
- skip_deserializing.set_true();
- }
-
- // Parse `#[serde(skip_serializing_if = "...")]`
- Meta(NameValue(ref m)) if m.ident == "skip_serializing_if" => {
- if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
- skip_serializing_if.set(path);
- }
- }
-
- // Parse `#[serde(serialize_with = "...")]`
- Meta(NameValue(ref m)) if m.ident == "serialize_with" => {
- if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
- serialize_with.set(path);
- }
- }
-
- // Parse `#[serde(deserialize_with = "...")]`
- Meta(NameValue(ref m)) if m.ident == "deserialize_with" => {
- if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
- deserialize_with.set(path);
- }
- }
-
- // Parse `#[serde(with = "...")]`
- Meta(NameValue(ref m)) if m.ident == "with" => {
- if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
- let mut ser_path = path.clone();
- ser_path.path.segments.push(Ident::new("serialize", Span::call_site()).into());
- serialize_with.set(ser_path);
- let mut de_path = path;
- de_path.path.segments.push(Ident::new("deserialize", Span::call_site()).into());
- deserialize_with.set(de_path);
- }
- }
-
- // Parse `#[serde(bound = "D: Serialize")]`
- Meta(NameValue(ref m)) if m.ident == "bound" => {
- if let Ok(where_predicates) =
- parse_lit_into_where(cx, m.ident.as_ref(), m.ident.as_ref(), &m.lit)
- {
- ser_bound.set(where_predicates.clone());
- de_bound.set(where_predicates);
- }
- }
-
- // Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
- Meta(List(ref m)) if m.ident == "bound" => {
- if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
- ser_bound.set_opt(ser);
- de_bound.set_opt(de);
- }
- }
-
- // Parse `#[serde(borrow)]`
- Meta(Word(word)) if word == "borrow" => {
- if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
- borrowed_lifetimes.set(borrowable);
- }
- }
-
- // Parse `#[serde(borrow = "'a + 'b")]`
- Meta(NameValue(ref m)) if m.ident == "borrow" => {
- if let Ok(lifetimes) = parse_lit_into_lifetimes(cx, m.ident.as_ref(), &m.lit) {
- if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, &field.ty) {
- for lifetime in &lifetimes {
- if !borrowable.contains(lifetime) {
- cx.error(format!(
- "field `{}` does not have lifetime {}",
- ident, lifetime
- ));
- }
- }
- borrowed_lifetimes.set(lifetimes);
- }
- }
- }
-
- // Parse `#[serde(getter = "...")]`
- Meta(NameValue(ref m)) if m.ident == "getter" => {
- if let Ok(path) = parse_lit_into_expr_path(cx, m.ident.as_ref(), &m.lit) {
- getter.set(path);
- }
- }
-
- // Parse `#[serde(flatten)]`
- Meta(Word(word)) if word == "flatten" => {
- flatten.set_true();
- }
-
- Meta(ref meta_item) => {
- cx.error(format!(
- "unknown serde field attribute `{}`",
- meta_item.name()
- ));
- }
-
- Literal(_) => {
- cx.error("unexpected literal in serde field attribute");
- }
- }
- }
- }
-
- // Is skip_deserializing, initialize the field to Default::default() unless a different
- // default is specified by `#[serde(default = "...")]` on ourselves or our container (e.g.
- // the struct we are in).
- if let Default::None = *container_default {
- if skip_deserializing.0.value.is_some() {
- default.set_if_none(Default::Default);
- }
- }
-
- let mut borrowed_lifetimes = borrowed_lifetimes.get().unwrap_or_default();
- if !borrowed_lifetimes.is_empty() {
- // Cow<str> and Cow<[u8]> never borrow by default:
- //
- // impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
- //
- // A #[serde(borrow)] attribute enables borrowing that corresponds
- // roughly to these impls:
- //
- // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, str>
- // impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]>
- if is_cow(&field.ty, is_str) {
- let mut path = syn::Path {
- leading_colon: None,
- segments: Punctuated::new(),
- };
- path.segments.push(Ident::new("_serde", Span::call_site()).into());
- path.segments.push(Ident::new("private", Span::call_site()).into());
- path.segments.push(Ident::new("de", Span::call_site()).into());
- path.segments.push(Ident::new("borrow_cow_str", Span::call_site()).into());
- let expr = syn::ExprPath {
- attrs: Vec::new(),
- qself: None,
- path: path,
- };
- deserialize_with.set_if_none(expr);
- } else if is_cow(&field.ty, is_slice_u8) {
- let mut path = syn::Path {
- leading_colon: None,
- segments: Punctuated::new(),
- };
- path.segments.push(Ident::new("_serde", Span::call_site()).into());
- path.segments.push(Ident::new("private", Span::call_site()).into());
- path.segments.push(Ident::new("de", Span::call_site()).into());
- path.segments.push(Ident::new("borrow_cow_bytes", Span::call_site()).into());
- let expr = syn::ExprPath {
- attrs: Vec::new(),
- qself: None,
- path: path,
- };
- deserialize_with.set_if_none(expr);
- }
- } else if is_rptr(&field.ty, is_str) || is_rptr(&field.ty, is_slice_u8) {
- // Types &str and &[u8] are always implicitly borrowed. No need for
- // a #[serde(borrow)].
- collect_lifetimes(&field.ty, &mut borrowed_lifetimes);
- }
-
- let ser_name = ser_name.get();
- let ser_renamed = ser_name.is_some();
- let de_name = de_name.get();
- let de_renamed = de_name.is_some();
- Field {
- name: Name {
- serialize: ser_name.unwrap_or_else(|| ident.clone()),
- deserialize: de_name.unwrap_or(ident),
- },
- ser_renamed: ser_renamed,
- de_renamed: de_renamed,
- skip_serializing: skip_serializing.get(),
- skip_deserializing: skip_deserializing.get(),
- skip_serializing_if: skip_serializing_if.get(),
- default: default.get().unwrap_or(Default::None),
- serialize_with: serialize_with.get(),
- deserialize_with: deserialize_with.get(),
- ser_bound: ser_bound.get(),
- de_bound: de_bound.get(),
- borrowed_lifetimes: borrowed_lifetimes,
- getter: getter.get(),
- flatten: flatten.get(),
- }
- }
-
- pub fn name(&self) -> &Name {
- &self.name
- }
-
- pub fn rename_by_rule(&mut self, rule: &RenameRule) {
- if !self.ser_renamed {
- self.name.serialize = rule.apply_to_field(&self.name.serialize);
- }
- if !self.de_renamed {
- self.name.deserialize = rule.apply_to_field(&self.name.deserialize);
- }
- }
-
- pub fn skip_serializing(&self) -> bool {
- self.skip_serializing
- }
-
- pub fn skip_deserializing(&self) -> bool {
- self.skip_deserializing
- }
-
- pub fn skip_serializing_if(&self) -> Option<&syn::ExprPath> {
- self.skip_serializing_if.as_ref()
- }
-
- pub fn default(&self) -> &Default {
- &self.default
- }
-
- pub fn serialize_with(&self) -> Option<&syn::ExprPath> {
- self.serialize_with.as_ref()
- }
-
- pub fn deserialize_with(&self) -> Option<&syn::ExprPath> {
- self.deserialize_with.as_ref()
- }
-
- pub fn ser_bound(&self) -> Option<&[syn::WherePredicate]> {
- self.ser_bound.as_ref().map(|vec| &vec[..])
- }
-
- pub fn de_bound(&self) -> Option<&[syn::WherePredicate]> {
- self.de_bound.as_ref().map(|vec| &vec[..])
- }
-
- pub fn borrowed_lifetimes(&self) -> &BTreeSet<syn::Lifetime> {
- &self.borrowed_lifetimes
- }
-
- pub fn getter(&self) -> Option<&syn::ExprPath> {
- self.getter.as_ref()
- }
-
- pub fn flatten(&self) -> bool {
- self.flatten
- }
-}
-
-type SerAndDe<T> = (Option<T>, Option<T>);
-
-fn get_ser_and_de<'a, T, F>(
- cx: &Ctxt,
- attr_name: &'static str,
- metas: &'a Punctuated<syn::NestedMeta, Token![,]>,
- f: F,
-) -> Result<SerAndDe<T>, ()>
-where
- T: 'a,
- F: Fn(&Ctxt, &str, &str, &'a syn::Lit) -> Result<T, ()>,
-{
- let mut ser_meta = Attr::none(cx, attr_name);
- let mut de_meta = Attr::none(cx, attr_name);
-
- for meta in metas {
- match *meta {
- Meta(NameValue(ref meta)) if meta.ident == "serialize" => {
- if let Ok(v) = f(cx, attr_name, meta.ident.as_ref(), &meta.lit) {
- ser_meta.set(v);
- }
- }
-
- Meta(NameValue(ref meta)) if meta.ident == "deserialize" => {
- if let Ok(v) = f(cx, attr_name, meta.ident.as_ref(), &meta.lit) {
- de_meta.set(v);
- }
- }
-
- _ => {
- cx.error(format!(
- "malformed {0} attribute, expected `{0}(serialize = ..., \
- deserialize = ...)`",
- attr_name
- ));
- return Err(());
- }
- }
- }
-
- Ok((ser_meta.get(), de_meta.get()))
-}
-
-fn get_renames<'a>(cx: &Ctxt, items: &'a Punctuated<syn::NestedMeta, Token![,]>) -> Result<SerAndDe<&'a syn::LitStr>, ()> {
- get_ser_and_de(cx, "rename", items, get_lit_str)
-}
-
-fn get_where_predicates(
- cx: &Ctxt,
- items: &Punctuated<syn::NestedMeta, Token![,]>,
-) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
- get_ser_and_de(cx, "bound", items, parse_lit_into_where)
-}
-
-pub fn get_serde_meta_items(attr: &syn::Attribute) -> Option<Vec<syn::NestedMeta>> {
- if attr.path.segments.len() == 1 && attr.path.segments[0].ident == "serde" {
- match attr.interpret_meta() {
- Some(List(ref meta)) => Some(meta.nested.iter().cloned().collect()),
- _ => {
- // TODO: produce an error
- None
- }
- }
- } else {
- None
- }
-}
-
-fn get_lit_str<'a>(
- cx: &Ctxt,
- attr_name: &str,
- meta_item_name: &str,
- lit: &'a syn::Lit,
-) -> Result<&'a syn::LitStr, ()> {
- if let syn::Lit::Str(ref lit) = *lit {
- Ok(lit)
- } else {
- cx.error(format!(
- "expected serde {} attribute to be a string: `{} = \"...\"`",
- attr_name, meta_item_name
- ));
- Err(())
- }
-}
-
-fn parse_lit_into_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Path, ()> {
- let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
- parse_lit_str(string).map_err(|_| cx.error(format!("failed to parse path: {:?}", string.value())))
-}
-
-fn parse_lit_into_expr_path(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::ExprPath, ()> {
- let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
- parse_lit_str(string).map_err(|_| cx.error(format!("failed to parse path: {:?}", string.value())))
-}
-
-fn parse_lit_into_where(
- cx: &Ctxt,
- attr_name: &str,
- meta_item_name: &str,
- lit: &syn::Lit,
-) -> Result<Vec<syn::WherePredicate>, ()> {
- let string = try!(get_lit_str(cx, attr_name, meta_item_name, lit));
- if string.value().is_empty() {
- return Ok(Vec::new());
- }
-
- let where_string = syn::LitStr::new(&format!("where {}", string.value()), string.span());
-
- parse_lit_str::<syn::WhereClause>(&where_string)
- .map(|wh| wh.predicates.into_iter().collect())
- .map_err(|err| cx.error(err))
-}
-
-fn parse_lit_into_ty(cx: &Ctxt, attr_name: &str, lit: &syn::Lit) -> Result<syn::Type, ()> {
- let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
-
- parse_lit_str(string).map_err(|_| {
- cx.error(format!(
- "failed to parse type: {} = {:?}",
- attr_name, string.value()
- ))
- })
-}
-
-// Parses a string literal like "'a + 'b + 'c" containing a nonempty list of
-// lifetimes separated by `+`.
-fn parse_lit_into_lifetimes(
- cx: &Ctxt,
- attr_name: &str,
- lit: &syn::Lit,
-) -> Result<BTreeSet<syn::Lifetime>, ()> {
- let string = try!(get_lit_str(cx, attr_name, attr_name, lit));
- if string.value().is_empty() {
- cx.error("at least one lifetime must be borrowed");
- return Err(());
- }
-
- struct BorrowedLifetimes(Punctuated<syn::Lifetime, Token![+]>);
-
- impl Synom for BorrowedLifetimes {
- named!(parse -> Self, map!(
- call!(Punctuated::parse_separated_nonempty),
- BorrowedLifetimes
- ));
- }
-
- if let Ok(BorrowedLifetimes(lifetimes)) = parse_lit_str(string) {
- let mut set = BTreeSet::new();
- for lifetime in lifetimes {
- if !set.insert(lifetime) {
- cx.error(format!("duplicate borrowed lifetime `{}`", lifetime));
- }
- }
- return Ok(set);
- }
-
- cx.error(format!("failed to parse borrowed lifetimes: {:?}", string.value()));
- Err(())
-}
-
-// Whether the type looks like it might be `std::borrow::Cow<T>` where elem="T".
-// This can have false negatives and false positives.
-//
-// False negative:
-//
-// use std::borrow::Cow as Pig;
-//
-// #[derive(Deserialize)]
-// struct S<'a> {
-// #[serde(borrow)]
-// pig: Pig<'a, str>,
-// }
-//
-// False positive:
-//
-// type str = [i16];
-//
-// #[derive(Deserialize)]
-// struct S<'a> {
-// #[serde(borrow)]
-// cow: Cow<'a, str>,
-// }
-fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
- let path = match *ty {
- syn::Type::Path(ref ty) => &ty.path,
- _ => {
- return false;
- }
- };
- let seg = match path.segments.last() {
- Some(seg) => seg.into_value(),
- None => {
- return false;
- }
- };
- let args = match seg.arguments {
- syn::PathArguments::AngleBracketed(ref bracketed) => &bracketed.args,
- _ => {
- return false;
- }
- };
- seg.ident == "Cow"
- && args.len() == 2
- && match (&args[0], &args[1]) {
- (&syn::GenericArgument::Lifetime(_), &syn::GenericArgument::Type(ref arg)) => {
- elem(arg)
- }
- _ => false,
- }
-}
-
-// Whether the type looks like it might be `&T` where elem="T". This can have
-// false negatives and false positives.
-//
-// False negative:
-//
-// type Yarn = str;
-//
-// #[derive(Deserialize)]
-// struct S<'a> {
-// r: &'a Yarn,
-// }
-//
-// False positive:
-//
-// type str = [i16];
-//
-// #[derive(Deserialize)]
-// struct S<'a> {
-// r: &'a str,
-// }
-fn is_rptr(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
- match *ty {
- syn::Type::Reference(ref ty) => {
- ty.mutability.is_none() && elem(&ty.elem)
- }
- _ => false,
- }
-}
-
-fn is_str(ty: &syn::Type) -> bool {
- is_primitive_type(ty, "str")
-}
-
-fn is_slice_u8(ty: &syn::Type) -> bool {
- match *ty {
- syn::Type::Slice(ref ty) => is_primitive_type(&ty.elem, "u8"),
- _ => false,
- }
-}
-
-fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool {
- match *ty {
- syn::Type::Path(ref ty) => {
- ty.qself.is_none() && is_primitive_path(&ty.path, primitive)
- }
- _ => false,
- }
-}
-
-fn is_primitive_path(path: &syn::Path, primitive: &str) -> bool {
- path.leading_colon.is_none()
- && path.segments.len() == 1
- && path.segments[0].ident == primitive
- && path.segments[0].arguments.is_empty()
-}
-
-// All lifetimes that this type could borrow from a Deserializer.
-//
-// For example a type `S<'a, 'b>` could borrow `'a` and `'b`. On the other hand
-// a type `for<'a> fn(&'a str)` could not borrow `'a` from the Deserializer.
-//
-// This is used when there is an explicit or implicit `#[serde(borrow)]`
-// attribute on the field so there must be at least one borrowable lifetime.
-fn borrowable_lifetimes(
- cx: &Ctxt,
- name: &str,
- ty: &syn::Type,
-) -> Result<BTreeSet<syn::Lifetime>, ()> {
- let mut lifetimes = BTreeSet::new();
- collect_lifetimes(ty, &mut lifetimes);
- if lifetimes.is_empty() {
- cx.error(format!("field `{}` has no lifetimes to borrow", name));
- Err(())
- } else {
- Ok(lifetimes)
- }
-}
-
-fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
- match *ty {
- syn::Type::Slice(ref ty) => {
- collect_lifetimes(&ty.elem, out);
- }
- syn::Type::Array(ref ty) => {
- collect_lifetimes(&ty.elem, out);
- }
- syn::Type::Ptr(ref ty) => {
- collect_lifetimes(&ty.elem, out);
- }
- syn::Type::Reference(ref ty) => {
- out.extend(ty.lifetime.iter().cloned());
- collect_lifetimes(&ty.elem, out);
- }
- syn::Type::Tuple(ref ty) => for elem in &ty.elems {
- collect_lifetimes(elem, out);
- },
- syn::Type::Path(ref ty) => {
- if let Some(ref qself) = ty.qself {
- collect_lifetimes(&qself.ty, out);
- }
- for seg in &ty.path.segments {
- if let syn::PathArguments::AngleBracketed(ref bracketed) = seg.arguments {
- for arg in &bracketed.args {
- match *arg {
- syn::GenericArgument::Lifetime(ref lifetime) => {
- out.insert(lifetime.clone());
- }
- syn::GenericArgument::Type(ref ty) => {
- collect_lifetimes(ty, out);
- }
- syn::GenericArgument::Binding(ref binding) => {
- collect_lifetimes(&binding.ty, out);
- }
- syn::GenericArgument::Const(_) => {}
- }
- }
- }
- }
- }
- syn::Type::Paren(ref ty) => {
- collect_lifetimes(&ty.elem, out);
- }
- syn::Type::Group(ref ty) => {
- collect_lifetimes(&ty.elem, out);
- }
- syn::Type::BareFn(_)
- | syn::Type::Never(_)
- | syn::Type::TraitObject(_)
- | syn::Type::ImplTrait(_)
- | syn::Type::Infer(_)
- | syn::Type::Macro(_)
- | syn::Type::Verbatim(_) => {}
- }
-}
-
-fn parse_lit_str<T>(s: &syn::LitStr) -> Result<T, ParseError>
-where
- T: Synom,
-{
- let tokens = try!(spanned_tokens(s));
- syn::parse2(tokens)
-}
-
-fn spanned_tokens(s: &syn::LitStr) -> Result<TokenStream, ParseError> {
- let stream = try!(syn::parse_str(&s.value()));
- Ok(respan_token_stream(stream, s.span()))
-}
-
-fn respan_token_stream(stream: TokenStream, span: Span) -> TokenStream {
- stream.into_iter().map(|token| respan_token_tree(token, span)).collect()
-}
-
-fn respan_token_tree(mut token: TokenTree, span: Span) -> TokenTree {
- if let TokenTree::Group(ref mut g) = token {
- *g = Group::new(g.delimiter(), respan_token_stream(g.stream().clone(), span));
- }
- token.set_span(span);
- token
-}
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/src/case.rs
+++ /dev/null
@@ -1,186 +0,0 @@
-// Copyright 2017 Serde Developers
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
-#[allow(deprecated, unused_imports)]
-use std::ascii::AsciiExt;
-
-use std::str::FromStr;
-
-use self::RenameRule::*;
-
-#[derive(PartialEq)]
-pub enum RenameRule {
- /// Don't apply a default rename rule.
- None,
- /// Rename direct children to "lowercase" style.
- LowerCase,
- /// Rename direct children to "UPPERCASE" style.
- UPPERCASE,
- /// Rename direct children to "PascalCase" style, as typically used for enum variants.
- PascalCase,
- /// Rename direct children to "camelCase" style.
- CamelCase,
- /// Rename direct children to "snake_case" style, as commonly used for fields.
- SnakeCase,
- /// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly used for constants.
- ScreamingSnakeCase,
- /// Rename direct children to "kebab-case" style.
- KebabCase,
- /// Rename direct children to "SCREAMING-KEBAB-CASE" style.
- ScreamingKebabCase,
-}
-
-impl RenameRule {
- pub fn apply_to_variant(&self, variant: &str) -> String {
- match *self {
- None | PascalCase => variant.to_owned(),
- LowerCase => variant.to_ascii_lowercase(),
- UPPERCASE => variant.to_ascii_uppercase(),
- CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..],
- SnakeCase => {
- let mut snake = String::new();
- for (i, ch) in variant.char_indices() {
- if i > 0 && ch.is_uppercase() {
- snake.push('_');
- }
- snake.push(ch.to_ascii_lowercase());
- }
- snake
- }
- ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(),
- KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"),
- ScreamingKebabCase => ScreamingSnakeCase
- .apply_to_variant(variant)
- .replace('_', "-"),
- }
- }
-
- pub fn apply_to_field(&self, field: &str) -> String {
- match *self {
- None | LowerCase | SnakeCase => field.to_owned(),
- UPPERCASE => field.to_ascii_uppercase(),
- PascalCase => {
- let mut pascal = String::new();
- let mut capitalize = true;
- for ch in field.chars() {
- if ch == '_' {
- capitalize = true;
- } else if capitalize {
- pascal.push(ch.to_ascii_uppercase());
- capitalize = false;
- } else {
- pascal.push(ch);
- }
- }
- pascal
- }
- CamelCase => {
- let pascal = PascalCase.apply_to_field(field);
- pascal[..1].to_ascii_lowercase() + &pascal[1..]
- }
- ScreamingSnakeCase => field.to_ascii_uppercase(),
- KebabCase => field.replace('_', "-"),
- ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-"),
- }
- }
-}
-
-impl FromStr for RenameRule {
- type Err = ();
-
- fn from_str(rename_all_str: &str) -> Result<Self, Self::Err> {
- match rename_all_str {
- "lowercase" => Ok(LowerCase),
- "UPPERCASE" => Ok(UPPERCASE),
- "PascalCase" => Ok(PascalCase),
- "camelCase" => Ok(CamelCase),
- "snake_case" => Ok(SnakeCase),
- "SCREAMING_SNAKE_CASE" => Ok(ScreamingSnakeCase),
- "kebab-case" => Ok(KebabCase),
- "SCREAMING-KEBAB-CASE" => Ok(ScreamingKebabCase),
- _ => Err(()),
- }
- }
-}
-
-#[test]
-fn rename_variants() {
- for &(original, lower, upper, camel, snake, screaming, kebab, screaming_kebab) in &[
- (
- "Outcome",
- "outcome",
- "OUTCOME",
- "outcome",
- "outcome",
- "OUTCOME",
- "outcome",
- "OUTCOME",
- ),
- (
- "VeryTasty",
- "verytasty",
- "VERYTASTY",
- "veryTasty",
- "very_tasty",
- "VERY_TASTY",
- "very-tasty",
- "VERY-TASTY",
- ),
- ("A", "a", "A", "a", "a", "A", "a", "A"),
- ("Z42", "z42", "Z42", "z42", "z42", "Z42", "z42", "Z42"),
- ] {
- assert_eq!(None.apply_to_variant(original), original);
- assert_eq!(LowerCase.apply_to_variant(original), lower);
- assert_eq!(UPPERCASE.apply_to_variant(original), upper);
- assert_eq!(PascalCase.apply_to_variant(original), original);
- assert_eq!(CamelCase.apply_to_variant(original), camel);
- assert_eq!(SnakeCase.apply_to_variant(original), snake);
- assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming);
- assert_eq!(KebabCase.apply_to_variant(original), kebab);
- assert_eq!(
- ScreamingKebabCase.apply_to_variant(original),
- screaming_kebab
- );
- }
-}
-
-#[test]
-fn rename_fields() {
- for &(original, upper, pascal, camel, screaming, kebab, screaming_kebab) in &[
- (
- "outcome",
- "OUTCOME",
- "Outcome",
- "outcome",
- "OUTCOME",
- "outcome",
- "OUTCOME",
- ),
- (
- "very_tasty",
- "VERY_TASTY",
- "VeryTasty",
- "veryTasty",
- "VERY_TASTY",
- "very-tasty",
- "VERY-TASTY",
- ),
- ("a", "A", "A", "a", "A", "a", "A"),
- ("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"),
- ] {
- assert_eq!(None.apply_to_field(original), original);
- assert_eq!(UPPERCASE.apply_to_field(original), upper);
- assert_eq!(PascalCase.apply_to_field(original), pascal);
- assert_eq!(CamelCase.apply_to_field(original), camel);
- assert_eq!(SnakeCase.apply_to_field(original), original);
- assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming);
- assert_eq!(KebabCase.apply_to_field(original), kebab);
- assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab);
- }
-}
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/src/check.rs
+++ /dev/null
@@ -1,281 +0,0 @@
-// Copyright 2017 Serde Developers
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use ast::{Data, Container, Style};
-use attr::{Identifier, EnumTag};
-use Ctxt;
-
-/// Cross-cutting checks that require looking at more than a single attrs
-/// object. Simpler checks should happen when parsing and building the attrs.
-pub fn check(cx: &Ctxt, cont: &Container) {
- check_getter(cx, cont);
- check_flatten(cx, cont);
- check_identifier(cx, cont);
- check_variant_skip_attrs(cx, cont);
- check_internal_tag_field_name_conflict(cx, cont);
- check_adjacent_tag_conflict(cx, cont);
-}
-
-/// Getters are only allowed inside structs (not enums) with the `remote`
-/// attribute.
-fn check_getter(cx: &Ctxt, cont: &Container) {
- match cont.data {
- Data::Enum(_, _) => {
- if cont.data.has_getter() {
- cx.error("#[serde(getter = \"...\")] is not allowed in an enum");
- }
- }
- Data::Struct(_, _) => {
- if cont.data.has_getter() && cont.attrs.remote().is_none() {
- cx.error(
- "#[serde(getter = \"...\")] can only be used in structs \
- that have #[serde(remote = \"...\")]",
- );
- }
- }
- }
-}
-
-/// Flattening has some restrictions we can test.
-fn check_flatten(cx: &Ctxt, cont: &Container) {
- match cont.data {
- Data::Enum(_, _) => {
- if cont.attrs.has_flatten() {
- cx.error("#[serde(flatten)] cannot be used within enums");
- }
- }
- Data::Struct(style, _) => {
- for field in cont.data.all_fields() {
- if !field.attrs.flatten() {
- continue;
- }
- match style {
- Style::Tuple => {
- cx.error("#[serde(flatten)] cannot be used on tuple structs");
- }
- Style::Newtype => {
- cx.error("#[serde(flatten)] cannot be used on newtype structs");
- }
- _ => {}
- }
- if field.attrs.skip_serializing() {
- cx.error(
- "#[serde(flatten] can not be combined with \
- #[serde(skip_serializing)]"
- );
- } else if field.attrs.skip_serializing_if().is_some() {
- cx.error(
- "#[serde(flatten] can not be combined with \
- #[serde(skip_serializing_if = \"...\")]"
- );
- } else if field.attrs.skip_deserializing() {
- cx.error(
- "#[serde(flatten] can not be combined with \
- #[serde(skip_deserializing)]"
- );
- }
- }
- }
- }
-}
-
-/// The `other` attribute must be used at most once and it must be the last
-/// variant of an enum that has the `field_identifier` attribute.
-///
-/// Inside a `variant_identifier` all variants must be unit variants. Inside a
-/// `field_identifier` all but possibly one variant must be unit variants. The
-/// last variant may be a newtype variant which is an implicit "other" case.
-fn check_identifier(cx: &Ctxt, cont: &Container) {
- let variants = match cont.data {
- Data::Enum(_, ref variants) => variants,
- Data::Struct(_, _) => {
- return;
- }
- };
-
- for (i, variant) in variants.iter().enumerate() {
- match (
- variant.style,
- cont.attrs.identifier(),
- variant.attrs.other(),
- ) {
- // The `other` attribute may only be used in a field_identifier.
- (_, Identifier::Variant, true) | (_, Identifier::No, true) => {
- cx.error("#[serde(other)] may only be used inside a field_identifier");
- }
-
- // Variant with `other` attribute must be the last one.
- (Style::Unit, Identifier::Field, true) => {
- if i < variants.len() - 1 {
- cx.error("#[serde(other)] must be the last variant");
- }
- }
-
- // Variant with `other` attribute must be a unit variant.
- (_, Identifier::Field, true) => {
- cx.error("#[serde(other)] must be on a unit variant");
- }
-
- // Any sort of variant is allowed if this is not an identifier.
- (_, Identifier::No, false) => {}
-
- // Unit variant without `other` attribute is always fine.
- (Style::Unit, _, false) => {}
-
- // The last field is allowed to be a newtype catch-all.
- (Style::Newtype, Identifier::Field, false) => {
- if i < variants.len() - 1 {
- cx.error(format!("`{}` must be the last variant", variant.ident));
- }
- }
-
- (_, Identifier::Field, false) => {
- cx.error("field_identifier may only contain unit variants");
- }
-
- (_, Identifier::Variant, false) => {
- cx.error("variant_identifier may only contain unit variants");
- }
- }
- }
-}
-
-/// Skip-(de)serializing attributes are not allowed on variants marked
-/// (de)serialize_with.
-fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
- let variants = match cont.data {
- Data::Enum(_, ref variants) => variants,
- Data::Struct(_, _) => {
- return;
- }
- };
-
- for variant in variants.iter() {
- if variant.attrs.serialize_with().is_some() {
- if variant.attrs.skip_serializing() {
- cx.error(format!(
- "variant `{}` cannot have both #[serde(serialize_with)] and \
- #[serde(skip_serializing)]",
- variant.ident
- ));
- }
-
- for (i, field) in variant.fields.iter().enumerate() {
- let ident = field
- .ident
- .as_ref()
- .map_or_else(|| format!("{}", i), |ident| format!("`{}`", ident));
-
- if field.attrs.skip_serializing() {
- cx.error(format!(
- "variant `{}` cannot have both #[serde(serialize_with)] and \
- a field {} marked with #[serde(skip_serializing)]",
- variant.ident, ident
- ));
- }
-
- if field.attrs.skip_serializing_if().is_some() {
- cx.error(format!(
- "variant `{}` cannot have both #[serde(serialize_with)] and \
- a field {} marked with #[serde(skip_serializing_if)]",
- variant.ident, ident
- ));
- }
- }
- }
-
- if variant.attrs.deserialize_with().is_some() {
- if variant.attrs.skip_deserializing() {
- cx.error(format!(
- "variant `{}` cannot have both #[serde(deserialize_with)] and \
- #[serde(skip_deserializing)]",
- variant.ident
- ));
- }
-
- for (i, field) in variant.fields.iter().enumerate() {
- if field.attrs.skip_deserializing() {
- let ident = field
- .ident
- .as_ref()
- .map_or_else(|| format!("{}", i), |ident| format!("`{}`", ident));
-
- cx.error(format!(
- "variant `{}` cannot have both #[serde(deserialize_with)] \
- and a field {} marked with #[serde(skip_deserializing)]",
- variant.ident, ident
- ));
- }
- }
- }
- }
-}
-
-/// The tag of an internally-tagged struct variant must not be
-/// the same as either one of its fields, as this would result in
-/// duplicate keys in the serialized output and/or ambiguity in
-/// the to-be-deserialized input.
-fn check_internal_tag_field_name_conflict(
- cx: &Ctxt,
- cont: &Container,
-) {
- let variants = match cont.data {
- Data::Enum(_, ref variants) => variants,
- Data::Struct(_, _) => return,
- };
-
- let tag = match *cont.attrs.tag() {
- EnumTag::Internal { ref tag } => tag.as_str(),
- EnumTag::External | EnumTag::Adjacent { .. } | EnumTag::None => return,
- };
-
- let diagnose_conflict = || {
- let message = format!(
- "variant field name `{}` conflicts with internal tag",
- tag
- );
- cx.error(message);
- };
-
- for variant in variants {
- match variant.style {
- Style::Struct => {
- for field in &variant.fields {
- let check_ser = !field.attrs.skip_serializing();
- let check_de = !field.attrs.skip_deserializing();
- let name = field.attrs.name();
- let ser_name = name.serialize_name();
- let de_name = name.deserialize_name();
-
- if check_ser && ser_name == tag || check_de && de_name == tag {
- diagnose_conflict();
- return;
- }
- }
- },
- Style::Unit | Style::Newtype | Style::Tuple => {},
- }
- }
-}
-
-/// In the case of adjacently-tagged enums, the type and the
-/// contents tag must differ, for the same reason.
-fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
- let (type_tag, content_tag) = match *cont.attrs.tag() {
- EnumTag::Adjacent { ref tag, ref content } => (tag, content),
- EnumTag::Internal { .. } | EnumTag::External | EnumTag::None => return,
- };
-
- if type_tag == content_tag {
- let message = format!(
- "enum tags `{}` for type and content conflict with each other",
- type_tag
- );
- cx.error(message);
- }
-}
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/src/ctxt.rs
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2017 Serde Developers
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use std::fmt::Display;
-use std::cell::RefCell;
-use std::thread;
-
-#[derive(Default)]
-pub struct Ctxt {
- errors: RefCell<Option<Vec<String>>>,
-}
-
-impl Ctxt {
- pub fn new() -> Self {
- Ctxt {
- errors: RefCell::new(Some(Vec::new())),
- }
- }
-
- pub fn error<T: Display>(&self, msg: T) {
- self.errors
- .borrow_mut()
- .as_mut()
- .unwrap()
- .push(msg.to_string());
- }
-
- pub fn check(self) -> Result<(), String> {
- let mut errors = self.errors.borrow_mut().take().unwrap();
- match errors.len() {
- 0 => Ok(()),
- 1 => Err(errors.pop().unwrap()),
- n => {
- let mut msg = format!("{} errors:", n);
- for err in errors {
- msg.push_str("\n\t# ");
- msg.push_str(&err);
- }
- Err(msg)
- }
- }
- }
-}
-
-impl Drop for Ctxt {
- fn drop(&mut self) {
- if !thread::panicking() && self.errors.borrow().is_some() {
- panic!("forgot to check for errors");
- }
- }
-}
deleted file mode 100644
--- a/third_party/rust/serde_derive_internals/src/lib.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-// Copyright 2017 Serde Developers
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.23.0")]
-#![cfg_attr(feature = "cargo-clippy", allow(cyclomatic_complexity, doc_markdown, match_same_arms,
- redundant_field_names))]
-
-#[macro_use]
-extern crate syn;
-
-extern crate proc_macro2;
-
-pub mod ast;
-pub mod attr;
-
-mod ctxt;
-pub use ctxt::Ctxt;
-
-mod case;
-mod check;