summaryrefslogtreecommitdiffstats
path: root/third_party/rust/serde
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--third_party/rust/serde/.cargo-checksum.json1
-rw-r--r--third_party/rust/serde/Cargo.toml70
-rw-r--r--third_party/rust/serde/LICENSE-APACHE201
-rw-r--r--third_party/rust/serde/LICENSE-MIT23
-rw-r--r--third_party/rust/serde/README.md114
-rw-r--r--third_party/rust/serde/build.rs146
-rw-r--r--third_party/rust/serde/crates-io.md65
-rw-r--r--third_party/rust/serde/src/de/format.rs30
-rw-r--r--third_party/rust/serde/src/de/ignored_any.rs243
-rw-r--r--third_party/rust/serde/src/de/impls.rs2733
-rw-r--r--third_party/rust/serde/src/de/mod.rs2299
-rw-r--r--third_party/rust/serde/src/de/seed.rs19
-rw-r--r--third_party/rust/serde/src/de/utf8.rs46
-rw-r--r--third_party/rust/serde/src/de/value.rs1714
-rw-r--r--third_party/rust/serde/src/integer128.rs82
-rw-r--r--third_party/rust/serde/src/lib.rs334
-rw-r--r--third_party/rust/serde/src/macros.rs236
-rw-r--r--third_party/rust/serde/src/private/de.rs2995
-rw-r--r--third_party/rust/serde/src/private/doc.rs159
-rw-r--r--third_party/rust/serde/src/private/mod.rs50
-rw-r--r--third_party/rust/serde/src/private/ser.rs1310
-rw-r--r--third_party/rust/serde/src/private/size_hint.rs21
-rw-r--r--third_party/rust/serde/src/ser/fmt.rs174
-rw-r--r--third_party/rust/serde/src/ser/impls.rs983
-rw-r--r--third_party/rust/serde/src/ser/impossible.rs216
-rw-r--r--third_party/rust/serde/src/ser/mod.rs1988
-rw-r--r--third_party/rust/serde/src/std_error.rs48
-rw-r--r--third_party/rust/serde_bytes/.cargo-checksum.json1
-rw-r--r--third_party/rust/serde_bytes/Cargo.toml56
-rw-r--r--third_party/rust/serde_bytes/LICENSE-APACHE176
-rw-r--r--third_party/rust/serde_bytes/LICENSE-MIT23
-rw-r--r--third_party/rust/serde_bytes/README.md54
-rw-r--r--third_party/rust/serde_bytes/src/bytebuf.rs253
-rw-r--r--third_party/rust/serde_bytes/src/bytes.rs172
-rw-r--r--third_party/rust/serde_bytes/src/de.rs229
-rw-r--r--third_party/rust/serde_bytes/src/lib.rs113
-rw-r--r--third_party/rust/serde_bytes/src/ser.rs136
-rw-r--r--third_party/rust/serde_bytes/tests/test_derive.rs101
-rw-r--r--third_party/rust/serde_bytes/tests/test_partialeq.rs15
-rw-r--r--third_party/rust/serde_bytes/tests/test_serde.rs59
-rw-r--r--third_party/rust/serde_cbor/.cargo-checksum.json1
-rw-r--r--third_party/rust/serde_cbor/CONTRIBUTING.md29
-rw-r--r--third_party/rust/serde_cbor/Cargo.lock68
-rw-r--r--third_party/rust/serde_cbor/Cargo.toml44
-rw-r--r--third_party/rust/serde_cbor/LICENSE-APACHE201
-rw-r--r--third_party/rust/serde_cbor/LICENSE-MIT19
-rw-r--r--third_party/rust/serde_cbor/README.md97
-rw-r--r--third_party/rust/serde_cbor/examples/readme.rs39
-rw-r--r--third_party/rust/serde_cbor/examples/tags.rs84
-rw-r--r--third_party/rust/serde_cbor/examples/tux.cbor1
-rw-r--r--third_party/rust/serde_cbor/src/de.rs1360
-rw-r--r--third_party/rust/serde_cbor/src/error.rs318
-rw-r--r--third_party/rust/serde_cbor/src/lib.rs369
-rw-r--r--third_party/rust/serde_cbor/src/read.rs637
-rw-r--r--third_party/rust/serde_cbor/src/ser.rs743
-rw-r--r--third_party/rust/serde_cbor/src/tags.rs220
-rw-r--r--third_party/rust/serde_cbor/src/value/de.rs166
-rw-r--r--third_party/rust/serde_cbor/src/value/mod.rs156
-rw-r--r--third_party/rust/serde_cbor/src/value/ser.rs443
-rw-r--r--third_party/rust/serde_cbor/src/write.rs175
-rw-r--r--third_party/rust/serde_cbor/tests/bennofs.rs60
-rw-r--r--third_party/rust/serde_cbor/tests/canonical.rs104
-rw-r--r--third_party/rust/serde_cbor/tests/crash.cborbin0 -> 190 bytes
-rw-r--r--third_party/rust/serde_cbor/tests/de.rs747
-rw-r--r--third_party/rust/serde_cbor/tests/enum.rs236
-rw-r--r--third_party/rust/serde_cbor/tests/kietaub.cborbin0 -> 212 bytes
-rw-r--r--third_party/rust/serde_cbor/tests/ser.rs254
-rw-r--r--third_party/rust/serde_cbor/tests/std_types.rs186
-rw-r--r--third_party/rust/serde_cbor/tests/tags.rs48
-rw-r--r--third_party/rust/serde_cbor/tests/value.rs100
-rw-r--r--third_party/rust/serde_derive/.cargo-checksum.json1
-rw-r--r--third_party/rust/serde_derive/Cargo.toml63
-rw-r--r--third_party/rust/serde_derive/LICENSE-APACHE201
-rw-r--r--third_party/rust/serde_derive/LICENSE-MIT23
-rw-r--r--third_party/rust/serde_derive/README.md114
-rw-r--r--third_party/rust/serde_derive/build.rs38
-rw-r--r--third_party/rust/serde_derive/crates-io.md65
-rw-r--r--third_party/rust/serde_derive/src/bound.rs406
-rw-r--r--third_party/rust/serde_derive/src/de.rs3142
-rw-r--r--third_party/rust/serde_derive/src/dummy.rs48
-rw-r--r--third_party/rust/serde_derive/src/fragment.rs74
-rw-r--r--third_party/rust/serde_derive/src/internals/ast.rs202
-rw-r--r--third_party/rust/serde_derive/src/internals/attr.rs1952
-rw-r--r--third_party/rust/serde_derive/src/internals/case.rs197
-rw-r--r--third_party/rust/serde_derive/src/internals/check.rs443
-rw-r--r--third_party/rust/serde_derive/src/internals/ctxt.rs62
-rw-r--r--third_party/rust/serde_derive/src/internals/mod.rs28
-rw-r--r--third_party/rust/serde_derive/src/internals/receiver.rs285
-rw-r--r--third_party/rust/serde_derive/src/internals/respan.rs16
-rw-r--r--third_party/rust/serde_derive/src/internals/symbol.rs68
-rw-r--r--third_party/rust/serde_derive/src/lib.rs109
-rw-r--r--third_party/rust/serde_derive/src/pretend.rs201
-rw-r--r--third_party/rust/serde_derive/src/ser.rs1340
-rw-r--r--third_party/rust/serde_derive/src/this.rs32
-rw-r--r--third_party/rust/serde_derive/src/try.rs24
-rw-r--r--third_party/rust/serde_json/.cargo-checksum.json1
-rw-r--r--third_party/rust/serde_json/CONTRIBUTING.md46
-rw-r--r--third_party/rust/serde_json/Cargo.toml109
-rw-r--r--third_party/rust/serde_json/LICENSE-APACHE176
-rw-r--r--third_party/rust/serde_json/LICENSE-MIT23
-rw-r--r--third_party/rust/serde_json/README.md390
-rw-r--r--third_party/rust/serde_json/build.rs54
-rw-r--r--third_party/rust/serde_json/src/de.rs2606
-rw-r--r--third_party/rust/serde_json/src/error.rs445
-rw-r--r--third_party/rust/serde_json/src/features_check/error.rs1
-rw-r--r--third_party/rust/serde_json/src/features_check/mod.rs13
-rw-r--r--third_party/rust/serde_json/src/io/core.rs79
-rw-r--r--third_party/rust/serde_json/src/io/mod.rs20
-rw-r--r--third_party/rust/serde_json/src/iter.rs70
-rw-r--r--third_party/rust/serde_json/src/lexical/algorithm.rs193
-rw-r--r--third_party/rust/serde_json/src/lexical/bhcomp.rs218
-rw-r--r--third_party/rust/serde_json/src/lexical/bignum.rs33
-rw-r--r--third_party/rust/serde_json/src/lexical/cached.rs82
-rw-r--r--third_party/rust/serde_json/src/lexical/cached_float80.rs206
-rw-r--r--third_party/rust/serde_json/src/lexical/digit.rs15
-rw-r--r--third_party/rust/serde_json/src/lexical/errors.rs133
-rw-r--r--third_party/rust/serde_json/src/lexical/exponent.rs50
-rw-r--r--third_party/rust/serde_json/src/lexical/float.rs183
-rw-r--r--third_party/rust/serde_json/src/lexical/large_powers.rs9
-rw-r--r--third_party/rust/serde_json/src/lexical/large_powers32.rs183
-rw-r--r--third_party/rust/serde_json/src/lexical/large_powers64.rs625
-rw-r--r--third_party/rust/serde_json/src/lexical/math.rs886
-rw-r--r--third_party/rust/serde_json/src/lexical/mod.rs38
-rw-r--r--third_party/rust/serde_json/src/lexical/num.rs440
-rw-r--r--third_party/rust/serde_json/src/lexical/parse.rs83
-rw-r--r--third_party/rust/serde_json/src/lexical/rounding.rs231
-rw-r--r--third_party/rust/serde_json/src/lexical/shift.rs46
-rw-r--r--third_party/rust/serde_json/src/lexical/small_powers.rs70
-rw-r--r--third_party/rust/serde_json/src/lib.rs421
-rw-r--r--third_party/rust/serde_json/src/macros.rs303
-rw-r--r--third_party/rust/serde_json/src/map.rs940
-rw-r--r--third_party/rust/serde_json/src/number.rs745
-rw-r--r--third_party/rust/serde_json/src/raw.rs531
-rw-r--r--third_party/rust/serde_json/src/read.rs1004
-rw-r--r--third_party/rust/serde_json/src/ser.rs2179
-rw-r--r--third_party/rust/serde_json/src/value/de.rs1377
-rw-r--r--third_party/rust/serde_json/src/value/from.rs277
-rw-r--r--third_party/rust/serde_json/src/value/index.rs258
-rw-r--r--third_party/rust/serde_json/src/value/mod.rs987
-rw-r--r--third_party/rust/serde_json/src/value/partial_eq.rs95
-rw-r--r--third_party/rust/serde_json/src/value/ser.rs1044
-rw-r--r--third_party/rust/serde_json/tests/compiletest.rs7
-rw-r--r--third_party/rust/serde_json/tests/debug.rs81
-rw-r--r--third_party/rust/serde_json/tests/lexical.rs52
-rw-r--r--third_party/rust/serde_json/tests/lexical/algorithm.rs110
-rw-r--r--third_party/rust/serde_json/tests/lexical/exponent.rs54
-rw-r--r--third_party/rust/serde_json/tests/lexical/float.rs581
-rw-r--r--third_party/rust/serde_json/tests/lexical/math.rs211
-rw-r--r--third_party/rust/serde_json/tests/lexical/num.rs76
-rw-r--r--third_party/rust/serde_json/tests/lexical/parse.rs204
-rw-r--r--third_party/rust/serde_json/tests/lexical/rounding.rs316
-rw-r--r--third_party/rust/serde_json/tests/macros/mod.rs61
-rw-r--r--third_party/rust/serde_json/tests/map.rs47
-rw-r--r--third_party/rust/serde_json/tests/regression.rs3
-rw-r--r--third_party/rust/serde_json/tests/regression/issue520.rs20
-rw-r--r--third_party/rust/serde_json/tests/regression/issue795.rs59
-rw-r--r--third_party/rust/serde_json/tests/regression/issue845.rs74
-rw-r--r--third_party/rust/serde_json/tests/regression/issue953.rs9
-rw-r--r--third_party/rust/serde_json/tests/stream.rs183
-rw-r--r--third_party/rust/serde_json/tests/test.rs2408
-rw-r--r--third_party/rust/serde_json/tests/ui/missing_colon.rs5
-rw-r--r--third_party/rust/serde_json/tests/ui/missing_colon.stderr12
-rw-r--r--third_party/rust/serde_json/tests/ui/missing_comma.rs5
-rw-r--r--third_party/rust/serde_json/tests/ui/missing_comma.stderr13
-rw-r--r--third_party/rust/serde_json/tests/ui/missing_value.rs5
-rw-r--r--third_party/rust/serde_json/tests/ui/missing_value.stderr12
-rw-r--r--third_party/rust/serde_json/tests/ui/not_found.rs5
-rw-r--r--third_party/rust/serde_json/tests/ui/not_found.stderr5
-rw-r--r--third_party/rust/serde_json/tests/ui/parse_expr.rs5
-rw-r--r--third_party/rust/serde_json/tests/ui/parse_expr.stderr11
-rw-r--r--third_party/rust/serde_json/tests/ui/parse_key.rs5
-rw-r--r--third_party/rust/serde_json/tests/ui/parse_key.stderr5
-rw-r--r--third_party/rust/serde_json/tests/ui/unexpected_after_array_element.rs5
-rw-r--r--third_party/rust/serde_json/tests/ui/unexpected_after_array_element.stderr7
-rw-r--r--third_party/rust/serde_json/tests/ui/unexpected_after_map_entry.rs5
-rw-r--r--third_party/rust/serde_json/tests/ui/unexpected_after_map_entry.stderr7
-rw-r--r--third_party/rust/serde_json/tests/ui/unexpected_colon.rs5
-rw-r--r--third_party/rust/serde_json/tests/ui/unexpected_colon.stderr7
-rw-r--r--third_party/rust/serde_json/tests/ui/unexpected_comma.rs5
-rw-r--r--third_party/rust/serde_json/tests/ui/unexpected_comma.stderr7
-rw-r--r--third_party/rust/serde_repr/.cargo-checksum.json1
-rw-r--r--third_party/rust/serde_repr/Cargo.toml59
-rw-r--r--third_party/rust/serde_repr/LICENSE-APACHE201
-rw-r--r--third_party/rust/serde_repr/LICENSE-MIT23
-rw-r--r--third_party/rust/serde_repr/README.md57
-rw-r--r--third_party/rust/serde_repr/src/lib.rs140
-rw-r--r--third_party/rust/serde_repr/src/parse.rs114
-rw-r--r--third_party/rust/serde_repr/tests/compiletest.rs7
-rw-r--r--third_party/rust/serde_repr/tests/test.rs81
-rw-r--r--third_party/rust/serde_repr/tests/ui/empty_enum.rs6
-rw-r--r--third_party/rust/serde_repr/tests/ui/empty_enum.stderr7
-rw-r--r--third_party/rust/serde_repr/tests/ui/missing_repr.rs11
-rw-r--r--third_party/rust/serde_repr/tests/ui/missing_repr.stderr7
-rw-r--r--third_party/rust/serde_repr/tests/ui/multiple_others.rs12
-rw-r--r--third_party/rust/serde_repr/tests/ui/multiple_others.stderr7
-rw-r--r--third_party/rust/serde_repr/tests/ui/non_unit_variant.rs12
-rw-r--r--third_party/rust/serde_repr/tests/ui/non_unit_variant.stderr5
-rw-r--r--third_party/rust/serde_repr/tests/ui/not_enum.rs11
-rw-r--r--third_party/rust/serde_repr/tests/ui/not_enum.stderr7
-rw-r--r--third_party/rust/serde_urlencoded/.cargo-checksum.json1
-rw-r--r--third_party/rust/serde_urlencoded/Cargo.toml41
-rw-r--r--third_party/rust/serde_urlencoded/LICENSE-APACHE176
-rw-r--r--third_party/rust/serde_urlencoded/LICENSE-MIT25
-rw-r--r--third_party/rust/serde_urlencoded/README.md53
-rw-r--r--third_party/rust/serde_urlencoded/rustfmt.toml5
-rw-r--r--third_party/rust/serde_urlencoded/src/de.rs321
-rw-r--r--third_party/rust/serde_urlencoded/src/lib.rs12
-rw-r--r--third_party/rust/serde_urlencoded/src/ser/key.rs77
-rw-r--r--third_party/rust/serde_urlencoded/src/ser/mod.rs555
-rw-r--r--third_party/rust/serde_urlencoded/src/ser/pair.rs271
-rw-r--r--third_party/rust/serde_urlencoded/src/ser/part.rs236
-rw-r--r--third_party/rust/serde_urlencoded/src/ser/value.rs62
-rw-r--r--third_party/rust/serde_urlencoded/tests/test_deserialize.rs88
-rw-r--r--third_party/rust/serde_urlencoded/tests/test_serialize.rs104
-rw-r--r--third_party/rust/serde_with/.cargo-checksum.json1
-rw-r--r--third_party/rust/serde_with/CHANGELOG.md682
-rw-r--r--third_party/rust/serde_with/Cargo.toml214
-rw-r--r--third_party/rust/serde_with/LICENSE-APACHE201
-rw-r--r--third_party/rust/serde_with/LICENSE-MIT25
-rw-r--r--third_party/rust/serde_with/README.md188
-rw-r--r--third_party/rust/serde_with/src/base64.rs205
-rw-r--r--third_party/rust/serde_with/src/chrono.rs516
-rw-r--r--third_party/rust/serde_with/src/content/mod.rs5
-rw-r--r--third_party/rust/serde_with/src/content/ser.rs623
-rw-r--r--third_party/rust/serde_with/src/de/const_arrays.rs338
-rw-r--r--third_party/rust/serde_with/src/de/impls.rs1508
-rw-r--r--third_party/rust/serde_with/src/de/legacy_arrays.rs85
-rw-r--r--third_party/rust/serde_with/src/de/mod.rs143
-rw-r--r--third_party/rust/serde_with/src/duplicate_key_impls/error_on_duplicate.rs127
-rw-r--r--third_party/rust/serde_with/src/duplicate_key_impls/first_value_wins.rs136
-rw-r--r--third_party/rust/serde_with/src/duplicate_key_impls/last_value_wins.rs69
-rw-r--r--third_party/rust/serde_with/src/duplicate_key_impls/mod.rs10
-rw-r--r--third_party/rust/serde_with/src/enum_map.rs888
-rw-r--r--third_party/rust/serde_with/src/flatten_maybe.rs86
-rw-r--r--third_party/rust/serde_with/src/formats.rs96
-rw-r--r--third_party/rust/serde_with/src/guide.md144
-rw-r--r--third_party/rust/serde_with/src/guide/feature_flags.md62
-rw-r--r--third_party/rust/serde_with/src/guide/serde_as.md332
-rw-r--r--third_party/rust/serde_with/src/guide/serde_as_transformations.md518
-rw-r--r--third_party/rust/serde_with/src/hex.rs155
-rw-r--r--third_party/rust/serde_with/src/json.rs150
-rw-r--r--third_party/rust/serde_with/src/lib.rs2034
-rw-r--r--third_party/rust/serde_with/src/rust.rs1943
-rw-r--r--third_party/rust/serde_with/src/ser/const_arrays.rs90
-rw-r--r--third_party/rust/serde_with/src/ser/impls.rs739
-rw-r--r--third_party/rust/serde_with/src/ser/legacy_arrays.rs34
-rw-r--r--third_party/rust/serde_with/src/ser/mod.rs158
-rw-r--r--third_party/rust/serde_with/src/serde_conv.rs147
-rw-r--r--third_party/rust/serde_with/src/time_0_3.rs382
-rw-r--r--third_party/rust/serde_with/src/utils.rs120
-rw-r--r--third_party/rust/serde_with/src/utils/duration.rs559
-rw-r--r--third_party/rust/serde_with/src/with_prefix.rs612
-rw-r--r--third_party/rust/serde_with/tests/base64.rs144
-rw-r--r--third_party/rust/serde_with/tests/chrono.rs740
-rw-r--r--third_party/rust/serde_with/tests/derives/deserialize_fromstr.rs96
-rw-r--r--third_party/rust/serde_with/tests/derives/lib.rs15
-rw-r--r--third_party/rust/serde_with/tests/derives/serialize_display.rs39
-rw-r--r--third_party/rust/serde_with/tests/hex.rs93
-rw-r--r--third_party/rust/serde_with/tests/indexmap.rs285
-rw-r--r--third_party/rust/serde_with/tests/json.rs41
-rw-r--r--third_party/rust/serde_with/tests/rust.rs676
-rw-r--r--third_party/rust/serde_with/tests/serde_as/collections.rs44
-rw-r--r--third_party/rust/serde_with/tests/serde_as/default_on.rs130
-rw-r--r--third_party/rust/serde_with/tests/serde_as/enum_map.rs459
-rw-r--r--third_party/rust/serde_with/tests/serde_as/frominto.rs187
-rw-r--r--third_party/rust/serde_with/tests/serde_as/lib.rs1129
-rw-r--r--third_party/rust/serde_with/tests/serde_as/map_tuple_list.rs272
-rw-r--r--third_party/rust/serde_with/tests/serde_as/pickfirst.rs134
-rw-r--r--third_party/rust/serde_with/tests/serde_as/serde_as_macro.rs191
-rw-r--r--third_party/rust/serde_with/tests/serde_as/serde_conv.rs52
-rw-r--r--third_party/rust/serde_with/tests/serde_as/time.rs521
-rw-r--r--third_party/rust/serde_with/tests/time_0_3.rs229
-rw-r--r--third_party/rust/serde_with/tests/utils.rs79
-rw-r--r--third_party/rust/serde_with/tests/version_numbers.rs80
-rw-r--r--third_party/rust/serde_with/tests/with_prefix.rs164
-rw-r--r--third_party/rust/serde_with_macros/.cargo-checksum.json1
-rw-r--r--third_party/rust/serde_with_macros/CHANGELOG.md157
-rw-r--r--third_party/rust/serde_with_macros/Cargo.toml62
-rw-r--r--third_party/rust/serde_with_macros/LICENSE-APACHE201
-rw-r--r--third_party/rust/serde_with_macros/LICENSE-MIT25
-rw-r--r--third_party/rust/serde_with_macros/README.md186
-rw-r--r--third_party/rust/serde_with_macros/src/lib.rs1016
-rw-r--r--third_party/rust/serde_with_macros/src/utils.rs77
-rw-r--r--third_party/rust/serde_yaml/.cargo-checksum.json1
-rw-r--r--third_party/rust/serde_yaml/Cargo.toml53
-rw-r--r--third_party/rust/serde_yaml/LICENSE-APACHE201
-rw-r--r--third_party/rust/serde_yaml/LICENSE-MIT23
-rw-r--r--third_party/rust/serde_yaml/README.md104
-rw-r--r--third_party/rust/serde_yaml/src/de.rs1525
-rw-r--r--third_party/rust/serde_yaml/src/error.rs244
-rw-r--r--third_party/rust/serde_yaml/src/lib.rs125
-rw-r--r--third_party/rust/serde_yaml/src/mapping.rs512
-rw-r--r--third_party/rust/serde_yaml/src/number.rs550
-rw-r--r--third_party/rust/serde_yaml/src/path.rs34
-rw-r--r--third_party/rust/serde_yaml/src/ser.rs887
-rw-r--r--third_party/rust/serde_yaml/src/value/de.rs707
-rw-r--r--third_party/rust/serde_yaml/src/value/from.rs180
-rw-r--r--third_party/rust/serde_yaml/src/value/index.rs260
-rw-r--r--third_party/rust/serde_yaml/src/value/mod.rs648
-rw-r--r--third_party/rust/serde_yaml/src/value/partial_eq.rs149
-rw-r--r--third_party/rust/serde_yaml/src/value/ser.rs25
-rw-r--r--third_party/rust/serde_yaml/tests/test_de.rs396
-rw-r--r--third_party/rust/serde_yaml/tests/test_error.rs287
-rw-r--r--third_party/rust/serde_yaml/tests/test_serde.rs434
-rw-r--r--third_party/rust/serde_yaml/tests/test_value.rs55
305 files changed, 88382 insertions, 0 deletions
diff --git a/third_party/rust/serde/.cargo-checksum.json b/third_party/rust/serde/.cargo-checksum.json
new file mode 100644
index 0000000000..812d0d93c1
--- /dev/null
+++ b/third_party/rust/serde/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"e390e019c701323f7a6f3b42dc1242445a0ea6c1188d91b1d3513fcebc7afe1d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"3c12b60b6c77a201665344a7612b42392e77ddc3e907f5a14e3f3a4bb6c4692e","build.rs":"bf6f7f791517c2d583457e74452c68a7308c5e5106d1a2cebcfa19c55a9c1a42","crates-io.md":"ee22254ee64c3189eef3e707c8d75dc66a8df2a7ee9e518d95238950780ec387","src/de/format.rs":"84f902fd4c3be66e81ac01d5b21cd876113c16f9890ff8bab5faa0d085386294","src/de/ignored_any.rs":"967184c86707c99b77a1cfb218dfc823f560fae227b6635aee6af19ee82962f5","src/de/impls.rs":"2d4d9985b1048f5f6371984c9bc8f273ad685901ba22ad27483dfb7cec65898c","src/de/mod.rs":"71198e80e4c64aa686b5ceb6e8bce10db20845a87a30fa14227ecbe365a046d5","src/de/seed.rs":"e8cf0233afe0af5b8fb9e4c94f301c92729c5ba417280af9e2201b732e374a72","src/de/utf8.rs":"f17524ee0af98ec3abcfd7d0b812fbd1033263bd8e2ce2f57c1e1999ce153558","src/de/value.rs":"aa5055923e2c3fd1c1f1abdfb380a1d63d07cf4d602ef62d2df2b7da33dd8c81","src/integer128.rs":"ca49591abde2d8c4f582174533fee28f0fa9139e5d71bf22b25a6b175f8abccc","src/lib.rs":"a359fe67a2d3a8bfe27219b35992c0ed390a65a409c69db75e3bf7e63fd16dde","src/macros.rs":"3d695a51f0a07f9f719dcb5620012c21a1b084c06a6283349cabf574ceba8123","src/private/de.rs":"a85efe9af4f5629ac7d946af56e20fbc184df6ac40a6cfe47bf3997a95b2ea20","src/private/doc.rs":"e9801a43c3088fccd5f1fac76416698f948e65b647024aa9da17d673e1e8c217","src/private/mod.rs":"37b204775e572396515477b393ce793b2579de48e5971e6f596ba3723c489fd6","src/private/ser.rs":"57fbff98429e870da86edcf61c0831caaa3b708c0c32e3038c4b2179e8dff73e","src/private/size_hint.rs":"605521227e9ba3100fbb9d5ea7fd5853385097c35015ce6908bd5f1ea20d59ad","src/ser/fmt.rs":"7827ed07fd8897e6324f75625ba0c926a4c4e7ec2914cd067391ce54d942ac7b","src/ser/impls.rs":"8cbe2b66ae950cbc5223e41ac82194cccfc2c26300acfe6328e5f20081f23af3","src/ser/impossible.rs":"db17913522c1c27389c5a085113911353b9813c1b116518681362e7c8b692c3a","src/ser/mod.rs":"e1e6c764837c70b6410dcf1949a0dae1b4b4ffce65b87607d3d173b612e9bccf","src/std_error.rs":"3aac687856c035517fae44ed2906dd4a1e3184bae4bf613adcdeb73f74126c57"},"package":"bb7d1f0d3021d347a83e556fc4683dea2ea09d87bccdf88ff5c12545d89d5efb"} \ No newline at end of file
diff --git a/third_party/rust/serde/Cargo.toml b/third_party/rust/serde/Cargo.toml
new file mode 100644
index 0000000000..93acff3a2a
--- /dev/null
+++ b/third_party/rust/serde/Cargo.toml
@@ -0,0 +1,70 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+rust-version = "1.13"
+name = "serde"
+version = "1.0.152"
+authors = [
+ "Erick Tryzelaar <erick.tryzelaar@gmail.com>",
+ "David Tolnay <dtolnay@gmail.com>",
+]
+build = "build.rs"
+include = [
+ "build.rs",
+ "src/**/*.rs",
+ "crates-io.md",
+ "README.md",
+ "LICENSE-APACHE",
+ "LICENSE-MIT",
+]
+description = "A generic serialization/deserialization framework"
+homepage = "https://serde.rs"
+documentation = "https://docs.rs/serde"
+readme = "crates-io.md"
+keywords = [
+ "serde",
+ "serialization",
+ "no_std",
+]
+categories = [
+ "encoding",
+ "no-std",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/serde-rs/serde"
+
+[package.metadata.playground]
+features = [
+ "derive",
+ "rc",
+]
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+doc-scrape-examples = false
+
+[dependencies.serde_derive]
+version = "=1.0.152"
+optional = true
+
+[dev-dependencies.serde_derive]
+version = "1.0"
+
+[features]
+alloc = []
+default = ["std"]
+derive = ["serde_derive"]
+rc = []
+std = []
+unstable = []
diff --git a/third_party/rust/serde/LICENSE-APACHE b/third_party/rust/serde/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/serde/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/third_party/rust/serde/LICENSE-MIT b/third_party/rust/serde/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/third_party/rust/serde/LICENSE-MIT
@@ -0,0 +1,23 @@
+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.
diff --git a/third_party/rust/serde/README.md b/third_party/rust/serde/README.md
new file mode 100644
index 0000000000..c3f6575ef0
--- /dev/null
+++ b/third_party/rust/serde/README.md
@@ -0,0 +1,114 @@
+# Serde &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.13+]][Rust 1.13] [![serde_derive: rustc 1.31+]][Rust 1.31]
+
+[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master
+[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster
+[Latest Version]: https://img.shields.io/crates/v/serde.svg
+[crates.io]: https://crates.io/crates/serde
+[serde: rustc 1.13+]: https://img.shields.io/badge/serde-rustc_1.13+-lightgray.svg
+[serde_derive: rustc 1.31+]: https://img.shields.io/badge/serde_derive-rustc_1.31+-lightgray.svg
+[Rust 1.13]: https://blog.rust-lang.org/2016/11/10/Rust-1.13.html
+[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.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/derive.html)
+- [Examples](https://serde.rs/examples.html)
+- [API documentation](https://docs.rs/serde)
+- [Release notes](https://github.com/serde-rs/serde/releases)
+
+## Serde in action
+
+<details>
+<summary>
+Click to show Cargo.toml.
+<a href="https://play.rust-lang.org/?edition=2018&gist=72755f28f99afc95e01d63174b28c1f5" 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. The "derive" feature is only required when
+# using #[derive(Serialize, Deserialize)] to make Serde work with structs
+# and enums defined in your crate.
+serde = { version = "1.0", features = ["derive"] }
+
+# 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
+use serde::{Serialize, Deserialize};
+
+#[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 is one of the most widely used Rust libraries so any place that Rustaceans
+congregate will be able to help you out. For chat, consider trying the
+[#rust-questions] or [#rust-beginners] channels of the unofficial community
+Discord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or
+[#beginners] channels of the official Rust Project Discord (invite:
+<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
+asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
+[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
+[Discourse forum][discourse]. It's acceptable to file a support issue in this
+repo but they tend not to get as many eyes as any of the above and may get
+closed without a response after some time.
+
+[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
+[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
+[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
+[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
+[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
+[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
+[/r/rust]: https://www.reddit.com/r/rust
+[discourse]: https://users.rust-lang.org
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+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.
+</sub>
diff --git a/third_party/rust/serde/build.rs b/third_party/rust/serde/build.rs
new file mode 100644
index 0000000000..ccbddd273d
--- /dev/null
+++ b/third_party/rust/serde/build.rs
@@ -0,0 +1,146 @@
+use std::env;
+use std::process::Command;
+use std::str::{self, FromStr};
+
+// The rustc-cfg strings below are *not* public API. Please let us know by
+// opening a GitHub issue if your build environment requires some way to enable
+// these cfgs other than by executing our build script.
+fn main() {
+ println!("cargo:rerun-if-changed=build.rs");
+
+ let minor = match rustc_minor_version() {
+ Some(minor) => minor,
+ None => return,
+ };
+
+ let target = env::var("TARGET").unwrap();
+ let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
+
+ // std::collections::Bound was stabilized in Rust 1.17
+ // but it was moved to core::ops later in Rust 1.26:
+ // https://doc.rust-lang.org/core/ops/enum.Bound.html
+ if minor < 26 {
+ println!("cargo:rustc-cfg=no_ops_bound");
+ if minor < 17 {
+ println!("cargo:rustc-cfg=no_collections_bound");
+ }
+ }
+
+ // core::cmp::Reverse stabilized in Rust 1.19:
+ // https://doc.rust-lang.org/stable/core/cmp/struct.Reverse.html
+ if minor < 19 {
+ println!("cargo:rustc-cfg=no_core_reverse");
+ }
+
+ // CString::into_boxed_c_str and PathBuf::into_boxed_path stabilized in Rust 1.20:
+ // https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
+ // https://doc.rust-lang.org/std/path/struct.PathBuf.html#method.into_boxed_path
+ if minor < 20 {
+ println!("cargo:rustc-cfg=no_de_boxed_c_str");
+ println!("cargo:rustc-cfg=no_de_boxed_path");
+ }
+
+ // From<Box<T>> for Rc<T> / Arc<T> stabilized in Rust 1.21:
+ // https://doc.rust-lang.org/std/rc/struct.Rc.html#impl-From<Box<T>>
+ // https://doc.rust-lang.org/std/sync/struct.Arc.html#impl-From<Box<T>>
+ if minor < 21 {
+ println!("cargo:rustc-cfg=no_de_rc_dst");
+ }
+
+ // Duration available in core since Rust 1.25:
+ // https://blog.rust-lang.org/2018/03/29/Rust-1.25.html#library-stabilizations
+ if minor < 25 {
+ println!("cargo:rustc-cfg=no_core_duration");
+ }
+
+ // 128-bit integers stabilized in Rust 1.26:
+ // https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
+ //
+ // Disabled on Emscripten targets before Rust 1.40 since
+ // Emscripten did not support 128-bit integers until Rust 1.40
+ // (https://github.com/rust-lang/rust/pull/65251)
+ if minor < 26 || emscripten && minor < 40 {
+ println!("cargo:rustc-cfg=no_integer128");
+ }
+
+ // Inclusive ranges methods stabilized in Rust 1.27:
+ // https://github.com/rust-lang/rust/pull/50758
+ // Also Iterator::try_for_each:
+ // https://blog.rust-lang.org/2018/06/21/Rust-1.27.html#library-stabilizations
+ if minor < 27 {
+ println!("cargo:rustc-cfg=no_range_inclusive");
+ println!("cargo:rustc-cfg=no_iterator_try_fold");
+ }
+
+ // Non-zero integers stabilized in Rust 1.28:
+ // https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#library-stabilizations
+ if minor < 28 {
+ println!("cargo:rustc-cfg=no_num_nonzero");
+ }
+
+ // Current minimum supported version of serde_derive crate is Rust 1.31.
+ if minor < 31 {
+ println!("cargo:rustc-cfg=no_serde_derive");
+ }
+
+ // TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add
+ // stabilized in Rust 1.34:
+ // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto
+ // https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations
+ if minor < 34 {
+ println!("cargo:rustc-cfg=no_core_try_from");
+ println!("cargo:rustc-cfg=no_num_nonzero_signed");
+ println!("cargo:rustc-cfg=no_systemtime_checked_add");
+ println!("cargo:rustc-cfg=no_relaxed_trait_bounds");
+ }
+
+ // Support for #[cfg(target_has_atomic = "...")] stabilized in Rust 1.60.
+ if minor < 60 {
+ println!("cargo:rustc-cfg=no_target_has_atomic");
+ // Allowlist of archs that support std::sync::atomic module. This is
+ // based on rustc's compiler/rustc_target/src/spec/*.rs.
+ let has_atomic64 = target.starts_with("x86_64")
+ || target.starts_with("i686")
+ || target.starts_with("aarch64")
+ || target.starts_with("powerpc64")
+ || target.starts_with("sparc64")
+ || target.starts_with("mips64el")
+ || target.starts_with("riscv64");
+ let has_atomic32 = has_atomic64 || emscripten;
+ if minor < 34 || !has_atomic64 {
+ println!("cargo:rustc-cfg=no_std_atomic64");
+ }
+ if minor < 34 || !has_atomic32 {
+ println!("cargo:rustc-cfg=no_std_atomic");
+ }
+ }
+}
+
+fn rustc_minor_version() -> Option<u32> {
+ let rustc = match env::var_os("RUSTC") {
+ Some(rustc) => rustc,
+ None => return None,
+ };
+
+ let output = match Command::new(rustc).arg("--version").output() {
+ Ok(output) => output,
+ Err(_) => return None,
+ };
+
+ let version = match str::from_utf8(&output.stdout) {
+ Ok(version) => version,
+ Err(_) => return None,
+ };
+
+ let mut pieces = version.split('.');
+ if pieces.next() != Some("rustc 1") {
+ return None;
+ }
+
+ let next = match pieces.next() {
+ Some(next) => next,
+ None => return None,
+ };
+
+ u32::from_str(next).ok()
+}
diff --git a/third_party/rust/serde/crates-io.md b/third_party/rust/serde/crates-io.md
new file mode 100644
index 0000000000..6e0ec280cf
--- /dev/null
+++ b/third_party/rust/serde/crates-io.md
@@ -0,0 +1,65 @@
+<!-- Serde readme rendered on crates.io -->
+
+**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/derive.html)
+- [Examples](https://serde.rs/examples.html)
+- [API documentation](https://docs.rs/serde)
+- [Release notes](https://github.com/serde-rs/serde/releases)
+
+## Serde in action
+
+```rust
+use serde::{Serialize, Deserialize};
+
+#[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 is one of the most widely used Rust libraries so any place that Rustaceans
+congregate will be able to help you out. For chat, consider trying the
+[#rust-questions] or [#rust-beginners] channels of the unofficial community
+Discord (invite: <https://discord.gg/rust-lang-community>, the [#rust-usage] or
+[#beginners] channels of the official Rust Project Discord (invite:
+<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
+asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
+[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
+[Discourse forum][discourse]. It's acceptable to file a support issue in this
+repo but they tend not to get as many eyes as any of the above and may get
+closed without a response after some time.
+
+[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
+[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
+[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
+[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
+[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
+[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
+[/r/rust]: https://www.reddit.com/r/rust
+[discourse]: https://users.rust-lang.org
diff --git a/third_party/rust/serde/src/de/format.rs b/third_party/rust/serde/src/de/format.rs
new file mode 100644
index 0000000000..f14580b8d1
--- /dev/null
+++ b/third_party/rust/serde/src/de/format.rs
@@ -0,0 +1,30 @@
+use lib::fmt::{self, Write};
+use lib::str;
+
+pub(super) struct Buf<'a> {
+ bytes: &'a mut [u8],
+ offset: usize,
+}
+
+impl<'a> Buf<'a> {
+ pub fn new(bytes: &'a mut [u8]) -> Self {
+ Buf { bytes, offset: 0 }
+ }
+
+ pub fn as_str(&self) -> &str {
+ let slice = &self.bytes[..self.offset];
+ unsafe { str::from_utf8_unchecked(slice) }
+ }
+}
+
+impl<'a> Write for Buf<'a> {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ if self.offset + s.len() > self.bytes.len() {
+ Err(fmt::Error)
+ } else {
+ self.bytes[self.offset..self.offset + s.len()].copy_from_slice(s.as_bytes());
+ self.offset += s.len();
+ Ok(())
+ }
+ }
+}
diff --git a/third_party/rust/serde/src/de/ignored_any.rs b/third_party/rust/serde/src/de/ignored_any.rs
new file mode 100644
index 0000000000..9ed438e797
--- /dev/null
+++ b/third_party/rust/serde/src/de/ignored_any.rs
@@ -0,0 +1,243 @@
+use lib::*;
+
+use de::{
+ Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor,
+};
+
+/// An efficient way of discarding data from a deserializer.
+///
+/// Think of this like `serde_json::Value` in that it can be deserialized from
+/// any type, except that it does not store any information about the data that
+/// gets deserialized.
+///
+/// ```edition2018
+/// use std::fmt;
+/// use std::marker::PhantomData;
+///
+/// use serde::de::{
+/// self, Deserialize, DeserializeSeed, Deserializer, IgnoredAny, SeqAccess, Visitor,
+/// };
+///
+/// /// A seed that can be used to deserialize only the `n`th element of a sequence
+/// /// while efficiently discarding elements of any type before or after index `n`.
+/// ///
+/// /// For example to deserialize only the element at index 3:
+/// ///
+/// /// ```
+/// /// NthElement::new(3).deserialize(deserializer)
+/// /// ```
+/// pub struct NthElement<T> {
+/// n: usize,
+/// marker: PhantomData<T>,
+/// }
+///
+/// impl<T> NthElement<T> {
+/// pub fn new(n: usize) -> Self {
+/// NthElement {
+/// n: n,
+/// marker: PhantomData,
+/// }
+/// }
+/// }
+///
+/// impl<'de, T> Visitor<'de> for NthElement<T>
+/// 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>,
+/// {
+/// // 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));
+/// }
+/// }
+///
+/// // Deserialize the one we care about.
+/// let nth = match seq.next_element()? {
+/// Some(nth) => nth,
+/// None => {
+/// return Err(de::Error::invalid_length(self.n, &self));
+/// }
+/// };
+///
+/// // Skip over any remaining elements in the sequence after `n`.
+/// while let Some(IgnoredAny) = seq.next_element()? {
+/// // ignore
+/// }
+///
+/// Ok(nth)
+/// }
+/// }
+///
+/// impl<'de, T> DeserializeSeed<'de> for NthElement<T>
+/// where
+/// T: Deserialize<'de>,
+/// {
+/// type Value = T;
+///
+/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+/// where
+/// D: Deserializer<'de>,
+/// {
+/// deserializer.deserialize_seq(self)
+/// }
+/// }
+///
+/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error>
+/// # 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(())
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct IgnoredAny;
+
+impl<'de> Visitor<'de> for IgnoredAny {
+ type Value = IgnoredAny;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("anything at all")
+ }
+
+ #[inline]
+ fn visit_bool<E>(self, x: bool) -> Result<Self::Value, E> {
+ let _ = x;
+ Ok(IgnoredAny)
+ }
+
+ #[inline]
+ fn visit_i64<E>(self, x: i64) -> Result<Self::Value, E> {
+ let _ = x;
+ Ok(IgnoredAny)
+ }
+
+ serde_if_integer128! {
+ #[inline]
+ fn visit_i128<E>(self, x: i128) -> Result<Self::Value, E> {
+ let _ = x;
+ Ok(IgnoredAny)
+ }
+ }
+
+ #[inline]
+ fn visit_u64<E>(self, x: u64) -> Result<Self::Value, E> {
+ let _ = x;
+ Ok(IgnoredAny)
+ }
+
+ serde_if_integer128! {
+ #[inline]
+ fn visit_u128<E>(self, x: u128) -> Result<Self::Value, E> {
+ let _ = x;
+ Ok(IgnoredAny)
+ }
+ }
+
+ #[inline]
+ fn visit_f64<E>(self, x: f64) -> Result<Self::Value, E> {
+ let _ = x;
+ Ok(IgnoredAny)
+ }
+
+ #[inline]
+ fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let _ = s;
+ Ok(IgnoredAny)
+ }
+
+ #[inline]
+ fn visit_none<E>(self) -> Result<Self::Value, E> {
+ Ok(IgnoredAny)
+ }
+
+ #[inline]
+ fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ IgnoredAny::deserialize(deserializer)
+ }
+
+ #[inline]
+ fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ IgnoredAny::deserialize(deserializer)
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<Self::Value, E> {
+ Ok(IgnoredAny)
+ }
+
+ #[inline]
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ while let Some(IgnoredAny) = try!(seq.next_element()) {
+ // Gobble
+ }
+ Ok(IgnoredAny)
+ }
+
+ #[inline]
+ fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ while let Some((IgnoredAny, IgnoredAny)) = try!(map.next_entry()) {
+ // Gobble
+ }
+ Ok(IgnoredAny)
+ }
+
+ #[inline]
+ fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let _ = bytes;
+ Ok(IgnoredAny)
+ }
+
+ fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
+ where
+ A: EnumAccess<'de>,
+ {
+ try!(data.variant::<IgnoredAny>()).1.newtype_variant()
+ }
+}
+
+impl<'de> Deserialize<'de> for IgnoredAny {
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<IgnoredAny, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_ignored_any(IgnoredAny)
+ }
+}
diff --git a/third_party/rust/serde/src/de/impls.rs b/third_party/rust/serde/src/de/impls.rs
new file mode 100644
index 0000000000..a257d9e2f4
--- /dev/null
+++ b/third_party/rust/serde/src/de/impls.rs
@@ -0,0 +1,2733 @@
+use lib::*;
+
+use de::{
+ Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor,
+};
+
+#[cfg(any(feature = "std", feature = "alloc", not(no_core_duration)))]
+use de::MapAccess;
+
+use seed::InPlaceSeed;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+use __private::size_hint;
+
+////////////////////////////////////////////////////////////////////////////////
+
+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<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(())
+ }
+}
+
+impl<'de> Deserialize<'de> for () {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_unit(UnitVisitor)
+ }
+}
+
+#[cfg(feature = "unstable")]
+impl<'de> Deserialize<'de> for ! {
+ fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Err(Error::custom("cannot deserialize `!`"))
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+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<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v)
+ }
+}
+
+impl<'de> Deserialize<'de> for bool {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_bool(BoolVisitor)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+macro_rules! impl_deserialize_num {
+ ($primitive:ident, $nonzero:ident $(cfg($($cfg:tt)*))*, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
+ impl_deserialize_num!($primitive, $deserialize $($method!($($val : $visit)*);)*);
+
+ #[cfg(all(not(no_num_nonzero), $($($cfg)*)*))]
+ impl<'de> Deserialize<'de> for num::$nonzero {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct NonZeroVisitor;
+
+ impl<'de> Visitor<'de> for NonZeroVisitor {
+ type Value = num::$nonzero;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(concat!("a nonzero ", stringify!($primitive)))
+ }
+
+ $($($method!(nonzero $primitive $val : $visit);)*)*
+ }
+
+ deserializer.$deserialize(NonZeroVisitor)
+ }
+ }
+ };
+
+ ($primitive:ident, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
+ impl<'de> Deserialize<'de> for $primitive {
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct PrimitiveVisitor;
+
+ impl<'de> Visitor<'de> for PrimitiveVisitor {
+ type Value = $primitive;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(stringify!($primitive))
+ }
+
+ $($($method!($val : $visit);)*)*
+ }
+
+ deserializer.$deserialize(PrimitiveVisitor)
+ }
+ }
+ };
+}
+
+macro_rules! num_self {
+ ($ty:ident : $visit:ident) => {
+ #[inline]
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v)
+ }
+ };
+
+ (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ if let Some(nonzero) = Self::Value::new(v) {
+ Ok(nonzero)
+ } else {
+ Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
+ }
+ }
+ };
+}
+
+macro_rules! num_as_self {
+ ($ty:ident : $visit:ident) => {
+ #[inline]
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v as Self::Value)
+ }
+ };
+
+ (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ if let Some(nonzero) = Self::Value::new(v as $primitive) {
+ Ok(nonzero)
+ } else {
+ Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
+ }
+ }
+ };
+}
+
+macro_rules! int_to_int {
+ ($ty:ident : $visit:ident) => {
+ #[inline]
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ if Self::Value::min_value() as i64 <= v as i64
+ && v as i64 <= Self::Value::max_value() as i64
+ {
+ Ok(v as Self::Value)
+ } else {
+ Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
+ }
+ }
+ };
+
+ (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ if $primitive::min_value() as i64 <= v as i64
+ && v as i64 <= $primitive::max_value() as i64
+ {
+ if let Some(nonzero) = Self::Value::new(v as $primitive) {
+ return Ok(nonzero);
+ }
+ }
+ Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
+ }
+ };
+}
+
+macro_rules! int_to_uint {
+ ($ty:ident : $visit:ident) => {
+ #[inline]
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ if 0 <= v && v as u64 <= Self::Value::max_value() as u64 {
+ Ok(v as Self::Value)
+ } else {
+ Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
+ }
+ }
+ };
+
+ (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ if 0 < v && v as u64 <= $primitive::max_value() as u64 {
+ if let Some(nonzero) = Self::Value::new(v as $primitive) {
+ return Ok(nonzero);
+ }
+ }
+ Err(Error::invalid_value(Unexpected::Signed(v as i64), &self))
+ }
+ };
+}
+
+macro_rules! uint_to_self {
+ ($ty:ident : $visit:ident) => {
+ #[inline]
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ if v as u64 <= Self::Value::max_value() as u64 {
+ Ok(v as Self::Value)
+ } else {
+ Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
+ }
+ }
+ };
+
+ (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ if v as u64 <= $primitive::max_value() as u64 {
+ if let Some(nonzero) = Self::Value::new(v as $primitive) {
+ return Ok(nonzero);
+ }
+ }
+ Err(Error::invalid_value(Unexpected::Unsigned(v as u64), &self))
+ }
+ };
+}
+
+impl_deserialize_num! {
+ i8, NonZeroI8 cfg(not(no_num_nonzero_signed)), deserialize_i8
+ num_self!(i8:visit_i8);
+ int_to_int!(i16:visit_i16 i32:visit_i32 i64:visit_i64);
+ uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
+}
+
+impl_deserialize_num! {
+ i16, NonZeroI16 cfg(not(no_num_nonzero_signed)), deserialize_i16
+ num_self!(i16:visit_i16);
+ num_as_self!(i8:visit_i8);
+ int_to_int!(i32:visit_i32 i64:visit_i64);
+ uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
+}
+
+impl_deserialize_num! {
+ i32, NonZeroI32 cfg(not(no_num_nonzero_signed)), deserialize_i32
+ num_self!(i32:visit_i32);
+ num_as_self!(i8:visit_i8 i16:visit_i16);
+ int_to_int!(i64:visit_i64);
+ uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
+}
+
+impl_deserialize_num! {
+ i64, NonZeroI64 cfg(not(no_num_nonzero_signed)), deserialize_i64
+ num_self!(i64:visit_i64);
+ num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32);
+ uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
+}
+
+impl_deserialize_num! {
+ isize, NonZeroIsize cfg(not(no_num_nonzero_signed)), deserialize_i64
+ num_as_self!(i8:visit_i8 i16:visit_i16);
+ int_to_int!(i32:visit_i32 i64:visit_i64);
+ uint_to_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
+}
+
+impl_deserialize_num! {
+ u8, NonZeroU8, deserialize_u8
+ num_self!(u8:visit_u8);
+ int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
+ uint_to_self!(u16:visit_u16 u32:visit_u32 u64:visit_u64);
+}
+
+impl_deserialize_num! {
+ u16, NonZeroU16, deserialize_u16
+ num_self!(u16:visit_u16);
+ num_as_self!(u8:visit_u8);
+ int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
+ uint_to_self!(u32:visit_u32 u64:visit_u64);
+}
+
+impl_deserialize_num! {
+ u32, NonZeroU32, deserialize_u32
+ num_self!(u32:visit_u32);
+ num_as_self!(u8:visit_u8 u16:visit_u16);
+ int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
+ uint_to_self!(u64:visit_u64);
+}
+
+impl_deserialize_num! {
+ u64, NonZeroU64, deserialize_u64
+ num_self!(u64:visit_u64);
+ num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32);
+ int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
+}
+
+impl_deserialize_num! {
+ usize, NonZeroUsize, deserialize_u64
+ num_as_self!(u8:visit_u8 u16:visit_u16);
+ int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
+ uint_to_self!(u32:visit_u32 u64:visit_u64);
+}
+
+impl_deserialize_num! {
+ f32, deserialize_f32
+ num_self!(f32:visit_f32);
+ num_as_self!(f64:visit_f64);
+ num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
+ num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
+}
+
+impl_deserialize_num! {
+ f64, deserialize_f64
+ num_self!(f64:visit_f64);
+ num_as_self!(f32:visit_f32);
+ num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
+ num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
+}
+
+serde_if_integer128! {
+ macro_rules! num_128 {
+ ($ty:ident : $visit:ident) => {
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ if v as i128 >= Self::Value::min_value() as i128
+ && v as u128 <= Self::Value::max_value() as u128
+ {
+ Ok(v as Self::Value)
+ } else {
+ Err(Error::invalid_value(
+ Unexpected::Other(stringify!($ty)),
+ &self,
+ ))
+ }
+ }
+ };
+
+ (nonzero $primitive:ident $ty:ident : $visit:ident) => {
+ fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ if v as i128 >= $primitive::min_value() as i128
+ && v as u128 <= $primitive::max_value() as u128
+ {
+ if let Some(nonzero) = Self::Value::new(v as $primitive) {
+ Ok(nonzero)
+ } else {
+ Err(Error::invalid_value(Unexpected::Unsigned(0), &self))
+ }
+ } else {
+ Err(Error::invalid_value(
+ Unexpected::Other(stringify!($ty)),
+ &self,
+ ))
+ }
+ }
+ };
+ }
+
+ impl_deserialize_num! {
+ i128, NonZeroI128 cfg(not(no_num_nonzero_signed)), deserialize_i128
+ num_self!(i128:visit_i128);
+ num_as_self!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
+ num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
+ num_128!(u128:visit_u128);
+ }
+
+ impl_deserialize_num! {
+ u128, NonZeroU128, deserialize_u128
+ num_self!(u128:visit_u128);
+ num_as_self!(u8:visit_u8 u16:visit_u16 u32:visit_u32 u64:visit_u64);
+ int_to_uint!(i8:visit_i8 i16:visit_i16 i32:visit_i32 i64:visit_i64);
+ num_128!(i128:visit_i128);
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+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<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v)
+ }
+
+ #[inline]
+ 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<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_char(CharVisitor)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+struct StringVisitor;
+#[cfg(any(feature = "std", feature = "alloc"))]
+struct StringInPlaceVisitor<'a>(&'a mut String);
+
+#[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<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v.to_owned())
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v)
+ }
+
+ 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<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,
+ )),
+ }
+ }
+}
+
+#[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<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.0.clear();
+ self.0.push_str(v);
+ Ok(())
+ }
+
+ 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<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<Self::Value, E>
+ where
+ E: Error,
+ {
+ match String::from_utf8(v) {
+ Ok(s) => {
+ *self.0 = s;
+ Ok(())
+ }
+ Err(e) => Err(Error::invalid_value(
+ Unexpected::Bytes(&e.into_bytes()),
+ &self,
+ )),
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de> Deserialize<'de> for String {
+ 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
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_string(StringInPlaceVisitor(place))
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct StrVisitor;
+
+impl<'a> Visitor<'a> for StrVisitor {
+ type Value = &'a str;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a borrowed string")
+ }
+
+ fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v) // so easy
+ }
+
+ fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ str::from_utf8(v).map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self))
+ }
+}
+
+impl<'de: 'a, 'a> Deserialize<'de> for &'a str {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_str(StrVisitor)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct BytesVisitor;
+
+impl<'a> Visitor<'a> for BytesVisitor {
+ type Value = &'a [u8];
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a borrowed byte array")
+ }
+
+ fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v)
+ }
+
+ fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v.as_bytes())
+ }
+}
+
+impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_bytes(BytesVisitor)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+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<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<Self::Value, E>
+ where
+ E: Error,
+ {
+ CString::new(v).map_err(Error::custom)
+ }
+
+ 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<Self::Value, E>
+ where
+ E: Error,
+ {
+ CString::new(v).map_err(Error::custom)
+ }
+
+ 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<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_byte_buf(CStringVisitor)
+ }
+}
+
+macro_rules! forwarded_impl {
+ (
+ $(#[doc = $doc:tt])*
+ ($($id:ident),*), $ty:ty, $func:expr
+ ) => {
+ $(#[doc = $doc])*
+ impl<'de $(, $id : Deserialize<'de>,)*> Deserialize<'de> for $ty {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer).map($func)
+ }
+ }
+ }
+}
+
+#[cfg(all(feature = "std", not(no_de_boxed_c_str)))]
+forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
+
+#[cfg(not(no_core_reverse))]
+forwarded_impl!((T), Reverse<T>, Reverse);
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct OptionVisitor<T> {
+ marker: PhantomData<T>,
+}
+
+impl<'de, T> Visitor<'de> for OptionVisitor<T>
+where
+ T: Deserialize<'de>,
+{
+ type Value = Option<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("option")
+ }
+
+ #[inline]
+ 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_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ T::deserialize(deserializer).map(Some)
+ }
+
+ 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<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_option(OptionVisitor {
+ marker: PhantomData,
+ })
+ }
+
+ // The Some variant's repr is opaque, so we can't play cute tricks with its
+ // tag to have deserialize_in_place build the content in place unconditionally.
+ //
+ // FIXME: investigate whether branching on the old value being Some to
+ // deserialize_in_place the value is profitable (probably data-dependent?)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct PhantomDataVisitor<T: ?Sized> {
+ marker: PhantomData<T>,
+}
+
+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<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(PhantomData)
+ }
+}
+
+impl<'de, T: ?Sized> Deserialize<'de> for PhantomData<T> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let visitor = PhantomDataVisitor {
+ marker: PhantomData,
+ };
+ deserializer.deserialize_unit_struct("PhantomData", visitor)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+macro_rules! seq_impl {
+ (
+ $ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)*>,
+ $access:ident,
+ $clear:expr,
+ $with_capacity:expr,
+ $reserve:expr,
+ $insert:expr
+ ) => {
+ impl<'de, T $(, $typaram)*> Deserialize<'de> for $ty<T $(, $typaram)*>
+ where
+ T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*,
+ $($typaram: $bound1 $(+ $bound2)*,)*
+ {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct SeqVisitor<T $(, $typaram)*> {
+ marker: PhantomData<$ty<T $(, $typaram)*>>,
+ }
+
+ impl<'de, T $(, $typaram)*> Visitor<'de> for SeqVisitor<T $(, $typaram)*>
+ where
+ T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*,
+ $($typaram: $bound1 $(+ $bound2)*,)*
+ {
+ type Value = $ty<T $(, $typaram)*>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ #[inline]
+ fn visit_seq<A>(self, mut $access: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut values = $with_capacity;
+
+ while let Some(value) = try!($access.next_element()) {
+ $insert(&mut values, value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = SeqVisitor { marker: PhantomData };
+ deserializer.deserialize_seq(visitor)
+ }
+
+ fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct SeqInPlaceVisitor<'a, T: 'a $(, $typaram: 'a)*>(&'a mut $ty<T $(, $typaram)*>);
+
+ impl<'a, 'de, T $(, $typaram)*> Visitor<'de> for SeqInPlaceVisitor<'a, T $(, $typaram)*>
+ where
+ T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*,
+ $($typaram: $bound1 $(+ $bound2)*,)*
+ {
+ 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<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()) {
+ $insert(&mut self.0, value);
+ }
+
+ Ok(())
+ }
+ }
+
+ deserializer.deserialize_seq(SeqInPlaceVisitor(place))
+ }
+ }
+ }
+}
+
+// Dummy impl of reserve
+#[cfg(any(feature = "std", feature = "alloc"))]
+fn nop_reserve<T>(_seq: T, _n: usize) {}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+seq_impl!(
+ BinaryHeap<T: Ord>,
+ seq,
+ BinaryHeap::clear,
+ BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
+ BinaryHeap::reserve,
+ BinaryHeap::push
+);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+seq_impl!(
+ BTreeSet<T: Eq + Ord>,
+ seq,
+ BTreeSet::clear,
+ BTreeSet::new(),
+ nop_reserve,
+ BTreeSet::insert
+);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+seq_impl!(
+ LinkedList<T>,
+ seq,
+ LinkedList::clear,
+ LinkedList::new(),
+ nop_reserve,
+ LinkedList::push_back
+);
+
+#[cfg(feature = "std")]
+seq_impl!(
+ HashSet<T: Eq + Hash, S: BuildHasher + Default>,
+ seq,
+ HashSet::clear,
+ HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
+ HashSet::reserve,
+ HashSet::insert);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+seq_impl!(
+ VecDeque<T>,
+ seq,
+ VecDeque::clear,
+ VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
+ VecDeque::reserve,
+ VecDeque::push_back
+);
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de, T> Deserialize<'de> for Vec<T>
+where
+ T: Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct VecVisitor<T> {
+ marker: PhantomData<T>,
+ }
+
+ impl<'de, T> Visitor<'de> for VecVisitor<T>
+ where
+ T: Deserialize<'de>,
+ {
+ type Value = Vec<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut values = Vec::with_capacity(size_hint::cautious(seq.size_hint()));
+
+ while let Some(value) = try!(seq.next_element()) {
+ values.push(value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = VecVisitor {
+ marker: PhantomData,
+ };
+ deserializer.deserialize_seq(visitor)
+ }
+
+ fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct VecInPlaceVisitor<'a, T: 'a>(&'a mut Vec<T>);
+
+ impl<'a, 'de, T> Visitor<'de> for VecInPlaceVisitor<'a, T>
+ where
+ T: Deserialize<'de>,
+ {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let hint = size_hint::cautious(seq.size_hint());
+ if let Some(additional) = hint.checked_sub(self.0.len()) {
+ self.0.reserve(additional);
+ }
+
+ for i in 0..self.0.len() {
+ let next = {
+ let next_place = InPlaceSeed(&mut self.0[i]);
+ try!(seq.next_element_seed(next_place))
+ };
+ if next.is_none() {
+ self.0.truncate(i);
+ return Ok(());
+ }
+ }
+
+ while let Some(value) = try!(seq.next_element()) {
+ self.0.push(value);
+ }
+
+ Ok(())
+ }
+ }
+
+ deserializer.deserialize_seq(VecInPlaceVisitor(place))
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+struct ArrayVisitor<A> {
+ marker: PhantomData<A>,
+}
+struct ArrayInPlaceVisitor<'a, A: 'a>(&'a mut A);
+
+impl<A> ArrayVisitor<A> {
+ fn new() -> Self {
+ ArrayVisitor {
+ marker: PhantomData,
+ }
+ }
+}
+
+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<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<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_tuple(0, ArrayVisitor::<[T; 0]>::new())
+ }
+}
+
+macro_rules! array_impls {
+ ($($len:expr => ($($n:tt)+))+) => {
+ $(
+ impl<'de, T> Visitor<'de> for ArrayVisitor<[T; $len]>
+ where
+ T: Deserialize<'de>,
+ {
+ 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<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ Ok([$(
+ match try!(seq.next_element()) {
+ Some(val) => val,
+ None => return Err(Error::invalid_length($n, &self)),
+ }
+ ),+])
+ }
+ }
+
+ impl<'a, 'de, T> Visitor<'de> for ArrayInPlaceVisitor<'a, [T; $len]>
+ where
+ T: Deserialize<'de>,
+ {
+ 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<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;
+ }
+ }
+ if let Some(idx) = fail_idx {
+ return Err(Error::invalid_length(idx, &self));
+ }
+ Ok(())
+ }
+ }
+
+ impl<'de, T> Deserialize<'de> for [T; $len]
+ where
+ T: Deserialize<'de>,
+ {
+ 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
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_tuple($len, ArrayInPlaceVisitor(place))
+ }
+ }
+ )+
+ }
+}
+
+array_impls! {
+ 1 => (0)
+ 2 => (0 1)
+ 3 => (0 1 2)
+ 4 => (0 1 2 3)
+ 5 => (0 1 2 3 4)
+ 6 => (0 1 2 3 4 5)
+ 7 => (0 1 2 3 4 5 6)
+ 8 => (0 1 2 3 4 5 6 7)
+ 9 => (0 1 2 3 4 5 6 7 8)
+ 10 => (0 1 2 3 4 5 6 7 8 9)
+ 11 => (0 1 2 3 4 5 6 7 8 9 10)
+ 12 => (0 1 2 3 4 5 6 7 8 9 10 11)
+ 13 => (0 1 2 3 4 5 6 7 8 9 10 11 12)
+ 14 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13)
+ 15 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14)
+ 16 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
+ 17 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)
+ 18 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17)
+ 19 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18)
+ 20 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
+ 21 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)
+ 22 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21)
+ 23 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22)
+ 24 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23)
+ 25 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24)
+ 26 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25)
+ 27 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26)
+ 28 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27)
+ 29 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28)
+ 30 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29)
+ 31 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30)
+ 32 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+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<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<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)),
+ };
+ )+
+
+ Ok(($($name,)+))
+ }
+ }
+
+ deserializer.deserialize_tuple($len, TupleVisitor { marker: PhantomData })
+ }
+
+ #[inline]
+ fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct TupleInPlaceVisitor<'a, $($name: 'a,)+>(&'a mut ($($name,)+));
+
+ impl<'a, 'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleInPlaceVisitor<'a, $($name,)+> {
+ 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<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));
+ }
+ )+
+
+ Ok(())
+ }
+ }
+
+ deserializer.deserialize_tuple($len, TupleInPlaceVisitor(place))
+ }
+ }
+ )+
+ }
+}
+
+tuple_impls! {
+ 1 => (0 T0)
+ 2 => (0 T0 1 T1)
+ 3 => (0 T0 1 T1 2 T2)
+ 4 => (0 T0 1 T1 2 T2 3 T3)
+ 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
+ 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
+ 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
+ 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
+ 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
+ 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
+ 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
+ 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
+ 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
+ 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
+ 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
+ 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+macro_rules! map_impl {
+ (
+ $ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)*>,
+ $access:ident,
+ $with_capacity:expr
+ ) => {
+ impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty<K, V $(, $typaram)*>
+ where
+ K: Deserialize<'de> $(+ $kbound1 $(+ $kbound2)*)*,
+ V: Deserialize<'de>,
+ $($typaram: $bound1 $(+ $bound2)*),*
+ {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct MapVisitor<K, V $(, $typaram)*> {
+ marker: PhantomData<$ty<K, V $(, $typaram)*>>,
+ }
+
+ impl<'de, K, V $(, $typaram)*> Visitor<'de> for MapVisitor<K, V $(, $typaram)*>
+ where
+ K: Deserialize<'de> $(+ $kbound1 $(+ $kbound2)*)*,
+ V: Deserialize<'de>,
+ $($typaram: $bound1 $(+ $bound2)*),*
+ {
+ type Value = $ty<K, V $(, $typaram)*>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a map")
+ }
+
+ #[inline]
+ fn visit_map<A>(self, mut $access: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let mut values = $with_capacity;
+
+ while let Some((key, value)) = try!($access.next_entry()) {
+ values.insert(key, value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = MapVisitor { marker: PhantomData };
+ deserializer.deserialize_map(visitor)
+ }
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+map_impl!(
+ BTreeMap<K: Ord, V>,
+ map,
+ BTreeMap::new());
+
+#[cfg(feature = "std")]
+map_impl!(
+ HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
+ map,
+ HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+macro_rules! parse_ip_impl {
+ ($expecting:tt $ty:ty; $size:tt) => {
+ impl<'de> Deserialize<'de> for $ty {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ if deserializer.is_human_readable() {
+ deserializer.deserialize_str(FromStrVisitor::new($expecting))
+ } else {
+ <[u8; $size]>::deserialize(deserializer).map(<$ty>::from)
+ }
+ }
+ }
+ };
+}
+
+#[cfg(feature = "std")]
+macro_rules! variant_identifier {
+ (
+ $name_kind:ident ($($variant:ident; $bytes:expr; $index:expr),*)
+ $expecting_message:expr,
+ $variants_name:ident
+ ) => {
+ enum $name_kind {
+ $($variant),*
+ }
+
+ static $variants_name: &'static [&'static str] = &[$(stringify!($variant)),*];
+
+ impl<'de> Deserialize<'de> for $name_kind {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct KindVisitor;
+
+ impl<'de> Visitor<'de> for KindVisitor {
+ type Value = $name_kind;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str($expecting_message)
+ }
+
+ fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ $(
+ $index => Ok($name_kind :: $variant),
+ )*
+ _ => Err(Error::invalid_value(Unexpected::Unsigned(value), &self),),
+ }
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ $(
+ stringify!($variant) => Ok($name_kind :: $variant),
+ )*
+ _ => Err(Error::unknown_variant(value, $variants_name)),
+ }
+ }
+
+ fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ $(
+ $bytes => Ok($name_kind :: $variant),
+ )*
+ _ => {
+ match str::from_utf8(value) {
+ Ok(value) => Err(Error::unknown_variant(value, $variants_name)),
+ Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)),
+ }
+ }
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(KindVisitor)
+ }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+macro_rules! deserialize_enum {
+ (
+ $name:ident $name_kind:ident ($($variant:ident; $bytes:expr; $index:expr),*)
+ $expecting_message:expr,
+ $deserializer:expr
+ ) => {
+ variant_identifier! {
+ $name_kind ($($variant; $bytes; $index),*)
+ $expecting_message,
+ VARIANTS
+ }
+
+ struct EnumVisitor;
+ impl<'de> Visitor<'de> for EnumVisitor {
+ type Value = $name;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(concat!("a ", stringify!($name)))
+ }
+
+
+ fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
+ where
+ A: EnumAccess<'de>,
+ {
+ match try!(data.variant()) {
+ $(
+ ($name_kind :: $variant, v) => v.newtype_variant().map($name :: $variant),
+ )*
+ }
+ }
+ }
+ $deserializer.deserialize_enum(stringify!($name), VARIANTS, EnumVisitor)
+ }
+}
+
+#[cfg(feature = "std")]
+impl<'de> Deserialize<'de> for net::IpAddr {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ if deserializer.is_human_readable() {
+ deserializer.deserialize_str(FromStrVisitor::new("IP address"))
+ } else {
+ use lib::net::IpAddr;
+ deserialize_enum! {
+ IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
+ "`V4` or `V6`",
+ deserializer
+ }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+parse_ip_impl!("IPv4 address" net::Ipv4Addr; 4);
+
+#[cfg(feature = "std")]
+parse_ip_impl!("IPv6 address" net::Ipv6Addr; 16);
+
+#[cfg(feature = "std")]
+macro_rules! parse_socket_impl {
+ ($expecting:tt $ty:ty, $new:expr) => {
+ impl<'de> Deserialize<'de> for $ty {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ if deserializer.is_human_readable() {
+ deserializer.deserialize_str(FromStrVisitor::new($expecting))
+ } else {
+ <(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port))
+ }
+ }
+ }
+ };
+}
+
+#[cfg(feature = "std")]
+impl<'de> Deserialize<'de> for net::SocketAddr {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ if deserializer.is_human_readable() {
+ deserializer.deserialize_str(FromStrVisitor::new("socket address"))
+ } else {
+ use lib::net::SocketAddr;
+ deserialize_enum! {
+ SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
+ "`V4` or `V6`",
+ deserializer
+ }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+parse_socket_impl!("IPv4 socket address" net::SocketAddrV4, net::SocketAddrV4::new);
+
+#[cfg(feature = "std")]
+parse_socket_impl!("IPv6 socket address" net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(
+ ip, port, 0, 0
+));
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+struct PathVisitor;
+
+#[cfg(feature = "std")]
+impl<'a> Visitor<'a> for PathVisitor {
+ type Value = &'a Path;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a borrowed path")
+ }
+
+ fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v.as_ref())
+ }
+
+ fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ str::from_utf8(v)
+ .map(AsRef::as_ref)
+ .map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self))
+ }
+}
+
+#[cfg(feature = "std")]
+impl<'de: 'a, 'a> Deserialize<'de> for &'a Path {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_str(PathVisitor)
+ }
+}
+
+#[cfg(feature = "std")]
+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<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(From::from(v))
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(From::from(v))
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ str::from_utf8(v)
+ .map(From::from)
+ .map_err(|_| Error::invalid_value(Unexpected::Bytes(v), &self))
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ String::from_utf8(v)
+ .map(From::from)
+ .map_err(|e| Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self))
+ }
+}
+
+#[cfg(feature = "std")]
+impl<'de> Deserialize<'de> for PathBuf {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_string(PathBufVisitor)
+ }
+}
+
+#[cfg(all(feature = "std", not(no_de_boxed_path)))]
+forwarded_impl!((), Box<Path>, PathBuf::into_boxed_path);
+
+////////////////////////////////////////////////////////////////////////////////
+
+// If this were outside of the serde crate, it would just use:
+//
+// #[derive(Deserialize)]
+// #[serde(variant_identifier)]
+#[cfg(all(feature = "std", any(unix, windows)))]
+variant_identifier! {
+ OsStringKind (Unix; b"Unix"; 0, Windows; b"Windows"; 1)
+ "`Unix` or `Windows`",
+ OSSTR_VARIANTS
+}
+
+#[cfg(all(feature = "std", any(unix, windows)))]
+struct OsStringVisitor;
+
+#[cfg(all(feature = "std", any(unix, windows)))]
+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<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<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)),
+ (OsStringKind::Unix, _) => Err(Error::custom(
+ "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<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_enum("OsString", OSSTR_VARIANTS, OsStringVisitor)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+forwarded_impl!((T), Box<T>, Box::new);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+forwarded_impl!((), Box<str>, String::into_boxed_str);
+
+#[cfg(all(no_de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
+forwarded_impl! {
+ /// This impl requires the [`"rc"`] Cargo feature of Serde.
+ ///
+ /// Deserializing a data structure containing `Arc` will not attempt to
+ /// deduplicate `Arc` references to the same data. Every deserialized `Arc`
+ /// will end up with a strong count of 1.
+ ///
+ /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
+ (T), Arc<T>, Arc::new
+}
+
+#[cfg(all(no_de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
+forwarded_impl! {
+ /// This impl requires the [`"rc"`] Cargo feature of Serde.
+ ///
+ /// Deserializing a data structure containing `Rc` will not attempt to
+ /// deduplicate `Rc` references to the same data. Every deserialized `Rc`
+ /// will end up with a strong count of 1.
+ ///
+ /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
+ (T), Rc<T>, Rc::new
+}
+
+#[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<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(
+ not(no_de_rc_dst),
+ 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>
+ where
+ Box<T>: Deserialize<'de>,
+ {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Box::deserialize(deserializer).map(Into::into)
+ }
+ }
+ };
+}
+
+#[cfg(all(
+ not(no_de_rc_dst),
+ feature = "rc",
+ any(feature = "std", feature = "alloc")
+))]
+box_forwarded_impl! {
+ /// This impl requires the [`"rc"`] Cargo feature of Serde.
+ ///
+ /// Deserializing a data structure containing `Rc` will not attempt to
+ /// deduplicate `Rc` references to the same data. Every deserialized `Rc`
+ /// will end up with a strong count of 1.
+ ///
+ /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
+ Rc
+}
+
+#[cfg(all(
+ not(no_de_rc_dst),
+ feature = "rc",
+ any(feature = "std", feature = "alloc")
+))]
+box_forwarded_impl! {
+ /// This impl requires the [`"rc"`] Cargo feature of Serde.
+ ///
+ /// Deserializing a data structure containing `Arc` will not attempt to
+ /// deduplicate `Arc` references to the same data. Every deserialized `Arc`
+ /// will end up with a strong count of 1.
+ ///
+ /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
+ Arc
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl<'de, T> Deserialize<'de> for Cell<T>
+where
+ T: Deserialize<'de> + Copy,
+{
+ 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);
+
+#[cfg(feature = "std")]
+forwarded_impl!((T), Mutex<T>, Mutex::new);
+
+#[cfg(feature = "std")]
+forwarded_impl!((T), RwLock<T>, RwLock::new);
+
+////////////////////////////////////////////////////////////////////////////////
+
+// This is a cleaned-up version of the impl generated by:
+//
+// #[derive(Deserialize)]
+// #[serde(deny_unknown_fields)]
+// struct Duration {
+// secs: u64,
+// nanos: u32,
+// }
+#[cfg(any(feature = "std", not(no_core_duration)))]
+impl<'de> Deserialize<'de> for Duration {
+ 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(field_identifier, rename_all = "lowercase")]
+ enum Field {
+ Secs,
+ Nanos,
+ }
+
+ impl<'de> Deserialize<'de> for Field {
+ 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<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<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ b"secs" => Ok(Field::Secs),
+ b"nanos" => Ok(Field::Nanos),
+ _ => {
+ let value = ::__private::from_utf8_lossy(value);
+ Err(Error::unknown_field(&*value, FIELDS))
+ }
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(FieldVisitor)
+ }
+ }
+
+ fn check_overflow<E>(secs: u64, nanos: u32) -> Result<(), E>
+ where
+ E: Error,
+ {
+ static NANOS_PER_SEC: u32 = 1_000_000_000;
+ match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
+ Some(_) => Ok(()),
+ None => Err(E::custom("overflow deserializing Duration")),
+ }
+ }
+
+ struct DurationVisitor;
+
+ 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<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));
+ }
+ };
+ let nanos: u32 = match try!(seq.next_element()) {
+ Some(value) => value,
+ None => {
+ return Err(Error::invalid_length(1, &self));
+ }
+ };
+ try!(check_overflow(secs, nanos));
+ Ok(Duration::new(secs, nanos))
+ }
+
+ 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 => {
+ if secs.is_some() {
+ return Err(<A::Error as Error>::duplicate_field("secs"));
+ }
+ secs = Some(try!(map.next_value()));
+ }
+ Field::Nanos => {
+ if nanos.is_some() {
+ return Err(<A::Error as Error>::duplicate_field("nanos"));
+ }
+ nanos = Some(try!(map.next_value()));
+ }
+ }
+ }
+ let secs = match secs {
+ Some(secs) => secs,
+ None => return Err(<A::Error as Error>::missing_field("secs")),
+ };
+ let nanos = match nanos {
+ Some(nanos) => nanos,
+ None => return Err(<A::Error as Error>::missing_field("nanos")),
+ };
+ try!(check_overflow(secs, nanos));
+ Ok(Duration::new(secs, nanos))
+ }
+ }
+
+ const FIELDS: &'static [&'static str] = &["secs", "nanos"];
+ deserializer.deserialize_struct("Duration", FIELDS, DurationVisitor)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+impl<'de> Deserialize<'de> for SystemTime {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // Reuse duration
+ enum Field {
+ Secs,
+ Nanos,
+ }
+
+ impl<'de> Deserialize<'de> for Field {
+ 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<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<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);
+ Err(Error::unknown_field(&value, FIELDS))
+ }
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(FieldVisitor)
+ }
+ }
+
+ fn check_overflow<E>(secs: u64, nanos: u32) -> Result<(), E>
+ where
+ E: Error,
+ {
+ static NANOS_PER_SEC: u32 = 1_000_000_000;
+ match secs.checked_add((nanos / NANOS_PER_SEC) as u64) {
+ Some(_) => Ok(()),
+ None => Err(E::custom("overflow deserializing SystemTime epoch offset")),
+ }
+ }
+
+ struct DurationVisitor;
+
+ 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<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));
+ }
+ };
+ let nanos: u32 = match try!(seq.next_element()) {
+ Some(value) => value,
+ None => {
+ return Err(Error::invalid_length(1, &self));
+ }
+ };
+ try!(check_overflow(secs, nanos));
+ Ok(Duration::new(secs, nanos))
+ }
+
+ 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 => {
+ if secs.is_some() {
+ return Err(<A::Error as Error>::duplicate_field(
+ "secs_since_epoch",
+ ));
+ }
+ secs = Some(try!(map.next_value()));
+ }
+ Field::Nanos => {
+ if nanos.is_some() {
+ return Err(<A::Error as Error>::duplicate_field(
+ "nanos_since_epoch",
+ ));
+ }
+ nanos = Some(try!(map.next_value()));
+ }
+ }
+ }
+ let secs = match secs {
+ Some(secs) => secs,
+ None => return Err(<A::Error as Error>::missing_field("secs_since_epoch")),
+ };
+ let nanos = match nanos {
+ Some(nanos) => nanos,
+ None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")),
+ };
+ try!(check_overflow(secs, nanos));
+ Ok(Duration::new(secs, nanos))
+ }
+ }
+
+ const FIELDS: &'static [&'static str] = &["secs_since_epoch", "nanos_since_epoch"];
+ let duration = try!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor));
+ #[cfg(not(no_systemtime_checked_add))]
+ let ret = UNIX_EPOCH
+ .checked_add(duration)
+ .ok_or_else(|| D::Error::custom("overflow deserializing SystemTime"));
+ #[cfg(no_systemtime_checked_add)]
+ let ret = Ok(UNIX_EPOCH + duration);
+ ret
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Similar to:
+//
+// #[derive(Deserialize)]
+// #[serde(deny_unknown_fields)]
+// struct Range {
+// start: u64,
+// end: u32,
+// }
+impl<'de, Idx> Deserialize<'de> for Range<Idx>
+where
+ Idx: Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let (start, end) = try!(deserializer.deserialize_struct(
+ "Range",
+ range::FIELDS,
+ range::RangeVisitor {
+ expecting: "struct Range",
+ phantom: PhantomData,
+ },
+ ));
+ Ok(start..end)
+ }
+}
+
+#[cfg(not(no_range_inclusive))]
+impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx>
+where
+ Idx: Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let (start, end) = try!(deserializer.deserialize_struct(
+ "RangeInclusive",
+ range::FIELDS,
+ range::RangeVisitor {
+ expecting: "struct RangeInclusive",
+ phantom: PhantomData,
+ },
+ ));
+ Ok(RangeInclusive::new(start, end))
+ }
+}
+
+mod range {
+ use lib::*;
+
+ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
+
+ pub const FIELDS: &'static [&'static str] = &["start", "end"];
+
+ // If this were outside of the serde crate, it would just use:
+ //
+ // #[derive(Deserialize)]
+ // #[serde(field_identifier, rename_all = "lowercase")]
+ enum Field {
+ Start,
+ End,
+ }
+
+ impl<'de> Deserialize<'de> for Field {
+ 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<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<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ b"start" => Ok(Field::Start),
+ b"end" => Ok(Field::End),
+ _ => {
+ let value = ::__private::from_utf8_lossy(value);
+ Err(Error::unknown_field(&*value, FIELDS))
+ }
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(FieldVisitor)
+ }
+ }
+
+ pub struct RangeVisitor<Idx> {
+ pub expecting: &'static str,
+ pub phantom: PhantomData<Idx>,
+ }
+
+ impl<'de, Idx> Visitor<'de> for RangeVisitor<Idx>
+ where
+ Idx: Deserialize<'de>,
+ {
+ type Value = (Idx, Idx);
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(self.expecting)
+ }
+
+ 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));
+ }
+ };
+ let end: Idx = match try!(seq.next_element()) {
+ Some(value) => value,
+ None => {
+ return Err(Error::invalid_length(1, &self));
+ }
+ };
+ Ok((start, end))
+ }
+
+ 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 => {
+ if start.is_some() {
+ return Err(<A::Error as Error>::duplicate_field("start"));
+ }
+ start = Some(try!(map.next_value()));
+ }
+ Field::End => {
+ if end.is_some() {
+ return Err(<A::Error as Error>::duplicate_field("end"));
+ }
+ end = Some(try!(map.next_value()));
+ }
+ }
+ }
+ let start = match start {
+ Some(start) => start,
+ None => return Err(<A::Error as Error>::missing_field("start")),
+ };
+ let end = match end {
+ Some(end) => end,
+ None => return Err(<A::Error as Error>::missing_field("end")),
+ };
+ Ok((start, end))
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
+impl<'de, T> Deserialize<'de> for Bound<T>
+where
+ T: Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ enum Field {
+ Unbounded,
+ Included,
+ Excluded,
+ }
+
+ impl<'de> Deserialize<'de> for Field {
+ #[inline]
+ 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("`Unbounded`, `Included` or `Excluded`")
+ }
+
+ fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ 0 => Ok(Field::Unbounded),
+ 1 => Ok(Field::Included),
+ 2 => Ok(Field::Excluded),
+ _ => Err(Error::invalid_value(Unexpected::Unsigned(value), &self)),
+ }
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ "Unbounded" => Ok(Field::Unbounded),
+ "Included" => Ok(Field::Included),
+ "Excluded" => Ok(Field::Excluded),
+ _ => Err(Error::unknown_variant(value, VARIANTS)),
+ }
+ }
+
+ fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ b"Unbounded" => Ok(Field::Unbounded),
+ b"Included" => Ok(Field::Included),
+ b"Excluded" => Ok(Field::Excluded),
+ _ => match str::from_utf8(value) {
+ Ok(value) => Err(Error::unknown_variant(value, VARIANTS)),
+ Err(_) => {
+ Err(Error::invalid_value(Unexpected::Bytes(value), &self))
+ }
+ },
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(FieldVisitor)
+ }
+ }
+
+ struct BoundVisitor<T>(PhantomData<Bound<T>>);
+
+ impl<'de, T> Visitor<'de> for BoundVisitor<T>
+ where
+ T: Deserialize<'de>,
+ {
+ type Value = Bound<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("enum Bound")
+ }
+
+ fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
+ where
+ A: EnumAccess<'de>,
+ {
+ match try!(data.variant()) {
+ (Field::Unbounded, v) => v.unit_variant().map(|()| Bound::Unbounded),
+ (Field::Included, v) => v.newtype_variant().map(Bound::Included),
+ (Field::Excluded, v) => v.newtype_variant().map(Bound::Excluded),
+ }
+ }
+ }
+
+ const VARIANTS: &'static [&'static str] = &["Unbounded", "Included", "Excluded"];
+
+ deserializer.deserialize_enum("Bound", VARIANTS, BoundVisitor(PhantomData))
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl<'de, T, E> Deserialize<'de> for Result<T, E>
+where
+ T: Deserialize<'de>,
+ E: Deserialize<'de>,
+{
+ 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<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_u64<E>(self, value: u64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ 0 => Ok(Field::Ok),
+ 1 => Ok(Field::Err),
+ _ => Err(Error::invalid_value(Unexpected::Unsigned(value), &self)),
+ }
+ }
+
+ 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<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)),
+ Err(_) => {
+ Err(Error::invalid_value(Unexpected::Bytes(value), &self))
+ }
+ },
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(FieldVisitor)
+ }
+ }
+
+ struct ResultVisitor<T, E>(PhantomData<Result<T, E>>);
+
+ impl<'de, T, E> Visitor<'de> for ResultVisitor<T, E>
+ where
+ T: Deserialize<'de>,
+ 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<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),
+ }
+ }
+ }
+
+ const VARIANTS: &'static [&'static str] = &["Ok", "Err"];
+
+ deserializer.deserialize_enum("Result", VARIANTS, ResultVisitor(PhantomData))
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl<'de, T> Deserialize<'de> for Wrapping<T>
+where
+ T: Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer).map(Wrapping)
+ }
+}
+
+#[cfg(all(feature = "std", not(no_std_atomic)))]
+macro_rules! atomic_impl {
+ ($($ty:ident $size:expr)*) => {
+ $(
+ #[cfg(any(no_target_has_atomic, target_has_atomic = $size))]
+ impl<'de> Deserialize<'de> for $ty {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer).map(Self::new)
+ }
+ }
+ )*
+ };
+}
+
+#[cfg(all(feature = "std", not(no_std_atomic)))]
+atomic_impl! {
+ AtomicBool "8"
+ AtomicI8 "8"
+ AtomicI16 "16"
+ AtomicI32 "32"
+ AtomicIsize "ptr"
+ AtomicU8 "8"
+ AtomicU16 "16"
+ AtomicU32 "32"
+ AtomicUsize "ptr"
+}
+
+#[cfg(all(feature = "std", not(no_std_atomic64)))]
+atomic_impl! {
+ AtomicI64 "64"
+ AtomicU64 "64"
+}
+
+#[cfg(feature = "std")]
+struct FromStrVisitor<T> {
+ expecting: &'static str,
+ ty: PhantomData<T>,
+}
+
+#[cfg(feature = "std")]
+impl<T> FromStrVisitor<T> {
+ fn new(expecting: &'static str) -> Self {
+ FromStrVisitor {
+ expecting: expecting,
+ ty: PhantomData,
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<'de, T> Visitor<'de> for FromStrVisitor<T>
+where
+ T: str::FromStr,
+ T::Err: fmt::Display,
+{
+ type Value = T;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(self.expecting)
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ s.parse().map_err(Error::custom)
+ }
+}
diff --git a/third_party/rust/serde/src/de/mod.rs b/third_party/rust/serde/src/de/mod.rs
new file mode 100644
index 0000000000..ca29ec610b
--- /dev/null
+++ b/third_party/rust/serde/src/de/mod.rs
@@ -0,0 +1,2299 @@
+//! Generic data structure deserialization framework.
+//!
+//! The two most important traits in this module are [`Deserialize`] and
+//! [`Deserializer`].
+//!
+//! - **A type that implements `Deserialize` is a data structure** that can be
+//! deserialized from any data format supported by Serde, and conversely
+//! - **A type that implements `Deserializer` is a data format** that can
+//! deserialize any data structure supported by Serde.
+//!
+//! # The Deserialize trait
+//!
+//! Serde provides [`Deserialize`] implementations for many Rust primitive and
+//! standard library types. The complete list is below. All of these can be
+//! deserialized using Serde out of the box.
+//!
+//! Additionally, Serde provides a procedural macro called [`serde_derive`] to
+//! automatically generate [`Deserialize`] implementations for structs and enums
+//! in your program. See the [derive section of the manual] for how to use this.
+//!
+//! In rare cases it may be necessary to implement [`Deserialize`] manually for
+//! some type in your program. See the [Implementing `Deserialize`] section of
+//! the manual for more about this.
+//!
+//! Third-party crates may provide [`Deserialize`] implementations for types
+//! that they expose. For example the [`linked-hash-map`] crate provides a
+//! [`LinkedHashMap<K, V>`] type that is deserializable by Serde because the
+//! crate provides an implementation of [`Deserialize`] for it.
+//!
+//! # The Deserializer trait
+//!
+//! [`Deserializer`] implementations are provided by third-party crates, for
+//! example [`serde_json`], [`serde_yaml`] and [`postcard`].
+//!
+//! A partial list of well-maintained formats is given on the [Serde
+//! website][data formats].
+//!
+//! # Implementations of Deserialize provided by Serde
+//!
+//! This is a slightly different set of types than what is supported for
+//! serialization. Some types can be serialized by Serde but not deserialized.
+//! One example is `OsStr`.
+//!
+//! - **Primitive types**:
+//! - bool
+//! - i8, i16, i32, i64, i128, isize
+//! - u8, u16, u32, u64, u128, usize
+//! - f32, f64
+//! - char
+//! - **Compound types**:
+//! - \[T; 0\] through \[T; 32\]
+//! - tuples up to size 16
+//! - **Common standard library types**:
+//! - String
+//! - Option\<T\>
+//! - Result\<T, E\>
+//! - PhantomData\<T\>
+//! - **Wrapper types**:
+//! - Box\<T\>
+//! - Box\<\[T\]\>
+//! - Box\<str\>
+//! - Cow\<'a, T\>
+//! - Cell\<T\>
+//! - RefCell\<T\>
+//! - Mutex\<T\>
+//! - RwLock\<T\>
+//! - Rc\<T\>&emsp;*(if* features = ["rc"] *is enabled)*
+//! - Arc\<T\>&emsp;*(if* features = ["rc"] *is enabled)*
+//! - **Collection types**:
+//! - BTreeMap\<K, V\>
+//! - BTreeSet\<T\>
+//! - BinaryHeap\<T\>
+//! - HashMap\<K, V, H\>
+//! - HashSet\<T, H\>
+//! - LinkedList\<T\>
+//! - VecDeque\<T\>
+//! - Vec\<T\>
+//! - **Zero-copy types**:
+//! - &str
+//! - &\[u8\]
+//! - **FFI types**:
+//! - CString
+//! - Box\<CStr\>
+//! - OsString
+//! - **Miscellaneous standard library types**:
+//! - Duration
+//! - SystemTime
+//! - Path
+//! - PathBuf
+//! - Range\<T\>
+//! - RangeInclusive\<T\>
+//! - Bound\<T\>
+//! - num::NonZero*
+//! - `!` *(unstable)*
+//! - **Net types**:
+//! - IpAddr
+//! - Ipv4Addr
+//! - Ipv6Addr
+//! - SocketAddr
+//! - SocketAddrV4
+//! - SocketAddrV6
+//!
+//! [Implementing `Deserialize`]: https://serde.rs/impl-deserialize.html
+//! [`Deserialize`]: ../trait.Deserialize.html
+//! [`Deserializer`]: ../trait.Deserializer.html
+//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
+//! [`postcard`]: https://github.com/jamesmunns/postcard
+//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
+//! [`serde_derive`]: https://crates.io/crates/serde_derive
+//! [`serde_json`]: https://github.com/serde-rs/json
+//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml
+//! [derive section of the manual]: https://serde.rs/derive.html
+//! [data formats]: https://serde.rs/#data-formats
+
+use lib::*;
+
+////////////////////////////////////////////////////////////////////////////////
+
+pub mod value;
+
+#[cfg(not(no_integer128))]
+mod format;
+mod ignored_any;
+mod impls;
+mod utf8;
+
+pub use self::ignored_any::IgnoredAny;
+
+#[cfg(feature = "std")]
+#[doc(no_inline)]
+pub use std::error::Error as StdError;
+#[cfg(not(feature = "std"))]
+#[doc(no_inline)]
+pub use std_error::Error as StdError;
+
+////////////////////////////////////////////////////////////////////////////////
+
+macro_rules! declare_error_trait {
+ (Error: Sized $(+ $($supertrait:ident)::+)*) => {
+ /// The `Error` trait allows `Deserialize` implementations to create descriptive
+ /// error messages belonging to the `Deserializer` against which they are
+ /// currently running.
+ ///
+ /// Every `Deserializer` declares an `Error` type that encompasses both
+ /// general-purpose deserialization errors as well as errors specific to the
+ /// particular deserialization format. For example the `Error` type of
+ /// `serde_json` can represent errors like an invalid JSON escape sequence or an
+ /// unterminated string literal, in addition to the error cases that are part of
+ /// this trait.
+ ///
+ /// Most deserializers should only need to provide the `Error::custom` method
+ /// and inherit the default behavior for the other methods.
+ ///
+ /// # Example implementation
+ ///
+ /// The [example data format] presented on the website shows an error
+ /// type appropriate for a basic JSON data format.
+ ///
+ /// [example data format]: https://serde.rs/data-format.html
+ pub trait Error: Sized $(+ $($supertrait)::+)* {
+ /// Raised when there is general error when deserializing a type.
+ ///
+ /// The message should not be capitalized and should not end with a period.
+ ///
+ /// ```edition2018
+ /// # use std::str::FromStr;
+ /// #
+ /// # struct IpAddr;
+ /// #
+ /// # impl FromStr for IpAddr {
+ /// # type Err = String;
+ /// #
+ /// # fn from_str(_: &str) -> Result<Self, String> {
+ /// # 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>,
+ /// {
+ /// let s = String::deserialize(deserializer)?;
+ /// s.parse().map_err(de::Error::custom)
+ /// }
+ /// }
+ /// ```
+ fn custom<T>(msg: T) -> Self
+ where
+ T: Display;
+
+ /// Raised when a `Deserialize` receives a type different from what it was
+ /// expecting.
+ ///
+ /// The `unexp` argument provides information about what type was received.
+ /// This is the type that was present in the input file or other source data
+ /// 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.
+ /// This is the value that was present in the input file or other source
+ /// 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")]
+declare_error_trait!(Error: Sized + StdError);
+
+#[cfg(not(feature = "std"))]
+declare_error_trait!(Error: Sized + Debug + Display);
+
+/// `Unexpected` represents an unexpected invocation of any one of the `Visitor`
+/// trait methods.
+///
+/// This is used as an argument to the `invalid_type`, `invalid_value`, and
+/// `invalid_length` methods of the `Error` trait to build error messages.
+///
+/// ```edition2018
+/// # use std::fmt;
+/// #
+/// # use serde::de::{self, Unexpected, Visitor};
+/// #
+/// # struct Example;
+/// #
+/// # 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,
+/// {
+/// 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.
+ Bool(bool),
+
+ /// The input contained an unsigned integer `u8`, `u16`, `u32` or `u64` that
+ /// was not expected.
+ Unsigned(u64),
+
+ /// The input contained a signed integer `i8`, `i16`, `i32` or `i64` that
+ /// was not expected.
+ Signed(i64),
+
+ /// The input contained a floating point `f32` or `f64` that was not
+ /// expected.
+ Float(f64),
+
+ /// The input contained a `char` that was not expected.
+ Char(char),
+
+ /// The input contained a `&str` or `String` that was not expected.
+ Str(&'a str),
+
+ /// The input contained a `&[u8]` or `Vec<u8>` that was not expected.
+ Bytes(&'a [u8]),
+
+ /// The input contained a unit `()` that was not expected.
+ Unit,
+
+ /// The input contained an `Option<T>` that was not expected.
+ Option,
+
+ /// The input contained a newtype struct that was not expected.
+ NewtypeStruct,
+
+ /// The input contained a sequence that was not expected.
+ Seq,
+
+ /// The input contained a map that was not expected.
+ Map,
+
+ /// The input contained an enum that was not expected.
+ Enum,
+
+ /// The input contained a unit variant that was not expected.
+ UnitVariant,
+
+ /// The input contained a newtype variant that was not expected.
+ NewtypeVariant,
+
+ /// The input contained a tuple variant that was not expected.
+ TupleVariant,
+
+ /// The input contained a struct variant that was not expected.
+ StructVariant,
+
+ /// A message stating what uncategorized thing the input contained that was
+ /// not expected.
+ ///
+ /// The message should be a noun or noun phrase, not capitalized and without
+ /// a period. An example message is "unoriginal superhero".
+ Other(&'a str),
+}
+
+impl<'a> fmt::Display for Unexpected<'a> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ use self::Unexpected::*;
+ match *self {
+ Bool(b) => write!(formatter, "boolean `{}`", b),
+ Unsigned(i) => write!(formatter, "integer `{}`", i),
+ Signed(i) => write!(formatter, "integer `{}`", i),
+ Float(f) => write!(formatter, "floating point `{}`", f),
+ Char(c) => write!(formatter, "character `{}`", c),
+ Str(s) => write!(formatter, "string {:?}", s),
+ Bytes(_) => write!(formatter, "byte array"),
+ Unit => write!(formatter, "unit value"),
+ Option => write!(formatter, "Option value"),
+ NewtypeStruct => write!(formatter, "newtype struct"),
+ Seq => write!(formatter, "sequence"),
+ Map => write!(formatter, "map"),
+ Enum => write!(formatter, "enum"),
+ UnitVariant => write!(formatter, "unit variant"),
+ NewtypeVariant => write!(formatter, "newtype variant"),
+ TupleVariant => write!(formatter, "tuple variant"),
+ StructVariant => write!(formatter, "struct variant"),
+ Other(other) => formatter.write_str(other),
+ }
+ }
+}
+
+/// `Expected` represents an explanation of what data a `Visitor` was expecting
+/// to receive.
+///
+/// This is used as an argument to the `invalid_type`, `invalid_value`, and
+/// `invalid_length` methods of the `Error` trait to build error messages. The
+/// message should be a noun or noun phrase that completes the sentence "This
+/// Visitor expects to receive ...", for example the message could be "an
+/// integer between 0 and 64". The message should not be capitalized and should
+/// not end with a period.
+///
+/// Within the context of a `Visitor` implementation, the `Visitor` itself
+/// (`&self`) is an implementation of this trait.
+///
+/// ```edition2018
+/// # use std::fmt;
+/// #
+/// # use serde::de::{self, Unexpected, Visitor};
+/// #
+/// # struct Example;
+/// #
+/// # 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,
+/// {
+/// Err(de::Error::invalid_type(Unexpected::Bool(v), &self))
+/// }
+/// # }
+/// ```
+///
+/// Outside of a `Visitor`, `&"..."` can be used.
+///
+/// ```edition2018
+/// # use serde::de::{self, Unexpected};
+/// #
+/// # fn example<E>() -> Result<(), E>
+/// # 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.
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result;
+}
+
+impl<'de, T> Expected for T
+where
+ T: Visitor<'de>,
+{
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.expecting(formatter)
+ }
+}
+
+impl<'a> Expected for &'a str {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(self)
+ }
+}
+
+impl<'a> Display for Expected + 'a {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ Expected::fmt(self, formatter)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A **data structure** that can be deserialized from any data format supported
+/// by Serde.
+///
+/// Serde provides `Deserialize` implementations for many Rust primitive and
+/// standard library types. The complete list is [here][crate::de]. All of these
+/// can be deserialized using Serde out of the box.
+///
+/// Additionally, Serde provides a procedural macro called `serde_derive` to
+/// automatically generate `Deserialize` implementations for structs and enums
+/// in your program. See the [derive section of the manual][derive] for how to
+/// use this.
+///
+/// In rare cases it may be necessary to implement `Deserialize` manually for
+/// some type in your program. See the [Implementing
+/// `Deserialize`][impl-deserialize] section of the manual for more about this.
+///
+/// Third-party crates may provide `Deserialize` implementations for types that
+/// they expose. For example the `linked-hash-map` crate provides a
+/// `LinkedHashMap<K, V>` type that is deserializable by Serde because the crate
+/// provides an implementation of `Deserialize` for it.
+///
+/// [derive]: https://serde.rs/derive.html
+/// [impl-deserialize]: https://serde.rs/impl-deserialize.html
+///
+/// # Lifetime
+///
+/// The `'de` lifetime of this trait is the lifetime of data that may be
+/// borrowed by `Self` when deserialized. See the page [Understanding
+/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
+///
+/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
+pub trait Deserialize<'de>: Sized {
+ /// Deserialize this value from the given Serde deserializer.
+ ///
+ /// See the [Implementing `Deserialize`][impl-deserialize] section of the
+ /// manual for more information about how to implement this method.
+ ///
+ /// [impl-deserialize]: https://serde.rs/impl-deserialize.html
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>;
+
+ /// Deserializes a value into `self` from the given Deserializer.
+ ///
+ /// The purpose of this method is to allow the deserializer to reuse
+ /// resources and avoid copies. As such, if this method returns an error,
+ /// `self` will be in an indeterminate state where some parts of the struct
+ /// have been overwritten. Although whatever state that is will be
+ /// memory-safe.
+ ///
+ /// This is generally useful when repeatedly deserializing values that
+ /// are processed one at a time, where the value of `self` doesn't matter
+ /// when the next deserialization occurs.
+ ///
+ /// If you manually implement this, your recursive deserializations should
+ /// use `deserialize_in_place`.
+ ///
+ /// This method is stable and an official public API, but hidden from the
+ /// documentation because it is almost never what newbies are looking for.
+ /// Showing it in rustdoc would cause it to be featured more prominently
+ /// than it deserves.
+ #[doc(hidden)]
+ fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // Default implementation just delegates to `deserialize` impl.
+ *place = try!(Deserialize::deserialize(deserializer));
+ Ok(())
+ }
+}
+
+/// A data structure that can be deserialized without borrowing any data from
+/// the deserializer.
+///
+/// This is primarily useful for trait bounds on functions. For example a
+/// `from_str` function may be able to deserialize a data structure that borrows
+/// from the input string, but a `from_reader` function may only deserialize
+/// owned data.
+///
+/// ```edition2018
+/// # 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>;
+///
+/// fn from_reader<R, T>(rdr: R) -> Result<T>
+/// where
+/// R: Read,
+/// T: DeserializeOwned;
+/// # }
+/// ```
+///
+/// # Lifetime
+///
+/// The relationship between `Deserialize` and `DeserializeOwned` in trait
+/// bounds is explained in more detail on the page [Understanding deserializer
+/// lifetimes].
+///
+/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
+pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
+impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
+
+/// `DeserializeSeed` is the stateful form of the `Deserialize` trait. If you
+/// ever find yourself looking for a way to pass data into a `Deserialize` impl,
+/// this trait is the way to do it.
+///
+/// As one example of stateful deserialization consider deserializing a JSON
+/// array into an existing buffer. Using the `Deserialize` trait we could
+/// deserialize a JSON array into a `Vec<T>` but it would be a freshly allocated
+/// `Vec<T>`; there is no way for `Deserialize` to reuse a previously allocated
+/// buffer. Using `DeserializeSeed` instead makes this possible as in the
+/// example code below.
+///
+/// The canonical API for stateless deserialization looks like this:
+///
+/// ```edition2018
+/// # use serde::Deserialize;
+/// #
+/// # enum Error {}
+/// #
+/// fn func<'de, T: Deserialize<'de>>() -> Result<T, Error>
+/// # {
+/// # unimplemented!()
+/// # }
+/// ```
+///
+/// Adjusting an API like this to support stateful deserialization is a matter
+/// of accepting a seed as input:
+///
+/// ```edition2018
+/// # use serde::de::DeserializeSeed;
+/// #
+/// # enum Error {}
+/// #
+/// fn func_seed<'de, T: DeserializeSeed<'de>>(seed: T) -> Result<T::Value, Error>
+/// # {
+/// # let _ = seed;
+/// # unimplemented!()
+/// # }
+/// ```
+///
+/// In practice the majority of deserialization is stateless. An API expecting a
+/// seed can be appeased by passing `std::marker::PhantomData` as a seed in the
+/// case of stateless deserialization.
+///
+/// # Lifetime
+///
+/// The `'de` lifetime of this trait is the lifetime of data that may be
+/// borrowed by `Self::Value` when deserialized. See the page [Understanding
+/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
+///
+/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
+///
+/// # Example
+///
+/// Suppose we have JSON that looks like `[[1, 2], [3, 4, 5], [6]]` and we need
+/// to deserialize it into a flat representation like `vec![1, 2, 3, 4, 5, 6]`.
+/// Allocating a brand new `Vec<T>` for each subarray would be slow. Instead we
+/// would like to allocate a single `Vec<T>` and then deserialize each subarray
+/// into it. This requires stateful deserialization using the `DeserializeSeed`
+/// trait.
+///
+/// ```edition2018
+/// use std::fmt;
+/// use std::marker::PhantomData;
+///
+/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor};
+///
+/// // 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>,
+/// {
+/// // 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>,
+/// {
+/// // 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>,
+/// {
+/// 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>,
+/// {
+/// // Decrease the number of reallocations if there are many elements
+/// if let Some(size_hint) = seq.size_hint() {
+/// self.0.reserve(size_hint);
+/// }
+///
+/// // 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(())
+/// }
+/// }
+///
+/// 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>,
+/// {
+/// // 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>,
+/// {
+/// // 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>,
+/// # {
+/// 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.
+ type Value;
+
+ /// Equivalent to the more common `Deserialize::deserialize` method, except
+ /// with some initial piece of data (the seed) passed in.
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>;
+}
+
+impl<'de, T> DeserializeSeed<'de> for PhantomData<T>
+where
+ T: Deserialize<'de>,
+{
+ type Value = T;
+
+ #[inline]
+ fn deserialize<D>(self, deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ T::deserialize(deserializer)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A **data format** that can deserialize any data structure supported by
+/// Serde.
+///
+/// The role of this trait is to define the deserialization half of the [Serde
+/// data model], which is a way to categorize every Rust data type into one of
+/// 29 possible types. Each method of the `Deserializer` trait corresponds to one
+/// of the types of the data model.
+///
+/// Implementations of `Deserialize` map themselves into this data model by
+/// passing to the `Deserializer` a `Visitor` implementation that can receive
+/// these various types.
+///
+/// The types that make up the Serde data model are:
+///
+/// - **14 primitive types**
+/// - bool
+/// - i8, i16, i32, i64, i128
+/// - u8, u16, u32, u64, u128
+/// - f32, f64
+/// - char
+/// - **string**
+/// - UTF-8 bytes with a length and no null terminator.
+/// - When serializing, all strings are handled equally. When deserializing,
+/// there are three flavors of strings: transient, owned, and borrowed.
+/// - **byte array** - \[u8\]
+/// - Similar to strings, during deserialization byte arrays can be
+/// transient, owned, or borrowed.
+/// - **option**
+/// - Either none or some value.
+/// - **unit**
+/// - The type of `()` in Rust. It represents an anonymous value containing
+/// no data.
+/// - **unit_struct**
+/// - For example `struct Unit` or `PhantomData<T>`. It represents a named
+/// value containing no data.
+/// - **unit_variant**
+/// - For example the `E::A` and `E::B` in `enum E { A, B }`.
+/// - **newtype_struct**
+/// - For example `struct Millimeters(u8)`.
+/// - **newtype_variant**
+/// - For example the `E::N` in `enum E { N(u8) }`.
+/// - **seq**
+/// - A variably sized heterogeneous sequence of values, for example `Vec<T>`
+/// or `HashSet<T>`. When serializing, the length may or may not be known
+/// before iterating through all the data. When deserializing, the length
+/// is determined by looking at the serialized data.
+/// - **tuple**
+/// - A statically sized heterogeneous sequence of values for which the
+/// length will be known at deserialization time without looking at the
+/// serialized data, for example `(u8,)` or `(String, u64, Vec<T>)` or
+/// `[u64; 10]`.
+/// - **tuple_struct**
+/// - A named tuple, for example `struct Rgb(u8, u8, u8)`.
+/// - **tuple_variant**
+/// - For example the `E::T` in `enum E { T(u8, u8) }`.
+/// - **map**
+/// - A heterogeneous key-value pairing, for example `BTreeMap<K, V>`.
+/// - **struct**
+/// - A heterogeneous key-value pairing in which the keys are strings and
+/// will be known at deserialization time without looking at the serialized
+/// data, for example `struct S { r: u8, g: u8, b: u8 }`.
+/// - **struct_variant**
+/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
+///
+/// The `Deserializer` trait supports two entry point styles which enables
+/// different kinds of deserialization.
+///
+/// 1. The `deserialize_any` method. Self-describing data formats like JSON are
+/// able to look at the serialized data and tell what it represents. For
+/// example the JSON deserializer may see an opening curly brace (`{`) and
+/// know that it is seeing a map. If the data format supports
+/// `Deserializer::deserialize_any`, it will drive the Visitor using whatever
+/// type it sees in the input. JSON uses this approach when deserializing
+/// `serde_json::Value` which is an enum that can represent any JSON
+/// document. Without knowing what is in a JSON document, we can deserialize
+/// it to `serde_json::Value` by going through
+/// `Deserializer::deserialize_any`.
+///
+/// 2. The various `deserialize_*` methods. Non-self-describing formats like
+/// Postcard need to be told what is in the input in order to deserialize it.
+/// The `deserialize_*` methods are hints to the deserializer for how to
+/// interpret the next piece of input. Non-self-describing formats are not
+/// able to deserialize something like `serde_json::Value` which relies on
+/// `Deserializer::deserialize_any`.
+///
+/// When implementing `Deserialize`, you should avoid relying on
+/// `Deserializer::deserialize_any` unless you need to be told by the
+/// Deserializer what type is in the input. Know that relying on
+/// `Deserializer::deserialize_any` means your data type will be able to
+/// deserialize from self-describing formats only, ruling out Postcard and many
+/// others.
+///
+/// [Serde data model]: https://serde.rs/data-model.html
+///
+/// # Lifetime
+///
+/// The `'de` lifetime of this trait is the lifetime of data that may be
+/// borrowed from the input when deserializing. See the page [Understanding
+/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
+///
+/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website contains example code for
+/// a basic JSON `Deserializer`.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait Deserializer<'de>: Sized {
+ /// The error type that can be returned if some error occurs during
+ /// deserialization.
+ type Error: Error;
+
+ /// Require the `Deserializer` to figure out how to drive the visitor based
+ /// on what data type is in the input.
+ ///
+ /// When implementing `Deserialize`, you should avoid relying on
+ /// `Deserializer::deserialize_any` unless you need to be told by the
+ /// Deserializer what type is in the input. Know that relying on
+ /// `Deserializer::deserialize_any` means your data type will be able to
+ /// deserialize from self-describing formats only, ruling out Postcard and
+ /// many others.
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a `bool` value.
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting an `i8` value.
+ fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting an `i16` value.
+ fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting an `i32` value.
+ fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting an `i64` value.
+ fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ serde_if_integer128! {
+ /// Hint that the `Deserialize` type is expecting an `i128` value.
+ ///
+ /// This method is available only on Rust compiler versions >=1.26. The
+ /// default behavior unconditionally returns an error.
+ fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>
+ {
+ let _ = visitor;
+ Err(Error::custom("i128 is not supported"))
+ }
+ }
+
+ /// Hint that the `Deserialize` type is expecting a `u8` value.
+ fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a `u16` value.
+ fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a `u32` value.
+ fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a `u64` value.
+ fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ serde_if_integer128! {
+ /// Hint that the `Deserialize` type is expecting an `u128` value.
+ ///
+ /// This method is available only on Rust compiler versions >=1.26. The
+ /// default behavior unconditionally returns an error.
+ fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>
+ {
+ let _ = visitor;
+ Err(Error::custom("u128 is not supported"))
+ }
+ }
+
+ /// Hint that the `Deserialize` type is expecting a `f32` value.
+ fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a `f64` value.
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a `char` value.
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a string value and does
+ /// not benefit from taking ownership of buffered data owned by the
+ /// `Deserializer`.
+ ///
+ /// If the `Visitor` would benefit from taking ownership of `String` data,
+ /// indicate this to the `Deserializer` by using `deserialize_string`
+ /// instead.
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a string value and would
+ /// benefit from taking ownership of buffered data owned by the
+ /// `Deserializer`.
+ ///
+ /// If the `Visitor` would not benefit from taking ownership of `String`
+ /// data, indicate that to the `Deserializer` by using `deserialize_str`
+ /// instead.
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a byte array and does not
+ /// benefit from taking ownership of buffered data owned by the
+ /// `Deserializer`.
+ ///
+ /// If the `Visitor` would benefit from taking ownership of `Vec<u8>` data,
+ /// indicate this to the `Deserializer` by using `deserialize_byte_buf`
+ /// instead.
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a byte array and would
+ /// benefit from taking ownership of buffered data owned by the
+ /// `Deserializer`.
+ ///
+ /// If the `Visitor` would not benefit from taking ownership of `Vec<u8>`
+ /// data, indicate that to the `Deserializer` by using `deserialize_bytes`
+ /// instead.
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting an optional value.
+ ///
+ /// This allows deserializers that encode an optional value as a nullable
+ /// value to convert the null value into `None` and a regular value into
+ /// `Some(value)`.
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a unit value.
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a unit struct with a
+ /// particular name.
+ fn deserialize_unit_struct<V>(
+ self,
+ name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a newtype struct with a
+ /// particular name.
+ fn deserialize_newtype_struct<V>(
+ self,
+ name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a sequence of values.
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a sequence of values and
+ /// knows how many values there are without looking at the serialized data.
+ fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a tuple struct with a
+ /// particular name and number of fields.
+ fn deserialize_tuple_struct<V>(
+ self,
+ name: &'static str,
+ len: usize,
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a map of key-value pairs.
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting a struct with a particular
+ /// name and fields.
+ fn deserialize_struct<V>(
+ self,
+ name: &'static str,
+ fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting an enum value with a
+ /// particular name and possible variants.
+ fn deserialize_enum<V>(
+ self,
+ name: &'static str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type is expecting the name of a struct
+ /// field or the discriminant of an enum variant.
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Hint that the `Deserialize` type needs to deserialize a value whose type
+ /// doesn't matter because it is ignored.
+ ///
+ /// Deserializers for non-self-describing formats may not support this mode.
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+
+ /// Determine whether `Deserialize` implementations should expect to
+ /// deserialize their human-readable form.
+ ///
+ /// Some types have a human-readable form that may be somewhat expensive to
+ /// construct, as well as a binary form that is compact and efficient.
+ /// Generally text-based formats like JSON and YAML will prefer to use the
+ /// human-readable one and binary formats like Postcard will prefer the
+ /// compact one.
+ ///
+ /// ```edition2018
+ /// # use std::ops::Add;
+ /// # use std::str::FromStr;
+ /// #
+ /// # struct Timestamp;
+ /// #
+ /// # impl Timestamp {
+ /// # const EPOCH: Timestamp = Timestamp;
+ /// # }
+ /// #
+ /// # impl FromStr for Timestamp {
+ /// # type Err = String;
+ /// # fn from_str(_: &str) -> Result<Self, Self::Err> {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// # struct Duration;
+ /// #
+ /// # impl Duration {
+ /// # fn seconds(_: u64) -> Self { unimplemented!() }
+ /// # }
+ /// #
+ /// # impl Add<Duration> for Timestamp {
+ /// # type Output = Timestamp;
+ /// # fn add(self, _: Duration) -> Self::Output {
+ /// # 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>,
+ /// {
+ /// 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.
+ /// let n = u64::deserialize(deserializer)?;
+ /// Ok(Timestamp::EPOCH + Duration::seconds(n))
+ /// }
+ /// }
+ /// }
+ /// ```
+ ///
+ /// The default implementation of this method returns `true`. Data formats
+ /// may override this to `false` to request a compact form for types that
+ /// support one. Note that modifying this method to change a format from
+ /// human-readable to compact or vice versa should be regarded as a breaking
+ /// change, as a value serialized in human-readable mode is not required to
+ /// deserialize from the same data in compact mode.
+ #[inline]
+ fn is_human_readable(&self) -> bool {
+ true
+ }
+
+ // Not public API.
+ #[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
+ #[doc(hidden)]
+ fn __deserialize_content<V>(
+ self,
+ _: ::actually_private::T,
+ visitor: V,
+ ) -> Result<::private::de::Content<'de>, Self::Error>
+ where
+ V: Visitor<'de, Value = ::private::de::Content<'de>>,
+ {
+ self.deserialize_any(visitor)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// This trait represents a visitor that walks through a deserializer.
+///
+/// # Lifetime
+///
+/// The `'de` lifetime of this trait is the requirement for lifetime of data
+/// that may be borrowed by `Self::Value`. See the page [Understanding
+/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
+///
+/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
+///
+/// # Example
+///
+/// ```edition2018
+/// # use std::fmt;
+/// #
+/// # use serde::de::{self, Unexpected, Visitor};
+/// #
+/// /// A visitor that deserializes a long string - a string containing at least
+/// /// some minimum number of bytes.
+/// struct LongString {
+/// min: usize,
+/// }
+///
+/// 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,
+/// {
+/// if s.len() >= self.min {
+/// Ok(s.to_owned())
+/// } else {
+/// Err(de::Error::invalid_value(Unexpected::Str(s), &self))
+/// }
+/// }
+/// }
+/// ```
+pub trait Visitor<'de>: Sized {
+ /// The value produced by this visitor.
+ type Value;
+
+ /// Format a message stating what data this Visitor expects to receive.
+ ///
+ /// This is used in error messages. The message should complete the sentence
+ /// "This Visitor expects to receive ...", for example the message could be
+ /// "an integer between 0 and 64". The message should not be capitalized and
+ /// should not end with a period.
+ ///
+ /// ```edition2018
+ /// # use std::fmt;
+ /// #
+ /// # struct S {
+ /// # max: usize,
+ /// # }
+ /// #
+ /// # impl<'de> serde::de::Visitor<'de> for S {
+ /// # type Value = ();
+ /// #
+ /// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ /// write!(formatter, "an integer between 0 and {}", self.max)
+ /// }
+ /// # }
+ /// ```
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result;
+
+ /// The input contains a boolean.
+ ///
+ /// The default implementation fails with a type error.
+ fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Err(Error::invalid_type(Unexpected::Bool(v), &self))
+ }
+
+ /// The input contains an `i8`.
+ ///
+ /// The default implementation forwards to [`visit_i64`].
+ ///
+ /// [`visit_i64`]: #method.visit_i64
+ fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_i64(v as i64)
+ }
+
+ /// The input contains an `i16`.
+ ///
+ /// The default implementation forwards to [`visit_i64`].
+ ///
+ /// [`visit_i64`]: #method.visit_i64
+ fn visit_i16<E>(self, v: i16) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_i64(v as i64)
+ }
+
+ /// The input contains an `i32`.
+ ///
+ /// The default implementation forwards to [`visit_i64`].
+ ///
+ /// [`visit_i64`]: #method.visit_i64
+ fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_i64(v as i64)
+ }
+
+ /// The input contains an `i64`.
+ ///
+ /// The default implementation fails with a type error.
+ fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Err(Error::invalid_type(Unexpected::Signed(v), &self))
+ }
+
+ serde_if_integer128! {
+ /// The input contains a `i128`.
+ ///
+ /// This method is available only on Rust compiler versions >=1.26. The
+ /// default implementation fails with a type error.
+ fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let mut buf = [0u8; 58];
+ let mut writer = format::Buf::new(&mut buf);
+ fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v)).unwrap();
+ Err(Error::invalid_type(Unexpected::Other(writer.as_str()), &self))
+ }
+ }
+
+ /// The input contains a `u8`.
+ ///
+ /// The default implementation forwards to [`visit_u64`].
+ ///
+ /// [`visit_u64`]: #method.visit_u64
+ fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_u64(v as u64)
+ }
+
+ /// The input contains a `u16`.
+ ///
+ /// The default implementation forwards to [`visit_u64`].
+ ///
+ /// [`visit_u64`]: #method.visit_u64
+ fn visit_u16<E>(self, v: u16) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_u64(v as u64)
+ }
+
+ /// The input contains a `u32`.
+ ///
+ /// The default implementation forwards to [`visit_u64`].
+ ///
+ /// [`visit_u64`]: #method.visit_u64
+ fn visit_u32<E>(self, v: u32) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_u64(v as u64)
+ }
+
+ /// The input contains a `u64`.
+ ///
+ /// The default implementation fails with a type error.
+ fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Err(Error::invalid_type(Unexpected::Unsigned(v), &self))
+ }
+
+ serde_if_integer128! {
+ /// The input contains a `u128`.
+ ///
+ /// This method is available only on Rust compiler versions >=1.26. The
+ /// default implementation fails with a type error.
+ fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let mut buf = [0u8; 57];
+ let mut writer = format::Buf::new(&mut buf);
+ fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as u128", v)).unwrap();
+ Err(Error::invalid_type(Unexpected::Other(writer.as_str()), &self))
+ }
+ }
+
+ /// The input contains an `f32`.
+ ///
+ /// The default implementation forwards to [`visit_f64`].
+ ///
+ /// [`visit_f64`]: #method.visit_f64
+ fn visit_f32<E>(self, v: f32) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_f64(v as f64)
+ }
+
+ /// The input contains an `f64`.
+ ///
+ /// The default implementation fails with a type error.
+ fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Err(Error::invalid_type(Unexpected::Float(v), &self))
+ }
+
+ /// The input contains a `char`.
+ ///
+ /// The default implementation forwards to [`visit_str`] as a one-character
+ /// string.
+ ///
+ /// [`visit_str`]: #method.visit_str
+ #[inline]
+ fn visit_char<E>(self, v: char) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_str(utf8::encode(v).as_str())
+ }
+
+ /// The input contains a string. The lifetime of the string is ephemeral and
+ /// it may be destroyed after this method returns.
+ ///
+ /// This method allows the `Deserializer` to avoid a copy by retaining
+ /// ownership of any buffered data. `Deserialize` implementations that do
+ /// not benefit from taking ownership of `String` data should indicate that
+ /// to the deserializer by using `Deserializer::deserialize_str` rather than
+ /// `Deserializer::deserialize_string`.
+ ///
+ /// It is never correct to implement `visit_string` without implementing
+ /// `visit_str`. Implement neither, both, or just `visit_str`.
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Err(Error::invalid_type(Unexpected::Str(v), &self))
+ }
+
+ /// The input contains a string that lives at least as long as the
+ /// `Deserializer`.
+ ///
+ /// This enables zero-copy deserialization of strings in some formats. For
+ /// example JSON input containing the JSON string `"borrowed"` can be
+ /// deserialized with zero copying into a `&'a str` as long as the input
+ /// data outlives `'a`.
+ ///
+ /// The default implementation forwards to `visit_str`.
+ #[inline]
+ fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_str(v)
+ }
+
+ /// The input contains a string and ownership of the string is being given
+ /// to the `Visitor`.
+ ///
+ /// This method allows the `Visitor` to avoid a copy by taking ownership of
+ /// a string created by the `Deserializer`. `Deserialize` implementations
+ /// that benefit from taking ownership of `String` data should indicate that
+ /// to the deserializer by using `Deserializer::deserialize_string` rather
+ /// than `Deserializer::deserialize_str`, although not every deserializer
+ /// will honor such a request.
+ ///
+ /// It is never correct to implement `visit_string` without implementing
+ /// `visit_str`. Implement neither, both, or just `visit_str`.
+ ///
+ /// The default implementation forwards to `visit_str` and then drops the
+ /// `String`.
+ #[inline]
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_str(&v)
+ }
+
+ /// The input contains a byte array. The lifetime of the byte array is
+ /// ephemeral and it may be destroyed after this method returns.
+ ///
+ /// This method allows the `Deserializer` to avoid a copy by retaining
+ /// ownership of any buffered data. `Deserialize` implementations that do
+ /// not benefit from taking ownership of `Vec<u8>` data should indicate that
+ /// to the deserializer by using `Deserializer::deserialize_bytes` rather
+ /// than `Deserializer::deserialize_byte_buf`.
+ ///
+ /// It is never correct to implement `visit_byte_buf` without implementing
+ /// `visit_bytes`. Implement neither, both, or just `visit_bytes`.
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let _ = v;
+ Err(Error::invalid_type(Unexpected::Bytes(v), &self))
+ }
+
+ /// The input contains a byte array that lives at least as long as the
+ /// `Deserializer`.
+ ///
+ /// This enables zero-copy deserialization of bytes in some formats. For
+ /// example Postcard data containing bytes can be deserialized with zero
+ /// copying into a `&'a [u8]` as long as the input data outlives `'a`.
+ ///
+ /// The default implementation forwards to `visit_bytes`.
+ #[inline]
+ fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_bytes(v)
+ }
+
+ /// The input contains a byte array and ownership of the byte array is being
+ /// given to the `Visitor`.
+ ///
+ /// This method allows the `Visitor` to avoid a copy by taking ownership of
+ /// a byte buffer created by the `Deserializer`. `Deserialize`
+ /// implementations that benefit from taking ownership of `Vec<u8>` data
+ /// should indicate that to the deserializer by using
+ /// `Deserializer::deserialize_byte_buf` rather than
+ /// `Deserializer::deserialize_bytes`, although not every deserializer will
+ /// honor such a request.
+ ///
+ /// It is never correct to implement `visit_byte_buf` without implementing
+ /// `visit_bytes`. Implement neither, both, or just `visit_bytes`.
+ ///
+ /// The default implementation forwards to `visit_bytes` and then drops the
+ /// `Vec<u8>`.
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ self.visit_bytes(&v)
+ }
+
+ /// The input contains an optional that is absent.
+ ///
+ /// The default implementation fails with a type error.
+ fn visit_none<E>(self) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Err(Error::invalid_type(Unexpected::Option, &self))
+ }
+
+ /// The input contains an optional that is present.
+ ///
+ /// The default implementation fails with a type error.
+ fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let _ = deserializer;
+ Err(Error::invalid_type(Unexpected::Option, &self))
+ }
+
+ /// The input contains a unit `()`.
+ ///
+ /// The default implementation fails with a type error.
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Err(Error::invalid_type(Unexpected::Unit, &self))
+ }
+
+ /// The input contains a newtype struct.
+ ///
+ /// The content of the newtype struct may be read from the given
+ /// `Deserializer`.
+ ///
+ /// The default implementation fails with a type error.
+ fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let _ = deserializer;
+ Err(Error::invalid_type(Unexpected::NewtypeStruct, &self))
+ }
+
+ /// The input contains a sequence of elements.
+ ///
+ /// The default implementation fails with a type error.
+ fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let _ = seq;
+ Err(Error::invalid_type(Unexpected::Seq, &self))
+ }
+
+ /// The input contains a key-value map.
+ ///
+ /// The default implementation fails with a type error.
+ fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let _ = map;
+ Err(Error::invalid_type(Unexpected::Map, &self))
+ }
+
+ /// The input contains an enum.
+ ///
+ /// 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.
+///
+/// # Lifetime
+///
+/// The `'de` lifetime of this trait is the lifetime of data that may be
+/// borrowed by deserialized sequence elements. See the page [Understanding
+/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
+///
+/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `SeqAccess` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait SeqAccess<'de> {
+ /// The error type that can be returned if some error occurs during
+ /// deserialization.
+ type Error: Error;
+
+ /// This returns `Ok(Some(value))` for the next value in the sequence, or
+ /// `Ok(None)` if there are no more remaining items.
+ ///
+ /// `Deserialize` implementations should typically use
+ /// `SeqAccess::next_element` instead.
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: DeserializeSeed<'de>;
+
+ /// This returns `Ok(Some(value))` for the next value in the sequence, or
+ /// `Ok(None)` if there are no more remaining items.
+ ///
+ /// This method exists as a convenience for `Deserialize` implementations.
+ /// `SeqAccess` implementations should not override the default behavior.
+ #[inline]
+ fn next_element<T>(&mut self) -> Result<Option<T>, Self::Error>
+ where
+ T: Deserialize<'de>,
+ {
+ self.next_element_seed(PhantomData)
+ }
+
+ /// Returns the number of elements remaining in the sequence, if known.
+ #[inline]
+ fn size_hint(&self) -> Option<usize> {
+ None
+ }
+}
+
+impl<'de, 'a, A: ?Sized> SeqAccess<'de> for &'a mut A
+where
+ A: SeqAccess<'de>,
+{
+ type Error = A::Error;
+
+ #[inline]
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ (**self).next_element_seed(seed)
+ }
+
+ #[inline]
+ fn next_element<T>(&mut self) -> Result<Option<T>, Self::Error>
+ where
+ T: Deserialize<'de>,
+ {
+ (**self).next_element()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> Option<usize> {
+ (**self).size_hint()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// Provides a `Visitor` access to each entry of a map in the input.
+///
+/// This is a trait that a `Deserializer` passes to a `Visitor` implementation.
+///
+/// # Lifetime
+///
+/// The `'de` lifetime of this trait is the lifetime of data that may be
+/// borrowed by deserialized map entries. See the page [Understanding
+/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
+///
+/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `MapAccess` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait MapAccess<'de> {
+ /// The error type that can be returned if some error occurs during
+ /// deserialization.
+ type Error: Error;
+
+ /// This returns `Ok(Some(key))` for the next key in the map, or `Ok(None)`
+ /// if there are no more remaining entries.
+ ///
+ /// `Deserialize` implementations should typically use
+ /// `MapAccess::next_key` or `MapAccess::next_entry` instead.
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
+ where
+ K: DeserializeSeed<'de>;
+
+ /// This returns a `Ok(value)` for the next value in the map.
+ ///
+ /// `Deserialize` implementations should typically use
+ /// `MapAccess::next_value` instead.
+ ///
+ /// # Panics
+ ///
+ /// Calling `next_value_seed` before `next_key_seed` is incorrect and is
+ /// allowed to panic or return bogus results.
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
+ where
+ V: DeserializeSeed<'de>;
+
+ /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in
+ /// the map, or `Ok(None)` if there are no more remaining items.
+ ///
+ /// `MapAccess` implementations should override the default behavior if a
+ /// more efficient implementation is possible.
+ ///
+ /// `Deserialize` implementations should typically use
+ /// `MapAccess::next_entry` instead.
+ #[inline]
+ fn next_entry_seed<K, V>(
+ &mut self,
+ kseed: K,
+ vseed: V,
+ ) -> Result<Option<(K::Value, V::Value)>, Self::Error>
+ where
+ K: DeserializeSeed<'de>,
+ V: DeserializeSeed<'de>,
+ {
+ match try!(self.next_key_seed(kseed)) {
+ Some(key) => {
+ let value = try!(self.next_value_seed(vseed));
+ Ok(Some((key, value)))
+ }
+ None => Ok(None),
+ }
+ }
+
+ /// This returns `Ok(Some(key))` for the next key in the map, or `Ok(None)`
+ /// if there are no more remaining entries.
+ ///
+ /// This method exists as a convenience for `Deserialize` implementations.
+ /// `MapAccess` implementations should not override the default behavior.
+ #[inline]
+ fn next_key<K>(&mut self) -> Result<Option<K>, Self::Error>
+ where
+ K: Deserialize<'de>,
+ {
+ self.next_key_seed(PhantomData)
+ }
+
+ /// This returns a `Ok(value)` for the next value in the map.
+ ///
+ /// This method exists as a convenience for `Deserialize` implementations.
+ /// `MapAccess` implementations should not override the default behavior.
+ ///
+ /// # Panics
+ ///
+ /// Calling `next_value` before `next_key` is incorrect and is allowed to
+ /// panic or return bogus results.
+ #[inline]
+ fn next_value<V>(&mut self) -> Result<V, Self::Error>
+ where
+ V: Deserialize<'de>,
+ {
+ self.next_value_seed(PhantomData)
+ }
+
+ /// This returns `Ok(Some((key, value)))` for the next (key-value) pair in
+ /// the map, or `Ok(None)` if there are no more remaining items.
+ ///
+ /// This method exists as a convenience for `Deserialize` implementations.
+ /// `MapAccess` implementations should not override the default behavior.
+ #[inline]
+ fn next_entry<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
+ where
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+ {
+ self.next_entry_seed(PhantomData, PhantomData)
+ }
+
+ /// Returns the number of entries remaining in the map, if known.
+ #[inline]
+ fn size_hint(&self) -> Option<usize> {
+ None
+ }
+}
+
+impl<'de, 'a, A: ?Sized> MapAccess<'de> for &'a mut A
+where
+ A: MapAccess<'de>,
+{
+ type Error = A::Error;
+
+ #[inline]
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
+ where
+ K: DeserializeSeed<'de>,
+ {
+ (**self).next_key_seed(seed)
+ }
+
+ #[inline]
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ (**self).next_value_seed(seed)
+ }
+
+ #[inline]
+ fn next_entry_seed<K, V>(
+ &mut self,
+ kseed: K,
+ vseed: V,
+ ) -> Result<Option<(K::Value, V::Value)>, Self::Error>
+ where
+ K: DeserializeSeed<'de>,
+ V: DeserializeSeed<'de>,
+ {
+ (**self).next_entry_seed(kseed, vseed)
+ }
+
+ #[inline]
+ fn next_entry<K, V>(&mut self) -> Result<Option<(K, V)>, Self::Error>
+ where
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+ {
+ (**self).next_entry()
+ }
+
+ #[inline]
+ fn next_key<K>(&mut self) -> Result<Option<K>, Self::Error>
+ where
+ K: Deserialize<'de>,
+ {
+ (**self).next_key()
+ }
+
+ #[inline]
+ fn next_value<V>(&mut self) -> Result<V, Self::Error>
+ where
+ V: Deserialize<'de>,
+ {
+ (**self).next_value()
+ }
+
+ #[inline]
+ fn size_hint(&self) -> Option<usize> {
+ (**self).size_hint()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// Provides a `Visitor` access to the data of an enum in the input.
+///
+/// `EnumAccess` is created by the `Deserializer` and passed to the
+/// `Visitor` in order to identify which variant of an enum to deserialize.
+///
+/// # Lifetime
+///
+/// The `'de` lifetime of this trait is the lifetime of data that may be
+/// borrowed by the deserialized enum variant. See the page [Understanding
+/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
+///
+/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `EnumAccess` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait EnumAccess<'de>: Sized {
+ /// The error type that can be returned if some error occurs during
+ /// deserialization.
+ type Error: Error;
+ /// The `Visitor` that will be used to deserialize the content of the enum
+ /// variant.
+ type Variant: VariantAccess<'de, Error = Self::Error>;
+
+ /// `variant` is called to identify which variant to deserialize.
+ ///
+ /// `Deserialize` implementations should typically use `EnumAccess::variant`
+ /// instead.
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
+ where
+ V: DeserializeSeed<'de>;
+
+ /// `variant` is called to identify which variant to deserialize.
+ ///
+ /// This method exists as a convenience for `Deserialize` implementations.
+ /// `EnumAccess` implementations should not override the default behavior.
+ #[inline]
+ fn variant<V>(self) -> Result<(V, Self::Variant), Self::Error>
+ where
+ V: Deserialize<'de>,
+ {
+ self.variant_seed(PhantomData)
+ }
+}
+
+/// `VariantAccess` is a visitor that is created by the `Deserializer` and
+/// passed to the `Deserialize` to deserialize the content of a particular enum
+/// variant.
+///
+/// # Lifetime
+///
+/// The `'de` lifetime of this trait is the lifetime of data that may be
+/// borrowed by the deserialized enum variant. See the page [Understanding
+/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
+///
+/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `VariantAccess` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait VariantAccess<'de>: Sized {
+ /// The error type that can be returned if some error occurs during
+ /// deserialization. Must match the error type of our `EnumAccess`.
+ type Error: Error;
+
+ /// Called when deserializing a variant with no values.
+ ///
+ /// If the data contains a different type of variant, the following
+ /// `invalid_type` error should be constructed:
+ ///
+ /// ```edition2018
+ /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
+ /// #
+ /// # struct X;
+ /// #
+ /// # impl<'de> VariantAccess<'de> for X {
+ /// # type Error = value::Error;
+ /// #
+ /// 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>,
+ /// # { unimplemented!() }
+ /// #
+ /// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
+ /// # where
+ /// # V: Visitor<'de>,
+ /// # { unimplemented!() }
+ /// #
+ /// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
+ /// # 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
+ /// `VariantAccess::newtype_variant` instead.
+ ///
+ /// If the data contains a different type of variant, the following
+ /// `invalid_type` error should be constructed:
+ ///
+ /// ```edition2018
+ /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
+ /// #
+ /// # struct X;
+ /// #
+ /// # 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>,
+ /// {
+ /// // 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>,
+ /// # { unimplemented!() }
+ /// #
+ /// # fn struct_variant<V>(self, _: &[&str], _: V) -> Result<V::Value, Self::Error>
+ /// # 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.
+ ///
+ /// This method exists as a convenience for `Deserialize` implementations.
+ /// `VariantAccess` implementations should not override the default
+ /// behavior.
+ #[inline]
+ fn newtype_variant<T>(self) -> Result<T, Self::Error>
+ where
+ T: Deserialize<'de>,
+ {
+ self.newtype_variant_seed(PhantomData)
+ }
+
+ /// Called when deserializing a tuple-like variant.
+ ///
+ /// The `len` is the number of fields expected in the tuple variant.
+ ///
+ /// If the data contains a different type of variant, the following
+ /// `invalid_type` error should be constructed:
+ ///
+ /// ```edition2018
+ /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
+ /// #
+ /// # struct X;
+ /// #
+ /// # 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>,
+ /// # { unimplemented!() }
+ /// #
+ /// 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>,
+ /// # { 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.
+ ///
+ /// The `fields` are the names of the fields of the struct variant.
+ ///
+ /// If the data contains a different type of variant, the following
+ /// `invalid_type` error should be constructed:
+ ///
+ /// ```edition2018
+ /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
+ /// #
+ /// # struct X;
+ /// #
+ /// # 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>,
+ /// # { unimplemented!() }
+ /// #
+ /// # fn tuple_variant<V>(self, _: usize, _: V) -> Result<V::Value, Self::Error>
+ /// # 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>,
+ /// {
+ /// // 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>(
+ self,
+ fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// Converts an existing value into a `Deserializer` from which other values can
+/// be deserialized.
+///
+/// # Lifetime
+///
+/// The `'de` lifetime of this trait is the lifetime of data that may be
+/// borrowed from the resulting `Deserializer`. See the page [Understanding
+/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
+///
+/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
+///
+/// # Example
+///
+/// ```edition2018
+/// use std::str::FromStr;
+/// use serde::Deserialize;
+/// use serde::de::{value, IntoDeserializer};
+///
+/// #[derive(Deserialize)]
+/// enum Setting {
+/// On,
+/// Off,
+/// }
+///
+/// impl FromStr for Setting {
+/// type Err = value::Error;
+///
+/// fn from_str(s: &str) -> Result<Self, Self::Err> {
+/// Self::deserialize(s.into_deserializer())
+/// }
+/// }
+/// ```
+pub trait IntoDeserializer<'de, E: Error = value::Error> {
+ /// The type of the deserializer being converted into.
+ type Deserializer: Deserializer<'de, Error = E>;
+
+ /// Convert this value into a deserializer.
+ fn into_deserializer(self) -> Self::Deserializer;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// Used in error messages.
+///
+/// - expected `a`
+/// - expected `a` or `b`
+/// - expected one of `a`, `b`, `c`
+///
+/// The slice of names must not be empty.
+struct OneOf {
+ names: &'static [&'static str],
+}
+
+impl Display for OneOf {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self.names.len() {
+ 0 => panic!(), // special case elsewhere
+ 1 => write!(formatter, "`{}`", self.names[0]),
+ 2 => write!(formatter, "`{}` or `{}`", self.names[0], self.names[1]),
+ _ => {
+ try!(write!(formatter, "one of "));
+ for (i, alt) in self.names.iter().enumerate() {
+ if i > 0 {
+ try!(write!(formatter, ", "));
+ }
+ try!(write!(formatter, "`{}`", alt));
+ }
+ Ok(())
+ }
+ }
+ }
+}
diff --git a/third_party/rust/serde/src/de/seed.rs b/third_party/rust/serde/src/de/seed.rs
new file mode 100644
index 0000000000..13b7ea461b
--- /dev/null
+++ b/third_party/rust/serde/src/de/seed.rs
@@ -0,0 +1,19 @@
+use de::{Deserialize, DeserializeSeed, Deserializer};
+
+/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
+///
+/// Wraps a mutable reference and calls deserialize_in_place on it.
+pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
+
+impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
+where
+ T: Deserialize<'de>,
+{
+ type Value = ();
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ T::deserialize_in_place(deserializer, self.0)
+ }
+}
diff --git a/third_party/rust/serde/src/de/utf8.rs b/third_party/rust/serde/src/de/utf8.rs
new file mode 100644
index 0000000000..576fd03cfa
--- /dev/null
+++ b/third_party/rust/serde/src/de/utf8.rs
@@ -0,0 +1,46 @@
+use lib::*;
+
+const TAG_CONT: u8 = 0b1000_0000;
+const TAG_TWO_B: u8 = 0b1100_0000;
+const TAG_THREE_B: u8 = 0b1110_0000;
+const TAG_FOUR_B: u8 = 0b1111_0000;
+const MAX_ONE_B: u32 = 0x80;
+const MAX_TWO_B: u32 = 0x800;
+const MAX_THREE_B: u32 = 0x10000;
+
+#[inline]
+pub fn encode(c: char) -> Encode {
+ let code = c as u32;
+ let mut buf = [0; 4];
+ let pos = if code < MAX_ONE_B {
+ buf[3] = code as u8;
+ 3
+ } else if code < MAX_TWO_B {
+ buf[2] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
+ buf[3] = (code & 0x3F) as u8 | TAG_CONT;
+ 2
+ } else if code < MAX_THREE_B {
+ buf[1] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
+ buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
+ buf[3] = (code & 0x3F) as u8 | TAG_CONT;
+ 1
+ } else {
+ buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
+ buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT;
+ buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
+ buf[3] = (code & 0x3F) as u8 | TAG_CONT;
+ 0
+ };
+ Encode { buf: buf, pos: pos }
+}
+
+pub struct Encode {
+ buf: [u8; 4],
+ pos: usize,
+}
+
+impl Encode {
+ pub fn as_str(&self) -> &str {
+ str::from_utf8(&self.buf[self.pos..]).unwrap()
+ }
+}
diff --git a/third_party/rust/serde/src/de/value.rs b/third_party/rust/serde/src/de/value.rs
new file mode 100644
index 0000000000..5d88862159
--- /dev/null
+++ b/third_party/rust/serde/src/de/value.rs
@@ -0,0 +1,1714 @@
+//! Building blocks for deserializing basic values using the `IntoDeserializer`
+//! trait.
+//!
+//! ```edition2018
+//! use std::str::FromStr;
+//! use serde::Deserialize;
+//! use serde::de::{value, IntoDeserializer};
+//!
+//! #[derive(Deserialize)]
+//! enum Setting {
+//! On,
+//! Off,
+//! }
+//!
+//! impl FromStr for Setting {
+//! type Err = value::Error;
+//!
+//! fn from_str(s: &str) -> Result<Self, Self::Err> {
+//! Self::deserialize(s.into_deserializer())
+//! }
+//! }
+//! ```
+
+use lib::*;
+
+use self::private::{First, Second};
+use __private::size_hint;
+use de::{self, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
+use ser;
+
+////////////////////////////////////////////////////////////////////////////////
+
+// For structs that contain a PhantomData. We do not want the trait
+// bound `E: Clone` inferred by derive(Clone).
+macro_rules! impl_copy_clone {
+ ($ty:ident $(<$lifetime:tt>)*) => {
+ impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {}
+
+ impl<$($lifetime,)* E> Clone for $ty<$($lifetime,)* E> {
+ fn clone(&self) -> Self {
+ *self
+ }
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A minimal representation of all possible errors that can occur using the
+/// `IntoDeserializer` trait.
+#[derive(Clone, PartialEq)]
+pub struct Error {
+ err: ErrorImpl,
+}
+
+#[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)
+ }
+}
+
+impl Display for Error {
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(&self.err)
+ }
+
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("Serde deserialization error")
+ }
+}
+
+impl Debug for Error {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ let mut debug = formatter.debug_tuple("Error");
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ debug.field(&self.err);
+ debug.finish()
+ }
+}
+
+#[cfg(feature = "std")]
+impl error::Error for Error {
+ fn description(&self) -> &str {
+ &self.err
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl<'de, E> IntoDeserializer<'de, E> for ()
+where
+ E: de::Error,
+{
+ type Deserializer = UnitDeserializer<E>;
+
+ fn into_deserializer(self) -> UnitDeserializer<E> {
+ UnitDeserializer::new()
+ }
+}
+
+/// A deserializer holding a `()`.
+pub struct UnitDeserializer<E> {
+ marker: PhantomData<E>,
+}
+
+impl_copy_clone!(UnitDeserializer);
+
+impl<E> UnitDeserializer<E> {
+ #[allow(missing_docs)]
+ pub fn new() -> Self {
+ UnitDeserializer {
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'de, E> de::Deserializer<'de> for UnitDeserializer<E>
+where
+ E: de::Error,
+{
+ type Error = E;
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct
+ map struct enum identifier ignored_any
+ }
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_unit()
+ }
+
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_none()
+ }
+}
+
+impl<E> Debug for UnitDeserializer<E> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.debug_struct("UnitDeserializer").finish()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer that cannot be instantiated.
+#[cfg(feature = "unstable")]
+pub struct NeverDeserializer<E> {
+ never: !,
+ marker: PhantomData<E>,
+}
+
+#[cfg(feature = "unstable")]
+impl<'de, E> IntoDeserializer<'de, E> for !
+where
+ E: de::Error,
+{
+ type Deserializer = NeverDeserializer<E>;
+
+ fn into_deserializer(self) -> Self::Deserializer {
+ self
+ }
+}
+
+#[cfg(feature = "unstable")]
+impl<'de, E> de::Deserializer<'de> for NeverDeserializer<E>
+where
+ E: de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.never
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+macro_rules! primitive_deserializer {
+ ($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => {
+ #[doc = "A deserializer holding"]
+ #[doc = $doc]
+ pub struct $name<E> {
+ value: $ty,
+ marker: PhantomData<E>
+ }
+
+ impl_copy_clone!($name);
+
+ impl<'de, E> IntoDeserializer<'de, E> for $ty
+ where
+ E: de::Error,
+ {
+ type Deserializer = $name<E>;
+
+ fn into_deserializer(self) -> $name<E> {
+ $name::new(self)
+ }
+ }
+
+ impl<E> $name<E> {
+ #[allow(missing_docs)]
+ pub fn new(value: $ty) -> Self {
+ $name {
+ value: value,
+ marker: PhantomData,
+ }
+ }
+ }
+
+ impl<'de, E> de::Deserializer<'de> for $name<E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str
+ string bytes byte_buf option unit unit_struct newtype_struct seq
+ tuple tuple_struct map struct enum identifier ignored_any
+ }
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.$method(self.value $($cast)*)
+ }
+ }
+
+ impl<E> Debug for $name<E> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_struct(stringify!($name))
+ .field("value", &self.value)
+ .finish()
+ }
+ }
+ }
+}
+
+primitive_deserializer!(bool, "a `bool`.", BoolDeserializer, visit_bool);
+primitive_deserializer!(i8, "an `i8`.", I8Deserializer, visit_i8);
+primitive_deserializer!(i16, "an `i16`.", I16Deserializer, visit_i16);
+primitive_deserializer!(i32, "an `i32`.", I32Deserializer, visit_i32);
+primitive_deserializer!(i64, "an `i64`.", I64Deserializer, visit_i64);
+primitive_deserializer!(isize, "an `isize`.", IsizeDeserializer, visit_i64 as i64);
+primitive_deserializer!(u8, "a `u8`.", U8Deserializer, visit_u8);
+primitive_deserializer!(u16, "a `u16`.", U16Deserializer, visit_u16);
+primitive_deserializer!(u64, "a `u64`.", U64Deserializer, visit_u64);
+primitive_deserializer!(usize, "a `usize`.", UsizeDeserializer, visit_u64 as u64);
+primitive_deserializer!(f32, "an `f32`.", F32Deserializer, visit_f32);
+primitive_deserializer!(f64, "an `f64`.", F64Deserializer, visit_f64);
+primitive_deserializer!(char, "a `char`.", CharDeserializer, visit_char);
+
+serde_if_integer128! {
+ primitive_deserializer!(i128, "an `i128`.", I128Deserializer, visit_i128);
+ primitive_deserializer!(u128, "a `u128`.", U128Deserializer, visit_u128);
+}
+
+/// A deserializer holding a `u32`.
+pub struct U32Deserializer<E> {
+ value: u32,
+ marker: PhantomData<E>,
+}
+
+impl_copy_clone!(U32Deserializer);
+
+impl<'de, E> IntoDeserializer<'de, E> for u32
+where
+ E: de::Error,
+{
+ type Deserializer = U32Deserializer<E>;
+
+ fn into_deserializer(self) -> U32Deserializer<E> {
+ U32Deserializer::new(self)
+ }
+}
+
+impl<E> U32Deserializer<E> {
+ #[allow(missing_docs)]
+ pub fn new(value: u32) -> Self {
+ U32Deserializer {
+ value: value,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'de, E> de::Deserializer<'de> for U32Deserializer<E>
+where
+ E: de::Error,
+{
+ type Error = E;
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct identifier ignored_any
+ }
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_u32(self.value)
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ name: &str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let _ = name;
+ let _ = variants;
+ visitor.visit_enum(self)
+ }
+}
+
+impl<'de, E> de::EnumAccess<'de> for U32Deserializer<E>
+where
+ E: de::Error,
+{
+ type Error = E;
+ type Variant = private::UnitOnly<E>;
+
+ fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(self).map(private::unit_only)
+ }
+}
+
+impl<E> Debug for U32Deserializer<E> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_struct("U32Deserializer")
+ .field("value", &self.value)
+ .finish()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer holding a `&str`.
+pub struct StrDeserializer<'a, E> {
+ value: &'a str,
+ marker: PhantomData<E>,
+}
+
+impl_copy_clone!(StrDeserializer<'de>);
+
+impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str
+where
+ E: de::Error,
+{
+ type Deserializer = StrDeserializer<'a, E>;
+
+ fn into_deserializer(self) -> StrDeserializer<'a, E> {
+ StrDeserializer::new(self)
+ }
+}
+
+impl<'a, E> StrDeserializer<'a, E> {
+ #[allow(missing_docs)]
+ pub fn new(value: &'a str) -> Self {
+ StrDeserializer {
+ value: value,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'de, 'a, E> de::Deserializer<'de> for StrDeserializer<'a, E>
+where
+ E: de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_str(self.value)
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ name: &str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let _ = name;
+ let _ = variants;
+ visitor.visit_enum(self)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct identifier ignored_any
+ }
+}
+
+impl<'de, 'a, E> de::EnumAccess<'de> for StrDeserializer<'a, E>
+where
+ E: de::Error,
+{
+ type Error = E;
+ type Variant = private::UnitOnly<E>;
+
+ fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(self).map(private::unit_only)
+ }
+}
+
+impl<'a, E> Debug for StrDeserializer<'a, E> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_struct("StrDeserializer")
+ .field("value", &self.value)
+ .finish()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer holding a `&str` with a lifetime tied to another
+/// deserializer.
+pub struct BorrowedStrDeserializer<'de, E> {
+ value: &'de str,
+ marker: PhantomData<E>,
+}
+
+impl_copy_clone!(BorrowedStrDeserializer<'de>);
+
+impl<'de, E> BorrowedStrDeserializer<'de, E> {
+ /// Create a new borrowed deserializer from the given string.
+ pub fn new(value: &'de str) -> BorrowedStrDeserializer<'de, E> {
+ BorrowedStrDeserializer {
+ value: value,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'de, E> de::Deserializer<'de> for BorrowedStrDeserializer<'de, E>
+where
+ E: de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_borrowed_str(self.value)
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ name: &str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let _ = name;
+ let _ = variants;
+ visitor.visit_enum(self)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct identifier ignored_any
+ }
+}
+
+impl<'de, E> de::EnumAccess<'de> for BorrowedStrDeserializer<'de, E>
+where
+ E: de::Error,
+{
+ type Error = E;
+ type Variant = private::UnitOnly<E>;
+
+ fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(self).map(private::unit_only)
+ }
+}
+
+impl<'de, E> Debug for BorrowedStrDeserializer<'de, E> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_struct("BorrowedStrDeserializer")
+ .field("value", &self.value)
+ .finish()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer holding a `String`.
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct StringDeserializer<E> {
+ value: String,
+ marker: PhantomData<E>,
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<E> Clone for StringDeserializer<E> {
+ fn clone(&self) -> Self {
+ StringDeserializer {
+ value: self.value.clone(),
+ marker: PhantomData,
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de, E> IntoDeserializer<'de, E> for String
+where
+ E: de::Error,
+{
+ type Deserializer = StringDeserializer<E>;
+
+ fn into_deserializer(self) -> StringDeserializer<E> {
+ StringDeserializer::new(self)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<E> StringDeserializer<E> {
+ #[allow(missing_docs)]
+ pub fn new(value: String) -> Self {
+ StringDeserializer {
+ value: value,
+ marker: PhantomData,
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de, E> de::Deserializer<'de> for StringDeserializer<E>
+where
+ E: de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_string(self.value)
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ name: &str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let _ = name;
+ let _ = variants;
+ visitor.visit_enum(self)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct identifier ignored_any
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de, E> de::EnumAccess<'de> for StringDeserializer<E>
+where
+ E: de::Error,
+{
+ type Error = E;
+ type Variant = private::UnitOnly<E>;
+
+ fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(self).map(private::unit_only)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<E> Debug for StringDeserializer<E> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_struct("StringDeserializer")
+ .field("value", &self.value)
+ .finish()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer holding a `Cow<str>`.
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct CowStrDeserializer<'a, E> {
+ value: Cow<'a, str>,
+ marker: PhantomData<E>,
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, E> Clone for CowStrDeserializer<'a, E> {
+ fn clone(&self) -> Self {
+ CowStrDeserializer {
+ value: self.value.clone(),
+ marker: PhantomData,
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str>
+where
+ E: de::Error,
+{
+ type Deserializer = CowStrDeserializer<'a, E>;
+
+ fn into_deserializer(self) -> CowStrDeserializer<'a, E> {
+ CowStrDeserializer::new(self)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, E> CowStrDeserializer<'a, E> {
+ #[allow(missing_docs)]
+ pub fn new(value: Cow<'a, str>) -> Self {
+ CowStrDeserializer {
+ value: value,
+ marker: PhantomData,
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E>
+where
+ E: de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.value {
+ Cow::Borrowed(string) => visitor.visit_str(string),
+ Cow::Owned(string) => visitor.visit_string(string),
+ }
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ name: &str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let _ = name;
+ let _ = variants;
+ visitor.visit_enum(self)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct identifier ignored_any
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E>
+where
+ E: de::Error,
+{
+ type Error = E;
+ type Variant = private::UnitOnly<E>;
+
+ fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(self).map(private::unit_only)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, E> Debug for CowStrDeserializer<'a, E> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_struct("CowStrDeserializer")
+ .field("value", &self.value)
+ .finish()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer holding a `&[u8]`. Always calls [`Visitor::visit_bytes`].
+pub struct BytesDeserializer<'a, E> {
+ value: &'a [u8],
+ marker: PhantomData<E>,
+}
+
+impl<'a, E> BytesDeserializer<'a, E> {
+ /// Create a new deserializer from the given bytes.
+ pub fn new(value: &'a [u8]) -> Self {
+ BytesDeserializer {
+ value: value,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl_copy_clone!(BytesDeserializer<'a>);
+
+impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a [u8]
+where
+ E: de::Error,
+{
+ type Deserializer = BytesDeserializer<'a, E>;
+
+ fn into_deserializer(self) -> BytesDeserializer<'a, E> {
+ BytesDeserializer::new(self)
+ }
+}
+
+impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
+where
+ E: de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_bytes(self.value)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+impl<'a, E> Debug for BytesDeserializer<'a, E> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_struct("BytesDeserializer")
+ .field("value", &self.value)
+ .finish()
+ }
+}
+
+/// A deserializer holding a `&[u8]` with a lifetime tied to another
+/// deserializer. Always calls [`Visitor::visit_borrowed_bytes`].
+pub struct BorrowedBytesDeserializer<'de, E> {
+ value: &'de [u8],
+ marker: PhantomData<E>,
+}
+
+impl<'de, E> BorrowedBytesDeserializer<'de, E> {
+ /// Create a new borrowed deserializer from the given borrowed bytes.
+ pub fn new(value: &'de [u8]) -> Self {
+ BorrowedBytesDeserializer {
+ value: value,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl_copy_clone!(BorrowedBytesDeserializer<'de>);
+
+impl<'de, E> Deserializer<'de> for BorrowedBytesDeserializer<'de, E>
+where
+ E: de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_borrowed_bytes(self.value)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+impl<'de, E> Debug for BorrowedBytesDeserializer<'de, E> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_struct("BorrowedBytesDeserializer")
+ .field("value", &self.value)
+ .finish()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer that iterates over a sequence.
+#[derive(Clone)]
+pub struct SeqDeserializer<I, E> {
+ iter: iter::Fuse<I>,
+ count: usize,
+ marker: PhantomData<E>,
+}
+
+impl<I, E> SeqDeserializer<I, E>
+where
+ I: Iterator,
+{
+ /// Construct a new `SeqDeserializer<I, E>`.
+ pub fn new(iter: I) -> Self {
+ SeqDeserializer {
+ iter: iter.fuse(),
+ count: 0,
+ marker: PhantomData,
+ }
+ }
+}
+
+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(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),
+ ))
+ }
+ }
+}
+
+impl<'de, I, T, E> de::Deserializer<'de> for SeqDeserializer<I, E>
+where
+ I: Iterator<Item = T>,
+ T: IntoDeserializer<'de, E>,
+ E: de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let v = try!(visitor.visit_seq(&mut self));
+ try!(self.end());
+ Ok(v)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+impl<'de, I, T, E> de::SeqAccess<'de> for SeqDeserializer<I, E>
+where
+ I: Iterator<Item = T>,
+ T: IntoDeserializer<'de, E>,
+ E: de::Error,
+{
+ type Error = E;
+
+ fn next_element_seed<V>(&mut self, seed: V) -> Result<Option<V::Value>, Self::Error>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some(value) => {
+ self.count += 1;
+ seed.deserialize(value.into_deserializer()).map(Some)
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ size_hint::from_bounds(&self.iter)
+ }
+}
+
+struct ExpectedInSeq(usize);
+
+impl Expected for ExpectedInSeq {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ if self.0 == 1 {
+ write!(formatter, "1 element in sequence")
+ } else {
+ write!(formatter, "{} elements in sequence", self.0)
+ }
+ }
+}
+
+impl<I, E> Debug for SeqDeserializer<I, E>
+where
+ I: Debug,
+{
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_struct("SeqDeserializer")
+ .field("iter", &self.iter)
+ .field("count", &self.count)
+ .finish()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de, T, E> IntoDeserializer<'de, E> for Vec<T>
+where
+ T: IntoDeserializer<'de, E>,
+ E: de::Error,
+{
+ type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>;
+
+ fn into_deserializer(self) -> Self::Deserializer {
+ SeqDeserializer::new(self.into_iter())
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet<T>
+where
+ T: IntoDeserializer<'de, E> + Eq + Ord,
+ E: de::Error,
+{
+ type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>;
+
+ fn into_deserializer(self) -> Self::Deserializer {
+ SeqDeserializer::new(self.into_iter())
+ }
+}
+
+#[cfg(feature = "std")]
+impl<'de, T, S, E> IntoDeserializer<'de, E> for HashSet<T, S>
+where
+ T: IntoDeserializer<'de, E> + Eq + Hash,
+ S: BuildHasher,
+ E: de::Error,
+{
+ type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>;
+
+ fn into_deserializer(self) -> Self::Deserializer {
+ SeqDeserializer::new(self.into_iter())
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer holding a `SeqAccess`.
+#[derive(Clone, Debug)]
+pub struct SeqAccessDeserializer<A> {
+ seq: A,
+}
+
+impl<A> SeqAccessDeserializer<A> {
+ /// Construct a new `SeqAccessDeserializer<A>`.
+ pub fn new(seq: A) -> Self {
+ SeqAccessDeserializer { seq: seq }
+ }
+}
+
+impl<'de, A> de::Deserializer<'de> for SeqAccessDeserializer<A>
+where
+ A: de::SeqAccess<'de>,
+{
+ type Error = A::Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_seq(self.seq)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer that iterates over a map.
+pub struct MapDeserializer<'de, I, E>
+where
+ I: Iterator,
+ I::Item: private::Pair,
+{
+ iter: iter::Fuse<I>,
+ value: Option<Second<I::Item>>,
+ count: usize,
+ lifetime: PhantomData<&'de ()>,
+ error: PhantomData<E>,
+}
+
+impl<'de, I, E> MapDeserializer<'de, I, E>
+where
+ I: Iterator,
+ I::Item: private::Pair,
+{
+ /// Construct a new `MapDeserializer<I, E>`.
+ pub fn new(iter: I) -> Self {
+ MapDeserializer {
+ iter: iter.fuse(),
+ value: None,
+ count: 0,
+ lifetime: PhantomData,
+ error: PhantomData,
+ }
+ }
+}
+
+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(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),
+ ))
+ }
+ }
+}
+
+impl<'de, I, E> MapDeserializer<'de, I, E>
+where
+ I: Iterator,
+ I::Item: private::Pair,
+{
+ fn next_pair(&mut self) -> Option<(First<I::Item>, Second<I::Item>)> {
+ match self.iter.next() {
+ Some(kv) => {
+ self.count += 1;
+ Some(private::Pair::split(kv))
+ }
+ None => None,
+ }
+ }
+}
+
+impl<'de, I, E> de::Deserializer<'de> for MapDeserializer<'de, I, E>
+where
+ I: Iterator,
+ I::Item: private::Pair,
+ First<I::Item>: IntoDeserializer<'de, E>,
+ Second<I::Item>: IntoDeserializer<'de, E>,
+ E: de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let value = try!(visitor.visit_map(&mut self));
+ try!(self.end());
+ Ok(value)
+ }
+
+ fn deserialize_seq<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let value = try!(visitor.visit_seq(&mut self));
+ try!(self.end());
+ Ok(value)
+ }
+
+ fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let _ = len;
+ self.deserialize_seq(visitor)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct tuple_struct map
+ struct enum identifier ignored_any
+ }
+}
+
+impl<'de, I, E> de::MapAccess<'de> for MapDeserializer<'de, I, E>
+where
+ I: Iterator,
+ I::Item: private::Pair,
+ First<I::Item>: IntoDeserializer<'de, E>,
+ Second<I::Item>: IntoDeserializer<'de, E>,
+ E: de::Error,
+{
+ type Error = E;
+
+ fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.next_pair() {
+ Some((key, value)) => {
+ self.value = Some(value);
+ seed.deserialize(key.into_deserializer()).map(Some)
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ let value = self.value.take();
+ // Panic because this indicates a bug in the program rather than an
+ // expected failure.
+ let value = value.expect("MapAccess::next_value called before next_key");
+ seed.deserialize(value.into_deserializer())
+ }
+
+ fn next_entry_seed<TK, TV>(
+ &mut self,
+ kseed: TK,
+ vseed: TV,
+ ) -> Result<Option<(TK::Value, TV::Value)>, Self::Error>
+ where
+ TK: de::DeserializeSeed<'de>,
+ TV: de::DeserializeSeed<'de>,
+ {
+ match self.next_pair() {
+ Some((key, value)) => {
+ let key = try!(kseed.deserialize(key.into_deserializer()));
+ let value = try!(vseed.deserialize(value.into_deserializer()));
+ Ok(Some((key, value)))
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ size_hint::from_bounds(&self.iter)
+ }
+}
+
+impl<'de, I, E> de::SeqAccess<'de> for MapDeserializer<'de, I, E>
+where
+ I: Iterator,
+ I::Item: private::Pair,
+ First<I::Item>: IntoDeserializer<'de, E>,
+ Second<I::Item>: IntoDeserializer<'de, E>,
+ E: de::Error,
+{
+ type Error = E;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.next_pair() {
+ Some((k, v)) => {
+ let de = PairDeserializer(k, v, PhantomData);
+ seed.deserialize(de).map(Some)
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ size_hint::from_bounds(&self.iter)
+ }
+}
+
+// Cannot #[derive(Clone)] because of the bound `Second<I::Item>: Clone`.
+impl<'de, I, E> Clone for MapDeserializer<'de, I, E>
+where
+ I: Iterator + Clone,
+ I::Item: private::Pair,
+ Second<I::Item>: Clone,
+{
+ fn clone(&self) -> Self {
+ MapDeserializer {
+ iter: self.iter.clone(),
+ value: self.value.clone(),
+ count: self.count,
+ lifetime: self.lifetime,
+ error: self.error,
+ }
+ }
+}
+
+impl<'de, I, E> Debug for MapDeserializer<'de, I, E>
+where
+ I: Iterator + Debug,
+ I::Item: private::Pair,
+ Second<I::Item>: Debug,
+{
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_struct("MapDeserializer")
+ .field("iter", &self.iter)
+ .field("value", &self.value)
+ .field("count", &self.count)
+ .finish()
+ }
+}
+
+// Used in the `impl SeqAccess for MapDeserializer` to visit the map as a
+// sequence of pairs.
+struct PairDeserializer<A, B, E>(A, B, PhantomData<E>);
+
+impl<'de, A, B, E> de::Deserializer<'de> for PairDeserializer<A, B, E>
+where
+ A: IntoDeserializer<'de, E>,
+ B: IntoDeserializer<'de, E>,
+ E: de::Error,
+{
+ type Error = E;
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct tuple_struct map
+ struct enum identifier ignored_any
+ }
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), PhantomData);
+ let pair = try!(visitor.visit_seq(&mut pair_visitor));
+ if pair_visitor.1.is_none() {
+ Ok(pair)
+ } else {
+ let remaining = pair_visitor.size_hint().unwrap();
+ // 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(2, &ExpectedInSeq(2 - remaining)))
+ }
+ }
+
+ fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ if len == 2 {
+ self.deserialize_seq(visitor)
+ } 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(2, &ExpectedInSeq(len)))
+ }
+ }
+}
+
+struct PairVisitor<A, B, E>(Option<A>, Option<B>, PhantomData<E>);
+
+impl<'de, A, B, E> de::SeqAccess<'de> for PairVisitor<A, B, E>
+where
+ A: IntoDeserializer<'de, E>,
+ B: IntoDeserializer<'de, E>,
+ E: de::Error,
+{
+ type Error = E;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ if let Some(k) = self.0.take() {
+ seed.deserialize(k.into_deserializer()).map(Some)
+ } else if let Some(v) = self.1.take() {
+ seed.deserialize(v.into_deserializer()).map(Some)
+ } else {
+ Ok(None)
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ if self.0.is_some() {
+ Some(2)
+ } else if self.1.is_some() {
+ Some(1)
+ } else {
+ Some(0)
+ }
+ }
+}
+
+struct ExpectedInMap(usize);
+
+impl Expected for ExpectedInMap {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ if self.0 == 1 {
+ write!(formatter, "1 element in map")
+ } else {
+ write!(formatter, "{} elements in map", self.0)
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap<K, V>
+where
+ K: IntoDeserializer<'de, E> + Eq + Ord,
+ V: IntoDeserializer<'de, E>,
+ E: de::Error,
+{
+ type Deserializer = MapDeserializer<'de, <Self as IntoIterator>::IntoIter, E>;
+
+ fn into_deserializer(self) -> Self::Deserializer {
+ MapDeserializer::new(self.into_iter())
+ }
+}
+
+#[cfg(feature = "std")]
+impl<'de, K, V, S, E> IntoDeserializer<'de, E> for HashMap<K, V, S>
+where
+ K: IntoDeserializer<'de, E> + Eq + Hash,
+ V: IntoDeserializer<'de, E>,
+ S: BuildHasher,
+ E: de::Error,
+{
+ type Deserializer = MapDeserializer<'de, <Self as IntoIterator>::IntoIter, E>;
+
+ fn into_deserializer(self) -> Self::Deserializer {
+ MapDeserializer::new(self.into_iter())
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer holding a `MapAccess`.
+#[derive(Clone, Debug)]
+pub struct MapAccessDeserializer<A> {
+ map: A,
+}
+
+impl<A> MapAccessDeserializer<A> {
+ /// Construct a new `MapAccessDeserializer<A>`.
+ pub fn new(map: A) -> Self {
+ MapAccessDeserializer { map: map }
+ }
+}
+
+impl<'de, A> de::Deserializer<'de> for MapAccessDeserializer<A>
+where
+ A: de::MapAccess<'de>,
+{
+ type Error = A::Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_map(self.map)
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ _name: &str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_enum(self)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct identifier ignored_any
+ }
+}
+
+impl<'de, A> de::EnumAccess<'de> for MapAccessDeserializer<A>
+where
+ A: de::MapAccess<'de>,
+{
+ type Error = A::Error;
+ type Variant = private::MapAsEnum<A>;
+
+ fn variant_seed<T>(mut self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match try!(self.map.next_key_seed(seed)) {
+ Some(key) => Ok((key, private::map_as_enum(self.map))),
+ None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")),
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A deserializer holding an `EnumAccess`.
+#[derive(Clone, Debug)]
+pub struct EnumAccessDeserializer<A> {
+ access: A,
+}
+
+impl<A> EnumAccessDeserializer<A> {
+ /// Construct a new `EnumAccessDeserializer<A>`.
+ pub fn new(access: A) -> Self {
+ EnumAccessDeserializer { access: access }
+ }
+}
+
+impl<'de, A> de::Deserializer<'de> for EnumAccessDeserializer<A>
+where
+ A: de::EnumAccess<'de>,
+{
+ type Error = A::Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_enum(self.access)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+mod private {
+ use lib::*;
+
+ use de::{self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor};
+
+ pub struct UnitOnly<E> {
+ marker: PhantomData<E>,
+ }
+
+ pub fn unit_only<T, E>(t: T) -> (T, UnitOnly<E>) {
+ (
+ t,
+ UnitOnly {
+ marker: PhantomData,
+ },
+ )
+ }
+
+ impl<'de, E> de::VariantAccess<'de> for UnitOnly<E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ fn unit_variant(self) -> Result<(), Self::Error> {
+ Ok(())
+ }
+
+ fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"newtype variant",
+ ))
+ }
+
+ fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"tuple variant",
+ ))
+ }
+
+ fn struct_variant<V>(
+ self,
+ _fields: &'static [&'static str],
+ _visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"struct variant",
+ ))
+ }
+ }
+
+ pub struct MapAsEnum<A> {
+ map: A,
+ }
+
+ pub fn map_as_enum<A>(map: A) -> MapAsEnum<A> {
+ MapAsEnum { map: map }
+ }
+
+ impl<'de, A> VariantAccess<'de> for MapAsEnum<A>
+ where
+ A: MapAccess<'de>,
+ {
+ type Error = A::Error;
+
+ fn unit_variant(mut self) -> Result<(), Self::Error> {
+ self.map.next_value()
+ }
+
+ fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ self.map.next_value_seed(seed)
+ }
+
+ fn tuple_variant<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.map.next_value_seed(SeedTupleVariant {
+ len: len,
+ visitor: visitor,
+ })
+ }
+
+ fn struct_variant<V>(
+ mut self,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.map
+ .next_value_seed(SeedStructVariant { visitor: visitor })
+ }
+ }
+
+ struct SeedTupleVariant<V> {
+ len: usize,
+ visitor: V,
+ }
+
+ impl<'de, V> DeserializeSeed<'de> for SeedTupleVariant<V>
+ where
+ V: Visitor<'de>,
+ {
+ type Value = V::Value;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_tuple(self.len, self.visitor)
+ }
+ }
+
+ struct SeedStructVariant<V> {
+ visitor: V,
+ }
+
+ impl<'de, V> DeserializeSeed<'de> for SeedStructVariant<V>
+ where
+ V: Visitor<'de>,
+ {
+ type Value = V::Value;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_map(self.visitor)
+ }
+ }
+
+ /// Avoid having to restate the generic types on `MapDeserializer`. The
+ /// `Iterator::Item` contains enough information to figure out K and V.
+ pub trait Pair {
+ type First;
+ type Second;
+ fn split(self) -> (Self::First, Self::Second);
+ }
+
+ impl<A, B> Pair for (A, B) {
+ type First = A;
+ type Second = B;
+ fn split(self) -> (A, B) {
+ self
+ }
+ }
+
+ pub type First<T> = <T as Pair>::First;
+ pub type Second<T> = <T as Pair>::Second;
+}
diff --git a/third_party/rust/serde/src/integer128.rs b/third_party/rust/serde/src/integer128.rs
new file mode 100644
index 0000000000..904c2a233f
--- /dev/null
+++ b/third_party/rust/serde/src/integer128.rs
@@ -0,0 +1,82 @@
+/// Conditional compilation depending on whether Serde is built with support for
+/// 128-bit integers.
+///
+/// Data formats that wish to support Rust compiler versions older than 1.26
+/// (or targets that lack 128-bit integers) may place the i128 / u128 methods
+/// of their Serializer and Deserializer behind this macro.
+///
+/// Data formats that require a minimum Rust compiler version of at least 1.26,
+/// or do not target platforms that lack 128-bit integers, do not need to
+/// bother with this macro and may assume support for 128-bit integers.
+///
+/// ```edition2018
+/// # use serde::__private::doc::Error;
+/// #
+/// # struct MySerializer;
+/// #
+/// use serde::{serde_if_integer128, Serializer};
+///
+/// impl Serializer for MySerializer {
+/// type Ok = ();
+/// type Error = Error;
+///
+/// fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error> {
+/// /* ... */
+/// # unimplemented!()
+/// }
+///
+/// /* ... */
+///
+/// serde_if_integer128! {
+/// fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
+/// /* ... */
+/// # unimplemented!()
+/// }
+///
+/// fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
+/// /* ... */
+/// # unimplemented!()
+/// }
+/// }
+/// #
+/// # serde::__serialize_unimplemented! {
+/// # bool i8 i16 i32 u8 u16 u32 u64 f32 f64 char str bytes none some
+/// # unit unit_struct unit_variant newtype_struct newtype_variant seq
+/// # tuple tuple_struct tuple_variant map struct struct_variant
+/// # }
+/// }
+/// ```
+///
+/// When Serde is built with support for 128-bit integers, this macro expands
+/// transparently into just the input tokens.
+///
+/// ```edition2018
+/// macro_rules! serde_if_integer128 {
+/// ($($tt:tt)*) => {
+/// $($tt)*
+/// };
+/// }
+/// ```
+///
+/// When built without support for 128-bit integers, this macro expands to
+/// nothing.
+///
+/// ```edition2018
+/// macro_rules! serde_if_integer128 {
+/// ($($tt:tt)*) => {};
+/// }
+/// ```
+#[cfg(not(no_integer128))]
+#[macro_export]
+macro_rules! serde_if_integer128 {
+ ($($tt:tt)*) => {
+ $($tt)*
+ };
+}
+
+#[cfg(no_integer128)]
+#[macro_export]
+#[doc(hidden)]
+macro_rules! serde_if_integer128 {
+ ($($tt:tt)*) => {};
+}
diff --git a/third_party/rust/serde/src/lib.rs b/third_party/rust/serde/src/lib.rs
new file mode 100644
index 0000000000..e4bc7c8f19
--- /dev/null
+++ b/third_party/rust/serde/src/lib.rs
@@ -0,0 +1,334 @@
+//! # Serde
+//!
+//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
+//! structures efficiently and generically.
+//!
+//! The Serde ecosystem consists of data structures that know how to serialize
+//! and deserialize themselves along with data formats that know how to
+//! serialize and deserialize other things. Serde provides the layer by which
+//! these two groups interact with each other, allowing any supported data
+//! structure to be serialized and deserialized using any supported data format.
+//!
+//! See the Serde website <https://serde.rs/> for additional documentation and
+//! usage examples.
+//!
+//! ## Design
+//!
+//! Where many other languages rely on runtime reflection for serializing data,
+//! Serde is instead built on Rust's powerful trait system. A data structure
+//! that knows how to serialize and deserialize itself is one that implements
+//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
+//! attribute to automatically generate implementations at compile time). This
+//! avoids any overhead of reflection or runtime type information. In fact in
+//! many situations the interaction between data structure and data format can
+//! be completely optimized away by the Rust compiler, leaving Serde
+//! serialization to perform the same speed as a handwritten serializer for the
+//! specific selection of data structure and data format.
+//!
+//! ## Data formats
+//!
+//! The following is a partial list of data formats that have been implemented
+//! for Serde by the community.
+//!
+//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
+//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
+//! - [CBOR], a Concise Binary Object Representation designed for small message
+//! size without the need for version negotiation.
+//! - [YAML], a self-proclaimed human-friendly configuration language that ain't
+//! markup language.
+//! - [MessagePack], an efficient binary format that resembles a compact JSON.
+//! - [TOML], a minimal configuration format used by [Cargo].
+//! - [Pickle], a format common in the Python world.
+//! - [RON], a Rusty Object Notation.
+//! - [BSON], the data storage and network transfer format used by MongoDB.
+//! - [Avro], a binary format used within Apache Hadoop, with support for schema
+//! definition.
+//! - [JSON5], a superset of JSON including some productions from ES5.
+//! - [URL] query strings, in the x-www-form-urlencoded format.
+//! - [Envy], a way to deserialize environment variables into Rust structs.
+//! *(deserialization only)*
+//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
+//! Rust structs. *(deserialization only)*
+//! - [S-expressions], the textual representation of code and data used by the
+//! Lisp language family.
+//! - [D-Bus]'s binary wire format.
+//! - [FlexBuffers], the schemaless cousin of Google's FlatBuffers zero-copy
+//! serialization format.
+//! - [Bencode], a simple binary format used in the BitTorrent protocol.
+//! - [Token streams], for processing Rust procedural macro input.
+//! *(deserialization only)*
+//! - [DynamoDB Items], the format used by [rusoto_dynamodb] to transfer data to
+//! and from DynamoDB.
+//! - [Hjson], a syntax extension to JSON designed around human reading and
+//! editing. *(deserialization only)*
+//!
+//! [JSON]: https://github.com/serde-rs/json
+//! [Postcard]: https://github.com/jamesmunns/postcard
+//! [CBOR]: https://github.com/enarx/ciborium
+//! [YAML]: https://github.com/dtolnay/serde-yaml
+//! [MessagePack]: https://github.com/3Hren/msgpack-rust
+//! [TOML]: https://docs.rs/toml
+//! [Pickle]: https://github.com/birkenfeld/serde-pickle
+//! [RON]: https://github.com/ron-rs/ron
+//! [BSON]: https://github.com/mongodb/bson-rust
+//! [Avro]: https://docs.rs/apache-avro
+//! [JSON5]: https://github.com/callum-oakley/json5-rs
+//! [URL]: https://docs.rs/serde_qs
+//! [Envy]: https://github.com/softprops/envy
+//! [Envy Store]: https://github.com/softprops/envy-store
+//! [Cargo]: https://doc.rust-lang.org/cargo/reference/manifest.html
+//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html
+//! [S-expressions]: https://github.com/rotty/lexpr-rs
+//! [D-Bus]: https://docs.rs/zvariant
+//! [FlexBuffers]: https://github.com/google/flatbuffers/tree/master/rust/flexbuffers
+//! [Bencode]: https://github.com/P3KI/bendy
+//! [Token streams]: https://github.com/oxidecomputer/serde_tokenstream
+//! [DynamoDB Items]: https://docs.rs/serde_dynamo
+//! [rusoto_dynamodb]: https://docs.rs/rusoto_dynamodb
+//! [Hjson]: https://github.com/Canop/deser-hjson
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Serde types in rustdoc of other crates get linked to here.
+#![doc(html_root_url = "https://docs.rs/serde/1.0.152")]
+// 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(error_in_core, never_type))]
+#![allow(unknown_lints, bare_trait_objects, deprecated)]
+#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
+// Ignored clippy and clippy_pedantic lints
+#![cfg_attr(
+ feature = "cargo-clippy",
+ allow(
+ // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
+ unnested_or_patterns,
+ // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768
+ semicolon_if_nothing_returned,
+ // not available in our oldest supported compiler
+ empty_enum,
+ type_repetition_in_bounds, // https://github.com/rust-lang/rust-clippy/issues/8772
+ // integer and float ser/de requires these sorts of casts
+ cast_possible_truncation,
+ cast_possible_wrap,
+ cast_sign_loss,
+ // things are often more readable this way
+ cast_lossless,
+ module_name_repetitions,
+ option_if_let_else,
+ single_match_else,
+ type_complexity,
+ use_self,
+ zero_prefixed_literal,
+ // correctly used
+ derive_partial_eq_without_eq,
+ enum_glob_use,
+ explicit_auto_deref,
+ map_err_ignore,
+ new_without_default,
+ result_unit_err,
+ wildcard_imports,
+ // not practical
+ needless_pass_by_value,
+ similar_names,
+ too_many_lines,
+ // preference
+ doc_markdown,
+ unseparated_literal_suffix,
+ // false positive
+ needless_doctest_main,
+ // noisy
+ missing_errors_doc,
+ must_use_candidate,
+ )
+)]
+// Rustc lints.
+#![deny(missing_docs, unused_imports)]
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+/// A facade around all the types we need from the `std`, `core`, and `alloc`
+/// crates. This avoids elaborate import wrangling having to happen in every
+/// module.
+mod lib {
+ mod core {
+ #[cfg(not(feature = "std"))]
+ pub use core::*;
+ #[cfg(feature = "std")]
+ pub use std::*;
+ }
+
+ pub use self::core::{cmp, iter, mem, num, ptr, slice, str};
+ pub use self::core::{f32, f64};
+ 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::num::Wrapping;
+ pub use self::core::ops::Range;
+ pub use self::core::option::{self, Option};
+ pub use self::core::result::{self, Result};
+
+ #[cfg(all(feature = "alloc", not(feature = "std")))]
+ pub use alloc::borrow::{Cow, ToOwned};
+ #[cfg(feature = "std")]
+ pub use std::borrow::{Cow, ToOwned};
+
+ #[cfg(all(feature = "alloc", not(feature = "std")))]
+ pub use alloc::string::{String, ToString};
+ #[cfg(feature = "std")]
+ pub use std::string::{String, ToString};
+
+ #[cfg(all(feature = "alloc", not(feature = "std")))]
+ pub use alloc::vec::Vec;
+ #[cfg(feature = "std")]
+ 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, Weak as RcWeak};
+ #[cfg(all(feature = "rc", feature = "std"))]
+ pub use std::rc::{Rc, Weak as RcWeak};
+
+ #[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
+ pub use alloc::sync::{Arc, Weak as ArcWeak};
+ #[cfg(all(feature = "rc", feature = "std"))]
+ pub use std::sync::{Arc, Weak as ArcWeak};
+
+ #[cfg(all(feature = "alloc", not(feature = "std")))]
+ pub use alloc::collections::{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};
+
+ #[cfg(feature = "std")]
+ pub use std::collections::{HashMap, HashSet};
+ #[cfg(feature = "std")]
+ pub use std::ffi::{CStr, CString, OsStr, OsString};
+ #[cfg(feature = "std")]
+ pub use std::hash::{BuildHasher, Hash};
+ #[cfg(feature = "std")]
+ pub use std::io::Write;
+ #[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::{SystemTime, UNIX_EPOCH};
+
+ #[cfg(all(feature = "std", not(no_collections_bound), no_ops_bound))]
+ pub use std::collections::Bound;
+
+ #[cfg(not(no_core_reverse))]
+ pub use self::core::cmp::Reverse;
+
+ #[cfg(not(no_ops_bound))]
+ pub use self::core::ops::Bound;
+
+ #[cfg(not(no_range_inclusive))]
+ pub use self::core::ops::RangeInclusive;
+
+ #[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic)))]
+ pub use std::sync::atomic::{
+ AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
+ AtomicUsize, Ordering,
+ };
+ #[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic64)))]
+ pub use std::sync::atomic::{AtomicI64, AtomicU64};
+
+ #[cfg(all(feature = "std", not(no_target_has_atomic)))]
+ pub use std::sync::atomic::Ordering;
+ #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "8"))]
+ pub use std::sync::atomic::{AtomicBool, AtomicI8, AtomicU8};
+ #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "16"))]
+ pub use std::sync::atomic::{AtomicI16, AtomicU16};
+ #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "32"))]
+ pub use std::sync::atomic::{AtomicI32, AtomicU32};
+ #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "64"))]
+ pub use std::sync::atomic::{AtomicI64, AtomicU64};
+ #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "ptr"))]
+ pub use std::sync::atomic::{AtomicIsize, AtomicUsize};
+
+ #[cfg(any(feature = "std", not(no_core_duration)))]
+ pub use self::core::time::Duration;
+}
+
+// None of this crate's error handling needs the `From::from` error conversion
+// performed implicitly by the `?` operator or the standard library's `try!`
+// macro. This simplified macro gives a 5.5% improvement in compile time
+// compared to standard `try!`, and 9% improvement compared to `?`.
+macro_rules! try {
+ ($expr:expr) => {
+ match $expr {
+ Ok(val) => val,
+ Err(err) => return Err(err),
+ }
+ };
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[macro_use]
+mod macros;
+
+#[macro_use]
+mod integer128;
+
+pub mod de;
+pub mod ser;
+
+#[doc(inline)]
+pub use de::{Deserialize, Deserializer};
+#[doc(inline)]
+pub use ser::{Serialize, Serializer};
+
+// Used by generated code and doc tests. Not public API.
+#[doc(hidden)]
+#[path = "private/mod.rs"]
+pub mod __private;
+
+#[allow(unused_imports)]
+use self::__private as export;
+#[allow(unused_imports)]
+use self::__private as private;
+
+#[path = "de/seed.rs"]
+mod seed;
+
+#[cfg(not(any(feature = "std", feature = "unstable")))]
+mod std_error;
+
+// Re-export #[derive(Serialize, Deserialize)].
+//
+// The reason re-exporting is not enabled by default is that disabling it would
+// be annoying for crates that provide handwritten impls or data formats. They
+// would need to disable default features and then explicitly re-enable std.
+#[cfg(feature = "serde_derive")]
+#[allow(unused_imports)]
+#[macro_use]
+extern crate serde_derive;
+#[cfg(feature = "serde_derive")]
+#[doc(hidden)]
+pub use serde_derive::*;
+
+#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
+mod actually_private {
+ pub struct T;
+}
diff --git a/third_party/rust/serde/src/macros.rs b/third_party/rust/serde/src/macros.rs
new file mode 100644
index 0000000000..6502a23a7a
--- /dev/null
+++ b/third_party/rust/serde/src/macros.rs
@@ -0,0 +1,236 @@
+// Super explicit first paragraph because this shows up at the top level and
+// trips up people who are just looking for basic Serialize / Deserialize
+// documentation.
+//
+/// Helper macro when implementing the `Deserializer` part of a new data format
+/// for Serde.
+///
+/// Some [`Deserializer`] implementations for self-describing formats do not
+/// care what hint the [`Visitor`] gives them, they just want to blindly call
+/// the [`Visitor`] method corresponding to the data they can tell is in the
+/// input. This requires repetitive implementations of all the [`Deserializer`]
+/// trait methods.
+///
+/// ```edition2018
+/// # use serde::forward_to_deserialize_any;
+/// # 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>,
+/// # {
+/// # unimplemented!()
+/// # }
+/// #
+/// #[inline]
+/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+/// where
+/// V: Visitor<'de>,
+/// {
+/// self.deserialize_any(visitor)
+/// }
+/// #
+/// # forward_to_deserialize_any! {
+/// # i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+/// # bytes byte_buf option unit unit_struct newtype_struct seq tuple
+/// # tuple_struct map struct enum identifier ignored_any
+/// # }
+/// # }
+/// ```
+///
+/// The `forward_to_deserialize_any!` macro implements these simple forwarding
+/// methods so that they forward directly to [`Deserializer::deserialize_any`].
+/// You can choose which methods to forward.
+///
+/// ```edition2018
+/// # use serde::forward_to_deserialize_any;
+/// # 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>,
+/// {
+/// /* ... */
+/// # let _ = visitor;
+/// # unimplemented!()
+/// }
+///
+/// forward_to_deserialize_any! {
+/// bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+/// bytes byte_buf option unit unit_struct newtype_struct seq tuple
+/// tuple_struct map struct enum identifier ignored_any
+/// }
+/// }
+/// ```
+///
+/// The macro assumes the convention that your `Deserializer` lifetime parameter
+/// is called `'de` and that the `Visitor` type parameters on each method are
+/// called `V`. A different type parameter and a different lifetime can be
+/// specified explicitly if necessary.
+///
+/// ```edition2018
+/// # use std::marker::PhantomData;
+/// #
+/// # use serde::forward_to_deserialize_any;
+/// # 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>,
+/// # {
+/// # unimplemented!()
+/// # }
+/// #
+/// forward_to_deserialize_any! {
+/// <W: Visitor<'q>>
+/// bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+/// bytes byte_buf option unit unit_struct newtype_struct seq tuple
+/// tuple_struct map struct enum identifier ignored_any
+/// }
+/// # }
+/// ```
+///
+/// [`Deserializer`]: trait.Deserializer.html
+/// [`Visitor`]: de/trait.Visitor.html
+/// [`Deserializer::deserialize_any`]: trait.Deserializer.html#tymethod.deserialize_any
+#[macro_export(local_inner_macros)]
+macro_rules! forward_to_deserialize_any {
+ (<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => {
+ $(forward_to_deserialize_any_helper!{$func<$lifetime, $visitor>})*
+ };
+ // This case must be after the previous one.
+ ($($func:ident)*) => {
+ $(forward_to_deserialize_any_helper!{$func<'de, V>})*
+ };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! forward_to_deserialize_any_method {
+ ($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => {
+ #[inline]
+ fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::__private::Result<$v::Value, Self::Error>
+ where
+ $v: $crate::de::Visitor<$l>,
+ {
+ $(
+ let _ = $arg;
+ )*
+ self.deserialize_any(visitor)
+ }
+ };
+}
+
+#[doc(hidden)]
+#[macro_export(local_inner_macros)]
+macro_rules! forward_to_deserialize_any_helper {
+ (bool<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_bool<$l, $v>()}
+ };
+ (i8<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_i8<$l, $v>()}
+ };
+ (i16<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_i16<$l, $v>()}
+ };
+ (i32<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_i32<$l, $v>()}
+ };
+ (i64<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_i64<$l, $v>()}
+ };
+ (i128<$l:tt, $v:ident>) => {
+ serde_if_integer128! {
+ forward_to_deserialize_any_method!{deserialize_i128<$l, $v>()}
+ }
+ };
+ (u8<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()}
+ };
+ (u16<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_u16<$l, $v>()}
+ };
+ (u32<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_u32<$l, $v>()}
+ };
+ (u64<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()}
+ };
+ (u128<$l:tt, $v:ident>) => {
+ serde_if_integer128! {
+ forward_to_deserialize_any_method!{deserialize_u128<$l, $v>()}
+ }
+ };
+ (f32<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_f32<$l, $v>()}
+ };
+ (f64<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_f64<$l, $v>()}
+ };
+ (char<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_char<$l, $v>()}
+ };
+ (str<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_str<$l, $v>()}
+ };
+ (string<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_string<$l, $v>()}
+ };
+ (bytes<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_bytes<$l, $v>()}
+ };
+ (byte_buf<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_byte_buf<$l, $v>()}
+ };
+ (option<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_option<$l, $v>()}
+ };
+ (unit<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_unit<$l, $v>()}
+ };
+ (unit_struct<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_unit_struct<$l, $v>(name: &'static str)}
+ };
+ (newtype_struct<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)}
+ };
+ (seq<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_seq<$l, $v>()}
+ };
+ (tuple<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_tuple<$l, $v>(len: usize)}
+ };
+ (tuple_struct<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)}
+ };
+ (map<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_map<$l, $v>()}
+ };
+ (struct<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])}
+ };
+ (enum<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])}
+ };
+ (identifier<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_identifier<$l, $v>()}
+ };
+ (ignored_any<$l:tt, $v:ident>) => {
+ forward_to_deserialize_any_method!{deserialize_ignored_any<$l, $v>()}
+ };
+}
diff --git a/third_party/rust/serde/src/private/de.rs b/third_party/rust/serde/src/private/de.rs
new file mode 100644
index 0000000000..e9c693d4dd
--- /dev/null
+++ b/third_party/rust/serde/src/private/de.rs
@@ -0,0 +1,2995 @@
+use lib::*;
+
+use de::value::{BorrowedBytesDeserializer, BytesDeserializer};
+use de::{Deserialize, Deserializer, Error, IntoDeserializer, Visitor};
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+use de::{DeserializeSeed, 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 seed::InPlaceSeed;
+
+/// 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,
+{
+ struct MissingFieldDeserializer<E>(&'static str, PhantomData<E>);
+
+ impl<'de, E> Deserializer<'de> for MissingFieldDeserializer<E>
+ where
+ E: Error,
+ {
+ type Error = E;
+
+ fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ {
+ Err(Error::missing_field(self.0))
+ }
+
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_none()
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+ }
+
+ let deserializer = MissingFieldDeserializer(field, PhantomData);
+ Deserialize::deserialize(deserializer)
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub fn borrow_cow_str<'de: 'a, 'a, D, R>(deserializer: D) -> Result<R, D::Error>
+where
+ D: Deserializer<'de>,
+ R: From<Cow<'a, str>>,
+{
+ struct CowStrVisitor;
+
+ impl<'a> Visitor<'a> for CowStrVisitor {
+ type Value = Cow<'a, str>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a string")
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.to_owned()))
+ }
+
+ fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Borrowed(v))
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v))
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match str::from_utf8(v) {
+ Ok(s) => Ok(Cow::Owned(s.to_owned())),
+ Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
+ }
+ }
+
+ fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match str::from_utf8(v) {
+ Ok(s) => Ok(Cow::Borrowed(s)),
+ Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
+ }
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match String::from_utf8(v) {
+ Ok(s) => Ok(Cow::Owned(s)),
+ Err(e) => Err(Error::invalid_value(
+ Unexpected::Bytes(&e.into_bytes()),
+ &self,
+ )),
+ }
+ }
+ }
+
+ deserializer.deserialize_str(CowStrVisitor).map(From::from)
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub fn borrow_cow_bytes<'de: 'a, 'a, D, R>(deserializer: D) -> Result<R, D::Error>
+where
+ D: Deserializer<'de>,
+ R: From<Cow<'a, [u8]>>,
+{
+ struct CowBytesVisitor;
+
+ impl<'a> Visitor<'a> for CowBytesVisitor {
+ type Value = Cow<'a, [u8]>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a byte array")
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.as_bytes().to_vec()))
+ }
+
+ fn visit_borrowed_str<E>(self, v: &'a str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Borrowed(v.as_bytes()))
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.into_bytes()))
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.to_vec()))
+ }
+
+ fn visit_borrowed_bytes<E>(self, v: &'a [u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Borrowed(v))
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v))
+ }
+ }
+
+ deserializer
+ .deserialize_bytes(CowBytesVisitor)
+ .map(From::from)
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+mod content {
+ // This module is private and nothing here should be used outside of
+ // generated code.
+ //
+ // We will iterate on the implementation for a few releases and only have to
+ // worry about backward compatibility for the `untagged` and `tag` attributes
+ // 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 __private::size_hint;
+ use actually_private;
+ use de::{
+ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
+ 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, Clone)]
+ pub enum Content<'de> {
+ Bool(bool),
+
+ U8(u8),
+ U16(u16),
+ U32(u32),
+ U64(u64),
+
+ I8(i8),
+ I16(i16),
+ I32(i32),
+ I64(i64),
+
+ F32(f32),
+ F64(f64),
+
+ Char(char),
+ String(String),
+ Str(&'de str),
+ ByteBuf(Vec<u8>),
+ Bytes(&'de [u8]),
+
+ None,
+ Some(Box<Content<'de>>),
+
+ Unit,
+ Newtype(Box<Content<'de>>),
+ Seq(Vec<Content<'de>>),
+ 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),
+ Content::I16(n) => Unexpected::Signed(n as i64),
+ Content::I32(n) => Unexpected::Signed(n as i64),
+ Content::I64(n) => Unexpected::Signed(n),
+ Content::F32(f) => Unexpected::Float(f as f64),
+ Content::F64(f) => Unexpected::Float(f),
+ Content::Char(c) => Unexpected::Char(c),
+ Content::String(ref s) => Unexpected::Str(s),
+ Content::Str(s) => Unexpected::Str(s),
+ Content::ByteBuf(ref b) => Unexpected::Bytes(b),
+ Content::Bytes(b) => Unexpected::Bytes(b),
+ Content::None | Content::Some(_) => Unexpected::Option,
+ Content::Unit => Unexpected::Unit,
+ Content::Newtype(_) => Unexpected::NewtypeStruct,
+ Content::Seq(_) => Unexpected::Seq,
+ Content::Map(_) => Unexpected::Map,
+ }
+ }
+ }
+
+ impl<'de> Deserialize<'de> for Content<'de> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // Untagged and internally tagged enums are only supported in
+ // self-describing formats.
+ let visitor = ContentVisitor { value: PhantomData };
+ deserializer.__deserialize_content(actually_private::T, visitor)
+ }
+ }
+
+ struct ContentVisitor<'de> {
+ value: PhantomData<Content<'de>>,
+ }
+
+ impl<'de> ContentVisitor<'de> {
+ fn new() -> Self {
+ ContentVisitor { value: PhantomData }
+ }
+ }
+
+ impl<'de> Visitor<'de> for ContentVisitor<'de> {
+ type Value = Content<'de>;
+
+ fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt.write_str("any value")
+ }
+
+ fn visit_bool<F>(self, value: bool) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::Bool(value))
+ }
+
+ fn visit_i8<F>(self, value: i8) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::I8(value))
+ }
+
+ fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::I16(value))
+ }
+
+ fn visit_i32<F>(self, value: i32) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::I32(value))
+ }
+
+ fn visit_i64<F>(self, value: i64) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::I64(value))
+ }
+
+ fn visit_u8<F>(self, value: u8) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::U8(value))
+ }
+
+ fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::U16(value))
+ }
+
+ fn visit_u32<F>(self, value: u32) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::U32(value))
+ }
+
+ fn visit_u64<F>(self, value: u64) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::U64(value))
+ }
+
+ fn visit_f32<F>(self, value: f32) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::F32(value))
+ }
+
+ fn visit_f64<F>(self, value: f64) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::F64(value))
+ }
+
+ fn visit_char<F>(self, value: char) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::Char(value))
+ }
+
+ fn visit_str<F>(self, value: &str) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::String(value.into()))
+ }
+
+ fn visit_borrowed_str<F>(self, value: &'de str) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::Str(value))
+ }
+
+ fn visit_string<F>(self, value: String) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::String(value))
+ }
+
+ fn visit_bytes<F>(self, value: &[u8]) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::ByteBuf(value.into()))
+ }
+
+ fn visit_borrowed_bytes<F>(self, value: &'de [u8]) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::Bytes(value))
+ }
+
+ fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::ByteBuf(value))
+ }
+
+ fn visit_unit<F>(self) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::Unit)
+ }
+
+ fn visit_none<F>(self) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ Ok(Content::None)
+ }
+
+ fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer).map(|v| Content::Some(Box::new(v)))
+ }
+
+ fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer).map(|v| Content::Newtype(Box::new(v)))
+ }
+
+ fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: SeqAccess<'de>,
+ {
+ let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint()));
+ while let Some(e) = try!(visitor.next_element()) {
+ vec.push(e);
+ }
+ Ok(Content::Seq(vec))
+ }
+
+ fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: MapAccess<'de>,
+ {
+ let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint()));
+ while let Some(kv) = try!(visitor.next_entry()) {
+ vec.push(kv);
+ }
+ Ok(Content::Map(vec))
+ }
+
+ fn visit_enum<V>(self, _visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: EnumAccess<'de>,
+ {
+ Err(de::Error::custom(
+ "untagged and internally tagged enums do not support enum input",
+ ))
+ }
+ }
+
+ /// This is the type of the map keys in an internally tagged enum.
+ ///
+ /// Not public API.
+ pub enum TagOrContent<'de> {
+ Tag,
+ Content(Content<'de>),
+ }
+
+ struct TagOrContentVisitor<'de> {
+ name: &'static str,
+ value: PhantomData<TagOrContent<'de>>,
+ }
+
+ impl<'de> TagOrContentVisitor<'de> {
+ fn new(name: &'static str) -> Self {
+ TagOrContentVisitor {
+ name: name,
+ value: PhantomData,
+ }
+ }
+ }
+
+ impl<'de> DeserializeSeed<'de> for TagOrContentVisitor<'de> {
+ type Value = TagOrContent<'de>;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // Internally tagged enums are only supported in self-describing
+ // formats.
+ deserializer.deserialize_any(self)
+ }
+ }
+
+ impl<'de> Visitor<'de> for TagOrContentVisitor<'de> {
+ type Value = TagOrContent<'de>;
+
+ fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ write!(fmt, "a type tag `{}` or any other value", self.name)
+ }
+
+ fn visit_bool<F>(self, value: bool) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_bool(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_i8<F>(self, value: i8) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_i8(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_i16<F>(self, value: i16) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_i16(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_i32<F>(self, value: i32) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_i32(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_i64<F>(self, value: i64) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_i64(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_u8<F>(self, value: u8) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_u8(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_u16<F>(self, value: u16) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_u16(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_u32<F>(self, value: u32) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_u32(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_u64<F>(self, value: u64) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_u64(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_f32<F>(self, value: f32) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_f32(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_f64<F>(self, value: f64) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_f64(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_char<F>(self, value: char) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_char(value)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_str<F>(self, value: &str) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ if value == self.name {
+ Ok(TagOrContent::Tag)
+ } else {
+ ContentVisitor::new()
+ .visit_str(value)
+ .map(TagOrContent::Content)
+ }
+ }
+
+ fn visit_borrowed_str<F>(self, value: &'de str) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ if value == self.name {
+ Ok(TagOrContent::Tag)
+ } else {
+ ContentVisitor::new()
+ .visit_borrowed_str(value)
+ .map(TagOrContent::Content)
+ }
+ }
+
+ fn visit_string<F>(self, value: String) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ if value == self.name {
+ Ok(TagOrContent::Tag)
+ } else {
+ ContentVisitor::new()
+ .visit_string(value)
+ .map(TagOrContent::Content)
+ }
+ }
+
+ fn visit_bytes<F>(self, value: &[u8]) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ if value == self.name.as_bytes() {
+ Ok(TagOrContent::Tag)
+ } else {
+ ContentVisitor::new()
+ .visit_bytes(value)
+ .map(TagOrContent::Content)
+ }
+ }
+
+ fn visit_borrowed_bytes<F>(self, value: &'de [u8]) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ if value == self.name.as_bytes() {
+ Ok(TagOrContent::Tag)
+ } else {
+ ContentVisitor::new()
+ .visit_borrowed_bytes(value)
+ .map(TagOrContent::Content)
+ }
+ }
+
+ fn visit_byte_buf<F>(self, value: Vec<u8>) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ if value == self.name.as_bytes() {
+ Ok(TagOrContent::Tag)
+ } else {
+ ContentVisitor::new()
+ .visit_byte_buf(value)
+ .map(TagOrContent::Content)
+ }
+ }
+
+ fn visit_unit<F>(self) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_unit()
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_none<F>(self) -> Result<Self::Value, F>
+ where
+ F: de::Error,
+ {
+ ContentVisitor::new()
+ .visit_none()
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ ContentVisitor::new()
+ .visit_some(deserializer)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ ContentVisitor::new()
+ .visit_newtype_struct(deserializer)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_seq<V>(self, visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: SeqAccess<'de>,
+ {
+ ContentVisitor::new()
+ .visit_seq(visitor)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_map<V>(self, visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: MapAccess<'de>,
+ {
+ ContentVisitor::new()
+ .visit_map(visitor)
+ .map(TagOrContent::Content)
+ }
+
+ fn visit_enum<V>(self, visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: EnumAccess<'de>,
+ {
+ ContentVisitor::new()
+ .visit_enum(visitor)
+ .map(TagOrContent::Content)
+ }
+ }
+
+ /// Used by generated code to deserialize an internally tagged enum.
+ ///
+ /// Not public API.
+ pub struct TaggedContent<'de, T> {
+ pub tag: T,
+ pub content: Content<'de>,
+ }
+
+ /// Not public API.
+ pub struct TaggedContentVisitor<'de, T> {
+ tag_name: &'static str,
+ expecting: &'static str,
+ value: PhantomData<TaggedContent<'de, T>>,
+ }
+
+ impl<'de, T> TaggedContentVisitor<'de, T> {
+ /// Visitor for the content of an internally tagged enum with the given
+ /// tag name.
+ pub fn new(name: &'static str, expecting: &'static str) -> Self {
+ TaggedContentVisitor {
+ tag_name: name,
+ expecting: expecting,
+ value: PhantomData,
+ }
+ }
+ }
+
+ impl<'de, T> DeserializeSeed<'de> for TaggedContentVisitor<'de, T>
+ where
+ T: Deserialize<'de>,
+ {
+ type Value = TaggedContent<'de, T>;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // Internally tagged enums are only supported in self-describing
+ // formats.
+ deserializer.deserialize_any(self)
+ }
+ }
+
+ impl<'de, T> Visitor<'de> for TaggedContentVisitor<'de, T>
+ where
+ T: Deserialize<'de>,
+ {
+ type Value = TaggedContent<'de, T>;
+
+ fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt.write_str(self.expecting)
+ }
+
+ fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
+ where
+ S: SeqAccess<'de>,
+ {
+ let tag = match try!(seq.next_element()) {
+ Some(tag) => tag,
+ None => {
+ return Err(de::Error::missing_field(self.tag_name));
+ }
+ };
+ let rest = de::value::SeqAccessDeserializer::new(seq);
+ Ok(TaggedContent {
+ tag: tag,
+ content: try!(Content::deserialize(rest)),
+ })
+ }
+
+ fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
+ where
+ M: MapAccess<'de>,
+ {
+ let mut tag = None;
+ let mut vec = Vec::with_capacity(size_hint::cautious(map.size_hint()));
+ while let Some(k) = try!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
+ match k {
+ TagOrContent::Tag => {
+ if tag.is_some() {
+ return Err(de::Error::duplicate_field(self.tag_name));
+ }
+ tag = Some(try!(map.next_value()));
+ }
+ TagOrContent::Content(k) => {
+ let v = try!(map.next_value());
+ vec.push((k, v));
+ }
+ }
+ }
+ match tag {
+ None => Err(de::Error::missing_field(self.tag_name)),
+ Some(tag) => Ok(TaggedContent {
+ tag: tag,
+ content: Content::Map(vec),
+ }),
+ }
+ }
+ }
+
+ /// Used by generated code to deserialize an adjacently tagged enum.
+ ///
+ /// Not public API.
+ pub enum TagOrContentField {
+ Tag,
+ Content,
+ }
+
+ /// Not public API.
+ pub struct TagOrContentFieldVisitor {
+ pub tag: &'static str,
+ pub content: &'static str,
+ }
+
+ impl<'de> DeserializeSeed<'de> for TagOrContentFieldVisitor {
+ type Value = TagOrContentField;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_str(self)
+ }
+ }
+
+ impl<'de> Visitor<'de> for TagOrContentFieldVisitor {
+ type Value = TagOrContentField;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "{:?} or {:?}", self.tag, self.content)
+ }
+
+ fn visit_str<E>(self, field: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ if field == self.tag {
+ Ok(TagOrContentField::Tag)
+ } else if field == self.content {
+ Ok(TagOrContentField::Content)
+ } else {
+ Err(de::Error::invalid_value(Unexpected::Str(field), &self))
+ }
+ }
+ }
+
+ /// Used by generated code to deserialize an adjacently tagged enum when
+ /// ignoring unrelated fields is allowed.
+ ///
+ /// Not public API.
+ pub enum TagContentOtherField {
+ Tag,
+ Content,
+ Other,
+ }
+
+ /// Not public API.
+ pub struct TagContentOtherFieldVisitor {
+ pub tag: &'static str,
+ pub content: &'static str,
+ }
+
+ impl<'de> DeserializeSeed<'de> for TagContentOtherFieldVisitor {
+ type Value = TagContentOtherField;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_str(self)
+ }
+ }
+
+ impl<'de> Visitor<'de> for TagContentOtherFieldVisitor {
+ type Value = TagContentOtherField;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ formatter,
+ "{:?}, {:?}, or other ignored fields",
+ self.tag, self.content
+ )
+ }
+
+ fn visit_str<E>(self, field: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ if field == self.tag {
+ Ok(TagContentOtherField::Tag)
+ } else if field == self.content {
+ Ok(TagContentOtherField::Content)
+ } else {
+ Ok(TagContentOtherField::Other)
+ }
+ }
+ }
+
+ /// 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 deserialize_float<V>(self, visitor: V) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::F32(v) => visitor.visit_f32(v),
+ Content::F64(v) => visitor.visit_f64(v),
+ 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;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ Content::Bool(v) => visitor.visit_bool(v),
+ 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),
+ Content::F32(v) => visitor.visit_f32(v),
+ Content::F64(v) => visitor.visit_f64(v),
+ Content::Char(v) => visitor.visit_char(v),
+ 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) => 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>,
+ {
+ self.deserialize_float(visitor)
+ }
+
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_float(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(),
+
+ // Allow deserializing newtype variant containing unit.
+ //
+ // #[derive(Deserialize)]
+ // #[serde(tag = "result")]
+ // enum Response<T> {
+ // Success(T),
+ // }
+ //
+ // We want {"result":"Success"} to deserialize into Response<()>.
+ Content::Map(ref v) if v.is_empty() => 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/seq.
+ Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
+ Content::Seq(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>,
+ {
+ 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>
+ where
+ V: Visitor<'de>,
+ {
+ let (variant, value) = match self.content {
+ Content::Map(value) => {
+ let mut iter = value.into_iter();
+ let (variant, value) = match iter.next() {
+ Some(v) => v,
+ None => {
+ return Err(de::Error::invalid_value(
+ de::Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ };
+ // enums are encoded in json as maps with a single key:value pair
+ if iter.next().is_some() {
+ return Err(de::Error::invalid_value(
+ de::Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ (variant, Some(value))
+ }
+ s @ Content::String(_) | s @ Content::Str(_) => (s, None),
+ other => {
+ return Err(de::Error::invalid_type(
+ other.unexpected(),
+ &"string or map",
+ ));
+ }
+ };
+
+ visitor.visit_enum(EnumDeserializer::new(variant, value))
+ }
+
+ fn deserialize_identifier<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::U8(v) => visitor.visit_u8(v),
+ Content::U64(v) => visitor.visit_u64(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ drop(self);
+ visitor.visit_unit()
+ }
+
+ fn __deserialize_content<V>(
+ self,
+ _: actually_private::T,
+ visitor: V,
+ ) -> Result<Content<'de>, Self::Error>
+ where
+ V: Visitor<'de, Value = Content<'de>>,
+ {
+ let _ = visitor;
+ Ok(self.content)
+ }
+ }
+
+ impl<'de, E> ContentDeserializer<'de, E> {
+ /// private API, don't use
+ pub fn new(content: Content<'de>) -> Self {
+ ContentDeserializer {
+ content: content,
+ err: PhantomData,
+ }
+ }
+ }
+
+ pub struct EnumDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ variant: Content<'de>,
+ value: Option<Content<'de>>,
+ err: PhantomData<E>,
+ }
+
+ impl<'de, E> EnumDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ pub fn new(variant: Content<'de>, value: Option<Content<'de>>) -> EnumDeserializer<'de, E> {
+ EnumDeserializer {
+ variant: variant,
+ value: value,
+ err: PhantomData,
+ }
+ }
+ }
+
+ impl<'de, E> de::EnumAccess<'de> for EnumDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+ type Variant = VariantDeserializer<'de, Self::Error>;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), E>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let visitor = VariantDeserializer {
+ value: self.value,
+ err: PhantomData,
+ };
+ seed.deserialize(ContentDeserializer::new(self.variant))
+ .map(|v| (v, visitor))
+ }
+ }
+
+ pub struct VariantDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ value: Option<Content<'de>>,
+ err: PhantomData<E>,
+ }
+
+ impl<'de, E> de::VariantAccess<'de> for VariantDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ fn unit_variant(self) -> Result<(), E> {
+ match self.value {
+ Some(value) => de::Deserialize::deserialize(ContentDeserializer::new(value)),
+ None => Ok(()),
+ }
+ }
+
+ fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, E>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.value {
+ Some(value) => seed.deserialize(ContentDeserializer::new(value)),
+ None => Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"newtype variant",
+ )),
+ }
+ }
+
+ fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.value {
+ Some(Content::Seq(v)) => {
+ de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
+ }
+ Some(other) => Err(de::Error::invalid_type(
+ other.unexpected(),
+ &"tuple variant",
+ )),
+ None => Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"tuple variant",
+ )),
+ }
+ }
+
+ fn struct_variant<V>(
+ self,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.value {
+ Some(Content::Map(v)) => {
+ de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
+ }
+ Some(Content::Seq(v)) => {
+ de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
+ }
+ Some(other) => Err(de::Error::invalid_type(
+ other.unexpected(),
+ &"struct variant",
+ )),
+ None => Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"struct variant",
+ )),
+ }
+ }
+ }
+
+ struct SeqDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ iter: <Vec<Content<'de>> as IntoIterator>::IntoIter,
+ err: PhantomData<E>,
+ }
+
+ impl<'de, E> SeqDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ fn new(vec: Vec<Content<'de>>) -> Self {
+ SeqDeserializer {
+ iter: vec.into_iter(),
+ err: PhantomData,
+ }
+ }
+ }
+
+ impl<'de, E> de::Deserializer<'de> for SeqDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ #[inline]
+ fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let len = self.iter.len();
+ if len == 0 {
+ visitor.visit_unit()
+ } else {
+ let ret = try!(visitor.visit_seq(&mut self));
+ let remaining = self.iter.len();
+ if remaining == 0 {
+ Ok(ret)
+ } else {
+ Err(de::Error::invalid_length(len, &"fewer elements in array"))
+ }
+ }
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+ }
+
+ impl<'de, E> de::SeqAccess<'de> for SeqDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some),
+ None => Ok(None),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ size_hint::from_bounds(&self.iter)
+ }
+ }
+
+ struct MapDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ iter: <Vec<(Content<'de>, Content<'de>)> as IntoIterator>::IntoIter,
+ value: Option<Content<'de>>,
+ err: PhantomData<E>,
+ }
+
+ impl<'de, E> MapDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ fn new(map: Vec<(Content<'de>, Content<'de>)>) -> Self {
+ MapDeserializer {
+ iter: map.into_iter(),
+ value: None,
+ err: PhantomData,
+ }
+ }
+ }
+
+ impl<'de, E> de::MapAccess<'de> for MapDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some((key, value)) => {
+ self.value = Some(value);
+ seed.deserialize(ContentDeserializer::new(key)).map(Some)
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.value.take() {
+ Some(value) => seed.deserialize(ContentDeserializer::new(value)),
+ None => Err(de::Error::custom("value is missing")),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ size_hint::from_bounds(&self.iter)
+ }
+ }
+
+ impl<'de, E> de::Deserializer<'de> for MapDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_map(self)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+ }
+
+ /// 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 deserialize_float<V>(self, visitor: V) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::F32(v) => visitor.visit_f32(v),
+ Content::F64(v) => visitor.visit_f64(v),
+ 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.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.iter().map(|(k, 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;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, E>
+ where
+ V: Visitor<'de>,
+ {
+ match *self.content {
+ Content::Bool(v) => visitor.visit_bool(v),
+ 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),
+ Content::F32(v) => visitor.visit_f32(v),
+ Content::F64(v) => visitor.visit_f64(v),
+ Content::Char(v) => visitor.visit_char(v),
+ 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::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) => 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>,
+ {
+ self.deserialize_float(visitor)
+ }
+
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_float(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>,
+ {
+ 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>
+ where
+ V: Visitor<'de>,
+ {
+ let (variant, value) = match *self.content {
+ Content::Map(ref value) => {
+ let mut iter = value.iter();
+ let (variant, value) = match iter.next() {
+ Some(v) => v,
+ None => {
+ return Err(de::Error::invalid_value(
+ de::Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ };
+ // enums are encoded in json as maps with a single key:value pair
+ if iter.next().is_some() {
+ return Err(de::Error::invalid_value(
+ de::Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ (variant, Some(value))
+ }
+ ref s @ Content::String(_) | ref s @ Content::Str(_) => (s, None),
+ ref other => {
+ return Err(de::Error::invalid_type(
+ other.unexpected(),
+ &"string or map",
+ ));
+ }
+ };
+
+ visitor.visit_enum(EnumRefDeserializer {
+ variant: variant,
+ value: value,
+ err: PhantomData,
+ })
+ }
+
+ 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),
+ Content::U8(v) => visitor.visit_u8(v),
+ Content::U64(v) => visitor.visit_u64(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()
+ }
+
+ fn __deserialize_content<V>(
+ self,
+ _: actually_private::T,
+ visitor: V,
+ ) -> Result<Content<'de>, Self::Error>
+ where
+ V: Visitor<'de, Value = Content<'de>>,
+ {
+ let _ = visitor;
+ Ok(self.content.clone())
+ }
+ }
+
+ impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> {
+ /// private API, don't use
+ pub fn new(content: &'a Content<'de>) -> Self {
+ ContentRefDeserializer {
+ content: content,
+ err: PhantomData,
+ }
+ }
+ }
+
+ struct EnumRefDeserializer<'a, 'de: 'a, E>
+ where
+ E: de::Error,
+ {
+ variant: &'a Content<'de>,
+ value: Option<&'a Content<'de>>,
+ err: PhantomData<E>,
+ }
+
+ impl<'de, 'a, E> de::EnumAccess<'de> for EnumRefDeserializer<'a, 'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+ type Variant = VariantRefDeserializer<'a, 'de, Self::Error>;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Self::Error>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let visitor = VariantRefDeserializer {
+ value: self.value,
+ err: PhantomData,
+ };
+ seed.deserialize(ContentRefDeserializer::new(self.variant))
+ .map(|v| (v, visitor))
+ }
+ }
+
+ struct VariantRefDeserializer<'a, 'de: 'a, E>
+ where
+ E: de::Error,
+ {
+ value: Option<&'a Content<'de>>,
+ err: PhantomData<E>,
+ }
+
+ impl<'de, 'a, E> de::VariantAccess<'de> for VariantRefDeserializer<'a, 'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ fn unit_variant(self) -> Result<(), E> {
+ match self.value {
+ Some(value) => de::Deserialize::deserialize(ContentRefDeserializer::new(value)),
+ None => Ok(()),
+ }
+ }
+
+ fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, E>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.value {
+ Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
+ None => Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"newtype variant",
+ )),
+ }
+ }
+
+ fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.value {
+ Some(Content::Seq(v)) => {
+ de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
+ }
+ Some(other) => Err(de::Error::invalid_type(
+ other.unexpected(),
+ &"tuple variant",
+ )),
+ None => Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"tuple variant",
+ )),
+ }
+ }
+
+ fn struct_variant<V>(
+ self,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.value {
+ Some(Content::Map(v)) => {
+ de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
+ }
+ Some(Content::Seq(v)) => {
+ de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
+ }
+ Some(other) => Err(de::Error::invalid_type(
+ other.unexpected(),
+ &"struct variant",
+ )),
+ None => Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"struct variant",
+ )),
+ }
+ }
+ }
+
+ struct SeqRefDeserializer<'a, 'de: 'a, E>
+ where
+ E: de::Error,
+ {
+ iter: <&'a [Content<'de>] as IntoIterator>::IntoIter,
+ err: PhantomData<E>,
+ }
+
+ impl<'a, 'de, E> SeqRefDeserializer<'a, 'de, E>
+ where
+ E: de::Error,
+ {
+ fn new(slice: &'a [Content<'de>]) -> Self {
+ SeqRefDeserializer {
+ iter: slice.iter(),
+ err: PhantomData,
+ }
+ }
+ }
+
+ impl<'de, 'a, E> de::Deserializer<'de> for SeqRefDeserializer<'a, 'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ #[inline]
+ fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ let len = self.iter.len();
+ if len == 0 {
+ visitor.visit_unit()
+ } else {
+ let ret = try!(visitor.visit_seq(&mut self));
+ let remaining = self.iter.len();
+ if remaining == 0 {
+ Ok(ret)
+ } else {
+ Err(de::Error::invalid_length(len, &"fewer elements in array"))
+ }
+ }
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+ }
+
+ impl<'de, 'a, E> de::SeqAccess<'de> for SeqRefDeserializer<'a, 'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some(value) => seed
+ .deserialize(ContentRefDeserializer::new(value))
+ .map(Some),
+ None => Ok(None),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ size_hint::from_bounds(&self.iter)
+ }
+ }
+
+ struct MapRefDeserializer<'a, 'de: 'a, E>
+ where
+ E: de::Error,
+ {
+ iter: <&'a [(Content<'de>, Content<'de>)] as IntoIterator>::IntoIter,
+ value: Option<&'a Content<'de>>,
+ err: PhantomData<E>,
+ }
+
+ impl<'a, 'de, E> MapRefDeserializer<'a, 'de, E>
+ where
+ E: de::Error,
+ {
+ fn new(map: &'a [(Content<'de>, Content<'de>)]) -> Self {
+ MapRefDeserializer {
+ iter: map.iter(),
+ value: None,
+ err: PhantomData,
+ }
+ }
+ }
+
+ impl<'de, 'a, E> de::MapAccess<'de> for MapRefDeserializer<'a, 'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some((key, value)) => {
+ self.value = Some(value);
+ 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: de::DeserializeSeed<'de>,
+ {
+ match self.value.take() {
+ Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
+ None => Err(de::Error::custom("value is missing")),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ size_hint::from_bounds(&self.iter)
+ }
+ }
+
+ impl<'de, 'a, E> de::Deserializer<'de> for MapRefDeserializer<'a, 'de, E>
+ where
+ E: de::Error,
+ {
+ type Error = E;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_map(self)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+ }
+
+ impl<'de, E> de::IntoDeserializer<'de, E> for ContentDeserializer<'de, E>
+ where
+ E: de::Error,
+ {
+ type Deserializer = Self;
+
+ fn into_deserializer(self) -> Self {
+ self
+ }
+ }
+
+ impl<'de, 'a, E> de::IntoDeserializer<'de, E> for ContentRefDeserializer<'a, 'de, E>
+ where
+ E: de::Error,
+ {
+ type Deserializer = Self;
+
+ fn into_deserializer(self) -> Self {
+ self
+ }
+ }
+
+ /// Visitor for deserializing an internally tagged unit variant.
+ ///
+ /// Not public API.
+ pub struct InternallyTaggedUnitVisitor<'a> {
+ type_name: &'a str,
+ variant_name: &'a str,
+ }
+
+ impl<'a> InternallyTaggedUnitVisitor<'a> {
+ /// Not public API.
+ pub fn new(type_name: &'a str, variant_name: &'a str) -> Self {
+ InternallyTaggedUnitVisitor {
+ type_name: type_name,
+ variant_name: variant_name,
+ }
+ }
+ }
+
+ impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ formatter,
+ "unit variant {}::{}",
+ self.type_name, self.variant_name
+ )
+ }
+
+ fn visit_seq<S>(self, _: S) -> Result<(), S::Error>
+ where
+ S: SeqAccess<'de>,
+ {
+ Ok(())
+ }
+
+ fn visit_map<M>(self, mut access: M) -> Result<(), M::Error>
+ where
+ M: MapAccess<'de>,
+ {
+ while try!(access.next_entry::<IgnoredAny, IgnoredAny>()).is_some() {}
+ Ok(())
+ }
+ }
+
+ /// Visitor for deserializing an untagged unit variant.
+ ///
+ /// Not public API.
+ pub struct UntaggedUnitVisitor<'a> {
+ type_name: &'a str,
+ variant_name: &'a str,
+ }
+
+ impl<'a> UntaggedUnitVisitor<'a> {
+ /// Not public API.
+ pub fn new(type_name: &'a str, variant_name: &'a str) -> Self {
+ UntaggedUnitVisitor {
+ type_name: type_name,
+ variant_name: variant_name,
+ }
+ }
+ }
+
+ impl<'de, 'a> Visitor<'de> for UntaggedUnitVisitor<'a> {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ formatter,
+ "unit variant {}::{}",
+ self.type_name, self.variant_name
+ )
+ }
+
+ fn visit_unit<E>(self) -> Result<(), E>
+ where
+ E: de::Error,
+ {
+ Ok(())
+ }
+
+ fn visit_none<E>(self) -> Result<(), E>
+ where
+ E: de::Error,
+ {
+ Ok(())
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Like `IntoDeserializer` but also implemented for `&[u8]`. This is used for
+// the newtype fallthrough case of `field_identifier`.
+//
+// #[derive(Deserialize)]
+// #[serde(field_identifier)]
+// enum F {
+// A,
+// B,
+// Other(String), // deserialized using IdentifierDeserializer
+// }
+pub trait IdentifierDeserializer<'de, E: Error> {
+ type Deserializer: Deserializer<'de, Error = E>;
+
+ fn from(self) -> Self::Deserializer;
+}
+
+pub struct Borrowed<'de, T: 'de + ?Sized>(pub &'de T);
+
+impl<'de, E> IdentifierDeserializer<'de, E> for u64
+where
+ E: Error,
+{
+ type Deserializer = <u64 as IntoDeserializer<'de, E>>::Deserializer;
+
+ fn from(self) -> Self::Deserializer {
+ self.into_deserializer()
+ }
+}
+
+pub struct StrDeserializer<'a, E> {
+ value: &'a str,
+ marker: PhantomData<E>,
+}
+
+impl<'de, 'a, E> Deserializer<'de> for StrDeserializer<'a, E>
+where
+ E: Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_str(self.value)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+pub struct BorrowedStrDeserializer<'de, E> {
+ value: &'de str,
+ marker: PhantomData<E>,
+}
+
+impl<'de, E> Deserializer<'de> for BorrowedStrDeserializer<'de, E>
+where
+ E: Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_borrowed_str(self.value)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+impl<'a, E> IdentifierDeserializer<'a, E> for &'a str
+where
+ E: Error,
+{
+ type Deserializer = StrDeserializer<'a, E>;
+
+ fn from(self) -> Self::Deserializer {
+ StrDeserializer {
+ value: self,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'de, E> IdentifierDeserializer<'de, E> for Borrowed<'de, str>
+where
+ E: Error,
+{
+ type Deserializer = BorrowedStrDeserializer<'de, E>;
+
+ fn from(self) -> Self::Deserializer {
+ BorrowedStrDeserializer {
+ value: self.0,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'a, E> IdentifierDeserializer<'a, E> for &'a [u8]
+where
+ E: Error,
+{
+ type Deserializer = BytesDeserializer<'a, E>;
+
+ fn from(self) -> Self::Deserializer {
+ BytesDeserializer::new(self)
+ }
+}
+
+impl<'de, E> IdentifierDeserializer<'de, E> for Borrowed<'de, [u8]>
+where
+ E: Error,
+{
+ type Deserializer = BorrowedBytesDeserializer<'de, E>;
+
+ fn from(self) -> Self::Deserializer {
+ BorrowedBytesDeserializer::new(self.0)
+ }
+}
+
+#[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, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ 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>
+ where
+ V: Visitor<'de>,
+ {
+ for item in self.0.iter_mut() {
+ // items in the vector are nulled out when used. So we can only use
+ // an item if it's still filled in and if the field is one we care
+ // about.
+ let use_item = match *item {
+ None => false,
+ Some((ref c, _)) => c.as_str().map_or(false, |x| variants.contains(&x)),
+ };
+
+ if use_item {
+ let (key, value) = item.take().unwrap();
+ return visitor.visit_enum(EnumDeserializer::new(key, Some(value)));
+ }
+ }
+
+ Err(Error::custom(format_args!(
+ "no variant of enum {} found in flattened data",
+ name
+ )))
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_map(FlatMapAccess::new(self.0.iter()))
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ _: &'static str,
+ fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_map(FlatStructAccess::new(self.0.iter_mut(), fields))
+ }
+
+ fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_newtype_struct(self)
+ }
+
+ 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(),
+ }
+ }
+
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_unit()
+ }
+
+ 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_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::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
+ pending_content: Option<&'a Content<'de>>,
+ _marker: PhantomData<E>,
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de, E> FlatMapAccess<'a, 'de, E> {
+ fn new(
+ iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
+ ) -> FlatMapAccess<'a, 'de, E> {
+ FlatMapAccess {
+ iter: iter,
+ pending_content: None,
+ _marker: PhantomData,
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de, E> MapAccess<'de> for FlatMapAccess<'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>,
+ {
+ for item in &mut self.iter {
+ // Items in the vector are nulled out when used by a struct.
+ if let Some((ref key, ref content)) = *item {
+ self.pending_content = Some(content);
+ return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
+ }
+ }
+ Ok(None)
+ }
+
+ fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.pending_content.take() {
+ Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
+ None => Err(Error::custom("value is missing")),
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatStructAccess<'a, 'de: 'a, E> {
+ iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
+ pending_content: Option<Content<'de>>,
+ fields: &'static [&'static str],
+ _marker: PhantomData<E>,
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de, E> FlatStructAccess<'a, 'de, E> {
+ fn new(
+ iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
+ fields: &'static [&'static str],
+ ) -> FlatStructAccess<'a, 'de, E> {
+ FlatStructAccess {
+ iter: iter,
+ pending_content: None,
+ fields: fields,
+ _marker: PhantomData,
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'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>,
+ {
+ while let Some(item) = self.iter.next() {
+ // items in the vector are nulled out when used. So we can only use
+ // an item if it's still filled in and if the field is one we care
+ // about. In case we do not know which fields we want, we take them all.
+ let use_item = match *item {
+ None => false,
+ Some((ref c, _)) => c.as_str().map_or(false, |key| self.fields.contains(&key)),
+ };
+
+ if use_item {
+ let (key, content) = item.take().unwrap();
+ self.pending_content = Some(content);
+ return seed.deserialize(ContentDeserializer::new(key)).map(Some);
+ }
+ }
+ Ok(None)
+ }
+
+ fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
+ 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>,
+ {
+ for item in &mut self.iter {
+ if let Some((ref key, ref content)) = *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.
+ self.pending = Some(content);
+ return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
+ }
+ }
+ 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"),
+ }
+ }
+}
diff --git a/third_party/rust/serde/src/private/doc.rs b/third_party/rust/serde/src/private/doc.rs
new file mode 100644
index 0000000000..f597af8445
--- /dev/null
+++ b/third_party/rust/serde/src/private/doc.rs
@@ -0,0 +1,159 @@
+// Used only by Serde doc tests. Not public API.
+
+use lib::*;
+
+use ser;
+
+#[doc(hidden)]
+#[derive(Debug)]
+pub struct Error;
+
+impl ser::Error for Error {
+ fn custom<T>(_: T) -> Self
+ where
+ T: Display,
+ {
+ unimplemented!()
+ }
+}
+
+#[cfg(feature = "std")]
+impl error::Error for Error {
+ fn description(&self) -> &str {
+ unimplemented!()
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
+ unimplemented!()
+ }
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __private_serialize {
+ () => {
+ trait Serialize {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: $crate::Serializer;
+ }
+ };
+}
+
+#[doc(hidden)]
+#[macro_export(local_inner_macros)]
+macro_rules! __serialize_unimplemented {
+ ($($func:ident)*) => {
+ $(
+ __serialize_unimplemented_helper!($func);
+ )*
+ };
+}
+
+#[doc(hidden)]
+#[macro_export]
+macro_rules! __serialize_unimplemented_method {
+ ($func:ident $(<$t:ident>)* ($($arg:ty),*) -> $ret:ident) => {
+ fn $func $(<$t: ?Sized + $crate::Serialize>)* (self $(, _: $arg)*) -> $crate::__private::Result<Self::$ret, Self::Error> {
+ unimplemented!()
+ }
+ };
+}
+
+#[doc(hidden)]
+#[macro_export(local_inner_macros)]
+macro_rules! __serialize_unimplemented_helper {
+ (bool) => {
+ __serialize_unimplemented_method!(serialize_bool(bool) -> Ok);
+ };
+ (i8) => {
+ __serialize_unimplemented_method!(serialize_i8(i8) -> Ok);
+ };
+ (i16) => {
+ __serialize_unimplemented_method!(serialize_i16(i16) -> Ok);
+ };
+ (i32) => {
+ __serialize_unimplemented_method!(serialize_i32(i32) -> Ok);
+ };
+ (i64) => {
+ __serialize_unimplemented_method!(serialize_i64(i64) -> Ok);
+ };
+ (u8) => {
+ __serialize_unimplemented_method!(serialize_u8(u8) -> Ok);
+ };
+ (u16) => {
+ __serialize_unimplemented_method!(serialize_u16(u16) -> Ok);
+ };
+ (u32) => {
+ __serialize_unimplemented_method!(serialize_u32(u32) -> Ok);
+ };
+ (u64) => {
+ __serialize_unimplemented_method!(serialize_u64(u64) -> Ok);
+ };
+ (f32) => {
+ __serialize_unimplemented_method!(serialize_f32(f32) -> Ok);
+ };
+ (f64) => {
+ __serialize_unimplemented_method!(serialize_f64(f64) -> Ok);
+ };
+ (char) => {
+ __serialize_unimplemented_method!(serialize_char(char) -> Ok);
+ };
+ (str) => {
+ __serialize_unimplemented_method!(serialize_str(&str) -> Ok);
+ };
+ (bytes) => {
+ __serialize_unimplemented_method!(serialize_bytes(&[u8]) -> Ok);
+ };
+ (none) => {
+ __serialize_unimplemented_method!(serialize_none() -> Ok);
+ };
+ (some) => {
+ __serialize_unimplemented_method!(serialize_some<T>(&T) -> Ok);
+ };
+ (unit) => {
+ __serialize_unimplemented_method!(serialize_unit() -> Ok);
+ };
+ (unit_struct) => {
+ __serialize_unimplemented_method!(serialize_unit_struct(&str) -> Ok);
+ };
+ (unit_variant) => {
+ __serialize_unimplemented_method!(serialize_unit_variant(&str, u32, &str) -> Ok);
+ };
+ (newtype_struct) => {
+ __serialize_unimplemented_method!(serialize_newtype_struct<T>(&str, &T) -> Ok);
+ };
+ (newtype_variant) => {
+ __serialize_unimplemented_method!(serialize_newtype_variant<T>(&str, u32, &str, &T) -> Ok);
+ };
+ (seq) => {
+ type SerializeSeq = $crate::ser::Impossible<Self::Ok, Self::Error>;
+ __serialize_unimplemented_method!(serialize_seq(Option<usize>) -> SerializeSeq);
+ };
+ (tuple) => {
+ type SerializeTuple = $crate::ser::Impossible<Self::Ok, Self::Error>;
+ __serialize_unimplemented_method!(serialize_tuple(usize) -> SerializeTuple);
+ };
+ (tuple_struct) => {
+ type SerializeTupleStruct = $crate::ser::Impossible<Self::Ok, Self::Error>;
+ __serialize_unimplemented_method!(serialize_tuple_struct(&str, usize) -> SerializeTupleStruct);
+ };
+ (tuple_variant) => {
+ type SerializeTupleVariant = $crate::ser::Impossible<Self::Ok, Self::Error>;
+ __serialize_unimplemented_method!(serialize_tuple_variant(&str, u32, &str, usize) -> SerializeTupleVariant);
+ };
+ (map) => {
+ type SerializeMap = $crate::ser::Impossible<Self::Ok, Self::Error>;
+ __serialize_unimplemented_method!(serialize_map(Option<usize>) -> SerializeMap);
+ };
+ (struct) => {
+ type SerializeStruct = $crate::ser::Impossible<Self::Ok, Self::Error>;
+ __serialize_unimplemented_method!(serialize_struct(&str, usize) -> SerializeStruct);
+ };
+ (struct_variant) => {
+ type SerializeStructVariant = $crate::ser::Impossible<Self::Ok, Self::Error>;
+ __serialize_unimplemented_method!(serialize_struct_variant(&str, u32, &str, usize) -> SerializeStructVariant);
+ };
+}
diff --git a/third_party/rust/serde/src/private/mod.rs b/third_party/rust/serde/src/private/mod.rs
new file mode 100644
index 0000000000..e896902360
--- /dev/null
+++ b/third_party/rust/serde/src/private/mod.rs
@@ -0,0 +1,50 @@
+#[cfg(not(no_serde_derive))]
+pub mod de;
+#[cfg(not(no_serde_derive))]
+pub mod ser;
+
+pub mod size_hint;
+
+// FIXME: #[cfg(doctest)] once https://github.com/rust-lang/rust/issues/67295 is fixed.
+pub mod doc;
+
+pub use lib::clone::Clone;
+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::ptr;
+pub use lib::result::Result::{self, Err, Ok};
+
+pub use self::string::from_utf8_lossy;
+
+#[cfg(any(feature = "alloc", feature = "std"))]
+pub use lib::{ToString, Vec};
+
+#[cfg(not(no_core_try_from))]
+pub use lib::convert::TryFrom;
+
+mod string {
+ use lib::*;
+
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
+ String::from_utf8_lossy(bytes)
+ }
+
+ // The generated code calls this like:
+ //
+ // let value = &_serde::__private::from_utf8_lossy(bytes);
+ // Err(_serde::de::Error::unknown_variant(value, VARIANTS))
+ //
+ // so it is okay for the return type to be different from the std case as long
+ // as the above works.
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
+ pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
+ // Three unicode replacement characters if it fails. They look like a
+ // white-on-black question mark. The user will recognize it as invalid
+ // UTF-8.
+ str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}")
+ }
+}
diff --git a/third_party/rust/serde/src/private/ser.rs b/third_party/rust/serde/src/private/ser.rs
new file mode 100644
index 0000000000..528e8c125a
--- /dev/null
+++ b/third_party/rust/serde/src/private/ser.rs
@@ -0,0 +1,1310 @@
+use lib::*;
+
+use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+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.
+pub fn serialize_tagged_newtype<S, T>(
+ serializer: S,
+ type_ident: &'static str,
+ variant_ident: &'static str,
+ tag: &'static str,
+ variant_name: &'static str,
+ value: &T,
+) -> Result<S::Ok, S::Error>
+where
+ S: Serializer,
+ T: Serialize,
+{
+ value.serialize(TaggedSerializer {
+ type_ident: type_ident,
+ variant_ident: variant_ident,
+ tag: tag,
+ variant_name: variant_name,
+ delegate: serializer,
+ })
+}
+
+struct TaggedSerializer<S> {
+ type_ident: &'static str,
+ variant_ident: &'static str,
+ tag: &'static str,
+ variant_name: &'static str,
+ delegate: S,
+}
+
+enum Unsupported {
+ Boolean,
+ Integer,
+ Float,
+ Char,
+ String,
+ ByteArray,
+ Optional,
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ UnitStruct,
+ Sequence,
+ Tuple,
+ TupleStruct,
+ Enum,
+}
+
+impl Display for Unsupported {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ Unsupported::Boolean => formatter.write_str("a boolean"),
+ Unsupported::Integer => formatter.write_str("an integer"),
+ Unsupported::Float => formatter.write_str("a float"),
+ Unsupported::Char => formatter.write_str("a char"),
+ Unsupported::String => formatter.write_str("a string"),
+ Unsupported::ByteArray => formatter.write_str("a byte array"),
+ Unsupported::Optional => formatter.write_str("an optional"),
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ Unsupported::UnitStruct => formatter.write_str("unit struct"),
+ Unsupported::Sequence => formatter.write_str("a sequence"),
+ Unsupported::Tuple => formatter.write_str("a tuple"),
+ Unsupported::TupleStruct => formatter.write_str("a tuple struct"),
+ Unsupported::Enum => formatter.write_str("an enum"),
+ }
+ }
+}
+
+impl<S> TaggedSerializer<S>
+where
+ S: Serializer,
+{
+ fn bad_type(self, what: Unsupported) -> S::Error {
+ ser::Error::custom(format_args!(
+ "cannot serialize tagged newtype variant {}::{} containing {}",
+ self.type_ident, self.variant_ident, what
+ ))
+ }
+}
+
+impl<S> Serializer for TaggedSerializer<S>
+where
+ S: Serializer,
+{
+ type Ok = S::Ok;
+ type Error = S::Error;
+
+ type SerializeSeq = Impossible<S::Ok, S::Error>;
+ type SerializeTuple = Impossible<S::Ok, S::Error>;
+ type SerializeTupleStruct = Impossible<S::Ok, S::Error>;
+ type SerializeMap = S::SerializeMap;
+ type SerializeStruct = S::SerializeStruct;
+
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
+ type SerializeTupleVariant = Impossible<S::Ok, S::Error>;
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ type SerializeTupleVariant = SerializeTupleVariantAsMapValue<S::SerializeMap>;
+
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
+ type SerializeStructVariant = Impossible<S::Ok, S::Error>;
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ type SerializeStructVariant = SerializeStructVariantAsMapValue<S::SerializeMap>;
+
+ fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Boolean))
+ }
+
+ fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Float))
+ }
+
+ fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Float))
+ }
+
+ fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
+ Err(self.bad_type(Unsupported::Char))
+ }
+
+ fn serialize_str(self, _: &str) -> Result<Self::Ok, Self::Error> {
+ 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))
+ }
+
+ fn serialize_some<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(self.bad_type(Unsupported::Optional))
+ }
+
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+ let mut map = try!(self.delegate.serialize_map(Some(1)));
+ try!(map.serialize_entry(self.tag, self.variant_name));
+ map.end()
+ }
+
+ fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
+ let mut map = try!(self.delegate.serialize_map(Some(1)));
+ try!(map.serialize_entry(self.tag, self.variant_name));
+ map.end()
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _: &'static str,
+ _: u32,
+ inner_variant: &'static str,
+ ) -> Result<Self::Ok, Self::Error> {
+ let mut map = try!(self.delegate.serialize_map(Some(2)));
+ try!(map.serialize_entry(self.tag, self.variant_name));
+ try!(map.serialize_entry(inner_variant, &()));
+ map.end()
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ _: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ _: &'static str,
+ _: u32,
+ inner_variant: &'static str,
+ inner_value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ let mut map = try!(self.delegate.serialize_map(Some(2)));
+ try!(map.serialize_entry(self.tag, self.variant_name));
+ try!(map.serialize_entry(inner_variant, inner_value));
+ map.end()
+ }
+
+ fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ Err(self.bad_type(Unsupported::Sequence))
+ }
+
+ fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ Err(self.bad_type(Unsupported::Tuple))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _: &'static str,
+ _: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+ Err(self.bad_type(Unsupported::TupleStruct))
+ }
+
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
+ fn serialize_tuple_variant(
+ self,
+ _: &'static str,
+ _: u32,
+ _: &'static str,
+ _: usize,
+ ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+ // Lack of push-based serialization means we need to buffer the content
+ // of the tuple variant, so it requires std.
+ Err(self.bad_type(Unsupported::Enum))
+ }
+
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ fn serialize_tuple_variant(
+ self,
+ _: &'static str,
+ _: u32,
+ inner_variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+ let mut map = try!(self.delegate.serialize_map(Some(2)));
+ try!(map.serialize_entry(self.tag, self.variant_name));
+ try!(map.serialize_key(inner_variant));
+ Ok(SerializeTupleVariantAsMapValue::new(
+ map,
+ inner_variant,
+ len,
+ ))
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ let mut map = try!(self.delegate.serialize_map(len.map(|len| len + 1)));
+ try!(map.serialize_entry(self.tag, self.variant_name));
+ Ok(map)
+ }
+
+ fn serialize_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStruct, Self::Error> {
+ let mut state = try!(self.delegate.serialize_struct(name, len + 1));
+ try!(state.serialize_field(self.tag, self.variant_name));
+ Ok(state)
+ }
+
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
+ fn serialize_struct_variant(
+ self,
+ _: &'static str,
+ _: u32,
+ _: &'static str,
+ _: usize,
+ ) -> Result<Self::SerializeStructVariant, Self::Error> {
+ // Lack of push-based serialization means we need to buffer the content
+ // of the struct variant, so it requires std.
+ Err(self.bad_type(Unsupported::Enum))
+ }
+
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ fn serialize_struct_variant(
+ self,
+ _: &'static str,
+ _: u32,
+ inner_variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant, Self::Error> {
+ let mut map = try!(self.delegate.serialize_map(Some(2)));
+ try!(map.serialize_entry(self.tag, self.variant_name));
+ try!(map.serialize_key(inner_variant));
+ Ok(SerializeStructVariantAsMapValue::new(
+ map,
+ inner_variant,
+ len,
+ ))
+ }
+
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
+ fn collect_str<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: Display,
+ {
+ Err(self.bad_type(Unsupported::String))
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+mod content {
+ use lib::*;
+
+ use ser::{self, Serialize, Serializer};
+
+ pub struct SerializeTupleVariantAsMapValue<M> {
+ map: M,
+ name: &'static str,
+ fields: Vec<Content>,
+ }
+
+ impl<M> SerializeTupleVariantAsMapValue<M> {
+ pub fn new(map: M, name: &'static str, len: usize) -> Self {
+ SerializeTupleVariantAsMapValue {
+ map: map,
+ name: name,
+ fields: Vec::with_capacity(len),
+ }
+ }
+ }
+
+ impl<M> ser::SerializeTupleVariant for SerializeTupleVariantAsMapValue<M>
+ where
+ M: ser::SerializeMap,
+ {
+ type Ok = M::Ok;
+ type Error = M::Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), M::Error>
+ where
+ T: Serialize,
+ {
+ let value = try!(value.serialize(ContentSerializer::<M::Error>::new()));
+ self.fields.push(value);
+ Ok(())
+ }
+
+ fn end(mut self) -> Result<M::Ok, M::Error> {
+ try!(self
+ .map
+ .serialize_value(&Content::TupleStruct(self.name, self.fields)));
+ self.map.end()
+ }
+ }
+
+ pub struct SerializeStructVariantAsMapValue<M> {
+ map: M,
+ name: &'static str,
+ fields: Vec<(&'static str, Content)>,
+ }
+
+ impl<M> SerializeStructVariantAsMapValue<M> {
+ pub fn new(map: M, name: &'static str, len: usize) -> Self {
+ SerializeStructVariantAsMapValue {
+ map: map,
+ name: name,
+ fields: Vec::with_capacity(len),
+ }
+ }
+ }
+
+ impl<M> ser::SerializeStructVariant for SerializeStructVariantAsMapValue<M>
+ where
+ M: ser::SerializeMap,
+ {
+ type Ok = M::Ok;
+ type Error = M::Error;
+
+ fn serialize_field<T: ?Sized>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), M::Error>
+ where
+ T: Serialize,
+ {
+ let value = try!(value.serialize(ContentSerializer::<M::Error>::new()));
+ self.fields.push((key, value));
+ Ok(())
+ }
+
+ fn end(mut self) -> Result<M::Ok, M::Error> {
+ try!(self
+ .map
+ .serialize_value(&Content::Struct(self.name, self.fields)));
+ self.map.end()
+ }
+ }
+
+ pub enum Content {
+ Bool(bool),
+
+ U8(u8),
+ U16(u16),
+ U32(u32),
+ U64(u64),
+
+ I8(i8),
+ I16(i16),
+ I32(i32),
+ I64(i64),
+
+ F32(f32),
+ F64(f64),
+
+ Char(char),
+ String(String),
+ Bytes(Vec<u8>),
+
+ None,
+ Some(Box<Content>),
+
+ Unit,
+ UnitStruct(&'static str),
+ UnitVariant(&'static str, u32, &'static str),
+ NewtypeStruct(&'static str, Box<Content>),
+ NewtypeVariant(&'static str, u32, &'static str, Box<Content>),
+
+ Seq(Vec<Content>),
+ Tuple(Vec<Content>),
+ TupleStruct(&'static str, Vec<Content>),
+ TupleVariant(&'static str, u32, &'static str, Vec<Content>),
+ Map(Vec<(Content, Content)>),
+ Struct(&'static str, Vec<(&'static str, Content)>),
+ StructVariant(
+ &'static str,
+ u32,
+ &'static str,
+ Vec<(&'static str, Content)>,
+ ),
+ }
+
+ impl Serialize for Content {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match *self {
+ Content::Bool(b) => serializer.serialize_bool(b),
+ Content::U8(u) => serializer.serialize_u8(u),
+ Content::U16(u) => serializer.serialize_u16(u),
+ Content::U32(u) => serializer.serialize_u32(u),
+ Content::U64(u) => serializer.serialize_u64(u),
+ Content::I8(i) => serializer.serialize_i8(i),
+ Content::I16(i) => serializer.serialize_i16(i),
+ Content::I32(i) => serializer.serialize_i32(i),
+ Content::I64(i) => serializer.serialize_i64(i),
+ Content::F32(f) => serializer.serialize_f32(f),
+ Content::F64(f) => serializer.serialize_f64(f),
+ Content::Char(c) => serializer.serialize_char(c),
+ Content::String(ref s) => serializer.serialize_str(s),
+ Content::Bytes(ref b) => serializer.serialize_bytes(b),
+ Content::None => serializer.serialize_none(),
+ Content::Some(ref c) => serializer.serialize_some(&**c),
+ Content::Unit => serializer.serialize_unit(),
+ Content::UnitStruct(n) => serializer.serialize_unit_struct(n),
+ Content::UnitVariant(n, i, v) => serializer.serialize_unit_variant(n, i, v),
+ Content::NewtypeStruct(n, ref c) => serializer.serialize_newtype_struct(n, &**c),
+ Content::NewtypeVariant(n, i, v, ref c) => {
+ serializer.serialize_newtype_variant(n, i, v, &**c)
+ }
+ Content::Seq(ref elements) => elements.serialize(serializer),
+ Content::Tuple(ref elements) => {
+ use ser::SerializeTuple;
+ let mut tuple = try!(serializer.serialize_tuple(elements.len()));
+ for e in elements {
+ try!(tuple.serialize_element(e));
+ }
+ tuple.end()
+ }
+ Content::TupleStruct(n, ref fields) => {
+ use ser::SerializeTupleStruct;
+ let mut ts = try!(serializer.serialize_tuple_struct(n, fields.len()));
+ for f in fields {
+ try!(ts.serialize_field(f));
+ }
+ ts.end()
+ }
+ Content::TupleVariant(n, i, v, ref fields) => {
+ use ser::SerializeTupleVariant;
+ let mut tv = try!(serializer.serialize_tuple_variant(n, i, v, fields.len()));
+ for f in fields {
+ try!(tv.serialize_field(f));
+ }
+ tv.end()
+ }
+ Content::Map(ref entries) => {
+ use ser::SerializeMap;
+ let mut map = try!(serializer.serialize_map(Some(entries.len())));
+ for (k, v) in entries {
+ try!(map.serialize_entry(k, v));
+ }
+ map.end()
+ }
+ Content::Struct(n, ref fields) => {
+ use ser::SerializeStruct;
+ let mut s = try!(serializer.serialize_struct(n, fields.len()));
+ for &(k, ref v) in fields {
+ try!(s.serialize_field(k, v));
+ }
+ s.end()
+ }
+ Content::StructVariant(n, i, v, ref fields) => {
+ use ser::SerializeStructVariant;
+ let mut sv = try!(serializer.serialize_struct_variant(n, i, v, fields.len()));
+ for &(k, ref v) in fields {
+ try!(sv.serialize_field(k, v));
+ }
+ sv.end()
+ }
+ }
+ }
+ }
+
+ pub struct ContentSerializer<E> {
+ error: PhantomData<E>,
+ }
+
+ impl<E> ContentSerializer<E> {
+ pub fn new() -> Self {
+ ContentSerializer { error: PhantomData }
+ }
+ }
+
+ impl<E> Serializer for ContentSerializer<E>
+ where
+ E: ser::Error,
+ {
+ type Ok = Content;
+ type Error = E;
+
+ type SerializeSeq = SerializeSeq<E>;
+ type SerializeTuple = SerializeTuple<E>;
+ type SerializeTupleStruct = SerializeTupleStruct<E>;
+ type SerializeTupleVariant = SerializeTupleVariant<E>;
+ type SerializeMap = SerializeMap<E>;
+ type SerializeStruct = SerializeStruct<E>;
+ type SerializeStructVariant = SerializeStructVariant<E>;
+
+ fn serialize_bool(self, v: bool) -> Result<Content, E> {
+ Ok(Content::Bool(v))
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<Content, E> {
+ Ok(Content::I8(v))
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<Content, E> {
+ Ok(Content::I16(v))
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<Content, E> {
+ Ok(Content::I32(v))
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<Content, E> {
+ Ok(Content::I64(v))
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<Content, E> {
+ Ok(Content::U8(v))
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<Content, E> {
+ Ok(Content::U16(v))
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<Content, E> {
+ Ok(Content::U32(v))
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<Content, E> {
+ Ok(Content::U64(v))
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<Content, E> {
+ Ok(Content::F32(v))
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<Content, E> {
+ Ok(Content::F64(v))
+ }
+
+ fn serialize_char(self, v: char) -> Result<Content, E> {
+ Ok(Content::Char(v))
+ }
+
+ fn serialize_str(self, value: &str) -> Result<Content, E> {
+ Ok(Content::String(value.to_owned()))
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<Content, E> {
+ Ok(Content::Bytes(value.to_owned()))
+ }
+
+ fn serialize_none(self) -> Result<Content, E> {
+ Ok(Content::None)
+ }
+
+ fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Content, E>
+ where
+ T: Serialize,
+ {
+ Ok(Content::Some(Box::new(try!(value.serialize(self)))))
+ }
+
+ fn serialize_unit(self) -> Result<Content, E> {
+ Ok(Content::Unit)
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<Content, E> {
+ Ok(Content::UnitStruct(name))
+ }
+
+ fn serialize_unit_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Content, E> {
+ Ok(Content::UnitVariant(name, variant_index, variant))
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ name: &'static str,
+ value: &T,
+ ) -> Result<Content, E>
+ where
+ T: Serialize,
+ {
+ Ok(Content::NewtypeStruct(
+ name,
+ Box::new(try!(value.serialize(self))),
+ ))
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Content, E>
+ where
+ T: Serialize,
+ {
+ Ok(Content::NewtypeVariant(
+ name,
+ variant_index,
+ variant,
+ Box::new(try!(value.serialize(self))),
+ ))
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, E> {
+ Ok(SerializeSeq {
+ elements: Vec::with_capacity(len.unwrap_or(0)),
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, E> {
+ Ok(SerializeTuple {
+ elements: Vec::with_capacity(len),
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct, E> {
+ Ok(SerializeTupleStruct {
+ name: name,
+ fields: Vec::with_capacity(len),
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant, E> {
+ Ok(SerializeTupleVariant {
+ name: name,
+ variant_index: variant_index,
+ variant: variant,
+ fields: Vec::with_capacity(len),
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, E> {
+ Ok(SerializeMap {
+ entries: Vec::with_capacity(len.unwrap_or(0)),
+ key: None,
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStruct, E> {
+ Ok(SerializeStruct {
+ name: name,
+ fields: Vec::with_capacity(len),
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_struct_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant, E> {
+ Ok(SerializeStructVariant {
+ name: name,
+ variant_index: variant_index,
+ variant: variant,
+ fields: Vec::with_capacity(len),
+ error: PhantomData,
+ })
+ }
+ }
+
+ pub struct SerializeSeq<E> {
+ elements: Vec<Content>,
+ error: PhantomData<E>,
+ }
+
+ impl<E> ser::SerializeSeq for SerializeSeq<E>
+ where
+ E: ser::Error,
+ {
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = try!(value.serialize(ContentSerializer::<E>::new()));
+ self.elements.push(value);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::Seq(self.elements))
+ }
+ }
+
+ pub struct SerializeTuple<E> {
+ elements: Vec<Content>,
+ error: PhantomData<E>,
+ }
+
+ impl<E> ser::SerializeTuple for SerializeTuple<E>
+ where
+ E: ser::Error,
+ {
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = try!(value.serialize(ContentSerializer::<E>::new()));
+ self.elements.push(value);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::Tuple(self.elements))
+ }
+ }
+
+ pub struct SerializeTupleStruct<E> {
+ name: &'static str,
+ fields: Vec<Content>,
+ error: PhantomData<E>,
+ }
+
+ impl<E> ser::SerializeTupleStruct for SerializeTupleStruct<E>
+ where
+ E: ser::Error,
+ {
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = try!(value.serialize(ContentSerializer::<E>::new()));
+ self.fields.push(value);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::TupleStruct(self.name, self.fields))
+ }
+ }
+
+ pub struct SerializeTupleVariant<E> {
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ fields: Vec<Content>,
+ error: PhantomData<E>,
+ }
+
+ impl<E> ser::SerializeTupleVariant for SerializeTupleVariant<E>
+ where
+ E: ser::Error,
+ {
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = try!(value.serialize(ContentSerializer::<E>::new()));
+ self.fields.push(value);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::TupleVariant(
+ self.name,
+ self.variant_index,
+ self.variant,
+ self.fields,
+ ))
+ }
+ }
+
+ pub struct SerializeMap<E> {
+ entries: Vec<(Content, Content)>,
+ key: Option<Content>,
+ error: PhantomData<E>,
+ }
+
+ impl<E> ser::SerializeMap for SerializeMap<E>
+ where
+ E: ser::Error,
+ {
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let key = try!(key.serialize(ContentSerializer::<E>::new()));
+ self.key = Some(key);
+ Ok(())
+ }
+
+ fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let key = self
+ .key
+ .take()
+ .expect("serialize_value called before serialize_key");
+ let value = try!(value.serialize(ContentSerializer::<E>::new()));
+ self.entries.push((key, value));
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::Map(self.entries))
+ }
+
+ fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<(), E>
+ where
+ K: Serialize,
+ V: Serialize,
+ {
+ let key = try!(key.serialize(ContentSerializer::<E>::new()));
+ let value = try!(value.serialize(ContentSerializer::<E>::new()));
+ self.entries.push((key, value));
+ Ok(())
+ }
+ }
+
+ pub struct SerializeStruct<E> {
+ name: &'static str,
+ fields: Vec<(&'static str, Content)>,
+ error: PhantomData<E>,
+ }
+
+ impl<E> ser::SerializeStruct for SerializeStruct<E>
+ where
+ E: ser::Error,
+ {
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = try!(value.serialize(ContentSerializer::<E>::new()));
+ self.fields.push((key, value));
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::Struct(self.name, self.fields))
+ }
+ }
+
+ pub struct SerializeStructVariant<E> {
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ fields: Vec<(&'static str, Content)>,
+ error: PhantomData<E>,
+ }
+
+ impl<E> ser::SerializeStructVariant for SerializeStructVariant<E>
+ where
+ E: ser::Error,
+ {
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = try!(value.serialize(ContentSerializer::<E>::new()));
+ self.fields.push((key, value));
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::StructVariant(
+ self.name,
+ self.variant_index,
+ self.variant,
+ self.fields,
+ ))
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatMapSerializer<'a, M: 'a>(pub &'a mut M);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> FlatMapSerializer<'a, M>
+where
+ M: SerializeMap + 'a,
+{
+ fn bad_type(what: Unsupported) -> M::Error {
+ ser::Error::custom(format_args!(
+ "can only flatten structs and maps (got {})",
+ what
+ ))
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> Serializer for FlatMapSerializer<'a, M>
+where
+ M: SerializeMap + 'a,
+{
+ type Ok = ();
+ type Error = M::Error;
+
+ type SerializeSeq = Impossible<Self::Ok, M::Error>;
+ type SerializeTuple = Impossible<Self::Ok, M::Error>;
+ type SerializeTupleStruct = Impossible<Self::Ok, M::Error>;
+ type SerializeMap = FlatMapSerializeMap<'a, M>;
+ type SerializeStruct = FlatMapSerializeStruct<'a, M>;
+ type SerializeTupleVariant = Impossible<Self::Ok, M::Error>;
+ type SerializeStructVariant = FlatMapSerializeStructVariantAsMapValue<'a, M>;
+
+ fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Boolean))
+ }
+
+ fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_i16(self, _: i16) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_i32(self, _: i32) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_i64(self, _: i64) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_u8(self, _: u8) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_u16(self, _: u16) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_u32(self, _: u32) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_u64(self, _: u64) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Integer))
+ }
+
+ fn serialize_f32(self, _: f32) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Float))
+ }
+
+ fn serialize_f64(self, _: f64) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Float))
+ }
+
+ fn serialize_char(self, _: char) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Char))
+ }
+
+ fn serialize_str(self, _: &str) -> Result<Self::Ok, Self::Error> {
+ 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> {
+ Ok(())
+ }
+
+ fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+ Ok(())
+ }
+
+ fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::UnitStruct))
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _: &'static str,
+ _: u32,
+ _: &'static str,
+ ) -> Result<Self::Ok, Self::Error> {
+ Err(Self::bad_type(Unsupported::Enum))
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ _: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ _: &'static str,
+ _: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ try!(self.0.serialize_key(variant));
+ self.0.serialize_value(value)
+ }
+
+ fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ Err(Self::bad_type(Unsupported::Sequence))
+ }
+
+ fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ Err(Self::bad_type(Unsupported::Tuple))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _: &'static str,
+ _: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+ Err(Self::bad_type(Unsupported::TupleStruct))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _: &'static str,
+ _: u32,
+ _: &'static str,
+ _: usize,
+ ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+ Err(Self::bad_type(Unsupported::Enum))
+ }
+
+ fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ Ok(FlatMapSerializeMap(self.0))
+ }
+
+ fn serialize_struct(
+ self,
+ _: &'static str,
+ _: usize,
+ ) -> Result<Self::SerializeStruct, Self::Error> {
+ Ok(FlatMapSerializeStruct(self.0))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _: &'static str,
+ _: u32,
+ inner_variant: &'static str,
+ _: usize,
+ ) -> Result<Self::SerializeStructVariant, Self::Error> {
+ try!(self.0.serialize_key(inner_variant));
+ Ok(FlatMapSerializeStructVariantAsMapValue::new(
+ self.0,
+ inner_variant,
+ ))
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatMapSerializeMap<'a, M: 'a>(&'a mut M);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> ser::SerializeMap for FlatMapSerializeMap<'a, M>
+where
+ M: SerializeMap + 'a,
+{
+ type Ok = ();
+ type Error = M::Error;
+
+ fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize,
+ {
+ self.0.serialize_key(key)
+ }
+
+ fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize,
+ {
+ self.0.serialize_value(value)
+ }
+
+ fn serialize_entry<K: ?Sized, V: ?Sized>(
+ &mut self,
+ key: &K,
+ value: &V,
+ ) -> Result<(), Self::Error>
+ where
+ K: Serialize,
+ V: Serialize,
+ {
+ self.0.serialize_entry(key, value)
+ }
+
+ fn end(self) -> Result<(), Self::Error> {
+ Ok(())
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatMapSerializeStruct<'a, M: 'a>(&'a mut M);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> ser::SerializeStruct for FlatMapSerializeStruct<'a, M>
+where
+ M: SerializeMap + 'a,
+{
+ type Ok = ();
+ type Error = M::Error;
+
+ fn serialize_field<T: ?Sized>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), Self::Error>
+ where
+ T: Serialize,
+ {
+ self.0.serialize_entry(key, value)
+ }
+
+ fn end(self) -> Result<(), Self::Error> {
+ Ok(())
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub struct FlatMapSerializeStructVariantAsMapValue<'a, M: 'a> {
+ map: &'a mut M,
+ name: &'static str,
+ fields: Vec<(&'static str, Content)>,
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> FlatMapSerializeStructVariantAsMapValue<'a, M>
+where
+ M: SerializeMap + 'a,
+{
+ fn new(map: &'a mut M, name: &'static str) -> FlatMapSerializeStructVariantAsMapValue<'a, M> {
+ FlatMapSerializeStructVariantAsMapValue {
+ map: map,
+ name: name,
+ fields: Vec::new(),
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, M> ser::SerializeStructVariant for FlatMapSerializeStructVariantAsMapValue<'a, M>
+where
+ M: SerializeMap + 'a,
+{
+ type Ok = ();
+ type Error = M::Error;
+
+ fn serialize_field<T: ?Sized>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), Self::Error>
+ where
+ T: Serialize,
+ {
+ let value = try!(value.serialize(ContentSerializer::<M::Error>::new()));
+ self.fields.push((key, value));
+ Ok(())
+ }
+
+ fn end(self) -> Result<(), Self::Error> {
+ try!(self
+ .map
+ .serialize_value(&Content::Struct(self.name, self.fields)));
+ Ok(())
+ }
+}
diff --git a/third_party/rust/serde/src/private/size_hint.rs b/third_party/rust/serde/src/private/size_hint.rs
new file mode 100644
index 0000000000..ca71e616bb
--- /dev/null
+++ b/third_party/rust/serde/src/private/size_hint.rs
@@ -0,0 +1,21 @@
+use lib::*;
+
+pub fn from_bounds<I>(iter: &I) -> Option<usize>
+where
+ I: Iterator,
+{
+ helper(iter.size_hint())
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+#[inline]
+pub fn cautious(hint: Option<usize>) -> usize {
+ cmp::min(hint.unwrap_or(0), 4096)
+}
+
+fn helper(bounds: (usize, Option<usize>)) -> Option<usize> {
+ match bounds {
+ (lower, Some(upper)) if lower == upper => Some(upper),
+ _ => None,
+ }
+}
diff --git a/third_party/rust/serde/src/ser/fmt.rs b/third_party/rust/serde/src/ser/fmt.rs
new file mode 100644
index 0000000000..e7e09a1bfe
--- /dev/null
+++ b/third_party/rust/serde/src/ser/fmt.rs
@@ -0,0 +1,174 @@
+use lib::*;
+use ser::{Error, Impossible, Serialize, Serializer};
+
+impl Error for fmt::Error {
+ fn custom<T: Display>(_msg: T) -> Self {
+ fmt::Error
+ }
+}
+
+macro_rules! fmt_primitives {
+ ($($f:ident: $t:ty,)*) => {
+ $(
+ fn $f(self, v: $t) -> fmt::Result {
+ Display::fmt(&v, self)
+ }
+ )*
+ };
+}
+
+/// ```edition2018
+/// use serde::Serialize;
+/// use std::fmt::{self, Display};
+///
+/// #[derive(Serialize)]
+/// #[serde(rename_all = "kebab-case")]
+/// pub enum MessageType {
+/// StartRequest,
+/// EndRequest,
+/// }
+///
+/// impl Display for MessageType {
+/// fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+/// self.serialize(f)
+/// }
+/// }
+/// ```
+impl<'a, 'b> Serializer for &'a mut fmt::Formatter<'b> {
+ type Ok = ();
+ type Error = fmt::Error;
+ type SerializeSeq = Impossible<(), fmt::Error>;
+ type SerializeTuple = Impossible<(), fmt::Error>;
+ type SerializeTupleStruct = Impossible<(), fmt::Error>;
+ type SerializeTupleVariant = Impossible<(), fmt::Error>;
+ type SerializeMap = Impossible<(), fmt::Error>;
+ type SerializeStruct = Impossible<(), fmt::Error>;
+ type SerializeStructVariant = Impossible<(), fmt::Error>;
+
+ fmt_primitives! {
+ serialize_bool: bool,
+ serialize_i8: i8,
+ serialize_i16: i16,
+ serialize_i32: i32,
+ serialize_i64: i64,
+ serialize_u8: u8,
+ serialize_u16: u16,
+ serialize_u32: u32,
+ serialize_u64: u64,
+ serialize_f32: f32,
+ serialize_f64: f64,
+ serialize_char: char,
+ serialize_str: &str,
+ serialize_unit_struct: &'static str,
+ }
+
+ serde_if_integer128! {
+ fmt_primitives! {
+ serialize_i128: i128,
+ serialize_u128: u128,
+ }
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> fmt::Result {
+ Display::fmt(variant, self)
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(self, _name: &'static str, value: &T) -> fmt::Result
+ where
+ T: Serialize,
+ {
+ Serialize::serialize(value, self)
+ }
+
+ fn serialize_bytes(self, _v: &[u8]) -> fmt::Result {
+ Err(fmt::Error)
+ }
+
+ fn serialize_none(self) -> fmt::Result {
+ Err(fmt::Error)
+ }
+
+ fn serialize_some<T: ?Sized>(self, _value: &T) -> fmt::Result
+ where
+ T: Serialize,
+ {
+ Err(fmt::Error)
+ }
+
+ fn serialize_unit(self) -> fmt::Result {
+ Err(fmt::Error)
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> fmt::Result
+ where
+ T: Serialize,
+ {
+ Err(fmt::Error)
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, fmt::Error> {
+ Err(fmt::Error)
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, fmt::Error> {
+ Err(fmt::Error)
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct, fmt::Error> {
+ Err(fmt::Error)
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant, fmt::Error> {
+ Err(fmt::Error)
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, fmt::Error> {
+ Err(fmt::Error)
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStruct, fmt::Error> {
+ Err(fmt::Error)
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant, fmt::Error> {
+ Err(fmt::Error)
+ }
+
+ fn collect_str<T: ?Sized>(self, value: &T) -> fmt::Result
+ where
+ T: Display,
+ {
+ Display::fmt(value, self)
+ }
+}
diff --git a/third_party/rust/serde/src/ser/impls.rs b/third_party/rust/serde/src/ser/impls.rs
new file mode 100644
index 0000000000..da26772611
--- /dev/null
+++ b/third_party/rust/serde/src/ser/impls.rs
@@ -0,0 +1,983 @@
+use lib::*;
+
+use ser::{Error, Serialize, SerializeTuple, Serializer};
+
+////////////////////////////////////////////////////////////////////////////////
+
+macro_rules! primitive_impl {
+ ($ty:ident, $method:ident $($cast:tt)*) => {
+ impl Serialize for $ty {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.$method(*self $($cast)*)
+ }
+ }
+ }
+}
+
+primitive_impl!(bool, serialize_bool);
+primitive_impl!(isize, serialize_i64 as i64);
+primitive_impl!(i8, serialize_i8);
+primitive_impl!(i16, serialize_i16);
+primitive_impl!(i32, serialize_i32);
+primitive_impl!(i64, serialize_i64);
+primitive_impl!(usize, serialize_u64 as u64);
+primitive_impl!(u8, serialize_u8);
+primitive_impl!(u16, serialize_u16);
+primitive_impl!(u32, serialize_u32);
+primitive_impl!(u64, serialize_u64);
+primitive_impl!(f32, serialize_f32);
+primitive_impl!(f64, serialize_f64);
+primitive_impl!(char, serialize_char);
+
+serde_if_integer128! {
+ primitive_impl!(i128, serialize_i128);
+ primitive_impl!(u128, serialize_u128);
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl Serialize for str {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_str(self)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl Serialize for String {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_str(self)
+ }
+}
+
+impl<'a> Serialize for fmt::Arguments<'a> {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_str(self)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+impl Serialize for CStr {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(self.to_bytes())
+ }
+}
+
+#[cfg(feature = "std")]
+impl Serialize for CString {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(self.to_bytes())
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl<T> Serialize for Option<T>
+where
+ T: Serialize,
+{
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match *self {
+ Some(ref value) => serializer.serialize_some(value),
+ None => serializer.serialize_none(),
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl<T: ?Sized> Serialize for PhantomData<T> {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_unit_struct("PhantomData")
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+// Does not require T: Serialize.
+impl<T> Serialize for [T; 0] {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ try!(serializer.serialize_tuple(0)).end()
+ }
+}
+
+macro_rules! array_impls {
+ ($($len:tt)+) => {
+ $(
+ impl<T> Serialize for [T; $len]
+ where
+ T: Serialize,
+ {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut seq = try!(serializer.serialize_tuple($len));
+ for e in self {
+ try!(seq.serialize_element(e));
+ }
+ seq.end()
+ }
+ }
+ )+
+ }
+}
+
+array_impls! {
+ 01 02 03 04 05 06 07 08 09 10
+ 11 12 13 14 15 16 17 18 19 20
+ 21 22 23 24 25 26 27 28 29 30
+ 31 32
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl<T> Serialize for [T]
+where
+ T: Serialize,
+{
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq(self)
+ }
+}
+
+#[cfg(all(any(feature = "std", feature = "alloc"), not(no_relaxed_trait_bounds)))]
+macro_rules! seq_impl {
+ ($ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)*>) => {
+ impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
+ where
+ T: Serialize,
+ {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq(self)
+ }
+ }
+ }
+}
+
+#[cfg(all(any(feature = "std", feature = "alloc"), no_relaxed_trait_bounds))]
+macro_rules! seq_impl {
+ ($ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)*>) => {
+ impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
+ where
+ T: Serialize $(+ $tbound1 $(+ $tbound2)*)*,
+ $($typaram: $bound,)*
+ {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq(self)
+ }
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+seq_impl!(BinaryHeap<T: Ord>);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+seq_impl!(BTreeSet<T: Ord>);
+
+#[cfg(feature = "std")]
+seq_impl!(HashSet<T: Eq + Hash, H: BuildHasher>);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+seq_impl!(LinkedList<T>);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+seq_impl!(Vec<T>);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+seq_impl!(VecDeque<T>);
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl<Idx> Serialize for Range<Idx>
+where
+ Idx: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use super::SerializeStruct;
+ let mut state = try!(serializer.serialize_struct("Range", 2));
+ try!(state.serialize_field("start", &self.start));
+ try!(state.serialize_field("end", &self.end));
+ state.end()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(not(no_range_inclusive))]
+impl<Idx> Serialize for RangeInclusive<Idx>
+where
+ Idx: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use super::SerializeStruct;
+ let mut state = try!(serializer.serialize_struct("RangeInclusive", 2));
+ try!(state.serialize_field("start", &self.start()));
+ try!(state.serialize_field("end", &self.end()));
+ state.end()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
+impl<T> Serialize for Bound<T>
+where
+ T: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match *self {
+ Bound::Unbounded => serializer.serialize_unit_variant("Bound", 0, "Unbounded"),
+ Bound::Included(ref value) => {
+ serializer.serialize_newtype_variant("Bound", 1, "Included", value)
+ }
+ Bound::Excluded(ref value) => {
+ serializer.serialize_newtype_variant("Bound", 2, "Excluded", value)
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl Serialize for () {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_unit()
+ }
+}
+
+#[cfg(feature = "unstable")]
+impl Serialize for ! {
+ fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ *self
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+macro_rules! tuple_impls {
+ ($($len:expr => ($($n:tt $name:ident)+))+) => {
+ $(
+ impl<$($name),+> Serialize for ($($name,)+)
+ where
+ $($name: Serialize,)+
+ {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut tuple = try!(serializer.serialize_tuple($len));
+ $(
+ try!(tuple.serialize_element(&self.$n));
+ )+
+ tuple.end()
+ }
+ }
+ )+
+ }
+}
+
+tuple_impls! {
+ 1 => (0 T0)
+ 2 => (0 T0 1 T1)
+ 3 => (0 T0 1 T1 2 T2)
+ 4 => (0 T0 1 T1 2 T2 3 T3)
+ 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
+ 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
+ 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
+ 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
+ 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
+ 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
+ 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
+ 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
+ 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
+ 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
+ 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
+ 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(all(any(feature = "std", feature = "alloc"), not(no_relaxed_trait_bounds)))]
+macro_rules! map_impl {
+ ($ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)*>) => {
+ impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
+ where
+ K: Serialize,
+ V: Serialize,
+ {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_map(self)
+ }
+ }
+ }
+}
+
+#[cfg(all(any(feature = "std", feature = "alloc"), no_relaxed_trait_bounds))]
+macro_rules! map_impl {
+ ($ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)*>) => {
+ impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
+ where
+ K: Serialize $(+ $kbound1 $(+ $kbound2)*)*,
+ V: Serialize,
+ $($typaram: $bound,)*
+ {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_map(self)
+ }
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+map_impl!(BTreeMap<K: Ord, V>);
+
+#[cfg(feature = "std")]
+map_impl!(HashMap<K: Eq + Hash, V, H: BuildHasher>);
+
+////////////////////////////////////////////////////////////////////////////////
+
+macro_rules! deref_impl {
+ (
+ $(#[doc = $doc:tt])*
+ <$($desc:tt)+
+ ) => {
+ $(#[doc = $doc])*
+ impl <$($desc)+ {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ (**self).serialize(serializer)
+ }
+ }
+ };
+}
+
+deref_impl!(<'a, T: ?Sized> Serialize for &'a T where T: Serialize);
+deref_impl!(<'a, T: ?Sized> Serialize for &'a mut T where T: Serialize);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+deref_impl!(<T: ?Sized> Serialize for Box<T> where T: Serialize);
+
+#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
+deref_impl! {
+ /// This impl requires the [`"rc"`] Cargo feature of Serde.
+ ///
+ /// Serializing a data structure containing `Rc` will serialize a copy of
+ /// the contents of the `Rc` each time the `Rc` is referenced within the
+ /// data structure. Serialization will not attempt to deduplicate these
+ /// repeated data.
+ ///
+ /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
+ <T: ?Sized> Serialize for Rc<T> where T: Serialize
+}
+
+#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
+deref_impl! {
+ /// This impl requires the [`"rc"`] Cargo feature of Serde.
+ ///
+ /// Serializing a data structure containing `Arc` will serialize a copy of
+ /// the contents of the `Arc` each time the `Arc` is referenced within the
+ /// data structure. Serialization will not attempt to deduplicate these
+ /// repeated data.
+ ///
+ /// [`"rc"`]: https://serde.rs/feature-flags.html#-features-rc
+ <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);
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// 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,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: 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(not(no_num_nonzero))]
+ impl Serialize for num::$T {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.get().serialize(serializer)
+ }
+ }
+ )+
+ }
+}
+
+nonzero_integers! {
+ NonZeroU8,
+ NonZeroU16,
+ NonZeroU32,
+ NonZeroU64,
+ NonZeroUsize,
+}
+
+#[cfg(not(no_num_nonzero_signed))]
+nonzero_integers! {
+ NonZeroI8,
+ NonZeroI16,
+ NonZeroI32,
+ NonZeroI64,
+ NonZeroIsize,
+}
+
+// Currently 128-bit integers do not work on Emscripten targets so we need an
+// additional `#[cfg]`
+serde_if_integer128! {
+ nonzero_integers! {
+ NonZeroU128,
+ }
+
+ #[cfg(not(no_num_nonzero_signed))]
+ nonzero_integers! {
+ NonZeroI128,
+ }
+}
+
+impl<T> Serialize for Cell<T>
+where
+ T: Serialize + Copy,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.get().serialize(serializer)
+ }
+}
+
+impl<T: ?Sized> Serialize for RefCell<T>
+where
+ T: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match self.try_borrow() {
+ Ok(value) => value.serialize(serializer),
+ Err(_) => Err(S::Error::custom("already mutably borrowed")),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<T: ?Sized> Serialize for Mutex<T>
+where
+ T: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match self.lock() {
+ Ok(locked) => locked.serialize(serializer),
+ Err(_) => Err(S::Error::custom("lock poison error while serializing")),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<T: ?Sized> Serialize for RwLock<T>
+where
+ T: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match self.read() {
+ Ok(locked) => locked.serialize(serializer),
+ Err(_) => Err(S::Error::custom("lock poison error while serializing")),
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl<T, E> Serialize for Result<T, E>
+where
+ T: Serialize,
+ E: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match *self {
+ Result::Ok(ref value) => serializer.serialize_newtype_variant("Result", 0, "Ok", value),
+ Result::Err(ref value) => {
+ serializer.serialize_newtype_variant("Result", 1, "Err", value)
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(any(feature = "std", not(no_core_duration)))]
+impl Serialize for Duration {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use super::SerializeStruct;
+ let mut state = try!(serializer.serialize_struct("Duration", 2));
+ try!(state.serialize_field("secs", &self.as_secs()));
+ try!(state.serialize_field("nanos", &self.subsec_nanos()));
+ state.end()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+impl Serialize for SystemTime {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use super::SerializeStruct;
+ let duration_since_epoch = match self.duration_since(UNIX_EPOCH) {
+ Ok(duration_since_epoch) => duration_since_epoch,
+ Err(_) => return Err(S::Error::custom("SystemTime must be later than UNIX_EPOCH")),
+ };
+ let mut state = try!(serializer.serialize_struct("SystemTime", 2));
+ try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
+ try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
+ state.end()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// Serialize a value that implements `Display` as a string, when that string is
+/// statically known to never have more than a constant `MAX_LEN` bytes.
+///
+/// Panics if the `Display` impl tries to write more than `MAX_LEN` bytes.
+#[cfg(feature = "std")]
+macro_rules! serialize_display_bounded_length {
+ ($value:expr, $max:expr, $serializer:expr) => {{
+ let mut buffer = [0u8; $max];
+ let remaining_len = {
+ let mut remaining = &mut buffer[..];
+ write!(remaining, "{}", $value).unwrap();
+ remaining.len()
+ };
+ let written_len = buffer.len() - remaining_len;
+ let written = &buffer[..written_len];
+
+ // write! only provides fmt::Formatter to Display implementations, which
+ // has methods write_str and write_char but no method to write arbitrary
+ // bytes. Therefore `written` must be valid UTF-8.
+ let written_str = str::from_utf8(written).expect("must be valid UTF-8");
+ $serializer.serialize_str(written_str)
+ }};
+}
+
+#[cfg(feature = "std")]
+impl Serialize for net::IpAddr {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ if serializer.is_human_readable() {
+ match *self {
+ net::IpAddr::V4(ref a) => a.serialize(serializer),
+ net::IpAddr::V6(ref a) => a.serialize(serializer),
+ }
+ } else {
+ match *self {
+ net::IpAddr::V4(ref a) => {
+ serializer.serialize_newtype_variant("IpAddr", 0, "V4", a)
+ }
+ net::IpAddr::V6(ref a) => {
+ serializer.serialize_newtype_variant("IpAddr", 1, "V6", a)
+ }
+ }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+const DEC_DIGITS_LUT: &'static [u8] = b"\
+ 0001020304050607080910111213141516171819\
+ 2021222324252627282930313233343536373839\
+ 4041424344454647484950515253545556575859\
+ 6061626364656667686970717273747576777879\
+ 8081828384858687888990919293949596979899";
+
+#[cfg(feature = "std")]
+#[inline]
+fn format_u8(mut n: u8, out: &mut [u8]) -> usize {
+ if n >= 100 {
+ let d1 = ((n % 100) << 1) as usize;
+ n /= 100;
+ out[0] = b'0' + n;
+ out[1] = DEC_DIGITS_LUT[d1];
+ out[2] = DEC_DIGITS_LUT[d1 + 1];
+ 3
+ } else if n >= 10 {
+ let d1 = (n << 1) as usize;
+ out[0] = DEC_DIGITS_LUT[d1];
+ out[1] = DEC_DIGITS_LUT[d1 + 1];
+ 2
+ } else {
+ out[0] = b'0' + n;
+ 1
+ }
+}
+
+#[cfg(feature = "std")]
+#[test]
+fn test_format_u8() {
+ let mut i = 0u8;
+
+ loop {
+ let mut buf = [0u8; 3];
+ let written = format_u8(i, &mut buf);
+ assert_eq!(i.to_string().as_bytes(), &buf[..written]);
+
+ match i.checked_add(1) {
+ Some(next) => i = next,
+ None => break,
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl Serialize for net::Ipv4Addr {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ if serializer.is_human_readable() {
+ const MAX_LEN: usize = 15;
+ debug_assert_eq!(MAX_LEN, "101.102.103.104".len());
+ let mut buf = [b'.'; MAX_LEN];
+ let mut written = format_u8(self.octets()[0], &mut buf);
+ for oct in &self.octets()[1..] {
+ // Skip over delimiters that we initialized buf with
+ written += format_u8(*oct, &mut buf[written + 1..]) + 1;
+ }
+ // Safety: We've only written ASCII bytes to the buffer, so it is valid UTF-8
+ let buf = unsafe { str::from_utf8_unchecked(&buf[..written]) };
+ serializer.serialize_str(buf)
+ } else {
+ self.octets().serialize(serializer)
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl Serialize for net::Ipv6Addr {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ if serializer.is_human_readable() {
+ const MAX_LEN: usize = 39;
+ debug_assert_eq!(MAX_LEN, "1001:1002:1003:1004:1005:1006:1007:1008".len());
+ serialize_display_bounded_length!(self, MAX_LEN, serializer)
+ } else {
+ self.octets().serialize(serializer)
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl Serialize for net::SocketAddr {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ if serializer.is_human_readable() {
+ match *self {
+ net::SocketAddr::V4(ref addr) => addr.serialize(serializer),
+ net::SocketAddr::V6(ref addr) => addr.serialize(serializer),
+ }
+ } else {
+ match *self {
+ net::SocketAddr::V4(ref addr) => {
+ serializer.serialize_newtype_variant("SocketAddr", 0, "V4", addr)
+ }
+ net::SocketAddr::V6(ref addr) => {
+ serializer.serialize_newtype_variant("SocketAddr", 1, "V6", addr)
+ }
+ }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl Serialize for net::SocketAddrV4 {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ if serializer.is_human_readable() {
+ const MAX_LEN: usize = 21;
+ debug_assert_eq!(MAX_LEN, "101.102.103.104:65000".len());
+ serialize_display_bounded_length!(self, MAX_LEN, serializer)
+ } else {
+ (self.ip(), self.port()).serialize(serializer)
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl Serialize for net::SocketAddrV6 {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ if serializer.is_human_readable() {
+ const MAX_LEN: usize = 58;
+ debug_assert_eq!(
+ MAX_LEN,
+ "[1001:1002:1003:1004:1005:1006:1007:1008%4294967295]:65000".len()
+ );
+ serialize_display_bounded_length!(self, MAX_LEN, serializer)
+ } else {
+ (self.ip(), self.port()).serialize(serializer)
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+impl Serialize for Path {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match self.to_str() {
+ Some(s) => s.serialize(serializer),
+ None => Err(Error::custom("path contains invalid UTF-8 characters")),
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl Serialize for PathBuf {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.as_path().serialize(serializer)
+ }
+}
+
+#[cfg(all(feature = "std", any(unix, windows)))]
+impl Serialize for OsStr {
+ #[cfg(unix)]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use std::os::unix::ffi::OsStrExt;
+ serializer.serialize_newtype_variant("OsString", 0, "Unix", self.as_bytes())
+ }
+
+ #[cfg(windows)]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use std::os::windows::ffi::OsStrExt;
+ let val = self.encode_wide().collect::<Vec<_>>();
+ serializer.serialize_newtype_variant("OsString", 1, "Windows", &val)
+ }
+}
+
+#[cfg(all(feature = "std", any(unix, windows)))]
+impl Serialize for OsString {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.as_os_str().serialize(serializer)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+impl<T> Serialize for Wrapping<T>
+where
+ T: Serialize,
+{
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.0.serialize(serializer)
+ }
+}
+
+#[cfg(not(no_core_reverse))]
+impl<T> Serialize for Reverse<T>
+where
+ T: Serialize,
+{
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.0.serialize(serializer)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(all(feature = "std", not(no_std_atomic)))]
+macro_rules! atomic_impl {
+ ($($ty:ident $size:expr)*) => {
+ $(
+ #[cfg(any(no_target_has_atomic, target_has_atomic = $size))]
+ impl Serialize for $ty {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ // Matches the atomic ordering used in libcore for the Debug impl
+ self.load(Ordering::Relaxed).serialize(serializer)
+ }
+ }
+ )*
+ }
+}
+
+#[cfg(all(feature = "std", not(no_std_atomic)))]
+atomic_impl! {
+ AtomicBool "8"
+ AtomicI8 "8"
+ AtomicI16 "16"
+ AtomicI32 "32"
+ AtomicIsize "ptr"
+ AtomicU8 "8"
+ AtomicU16 "16"
+ AtomicU32 "32"
+ AtomicUsize "ptr"
+}
+
+#[cfg(all(feature = "std", not(no_std_atomic64)))]
+atomic_impl! {
+ AtomicI64 "64"
+ AtomicU64 "64"
+}
diff --git a/third_party/rust/serde/src/ser/impossible.rs b/third_party/rust/serde/src/ser/impossible.rs
new file mode 100644
index 0000000000..e8df9ca7aa
--- /dev/null
+++ b/third_party/rust/serde/src/ser/impossible.rs
@@ -0,0 +1,216 @@
+//! This module contains `Impossible` serializer and its implementations.
+
+use lib::*;
+
+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`].
+///
+/// ```edition2018
+/// # use serde::ser::{Serializer, Impossible};
+/// # use serde::__private::doc::Error;
+/// #
+/// # struct MySerializer;
+/// #
+/// impl Serializer for MySerializer {
+/// type Ok = ();
+/// type Error = Error;
+///
+/// type SerializeSeq = Impossible<(), Error>;
+/// /* other associated types */
+///
+/// /// This data format does not support serializing sequences.
+/// fn serialize_seq(self,
+/// len: Option<usize>)
+/// -> Result<Self::SerializeSeq, Error> {
+/// // Given Impossible cannot be instantiated, the only
+/// // thing we can do here is to return an error.
+/// # stringify! {
+/// Err(...)
+/// # };
+/// # unimplemented!()
+/// }
+///
+/// /* other Serializer methods */
+/// # serde::__serialize_unimplemented! {
+/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str bytes none some
+/// # unit unit_struct unit_variant newtype_struct newtype_variant
+/// # tuple tuple_struct tuple_variant map struct struct_variant
+/// # }
+/// }
+/// ```
+///
+/// [`Serializer`]: trait.Serializer.html
+/// [`SerializeSeq`]: trait.SerializeSeq.html
+/// [`SerializeTuple`]: trait.SerializeTuple.html
+/// [`SerializeTupleStruct`]: trait.SerializeTupleStruct.html
+/// [`SerializeTupleVariant`]: trait.SerializeTupleVariant.html
+/// [`SerializeMap`]: trait.SerializeMap.html
+/// [`SerializeStruct`]: trait.SerializeStruct.html
+/// [`SerializeStructVariant`]: trait.SerializeStructVariant.html
+pub struct Impossible<Ok, Error> {
+ void: Void,
+ ok: PhantomData<Ok>,
+ error: PhantomData<Error>,
+}
+
+enum Void {}
+
+impl<Ok, Error> SerializeSeq for Impossible<Ok, Error>
+where
+ Error: ser::Error,
+{
+ type Ok = Ok;
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ let _ = value;
+ match self.void {}
+ }
+
+ fn end(self) -> Result<Ok, Error> {
+ match self.void {}
+ }
+}
+
+impl<Ok, Error> SerializeTuple for Impossible<Ok, Error>
+where
+ Error: ser::Error,
+{
+ type Ok = Ok;
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ let _ = value;
+ match self.void {}
+ }
+
+ fn end(self) -> Result<Ok, Error> {
+ match self.void {}
+ }
+}
+
+impl<Ok, Error> SerializeTupleStruct for Impossible<Ok, Error>
+where
+ Error: ser::Error,
+{
+ type Ok = Ok;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ let _ = value;
+ match self.void {}
+ }
+
+ fn end(self) -> Result<Ok, Error> {
+ match self.void {}
+ }
+}
+
+impl<Ok, Error> SerializeTupleVariant for Impossible<Ok, Error>
+where
+ Error: ser::Error,
+{
+ type Ok = Ok;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ let _ = value;
+ match self.void {}
+ }
+
+ fn end(self) -> Result<Ok, Error> {
+ match self.void {}
+ }
+}
+
+impl<Ok, Error> SerializeMap for Impossible<Ok, Error>
+where
+ Error: ser::Error,
+{
+ type Ok = Ok;
+ type Error = Error;
+
+ fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ let _ = key;
+ match self.void {}
+ }
+
+ fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ let _ = value;
+ match self.void {}
+ }
+
+ fn end(self) -> Result<Ok, Error> {
+ match self.void {}
+ }
+}
+
+impl<Ok, Error> SerializeStruct for Impossible<Ok, Error>
+where
+ Error: ser::Error,
+{
+ type Ok = Ok;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ let _ = key;
+ let _ = value;
+ match self.void {}
+ }
+
+ fn end(self) -> Result<Ok, Error> {
+ match self.void {}
+ }
+}
+
+impl<Ok, Error> SerializeStructVariant for Impossible<Ok, Error>
+where
+ Error: ser::Error,
+{
+ type Ok = Ok;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ let _ = key;
+ let _ = value;
+ match self.void {}
+ }
+
+ fn end(self) -> Result<Ok, Error> {
+ match self.void {}
+ }
+}
diff --git a/third_party/rust/serde/src/ser/mod.rs b/third_party/rust/serde/src/ser/mod.rs
new file mode 100644
index 0000000000..5c45426e80
--- /dev/null
+++ b/third_party/rust/serde/src/ser/mod.rs
@@ -0,0 +1,1988 @@
+//! Generic data structure serialization framework.
+//!
+//! The two most important traits in this module are [`Serialize`] and
+//! [`Serializer`].
+//!
+//! - **A type that implements `Serialize` is a data structure** that can be
+//! serialized to any data format supported by Serde, and conversely
+//! - **A type that implements `Serializer` is a data format** that can
+//! serialize any data structure supported by Serde.
+//!
+//! # The Serialize trait
+//!
+//! Serde provides [`Serialize`] implementations for many Rust primitive and
+//! standard library types. The complete list is below. All of these can be
+//! serialized using Serde out of the box.
+//!
+//! Additionally, Serde provides a procedural macro called [`serde_derive`] to
+//! automatically generate [`Serialize`] implementations for structs and enums
+//! in your program. See the [derive section of the manual] for how to use this.
+//!
+//! In rare cases it may be necessary to implement [`Serialize`] manually for
+//! some type in your program. See the [Implementing `Serialize`] section of the
+//! manual for more about this.
+//!
+//! Third-party crates may provide [`Serialize`] implementations for types that
+//! they expose. For example the [`linked-hash-map`] crate provides a
+//! [`LinkedHashMap<K, V>`] type that is serializable by Serde because the crate
+//! provides an implementation of [`Serialize`] for it.
+//!
+//! # The Serializer trait
+//!
+//! [`Serializer`] implementations are provided by third-party crates, for
+//! example [`serde_json`], [`serde_yaml`] and [`postcard`].
+//!
+//! A partial list of well-maintained formats is given on the [Serde
+//! website][data formats].
+//!
+//! # Implementations of Serialize provided by Serde
+//!
+//! - **Primitive types**:
+//! - bool
+//! - i8, i16, i32, i64, i128, isize
+//! - u8, u16, u32, u64, u128, usize
+//! - f32, f64
+//! - char
+//! - str
+//! - &T and &mut T
+//! - **Compound types**:
+//! - \[T\]
+//! - \[T; 0\] through \[T; 32\]
+//! - tuples up to size 16
+//! - **Common standard library types**:
+//! - String
+//! - Option\<T\>
+//! - Result\<T, E\>
+//! - PhantomData\<T\>
+//! - **Wrapper types**:
+//! - Box\<T\>
+//! - Cow\<'a, T\>
+//! - Cell\<T\>
+//! - RefCell\<T\>
+//! - Mutex\<T\>
+//! - RwLock\<T\>
+//! - Rc\<T\>&emsp;*(if* features = ["rc"] *is enabled)*
+//! - Arc\<T\>&emsp;*(if* features = ["rc"] *is enabled)*
+//! - **Collection types**:
+//! - BTreeMap\<K, V\>
+//! - BTreeSet\<T\>
+//! - BinaryHeap\<T\>
+//! - HashMap\<K, V, H\>
+//! - HashSet\<T, H\>
+//! - LinkedList\<T\>
+//! - VecDeque\<T\>
+//! - Vec\<T\>
+//! - **FFI types**:
+//! - CStr
+//! - CString
+//! - OsStr
+//! - OsString
+//! - **Miscellaneous standard library types**:
+//! - Duration
+//! - SystemTime
+//! - Path
+//! - PathBuf
+//! - Range\<T\>
+//! - RangeInclusive\<T\>
+//! - Bound\<T\>
+//! - num::NonZero*
+//! - `!` *(unstable)*
+//! - **Net types**:
+//! - IpAddr
+//! - Ipv4Addr
+//! - Ipv6Addr
+//! - SocketAddr
+//! - SocketAddrV4
+//! - SocketAddrV6
+//!
+//! [Implementing `Serialize`]: https://serde.rs/impl-serialize.html
+//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
+//! [`Serialize`]: ../trait.Serialize.html
+//! [`Serializer`]: ../trait.Serializer.html
+//! [`postcard`]: https://github.com/jamesmunns/postcard
+//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
+//! [`serde_derive`]: https://crates.io/crates/serde_derive
+//! [`serde_json`]: https://github.com/serde-rs/json
+//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml
+//! [derive section of the manual]: https://serde.rs/derive.html
+//! [data formats]: https://serde.rs/#data-formats
+
+use lib::*;
+
+mod fmt;
+mod impls;
+mod impossible;
+
+pub use self::impossible::Impossible;
+
+#[cfg(all(feature = "unstable", not(feature = "std")))]
+#[doc(inline)]
+pub use core::error::Error as StdError;
+#[cfg(feature = "std")]
+#[doc(no_inline)]
+pub use std::error::Error as StdError;
+#[cfg(not(any(feature = "std", feature = "unstable")))]
+#[doc(no_inline)]
+pub use std_error::Error as StdError;
+
+////////////////////////////////////////////////////////////////////////////////
+
+macro_rules! declare_error_trait {
+ (Error: Sized $(+ $($supertrait:ident)::+)*) => {
+ /// Trait used by `Serialize` implementations to generically construct
+ /// errors belonging to the `Serializer` against which they are
+ /// currently running.
+ ///
+ /// # Example implementation
+ ///
+ /// The [example data format] presented on the website shows an error
+ /// type appropriate for a basic JSON data format.
+ ///
+ /// [example data format]: https://serde.rs/data-format.html
+ pub trait Error: Sized $(+ $($supertrait)::+)* {
+ /// Used when a [`Serialize`] implementation encounters any error
+ /// while serializing a type.
+ ///
+ /// The message should not be capitalized and should not end with a
+ /// period.
+ ///
+ /// For example, a filesystem [`Path`] may refuse to serialize
+ /// itself if it contains invalid UTF-8 data.
+ ///
+ /// ```edition2018
+ /// # struct Path;
+ /// #
+ /// # impl Path {
+ /// # fn to_str(&self) -> Option<&str> {
+ /// # 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,
+ /// {
+ /// match self.to_str() {
+ /// Some(s) => serializer.serialize_str(s),
+ /// None => Err(ser::Error::custom("path contains invalid UTF-8 characters")),
+ /// }
+ /// }
+ /// }
+ /// ```
+ ///
+ /// [`Path`]: https://doc.rust-lang.org/std/path/struct.Path.html
+ /// [`Serialize`]: ../trait.Serialize.html
+ fn custom<T>(msg: T) -> Self
+ where
+ T: Display;
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+declare_error_trait!(Error: Sized + StdError);
+
+#[cfg(not(feature = "std"))]
+declare_error_trait!(Error: Sized + Debug + Display);
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A **data structure** that can be serialized into any data format supported
+/// by Serde.
+///
+/// Serde provides `Serialize` implementations for many Rust primitive and
+/// standard library types. The complete list is [here][crate::ser]. All of
+/// these can be serialized using Serde out of the box.
+///
+/// Additionally, Serde provides a procedural macro called [`serde_derive`] to
+/// automatically generate `Serialize` implementations for structs and enums in
+/// your program. See the [derive section of the manual] for how to use this.
+///
+/// In rare cases it may be necessary to implement `Serialize` manually for some
+/// type in your program. See the [Implementing `Serialize`] section of the
+/// manual for more about this.
+///
+/// Third-party crates may provide `Serialize` implementations for types that
+/// they expose. For example the [`linked-hash-map`] crate provides a
+/// [`LinkedHashMap<K, V>`] type that is serializable by Serde because the crate
+/// provides an implementation of `Serialize` for it.
+///
+/// [Implementing `Serialize`]: https://serde.rs/impl-serialize.html
+/// [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
+/// [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
+/// [`serde_derive`]: https://crates.io/crates/serde_derive
+/// [derive section of the manual]: https://serde.rs/derive.html
+pub trait Serialize {
+ /// Serialize this value into the given Serde serializer.
+ ///
+ /// See the [Implementing `Serialize`] section of the manual for more
+ /// information about how to implement this method.
+ ///
+ /// ```edition2018
+ /// use serde::ser::{Serialize, SerializeStruct, Serializer};
+ ///
+ /// struct Person {
+ /// 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,
+ /// {
+ /// 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()
+ /// }
+ /// }
+ /// ```
+ ///
+ /// [Implementing `Serialize`]: https://serde.rs/impl-serialize.html
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+/// A **data format** that can serialize any data structure supported by Serde.
+///
+/// The role of this trait is to define the serialization half of the [Serde
+/// data model], which is a way to categorize every Rust data structure into one
+/// of 29 possible types. Each method of the `Serializer` trait corresponds to
+/// one of the types of the data model.
+///
+/// Implementations of `Serialize` map themselves into this data model by
+/// invoking exactly one of the `Serializer` methods.
+///
+/// The types that make up the Serde data model are:
+///
+/// - **14 primitive types**
+/// - bool
+/// - i8, i16, i32, i64, i128
+/// - u8, u16, u32, u64, u128
+/// - f32, f64
+/// - char
+/// - **string**
+/// - UTF-8 bytes with a length and no null terminator.
+/// - When serializing, all strings are handled equally. When deserializing,
+/// there are three flavors of strings: transient, owned, and borrowed.
+/// - **byte array** - \[u8\]
+/// - Similar to strings, during deserialization byte arrays can be
+/// transient, owned, or borrowed.
+/// - **option**
+/// - Either none or some value.
+/// - **unit**
+/// - The type of `()` in Rust. It represents an anonymous value containing
+/// no data.
+/// - **unit_struct**
+/// - For example `struct Unit` or `PhantomData<T>`. It represents a named
+/// value containing no data.
+/// - **unit_variant**
+/// - For example the `E::A` and `E::B` in `enum E { A, B }`.
+/// - **newtype_struct**
+/// - For example `struct Millimeters(u8)`.
+/// - **newtype_variant**
+/// - For example the `E::N` in `enum E { N(u8) }`.
+/// - **seq**
+/// - A variably sized heterogeneous sequence of values, for example
+/// `Vec<T>` or `HashSet<T>`. When serializing, the length may or may not
+/// be known before iterating through all the data. When deserializing,
+/// the length is determined by looking at the serialized data.
+/// - **tuple**
+/// - A statically sized heterogeneous sequence of values for which the
+/// length will be known at deserialization time without looking at the
+/// serialized data, for example `(u8,)` or `(String, u64, Vec<T>)` or
+/// `[u64; 10]`.
+/// - **tuple_struct**
+/// - A named tuple, for example `struct Rgb(u8, u8, u8)`.
+/// - **tuple_variant**
+/// - For example the `E::T` in `enum E { T(u8, u8) }`.
+/// - **map**
+/// - A heterogeneous key-value pairing, for example `BTreeMap<K, V>`.
+/// - **struct**
+/// - A heterogeneous key-value pairing in which the keys are strings and
+/// will be known at deserialization time without looking at the
+/// serialized data, for example `struct S { r: u8, g: u8, b: u8 }`.
+/// - **struct_variant**
+/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
+///
+/// Many Serde serializers produce text or binary data as output, for example
+/// JSON or Postcard. This is not a requirement of the `Serializer` trait, and
+/// there are serializers that do not produce text or binary output. One example
+/// is the `serde_json::value::Serializer` (distinct from the main `serde_json`
+/// serializer) that produces a `serde_json::Value` data structure in memory as
+/// output.
+///
+/// [Serde data model]: https://serde.rs/data-model.html
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website contains example code for
+/// a basic JSON `Serializer`.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait Serializer: Sized {
+ /// The output type produced by this `Serializer` during successful
+ /// serialization. Most serializers that produce text or binary output
+ /// should set `Ok = ()` and serialize into an [`io::Write`] or buffer
+ /// contained within the `Serializer` instance. Serializers that build
+ /// in-memory data structures may be simplified by using `Ok` to propagate
+ /// the data structure around.
+ ///
+ /// [`io::Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
+ type Ok;
+
+ /// The error type when some error occurs during serialization.
+ type Error: Error;
+
+ /// Type returned from [`serialize_seq`] for serializing the content of the
+ /// sequence.
+ ///
+ /// [`serialize_seq`]: #tymethod.serialize_seq
+ type SerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>;
+
+ /// Type returned from [`serialize_tuple`] for serializing the content of
+ /// the tuple.
+ ///
+ /// [`serialize_tuple`]: #tymethod.serialize_tuple
+ type SerializeTuple: SerializeTuple<Ok = Self::Ok, Error = Self::Error>;
+
+ /// Type returned from [`serialize_tuple_struct`] for serializing the
+ /// content of the tuple struct.
+ ///
+ /// [`serialize_tuple_struct`]: #tymethod.serialize_tuple_struct
+ type SerializeTupleStruct: SerializeTupleStruct<Ok = Self::Ok, Error = Self::Error>;
+
+ /// Type returned from [`serialize_tuple_variant`] for serializing the
+ /// content of the tuple variant.
+ ///
+ /// [`serialize_tuple_variant`]: #tymethod.serialize_tuple_variant
+ type SerializeTupleVariant: SerializeTupleVariant<Ok = Self::Ok, Error = Self::Error>;
+
+ /// Type returned from [`serialize_map`] for serializing the content of the
+ /// map.
+ ///
+ /// [`serialize_map`]: #tymethod.serialize_map
+ type SerializeMap: SerializeMap<Ok = Self::Ok, Error = Self::Error>;
+
+ /// Type returned from [`serialize_struct`] for serializing the content of
+ /// the struct.
+ ///
+ /// [`serialize_struct`]: #tymethod.serialize_struct
+ type SerializeStruct: SerializeStruct<Ok = Self::Ok, Error = Self::Error>;
+
+ /// Type returned from [`serialize_struct_variant`] for serializing the
+ /// content of the struct variant.
+ ///
+ /// [`serialize_struct_variant`]: #tymethod.serialize_struct_variant
+ type SerializeStructVariant: SerializeStructVariant<Ok = Self::Ok, Error = Self::Error>;
+
+ /// Serialize a `bool` value.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for bool {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_bool(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize an `i8` value.
+ ///
+ /// If the format does not differentiate between `i8` and `i64`, a
+ /// reasonable implementation would be to cast the value to `i64` and
+ /// forward to `serialize_i64`.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for i8 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_i8(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize an `i16` value.
+ ///
+ /// If the format does not differentiate between `i16` and `i64`, a
+ /// reasonable implementation would be to cast the value to `i64` and
+ /// forward to `serialize_i64`.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for i16 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_i16(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize an `i32` value.
+ ///
+ /// If the format does not differentiate between `i32` and `i64`, a
+ /// reasonable implementation would be to cast the value to `i64` and
+ /// forward to `serialize_i64`.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for i32 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_i32(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize an `i64` value.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for i64 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_i64(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>;
+
+ serde_if_integer128! {
+ /// Serialize an `i128` value.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for i128 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_i128(*self)
+ /// }
+ /// }
+ /// ```
+ ///
+ /// This method is available only on Rust compiler versions >=1.26. The
+ /// default behavior unconditionally returns an error.
+ fn serialize_i128(self, v: i128) -> Result<Self::Ok, Self::Error> {
+ let _ = v;
+ Err(Error::custom("i128 is not supported"))
+ }
+ }
+
+ /// Serialize a `u8` value.
+ ///
+ /// If the format does not differentiate between `u8` and `u64`, a
+ /// reasonable implementation would be to cast the value to `u64` and
+ /// forward to `serialize_u64`.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for u8 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_u8(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize a `u16` value.
+ ///
+ /// If the format does not differentiate between `u16` and `u64`, a
+ /// reasonable implementation would be to cast the value to `u64` and
+ /// forward to `serialize_u64`.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for u16 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_u16(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize a `u32` value.
+ ///
+ /// If the format does not differentiate between `u32` and `u64`, a
+ /// reasonable implementation would be to cast the value to `u64` and
+ /// forward to `serialize_u64`.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for u32 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_u32(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize a `u64` value.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for u64 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_u64(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>;
+
+ serde_if_integer128! {
+ /// Serialize a `u128` value.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for u128 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_u128(*self)
+ /// }
+ /// }
+ /// ```
+ ///
+ /// This method is available only on Rust compiler versions >=1.26. The
+ /// default behavior unconditionally returns an error.
+ fn serialize_u128(self, v: u128) -> Result<Self::Ok, Self::Error> {
+ let _ = v;
+ Err(Error::custom("u128 is not supported"))
+ }
+ }
+
+ /// Serialize an `f32` value.
+ ///
+ /// If the format does not differentiate between `f32` and `f64`, a
+ /// reasonable implementation would be to cast the value to `f64` and
+ /// forward to `serialize_f64`.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for f32 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_f32(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize an `f64` value.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for f64 {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_f64(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize a character.
+ ///
+ /// If the format does not support characters, it is reasonable to serialize
+ /// it as a single element `str` or a `u32`.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for char {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_char(*self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize a `&str`.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for str {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_str(self)
+ /// }
+ /// }
+ /// ```
+ fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize a chunk of raw byte data.
+ ///
+ /// Enables serializers to serialize byte slices more compactly or more
+ /// efficiently than other types of slices. If no efficient implementation
+ /// is available, a reasonable implementation would be to forward to
+ /// `serialize_seq`. If forwarded, the implementation looks usually just
+ /// like this:
+ ///
+ /// ```edition2018
+ /// # use serde::ser::{Serializer, SerializeSeq};
+ /// # use serde::__private::doc::Error;
+ /// #
+ /// # struct MySerializer;
+ /// #
+ /// # impl Serializer for MySerializer {
+ /// # type Ok = ();
+ /// # type Error = Error;
+ /// #
+ /// fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error> {
+ /// let mut seq = self.serialize_seq(Some(v.len()))?;
+ /// for b in v {
+ /// seq.serialize_element(b)?;
+ /// }
+ /// seq.end()
+ /// }
+ /// #
+ /// # serde::__serialize_unimplemented! {
+ /// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str none some
+ /// # unit unit_struct unit_variant newtype_struct newtype_variant
+ /// # seq tuple tuple_struct tuple_variant map struct struct_variant
+ /// # }
+ /// # }
+ /// ```
+ fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize a [`None`] value.
+ ///
+ /// ```edition2018
+ /// # use serde::{Serialize, Serializer};
+ /// #
+ /// # enum Option<T> {
+ /// # Some(T),
+ /// # None,
+ /// # }
+ /// #
+ /// # use self::Option::{Some, None};
+ /// #
+ /// impl<T> Serialize for Option<T>
+ /// where
+ /// T: Serialize,
+ /// {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// match *self {
+ /// Some(ref value) => serializer.serialize_some(value),
+ /// None => serializer.serialize_none(),
+ /// }
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ ///
+ /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.None
+ fn serialize_none(self) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize a [`Some(T)`] value.
+ ///
+ /// ```edition2018
+ /// # use serde::{Serialize, Serializer};
+ /// #
+ /// # enum Option<T> {
+ /// # Some(T),
+ /// # None,
+ /// # }
+ /// #
+ /// # use self::Option::{Some, None};
+ /// #
+ /// impl<T> Serialize for Option<T>
+ /// where
+ /// T: Serialize,
+ /// {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// match *self {
+ /// Some(ref value) => serializer.serialize_some(value),
+ /// None => serializer.serialize_none(),
+ /// }
+ /// }
+ /// }
+ /// #
+ /// # fn main() {}
+ /// ```
+ ///
+ /// [`Some(T)`]: https://doc.rust-lang.org/std/option/enum.Option.html#variant.Some
+ fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize;
+
+ /// Serialize a `()` value.
+ ///
+ /// ```edition2018
+ /// # use serde::Serializer;
+ /// #
+ /// # serde::__private_serialize!();
+ /// #
+ /// impl Serialize for () {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// serializer.serialize_unit()
+ /// }
+ /// }
+ /// ```
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize a unit struct like `struct Unit` or `PhantomData<T>`.
+ ///
+ /// A reasonable implementation would be to forward to `serialize_unit`.
+ ///
+ /// ```edition2018
+ /// use serde::{Serialize, Serializer};
+ ///
+ /// struct Nothing;
+ ///
+ /// impl Serialize for Nothing {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// 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 }`.
+ ///
+ /// The `name` is the name of the enum, the `variant_index` is the index of
+ /// this variant within the enum, and the `variant` is the name of the
+ /// variant.
+ ///
+ /// ```edition2018
+ /// use serde::{Serialize, Serializer};
+ ///
+ /// enum E {
+ /// A,
+ /// B,
+ /// }
+ ///
+ /// impl Serialize for E {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// match *self {
+ /// E::A => serializer.serialize_unit_variant("E", 0, "A"),
+ /// E::B => serializer.serialize_unit_variant("E", 1, "B"),
+ /// }
+ /// }
+ /// }
+ /// ```
+ fn serialize_unit_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Self::Ok, Self::Error>;
+
+ /// Serialize a newtype struct like `struct Millimeters(u8)`.
+ ///
+ /// Serializers are encouraged to treat newtype structs as insignificant
+ /// wrappers around the data they contain. A reasonable implementation would
+ /// be to forward to `value.serialize(self)`.
+ ///
+ /// ```edition2018
+ /// 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,
+ /// {
+ /// serializer.serialize_newtype_struct("Millimeters", &self.0)
+ /// }
+ /// }
+ /// ```
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ name: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize;
+
+ /// Serialize a newtype variant like `E::N` in `enum E { N(u8) }`.
+ ///
+ /// The `name` is the name of the enum, the `variant_index` is the index of
+ /// this variant within the enum, and the `variant` is the name of the
+ /// variant. The `value` is the data contained within this newtype variant.
+ ///
+ /// ```edition2018
+ /// use serde::{Serialize, Serializer};
+ ///
+ /// enum E {
+ /// M(String),
+ /// N(u8),
+ /// }
+ ///
+ /// impl Serialize for E {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// 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),
+ /// }
+ /// }
+ /// }
+ /// ```
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize;
+
+ /// Begin to serialize a variably sized sequence. This call must be
+ /// followed by zero or more calls to `serialize_element`, then a call to
+ /// `end`.
+ ///
+ /// The argument is the number of elements in the sequence, which may or may
+ /// not be computable before the sequence is iterated. Some serializers only
+ /// support sequences whose length is known up front.
+ ///
+ /// ```edition2018
+ /// # use std::marker::PhantomData;
+ /// #
+ /// # struct Vec<T>(PhantomData<T>);
+ /// #
+ /// # impl<T> Vec<T> {
+ /// # fn len(&self) -> usize {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// # impl<'a, T> IntoIterator for &'a Vec<T> {
+ /// # type Item = &'a T;
+ /// # type IntoIter = Box<Iterator<Item = &'a T>>;
+ /// #
+ /// # fn into_iter(self) -> Self::IntoIter {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// use serde::ser::{Serialize, Serializer, SerializeSeq};
+ ///
+ /// impl<T> Serialize for Vec<T>
+ /// where
+ /// T: Serialize,
+ /// {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// let mut seq = serializer.serialize_seq(Some(self.len()))?;
+ /// for element in self {
+ /// seq.serialize_element(element)?;
+ /// }
+ /// seq.end()
+ /// }
+ /// }
+ /// ```
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error>;
+
+ /// Begin to serialize a statically sized sequence whose length will be
+ /// known at deserialization time without looking at the serialized data.
+ /// This call must be followed by zero or more calls to `serialize_element`,
+ /// then a call to `end`.
+ ///
+ /// ```edition2018
+ /// use serde::ser::{Serialize, Serializer, SerializeTuple};
+ ///
+ /// # mod fool {
+ /// # 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,
+ /// {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// 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()
+ /// }
+ /// }
+ /// ```
+ ///
+ /// ```edition2018
+ /// use serde::ser::{Serialize, SerializeTuple, Serializer};
+ ///
+ /// 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,
+ /// {
+ /// let mut seq = serializer.serialize_tuple(VRAM_SIZE)?;
+ /// for element in &self.0[..] {
+ /// seq.serialize_element(element)?;
+ /// }
+ /// seq.end()
+ /// }
+ /// }
+ /// ```
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error>;
+
+ /// Begin to serialize a tuple struct like `struct Rgb(u8, u8, u8)`. This
+ /// call must be followed by zero or more calls to `serialize_field`, then a
+ /// call to `end`.
+ ///
+ /// The `name` is the name of the tuple struct and the `len` is the number
+ /// of data fields that will be serialized.
+ ///
+ /// ```edition2018
+ /// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
+ ///
+ /// struct Rgb(u8, u8, u8);
+ ///
+ /// impl Serialize for Rgb {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// 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()
+ /// }
+ /// }
+ /// ```
+ fn serialize_tuple_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::Error>;
+
+ /// Begin to serialize a tuple variant like `E::T` in `enum E { T(u8, u8)
+ /// }`. This call must be followed by zero or more calls to
+ /// `serialize_field`, then a call to `end`.
+ ///
+ /// The `name` is the name of the enum, the `variant_index` is the index of
+ /// this variant within the enum, the `variant` is the name of the variant,
+ /// and the `len` is the number of data fields that will be serialized.
+ ///
+ /// ```edition2018
+ /// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
+ ///
+ /// 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,
+ /// {
+ /// 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()
+ /// }
+ /// E::U(ref a, ref b, ref c) => {
+ /// let mut tv = serializer.serialize_tuple_variant("E", 1, "U", 3)?;
+ /// tv.serialize_field(a)?;
+ /// tv.serialize_field(b)?;
+ /// tv.serialize_field(c)?;
+ /// tv.end()
+ /// }
+ /// }
+ /// }
+ /// }
+ /// ```
+ fn serialize_tuple_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Self::Error>;
+
+ /// Begin to serialize a map. This call must be followed by zero or more
+ /// calls to `serialize_key` and `serialize_value`, then a call to `end`.
+ ///
+ /// The argument is the number of elements in the map, which may or may not
+ /// be computable before the map is iterated. Some serializers only support
+ /// maps whose length is known up front.
+ ///
+ /// ```edition2018
+ /// # use std::marker::PhantomData;
+ /// #
+ /// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>);
+ /// #
+ /// # impl<K, V> HashMap<K, V> {
+ /// # fn len(&self) -> usize {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// # impl<'a, K, V> IntoIterator for &'a HashMap<K, V> {
+ /// # type Item = (&'a K, &'a V);
+ /// # type IntoIter = Box<Iterator<Item = (&'a K, &'a V)>>;
+ /// #
+ /// # 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,
+ /// {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where
+ /// S: Serializer,
+ /// {
+ /// let mut map = serializer.serialize_map(Some(self.len()))?;
+ /// for (k, v) in self {
+ /// map.serialize_entry(k, v)?;
+ /// }
+ /// map.end()
+ /// }
+ /// }
+ /// ```
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error>;
+
+ /// Begin to serialize a struct like `struct Rgb { r: u8, g: u8, b: u8 }`.
+ /// This call must be followed by zero or more calls to `serialize_field`,
+ /// then a call to `end`.
+ ///
+ /// The `name` is the name of the struct and the `len` is the number of
+ /// data fields that will be serialized.
+ ///
+ /// ```edition2018
+ /// use serde::ser::{Serialize, SerializeStruct, Serializer};
+ ///
+ /// 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,
+ /// {
+ /// 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()
+ /// }
+ /// }
+ /// ```
+ fn serialize_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStruct, Self::Error>;
+
+ /// Begin to serialize a struct variant like `E::S` in `enum E { S { r: u8,
+ /// g: u8, b: u8 } }`. This call must be followed by zero or more calls to
+ /// `serialize_field`, then a call to `end`.
+ ///
+ /// The `name` is the name of the enum, the `variant_index` is the index of
+ /// this variant within the enum, the `variant` is the name of the variant,
+ /// and the `len` is the number of data fields that will be serialized.
+ ///
+ /// ```edition2018
+ /// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
+ ///
+ /// 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,
+ /// {
+ /// 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()
+ /// }
+ /// }
+ /// }
+ /// }
+ /// ```
+ fn serialize_struct_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant, Self::Error>;
+
+ /// Collect an iterator as a sequence.
+ ///
+ /// The default implementation serializes each item yielded by the iterator
+ /// using [`serialize_seq`]. Implementors should not need to override this
+ /// method.
+ ///
+ /// ```edition2018
+ /// 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,
+ /// {
+ /// 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>
+ where
+ I: IntoIterator,
+ <I as IntoIterator>::Item: Serialize,
+ {
+ let iter = iter.into_iter();
+ let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter)));
+
+ #[cfg(not(no_iterator_try_fold))]
+ {
+ let mut iter = iter;
+ try!(iter.try_for_each(|item| serializer.serialize_element(&item)));
+ }
+
+ #[cfg(no_iterator_try_fold)]
+ {
+ for item in iter {
+ try!(serializer.serialize_element(&item));
+ }
+ }
+
+ serializer.end()
+ }
+
+ /// Collect an iterator as a map.
+ ///
+ /// The default implementation serializes each pair yielded by the iterator
+ /// using [`serialize_map`]. Implementors should not need to override this
+ /// method.
+ ///
+ /// ```edition2018
+ /// use serde::{Serialize, Serializer};
+ /// use std::collections::BTreeSet;
+ ///
+ /// 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,
+ /// {
+ /// 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>
+ where
+ K: Serialize,
+ V: Serialize,
+ I: IntoIterator<Item = (K, V)>,
+ {
+ let iter = iter.into_iter();
+ let mut serializer = try!(self.serialize_map(iterator_len_hint(&iter)));
+
+ #[cfg(not(no_iterator_try_fold))]
+ {
+ let mut iter = iter;
+ try!(iter.try_for_each(|(key, value)| serializer.serialize_entry(&key, &value)));
+ }
+
+ #[cfg(no_iterator_try_fold)]
+ {
+ for (key, value) in iter {
+ try!(serializer.serialize_entry(&key, &value));
+ }
+ }
+
+ serializer.end()
+ }
+
+ /// Serialize a string produced by an implementation of `Display`.
+ ///
+ /// The default implementation builds a heap-allocated [`String`] and
+ /// delegates to [`serialize_str`]. Serializers are encouraged to provide a
+ /// more efficient implementation if possible.
+ ///
+ /// ```edition2018
+ /// # struct DateTime;
+ /// #
+ /// # impl DateTime {
+ /// # 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,
+ /// {
+ /// serializer.collect_str(&format_args!("{:?}{:?}",
+ /// self.naive_local(),
+ /// self.offset()))
+ /// }
+ /// }
+ /// ```
+ ///
+ /// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
+ /// [`serialize_str`]: #tymethod.serialize_str
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: Display,
+ {
+ self.serialize_str(&value.to_string())
+ }
+
+ /// Serialize a string produced by an implementation of `Display`.
+ ///
+ /// Serializers that use `no_std` are required to provide an implementation
+ /// of this method. If no more sensible behavior is possible, the
+ /// implementation is expected to return an error.
+ ///
+ /// ```edition2018
+ /// # struct DateTime;
+ /// #
+ /// # impl DateTime {
+ /// # 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,
+ /// {
+ /// serializer.collect_str(&format_args!("{:?}{:?}",
+ /// self.naive_local(),
+ /// self.offset()))
+ /// }
+ /// }
+ /// ```
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
+ fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: Display;
+
+ /// Determine whether `Serialize` implementations should serialize in
+ /// human-readable form.
+ ///
+ /// Some types have a human-readable form that may be somewhat expensive to
+ /// construct, as well as a binary form that is compact and efficient.
+ /// Generally text-based formats like JSON and YAML will prefer to use the
+ /// human-readable one and binary formats like Postcard will prefer the
+ /// compact one.
+ ///
+ /// ```edition2018
+ /// # use std::fmt::{self, Display};
+ /// #
+ /// # struct Timestamp;
+ /// #
+ /// # impl Timestamp {
+ /// # fn seconds_since_epoch(&self) -> u64 { unimplemented!() }
+ /// # }
+ /// #
+ /// # impl Display for Timestamp {
+ /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// use serde::{Serialize, Serializer};
+ ///
+ /// impl Serialize for Timestamp {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// 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)
+ /// }
+ /// }
+ /// }
+ /// ```
+ ///
+ /// The default implementation of this method returns `true`. Data formats
+ /// may override this to `false` to request a compact form for types that
+ /// support one. Note that modifying this method to change a format from
+ /// human-readable to compact or vice versa should be regarded as a breaking
+ /// change, as a value serialized in human-readable mode is not required to
+ /// deserialize from the same data in compact mode.
+ #[inline]
+ fn is_human_readable(&self) -> bool {
+ true
+ }
+}
+
+/// Returned from `Serializer::serialize_seq`.
+///
+/// # Example use
+///
+/// ```edition2018
+/// # use std::marker::PhantomData;
+/// #
+/// # struct Vec<T>(PhantomData<T>);
+/// #
+/// # impl<T> Vec<T> {
+/// # fn len(&self) -> usize {
+/// # unimplemented!()
+/// # }
+/// # }
+/// #
+/// # impl<'a, T> IntoIterator for &'a Vec<T> {
+/// # type Item = &'a T;
+/// # type IntoIter = Box<Iterator<Item = &'a T>>;
+/// # fn into_iter(self) -> Self::IntoIter {
+/// # unimplemented!()
+/// # }
+/// # }
+/// #
+/// use serde::ser::{Serialize, Serializer, SerializeSeq};
+///
+/// impl<T> Serialize for Vec<T>
+/// where
+/// T: Serialize,
+/// {
+/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+/// where
+/// S: Serializer,
+/// {
+/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
+/// for element in self {
+/// seq.serialize_element(element)?;
+/// }
+/// seq.end()
+/// }
+/// }
+/// ```
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `SerializeSeq` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait SerializeSeq {
+ /// Must match the `Ok` type of our `Serializer`.
+ type Ok;
+
+ /// Must match the `Error` type of our `Serializer`.
+ type Error: Error;
+
+ /// Serialize a sequence element.
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize;
+
+ /// Finish serializing a sequence.
+ fn end(self) -> Result<Self::Ok, Self::Error>;
+}
+
+/// Returned from `Serializer::serialize_tuple`.
+///
+/// # Example use
+///
+/// ```edition2018
+/// use serde::ser::{Serialize, Serializer, SerializeTuple};
+///
+/// # mod fool {
+/// # 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,
+/// {
+/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+/// 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()
+/// }
+/// }
+/// ```
+///
+/// ```edition2018
+/// # use std::marker::PhantomData;
+/// #
+/// # struct Array<T>(PhantomData<T>);
+/// #
+/// # impl<T> Array<T> {
+/// # fn len(&self) -> usize {
+/// # unimplemented!()
+/// # }
+/// # }
+/// #
+/// # impl<'a, T> IntoIterator for &'a Array<T> {
+/// # type Item = &'a T;
+/// # type IntoIter = Box<Iterator<Item = &'a T>>;
+/// # fn into_iter(self) -> Self::IntoIter {
+/// # unimplemented!()
+/// # }
+/// # }
+/// #
+/// use serde::ser::{Serialize, Serializer, SerializeTuple};
+///
+/// # mod fool {
+/// # trait Serialize {}
+/// impl<T> Serialize for [T; 16]
+/// # {}
+/// # }
+/// #
+/// # impl<T> Serialize for Array<T>
+/// where
+/// T: Serialize,
+/// {
+/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+/// where
+/// S: Serializer,
+/// {
+/// let mut seq = serializer.serialize_tuple(16)?;
+/// for element in self {
+/// seq.serialize_element(element)?;
+/// }
+/// seq.end()
+/// }
+/// }
+/// ```
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `SerializeTuple` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait SerializeTuple {
+ /// Must match the `Ok` type of our `Serializer`.
+ type Ok;
+
+ /// Must match the `Error` type of our `Serializer`.
+ type Error: Error;
+
+ /// Serialize a tuple element.
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize;
+
+ /// Finish serializing a tuple.
+ fn end(self) -> Result<Self::Ok, Self::Error>;
+}
+
+/// Returned from `Serializer::serialize_tuple_struct`.
+///
+/// # Example use
+///
+/// ```edition2018
+/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
+///
+/// struct Rgb(u8, u8, u8);
+///
+/// impl Serialize for Rgb {
+/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+/// 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()
+/// }
+/// }
+/// ```
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `SerializeTupleStruct` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait SerializeTupleStruct {
+ /// Must match the `Ok` type of our `Serializer`.
+ type Ok;
+
+ /// Must match the `Error` type of our `Serializer`.
+ type Error: Error;
+
+ /// Serialize a tuple struct field.
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize;
+
+ /// Finish serializing a tuple struct.
+ fn end(self) -> Result<Self::Ok, Self::Error>;
+}
+
+/// Returned from `Serializer::serialize_tuple_variant`.
+///
+/// # Example use
+///
+/// ```edition2018
+/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
+///
+/// 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,
+/// {
+/// 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()
+/// }
+/// E::U(ref a, ref b, ref c) => {
+/// let mut tv = serializer.serialize_tuple_variant("E", 1, "U", 3)?;
+/// tv.serialize_field(a)?;
+/// tv.serialize_field(b)?;
+/// tv.serialize_field(c)?;
+/// tv.end()
+/// }
+/// }
+/// }
+/// }
+/// ```
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `SerializeTupleVariant` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait SerializeTupleVariant {
+ /// Must match the `Ok` type of our `Serializer`.
+ type Ok;
+
+ /// Must match the `Error` type of our `Serializer`.
+ type Error: Error;
+
+ /// Serialize a tuple variant field.
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize;
+
+ /// Finish serializing a tuple variant.
+ fn end(self) -> Result<Self::Ok, Self::Error>;
+}
+
+/// Returned from `Serializer::serialize_map`.
+///
+/// # Example use
+///
+/// ```edition2018
+/// # use std::marker::PhantomData;
+/// #
+/// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>);
+/// #
+/// # impl<K, V> HashMap<K, V> {
+/// # fn len(&self) -> usize {
+/// # unimplemented!()
+/// # }
+/// # }
+/// #
+/// # impl<'a, K, V> IntoIterator for &'a HashMap<K, V> {
+/// # type Item = (&'a K, &'a V);
+/// # type IntoIter = Box<Iterator<Item = (&'a K, &'a V)>>;
+/// #
+/// # 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,
+/// {
+/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+/// where
+/// S: Serializer,
+/// {
+/// let mut map = serializer.serialize_map(Some(self.len()))?;
+/// for (k, v) in self {
+/// map.serialize_entry(k, v)?;
+/// }
+/// map.end()
+/// }
+/// }
+/// ```
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `SerializeMap` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait SerializeMap {
+ /// Must match the `Ok` type of our `Serializer`.
+ type Ok;
+
+ /// Must match the `Error` type of our `Serializer`.
+ type Error: Error;
+
+ /// Serialize a map key.
+ ///
+ /// If possible, `Serialize` implementations are encouraged to use
+ /// `serialize_entry` instead as it may be implemented more efficiently in
+ /// some formats compared to a pair of calls to `serialize_key` and
+ /// `serialize_value`.
+ fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize;
+
+ /// Serialize a map value.
+ ///
+ /// # Panics
+ ///
+ /// Calling `serialize_value` before `serialize_key` is incorrect and is
+ /// allowed to panic or produce bogus results.
+ fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize;
+
+ /// Serialize a map entry consisting of a key and a value.
+ ///
+ /// Some [`Serialize`] types are not able to hold a key and value in memory
+ /// at the same time so `SerializeMap` implementations are required to
+ /// support [`serialize_key`] and [`serialize_value`] individually. The
+ /// `serialize_entry` method allows serializers to optimize for the case
+ /// where key and value are both available. [`Serialize`] implementations
+ /// are encouraged to use `serialize_entry` if possible.
+ ///
+ /// The default implementation delegates to [`serialize_key`] and
+ /// [`serialize_value`]. This is appropriate for serializers that do not
+ /// care about performance or are not able to optimize `serialize_entry` any
+ /// better than this.
+ ///
+ /// [`Serialize`]: ../trait.Serialize.html
+ /// [`serialize_key`]: #tymethod.serialize_key
+ /// [`serialize_value`]: #tymethod.serialize_value
+ fn serialize_entry<K: ?Sized, V: ?Sized>(
+ &mut self,
+ key: &K,
+ value: &V,
+ ) -> Result<(), Self::Error>
+ where
+ K: Serialize,
+ V: Serialize,
+ {
+ try!(self.serialize_key(key));
+ self.serialize_value(value)
+ }
+
+ /// Finish serializing a map.
+ fn end(self) -> Result<Self::Ok, Self::Error>;
+}
+
+/// Returned from `Serializer::serialize_struct`.
+///
+/// # Example use
+///
+/// ```edition2018
+/// use serde::ser::{Serialize, SerializeStruct, Serializer};
+///
+/// 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,
+/// {
+/// 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()
+/// }
+/// }
+/// ```
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `SerializeStruct` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait SerializeStruct {
+ /// Must match the `Ok` type of our `Serializer`.
+ type Ok;
+
+ /// Must match the `Error` type of our `Serializer`.
+ type Error: Error;
+
+ /// Serialize a struct field.
+ fn serialize_field<T: ?Sized>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), Self::Error>
+ where
+ T: Serialize;
+
+ /// Indicate that a struct field has been skipped.
+ #[inline]
+ fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
+ let _ = key;
+ Ok(())
+ }
+
+ /// Finish serializing a struct.
+ fn end(self) -> Result<Self::Ok, Self::Error>;
+}
+
+/// Returned from `Serializer::serialize_struct_variant`.
+///
+/// # Example use
+///
+/// ```edition2018
+/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
+///
+/// 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,
+/// {
+/// 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()
+/// }
+/// }
+/// }
+/// }
+/// ```
+///
+/// # Example implementation
+///
+/// The [example data format] presented on the website demonstrates an
+/// implementation of `SerializeStructVariant` for a basic JSON data format.
+///
+/// [example data format]: https://serde.rs/data-format.html
+pub trait SerializeStructVariant {
+ /// Must match the `Ok` type of our `Serializer`.
+ type Ok;
+
+ /// Must match the `Error` type of our `Serializer`.
+ type Error: Error;
+
+ /// Serialize a struct variant field.
+ fn serialize_field<T: ?Sized>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), Self::Error>
+ where
+ T: Serialize;
+
+ /// Indicate that a struct variant field has been skipped.
+ #[inline]
+ fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
+ let _ = key;
+ Ok(())
+ }
+
+ /// Finish serializing a struct variant.
+ fn end(self) -> Result<Self::Ok, Self::Error>;
+}
+
+fn iterator_len_hint<I>(iter: &I) -> Option<usize>
+where
+ I: Iterator,
+{
+ match iter.size_hint() {
+ (lo, Some(hi)) if lo == hi => Some(lo),
+ _ => None,
+ }
+}
diff --git a/third_party/rust/serde/src/std_error.rs b/third_party/rust/serde/src/std_error.rs
new file mode 100644
index 0000000000..1055e0ffbc
--- /dev/null
+++ b/third_party/rust/serde/src/std_error.rs
@@ -0,0 +1,48 @@
+use lib::{Debug, Display};
+
+/// Either a re-export of std::error::Error or a new identical trait, depending
+/// on whether Serde's "std" feature is enabled.
+///
+/// Serde's error traits [`serde::ser::Error`] and [`serde::de::Error`] require
+/// [`std::error::Error`] as a supertrait, but only when Serde is built with
+/// "std" enabled. Data formats that don't care about no\_std support should
+/// generally provide their error types with a `std::error::Error` impl
+/// directly:
+///
+/// ```edition2018
+/// #[derive(Debug)]
+/// struct MySerError {...}
+///
+/// impl serde::ser::Error for MySerError {...}
+///
+/// impl std::fmt::Display for MySerError {...}
+///
+/// // We don't support no_std!
+/// impl std::error::Error for MySerError {}
+/// ```
+///
+/// Data formats that *do* support no\_std may either have a "std" feature of
+/// their own:
+///
+/// ```toml
+/// [features]
+/// std = ["serde/std"]
+/// ```
+///
+/// ```edition2018
+/// #[cfg(feature = "std")]
+/// impl std::error::Error for MySerError {}
+/// ```
+///
+/// ... or else provide the std Error impl unconditionally via Serde's
+/// re-export:
+///
+/// ```edition2018
+/// impl serde::ser::StdError for MySerError {}
+/// ```
+pub trait Error: Debug + Display {
+ /// The underlying cause of this error, if any.
+ fn source(&self) -> Option<&(Error + 'static)> {
+ None
+ }
+}
diff --git a/third_party/rust/serde_bytes/.cargo-checksum.json b/third_party/rust/serde_bytes/.cargo-checksum.json
new file mode 100644
index 0000000000..27ae813b4f
--- /dev/null
+++ b/third_party/rust/serde_bytes/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"e3f6c9804e4d0ed098b931d2823029db07e50733a87896d9061815d05b998deb","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"f544725bdd52ea9c6ad7a4240b64acce9ca51d7776b1d7fd157d286b5f01260e","src/bytebuf.rs":"4a03836f0e6cb04c9ea3db4880e1ab58d99ed9157a15470c54b60c332bbd8312","src/bytes.rs":"2bc824cc618b9db549a53899a4bbddc95698490dc935f4a41ae9a620524a0392","src/de.rs":"4ca87484a7015be6104022dabfaa50bcb296e1d809edbf040122d75515dadab2","src/lib.rs":"a923700a65bcdf312ed5eeba18e95b4b81078e1e3991aabfcaf3eb9d684e461e","src/ser.rs":"be02fcc1fb228caf6ce6f564bee8041579bd23069d75659ac665ce8e82b2c05d","tests/test_derive.rs":"ea246011c4b5008df6c5170640e806be8f553d0a7e7801254dadd156440c95bb","tests/test_partialeq.rs":"3ff7ba1dfa9f5b0213cc53d072364a9a1f00399a758b34c02d90e77da1536d94","tests/test_serde.rs":"10c980110505d47c7b8a876dcb911154339aa52124b6f1de5636001bcf39b56d"},"package":"416bda436f9aab92e02c8e10d49a15ddd339cea90b6e340fe51ed97abb548294"} \ No newline at end of file
diff --git a/third_party/rust/serde_bytes/Cargo.toml b/third_party/rust/serde_bytes/Cargo.toml
new file mode 100644
index 0000000000..2e75f8ae7f
--- /dev/null
+++ b/third_party/rust/serde_bytes/Cargo.toml
@@ -0,0 +1,56 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+rust-version = "1.31"
+name = "serde_bytes"
+version = "0.11.9"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+description = "Optimized handling of `&[u8]` and `Vec<u8>` for Serde"
+documentation = "https://docs.rs/serde_bytes"
+readme = "README.md"
+keywords = [
+ "serde",
+ "serialization",
+ "no_std",
+ "bytes",
+]
+categories = [
+ "encoding",
+ "no-std",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/serde-rs/bytes"
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+doc-scrape-examples = false
+
+[dependencies.serde]
+version = "1.0"
+default-features = false
+
+[dev-dependencies.bincode]
+version = "1.0"
+
+[dev-dependencies.serde_derive]
+version = "1.0"
+
+[dev-dependencies.serde_test]
+version = "1.0"
+
+[features]
+alloc = ["serde/alloc"]
+default = ["std"]
+std = ["serde/std"]
diff --git a/third_party/rust/serde_bytes/LICENSE-APACHE b/third_party/rust/serde_bytes/LICENSE-APACHE
new file mode 100644
index 0000000000..1b5ec8b78e
--- /dev/null
+++ b/third_party/rust/serde_bytes/LICENSE-APACHE
@@ -0,0 +1,176 @@
+ 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
diff --git a/third_party/rust/serde_bytes/LICENSE-MIT b/third_party/rust/serde_bytes/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/third_party/rust/serde_bytes/LICENSE-MIT
@@ -0,0 +1,23 @@
+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.
diff --git a/third_party/rust/serde_bytes/README.md b/third_party/rust/serde_bytes/README.md
new file mode 100644
index 0000000000..e0a0e9f040
--- /dev/null
+++ b/third_party/rust/serde_bytes/README.md
@@ -0,0 +1,54 @@
+# serde\_bytes [![Build Status](https://img.shields.io/github/actions/workflow/status/serde-rs/bytes/ci.yml?branch=master)](https://github.com/serde-rs/bytes/actions?query=branch%3Amaster) [![Latest Version](https://img.shields.io/crates/v/serde_bytes.svg)](https://crates.io/crates/serde_bytes)
+
+Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`.
+
+```toml
+[dependencies]
+serde_bytes = "0.11"
+```
+
+## Explanation
+
+Without specialization, Rust forces Serde to treat `&[u8]` just like any
+other slice and `Vec<u8>` just like any other vector. In reality this
+particular slice and vector can often be serialized and deserialized in a
+more efficient, compact representation in many formats.
+
+When working with such a format, you can opt into specialized handling of
+`&[u8]` by wrapping it in `serde_bytes::Bytes` and `Vec<u8>` by wrapping it
+in `serde_bytes::ByteBuf`.
+
+Additionally this crate supports the Serde `with` attribute to enable efficient
+handling of `&[u8]` and `Vec<u8>` in structs without needing a wrapper type.
+
+## Example
+
+```rust
+use serde::{Deserialize, Serialize};
+
+#[derive(Deserialize, Serialize)]
+struct Efficient<'a> {
+ #[serde(with = "serde_bytes")]
+ bytes: &'a [u8],
+
+ #[serde(with = "serde_bytes")]
+ byte_buf: Vec<u8>,
+}
+```
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
+be dual licensed as above, without any additional terms or conditions.
+</sub>
diff --git a/third_party/rust/serde_bytes/src/bytebuf.rs b/third_party/rust/serde_bytes/src/bytebuf.rs
new file mode 100644
index 0000000000..0c2daa6e25
--- /dev/null
+++ b/third_party/rust/serde_bytes/src/bytebuf.rs
@@ -0,0 +1,253 @@
+use core::borrow::{Borrow, BorrowMut};
+use core::cmp::{self, Ordering};
+use core::fmt::{self, Debug};
+use core::hash::{Hash, Hasher};
+use core::ops::{Deref, DerefMut};
+
+#[cfg(feature = "alloc")]
+use alloc::boxed::Box;
+#[cfg(feature = "alloc")]
+use alloc::string::String;
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+
+use serde::de::{Deserialize, Deserializer, Error, SeqAccess, Visitor};
+use serde::ser::{Serialize, Serializer};
+
+use crate::Bytes;
+
+/// Wrapper around `Vec<u8>` to serialize and deserialize efficiently.
+///
+/// ```
+/// use std::collections::HashMap;
+/// use std::io;
+///
+/// use serde_bytes::ByteBuf;
+///
+/// fn deserialize_bytebufs() -> bincode::Result<()> {
+/// let example_data = [
+/// 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 116,
+/// 119, 111, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 111, 110, 101];
+///
+/// let map: HashMap<u32, ByteBuf> = bincode::deserialize(&example_data[..])?;
+///
+/// println!("{:?}", map);
+///
+/// Ok(())
+/// }
+/// #
+/// # fn main() {
+/// # deserialize_bytebufs().unwrap();
+/// # }
+/// ```
+#[derive(Clone, Default, Eq, Ord)]
+pub struct ByteBuf {
+ bytes: Vec<u8>,
+}
+
+impl ByteBuf {
+ /// Construct a new, empty `ByteBuf`.
+ pub fn new() -> Self {
+ ByteBuf::from(Vec::new())
+ }
+
+ /// Construct a new, empty `ByteBuf` with the specified capacity.
+ pub fn with_capacity(cap: usize) -> Self {
+ ByteBuf::from(Vec::with_capacity(cap))
+ }
+
+ /// Wrap existing bytes in a `ByteBuf`.
+ pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self {
+ ByteBuf {
+ bytes: bytes.into(),
+ }
+ }
+
+ /// Unwrap the vector of byte underlying this `ByteBuf`.
+ pub fn into_vec(self) -> Vec<u8> {
+ self.bytes
+ }
+
+ #[allow(missing_docs)]
+ pub fn into_boxed_bytes(self) -> Box<Bytes> {
+ self.bytes.into_boxed_slice().into()
+ }
+
+ // This would hit "cannot move out of borrowed content" if invoked through
+ // the Deref impl; make it just work.
+ #[doc(hidden)]
+ pub fn into_boxed_slice(self) -> Box<[u8]> {
+ self.bytes.into_boxed_slice()
+ }
+
+ #[doc(hidden)]
+ #[allow(clippy::should_implement_trait)]
+ pub fn into_iter(self) -> <Vec<u8> as IntoIterator>::IntoIter {
+ self.bytes.into_iter()
+ }
+}
+
+impl Debug for ByteBuf {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.bytes, f)
+ }
+}
+
+impl AsRef<[u8]> for ByteBuf {
+ fn as_ref(&self) -> &[u8] {
+ &self.bytes
+ }
+}
+
+impl AsMut<[u8]> for ByteBuf {
+ fn as_mut(&mut self) -> &mut [u8] {
+ &mut self.bytes
+ }
+}
+
+impl Deref for ByteBuf {
+ type Target = Vec<u8>;
+
+ fn deref(&self) -> &Self::Target {
+ &self.bytes
+ }
+}
+
+impl DerefMut for ByteBuf {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.bytes
+ }
+}
+
+impl Borrow<Bytes> for ByteBuf {
+ fn borrow(&self) -> &Bytes {
+ Bytes::new(&self.bytes)
+ }
+}
+
+impl BorrowMut<Bytes> for ByteBuf {
+ fn borrow_mut(&mut self) -> &mut Bytes {
+ unsafe { &mut *(&mut self.bytes as &mut [u8] as *mut [u8] as *mut Bytes) }
+ }
+}
+
+impl<Rhs> PartialEq<Rhs> for ByteBuf
+where
+ Rhs: ?Sized + AsRef<[u8]>,
+{
+ fn eq(&self, other: &Rhs) -> bool {
+ self.as_ref().eq(other.as_ref())
+ }
+}
+
+impl<Rhs> PartialOrd<Rhs> for ByteBuf
+where
+ Rhs: ?Sized + AsRef<[u8]>,
+{
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
+ self.as_ref().partial_cmp(other.as_ref())
+ }
+}
+
+impl Hash for ByteBuf {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.bytes.hash(state);
+ }
+}
+
+impl IntoIterator for ByteBuf {
+ type Item = u8;
+ type IntoIter = <Vec<u8> as IntoIterator>::IntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.bytes.into_iter()
+ }
+}
+
+impl<'a> IntoIterator for &'a ByteBuf {
+ type Item = &'a u8;
+ type IntoIter = <&'a [u8] as IntoIterator>::IntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.bytes.iter()
+ }
+}
+
+impl<'a> IntoIterator for &'a mut ByteBuf {
+ type Item = &'a mut u8;
+ type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.bytes.iter_mut()
+ }
+}
+
+impl Serialize for ByteBuf {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(&self.bytes)
+ }
+}
+
+struct ByteBufVisitor;
+
+impl<'de> Visitor<'de> for ByteBufVisitor {
+ type Value = ByteBuf;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("byte array")
+ }
+
+ fn visit_seq<V>(self, mut visitor: V) -> Result<ByteBuf, V::Error>
+ where
+ V: SeqAccess<'de>,
+ {
+ let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
+ let mut bytes = Vec::with_capacity(len);
+
+ while let Some(b) = visitor.next_element()? {
+ bytes.push(b);
+ }
+
+ Ok(ByteBuf::from(bytes))
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<ByteBuf, E>
+ where
+ E: Error,
+ {
+ Ok(ByteBuf::from(v))
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<ByteBuf, E>
+ where
+ E: Error,
+ {
+ Ok(ByteBuf::from(v))
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<ByteBuf, E>
+ where
+ E: Error,
+ {
+ Ok(ByteBuf::from(v))
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<ByteBuf, E>
+ where
+ E: Error,
+ {
+ Ok(ByteBuf::from(v))
+ }
+}
+
+impl<'de> Deserialize<'de> for ByteBuf {
+ fn deserialize<D>(deserializer: D) -> Result<ByteBuf, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_byte_buf(ByteBufVisitor)
+ }
+}
diff --git a/third_party/rust/serde_bytes/src/bytes.rs b/third_party/rust/serde_bytes/src/bytes.rs
new file mode 100644
index 0000000000..ad0902b434
--- /dev/null
+++ b/third_party/rust/serde_bytes/src/bytes.rs
@@ -0,0 +1,172 @@
+use core::cmp::Ordering;
+use core::fmt::{self, Debug};
+use core::hash::{Hash, Hasher};
+use core::ops::{Deref, DerefMut};
+
+#[cfg(feature = "alloc")]
+use alloc::borrow::ToOwned;
+
+#[cfg(feature = "alloc")]
+use alloc::boxed::Box;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+use crate::ByteBuf;
+
+use serde::de::{Deserialize, Deserializer};
+use serde::ser::{Serialize, Serializer};
+
+/// Wrapper around `[u8]` to serialize and deserialize efficiently.
+///
+/// ```
+/// use std::collections::HashMap;
+/// use std::io;
+///
+/// use serde_bytes::Bytes;
+///
+/// fn print_encoded_cache() -> bincode::Result<()> {
+/// let mut cache = HashMap::new();
+/// cache.insert(3, Bytes::new(b"three"));
+/// cache.insert(2, Bytes::new(b"two"));
+/// cache.insert(1, Bytes::new(b"one"));
+///
+/// bincode::serialize_into(&mut io::stdout(), &cache)
+/// }
+/// #
+/// # fn main() {
+/// # print_encoded_cache().unwrap();
+/// # }
+/// ```
+#[derive(Eq, Ord)]
+#[cfg_attr(not(doc), repr(transparent))]
+pub struct Bytes {
+ bytes: [u8],
+}
+
+impl Bytes {
+ /// Wrap an existing `&[u8]`.
+ pub fn new(bytes: &[u8]) -> &Self {
+ unsafe { &*(bytes as *const [u8] as *const Bytes) }
+ }
+}
+
+impl Debug for Bytes {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.bytes, f)
+ }
+}
+
+impl AsRef<[u8]> for Bytes {
+ fn as_ref(&self) -> &[u8] {
+ &self.bytes
+ }
+}
+
+impl AsMut<[u8]> for Bytes {
+ fn as_mut(&mut self) -> &mut [u8] {
+ &mut self.bytes
+ }
+}
+
+impl Deref for Bytes {
+ type Target = [u8];
+
+ fn deref(&self) -> &Self::Target {
+ &self.bytes
+ }
+}
+
+impl DerefMut for Bytes {
+ fn deref_mut(&mut self) -> &mut Self::Target {
+ &mut self.bytes
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl ToOwned for Bytes {
+ type Owned = ByteBuf;
+
+ fn to_owned(&self) -> Self::Owned {
+ ByteBuf::from(&self.bytes)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl From<Box<[u8]>> for Box<Bytes> {
+ fn from(bytes: Box<[u8]>) -> Self {
+ unsafe { Box::from_raw(Box::into_raw(bytes) as *mut Bytes) }
+ }
+}
+
+impl<'a> Default for &'a Bytes {
+ fn default() -> Self {
+ Bytes::new(&[])
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl Default for Box<Bytes> {
+ fn default() -> Self {
+ ByteBuf::new().into_boxed_bytes()
+ }
+}
+
+impl<Rhs> PartialEq<Rhs> for Bytes
+where
+ Rhs: ?Sized + AsRef<[u8]>,
+{
+ fn eq(&self, other: &Rhs) -> bool {
+ self.as_ref().eq(other.as_ref())
+ }
+}
+
+impl<Rhs> PartialOrd<Rhs> for Bytes
+where
+ Rhs: ?Sized + AsRef<[u8]>,
+{
+ fn partial_cmp(&self, other: &Rhs) -> Option<Ordering> {
+ self.as_ref().partial_cmp(other.as_ref())
+ }
+}
+
+impl Hash for Bytes {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ self.bytes.hash(state);
+ }
+}
+
+impl<'a> IntoIterator for &'a Bytes {
+ type Item = &'a u8;
+ type IntoIter = <&'a [u8] as IntoIterator>::IntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.bytes.iter()
+ }
+}
+
+impl<'a> IntoIterator for &'a mut Bytes {
+ type Item = &'a mut u8;
+ type IntoIter = <&'a mut [u8] as IntoIterator>::IntoIter;
+
+ fn into_iter(self) -> Self::IntoIter {
+ self.bytes.iter_mut()
+ }
+}
+
+impl Serialize for Bytes {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(&self.bytes)
+ }
+}
+
+impl<'a, 'de: 'a> Deserialize<'de> for &'a Bytes {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // serde::Deserialize for &[u8] is already optimized, so simply forward to that.
+ Deserialize::deserialize(deserializer).map(Bytes::new)
+ }
+}
diff --git a/third_party/rust/serde_bytes/src/de.rs b/third_party/rust/serde_bytes/src/de.rs
new file mode 100644
index 0000000000..e4a4732eea
--- /dev/null
+++ b/third_party/rust/serde_bytes/src/de.rs
@@ -0,0 +1,229 @@
+use crate::Bytes;
+use core::fmt;
+use core::marker::PhantomData;
+use serde::de::{Error, Visitor};
+use serde::Deserializer;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+use crate::ByteBuf;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+use core::cmp;
+
+#[cfg(feature = "alloc")]
+use alloc::borrow::Cow;
+#[cfg(all(feature = "std", not(feature = "alloc")))]
+use std::borrow::Cow;
+
+#[cfg(feature = "alloc")]
+use alloc::boxed::Box;
+#[cfg(feature = "alloc")]
+use alloc::string::String;
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+use serde::de::SeqAccess;
+
+/// Types that can be deserialized via `#[serde(with = "serde_bytes")]`.
+pub trait Deserialize<'de>: Sized {
+ #[allow(missing_docs)]
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>;
+}
+
+impl<'de: 'a, 'a> Deserialize<'de> for &'a [u8] {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // serde::Deserialize for &[u8] is already optimized, so simply forward to that.
+ serde::Deserialize::deserialize(deserializer)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de> Deserialize<'de> for Vec<u8> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer).map(ByteBuf::into_vec)
+ }
+}
+
+impl<'de: 'a, 'a> Deserialize<'de> for &'a Bytes {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // serde::Deserialize for &[u8] is already optimized, so simply forward to that.
+ serde::Deserialize::deserialize(deserializer).map(Bytes::new)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de> Deserialize<'de> for ByteBuf {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // Via the serde::Deserialize impl for ByteBuf.
+ serde::Deserialize::deserialize(deserializer)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, [u8]> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct CowVisitor;
+
+ impl<'de> Visitor<'de> for CowVisitor {
+ type Value = Cow<'de, [u8]>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a byte array")
+ }
+
+ fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Borrowed(v))
+ }
+
+ fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Borrowed(v.as_bytes()))
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.to_vec()))
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.as_bytes().to_vec()))
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v))
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.into_bytes()))
+ }
+
+ fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: SeqAccess<'de>,
+ {
+ let len = cmp::min(visitor.size_hint().unwrap_or(0), 4096);
+ let mut bytes = Vec::with_capacity(len);
+
+ while let Some(b) = visitor.next_element()? {
+ bytes.push(b);
+ }
+
+ Ok(Cow::Owned(bytes))
+ }
+ }
+
+ deserializer.deserialize_bytes(CowVisitor)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de: 'a, 'a> Deserialize<'de> for Cow<'a, Bytes> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let cow: Cow<[u8]> = Deserialize::deserialize(deserializer)?;
+ match cow {
+ Cow::Borrowed(bytes) => Ok(Cow::Borrowed(Bytes::new(bytes))),
+ Cow::Owned(bytes) => Ok(Cow::Owned(ByteBuf::from(bytes))),
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de> Deserialize<'de> for Box<[u8]> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer).map(Vec::into_boxed_slice)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'de> Deserialize<'de> for Box<Bytes> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let bytes: Box<[u8]> = Deserialize::deserialize(deserializer)?;
+ Ok(bytes.into())
+ }
+}
+
+impl<'de, T> Deserialize<'de> for Option<T>
+where
+ T: Deserialize<'de>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct BytesVisitor<T> {
+ out: PhantomData<T>,
+ }
+
+ impl<'de, T> Visitor<'de> for BytesVisitor<T>
+ where
+ T: Deserialize<'de>,
+ {
+ type Value = Option<T>;
+
+ fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("optional byte array")
+ }
+
+ fn visit_unit<E: Error>(self) -> Result<Self::Value, E> {
+ Ok(None)
+ }
+
+ fn visit_none<E: Error>(self) -> Result<Self::Value, E> {
+ Ok(None)
+ }
+
+ fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ T::deserialize(deserializer).map(Some)
+ }
+ }
+
+ let visitor = BytesVisitor { out: PhantomData };
+ deserializer.deserialize_option(visitor)
+ }
+}
diff --git a/third_party/rust/serde_bytes/src/lib.rs b/third_party/rust/serde_bytes/src/lib.rs
new file mode 100644
index 0000000000..871d6cbcb9
--- /dev/null
+++ b/third_party/rust/serde_bytes/src/lib.rs
@@ -0,0 +1,113 @@
+//! Wrapper types to enable optimized handling of `&[u8]` and `Vec<u8>`.
+//!
+//! Without specialization, Rust forces Serde to treat `&[u8]` just like any
+//! other slice and `Vec<u8>` just like any other vector. In reality this
+//! particular slice and vector can often be serialized and deserialized in a
+//! more efficient, compact representation in many formats.
+//!
+//! When working with such a format, you can opt into specialized handling of
+//! `&[u8]` by wrapping it in `serde_bytes::Bytes` and `Vec<u8>` by wrapping it
+//! in `serde_bytes::ByteBuf`.
+//!
+//! Additionally this crate supports the Serde `with` attribute to enable
+//! efficient handling of `&[u8]` and `Vec<u8>` in structs without needing a
+//! wrapper type.
+//!
+//! ```
+//! # use serde_derive::{Deserialize, Serialize};
+//! use serde::{Deserialize, Serialize};
+//!
+//! #[derive(Deserialize, Serialize)]
+//! struct Efficient<'a> {
+//! #[serde(with = "serde_bytes")]
+//! bytes: &'a [u8],
+//!
+//! #[serde(with = "serde_bytes")]
+//! byte_buf: Vec<u8>,
+//! }
+//! ```
+
+#![doc(html_root_url = "https://docs.rs/serde_bytes/0.11.9")]
+#![cfg_attr(not(feature = "std"), no_std)]
+#![deny(missing_docs)]
+#![allow(
+ clippy::missing_errors_doc,
+ clippy::must_use_candidate,
+ clippy::needless_doctest_main
+)]
+
+mod bytes;
+mod de;
+mod ser;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+mod bytebuf;
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+use serde::Deserializer;
+
+use serde::Serializer;
+
+pub use crate::bytes::Bytes;
+pub use crate::de::Deserialize;
+pub use crate::ser::Serialize;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub use crate::bytebuf::ByteBuf;
+
+/// Serde `serialize_with` function to serialize bytes efficiently.
+///
+/// This function can be used with either of the following Serde attributes:
+///
+/// - `#[serde(with = "serde_bytes")]`
+/// - `#[serde(serialize_with = "serde_bytes::serialize")]`
+///
+/// ```
+/// # use serde_derive::Serialize;
+/// use serde::Serialize;
+///
+/// #[derive(Serialize)]
+/// struct Efficient<'a> {
+/// #[serde(with = "serde_bytes")]
+/// bytes: &'a [u8],
+///
+/// #[serde(with = "serde_bytes")]
+/// byte_buf: Vec<u8>,
+/// }
+/// ```
+pub fn serialize<T, S>(bytes: &T, serializer: S) -> Result<S::Ok, S::Error>
+where
+ T: ?Sized + Serialize,
+ S: Serializer,
+{
+ Serialize::serialize(bytes, serializer)
+}
+
+/// Serde `deserialize_with` function to deserialize bytes efficiently.
+///
+/// This function can be used with either of the following Serde attributes:
+///
+/// - `#[serde(with = "serde_bytes")]`
+/// - `#[serde(deserialize_with = "serde_bytes::deserialize")]`
+///
+/// ```
+/// # use serde_derive::Deserialize;
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize)]
+/// struct Packet {
+/// #[serde(with = "serde_bytes")]
+/// payload: Vec<u8>,
+/// }
+/// ```
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub fn deserialize<'de, T, D>(deserializer: D) -> Result<T, D::Error>
+where
+ T: Deserialize<'de>,
+ D: Deserializer<'de>,
+{
+ Deserialize::deserialize(deserializer)
+}
diff --git a/third_party/rust/serde_bytes/src/ser.rs b/third_party/rust/serde_bytes/src/ser.rs
new file mode 100644
index 0000000000..1cbed9f757
--- /dev/null
+++ b/third_party/rust/serde_bytes/src/ser.rs
@@ -0,0 +1,136 @@
+use crate::Bytes;
+use serde::Serializer;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+use crate::ByteBuf;
+
+#[cfg(feature = "alloc")]
+use alloc::borrow::Cow;
+#[cfg(all(feature = "std", not(feature = "alloc")))]
+use std::borrow::Cow;
+
+#[cfg(feature = "alloc")]
+use alloc::boxed::Box;
+
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+
+/// Types that can be serialized via `#[serde(with = "serde_bytes")]`.
+pub trait Serialize {
+ #[allow(missing_docs)]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer;
+}
+
+impl Serialize for [u8] {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(self)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl Serialize for Vec<u8> {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(self)
+ }
+}
+
+impl Serialize for Bytes {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(self)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl Serialize for ByteBuf {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(self)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a> Serialize for Cow<'a, [u8]> {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(self)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a> Serialize for Cow<'a, Bytes> {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(self)
+ }
+}
+
+impl<'a, T> Serialize for &'a T
+where
+ T: ?Sized + Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ (**self).serialize(serializer)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<T> Serialize for Box<T>
+where
+ T: ?Sized + Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ (**self).serialize(serializer)
+ }
+}
+
+impl<T> Serialize for Option<T>
+where
+ T: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ struct AsBytes<T>(T);
+
+ impl<T> serde::Serialize for AsBytes<T>
+ where
+ T: Serialize,
+ {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.0.serialize(serializer)
+ }
+ }
+
+ match self {
+ Some(b) => serializer.serialize_some(&AsBytes(b)),
+ None => serializer.serialize_none(),
+ }
+ }
+}
diff --git a/third_party/rust/serde_bytes/tests/test_derive.rs b/third_party/rust/serde_bytes/tests/test_derive.rs
new file mode 100644
index 0000000000..c7e97f1ec4
--- /dev/null
+++ b/third_party/rust/serde_bytes/tests/test_derive.rs
@@ -0,0 +1,101 @@
+#![allow(clippy::derive_partial_eq_without_eq, clippy::ref_option_ref)]
+
+use serde_bytes::{ByteBuf, Bytes};
+use serde_derive::{Deserialize, Serialize};
+use serde_test::{assert_tokens, Token};
+use std::borrow::Cow;
+
+#[derive(Serialize, Deserialize, PartialEq, Debug)]
+struct Test<'a> {
+ #[serde(with = "serde_bytes")]
+ slice: &'a [u8],
+
+ #[serde(with = "serde_bytes")]
+ vec: Vec<u8>,
+
+ #[serde(with = "serde_bytes")]
+ bytes: &'a Bytes,
+
+ #[serde(with = "serde_bytes")]
+ byte_buf: ByteBuf,
+
+ #[serde(with = "serde_bytes")]
+ cow_slice: Cow<'a, [u8]>,
+
+ #[serde(with = "serde_bytes")]
+ cow_bytes: Cow<'a, Bytes>,
+
+ #[serde(with = "serde_bytes")]
+ boxed_slice: Box<[u8]>,
+
+ #[serde(with = "serde_bytes")]
+ boxed_bytes: Box<Bytes>,
+
+ #[serde(with = "serde_bytes")]
+ opt_slice: Option<&'a [u8]>,
+
+ #[serde(with = "serde_bytes")]
+ opt_vec: Option<Vec<u8>>,
+
+ #[serde(with = "serde_bytes")]
+ opt_cow_slice: Option<Cow<'a, [u8]>>,
+}
+
+#[derive(Serialize)]
+struct Dst {
+ #[serde(with = "serde_bytes")]
+ bytes: [u8],
+}
+
+#[test]
+fn test() {
+ let test = Test {
+ slice: b"...",
+ vec: b"...".to_vec(),
+ bytes: Bytes::new(b"..."),
+ byte_buf: ByteBuf::from(b"...".as_ref()),
+ cow_slice: Cow::Borrowed(b"..."),
+ cow_bytes: Cow::Borrowed(Bytes::new(b"...")),
+ boxed_slice: b"...".to_vec().into_boxed_slice(),
+ boxed_bytes: ByteBuf::from(b"...".as_ref()).into_boxed_bytes(),
+ opt_slice: Some(b"..."),
+ opt_vec: Some(b"...".to_vec()),
+ opt_cow_slice: Some(Cow::Borrowed(b"...")),
+ };
+
+ assert_tokens(
+ &test,
+ &[
+ Token::Struct {
+ name: "Test",
+ len: 11,
+ },
+ Token::Str("slice"),
+ Token::BorrowedBytes(b"..."),
+ Token::Str("vec"),
+ Token::Bytes(b"..."),
+ Token::Str("bytes"),
+ Token::BorrowedBytes(b"..."),
+ Token::Str("byte_buf"),
+ Token::Bytes(b"..."),
+ Token::Str("cow_slice"),
+ Token::BorrowedBytes(b"..."),
+ Token::Str("cow_bytes"),
+ Token::BorrowedBytes(b"..."),
+ Token::Str("boxed_slice"),
+ Token::Bytes(b"..."),
+ Token::Str("boxed_bytes"),
+ Token::Bytes(b"..."),
+ Token::Str("opt_slice"),
+ Token::Some,
+ Token::BorrowedBytes(b"..."),
+ Token::Str("opt_vec"),
+ Token::Some,
+ Token::Bytes(b"..."),
+ Token::Str("opt_cow_slice"),
+ Token::Some,
+ Token::BorrowedBytes(b"..."),
+ Token::StructEnd,
+ ],
+ );
+}
diff --git a/third_party/rust/serde_bytes/tests/test_partialeq.rs b/third_party/rust/serde_bytes/tests/test_partialeq.rs
new file mode 100644
index 0000000000..a57d194882
--- /dev/null
+++ b/third_party/rust/serde_bytes/tests/test_partialeq.rs
@@ -0,0 +1,15 @@
+#![allow(clippy::needless_pass_by_value)]
+
+use serde_bytes::{ByteBuf, Bytes};
+
+fn _bytes_eq_slice(bytes: &Bytes, slice: &[u8]) -> bool {
+ bytes == slice
+}
+
+fn _bytebuf_eq_vec(bytebuf: ByteBuf, vec: Vec<u8>) -> bool {
+ bytebuf == vec
+}
+
+fn _bytes_eq_bytestring(bytes: &Bytes) -> bool {
+ bytes == b"..."
+}
diff --git a/third_party/rust/serde_bytes/tests/test_serde.rs b/third_party/rust/serde_bytes/tests/test_serde.rs
new file mode 100644
index 0000000000..d48e3fd434
--- /dev/null
+++ b/third_party/rust/serde_bytes/tests/test_serde.rs
@@ -0,0 +1,59 @@
+use serde_bytes::{ByteBuf, Bytes};
+use serde_test::{assert_de_tokens, assert_ser_tokens, assert_tokens, Token};
+
+#[test]
+fn test_bytes() {
+ let empty = Bytes::new(&[]);
+ assert_tokens(&empty, &[Token::BorrowedBytes(b"")]);
+ assert_ser_tokens(&empty, &[Token::Bytes(b"")]);
+ assert_ser_tokens(&empty, &[Token::ByteBuf(b"")]);
+ assert_de_tokens(&empty, &[Token::BorrowedStr("")]);
+
+ let buf = vec![65, 66, 67];
+ let bytes = Bytes::new(&buf);
+ assert_tokens(&bytes, &[Token::BorrowedBytes(b"ABC")]);
+ assert_ser_tokens(&bytes, &[Token::Bytes(b"ABC")]);
+ assert_ser_tokens(&bytes, &[Token::ByteBuf(b"ABC")]);
+ assert_de_tokens(&bytes, &[Token::BorrowedStr("ABC")]);
+}
+
+#[test]
+fn test_byte_buf() {
+ let empty = ByteBuf::new();
+ assert_tokens(&empty, &[Token::BorrowedBytes(b"")]);
+ assert_tokens(&empty, &[Token::Bytes(b"")]);
+ assert_tokens(&empty, &[Token::ByteBuf(b"")]);
+ assert_de_tokens(&empty, &[Token::BorrowedStr("")]);
+ assert_de_tokens(&empty, &[Token::Str("")]);
+ assert_de_tokens(&empty, &[Token::String("")]);
+ assert_de_tokens(&empty, &[Token::Seq { len: None }, Token::SeqEnd]);
+ assert_de_tokens(&empty, &[Token::Seq { len: Some(0) }, Token::SeqEnd]);
+
+ let buf = ByteBuf::from(vec![65, 66, 67]);
+ assert_tokens(&buf, &[Token::BorrowedBytes(b"ABC")]);
+ assert_tokens(&buf, &[Token::Bytes(b"ABC")]);
+ assert_tokens(&buf, &[Token::ByteBuf(b"ABC")]);
+ assert_de_tokens(&buf, &[Token::BorrowedStr("ABC")]);
+ assert_de_tokens(&buf, &[Token::Str("ABC")]);
+ assert_de_tokens(&buf, &[Token::String("ABC")]);
+ assert_de_tokens(
+ &buf,
+ &[
+ Token::Seq { len: None },
+ Token::U8(65),
+ Token::U8(66),
+ Token::U8(67),
+ Token::SeqEnd,
+ ],
+ );
+ assert_de_tokens(
+ &buf,
+ &[
+ Token::Seq { len: Some(3) },
+ Token::U8(65),
+ Token::U8(66),
+ Token::U8(67),
+ Token::SeqEnd,
+ ],
+ );
+}
diff --git a/third_party/rust/serde_cbor/.cargo-checksum.json b/third_party/rust/serde_cbor/.cargo-checksum.json
new file mode 100644
index 0000000000..03e08b7b06
--- /dev/null
+++ b/third_party/rust/serde_cbor/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CONTRIBUTING.md":"bcbbc1fd8aefd2af15d432b551ddc32b0b832c1ad669eeedfaffb2092448c080","Cargo.lock":"b900f78562d5ae2ffffc0e8f739328df268f0fb80696018eb5df8e5e633b733e","Cargo.toml":"522e55ca99d851f9a3e7361f090451fc87c6097320c77bd574a80df27c183078","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"e03e58ea9205f51989b7a50f450051b24e6516cc1f0b920222dcda992072be99","README.md":"abb494d9608a40bac62da0bbd4680c0f03d960922d92261fb6492a1ee448d5c6","examples/readme.rs":"2e356830c62e84605d6b7efa07a0266ad96ed960fde09d4ae241c642ff662ab2","examples/tags.rs":"a1e1e4de8a5b09c54f96a56b8d7dc749fff9c73facb1dcad05540bc83f34dbd2","examples/tux.cbor":"3251bceb0a182543de2129cd920b2af597c481513a0624887a7daeb468c530f8","src/de.rs":"433d2e10bf1be80f881dfd5355a0df1a1c6b1e09a2d36c4d6f39894b13b42e0b","src/error.rs":"9247283d47617626c90a0d32bba40b54a18c6bb0ecce37057d7423ff9158d223","src/lib.rs":"efe97da47a332789d29eb4480a65ae00b4ccd9e6ba22d2b2c945cbeb97edf2b5","src/read.rs":"001754714cf10e9691e3284bf8170348346858be8e5d72ee845853b928588c7c","src/ser.rs":"0b7cb6162e104bfea55f6bffa591d19876236a798134fec8dbabb1c2d4a22363","src/tags.rs":"8d83efd96daca49ac51f24d41b986f4247fcd2a011855ffc99e9388834bd31a3","src/value/de.rs":"986784dcf015464b01f669949f823ba0e29b7414f6d56cad3311cee036d1a954","src/value/mod.rs":"0afa696a6ed01f97380f84e4e219090393bc8cc52cd9c11f4db3eb5b1fb85e7f","src/value/ser.rs":"f5d505125ae496c99d611c24cb0905199b3b66b949ae18bb48863317b686f301","src/write.rs":"6bcc413fe531799cd979d954615e73dd87e185082858a63c5aef73f0fbe08806","tests/bennofs.rs":"2211b234f442e909659f0610fcb20e7cf746bc6c648fe258e5300ebcd6a4251f","tests/canonical.rs":"37fcbe3a1956c72e4aef808acb2e194f09ae8aaa752c6a94cf6d06731c19948d","tests/crash.cbor":"8aeb60947fc5d43e80f3c884fc6cb37c9021cc691492d055a14e55c69b366d1f","tests/de.rs":"545cf5f5bd1ab0b3b4c05c4985baf40ad419dc1568f28549d17eacf5efc7beb7","tests/enum.rs":"699886e517546396979c9843b6d1c513b4370af81e2b0d3bcf0727435c5c0a8a","tests/kietaub.cbor":"98146fa75d5970eea896baa19b5aeda31695d6ceeed4b23aa67fc13142123a9a","tests/ser.rs":"7eadf27fb58b8bd498f0be8e1670d76de36e3f21b565daeb8ec9cf30140c068e","tests/std_types.rs":"549e357ad5062eb8ae298df3bbbd0e8ee87ee0434f8c67dc53642ff2b2171e40","tests/tags.rs":"e847b9ab49f47a81a09e34d4af3bd25bb546e408915f033dc06b03b275f68065","tests/value.rs":"540469dccb6c6f3542b75934707203dff93132a7e160de798a21f16caf16075e"},"package":"2bef2ebfde456fb76bbcf9f59315333decc4fda0b2b44b420243c11e0f5ec1f5"} \ No newline at end of file
diff --git a/third_party/rust/serde_cbor/CONTRIBUTING.md b/third_party/rust/serde_cbor/CONTRIBUTING.md
new file mode 100644
index 0000000000..1489ade658
--- /dev/null
+++ b/third_party/rust/serde_cbor/CONTRIBUTING.md
@@ -0,0 +1,29 @@
+# Contributing to Serde CBOR
+Thanks for your interest!
+There are many ways to help:
+
+* write an issue about a problem you encountered
+* submit a pull request
+* add documentation and examples
+
+## Pull Requests
+
+Code should be easy to understand and documented.
+For new features and fixed bugs please add a test to one of the files in `test/`.
+The tests are run on Travis CI to catch regressions early.
+Format your code with `cargo fmt` before committing.
+Currently Serde CBOR does not contain `unsafe` code and I would like to keep it this way.
+
+## Making a Release
+
+* [ ] Make sure the crate compiles and all tests pass.
+* [ ] (Optional) Test that the fuzzer works and fuzz the crate for some time.
+* [ ] Write a list with all changes made since the last release
+* [ ] Increment the version number in `Cargo.toml` and the `README.md`. Bugfixes increase the patch version while new features or an increased minimum Rust version require a new minor version.
+* [ ] Check that the file `examples/readme.rs` and the example from the `README.md` match.
+* [ ] Commit the changes.
+* [ ] Add a git tag with the new version number:
+ `git tag "v42.0.2"`
+* [ ] Push the changes: `git push --tags`
+* [ ] Run `cargo publish`
+* [ ] Add a new release to GitHub with a list of changes. \ No newline at end of file
diff --git a/third_party/rust/serde_cbor/Cargo.lock b/third_party/rust/serde_cbor/Cargo.lock
new file mode 100644
index 0000000000..b91ed7cd52
--- /dev/null
+++ b/third_party/rust/serde_cbor/Cargo.lock
@@ -0,0 +1,68 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+[[package]]
+name = "half"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9ff54597ea139063f4225f1ec47011b03c9de4a486957ff3fc506881dac951d0"
+
+[[package]]
+name = "proc-macro2"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0319972dcae462681daf4da1adeeaa066e3ebd29c69be96c6abb1259d2ee2bcc"
+dependencies = [
+ "unicode-xid",
+]
+
+[[package]]
+name = "quote"
+version = "1.0.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
+dependencies = [
+ "proc-macro2",
+]
+
+[[package]]
+name = "serde"
+version = "1.0.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449"
+
+[[package]]
+name = "serde_cbor"
+version = "0.11.2"
+dependencies = [
+ "half",
+ "serde",
+ "serde_derive",
+]
+
+[[package]]
+name = "serde_derive"
+version = "1.0.104"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "syn"
+version = "1.0.13"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e4ff033220a41d1a57d8125eab57bf5263783dfdcc18688b1dacc6ce9651ef8"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "unicode-xid",
+]
+
+[[package]]
+name = "unicode-xid"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
diff --git a/third_party/rust/serde_cbor/Cargo.toml b/third_party/rust/serde_cbor/Cargo.toml
new file mode 100644
index 0000000000..2960dbe95d
--- /dev/null
+++ b/third_party/rust/serde_cbor/Cargo.toml
@@ -0,0 +1,44 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you 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]
+edition = "2018"
+name = "serde_cbor"
+version = "0.11.2"
+authors = ["Pyfisch <pyfisch@posteo.org>", "Steven Fackler <sfackler@gmail.com>"]
+description = "CBOR support for serde."
+readme = "README.md"
+keywords = ["serde", "cbor", "serialization", "no_std"]
+categories = ["encoding"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/pyfisch/cbor"
+[dependencies.half]
+version = "1.2.0"
+
+[dependencies.serde]
+version = "1.0.14"
+default-features = false
+[dev-dependencies.serde_derive]
+version = "1.0.14"
+default-features = false
+
+[features]
+alloc = ["serde/alloc"]
+default = ["std"]
+std = ["serde/std"]
+tags = []
+unsealed_read_write = []
+[badges.maintenance]
+status = "as-is"
+
+[badges.travis-ci]
+repository = "pyfisch/cbor"
diff --git a/third_party/rust/serde_cbor/LICENSE-APACHE b/third_party/rust/serde_cbor/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/serde_cbor/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/third_party/rust/serde_cbor/LICENSE-MIT b/third_party/rust/serde_cbor/LICENSE-MIT
new file mode 100644
index 0000000000..b1b75fa62c
--- /dev/null
+++ b/third_party/rust/serde_cbor/LICENSE-MIT
@@ -0,0 +1,19 @@
+Copyright (c) 2015 Pyfisch
+
+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.
diff --git a/third_party/rust/serde_cbor/README.md b/third_party/rust/serde_cbor/README.md
new file mode 100644
index 0000000000..b49e8adbc3
--- /dev/null
+++ b/third_party/rust/serde_cbor/README.md
@@ -0,0 +1,97 @@
+# Serde CBOR
+[![Build Status](https://travis-ci.org/pyfisch/cbor.svg?branch=master)](https://travis-ci.org/pyfisch/cbor)
+[![Crates.io](https://img.shields.io/crates/v/serde_cbor.svg)](https://crates.io/crates/serde_cbor)
+[![Documentation](https://docs.rs/serde_cbor/badge.svg)](https://docs.rs/serde_cbor)
+
+## PROJECT IS ARCHIVED
+
+After almost 6 years it is time to retire this crate.
+This implementation of CBOR for serde is used in hundreds of projects with widely differing needs.
+Besides the standard features it contains code for no-std environments, a packed encoding and CBOR tags.
+However while these features are useful to many people they sometimes interact poorly with each others and with optional features of serde itself.
+Because I don't use the crate myself and because of the potential for new errors I have been reluctant to accept any changes or additional features for the crate.
+Since this situation is unlikely to change anytime soon and no one else stepped up to maintain this crate I am archiving the repository today.
+If the crate works for you there is no need to switch to another implementation.
+However if you encounter problems or for new projects I recommend you take a look at these crates:
+
+* [ciborium](https://crates.io/crates/ciborium)
+* [minicbor](https://crates.io/crates/minicbor)
+
+~~ Pyfisch, August 2021
+
+
+
+This crate implements the Concise Binary Object Representation from [RFC 7049].
+It builds on [Serde], the generic serialization framework for Rust.
+CBOR provides a binary encoding for a superset
+of the JSON data model that is small and very fast to parse.
+
+[RFC 7049]: https://tools.ietf.org/html/rfc7049
+[Serde]: https://github.com/serde-rs/serde
+
+## Usage
+
+Serde CBOR supports Rust 1.40 and up. Add this to your `Cargo.toml`:
+```toml
+[dependencies]
+serde_cbor = "0.11.2"
+```
+
+Storing and loading Rust types is easy and requires only
+minimal modifications to the program code.
+
+```rust
+use serde_derive::{Deserialize, Serialize};
+use std::error::Error;
+use std::fs::File;
+
+// Types annotated with `Serialize` can be stored as CBOR.
+// To be able to load them again add `Deserialize`.
+#[derive(Debug, Serialize, Deserialize)]
+struct Mascot {
+ name: String,
+ species: String,
+ year_of_birth: u32,
+}
+
+fn main() -> Result<(), Box<dyn Error>> {
+ let ferris = Mascot {
+ name: "Ferris".to_owned(),
+ species: "crab".to_owned(),
+ year_of_birth: 2015,
+ };
+
+ let ferris_file = File::create("examples/ferris.cbor")?;
+ // Write Ferris to the given file.
+ // Instead of a file you can use any type that implements `io::Write`
+ // like a HTTP body, database connection etc.
+ serde_cbor::to_writer(ferris_file, &ferris)?;
+
+ let tux_file = File::open("examples/tux.cbor")?;
+ // Load Tux from a file.
+ // Serde CBOR performs roundtrip serialization meaning that
+ // the data will not change in any way.
+ let tux: Mascot = serde_cbor::from_reader(tux_file)?;
+
+ println!("{:?}", tux);
+ // prints: Mascot { name: "Tux", species: "penguin", year_of_birth: 1996 }
+
+ Ok(())
+}
+```
+
+There are a lot of options available to customize the format.
+To operate on untyped CBOR values have a look at the `Value` type.
+
+## License
+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 the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any
+additional terms or conditions.
diff --git a/third_party/rust/serde_cbor/examples/readme.rs b/third_party/rust/serde_cbor/examples/readme.rs
new file mode 100644
index 0000000000..7689394b79
--- /dev/null
+++ b/third_party/rust/serde_cbor/examples/readme.rs
@@ -0,0 +1,39 @@
+// NOTE: This file should be kept in sync with README.md
+
+use serde_derive::{Deserialize, Serialize};
+use std::error::Error;
+use std::fs::File;
+
+// Types annotated with `Serialize` can be stored as CBOR.
+// To be able to load them again add `Deserialize`.
+#[derive(Debug, Serialize, Deserialize)]
+struct Mascot {
+ name: String,
+ species: String,
+ year_of_birth: u32,
+}
+
+fn main() -> Result<(), Box<dyn Error>> {
+ let ferris = Mascot {
+ name: "Ferris".to_owned(),
+ species: "crab".to_owned(),
+ year_of_birth: 2015,
+ };
+
+ let ferris_file = File::create("examples/ferris.cbor")?;
+ // Write Ferris to the given file.
+ // Instead of a file you can use any type that implements `io::Write`
+ // like a HTTP body, database connection etc.
+ serde_cbor::to_writer(ferris_file, &ferris)?;
+
+ let tux_file = File::open("examples/tux.cbor")?;
+ // Load Tux from a file.
+ // Serde CBOR performs roundtrip serialization meaning that
+ // the data will not change in any way.
+ let tux: Mascot = serde_cbor::from_reader(tux_file)?;
+
+ println!("{:?}", tux);
+ // prints: Mascot { name: "Tux", species: "penguin", year_of_birth: 1996 }
+
+ Ok(())
+}
diff --git a/third_party/rust/serde_cbor/examples/tags.rs b/third_party/rust/serde_cbor/examples/tags.rs
new file mode 100644
index 0000000000..9281b9b845
--- /dev/null
+++ b/third_party/rust/serde_cbor/examples/tags.rs
@@ -0,0 +1,84 @@
+use serde::de::{Deserialize, Deserializer};
+use serde::ser::{Serialize, Serializer};
+use serde_cbor::tags::Tagged;
+use serde_cbor::Value;
+use serde_derive::{Deserialize, Serialize};
+use std::error::Error;
+
+/// https://tools.ietf.org/html/rfc7049#section-2.4.1
+#[derive(Debug, PartialEq)]
+struct Date(String);
+
+impl Serialize for Date {
+ fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
+ Tagged::new(Some(0), &self.0).serialize(s)
+ }
+}
+
+impl<'de> Deserialize<'de> for Date {
+ fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+ let tagged = Tagged::<String>::deserialize(deserializer)?;
+ match tagged.tag {
+ Some(0) | None => Ok(Date(tagged.value)),
+ Some(_) => Err(serde::de::Error::custom("unexpected tag")),
+ }
+ }
+}
+
+/// https://tools.ietf.org/html/rfc7049#section-2.4.4.3
+#[derive(Debug, PartialEq)]
+struct Uri(String);
+
+impl Serialize for Uri {
+ fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
+ Tagged::new(Some(32), &self.0).serialize(s)
+ }
+}
+impl<'de> Deserialize<'de> for Uri {
+ fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+ let tagged = Tagged::<String>::deserialize(deserializer)?;
+ match tagged.tag {
+ // allow deserialization even if there is no tag. Allows roundtrip via other formats such as json
+ Some(0) | None => Ok(Uri(tagged.value)),
+ Some(_) => Err(serde::de::Error::custom("unexpected tag")),
+ }
+ }
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq)]
+struct Bookmark {
+ title: String,
+ link: Uri,
+ created: Date,
+}
+
+fn main() -> Result<(), Box<dyn Error>> {
+ let bookmark = Bookmark {
+ title: "The Example Domain".into(),
+ link: Uri("http://example.org/".into()),
+ created: Date("2003-12-13T18:30:02Z".into()),
+ };
+
+ // serialize the struct to bytes
+ let bytes1 = serde_cbor::to_vec(&bookmark)?;
+ // deserialize to a serde_cbor::Value
+ let value1: Value = serde_cbor::from_slice(&bytes1)?;
+ println!("{:?}", value1);
+ // serialize the value to bytes
+ let bytes2 = serde_cbor::to_vec(&value1)?;
+ // deserialize to a serde_cbor::Value
+ let value2: Value = serde_cbor::from_slice(&bytes2)?;
+ println!("{:?}", value2);
+ // deserialize to a Bookmark
+ let result: Bookmark = serde_cbor::from_slice(&bytes2)?;
+
+ // check that the roundtrip was successful
+ assert_eq!(value1, value2);
+ assert_eq!(bookmark, result);
+
+ // check that going via a format that does not support tags does work
+ // let json = serde_json::to_vec(&bookmark)?;
+ // let result: Bookmark = serde_json::from_slice(&json)?;
+ // assert_eq!(bookmark, result);
+ Ok(())
+}
diff --git a/third_party/rust/serde_cbor/examples/tux.cbor b/third_party/rust/serde_cbor/examples/tux.cbor
new file mode 100644
index 0000000000..c3331aabc1
--- /dev/null
+++ b/third_party/rust/serde_cbor/examples/tux.cbor
@@ -0,0 +1 @@
+£dnamecTuxgspeciesgpenguinmyear_of_birthÌ \ No newline at end of file
diff --git a/third_party/rust/serde_cbor/src/de.rs b/third_party/rust/serde_cbor/src/de.rs
new file mode 100644
index 0000000000..170e0593cf
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/de.rs
@@ -0,0 +1,1360 @@
+//! Deserialization.
+
+use core::f32;
+use core::marker::PhantomData;
+use core::result;
+use core::str;
+use half::f16;
+use serde::de;
+#[cfg(feature = "std")]
+use std::io;
+
+use crate::error::{Error, ErrorCode, Result};
+#[cfg(not(feature = "unsealed_read_write"))]
+use crate::read::EitherLifetime;
+#[cfg(feature = "unsealed_read_write")]
+pub use crate::read::EitherLifetime;
+#[cfg(feature = "std")]
+pub use crate::read::IoRead;
+use crate::read::Offset;
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub use crate::read::SliceRead;
+pub use crate::read::{MutSliceRead, Read, SliceReadFixed};
+#[cfg(feature = "tags")]
+use crate::tags::set_tag;
+/// Decodes a value from CBOR data in a slice.
+///
+/// # Examples
+///
+/// Deserialize a `String`
+///
+/// ```
+/// # use serde_cbor::de;
+/// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72];
+/// let value: String = de::from_slice(&v[..]).unwrap();
+/// assert_eq!(value, "foobar");
+/// ```
+///
+/// Deserialize a borrowed string with zero copies.
+///
+/// ```
+/// # use serde_cbor::de;
+/// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72];
+/// let value: &str = de::from_slice(&v[..]).unwrap();
+/// assert_eq!(value, "foobar");
+/// ```
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub fn from_slice<'a, T>(slice: &'a [u8]) -> Result<T>
+where
+ T: de::Deserialize<'a>,
+{
+ let mut deserializer = Deserializer::from_slice(slice);
+ let value = de::Deserialize::deserialize(&mut deserializer)?;
+ deserializer.end()?;
+ Ok(value)
+}
+
+// When the "std" feature is enabled there should be little to no need to ever use this function,
+// as `from_slice` covers all use cases (at the expense of being less efficient).
+/// Decode a value from CBOR data in a mutable slice.
+///
+/// This can be used in analogy to `from_slice`. Unlike `from_slice`, this will use the slice's
+/// mutability to rearrange data in it in order to resolve indefinite byte or text strings without
+/// resorting to allocations.
+pub fn from_mut_slice<'a, T>(slice: &'a mut [u8]) -> Result<T>
+where
+ T: de::Deserialize<'a>,
+{
+ let mut deserializer = Deserializer::from_mut_slice(slice);
+ let value = de::Deserialize::deserialize(&mut deserializer)?;
+ deserializer.end()?;
+ Ok(value)
+}
+
+// When the "std" feature is enabled there should be little to no need to ever use this function,
+// as `from_slice` covers all use cases and is much more reliable (at the expense of being less
+// efficient).
+/// Decode a value from CBOR data using a scratch buffer.
+///
+/// Users should generally prefer to use `from_slice` or `from_mut_slice` over this function,
+/// as decoding may fail when the scratch buffer turns out to be too small.
+///
+/// A realistic use case for this method would be decoding in a `no_std` environment from an
+/// immutable slice that is too large to copy.
+pub fn from_slice_with_scratch<'a, 'b, T>(slice: &'a [u8], scratch: &'b mut [u8]) -> Result<T>
+where
+ T: de::Deserialize<'a>,
+{
+ let mut deserializer = Deserializer::from_slice_with_scratch(slice, scratch);
+ let value = de::Deserialize::deserialize(&mut deserializer)?;
+ deserializer.end()?;
+ Ok(value)
+}
+
+/// Decodes a value from CBOR data in a reader.
+///
+/// # Examples
+///
+/// Deserialize a `String`
+///
+/// ```
+/// # use serde_cbor::de;
+/// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72];
+/// let value: String = de::from_reader(&v[..]).unwrap();
+/// assert_eq!(value, "foobar");
+/// ```
+///
+/// Note that `from_reader` cannot borrow data:
+///
+/// ```compile_fail
+/// # use serde_cbor::de;
+/// let v: Vec<u8> = vec![0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72];
+/// let value: &str = de::from_reader(&v[..]).unwrap();
+/// assert_eq!(value, "foobar");
+/// ```
+#[cfg(feature = "std")]
+pub fn from_reader<T, R>(reader: R) -> Result<T>
+where
+ T: de::DeserializeOwned,
+ R: io::Read,
+{
+ let mut deserializer = Deserializer::from_reader(reader);
+ let value = de::Deserialize::deserialize(&mut deserializer)?;
+ deserializer.end()?;
+ Ok(value)
+}
+
+/// A Serde `Deserialize`r of CBOR data.
+#[derive(Debug)]
+pub struct Deserializer<R> {
+ read: R,
+ remaining_depth: u8,
+ accept_named: bool,
+ accept_packed: bool,
+ accept_standard_enums: bool,
+ accept_legacy_enums: bool,
+}
+
+#[cfg(feature = "std")]
+impl<R> Deserializer<IoRead<R>>
+where
+ R: io::Read,
+{
+ /// Constructs a `Deserializer` which reads from a `Read`er.
+ pub fn from_reader(reader: R) -> Deserializer<IoRead<R>> {
+ Deserializer::new(IoRead::new(reader))
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a> Deserializer<SliceRead<'a>> {
+ /// Constructs a `Deserializer` which reads from a slice.
+ ///
+ /// Borrowed strings and byte slices will be provided when possible.
+ pub fn from_slice(bytes: &'a [u8]) -> Deserializer<SliceRead<'a>> {
+ Deserializer::new(SliceRead::new(bytes))
+ }
+}
+
+impl<'a> Deserializer<MutSliceRead<'a>> {
+ /// Constructs a `Deserializer` which reads from a mutable slice that doubles as its own
+ /// scratch buffer.
+ ///
+ /// Borrowed strings and byte slices will be provided even for indefinite strings.
+ pub fn from_mut_slice(bytes: &'a mut [u8]) -> Deserializer<MutSliceRead<'a>> {
+ Deserializer::new(MutSliceRead::new(bytes))
+ }
+}
+
+impl<'a, 'b> Deserializer<SliceReadFixed<'a, 'b>> {
+ #[doc(hidden)]
+ pub fn from_slice_with_scratch(
+ bytes: &'a [u8],
+ scratch: &'b mut [u8],
+ ) -> Deserializer<SliceReadFixed<'a, 'b>> {
+ Deserializer::new(SliceReadFixed::new(bytes, scratch))
+ }
+}
+
+impl<'de, R> Deserializer<R>
+where
+ R: Read<'de>,
+{
+ /// Constructs a `Deserializer` from one of the possible serde_cbor input sources.
+ ///
+ /// `from_slice` and `from_reader` should normally be used instead of this method.
+ pub fn new(read: R) -> Self {
+ Deserializer {
+ read,
+ remaining_depth: 128,
+ accept_named: true,
+ accept_packed: true,
+ accept_standard_enums: true,
+ accept_legacy_enums: true,
+ }
+ }
+
+ /// Don't accept named variants and fields.
+ pub fn disable_named_format(mut self) -> Self {
+ self.accept_named = false;
+ self
+ }
+
+ /// Don't accept numbered variants and fields.
+ pub fn disable_packed_format(mut self) -> Self {
+ self.accept_packed = false;
+ self
+ }
+
+ /// Don't accept the new enum format used by `serde_cbor` versions >= v0.10.
+ pub fn disable_standard_enums(mut self) -> Self {
+ self.accept_standard_enums = false;
+ self
+ }
+
+ /// Don't accept the old enum format used by `serde_cbor` versions <= v0.9.
+ pub fn disable_legacy_enums(mut self) -> Self {
+ self.accept_legacy_enums = false;
+ self
+ }
+
+ /// This method should be called after a value has been deserialized to ensure there is no
+ /// trailing data in the input source.
+ pub fn end(&mut self) -> Result<()> {
+ match self.next()? {
+ Some(_) => Err(self.error(ErrorCode::TrailingData)),
+ None => Ok(()),
+ }
+ }
+
+ /// Turn a CBOR deserializer into an iterator over values of type T.
+ #[allow(clippy::should_implement_trait)] // Trait doesn't allow unconstrained T.
+ pub fn into_iter<T>(self) -> StreamDeserializer<'de, R, T>
+ where
+ T: de::Deserialize<'de>,
+ {
+ StreamDeserializer {
+ de: self,
+ output: PhantomData,
+ lifetime: PhantomData,
+ }
+ }
+
+ fn next(&mut self) -> Result<Option<u8>> {
+ self.read.next()
+ }
+
+ fn peek(&mut self) -> Result<Option<u8>> {
+ self.read.peek()
+ }
+
+ fn consume(&mut self) {
+ self.read.discard();
+ }
+
+ fn error(&self, reason: ErrorCode) -> Error {
+ let offset = self.read.offset();
+ Error::syntax(reason, offset)
+ }
+
+ fn parse_u8(&mut self) -> Result<u8> {
+ match self.next()? {
+ Some(byte) => Ok(byte),
+ None => Err(self.error(ErrorCode::EofWhileParsingValue)),
+ }
+ }
+
+ fn parse_u16(&mut self) -> Result<u16> {
+ let mut buf = [0; 2];
+ self.read
+ .read_into(&mut buf)
+ .map(|()| u16::from_be_bytes(buf))
+ }
+
+ fn parse_u32(&mut self) -> Result<u32> {
+ let mut buf = [0; 4];
+ self.read
+ .read_into(&mut buf)
+ .map(|()| u32::from_be_bytes(buf))
+ }
+
+ fn parse_u64(&mut self) -> Result<u64> {
+ let mut buf = [0; 8];
+ self.read
+ .read_into(&mut buf)
+ .map(|()| u64::from_be_bytes(buf))
+ }
+
+ fn parse_bytes<V>(&mut self, len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.read.read(len)? {
+ EitherLifetime::Long(buf) => visitor.visit_borrowed_bytes(buf),
+ EitherLifetime::Short(buf) => visitor.visit_bytes(buf),
+ }
+ }
+
+ fn parse_indefinite_bytes<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.read.clear_buffer();
+ loop {
+ let byte = self.parse_u8()?;
+ let len = match byte {
+ 0x40..=0x57 => byte as usize - 0x40,
+ 0x58 => self.parse_u8()? as usize,
+ 0x59 => self.parse_u16()? as usize,
+ 0x5a => self.parse_u32()? as usize,
+ 0x5b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ len as usize
+ }
+ 0xff => break,
+ _ => return Err(self.error(ErrorCode::UnexpectedCode)),
+ };
+
+ self.read.read_to_buffer(len)?;
+ }
+
+ match self.read.take_buffer() {
+ EitherLifetime::Long(buf) => visitor.visit_borrowed_bytes(buf),
+ EitherLifetime::Short(buf) => visitor.visit_bytes(buf),
+ }
+ }
+
+ fn convert_str<'a>(buf: &'a [u8], buf_end_offset: u64) -> Result<&'a str> {
+ match str::from_utf8(buf) {
+ Ok(s) => Ok(s),
+ Err(e) => {
+ let shift = buf.len() - e.valid_up_to();
+ let offset = buf_end_offset - shift as u64;
+ Err(Error::syntax(ErrorCode::InvalidUtf8, offset))
+ }
+ }
+ }
+
+ fn parse_str<V>(&mut self, len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ if let Some(offset) = self.read.offset().checked_add(len as u64) {
+ match self.read.read(len)? {
+ EitherLifetime::Long(buf) => {
+ let s = Self::convert_str(buf, offset)?;
+ visitor.visit_borrowed_str(s)
+ }
+ EitherLifetime::Short(buf) => {
+ let s = Self::convert_str(buf, offset)?;
+ visitor.visit_str(s)
+ }
+ }
+ } else {
+ // An overflow would have occured.
+ Err(Error::syntax(
+ ErrorCode::LengthOutOfRange,
+ self.read.offset(),
+ ))
+ }
+ }
+
+ fn parse_indefinite_str<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.read.clear_buffer();
+ loop {
+ let byte = self.parse_u8()?;
+ let len = match byte {
+ 0x60..=0x77 => byte as usize - 0x60,
+ 0x78 => self.parse_u8()? as usize,
+ 0x79 => self.parse_u16()? as usize,
+ 0x7a => self.parse_u32()? as usize,
+ 0x7b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ len as usize
+ }
+ 0xff => break,
+ _ => return Err(self.error(ErrorCode::UnexpectedCode)),
+ };
+
+ self.read.read_to_buffer(len)?;
+ }
+
+ let offset = self.read.offset();
+ match self.read.take_buffer() {
+ EitherLifetime::Long(buf) => {
+ let s = Self::convert_str(buf, offset)?;
+ visitor.visit_borrowed_str(s)
+ }
+ EitherLifetime::Short(buf) => {
+ let s = Self::convert_str(buf, offset)?;
+ visitor.visit_str(s)
+ }
+ }
+ }
+
+ #[cfg(feature = "tags")]
+ fn handle_tagged_value<V>(&mut self, tag: u64, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|d| {
+ set_tag(Some(tag));
+ let r = visitor.visit_newtype_struct(d);
+ set_tag(None);
+ r
+ })
+ }
+
+ #[cfg(not(feature = "tags"))]
+ fn handle_tagged_value<V>(&mut self, _tag: u64, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|de| de.parse_value(visitor))
+ }
+
+ fn recursion_checked<F, T>(&mut self, f: F) -> Result<T>
+ where
+ F: FnOnce(&mut Deserializer<R>) -> Result<T>,
+ {
+ self.remaining_depth -= 1;
+ if self.remaining_depth == 0 {
+ return Err(self.error(ErrorCode::RecursionLimitExceeded));
+ }
+ let r = f(self);
+ self.remaining_depth += 1;
+ r
+ }
+
+ fn parse_array<V>(&mut self, mut len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|de| {
+ let value = visitor.visit_seq(SeqAccess { de, len: &mut len })?;
+
+ if len != 0 {
+ Err(de.error(ErrorCode::TrailingData))
+ } else {
+ Ok(value)
+ }
+ })
+ }
+
+ fn parse_indefinite_array<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|de| {
+ let value = visitor.visit_seq(IndefiniteSeqAccess { de })?;
+ match de.next()? {
+ Some(0xff) => Ok(value),
+ Some(_) => Err(de.error(ErrorCode::TrailingData)),
+ None => Err(de.error(ErrorCode::EofWhileParsingArray)),
+ }
+ })
+ }
+
+ fn parse_map<V>(&mut self, mut len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let accept_packed = self.accept_packed;
+ let accept_named = self.accept_named;
+ self.recursion_checked(|de| {
+ let value = visitor.visit_map(MapAccess {
+ de,
+ len: &mut len,
+ accept_named,
+ accept_packed,
+ })?;
+
+ if len != 0 {
+ Err(de.error(ErrorCode::TrailingData))
+ } else {
+ Ok(value)
+ }
+ })
+ }
+
+ fn parse_indefinite_map<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let accept_named = self.accept_named;
+ let accept_packed = self.accept_packed;
+ self.recursion_checked(|de| {
+ let value = visitor.visit_map(IndefiniteMapAccess {
+ de,
+ accept_packed,
+ accept_named,
+ })?;
+ match de.next()? {
+ Some(0xff) => Ok(value),
+ Some(_) => Err(de.error(ErrorCode::TrailingData)),
+ None => Err(de.error(ErrorCode::EofWhileParsingMap)),
+ }
+ })
+ }
+
+ fn parse_enum<V>(&mut self, mut len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|de| {
+ let value = visitor.visit_enum(VariantAccess {
+ seq: SeqAccess { de, len: &mut len },
+ })?;
+
+ if len != 0 {
+ Err(de.error(ErrorCode::TrailingData))
+ } else {
+ Ok(value)
+ }
+ })
+ }
+
+ fn parse_enum_map<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let accept_named = self.accept_named;
+ let accept_packed = self.accept_packed;
+ self.recursion_checked(|de| {
+ let mut len = 1;
+ let value = visitor.visit_enum(VariantAccessMap {
+ map: MapAccess {
+ de,
+ len: &mut len,
+ accept_packed,
+ accept_named,
+ },
+ })?;
+
+ if len != 0 {
+ Err(de.error(ErrorCode::TrailingData))
+ } else {
+ Ok(value)
+ }
+ })
+ }
+
+ fn parse_indefinite_enum<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.recursion_checked(|de| {
+ let value = visitor.visit_enum(VariantAccess {
+ seq: IndefiniteSeqAccess { de },
+ })?;
+ match de.next()? {
+ Some(0xff) => Ok(value),
+ Some(_) => Err(de.error(ErrorCode::TrailingData)),
+ None => Err(de.error(ErrorCode::EofWhileParsingArray)),
+ }
+ })
+ }
+
+ fn parse_f16(&mut self) -> Result<f32> {
+ Ok(f32::from(f16::from_bits(self.parse_u16()?)))
+ }
+
+ fn parse_f32(&mut self) -> Result<f32> {
+ self.parse_u32().map(|i| f32::from_bits(i))
+ }
+
+ fn parse_f64(&mut self) -> Result<f64> {
+ self.parse_u64().map(|i| f64::from_bits(i))
+ }
+
+ // Don't warn about the `unreachable!` in case
+ // exhaustive integer pattern matching is enabled.
+ #[allow(unreachable_patterns)]
+ fn parse_value<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let byte = self.parse_u8()?;
+ match byte {
+ // Major type 0: an unsigned integer
+ 0x00..=0x17 => visitor.visit_u8(byte),
+ 0x18 => {
+ let value = self.parse_u8()?;
+ visitor.visit_u8(value)
+ }
+ 0x19 => {
+ let value = self.parse_u16()?;
+ visitor.visit_u16(value)
+ }
+ 0x1a => {
+ let value = self.parse_u32()?;
+ visitor.visit_u32(value)
+ }
+ 0x1b => {
+ let value = self.parse_u64()?;
+ visitor.visit_u64(value)
+ }
+ 0x1c..=0x1f => Err(self.error(ErrorCode::UnassignedCode)),
+
+ // Major type 1: a negative integer
+ 0x20..=0x37 => visitor.visit_i8(-1 - (byte - 0x20) as i8),
+ 0x38 => {
+ let value = self.parse_u8()?;
+ visitor.visit_i16(-1 - i16::from(value))
+ }
+ 0x39 => {
+ let value = self.parse_u16()?;
+ visitor.visit_i32(-1 - i32::from(value))
+ }
+ 0x3a => {
+ let value = self.parse_u32()?;
+ visitor.visit_i64(-1 - i64::from(value))
+ }
+ 0x3b => {
+ let value = self.parse_u64()?;
+ if value > i64::max_value() as u64 {
+ return visitor.visit_i128(-1 - i128::from(value));
+ }
+ visitor.visit_i64(-1 - value as i64)
+ }
+ 0x3c..=0x3f => Err(self.error(ErrorCode::UnassignedCode)),
+
+ // Major type 2: a byte string
+ 0x40..=0x57 => self.parse_bytes(byte as usize - 0x40, visitor),
+ 0x58 => {
+ let len = self.parse_u8()?;
+ self.parse_bytes(len as usize, visitor)
+ }
+ 0x59 => {
+ let len = self.parse_u16()?;
+ self.parse_bytes(len as usize, visitor)
+ }
+ 0x5a => {
+ let len = self.parse_u32()?;
+ self.parse_bytes(len as usize, visitor)
+ }
+ 0x5b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ self.parse_bytes(len as usize, visitor)
+ }
+ 0x5c..=0x5e => Err(self.error(ErrorCode::UnassignedCode)),
+ 0x5f => self.parse_indefinite_bytes(visitor),
+
+ // Major type 3: a text string
+ 0x60..=0x77 => self.parse_str(byte as usize - 0x60, visitor),
+ 0x78 => {
+ let len = self.parse_u8()?;
+ self.parse_str(len as usize, visitor)
+ }
+ 0x79 => {
+ let len = self.parse_u16()?;
+ self.parse_str(len as usize, visitor)
+ }
+ 0x7a => {
+ let len = self.parse_u32()?;
+ self.parse_str(len as usize, visitor)
+ }
+ 0x7b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ self.parse_str(len as usize, visitor)
+ }
+ 0x7c..=0x7e => Err(self.error(ErrorCode::UnassignedCode)),
+ 0x7f => self.parse_indefinite_str(visitor),
+
+ // Major type 4: an array of data items
+ 0x80..=0x97 => self.parse_array(byte as usize - 0x80, visitor),
+ 0x98 => {
+ let len = self.parse_u8()?;
+ self.parse_array(len as usize, visitor)
+ }
+ 0x99 => {
+ let len = self.parse_u16()?;
+ self.parse_array(len as usize, visitor)
+ }
+ 0x9a => {
+ let len = self.parse_u32()?;
+ self.parse_array(len as usize, visitor)
+ }
+ 0x9b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ self.parse_array(len as usize, visitor)
+ }
+ 0x9c..=0x9e => Err(self.error(ErrorCode::UnassignedCode)),
+ 0x9f => self.parse_indefinite_array(visitor),
+
+ // Major type 5: a map of pairs of data items
+ 0xa0..=0xb7 => self.parse_map(byte as usize - 0xa0, visitor),
+ 0xb8 => {
+ let len = self.parse_u8()?;
+ self.parse_map(len as usize, visitor)
+ }
+ 0xb9 => {
+ let len = self.parse_u16()?;
+ self.parse_map(len as usize, visitor)
+ }
+ 0xba => {
+ let len = self.parse_u32()?;
+ self.parse_map(len as usize, visitor)
+ }
+ 0xbb => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ self.parse_map(len as usize, visitor)
+ }
+ 0xbc..=0xbe => Err(self.error(ErrorCode::UnassignedCode)),
+ 0xbf => self.parse_indefinite_map(visitor),
+
+ // Major type 6: optional semantic tagging of other major types
+ 0xc0..=0xd7 => {
+ let tag = u64::from(byte) - 0xc0;
+ self.handle_tagged_value(tag, visitor)
+ }
+ 0xd8 => {
+ let tag = self.parse_u8()?;
+ self.handle_tagged_value(tag.into(), visitor)
+ }
+ 0xd9 => {
+ let tag = self.parse_u16()?;
+ self.handle_tagged_value(tag.into(), visitor)
+ }
+ 0xda => {
+ let tag = self.parse_u32()?;
+ self.handle_tagged_value(tag.into(), visitor)
+ }
+ 0xdb => {
+ let tag = self.parse_u64()?;
+ self.handle_tagged_value(tag, visitor)
+ }
+ 0xdc..=0xdf => Err(self.error(ErrorCode::UnassignedCode)),
+
+ // Major type 7: floating-point numbers and other simple data types that need no content
+ 0xe0..=0xf3 => Err(self.error(ErrorCode::UnassignedCode)),
+ 0xf4 => visitor.visit_bool(false),
+ 0xf5 => visitor.visit_bool(true),
+ 0xf6 => visitor.visit_unit(),
+ 0xf7 => visitor.visit_unit(),
+ 0xf8 => Err(self.error(ErrorCode::UnassignedCode)),
+ 0xf9 => {
+ let value = self.parse_f16()?;
+ visitor.visit_f32(value)
+ }
+ 0xfa => {
+ let value = self.parse_f32()?;
+ visitor.visit_f32(value)
+ }
+ 0xfb => {
+ let value = self.parse_f64()?;
+ visitor.visit_f64(value)
+ }
+ 0xfc..=0xfe => Err(self.error(ErrorCode::UnassignedCode)),
+ 0xff => Err(self.error(ErrorCode::UnexpectedCode)),
+
+ _ => unreachable!(),
+ }
+ }
+}
+
+impl<'de, 'a, R> de::Deserializer<'de> for &'a mut Deserializer<R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.parse_value(visitor)
+ }
+
+ #[inline]
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.peek()? {
+ Some(0xf6) => {
+ self.consume();
+ visitor.visit_none()
+ }
+ _ => visitor.visit_some(self),
+ }
+ }
+
+ #[inline]
+ fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_newtype_struct(self)
+ }
+
+ // Unit variants are encoded as just the variant identifier.
+ // Tuple variants are encoded as an array of the variant identifier followed by the fields.
+ // Struct variants are encoded as an array of the variant identifier followed by the struct.
+ #[inline]
+ fn deserialize_enum<V>(
+ self,
+ _name: &str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.peek()? {
+ Some(byte @ 0x80..=0x9f) => {
+ if !self.accept_legacy_enums {
+ return Err(self.error(ErrorCode::WrongEnumFormat));
+ }
+ self.consume();
+ match byte {
+ 0x80..=0x97 => self.parse_enum(byte as usize - 0x80, visitor),
+ 0x98 => {
+ let len = self.parse_u8()?;
+ self.parse_enum(len as usize, visitor)
+ }
+ 0x99 => {
+ let len = self.parse_u16()?;
+ self.parse_enum(len as usize, visitor)
+ }
+ 0x9a => {
+ let len = self.parse_u32()?;
+ self.parse_enum(len as usize, visitor)
+ }
+ 0x9b => {
+ let len = self.parse_u64()?;
+ if len > usize::max_value() as u64 {
+ return Err(self.error(ErrorCode::LengthOutOfRange));
+ }
+ self.parse_enum(len as usize, visitor)
+ }
+ 0x9c..=0x9e => Err(self.error(ErrorCode::UnassignedCode)),
+ 0x9f => self.parse_indefinite_enum(visitor),
+
+ _ => unreachable!(),
+ }
+ }
+ Some(0xa1) => {
+ if !self.accept_standard_enums {
+ return Err(self.error(ErrorCode::WrongEnumFormat));
+ }
+ self.consume();
+ self.parse_enum_map(visitor)
+ }
+ None => Err(self.error(ErrorCode::EofWhileParsingValue)),
+ _ => {
+ if !self.accept_standard_enums && !self.accept_legacy_enums {
+ return Err(self.error(ErrorCode::WrongEnumFormat));
+ }
+ visitor.visit_enum(UnitVariantAccess { de: self })
+ }
+ }
+ }
+
+ #[inline]
+ fn is_human_readable(&self) -> bool {
+ false
+ }
+
+ serde::forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string unit
+ unit_struct seq tuple tuple_struct map struct identifier ignored_any
+ bytes byte_buf
+ }
+}
+
+impl<R> Deserializer<R>
+where
+ R: Offset,
+{
+ /// Return the current offset in the reader
+ #[inline]
+ pub fn byte_offset(&self) -> usize {
+ self.read.byte_offset()
+ }
+}
+
+trait MakeError {
+ fn error(&self, code: ErrorCode) -> Error;
+}
+
+struct SeqAccess<'a, R> {
+ de: &'a mut Deserializer<R>,
+ len: &'a mut usize,
+}
+
+impl<'de, 'a, R> de::SeqAccess<'de> for SeqAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ if *self.len == 0 {
+ return Ok(None);
+ }
+ *self.len -= 1;
+
+ let value = seed.deserialize(&mut *self.de)?;
+ Ok(Some(value))
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ Some(*self.len)
+ }
+}
+
+impl<'de, 'a, R> MakeError for SeqAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ fn error(&self, code: ErrorCode) -> Error {
+ self.de.error(code)
+ }
+}
+
+struct IndefiniteSeqAccess<'a, R> {
+ de: &'a mut Deserializer<R>,
+}
+
+impl<'de, 'a, R> de::SeqAccess<'de> for IndefiniteSeqAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ match self.de.peek()? {
+ Some(0xff) => return Ok(None),
+ Some(_) => {}
+ None => return Err(self.de.error(ErrorCode::EofWhileParsingArray)),
+ }
+
+ let value = seed.deserialize(&mut *self.de)?;
+ Ok(Some(value))
+ }
+}
+
+impl<'de, 'a, R> MakeError for IndefiniteSeqAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ fn error(&self, code: ErrorCode) -> Error {
+ self.de.error(code)
+ }
+}
+
+struct MapAccess<'a, R> {
+ de: &'a mut Deserializer<R>,
+ len: &'a mut usize,
+ accept_named: bool,
+ accept_packed: bool,
+}
+
+impl<'de, 'a, R> de::MapAccess<'de> for MapAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
+ where
+ K: de::DeserializeSeed<'de>,
+ {
+ if *self.len == 0 {
+ return Ok(None);
+ }
+ *self.len -= 1;
+
+ match self.de.peek()? {
+ Some(_byte @ 0x00..=0x1b) if !self.accept_packed => {
+ return Err(self.de.error(ErrorCode::WrongStructFormat));
+ }
+ Some(_byte @ 0x60..=0x7f) if !self.accept_named => {
+ return Err(self.de.error(ErrorCode::WrongStructFormat));
+ }
+ _ => {}
+ };
+
+ let value = seed.deserialize(&mut *self.de)?;
+ Ok(Some(value))
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(&mut *self.de)
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ Some(*self.len)
+ }
+}
+
+impl<'de, 'a, R> MakeError for MapAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ fn error(&self, code: ErrorCode) -> Error {
+ self.de.error(code)
+ }
+}
+
+struct IndefiniteMapAccess<'a, R> {
+ de: &'a mut Deserializer<R>,
+ accept_packed: bool,
+ accept_named: bool,
+}
+
+impl<'de, 'a, R> de::MapAccess<'de> for IndefiniteMapAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
+ where
+ K: de::DeserializeSeed<'de>,
+ {
+ match self.de.peek()? {
+ Some(_byte @ 0x00..=0x1b) if !self.accept_packed => {
+ return Err(self.de.error(ErrorCode::WrongStructFormat))
+ }
+ Some(_byte @ 0x60..=0x7f) if !self.accept_named => {
+ return Err(self.de.error(ErrorCode::WrongStructFormat))
+ }
+ Some(0xff) => return Ok(None),
+ Some(_) => {}
+ None => return Err(self.de.error(ErrorCode::EofWhileParsingMap)),
+ }
+
+ let value = seed.deserialize(&mut *self.de)?;
+ Ok(Some(value))
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(&mut *self.de)
+ }
+}
+
+struct UnitVariantAccess<'a, R> {
+ de: &'a mut Deserializer<R>,
+}
+
+impl<'de, 'a, R> de::EnumAccess<'de> for UnitVariantAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+ type Variant = UnitVariantAccess<'a, R>;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, UnitVariantAccess<'a, R>)>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let variant = seed.deserialize(&mut *self.de)?;
+ Ok((variant, self))
+ }
+}
+
+impl<'de, 'a, R> de::VariantAccess<'de> for UnitVariantAccess<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<()> {
+ Ok(())
+ }
+
+ fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"newtype variant",
+ ))
+ }
+
+ fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"tuple variant",
+ ))
+ }
+
+ fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ de::Unexpected::UnitVariant,
+ &"struct variant",
+ ))
+ }
+}
+
+struct VariantAccess<T> {
+ seq: T,
+}
+
+impl<'de, T> de::EnumAccess<'de> for VariantAccess<T>
+where
+ T: de::SeqAccess<'de, Error = Error> + MakeError,
+{
+ type Error = Error;
+ type Variant = VariantAccess<T>;
+
+ fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, VariantAccess<T>)>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let variant = match self.seq.next_element_seed(seed) {
+ Ok(Some(variant)) => variant,
+ Ok(None) => return Err(self.seq.error(ErrorCode::ArrayTooShort)),
+ Err(e) => return Err(e),
+ };
+ Ok((variant, self))
+ }
+}
+
+impl<'de, T> de::VariantAccess<'de> for VariantAccess<T>
+where
+ T: de::SeqAccess<'de, Error = Error> + MakeError,
+{
+ type Error = Error;
+
+ fn unit_variant(mut self) -> Result<()> {
+ match self.seq.next_element() {
+ Ok(Some(())) => Ok(()),
+ Ok(None) => Err(self.seq.error(ErrorCode::ArrayTooLong)),
+ Err(e) => Err(e),
+ }
+ }
+
+ fn newtype_variant_seed<S>(mut self, seed: S) -> Result<S::Value>
+ where
+ S: de::DeserializeSeed<'de>,
+ {
+ match self.seq.next_element_seed(seed) {
+ Ok(Some(variant)) => Ok(variant),
+ Ok(None) => Err(self.seq.error(ErrorCode::ArrayTooShort)),
+ Err(e) => Err(e),
+ }
+ }
+
+ fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_seq(self.seq)
+ }
+
+ fn struct_variant<V>(mut self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let seed = StructVariantSeed { visitor };
+ match self.seq.next_element_seed(seed) {
+ Ok(Some(variant)) => Ok(variant),
+ Ok(None) => Err(self.seq.error(ErrorCode::ArrayTooShort)),
+ Err(e) => Err(e),
+ }
+ }
+}
+
+struct StructVariantSeed<V> {
+ visitor: V,
+}
+
+impl<'de, V> de::DeserializeSeed<'de> for StructVariantSeed<V>
+where
+ V: de::Visitor<'de>,
+{
+ type Value = V::Value;
+
+ fn deserialize<D>(self, de: D) -> result::Result<V::Value, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ de.deserialize_any(self.visitor)
+ }
+}
+
+/// Iterator that deserializes a stream into multiple CBOR values.
+///
+/// A stream deserializer can be created from any CBOR deserializer using the
+/// `Deserializer::into_iter` method.
+///
+/// ```
+/// # extern crate serde_cbor;
+/// use serde_cbor::de::Deserializer;
+/// use serde_cbor::value::Value;
+///
+/// # fn main() {
+/// let data: Vec<u8> = vec![
+/// 0x01, 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72,
+/// ];
+/// let mut it = Deserializer::from_slice(&data[..]).into_iter::<Value>();
+/// assert_eq!(
+/// Value::Integer(1),
+/// it.next().unwrap().unwrap()
+/// );
+/// assert_eq!(
+/// Value::Text("foobar".to_string()),
+/// it.next().unwrap().unwrap()
+/// );
+/// # }
+/// ```
+#[derive(Debug)]
+pub struct StreamDeserializer<'de, R, T> {
+ de: Deserializer<R>,
+ output: PhantomData<T>,
+ lifetime: PhantomData<&'de ()>,
+}
+
+impl<'de, R, T> StreamDeserializer<'de, R, T>
+where
+ R: Read<'de>,
+ T: de::Deserialize<'de>,
+{
+ /// Create a new CBOR stream deserializer from one of the possible
+ /// serde_cbor input sources.
+ ///
+ /// Typically it is more convenient to use one of these methods instead:
+ ///
+ /// * `Deserializer::from_slice(...).into_iter()`
+ /// * `Deserializer::from_reader(...).into_iter()`
+ pub fn new(read: R) -> StreamDeserializer<'de, R, T> {
+ StreamDeserializer {
+ de: Deserializer::new(read),
+ output: PhantomData,
+ lifetime: PhantomData,
+ }
+ }
+}
+
+impl<'de, R, T> StreamDeserializer<'de, R, T>
+where
+ R: Offset,
+ T: de::Deserialize<'de>,
+{
+ /// Return the current offset in the reader
+ #[inline]
+ pub fn byte_offset(&self) -> usize {
+ self.de.byte_offset()
+ }
+}
+
+impl<'de, R, T> Iterator for StreamDeserializer<'de, R, T>
+where
+ R: Read<'de>,
+ T: de::Deserialize<'de>,
+{
+ type Item = Result<T>;
+
+ fn next(&mut self) -> Option<Result<T>> {
+ match self.de.peek() {
+ Ok(Some(_)) => Some(T::deserialize(&mut self.de)),
+ Ok(None) => None,
+ Err(e) => Some(Err(e)),
+ }
+ }
+}
+
+struct VariantAccessMap<T> {
+ map: T,
+}
+
+impl<'de, T> de::EnumAccess<'de> for VariantAccessMap<T>
+where
+ T: de::MapAccess<'de, Error = Error> + MakeError,
+{
+ type Error = Error;
+ type Variant = VariantAccessMap<T>;
+
+ fn variant_seed<V>(mut self, seed: V) -> Result<(V::Value, VariantAccessMap<T>)>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let variant = match self.map.next_key_seed(seed) {
+ Ok(Some(variant)) => variant,
+ Ok(None) => return Err(self.map.error(ErrorCode::ArrayTooShort)),
+ Err(e) => return Err(e),
+ };
+ Ok((variant, self))
+ }
+}
+
+impl<'de, T> de::VariantAccess<'de> for VariantAccessMap<T>
+where
+ T: de::MapAccess<'de, Error = Error> + MakeError,
+{
+ type Error = Error;
+
+ fn unit_variant(mut self) -> Result<()> {
+ match self.map.next_value() {
+ Ok(()) => Ok(()),
+ Err(e) => Err(e),
+ }
+ }
+
+ fn newtype_variant_seed<S>(mut self, seed: S) -> Result<S::Value>
+ where
+ S: de::DeserializeSeed<'de>,
+ {
+ self.map.next_value_seed(seed)
+ }
+
+ fn tuple_variant<V>(mut self, _len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let seed = StructVariantSeed { visitor };
+ self.map.next_value_seed(seed)
+ }
+
+ fn struct_variant<V>(mut self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let seed = StructVariantSeed { visitor };
+ self.map.next_value_seed(seed)
+ }
+}
diff --git a/third_party/rust/serde_cbor/src/error.rs b/third_party/rust/serde_cbor/src/error.rs
new file mode 100644
index 0000000000..b1a6a459e5
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/error.rs
@@ -0,0 +1,318 @@
+//! When serializing or deserializing CBOR goes wrong.
+use core::fmt;
+use core::result;
+use serde::de;
+use serde::ser;
+#[cfg(feature = "std")]
+use std::error;
+#[cfg(feature = "std")]
+use std::io;
+
+/// This type represents all possible errors that can occur when serializing or deserializing CBOR
+/// data.
+pub struct Error(ErrorImpl);
+
+/// Alias for a `Result` with the error type `serde_cbor::Error`.
+pub type Result<T> = result::Result<T, Error>;
+
+/// Categorizes the cause of a `serde_cbor::Error`.
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub enum Category {
+ /// The error was caused by a failure to read or write bytes on an IO stream.
+ Io,
+ /// The error was caused by input that was not syntactically valid CBOR.
+ Syntax,
+ /// The error was caused by input data that was semantically incorrect.
+ Data,
+ /// The error was caused by prematurely reaching the end of the input data.
+ Eof,
+}
+
+impl Error {
+ /// The byte offset at which the error occurred.
+ pub fn offset(&self) -> u64 {
+ self.0.offset
+ }
+
+ pub(crate) fn syntax(code: ErrorCode, offset: u64) -> Error {
+ Error(ErrorImpl { code, offset })
+ }
+
+ #[cfg(feature = "std")]
+ pub(crate) fn io(error: io::Error) -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::Io(error),
+ offset: 0,
+ })
+ }
+
+ #[cfg(all(not(feature = "std"), feature = "unsealed_read_write"))]
+ /// Creates an error signalling that the underlying `Read` encountered an I/O error.
+ pub fn io() -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::Io,
+ offset: 0,
+ })
+ }
+
+ #[cfg(feature = "unsealed_read_write")]
+ /// Creates an error signalling that the scratch buffer was too small to fit the data.
+ pub fn scratch_too_small(offset: u64) -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::ScratchTooSmall,
+ offset,
+ })
+ }
+
+ #[cfg(not(feature = "unsealed_read_write"))]
+ pub(crate) fn scratch_too_small(offset: u64) -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::ScratchTooSmall,
+ offset,
+ })
+ }
+
+ #[cfg(feature = "unsealed_read_write")]
+ /// Creates an error with a custom message.
+ ///
+ /// **Note**: When the "std" feature is disabled, the message will be discarded.
+ pub fn message<T: fmt::Display>(_msg: T) -> Error {
+ #[cfg(not(feature = "std"))]
+ {
+ Error(ErrorImpl {
+ code: ErrorCode::Message,
+ offset: 0,
+ })
+ }
+ #[cfg(feature = "std")]
+ {
+ Error(ErrorImpl {
+ code: ErrorCode::Message(_msg.to_string()),
+ offset: 0,
+ })
+ }
+ }
+
+ #[cfg(not(feature = "unsealed_read_write"))]
+ pub(crate) fn message<T: fmt::Display>(_msg: T) -> Error {
+ #[cfg(not(feature = "std"))]
+ {
+ Error(ErrorImpl {
+ code: ErrorCode::Message,
+ offset: 0,
+ })
+ }
+ #[cfg(feature = "std")]
+ {
+ Error(ErrorImpl {
+ code: ErrorCode::Message(_msg.to_string()),
+ offset: 0,
+ })
+ }
+ }
+
+ #[cfg(feature = "unsealed_read_write")]
+ /// Creates an error signalling that the underlying read
+ /// encountered an end of input.
+ pub fn eof(offset: u64) -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::EofWhileParsingValue,
+ offset,
+ })
+ }
+
+ /// Categorizes the cause of this error.
+ pub fn classify(&self) -> Category {
+ match self.0.code {
+ #[cfg(feature = "std")]
+ ErrorCode::Message(_) => Category::Data,
+ #[cfg(not(feature = "std"))]
+ ErrorCode::Message => Category::Data,
+ #[cfg(feature = "std")]
+ ErrorCode::Io(_) => Category::Io,
+ #[cfg(not(feature = "std"))]
+ ErrorCode::Io => Category::Io,
+ ErrorCode::ScratchTooSmall => Category::Io,
+ ErrorCode::EofWhileParsingValue
+ | ErrorCode::EofWhileParsingArray
+ | ErrorCode::EofWhileParsingMap => Category::Eof,
+ ErrorCode::LengthOutOfRange
+ | ErrorCode::InvalidUtf8
+ | ErrorCode::UnassignedCode
+ | ErrorCode::UnexpectedCode
+ | ErrorCode::TrailingData
+ | ErrorCode::ArrayTooShort
+ | ErrorCode::ArrayTooLong
+ | ErrorCode::RecursionLimitExceeded
+ | ErrorCode::WrongEnumFormat
+ | ErrorCode::WrongStructFormat => Category::Syntax,
+ }
+ }
+
+ /// Returns true if this error was caused by a failure to read or write bytes on an IO stream.
+ pub fn is_io(&self) -> bool {
+ match self.classify() {
+ Category::Io => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if this error was caused by input that was not syntactically valid CBOR.
+ pub fn is_syntax(&self) -> bool {
+ match self.classify() {
+ Category::Syntax => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if this error was caused by data that was semantically incorrect.
+ pub fn is_data(&self) -> bool {
+ match self.classify() {
+ Category::Data => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if this error was caused by prematurely reaching the end of the input data.
+ pub fn is_eof(&self) -> bool {
+ match self.classify() {
+ Category::Eof => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if this error was caused by the scratch buffer being too small.
+ ///
+ /// Note this being `true` implies that `is_io()` is also `true`.
+ pub fn is_scratch_too_small(&self) -> bool {
+ match self.0.code {
+ ErrorCode::ScratchTooSmall => true,
+ _ => false,
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl error::Error for Error {
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+ match self.0.code {
+ ErrorCode::Io(ref err) => Some(err),
+ _ => None,
+ }
+ }
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ if self.0.offset == 0 {
+ fmt::Display::fmt(&self.0.code, f)
+ } else {
+ write!(f, "{} at offset {}", self.0.code, self.0.offset)
+ }
+ }
+}
+
+impl fmt::Debug for Error {
+ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+ fmt::Debug::fmt(&self.0, fmt)
+ }
+}
+
+impl de::Error for Error {
+ fn custom<T: fmt::Display>(msg: T) -> Error {
+ Error::message(msg)
+ }
+
+ fn invalid_type(unexp: de::Unexpected<'_>, exp: &dyn de::Expected) -> Error {
+ if let de::Unexpected::Unit = unexp {
+ Error::custom(format_args!("invalid type: null, expected {}", exp))
+ } else {
+ Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
+ }
+ }
+}
+
+impl ser::Error for Error {
+ fn custom<T: fmt::Display>(msg: T) -> Error {
+ Error::message(msg)
+ }
+}
+
+#[cfg(feature = "std")]
+impl From<io::Error> for Error {
+ fn from(e: io::Error) -> Error {
+ Error::io(e)
+ }
+}
+
+#[cfg(not(feature = "std"))]
+impl From<core::fmt::Error> for Error {
+ fn from(_: core::fmt::Error) -> Error {
+ Error(ErrorImpl {
+ code: ErrorCode::Message,
+ offset: 0,
+ })
+ }
+}
+
+#[derive(Debug)]
+struct ErrorImpl {
+ code: ErrorCode,
+ offset: u64,
+}
+
+#[derive(Debug)]
+pub(crate) enum ErrorCode {
+ #[cfg(feature = "std")]
+ Message(String),
+ #[cfg(not(feature = "std"))]
+ Message,
+ #[cfg(feature = "std")]
+ Io(io::Error),
+ #[allow(unused)]
+ #[cfg(not(feature = "std"))]
+ Io,
+ ScratchTooSmall,
+ EofWhileParsingValue,
+ EofWhileParsingArray,
+ EofWhileParsingMap,
+ LengthOutOfRange,
+ InvalidUtf8,
+ UnassignedCode,
+ UnexpectedCode,
+ TrailingData,
+ ArrayTooShort,
+ ArrayTooLong,
+ RecursionLimitExceeded,
+ WrongEnumFormat,
+ WrongStructFormat,
+}
+
+impl fmt::Display for ErrorCode {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match *self {
+ #[cfg(feature = "std")]
+ ErrorCode::Message(ref msg) => f.write_str(msg),
+ #[cfg(not(feature = "std"))]
+ ErrorCode::Message => f.write_str("Unknown error"),
+ #[cfg(feature = "std")]
+ ErrorCode::Io(ref err) => fmt::Display::fmt(err, f),
+ #[cfg(not(feature = "std"))]
+ ErrorCode::Io => f.write_str("Unknown I/O error"),
+ ErrorCode::ScratchTooSmall => f.write_str("Scratch buffer too small"),
+ ErrorCode::EofWhileParsingValue => f.write_str("EOF while parsing a value"),
+ ErrorCode::EofWhileParsingArray => f.write_str("EOF while parsing an array"),
+ ErrorCode::EofWhileParsingMap => f.write_str("EOF while parsing a map"),
+ ErrorCode::LengthOutOfRange => f.write_str("length out of range"),
+ ErrorCode::InvalidUtf8 => f.write_str("invalid UTF-8"),
+ ErrorCode::UnassignedCode => f.write_str("unassigned type"),
+ ErrorCode::UnexpectedCode => f.write_str("unexpected code"),
+ ErrorCode::TrailingData => f.write_str("trailing data"),
+ ErrorCode::ArrayTooShort => f.write_str("array too short"),
+ ErrorCode::ArrayTooLong => f.write_str("array too long"),
+ ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"),
+ ErrorCode::WrongEnumFormat => f.write_str("wrong enum format"),
+ ErrorCode::WrongStructFormat => f.write_str("wrong struct format"),
+ }
+ }
+}
diff --git a/third_party/rust/serde_cbor/src/lib.rs b/third_party/rust/serde_cbor/src/lib.rs
new file mode 100644
index 0000000000..5566854153
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/lib.rs
@@ -0,0 +1,369 @@
+//! CBOR and serialization.
+//!
+//! # Usage
+//!
+//! Serde CBOR supports Rust 1.40 and up. Add this to your `Cargo.toml`:
+//! ```toml
+//! [dependencies]
+//! serde_cbor = "0.10"
+//! ```
+//!
+//! Storing and loading Rust types is easy and requires only
+//! minimal modifications to the program code.
+//!
+//! ```rust
+//! use serde_derive::{Deserialize, Serialize};
+//! use std::error::Error;
+//! use std::fs::File;
+//!
+//! // Types annotated with `Serialize` can be stored as CBOR.
+//! // To be able to load them again add `Deserialize`.
+//! #[derive(Debug, Serialize, Deserialize)]
+//! struct Mascot {
+//! name: String,
+//! species: String,
+//! year_of_birth: u32,
+//! }
+//!
+//! fn main() -> Result<(), Box<dyn Error>> {
+//! let ferris = Mascot {
+//! name: "Ferris".to_owned(),
+//! species: "crab".to_owned(),
+//! year_of_birth: 2015,
+//! };
+//!
+//! let ferris_file = File::create("examples/ferris.cbor")?;
+//! // Write Ferris to the given file.
+//! // Instead of a file you can use any type that implements `io::Write`
+//! // like a HTTP body, database connection etc.
+//! serde_cbor::to_writer(ferris_file, &ferris)?;
+//!
+//! let tux_file = File::open("examples/tux.cbor")?;
+//! // Load Tux from a file.
+//! // Serde CBOR performs roundtrip serialization meaning that
+//! // the data will not change in any way.
+//! let tux: Mascot = serde_cbor::from_reader(tux_file)?;
+//!
+//! println!("{:?}", tux);
+//! // prints: Mascot { name: "Tux", species: "penguin", year_of_birth: 1996 }
+//!
+//! Ok(())
+//! }
+//! ```
+//!
+//! There are a lot of options available to customize the format.
+//! To operate on untyped CBOR values have a look at the `Value` type.
+//!
+//! # Type-based Serialization and Deserialization
+//! Serde provides a mechanism for low boilerplate serialization & deserialization of values to and
+//! from CBOR via the serialization API. To be able to serialize a piece of data, it must implement
+//! the `serde::Serialize` trait. To be able to deserialize a piece of data, it must implement the
+//! `serde::Deserialize` trait. Serde provides an annotation to automatically generate the
+//! code for these traits: `#[derive(Serialize, Deserialize)]`.
+//!
+//! The CBOR API also provides an enum `serde_cbor::Value`.
+//!
+//! # Packed Encoding
+//! When serializing structs or enums in CBOR the keys or enum variant names will be serialized
+//! as string keys to a map. Especially in embedded environments this can increase the file
+//! size too much. In packed encoding all struct keys, as well as any enum variant that has no data,
+//! will be serialized as variable sized integers. The first 24 entries in any struct consume only a
+//! single byte! Packed encoding uses serde's preferred [externally tagged enum
+//! format](https://serde.rs/enum-representations.html) and therefore serializes enum variant names
+//! as string keys when that variant contains data. So, in the packed encoding example, `FirstVariant`
+//! encodes to a single byte, but encoding `SecondVariant` requires 16 bytes.
+//!
+//! To serialize a document in this format use `Serializer::new(writer).packed_format()` or
+//! the shorthand `ser::to_vec_packed`. The deserialization works without any changes.
+//!
+//! If you would like to omit the enum variant encoding for all variants, including ones that
+//! contain data, you can add `legacy_enums()` in addition to `packed_format()`, as can seen
+//! in the Serialize using minimal encoding example.
+//!
+//! # Self describing documents
+//! In some contexts different formats are used but there is no way to declare the format used
+//! out of band. For this reason CBOR has a magic number that may be added before any document.
+//! Self describing documents are created with `serializer.self_describe()`.
+//!
+//! # Examples
+//! Read a CBOR value that is known to be a map of string keys to string values and print it.
+//!
+//! ```rust
+//! use std::collections::BTreeMap;
+//! use serde_cbor::from_slice;
+//!
+//! let slice = b"\xa5aaaAabaBacaCadaDaeaE";
+//! let value: BTreeMap<String, String> = from_slice(slice).unwrap();
+//! println!("{:?}", value); // {"e": "E", "d": "D", "a": "A", "c": "C", "b": "B"}
+//! ```
+//!
+//! Read a general CBOR value with an unknown content.
+//!
+//! ```rust
+//! use serde_cbor::from_slice;
+//! use serde_cbor::value::Value;
+//!
+//! let slice = b"\x82\x01\xa1aaab";
+//! let value: Value = from_slice(slice).unwrap();
+//! println!("{:?}", value); // Array([U64(1), Object({String("a"): String("b")})])
+//! ```
+//!
+//! Serialize an object.
+//!
+//! ```rust
+//! use std::collections::BTreeMap;
+//! use serde_cbor::to_vec;
+//!
+//! let mut programming_languages = BTreeMap::new();
+//! programming_languages.insert("rust", vec!["safe", "concurrent", "fast"]);
+//! programming_languages.insert("python", vec!["powerful", "friendly", "open"]);
+//! programming_languages.insert("js", vec!["lightweight", "interpreted", "object-oriented"]);
+//! let encoded = to_vec(&programming_languages);
+//! assert_eq!(encoded.unwrap().len(), 103);
+//! ```
+//!
+//! Deserializing data in the middle of a slice
+//! ```
+//! # extern crate serde_cbor;
+//! use serde_cbor::Deserializer;
+//!
+//! # fn main() {
+//! let data: Vec<u8> = vec![
+//! 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x66, 0x66, 0x6f, 0x6f, 0x62,
+//! 0x61, 0x72,
+//! ];
+//! let mut deserializer = Deserializer::from_slice(&data);
+//! let value: &str = serde::de::Deserialize::deserialize(&mut deserializer)
+//! .unwrap();
+//! let rest = &data[deserializer.byte_offset()..];
+//! assert_eq!(value, "foobar");
+//! assert_eq!(rest, &[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
+//! # }
+//! ```
+//!
+//! Serialize using packed encoding
+//!
+//! ```rust
+//! use serde_derive::{Deserialize, Serialize};
+//! use serde_cbor::ser::to_vec_packed;
+//! use WithTwoVariants::*;
+//!
+//! #[derive(Debug, Serialize, Deserialize)]
+//! enum WithTwoVariants {
+//! FirstVariant,
+//! SecondVariant(u8),
+//! }
+//!
+//! let cbor = to_vec_packed(&FirstVariant).unwrap();
+//! assert_eq!(cbor.len(), 1);
+//!
+//! let cbor = to_vec_packed(&SecondVariant(0)).unwrap();
+//! assert_eq!(cbor.len(), 16); // Includes 13 bytes of "SecondVariant"
+//! ```
+//!
+//! Serialize using minimal encoding
+//!
+//! ```rust
+//! use serde_derive::{Deserialize, Serialize};
+//! use serde_cbor::{Result, Serializer, ser::{self, IoWrite}};
+//! use WithTwoVariants::*;
+//!
+//! fn to_vec_minimal<T>(value: &T) -> Result<Vec<u8>>
+//! where
+//! T: serde::Serialize,
+//! {
+//! let mut vec = Vec::new();
+//! value.serialize(&mut Serializer::new(&mut IoWrite::new(&mut vec)).packed_format().legacy_enums())?;
+//! Ok(vec)
+//! }
+//!
+//! #[derive(Debug, Serialize, Deserialize)]
+//! enum WithTwoVariants {
+//! FirstVariant,
+//! SecondVariant(u8),
+//! }
+//!
+//! let cbor = to_vec_minimal(&FirstVariant).unwrap();
+//! assert_eq!(cbor.len(), 1);
+//!
+//! let cbor = to_vec_minimal(&SecondVariant(0)).unwrap();
+//! assert_eq!(cbor.len(), 3);
+//! ```
+//!
+//! # `no-std` support
+//!
+//! Serde CBOR supports building in a `no_std` context, use the following lines
+//! in your `Cargo.toml` dependencies:
+//! ``` toml
+//! [dependencies]
+//! serde = { version = "1.0", default-features = false }
+//! serde_cbor = { version = "0.10", default-features = false }
+//! ```
+//!
+//! Without the `std` feature the functions [from_reader], [from_slice], [to_vec], and [to_writer]
+//! are not exported. To export [from_slice] and [to_vec] enable the `alloc` feature. The `alloc`
+//! feature uses the [`alloc` library][alloc-lib] and requires at least version 1.36.0 of Rust.
+//!
+//! [alloc-lib]: https://doc.rust-lang.org/alloc/
+//!
+//! *Note*: to use derive macros in serde you will need to declare `serde`
+//! dependency like so:
+//! ``` toml
+//! serde = { version = "1.0", default-features = false, features = ["derive"] }
+//! ```
+//!
+//! Serialize an object with `no_std` and without `alloc`.
+//! ``` rust
+//! # #[macro_use] extern crate serde_derive;
+//! # fn main() -> Result<(), serde_cbor::Error> {
+//! use serde::Serialize;
+//! use serde_cbor::Serializer;
+//! use serde_cbor::ser::SliceWrite;
+//!
+//! #[derive(Serialize)]
+//! struct User {
+//! user_id: u32,
+//! password_hash: [u8; 4],
+//! }
+//!
+//! let mut buf = [0u8; 100];
+//! let writer = SliceWrite::new(&mut buf[..]);
+//! let mut ser = Serializer::new(writer);
+//! let user = User {
+//! user_id: 42,
+//! password_hash: [1, 2, 3, 4],
+//! };
+//! user.serialize(&mut ser)?;
+//! let writer = ser.into_inner();
+//! let size = writer.bytes_written();
+//! let expected = [
+//! 0xa2, 0x67, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x2a, 0x6d,
+//! 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73,
+//! 0x68, 0x84, 0x1, 0x2, 0x3, 0x4
+//! ];
+//! assert_eq!(&buf[..size], expected);
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! Deserialize an object.
+//! ``` rust
+//! # #[macro_use] extern crate serde_derive;
+//! # fn main() -> Result<(), serde_cbor::Error> {
+//! #[derive(Debug, PartialEq, Deserialize)]
+//! struct User {
+//! user_id: u32,
+//! password_hash: [u8; 4],
+//! }
+//!
+//! let value = [
+//! 0xa2, 0x67, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x2a, 0x6d,
+//! 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73,
+//! 0x68, 0x84, 0x1, 0x2, 0x3, 0x4
+//! ];
+//!
+//! // from_slice_with_scratch will not alter input data, use it whenever you
+//! // borrow from somewhere else.
+//! // You will have to size your scratch according to the input data you
+//! // expect.
+//! use serde_cbor::de::from_slice_with_scratch;
+//! let mut scratch = [0u8; 32];
+//! let user: User = from_slice_with_scratch(&value[..], &mut scratch)?;
+//! assert_eq!(user, User {
+//! user_id: 42,
+//! password_hash: [1, 2, 3, 4],
+//! });
+//!
+//! let mut value = [
+//! 0xa2, 0x67, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x2a, 0x6d,
+//! 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73,
+//! 0x68, 0x84, 0x1, 0x2, 0x3, 0x4
+//! ];
+//!
+//! // from_mut_slice will move data around the input slice, you may only use it
+//! // on data you may own or can modify.
+//! use serde_cbor::de::from_mut_slice;
+//! let user: User = from_mut_slice(&mut value[..])?;
+//! assert_eq!(user, User {
+//! user_id: 42,
+//! password_hash: [1, 2, 3, 4],
+//! });
+//! # Ok(())
+//! # }
+//! ```
+//!
+//! # Limitations
+//!
+//! While Serde CBOR strives to support all features of Serde and CBOR
+//! there are a few limitations.
+//!
+//! * [Tags] are ignored during deserialization and can't be emitted during
+//! serialization. This is because Serde has no concept of tagged
+//! values. See:&nbsp;[#3]
+//! * Unknown [simple values] cause an `UnassignedCode` error.
+//! The simple values *False* and *True* are recognized and parsed as bool.
+//! *Null* and *Undefined* are both deserialized as *unit*.
+//! The *unit* type is serialized as *Null*. See:&nbsp;[#86]
+//! * [128-bit integers] can't be directly encoded in CBOR. If you need them
+//! store them as a byte string. See:&nbsp;[#77]
+//!
+//! [Tags]: https://tools.ietf.org/html/rfc7049#section-2.4.4
+//! [#3]: https://github.com/pyfisch/cbor/issues/3
+//! [simple values]: https://tools.ietf.org/html/rfc7049#section-3.5
+//! [#86]: https://github.com/pyfisch/cbor/issues/86
+//! [128-bit integers]: https://doc.rust-lang.org/std/primitive.u128.html
+//! [#77]: https://github.com/pyfisch/cbor/issues/77
+
+#![deny(missing_docs)]
+#![cfg_attr(not(feature = "std"), no_std)]
+
+// When we are running tests in no_std mode we need to explicitly link std, because `cargo test`
+// will not work without it.
+#[cfg(all(not(feature = "std"), test))]
+extern crate std;
+
+#[cfg(feature = "alloc")]
+extern crate alloc;
+
+pub mod de;
+pub mod error;
+mod read;
+pub mod ser;
+pub mod tags;
+mod write;
+
+#[cfg(feature = "std")]
+pub mod value;
+
+// Re-export the [items recommended by serde](https://serde.rs/conventions.html).
+#[doc(inline)]
+pub use crate::de::{Deserializer, StreamDeserializer};
+
+#[doc(inline)]
+pub use crate::error::{Error, Result};
+
+#[doc(inline)]
+pub use crate::ser::Serializer;
+
+// Convenience functions for serialization and deserialization.
+// These functions are only available in `std` mode.
+#[cfg(feature = "std")]
+#[doc(inline)]
+pub use crate::de::from_reader;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+#[doc(inline)]
+pub use crate::de::from_slice;
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+#[doc(inline)]
+pub use crate::ser::to_vec;
+
+#[cfg(feature = "std")]
+#[doc(inline)]
+pub use crate::ser::to_writer;
+
+// Re-export the value type like serde_json
+#[cfg(feature = "std")]
+#[doc(inline)]
+pub use crate::value::Value;
diff --git a/third_party/rust/serde_cbor/src/read.rs b/third_party/rust/serde_cbor/src/read.rs
new file mode 100644
index 0000000000..1b53018df8
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/read.rs
@@ -0,0 +1,637 @@
+#[cfg(feature = "alloc")]
+use alloc::{vec, vec::Vec};
+#[cfg(feature = "std")]
+use core::cmp;
+use core::mem;
+
+#[cfg(feature = "std")]
+use std::io::{self, Read as StdRead};
+
+use crate::error::{Error, ErrorCode, Result};
+
+#[cfg(not(feature = "unsealed_read_write"))]
+/// Trait used by the deserializer for iterating over input.
+///
+/// This trait is sealed by default, enabling the `unsealed_read_write` feature removes this bound
+/// to allow objects outside of this crate to implement this trait.
+pub trait Read<'de>: private::Sealed {
+ #[doc(hidden)]
+ /// Read n bytes from the input.
+ ///
+ /// Implementations that can are asked to return a slice with a Long lifetime that outlives the
+ /// decoder, but others (eg. ones that need to allocate the data into a temporary buffer) can
+ /// return it with a Short lifetime that just lives for the time of read's mutable borrow of
+ /// the reader.
+ ///
+ /// This may, as a side effect, clear the reader's scratch buffer (as the provided
+ /// implementation does).
+
+ // A more appropriate lifetime setup for this (that would allow the Deserializer::convert_str
+ // to stay a function) would be something like `fn read<'a, 'r: 'a>(&'a mut 'r immut self, ...) -> ...
+ // EitherLifetime<'r, 'de>>`, which borrows self mutably for the duration of the function and
+ // downgrates that reference to an immutable one that outlives the result (protecting the
+ // scratch buffer from changes), but alas, that can't be expressed (yet?).
+ fn read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>> {
+ self.clear_buffer();
+ self.read_to_buffer(n)?;
+
+ Ok(self.take_buffer())
+ }
+
+ #[doc(hidden)]
+ fn next(&mut self) -> Result<Option<u8>>;
+
+ #[doc(hidden)]
+ fn peek(&mut self) -> Result<Option<u8>>;
+
+ #[doc(hidden)]
+ fn clear_buffer(&mut self);
+
+ #[doc(hidden)]
+ fn read_to_buffer(&mut self, n: usize) -> Result<()>;
+
+ #[doc(hidden)]
+ fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>;
+
+ #[doc(hidden)]
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()>;
+
+ #[doc(hidden)]
+ fn discard(&mut self);
+
+ #[doc(hidden)]
+ fn offset(&self) -> u64;
+}
+
+#[cfg(feature = "unsealed_read_write")]
+/// Trait used by the deserializer for iterating over input.
+pub trait Read<'de> {
+ /// Read n bytes from the input.
+ ///
+ /// Implementations that can are asked to return a slice with a Long lifetime that outlives the
+ /// decoder, but others (eg. ones that need to allocate the data into a temporary buffer) can
+ /// return it with a Short lifetime that just lives for the time of read's mutable borrow of
+ /// the reader.
+ ///
+ /// This may, as a side effect, clear the reader's scratch buffer (as the provided
+ /// implementation does).
+
+ // A more appropriate lifetime setup for this (that would allow the Deserializer::convert_str
+ // to stay a function) would be something like `fn read<'a, 'r: 'a>(&'a mut 'r immut self, ...) -> ...
+ // EitherLifetime<'r, 'de>>`, which borrows self mutably for the duration of the function and
+ // downgrates that reference to an immutable one that outlives the result (protecting the
+ // scratch buffer from changes), but alas, that can't be expressed (yet?).
+ fn read<'a>(&'a mut self, n: usize) -> Result<EitherLifetime<'a, 'de>> {
+ self.clear_buffer();
+ self.read_to_buffer(n)?;
+
+ Ok(self.take_buffer())
+ }
+
+ /// Read the next byte from the input, if any.
+ fn next(&mut self) -> Result<Option<u8>>;
+
+ /// Peek at the next byte of the input, if any. This does not advance the reader, so the result
+ /// of this function will remain the same until a read or clear occurs.
+ fn peek(&mut self) -> Result<Option<u8>>;
+
+ /// Clear the underlying scratch buffer
+ fn clear_buffer(&mut self);
+
+ /// Append n bytes from the reader to the reader's scratch buffer (without clearing it)
+ fn read_to_buffer(&mut self, n: usize) -> Result<()>;
+
+ /// Read out everything accumulated in the reader's scratch buffer. This may, as a side effect,
+ /// clear it.
+ fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de>;
+
+ /// Read from the input until `buf` is full or end of input is encountered.
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()>;
+
+ /// Discard any data read by `peek`.
+ fn discard(&mut self);
+
+ /// Returns the offset from the start of the reader.
+ fn offset(&self) -> u64;
+}
+
+/// Represents a reader that can return its current position
+pub trait Offset {
+ fn byte_offset(&self) -> usize;
+}
+
+/// Represents a buffer with one of two lifetimes.
+pub enum EitherLifetime<'short, 'long> {
+ /// The short lifetime
+ Short(&'short [u8]),
+ /// The long lifetime
+ Long(&'long [u8]),
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+mod private {
+ pub trait Sealed {}
+}
+
+/// CBOR input source that reads from a std::io input stream.
+#[cfg(feature = "std")]
+#[derive(Debug)]
+pub struct IoRead<R>
+where
+ R: io::Read,
+{
+ reader: OffsetReader<R>,
+ scratch: Vec<u8>,
+ ch: Option<u8>,
+}
+
+#[cfg(feature = "std")]
+impl<R> IoRead<R>
+where
+ R: io::Read,
+{
+ /// Creates a new CBOR input source to read from a std::io input stream.
+ pub fn new(reader: R) -> IoRead<R> {
+ IoRead {
+ reader: OffsetReader { reader, offset: 0 },
+ scratch: vec![],
+ ch: None,
+ }
+ }
+
+ #[inline]
+ fn next_inner(&mut self) -> Result<Option<u8>> {
+ let mut buf = [0; 1];
+ loop {
+ match self.reader.read(&mut buf) {
+ Ok(0) => return Ok(None),
+ Ok(_) => return Ok(Some(buf[0])),
+ Err(ref e) if e.kind() == io::ErrorKind::Interrupted => {}
+ Err(e) => return Err(Error::io(e)),
+ }
+ }
+ }
+}
+
+#[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
+impl<R> private::Sealed for IoRead<R> where R: io::Read {}
+
+#[cfg(feature = "std")]
+impl<'de, R> Read<'de> for IoRead<R>
+where
+ R: io::Read,
+{
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ match self.ch.take() {
+ Some(ch) => Ok(Some(ch)),
+ None => self.next_inner(),
+ }
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ match self.ch {
+ Some(ch) => Ok(Some(ch)),
+ None => {
+ self.ch = self.next_inner()?;
+ Ok(self.ch)
+ }
+ }
+ }
+
+ fn read_to_buffer(&mut self, mut n: usize) -> Result<()> {
+ // defend against malicious input pretending to be huge strings by limiting growth
+ self.scratch.reserve(cmp::min(n, 16 * 1024));
+
+ if n == 0 {
+ return Ok(());
+ }
+
+ if let Some(ch) = self.ch.take() {
+ self.scratch.push(ch);
+ n -= 1;
+ }
+
+ // n == 0 is OK here and needs no further special treatment
+
+ let transfer_result = {
+ // Prepare for take() (which consumes its reader) by creating a reference adaptor
+ // that'll only live in this block
+ let reference = self.reader.by_ref();
+ // Append the first n bytes of the reader to the scratch vector (or up to
+ // an error or EOF indicated by a shorter read)
+ let mut taken = reference.take(n as u64);
+ taken.read_to_end(&mut self.scratch)
+ };
+
+ match transfer_result {
+ Ok(r) if r == n => Ok(()),
+ Ok(_) => Err(Error::syntax(
+ ErrorCode::EofWhileParsingValue,
+ self.offset(),
+ )),
+ Err(e) => Err(Error::io(e)),
+ }
+ }
+
+ fn clear_buffer(&mut self) {
+ self.scratch.clear();
+ }
+
+ fn take_buffer<'a>(&'a mut self) -> EitherLifetime<'a, 'de> {
+ EitherLifetime::Short(&self.scratch)
+ }
+
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
+ self.reader.read_exact(buf).map_err(|e| {
+ if e.kind() == io::ErrorKind::UnexpectedEof {
+ Error::syntax(ErrorCode::EofWhileParsingValue, self.offset())
+ } else {
+ Error::io(e)
+ }
+ })
+ }
+
+ #[inline]
+ fn discard(&mut self) {
+ self.ch = None;
+ }
+
+ fn offset(&self) -> u64 {
+ self.reader.offset
+ }
+}
+
+#[cfg(feature = "std")]
+impl<R> Offset for IoRead<R>
+where
+ R: std::io::Read,
+{
+ fn byte_offset(&self) -> usize {
+ self.offset() as usize
+ }
+}
+
+#[cfg(feature = "std")]
+#[derive(Debug)]
+struct OffsetReader<R> {
+ reader: R,
+ offset: u64,
+}
+
+#[cfg(feature = "std")]
+impl<R> io::Read for OffsetReader<R>
+where
+ R: io::Read,
+{
+ #[inline]
+ fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
+ let r = self.reader.read(buf);
+ if let Ok(count) = r {
+ self.offset += count as u64;
+ }
+ r
+ }
+}
+
+/// A CBOR input source that reads from a slice of bytes.
+#[cfg(any(feature = "std", feature = "alloc"))]
+#[derive(Debug)]
+pub struct SliceRead<'a> {
+ slice: &'a [u8],
+ scratch: Vec<u8>,
+ index: usize,
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a> SliceRead<'a> {
+ /// Creates a CBOR input source to read from a slice of bytes.
+ pub fn new(slice: &'a [u8]) -> SliceRead<'a> {
+ SliceRead {
+ slice,
+ scratch: vec![],
+ index: 0,
+ }
+ }
+
+ fn end(&self, n: usize) -> Result<usize> {
+ match self.index.checked_add(n) {
+ Some(end) if end <= self.slice.len() => Ok(end),
+ _ => Err(Error::syntax(
+ ErrorCode::EofWhileParsingValue,
+ self.slice.len() as u64,
+ )),
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a> Offset for SliceRead<'a> {
+ #[inline]
+ fn byte_offset(&self) -> usize {
+ self.index
+ }
+}
+
+#[cfg(all(
+ any(feature = "std", feature = "alloc"),
+ not(feature = "unsealed_read_write")
+))]
+impl<'a> private::Sealed for SliceRead<'a> {}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a> Read<'a> for SliceRead<'a> {
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ Ok(if self.index < self.slice.len() {
+ let ch = self.slice[self.index];
+ self.index += 1;
+ Some(ch)
+ } else {
+ None
+ })
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ Ok(if self.index < self.slice.len() {
+ Some(self.slice[self.index])
+ } else {
+ None
+ })
+ }
+
+ fn clear_buffer(&mut self) {
+ self.scratch.clear();
+ }
+
+ fn read_to_buffer(&mut self, n: usize) -> Result<()> {
+ let end = self.end(n)?;
+ let slice = &self.slice[self.index..end];
+ self.scratch.extend_from_slice(slice);
+ self.index = end;
+
+ Ok(())
+ }
+
+ #[inline]
+ fn read<'b>(&'b mut self, n: usize) -> Result<EitherLifetime<'b, 'a>> {
+ let end = self.end(n)?;
+ let slice = &self.slice[self.index..end];
+ self.index = end;
+ Ok(EitherLifetime::Long(slice))
+ }
+
+ fn take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a> {
+ EitherLifetime::Short(&self.scratch)
+ }
+
+ #[inline]
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
+ let end = self.end(buf.len())?;
+ buf.copy_from_slice(&self.slice[self.index..end]);
+ self.index = end;
+ Ok(())
+ }
+
+ #[inline]
+ fn discard(&mut self) {
+ self.index += 1;
+ }
+
+ fn offset(&self) -> u64 {
+ self.index as u64
+ }
+}
+
+/// A CBOR input source that reads from a slice of bytes using a fixed size scratch buffer.
+///
+/// [`SliceRead`](struct.SliceRead.html) and [`MutSliceRead`](struct.MutSliceRead.html) are usually
+/// preferred over this, as they can handle indefinite length items.
+#[derive(Debug)]
+pub struct SliceReadFixed<'a, 'b> {
+ slice: &'a [u8],
+ scratch: &'b mut [u8],
+ index: usize,
+ scratch_index: usize,
+}
+
+impl<'a, 'b> SliceReadFixed<'a, 'b> {
+ /// Creates a CBOR input source to read from a slice of bytes, backed by a scratch buffer.
+ pub fn new(slice: &'a [u8], scratch: &'b mut [u8]) -> SliceReadFixed<'a, 'b> {
+ SliceReadFixed {
+ slice,
+ scratch,
+ index: 0,
+ scratch_index: 0,
+ }
+ }
+
+ fn end(&self, n: usize) -> Result<usize> {
+ match self.index.checked_add(n) {
+ Some(end) if end <= self.slice.len() => Ok(end),
+ _ => Err(Error::syntax(
+ ErrorCode::EofWhileParsingValue,
+ self.slice.len() as u64,
+ )),
+ }
+ }
+
+ fn scratch_end(&self, n: usize) -> Result<usize> {
+ match self.scratch_index.checked_add(n) {
+ Some(end) if end <= self.scratch.len() => Ok(end),
+ _ => Err(Error::scratch_too_small(self.index as u64)),
+ }
+ }
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+impl<'a, 'b> private::Sealed for SliceReadFixed<'a, 'b> {}
+
+impl<'a, 'b> Read<'a> for SliceReadFixed<'a, 'b> {
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ Ok(if self.index < self.slice.len() {
+ let ch = self.slice[self.index];
+ self.index += 1;
+ Some(ch)
+ } else {
+ None
+ })
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ Ok(if self.index < self.slice.len() {
+ Some(self.slice[self.index])
+ } else {
+ None
+ })
+ }
+
+ fn clear_buffer(&mut self) {
+ self.scratch_index = 0;
+ }
+
+ fn read_to_buffer(&mut self, n: usize) -> Result<()> {
+ let end = self.end(n)?;
+ let scratch_end = self.scratch_end(n)?;
+ let slice = &self.slice[self.index..end];
+ self.scratch[self.scratch_index..scratch_end].copy_from_slice(&slice);
+ self.index = end;
+ self.scratch_index = scratch_end;
+
+ Ok(())
+ }
+
+ fn read<'c>(&'c mut self, n: usize) -> Result<EitherLifetime<'c, 'a>> {
+ let end = self.end(n)?;
+ let slice = &self.slice[self.index..end];
+ self.index = end;
+ Ok(EitherLifetime::Long(slice))
+ }
+
+ fn take_buffer<'c>(&'c mut self) -> EitherLifetime<'c, 'a> {
+ EitherLifetime::Short(&self.scratch[0..self.scratch_index])
+ }
+
+ #[inline]
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
+ let end = self.end(buf.len())?;
+ buf.copy_from_slice(&self.slice[self.index..end]);
+ self.index = end;
+ Ok(())
+ }
+
+ #[inline]
+ fn discard(&mut self) {
+ self.index += 1;
+ }
+
+ fn offset(&self) -> u64 {
+ self.index as u64
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'b> Offset for SliceReadFixed<'a, 'b> {
+ #[inline]
+ fn byte_offset(&self) -> usize {
+ self.index
+ }
+}
+
+/// A CBOR input source that reads from a slice of bytes, and can move data around internally to
+/// reassemble indefinite strings without the need of an allocated scratch buffer.
+#[derive(Debug)]
+pub struct MutSliceRead<'a> {
+ /// A complete view of the reader's data. It is promised that bytes before buffer_end are not
+ /// mutated any more.
+ slice: &'a mut [u8],
+ /// Read cursor position in slice
+ index: usize,
+ /// Number of bytes already discarded from the slice
+ before: usize,
+ /// End of the buffer area that contains all bytes read_into_buffer. This is always <= index.
+ buffer_end: usize,
+}
+
+impl<'a> MutSliceRead<'a> {
+ /// Creates a CBOR input source to read from a slice of bytes.
+ pub fn new(slice: &'a mut [u8]) -> MutSliceRead<'a> {
+ MutSliceRead {
+ slice,
+ index: 0,
+ before: 0,
+ buffer_end: 0,
+ }
+ }
+
+ fn end(&self, n: usize) -> Result<usize> {
+ match self.index.checked_add(n) {
+ Some(end) if end <= self.slice.len() => Ok(end),
+ _ => Err(Error::syntax(
+ ErrorCode::EofWhileParsingValue,
+ self.slice.len() as u64,
+ )),
+ }
+ }
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+impl<'a> private::Sealed for MutSliceRead<'a> {}
+
+impl<'a> Read<'a> for MutSliceRead<'a> {
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ // This is duplicated from SliceRead, can that be eased?
+ Ok(if self.index < self.slice.len() {
+ let ch = self.slice[self.index];
+ self.index += 1;
+ Some(ch)
+ } else {
+ None
+ })
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ // This is duplicated from SliceRead, can that be eased?
+ Ok(if self.index < self.slice.len() {
+ Some(self.slice[self.index])
+ } else {
+ None
+ })
+ }
+
+ fn clear_buffer(&mut self) {
+ self.slice = &mut mem::replace(&mut self.slice, &mut [])[self.index..];
+ self.before += self.index;
+ self.index = 0;
+ self.buffer_end = 0;
+ }
+
+ fn read_to_buffer(&mut self, n: usize) -> Result<()> {
+ let end = self.end(n)?;
+ debug_assert!(
+ self.buffer_end <= self.index,
+ "MutSliceRead invariant violated: scratch buffer exceeds index"
+ );
+ self.slice[self.buffer_end..end].rotate_left(self.index - self.buffer_end);
+ self.buffer_end += n;
+ self.index = end;
+
+ Ok(())
+ }
+
+ fn take_buffer<'b>(&'b mut self) -> EitherLifetime<'b, 'a> {
+ let (left, right) = mem::replace(&mut self.slice, &mut []).split_at_mut(self.index);
+ self.slice = right;
+ self.before += self.index;
+ self.index = 0;
+
+ let left = &left[..self.buffer_end];
+ self.buffer_end = 0;
+
+ EitherLifetime::Long(left)
+ }
+
+ #[inline]
+ fn read_into(&mut self, buf: &mut [u8]) -> Result<()> {
+ // This is duplicated from SliceRead, can that be eased?
+ let end = self.end(buf.len())?;
+ buf.copy_from_slice(&self.slice[self.index..end]);
+ self.index = end;
+ Ok(())
+ }
+
+ #[inline]
+ fn discard(&mut self) {
+ self.index += 1;
+ }
+
+ fn offset(&self) -> u64 {
+ (self.before + self.index) as u64
+ }
+}
diff --git a/third_party/rust/serde_cbor/src/ser.rs b/third_party/rust/serde_cbor/src/ser.rs
new file mode 100644
index 0000000000..7016dc340a
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/ser.rs
@@ -0,0 +1,743 @@
+//! Serialize a Rust data structure to CBOR data.
+
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+
+#[cfg(feature = "std")]
+pub use crate::write::IoWrite;
+pub use crate::write::{SliceWrite, Write};
+
+use crate::error::{Error, Result};
+use half::f16;
+use serde::ser::{self, Serialize};
+#[cfg(feature = "std")]
+use std::io;
+
+use crate::tags::{get_tag, CBOR_NEWTYPE_NAME};
+
+/// Serializes a value to a vector.
+#[cfg(any(feature = "std", feature = "alloc"))]
+pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
+where
+ T: ser::Serialize,
+{
+ let mut vec = Vec::new();
+ value.serialize(&mut Serializer::new(&mut vec))?;
+ Ok(vec)
+}
+
+/// Serializes a value to a vector in packed format.
+#[cfg(feature = "std")]
+pub fn to_vec_packed<T>(value: &T) -> Result<Vec<u8>>
+where
+ T: ser::Serialize,
+{
+ let mut vec = Vec::new();
+ value.serialize(&mut Serializer::new(&mut IoWrite::new(&mut vec)).packed_format())?;
+ Ok(vec)
+}
+
+/// Serializes a value to a writer.
+#[cfg(feature = "std")]
+pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
+where
+ W: io::Write,
+ T: ser::Serialize,
+{
+ value.serialize(&mut Serializer::new(&mut IoWrite::new(writer)))
+}
+
+/// A structure for serializing Rust values to CBOR.
+#[derive(Debug)]
+pub struct Serializer<W> {
+ writer: W,
+ packed: bool,
+ enum_as_map: bool,
+}
+
+impl<W> Serializer<W>
+where
+ W: Write,
+{
+ /// Creates a new CBOR serializer.
+ ///
+ /// `to_vec` and `to_writer` should normally be used instead of this method.
+ #[inline]
+ pub fn new(writer: W) -> Self {
+ Serializer {
+ writer,
+ packed: false,
+ enum_as_map: true,
+ }
+ }
+
+ /// Choose concise/packed format for serializer.
+ ///
+ /// In the packed format enum variant names and field names
+ /// are replaced with numeric indizes to conserve space.
+ pub fn packed_format(mut self) -> Self {
+ self.packed = true;
+ self
+ }
+
+ /// Enable old enum format used by `serde_cbor` versions <= v0.9.
+ ///
+ /// The `legacy_enums` option determines how enums are encoded.
+ ///
+ /// This makes no difference when encoding and decoding enums using
+ /// this crate, but it shows up when decoding to a `Value` or decoding
+ /// in other languages.
+ ///
+ /// # Examples
+ ///
+ /// Given the following enum
+ ///
+ /// ```rust
+ /// enum Enum {
+ /// Unit,
+ /// NewType(i32),
+ /// Tuple(String, bool),
+ /// Struct{ x: i32, y: i32 },
+ /// }
+ /// ```
+ /// we will give the `Value` with the same encoding for each case using
+ /// JSON notation.
+ ///
+ /// ## Default encodings
+ ///
+ /// * `Enum::Unit` encodes as `"Unit"`
+ /// * `Enum::NewType(10)` encodes as `{"NewType": 10}`
+ /// * `Enum::Tuple("x", true)` encodes as `{"Tuple": ["x", true]}`
+ ///
+ /// ## Legacy encodings
+ ///
+ /// * `Enum::Unit` encodes as `"Unit"`
+ /// * `Enum::NewType(10)` encodes as `["NewType", 10]`
+ /// * `Enum::Tuple("x", true)` encodes as `["Tuple", "x", true]`
+ /// * `Enum::Struct{ x: 5, y: -5 }` encodes as `["Struct", {"x": 5, "y": -5}]`
+ pub fn legacy_enums(mut self) -> Self {
+ self.enum_as_map = false;
+ self
+ }
+
+ /// Writes a CBOR self-describe tag to the stream.
+ ///
+ /// Tagging allows a decoder to distinguish different file formats based on their content
+ /// without further information.
+ #[inline]
+ pub fn self_describe(&mut self) -> Result<()> {
+ let mut buf = [6 << 5 | 25, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&55799u16.to_be_bytes());
+ self.writer.write_all(&buf).map_err(|e| e.into())
+ }
+
+ /// Unwrap the `Writer` from the `Serializer`.
+ #[inline]
+ pub fn into_inner(self) -> W {
+ self.writer
+ }
+
+ #[inline]
+ fn write_u8(&mut self, major: u8, value: u8) -> Result<()> {
+ if value <= 0x17 {
+ self.writer.write_all(&[major << 5 | value])
+ } else {
+ let buf = [major << 5 | 24, value];
+ self.writer.write_all(&buf)
+ }
+ .map_err(|e| e.into())
+ }
+
+ #[inline]
+ fn write_u16(&mut self, major: u8, value: u16) -> Result<()> {
+ if value <= u16::from(u8::max_value()) {
+ self.write_u8(major, value as u8)
+ } else {
+ let mut buf = [major << 5 | 25, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&value.to_be_bytes());
+ self.writer.write_all(&buf).map_err(|e| e.into())
+ }
+ }
+
+ #[inline]
+ fn write_u32(&mut self, major: u8, value: u32) -> Result<()> {
+ if value <= u32::from(u16::max_value()) {
+ self.write_u16(major, value as u16)
+ } else {
+ let mut buf = [major << 5 | 26, 0, 0, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&value.to_be_bytes());
+ self.writer.write_all(&buf).map_err(|e| e.into())
+ }
+ }
+
+ #[inline]
+ fn write_u64(&mut self, major: u8, value: u64) -> Result<()> {
+ if value <= u64::from(u32::max_value()) {
+ self.write_u32(major, value as u32)
+ } else {
+ let mut buf = [major << 5 | 27, 0, 0, 0, 0, 0, 0, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&value.to_be_bytes());
+ self.writer.write_all(&buf).map_err(|e| e.into())
+ }
+ }
+
+ #[inline]
+ fn serialize_collection<'a>(
+ &'a mut self,
+ major: u8,
+ len: Option<usize>,
+ ) -> Result<CollectionSerializer<'a, W>> {
+ let needs_eof = match len {
+ Some(len) => {
+ self.write_u64(major, len as u64)?;
+ false
+ }
+ None => {
+ self.writer
+ .write_all(&[major << 5 | 31])
+ .map_err(|e| e.into())?;
+ true
+ }
+ };
+
+ Ok(CollectionSerializer {
+ ser: self,
+ needs_eof,
+ })
+ }
+}
+
+impl<'a, W> ser::Serializer for &'a mut Serializer<W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ type SerializeSeq = CollectionSerializer<'a, W>;
+ type SerializeTuple = &'a mut Serializer<W>;
+ type SerializeTupleStruct = &'a mut Serializer<W>;
+ type SerializeTupleVariant = &'a mut Serializer<W>;
+ type SerializeMap = CollectionSerializer<'a, W>;
+ type SerializeStruct = StructSerializer<'a, W>;
+ type SerializeStructVariant = StructSerializer<'a, W>;
+
+ #[inline]
+ fn serialize_bool(self, value: bool) -> Result<()> {
+ let value = if value { 0xf5 } else { 0xf4 };
+ self.writer.write_all(&[value]).map_err(|e| e.into())
+ }
+
+ #[inline]
+ fn serialize_i8(self, value: i8) -> Result<()> {
+ if value < 0 {
+ self.write_u8(1, -(value + 1) as u8)
+ } else {
+ self.write_u8(0, value as u8)
+ }
+ }
+
+ #[inline]
+ fn serialize_i16(self, value: i16) -> Result<()> {
+ if value < 0 {
+ self.write_u16(1, -(value + 1) as u16)
+ } else {
+ self.write_u16(0, value as u16)
+ }
+ }
+
+ #[inline]
+ fn serialize_i32(self, value: i32) -> Result<()> {
+ if value < 0 {
+ self.write_u32(1, -(value + 1) as u32)
+ } else {
+ self.write_u32(0, value as u32)
+ }
+ }
+
+ #[inline]
+ fn serialize_i64(self, value: i64) -> Result<()> {
+ if value < 0 {
+ self.write_u64(1, -(value + 1) as u64)
+ } else {
+ self.write_u64(0, value as u64)
+ }
+ }
+
+ #[inline]
+ fn serialize_i128(self, value: i128) -> Result<()> {
+ if value < 0 {
+ if -(value + 1) > i128::from(u64::max_value()) {
+ return Err(Error::message("The number can't be stored in CBOR"));
+ }
+ self.write_u64(1, -(value + 1) as u64)
+ } else {
+ if value > i128::from(u64::max_value()) {
+ return Err(Error::message("The number can't be stored in CBOR"));
+ }
+ self.write_u64(0, value as u64)
+ }
+ }
+
+ #[inline]
+ fn serialize_u8(self, value: u8) -> Result<()> {
+ self.write_u8(0, value)
+ }
+
+ #[inline]
+ fn serialize_u16(self, value: u16) -> Result<()> {
+ self.write_u16(0, value)
+ }
+
+ #[inline]
+ fn serialize_u32(self, value: u32) -> Result<()> {
+ self.write_u32(0, value)
+ }
+
+ #[inline]
+ fn serialize_u64(self, value: u64) -> Result<()> {
+ self.write_u64(0, value)
+ }
+
+ #[inline]
+ fn serialize_u128(self, value: u128) -> Result<()> {
+ if value > u128::from(u64::max_value()) {
+ return Err(Error::message("The number can't be stored in CBOR"));
+ }
+ self.write_u64(0, value as u64)
+ }
+
+ #[inline]
+ #[allow(clippy::float_cmp)]
+ fn serialize_f32(self, value: f32) -> Result<()> {
+ if value.is_infinite() {
+ if value.is_sign_positive() {
+ self.writer.write_all(&[0xf9, 0x7c, 0x00])
+ } else {
+ self.writer.write_all(&[0xf9, 0xfc, 0x00])
+ }
+ } else if value.is_nan() {
+ self.writer.write_all(&[0xf9, 0x7e, 0x00])
+ } else if f32::from(f16::from_f32(value)) == value {
+ let mut buf = [0xf9, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&f16::from_f32(value).to_bits().to_be_bytes());
+ self.writer.write_all(&buf)
+ } else {
+ let mut buf = [0xfa, 0, 0, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&value.to_bits().to_be_bytes());
+ self.writer.write_all(&buf)
+ }
+ .map_err(|e| e.into())
+ }
+
+ #[inline]
+ #[allow(clippy::float_cmp)]
+ fn serialize_f64(self, value: f64) -> Result<()> {
+ if !value.is_finite() || f64::from(value as f32) == value {
+ self.serialize_f32(value as f32)
+ } else {
+ let mut buf = [0xfb, 0, 0, 0, 0, 0, 0, 0, 0];
+ (&mut buf[1..]).copy_from_slice(&value.to_bits().to_be_bytes());
+ self.writer.write_all(&buf).map_err(|e| e.into())
+ }
+ }
+
+ #[inline]
+ fn serialize_char(self, value: char) -> Result<()> {
+ // A char encoded as UTF-8 takes 4 bytes at most.
+ let mut buf = [0; 4];
+ self.serialize_str(value.encode_utf8(&mut buf))
+ }
+
+ #[inline]
+ fn serialize_str(self, value: &str) -> Result<()> {
+ self.write_u64(3, value.len() as u64)?;
+ self.writer
+ .write_all(value.as_bytes())
+ .map_err(|e| e.into())
+ }
+
+ #[inline]
+ fn serialize_bytes(self, value: &[u8]) -> Result<()> {
+ self.write_u64(2, value.len() as u64)?;
+ self.writer.write_all(value).map_err(|e| e.into())
+ }
+
+ #[inline]
+ fn serialize_unit(self) -> Result<()> {
+ self.serialize_none()
+ }
+
+ #[inline]
+ fn serialize_some<T>(self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(self)
+ }
+
+ #[inline]
+ fn serialize_none(self) -> Result<()> {
+ self.writer.write_all(&[0xf6]).map_err(|e| e.into())
+ }
+
+ #[inline]
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ ) -> Result<()> {
+ if self.packed {
+ self.serialize_u32(variant_index)
+ } else {
+ self.serialize_str(variant)
+ }
+ }
+
+ #[inline]
+ fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ if name == CBOR_NEWTYPE_NAME {
+ for tag in get_tag().into_iter() {
+ self.write_u64(6, tag)?;
+ }
+ }
+ value.serialize(self)
+ }
+
+ #[inline]
+ fn serialize_newtype_variant<T>(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ if self.enum_as_map {
+ self.write_u64(5, 1u64)?;
+ variant.serialize(&mut *self)?;
+ } else {
+ self.writer.write_all(&[4 << 5 | 2]).map_err(|e| e.into())?;
+ self.serialize_unit_variant(name, variant_index, variant)?;
+ }
+ value.serialize(self)
+ }
+
+ #[inline]
+ fn serialize_seq(self, len: Option<usize>) -> Result<CollectionSerializer<'a, W>> {
+ self.serialize_collection(4, len)
+ }
+
+ #[inline]
+ fn serialize_tuple(self, len: usize) -> Result<&'a mut Serializer<W>> {
+ self.write_u64(4, len as u64)?;
+ Ok(self)
+ }
+
+ #[inline]
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<&'a mut Serializer<W>> {
+ self.serialize_tuple(len)
+ }
+
+ #[inline]
+ fn serialize_tuple_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<&'a mut Serializer<W>> {
+ if self.enum_as_map {
+ self.write_u64(5, 1u64)?;
+ variant.serialize(&mut *self)?;
+ self.serialize_tuple(len)
+ } else {
+ self.write_u64(4, (len + 1) as u64)?;
+ self.serialize_unit_variant(name, variant_index, variant)?;
+ Ok(self)
+ }
+ }
+
+ #[inline]
+ fn serialize_map(self, len: Option<usize>) -> Result<CollectionSerializer<'a, W>> {
+ self.serialize_collection(5, len)
+ }
+
+ #[cfg(not(feature = "std"))]
+ fn collect_str<T: ?Sized>(self, value: &T) -> Result<()>
+ where
+ T: core::fmt::Display,
+ {
+ use crate::write::FmtWrite;
+ use core::fmt::Write;
+
+ let mut w = FmtWrite::new(&mut self.writer);
+ write!(w, "{}", value)?;
+ Ok(())
+ }
+
+ #[inline]
+ fn serialize_struct(self, _name: &'static str, len: usize) -> Result<StructSerializer<'a, W>> {
+ self.write_u64(5, len as u64)?;
+ Ok(StructSerializer { ser: self, idx: 0 })
+ }
+
+ #[inline]
+ fn serialize_struct_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<StructSerializer<'a, W>> {
+ if self.enum_as_map {
+ self.write_u64(5, 1u64)?;
+ } else {
+ self.writer.write_all(&[4 << 5 | 2]).map_err(|e| e.into())?;
+ }
+ self.serialize_unit_variant(name, variant_index, variant)?;
+ self.serialize_struct(name, len)
+ }
+
+ #[inline]
+ fn is_human_readable(&self) -> bool {
+ false
+ }
+}
+
+impl<'a, W> ser::SerializeTuple for &'a mut Serializer<W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(&mut **self)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ Ok(())
+ }
+}
+
+impl<'a, W> ser::SerializeTupleStruct for &'a mut Serializer<W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(&mut **self)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ Ok(())
+ }
+}
+
+impl<'a, W> ser::SerializeTupleVariant for &'a mut Serializer<W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(&mut **self)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ Ok(())
+ }
+}
+
+#[doc(hidden)]
+pub struct StructSerializer<'a, W> {
+ ser: &'a mut Serializer<W>,
+ idx: u32,
+}
+
+impl<'a, W> StructSerializer<'a, W>
+where
+ W: Write,
+{
+ #[inline]
+ fn serialize_field_inner<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ if self.ser.packed {
+ self.idx.serialize(&mut *self.ser)?;
+ } else {
+ key.serialize(&mut *self.ser)?;
+ }
+ value.serialize(&mut *self.ser)?;
+ self.idx += 1;
+ Ok(())
+ }
+
+ #[inline]
+ fn skip_field_inner(&mut self, _: &'static str) -> Result<()> {
+ self.idx += 1;
+ Ok(())
+ }
+
+ #[inline]
+ fn end_inner(self) -> Result<()> {
+ Ok(())
+ }
+}
+
+impl<'a, W> ser::SerializeStruct for StructSerializer<'a, W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.serialize_field_inner(key, value)
+ }
+
+ #[inline]
+ fn skip_field(&mut self, key: &'static str) -> Result<()> {
+ self.skip_field_inner(key)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ self.end_inner()
+ }
+}
+
+impl<'a, W> ser::SerializeStructVariant for StructSerializer<'a, W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.serialize_field_inner(key, value)
+ }
+
+ #[inline]
+ fn skip_field(&mut self, key: &'static str) -> Result<()> {
+ self.skip_field_inner(key)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ self.end_inner()
+ }
+}
+
+#[doc(hidden)]
+pub struct CollectionSerializer<'a, W> {
+ ser: &'a mut Serializer<W>,
+ needs_eof: bool,
+}
+
+impl<'a, W> CollectionSerializer<'a, W>
+where
+ W: Write,
+{
+ #[inline]
+ fn end_inner(self) -> Result<()> {
+ if self.needs_eof {
+ self.ser.writer.write_all(&[0xff]).map_err(|e| e.into())
+ } else {
+ Ok(())
+ }
+ }
+}
+
+impl<'a, W> ser::SerializeSeq for CollectionSerializer<'a, W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(&mut *self.ser)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ self.end_inner()
+ }
+}
+
+impl<'a, W> ser::SerializeMap for CollectionSerializer<'a, W>
+where
+ W: Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_key<T>(&mut self, key: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ key.serialize(&mut *self.ser)
+ }
+
+ #[inline]
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(&mut *self.ser)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ self.end_inner()
+ }
+}
diff --git a/third_party/rust/serde_cbor/src/tags.rs b/third_party/rust/serde_cbor/src/tags.rs
new file mode 100644
index 0000000000..8adccb8ea8
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/tags.rs
@@ -0,0 +1,220 @@
+//! Support for cbor tags
+use core::fmt;
+use core::marker::PhantomData;
+use serde::de::{
+ Deserialize, Deserializer, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, Visitor,
+};
+use serde::forward_to_deserialize_any;
+use serde::ser::{Serialize, Serializer};
+
+/// signals that a newtype is from a CBOR tag
+pub(crate) const CBOR_NEWTYPE_NAME: &str = "\0cbor_tag";
+
+/// A value that is optionally tagged with a cbor tag
+///
+/// this only serves as an intermediate helper for tag serialization or deserialization
+pub struct Tagged<T> {
+ /// cbor tag
+ pub tag: Option<u64>,
+ /// value
+ pub value: T,
+}
+
+impl<T> Tagged<T> {
+ /// Create a new tagged value
+ pub fn new(tag: Option<u64>, value: T) -> Self {
+ Self { tag, value }
+ }
+}
+
+impl<T: Serialize> Serialize for Tagged<T> {
+ fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
+ set_tag(self.tag);
+ let r = s.serialize_newtype_struct(CBOR_NEWTYPE_NAME, &self.value);
+ set_tag(None);
+ r
+ }
+}
+
+fn untagged<T>(value: T) -> Tagged<T> {
+ Tagged::new(None, value)
+}
+
+macro_rules! delegate {
+ ($name: ident, $type: ty) => {
+ fn $name<E: serde::de::Error>(self, v: $type) -> Result<Self::Value, E> {
+ T::deserialize(v.into_deserializer()).map(untagged)
+ }
+ };
+}
+
+struct EnumDeserializer<A>(A);
+
+impl<'de, A> Deserializer<'de> for EnumDeserializer<A>
+where
+ A: EnumAccess<'de>,
+{
+ type Error = A::Error;
+
+ fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
+ visitor.visit_enum(self.0)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+struct NoneDeserializer<E>(PhantomData<E>);
+
+impl<'de, E> Deserializer<'de> for NoneDeserializer<E>
+where
+ E: serde::de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
+ visitor.visit_none()
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+struct BytesDeserializer<'a, E>(&'a [u8], PhantomData<E>);
+
+impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
+where
+ E: serde::de::Error,
+{
+ type Error = E;
+
+ fn deserialize_any<V: Visitor<'de>>(self, visitor: V) -> Result<V::Value, Self::Error> {
+ visitor.visit_bytes(self.0)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+/// A visitor that intercepts *just* visit_newtype_struct and passes through everything else.
+struct MaybeTaggedVisitor<T>(PhantomData<T>);
+
+impl<'de, T: Deserialize<'de>> Visitor<'de> for MaybeTaggedVisitor<T> {
+ type Value = Tagged<T>;
+
+ fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.write_str("a cbor tag newtype")
+ }
+
+ delegate!(visit_bool, bool);
+
+ delegate!(visit_i8, i8);
+ delegate!(visit_i16, i16);
+ delegate!(visit_i32, i32);
+ delegate!(visit_i64, i64);
+
+ delegate!(visit_u8, u8);
+ delegate!(visit_u16, u16);
+ delegate!(visit_u32, u32);
+ delegate!(visit_u64, u64);
+
+ delegate!(visit_f32, f32);
+ delegate!(visit_f64, f64);
+
+ delegate!(visit_char, char);
+ delegate!(visit_str, &str);
+ delegate!(visit_borrowed_str, &'de str);
+
+ #[cfg(feature = "std")]
+ delegate!(visit_byte_buf, Vec<u8>);
+
+ #[cfg(feature = "std")]
+ delegate!(visit_string, String);
+
+ fn visit_bytes<E: serde::de::Error>(self, value: &[u8]) -> Result<Self::Value, E> {
+ T::deserialize(BytesDeserializer(value, PhantomData)).map(untagged)
+ }
+
+ fn visit_borrowed_bytes<E: serde::de::Error>(self, value: &'de [u8]) -> Result<Self::Value, E> {
+ T::deserialize(serde::de::value::BorrowedBytesDeserializer::new(value)).map(untagged)
+ }
+
+ fn visit_unit<E: serde::de::Error>(self) -> Result<Self::Value, E> {
+ T::deserialize(().into_deserializer()).map(untagged)
+ }
+
+ fn visit_none<E: serde::de::Error>(self) -> Result<Self::Value, E> {
+ T::deserialize(NoneDeserializer(PhantomData)).map(untagged)
+ }
+
+ fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> Result<Self::Value, D::Error> {
+ T::deserialize(deserializer).map(untagged)
+ }
+
+ fn visit_seq<A: SeqAccess<'de>>(self, seq: A) -> Result<Self::Value, A::Error> {
+ T::deserialize(serde::de::value::SeqAccessDeserializer::new(seq)).map(untagged)
+ }
+
+ fn visit_map<V: MapAccess<'de>>(self, map: V) -> Result<Self::Value, V::Error> {
+ T::deserialize(serde::de::value::MapAccessDeserializer::new(map)).map(untagged)
+ }
+
+ fn visit_enum<A: EnumAccess<'de>>(self, data: A) -> Result<Self::Value, A::Error> {
+ T::deserialize(EnumDeserializer(data)).map(untagged)
+ }
+
+ fn visit_newtype_struct<D: serde::Deserializer<'de>>(
+ self,
+ deserializer: D,
+ ) -> Result<Self::Value, D::Error> {
+ let t = get_tag();
+ T::deserialize(deserializer).map(|v| Tagged::new(t, v))
+ }
+}
+
+impl<'de, T: serde::de::Deserialize<'de>> serde::de::Deserialize<'de> for Tagged<T> {
+ fn deserialize<D: serde::de::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
+ deserializer.deserialize_any(MaybeTaggedVisitor::<T>(PhantomData))
+ }
+}
+
+/// function to get the current cbor tag
+///
+/// The only place where it makes sense to call this function is within visit_newtype_struct of a serde visitor.
+/// This is a low level API. In most cases it is preferable to use Tagged
+pub fn current_cbor_tag() -> Option<u64> {
+ get_tag()
+}
+
+#[cfg(feature = "tags")]
+pub(crate) fn set_tag(value: Option<u64>) {
+ CBOR_TAG.with(|f| *f.borrow_mut() = value);
+}
+
+#[cfg(feature = "tags")]
+pub(crate) fn get_tag() -> Option<u64> {
+ CBOR_TAG.with(|f| *f.borrow())
+}
+
+#[cfg(not(feature = "tags"))]
+pub(crate) fn set_tag(_value: Option<u64>) {}
+
+#[cfg(not(feature = "tags"))]
+pub(crate) fn get_tag() -> Option<u64> {
+ None
+}
+
+#[cfg(feature = "tags")]
+use std::cell::RefCell;
+
+#[cfg(feature = "tags")]
+thread_local!(static CBOR_TAG: RefCell<Option<u64>> = RefCell::new(None));
diff --git a/third_party/rust/serde_cbor/src/value/de.rs b/third_party/rust/serde_cbor/src/value/de.rs
new file mode 100644
index 0000000000..f5bdbb7467
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/value/de.rs
@@ -0,0 +1,166 @@
+use std::collections::BTreeMap;
+use std::fmt;
+
+use crate::value::Value;
+use serde::de;
+
+impl<'de> de::Deserialize<'de> for Value {
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ struct ValueVisitor;
+
+ impl<'de> de::Visitor<'de> for ValueVisitor {
+ type Value = Value;
+
+ fn expecting(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
+ fmt.write_str("any valid CBOR value")
+ }
+
+ #[inline]
+ fn visit_str<E>(self, value: &str) -> Result<Value, E>
+ where
+ E: de::Error,
+ {
+ self.visit_string(String::from(value))
+ }
+
+ #[inline]
+ fn visit_string<E>(self, value: String) -> Result<Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Text(value))
+ }
+ #[inline]
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ self.visit_byte_buf(v.to_owned())
+ }
+
+ #[inline]
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Bytes(v))
+ }
+
+ #[inline]
+ fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Integer(v.into()))
+ }
+
+ #[inline]
+ fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Integer(v.into()))
+ }
+
+ #[inline]
+ fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Integer(v))
+ }
+
+ #[inline]
+ fn visit_bool<E>(self, v: bool) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Bool(v))
+ }
+
+ #[inline]
+ fn visit_none<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ self.visit_unit()
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Null)
+ }
+
+ #[inline]
+ fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: de::SeqAccess<'de>,
+ {
+ let mut vec = Vec::new();
+
+ while let Some(elem) = visitor.next_element()? {
+ vec.push(elem);
+ }
+
+ Ok(Value::Array(vec))
+ }
+
+ #[inline]
+ fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
+ where
+ V: de::MapAccess<'de>,
+ {
+ let mut values = BTreeMap::new();
+
+ while let Some((key, value)) = visitor.next_entry()? {
+ values.insert(key, value);
+ }
+
+ Ok(Value::Map(values))
+ }
+
+ #[inline]
+ fn visit_f64<E>(self, v: f64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Value::Float(v))
+ }
+
+ fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let tag = crate::tags::get_tag();
+ let inner = deserializer.deserialize_any(self);
+ match tag {
+ Some(tag) => inner.map(|v| Value::Tag(tag, Box::new(v))),
+ None => inner,
+ }
+ }
+ }
+
+ deserializer.deserialize_any(ValueVisitor)
+ }
+}
+
+/// Convert a `serde_cbor::Value` into a type `T`
+#[allow(clippy::needless_pass_by_value)]
+pub fn from_value<T>(value: Value) -> Result<T, crate::error::Error>
+where
+ T: de::DeserializeOwned,
+{
+ // TODO implement in a way that doesn't require
+ // roundtrip through buffer (i.e. by implementing
+ // `serde::de::Deserializer` for `Value` and then doing
+ // `T::deserialize(value)`).
+ let buf = crate::to_vec(&value)?;
+ crate::from_slice(buf.as_slice())
+}
diff --git a/third_party/rust/serde_cbor/src/value/mod.rs b/third_party/rust/serde_cbor/src/value/mod.rs
new file mode 100644
index 0000000000..7bd2255314
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/value/mod.rs
@@ -0,0 +1,156 @@
+//! CBOR values, keys and serialization routines.
+
+mod de;
+mod ser;
+
+use std::cmp::{Ord, Ordering, PartialOrd};
+use std::collections::BTreeMap;
+
+#[doc(inline)]
+pub use self::de::from_value;
+#[doc(inline)]
+pub use self::ser::to_value;
+
+/// The `Value` enum, a loosely typed way of representing any valid CBOR value.
+///
+/// Maps are sorted according to the canonical ordering
+/// described in [RFC 7049 bis].
+/// Therefore values are unambiguously serialized
+/// to a canonical form of CBOR from the same RFC.
+///
+/// [RFC 7049 bis]: https://tools.ietf.org/html/draft-ietf-cbor-7049bis-04#section-2
+#[derive(Clone, Debug)]
+pub enum Value {
+ /// Represents the absence of a value or the value undefined.
+ Null,
+ /// Represents a boolean value.
+ Bool(bool),
+ /// Integer CBOR numbers.
+ ///
+ /// The biggest value that can be represented is 2^64 - 1.
+ /// While the smallest value is -2^64.
+ /// Values outside this range can't be serialized
+ /// and will cause an error.
+ Integer(i128),
+ /// Represents a floating point value.
+ Float(f64),
+ /// Represents a byte string.
+ Bytes(Vec<u8>),
+ /// Represents an UTF-8 encoded string.
+ Text(String),
+ /// Represents an array of values.
+ Array(Vec<Value>),
+ /// Represents a map.
+ ///
+ /// Maps are also called tables, dictionaries, hashes, or objects (in JSON).
+ /// While any value can be used as a CBOR key
+ /// it is better to use only one type of key in a map
+ /// to avoid ambiguity.
+ /// If floating point values are used as keys they are compared bit-by-bit for equality.
+ /// If arrays or maps are used as keys the comparisons
+ /// to establish canonical order may be slow and therefore insertion
+ /// and retrieval of values will be slow too.
+ Map(BTreeMap<Value, Value>),
+ /// Represents a tagged value
+ Tag(u64, Box<Value>),
+ // The hidden variant allows the enum to be extended
+ // with variants for tags and simple values.
+ #[doc(hidden)]
+ __Hidden,
+}
+
+impl PartialEq for Value {
+ fn eq(&self, other: &Value) -> bool {
+ self.cmp(other) == Ordering::Equal
+ }
+}
+
+impl Eq for Value {}
+
+impl PartialOrd for Value {
+ fn partial_cmp(&self, other: &Value) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl Ord for Value {
+ fn cmp(&self, other: &Value) -> Ordering {
+ // Determine the canonical order of two values:
+ // 1. Smaller major type sorts first.
+ // 2. Shorter sequence sorts first.
+ // 3. Compare integers by magnitude.
+ // 4. Compare byte and text sequences lexically.
+ // 5. Compare the serializations of both types. (expensive)
+ use self::Value::*;
+ if self.major_type() != other.major_type() {
+ return self.major_type().cmp(&other.major_type());
+ }
+ match (self, other) {
+ (Integer(a), Integer(b)) => a.abs().cmp(&b.abs()),
+ (Bytes(a), Bytes(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+ (Text(a), Text(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+ (Array(a), Array(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+ (Map(a), Map(b)) if a.len() != b.len() => a.len().cmp(&b.len()),
+ (Bytes(a), Bytes(b)) => a.cmp(b),
+ (Text(a), Text(b)) => a.cmp(b),
+ (a, b) => {
+ let a = crate::to_vec(a).expect("self is serializable");
+ let b = crate::to_vec(b).expect("other is serializable");
+ a.cmp(&b)
+ }
+ }
+ }
+}
+
+macro_rules! impl_from {
+ ($variant:path, $for_type:ty) => {
+ impl From<$for_type> for Value {
+ fn from(v: $for_type) -> Value {
+ $variant(v.into())
+ }
+ }
+ };
+}
+
+impl_from!(Value::Bool, bool);
+impl_from!(Value::Integer, i8);
+impl_from!(Value::Integer, i16);
+impl_from!(Value::Integer, i32);
+impl_from!(Value::Integer, i64);
+// i128 omitted because not all numbers fit in CBOR serialization
+impl_from!(Value::Integer, u8);
+impl_from!(Value::Integer, u16);
+impl_from!(Value::Integer, u32);
+impl_from!(Value::Integer, u64);
+// u128 omitted because not all numbers fit in CBOR serialization
+impl_from!(Value::Float, f32);
+impl_from!(Value::Float, f64);
+impl_from!(Value::Bytes, Vec<u8>);
+impl_from!(Value::Text, String);
+// TODO: figure out if these impls should be more generic or removed.
+impl_from!(Value::Array, Vec<Value>);
+impl_from!(Value::Map, BTreeMap<Value, Value>);
+
+impl Value {
+ fn major_type(&self) -> u8 {
+ use self::Value::*;
+ match self {
+ Null => 7,
+ Bool(_) => 7,
+ Integer(v) => {
+ if *v >= 0 {
+ 0
+ } else {
+ 1
+ }
+ }
+ Tag(_, _) => 6,
+ Float(_) => 7,
+ Bytes(_) => 2,
+ Text(_) => 3,
+ Array(_) => 4,
+ Map(_) => 5,
+ __Hidden => unreachable!(),
+ }
+ }
+}
diff --git a/third_party/rust/serde_cbor/src/value/ser.rs b/third_party/rust/serde_cbor/src/value/ser.rs
new file mode 100644
index 0000000000..347aae9601
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/value/ser.rs
@@ -0,0 +1,443 @@
+// 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::collections::BTreeMap;
+
+use crate::error::Error;
+use serde::{self, Serialize};
+
+use crate::tags::Tagged;
+use crate::value::Value;
+
+impl serde::Serialize for Value {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ match *self {
+ Value::Integer(v) => serializer.serialize_i128(v),
+ Value::Bytes(ref v) => serializer.serialize_bytes(&v),
+ Value::Text(ref v) => serializer.serialize_str(&v),
+ Value::Array(ref v) => v.serialize(serializer),
+ Value::Map(ref v) => v.serialize(serializer),
+ Value::Tag(tag, ref v) => Tagged::new(Some(tag), v).serialize(serializer),
+ Value::Float(v) => serializer.serialize_f64(v),
+ Value::Bool(v) => serializer.serialize_bool(v),
+ Value::Null => serializer.serialize_unit(),
+ Value::__Hidden => unreachable!(),
+ }
+ }
+}
+
+struct Serializer;
+
+impl serde::Serializer for Serializer {
+ type Ok = Value;
+ type Error = Error;
+
+ type SerializeSeq = SerializeVec;
+ type SerializeTuple = SerializeVec;
+ type SerializeTupleStruct = SerializeVec;
+ type SerializeTupleVariant = SerializeTupleVariant;
+ type SerializeMap = SerializeMap;
+ type SerializeStruct = SerializeMap;
+ type SerializeStructVariant = SerializeStructVariant;
+
+ #[inline]
+ fn serialize_bool(self, value: bool) -> Result<Value, Error> {
+ Ok(Value::Bool(value))
+ }
+
+ #[inline]
+ fn serialize_i8(self, value: i8) -> Result<Value, Error> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_i16(self, value: i16) -> Result<Value, Error> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_i32(self, value: i32) -> Result<Value, Error> {
+ self.serialize_i64(i64::from(value))
+ }
+
+ #[inline]
+ fn serialize_i64(self, value: i64) -> Result<Value, Error> {
+ self.serialize_i128(i128::from(value))
+ }
+
+ fn serialize_i128(self, value: i128) -> Result<Value, Error> {
+ Ok(Value::Integer(value))
+ }
+
+ #[inline]
+ fn serialize_u8(self, value: u8) -> Result<Value, Error> {
+ self.serialize_u64(u64::from(value))
+ }
+
+ #[inline]
+ fn serialize_u16(self, value: u16) -> Result<Value, Error> {
+ self.serialize_u64(u64::from(value))
+ }
+
+ #[inline]
+ fn serialize_u32(self, value: u32) -> Result<Value, Error> {
+ self.serialize_u64(u64::from(value))
+ }
+
+ #[inline]
+ fn serialize_u64(self, value: u64) -> Result<Value, Error> {
+ Ok(Value::Integer(value.into()))
+ }
+
+ #[inline]
+ fn serialize_f32(self, value: f32) -> Result<Value, Error> {
+ self.serialize_f64(f64::from(value))
+ }
+
+ #[inline]
+ fn serialize_f64(self, value: f64) -> Result<Value, Error> {
+ Ok(Value::Float(value))
+ }
+
+ #[inline]
+ fn serialize_char(self, value: char) -> Result<Value, Error> {
+ let mut s = String::new();
+ s.push(value);
+ self.serialize_str(&s)
+ }
+
+ #[inline]
+ fn serialize_str(self, value: &str) -> Result<Value, Error> {
+ Ok(Value::Text(value.to_owned()))
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<Value, Error> {
+ Ok(Value::Bytes(value.to_vec()))
+ }
+
+ #[inline]
+ fn serialize_unit(self) -> Result<Value, Error> {
+ Ok(Value::Null)
+ }
+
+ #[inline]
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Value, Error> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Value, Error> {
+ self.serialize_str(variant)
+ }
+
+ #[inline]
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ _name: &'static str,
+ value: &T,
+ ) -> Result<Value, Error>
+ where
+ T: Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Value, Error>
+ where
+ T: Serialize,
+ {
+ let mut values = BTreeMap::new();
+ values.insert(Value::from(variant.to_owned()), to_value(&value)?);
+ Ok(Value::Map(values))
+ }
+
+ #[inline]
+ fn serialize_none(self) -> Result<Value, Error> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Value, Error>
+ where
+ T: Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Error> {
+ Ok(SerializeVec {
+ vec: Vec::with_capacity(len.unwrap_or(0)),
+ })
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Error> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Error> {
+ self.serialize_tuple(len)
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Error> {
+ Ok(SerializeTupleVariant {
+ name: String::from(variant),
+ vec: Vec::with_capacity(len),
+ })
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Error> {
+ Ok(SerializeMap {
+ map: BTreeMap::new(),
+ next_key: None,
+ })
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStruct, Error> {
+ self.serialize_map(Some(len))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant, Error> {
+ Ok(SerializeStructVariant {
+ name: String::from(variant),
+ map: BTreeMap::new(),
+ })
+ }
+
+ #[inline]
+ fn is_human_readable(&self) -> bool {
+ false
+ }
+}
+
+pub struct SerializeVec {
+ vec: Vec<Value>,
+}
+
+pub struct SerializeTupleVariant {
+ name: String,
+ vec: Vec<Value>,
+}
+
+pub struct SerializeMap {
+ map: BTreeMap<Value, Value>,
+ next_key: Option<Value>,
+}
+
+pub struct SerializeStructVariant {
+ name: String,
+ map: BTreeMap<Value, Value>,
+}
+
+impl serde::ser::SerializeSeq for SerializeVec {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ self.vec.push(to_value(&value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ Ok(Value::Array(self.vec))
+ }
+}
+
+impl serde::ser::SerializeTuple for SerializeVec {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ serde::ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ serde::ser::SerializeSeq::end(self)
+ }
+}
+
+impl serde::ser::SerializeTupleStruct for SerializeVec {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ serde::ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ serde::ser::SerializeSeq::end(self)
+ }
+}
+
+impl serde::ser::SerializeTupleVariant for SerializeTupleVariant {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ self.vec.push(to_value(&value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ let mut object = BTreeMap::new();
+
+ object.insert(Value::from(self.name), Value::Array(self.vec));
+
+ Ok(Value::Map(object))
+ }
+}
+
+impl serde::ser::SerializeMap for SerializeMap {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ self.next_key = Some(to_value(&key)?);
+ Ok(())
+ }
+
+ fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ let key = self.next_key.take();
+ // Panic because this indicates a bug in the program rather than an
+ // expected failure.
+ let key = key.expect("serialize_value called before serialize_key");
+ self.map.insert(key, to_value(&value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ Ok(Value::Map(self.map))
+ }
+}
+
+impl serde::ser::SerializeStruct for SerializeMap {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ serde::ser::SerializeMap::serialize_key(self, key)?;
+ serde::ser::SerializeMap::serialize_value(self, value)
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ serde::ser::SerializeMap::end(self)
+ }
+}
+
+impl serde::ser::SerializeStructVariant for SerializeStructVariant {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
+ where
+ T: Serialize,
+ {
+ self.map
+ .insert(Value::from(String::from(key)), to_value(&value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value, Error> {
+ let mut object = BTreeMap::new();
+
+ object.insert(Value::from(self.name), Value::Map(self.map));
+
+ Ok(Value::Map(object))
+ }
+}
+
+/// Convert a `T` into `serde_cbor::Value` which is an enum that can represent
+/// any valid CBOR data.
+///
+/// ```rust
+/// extern crate serde;
+///
+/// #[macro_use]
+/// extern crate serde_derive;
+/// extern crate serde_cbor;
+///
+/// use std::error::Error;
+///
+/// #[derive(Serialize)]
+/// struct User {
+/// fingerprint: String,
+/// location: String,
+/// }
+///
+/// fn main() {
+/// let u = User {
+/// fingerprint: "0xF9BA143B95FF6D82".to_owned(),
+/// location: "Menlo Park, CA".to_owned(),
+/// };
+///
+/// let v = serde_cbor::value::to_value(u).unwrap();
+/// }
+/// ```
+#[allow(clippy::needless_pass_by_value)]
+// Taking by value is more friendly to iterator adapters, option and result
+pub fn to_value<T>(value: T) -> Result<Value, Error>
+where
+ T: Serialize,
+{
+ value.serialize(Serializer)
+}
diff --git a/third_party/rust/serde_cbor/src/write.rs b/third_party/rust/serde_cbor/src/write.rs
new file mode 100644
index 0000000000..94c326ef96
--- /dev/null
+++ b/third_party/rust/serde_cbor/src/write.rs
@@ -0,0 +1,175 @@
+#[cfg(feature = "alloc")]
+use alloc::vec::Vec;
+#[cfg(not(feature = "std"))]
+use core::fmt;
+#[cfg(feature = "std")]
+use std::io;
+
+use crate::error;
+
+#[cfg(not(feature = "unsealed_read_write"))]
+/// A sink for serialized CBOR.
+///
+/// This trait is similar to the [`Write`]() trait in the standard library,
+/// but has a smaller and more general API.
+///
+/// Any object implementing `std::io::Write`
+/// can be wrapped in an [`IoWrite`](../write/struct.IoWrite.html) that implements
+/// this trait for the underlying object.
+pub trait Write: private::Sealed {
+ /// The type of error returned when a write operation fails.
+ #[doc(hidden)]
+ type Error: Into<error::Error>;
+
+ /// Attempts to write an entire buffer into this write.
+ #[doc(hidden)]
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
+}
+
+#[cfg(feature = "unsealed_read_write")]
+/// A sink for serialized CBOR.
+///
+/// This trait is similar to the [`Write`]() trait in the standard library,
+/// but has a smaller and more general API.
+///
+/// Any object implementing `std::io::Write`
+/// can be wrapped in an [`IoWrite`](../write/struct.IoWrite.html) that implements
+/// this trait for the underlying object.
+///
+/// This trait is sealed by default, enabling the `unsealed_read_write` feature removes this bound
+/// to allow objects outside of this crate to implement this trait.
+pub trait Write {
+ /// The type of error returned when a write operation fails.
+ type Error: Into<error::Error>;
+
+ /// Attempts to write an entire buffer into this write.
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error>;
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+mod private {
+ pub trait Sealed {}
+}
+
+impl<W> Write for &mut W
+where
+ W: Write,
+{
+ type Error = W::Error;
+
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
+ (*self).write_all(buf)
+ }
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+impl<W> private::Sealed for &mut W where W: Write {}
+
+#[cfg(feature = "std")]
+/// A wrapper for types that implement
+/// [`std::io::Write`](https://doc.rust-lang.org/std/io/trait.Write.html) to implement the local
+/// [`Write`](trait.Write.html) trait.
+#[derive(Debug)]
+pub struct IoWrite<W>(W);
+
+#[cfg(feature = "std")]
+impl<W: io::Write> IoWrite<W> {
+ /// Wraps an `io::Write` writer to make it compatible with [`Write`](trait.Write.html)
+ pub fn new(w: W) -> IoWrite<W> {
+ IoWrite(w)
+ }
+}
+
+#[cfg(feature = "std")]
+impl<W: io::Write> Write for IoWrite<W> {
+ type Error = io::Error;
+
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
+ self.0.write_all(buf)
+ }
+}
+
+#[cfg(all(feature = "std", not(feature = "unsealed_read_write")))]
+impl<W> private::Sealed for IoWrite<W> where W: io::Write {}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl Write for Vec<u8> {
+ type Error = error::Error;
+
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
+ self.extend_from_slice(buf);
+ Ok(())
+ }
+}
+
+#[cfg(all(
+ any(feature = "std", feature = "alloc"),
+ not(feature = "unsealed_read_write")
+))]
+impl private::Sealed for Vec<u8> {}
+
+#[cfg(not(feature = "std"))]
+#[derive(Debug)]
+pub struct FmtWrite<'a, W: Write>(&'a mut W);
+
+#[cfg(not(feature = "std"))]
+impl<'a, W: Write> FmtWrite<'a, W> {
+ /// Wraps an `fmt::Write` writer to make it compatible with [`Write`](trait.Write.html)
+ pub fn new(w: &'a mut W) -> FmtWrite<'a, W> {
+ FmtWrite(w)
+ }
+}
+
+#[cfg(not(feature = "std"))]
+impl<'a, W: Write> fmt::Write for FmtWrite<'a, W> {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ self.0.write_all(s.as_bytes()).map_err(|_| fmt::Error)
+ }
+}
+
+#[cfg(all(not(feature = "std"), not(feature = "unsealed_read_write")))]
+impl<'a, W> private::Sealed for FmtWrite<'a, W> where W: Write {}
+
+/// Implements [`Write`](trait.Write.html) for mutable byte slices (`&mut [u8]`).
+///
+/// Returns an error if the value to serialize is too large to fit in the slice.
+#[derive(Debug)]
+pub struct SliceWrite<'a> {
+ slice: &'a mut [u8],
+ index: usize,
+}
+
+impl<'a> SliceWrite<'a> {
+ /// Wraps a mutable slice so it can be used as a `Write`.
+ pub fn new(slice: &'a mut [u8]) -> SliceWrite<'a> {
+ SliceWrite { slice, index: 0 }
+ }
+
+ /// Returns the number of bytes written to the underlying slice.
+ pub fn bytes_written(&self) -> usize {
+ self.index
+ }
+
+ /// Returns the underlying slice.
+ pub fn into_inner(self) -> &'a mut [u8] {
+ self.slice
+ }
+}
+
+impl<'a> Write for SliceWrite<'a> {
+ type Error = error::Error;
+
+ fn write_all(&mut self, buf: &[u8]) -> Result<(), Self::Error> {
+ if self.slice.len() - self.index < buf.len() {
+ // This buffer will not fit in our slice
+ return Err(error::Error::scratch_too_small(self.index as u64));
+ }
+ let end = self.index + buf.len();
+ self.slice[self.index..end].copy_from_slice(buf);
+ self.index = end;
+ Ok(())
+ }
+}
+
+#[cfg(not(feature = "unsealed_read_write"))]
+impl<'a> private::Sealed for SliceWrite<'a> {}
diff --git a/third_party/rust/serde_cbor/tests/bennofs.rs b/third_party/rust/serde_cbor/tests/bennofs.rs
new file mode 100644
index 0000000000..1b289f40d4
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/bennofs.rs
@@ -0,0 +1,60 @@
+#[macro_use]
+extern crate serde_derive;
+
+use serde::Serialize;
+use serde_cbor::ser::SliceWrite;
+use serde_cbor::{self, Serializer};
+
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+struct Example {
+ foo: Foo,
+ payload: u8,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+struct Foo {
+ x: u8,
+ color: Color,
+}
+
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+enum Color {
+ Red,
+ Blue,
+ Yellow(u8),
+}
+
+const EXAMPLE: Example = Example {
+ foo: Foo {
+ x: 0xAA,
+ color: Color::Yellow(40),
+ },
+ payload: 0xCC,
+};
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use super::*;
+
+ #[test]
+ fn test() {
+ let serialized = serde_cbor::ser::to_vec_packed(&EXAMPLE).expect("bennofs 1");
+ println!("{:?}", serialized);
+ let deserialized: Example = serde_cbor::from_slice(&serialized).expect("bennofs 2");
+ assert_eq!(EXAMPLE, deserialized);
+ }
+}
+
+#[test]
+fn test() {
+ let mut slice = [0u8; 64];
+ let writer = SliceWrite::new(&mut slice);
+ let mut serializer = Serializer::new(writer).packed_format();
+ EXAMPLE.serialize(&mut serializer).unwrap();
+ let writer = serializer.into_inner();
+ let end = writer.bytes_written();
+ let slice = writer.into_inner();
+ let deserialized: Example =
+ serde_cbor::de::from_slice_with_scratch(&slice[..end], &mut []).unwrap();
+ assert_eq!(EXAMPLE, deserialized);
+}
diff --git a/third_party/rust/serde_cbor/tests/canonical.rs b/third_party/rust/serde_cbor/tests/canonical.rs
new file mode 100644
index 0000000000..438e29e7d4
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/canonical.rs
@@ -0,0 +1,104 @@
+#[cfg(feature = "std")]
+mod std_tests {
+ use serde_cbor::value::Value;
+
+ #[test]
+ fn integer_canonical_sort_order() {
+ let expected = [
+ 0,
+ 23,
+ 24,
+ 255,
+ 256,
+ 65535,
+ 65536,
+ 4294967295,
+ -1,
+ -24,
+ -25,
+ -256,
+ -257,
+ -65536,
+ -65537,
+ -4294967296,
+ ]
+ .iter()
+ .map(|i| Value::Integer(*i))
+ .collect::<Vec<_>>();
+
+ let mut sorted = expected.clone();
+ sorted.sort();
+
+ assert_eq!(expected, sorted);
+ }
+
+ #[test]
+ fn string_canonical_sort_order() {
+ let expected = ["", "a", "b", "aa"]
+ .iter()
+ .map(|s| Value::Text(s.to_string()))
+ .collect::<Vec<_>>();
+
+ let mut sorted = expected.clone();
+ sorted.sort();
+
+ assert_eq!(expected, sorted);
+ }
+
+ #[test]
+ fn bytes_canonical_sort_order() {
+ let expected = vec![vec![], vec![0u8], vec![1u8], vec![0u8, 0u8]]
+ .into_iter()
+ .map(|v| Value::Bytes(v))
+ .collect::<Vec<_>>();
+
+ let mut sorted = expected.clone();
+ sorted.sort();
+
+ assert_eq!(expected, sorted);
+ }
+
+ #[test]
+ fn simple_data_canonical_sort_order() {
+ let expected = vec![Value::Bool(false), Value::Bool(true), Value::Null];
+
+ let mut sorted = expected.clone();
+ sorted.sort();
+
+ assert_eq!(expected, sorted);
+ }
+
+ #[test]
+ fn major_type_canonical_sort_order() {
+ let expected = vec![
+ Value::Integer(0),
+ Value::Integer(-1),
+ Value::Bytes(vec![]),
+ Value::Text("".to_string()),
+ Value::Null,
+ ];
+
+ let mut sorted = expected.clone();
+ sorted.sort();
+
+ assert_eq!(expected, sorted);
+ }
+
+ #[test]
+ fn test_rfc_example() {
+ // See: https://tools.ietf.org/html/draft-ietf-cbor-7049bis-04#section-4.10
+ let expected = vec![
+ Value::Integer(10),
+ Value::Integer(100),
+ Value::Integer(-1),
+ Value::Text("z".to_owned()),
+ Value::Text("aa".to_owned()),
+ Value::Array(vec![Value::Integer(100)]),
+ Value::Array(vec![Value::Integer(-1)]),
+ Value::Bool(false),
+ ];
+ let mut sorted = expected.clone();
+ sorted.sort();
+ assert_eq!(expected, sorted);
+ }
+}
diff --git a/third_party/rust/serde_cbor/tests/crash.cbor b/third_party/rust/serde_cbor/tests/crash.cbor
new file mode 100644
index 0000000000..a3bc785ca3
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/crash.cbor
Binary files differ
diff --git a/third_party/rust/serde_cbor/tests/de.rs b/third_party/rust/serde_cbor/tests/de.rs
new file mode 100644
index 0000000000..01d7914502
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/de.rs
@@ -0,0 +1,747 @@
+#[macro_use]
+extern crate serde_derive;
+
+use serde_cbor;
+use serde_cbor::de;
+
+#[test]
+fn test_str() {
+ let s: &str =
+ de::from_slice_with_scratch(&[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72], &mut []).unwrap();
+ assert_eq!(s, "foobar");
+}
+
+#[test]
+fn test_bytes() {
+ let s: &[u8] =
+ de::from_slice_with_scratch(&[0x46, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72], &mut []).unwrap();
+ assert_eq!(s, b"foobar");
+}
+
+#[test]
+fn test_int() {
+ let num: i64 = de::from_slice_with_scratch(&[0x39, 0x07, 0xde], &mut []).unwrap();
+ assert_eq!(num, -2015);
+}
+
+#[test]
+fn test_float() {
+ let float: f64 = de::from_slice_with_scratch(b"\xfa\x47\xc3\x50\x00", &mut []).unwrap();
+ assert_eq!(float, 100000.0);
+}
+
+#[test]
+fn test_indefinite_object() {
+ #[derive(Debug, Deserialize, PartialEq)]
+ struct Foo {
+ a: u64,
+ b: [u64; 2],
+ }
+ let expected = Foo { a: 1, b: [2, 3] };
+ let actual: Foo =
+ de::from_slice_with_scratch(b"\xbfaa\x01ab\x9f\x02\x03\xff\xff", &mut []).unwrap();
+ assert_eq!(expected, actual);
+}
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use std::collections::BTreeMap;
+
+ use serde::de as serde_de;
+ use serde_cbor::value::Value;
+ use serde_cbor::{de, error, to_vec, Deserializer};
+
+ #[test]
+ fn test_string1() {
+ let value: error::Result<Value> =
+ de::from_slice(&[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
+ assert_eq!(value.unwrap(), Value::Text("foobar".to_owned()));
+ }
+
+ #[test]
+ fn test_string2() {
+ let value: error::Result<Value> = de::from_slice(&[
+ 0x71, 0x49, 0x20, 0x6d, 0x65, 0x74, 0x20, 0x61, 0x20, 0x74, 0x72, 0x61, 0x76, 0x65,
+ 0x6c, 0x6c, 0x65, 0x72,
+ ]);
+ assert_eq!(value.unwrap(), Value::Text("I met a traveller".to_owned()));
+ }
+
+ #[test]
+ fn test_string3() {
+ let slice = b"\x78\x2fI met a traveller from an antique land who said";
+ let value: error::Result<Value> = de::from_slice(slice);
+ assert_eq!(
+ value.unwrap(),
+ Value::Text("I met a traveller from an antique land who said".to_owned())
+ );
+ }
+
+ #[test]
+ fn test_byte_string() {
+ let value: error::Result<Value> =
+ de::from_slice(&[0x46, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
+ assert_eq!(value.unwrap(), Value::Bytes(b"foobar".to_vec()));
+ }
+
+ #[test]
+ fn test_numbers1() {
+ let value: error::Result<Value> = de::from_slice(&[0x00]);
+ assert_eq!(value.unwrap(), Value::Integer(0));
+ }
+
+ #[test]
+ fn test_numbers2() {
+ let value: error::Result<Value> = de::from_slice(&[0x1a, 0x00, 0xbc, 0x61, 0x4e]);
+ assert_eq!(value.unwrap(), Value::Integer(12345678));
+ }
+
+ #[test]
+ fn test_numbers3() {
+ let value: error::Result<Value> = de::from_slice(&[0x39, 0x07, 0xde]);
+ assert_eq!(value.unwrap(), Value::Integer(-2015));
+ }
+
+ #[test]
+ fn test_bool() {
+ let value: error::Result<Value> = de::from_slice(b"\xf4");
+ assert_eq!(value.unwrap(), Value::Bool(false));
+ }
+
+ #[test]
+ fn test_trailing_bytes() {
+ let value: error::Result<Value> = de::from_slice(b"\xf4trailing");
+ assert!(value.is_err());
+ }
+
+ #[test]
+ fn test_list1() {
+ let value: error::Result<Value> = de::from_slice(b"\x83\x01\x02\x03");
+ assert_eq!(
+ value.unwrap(),
+ Value::Array(vec![
+ Value::Integer(1),
+ Value::Integer(2),
+ Value::Integer(3)
+ ])
+ );
+ }
+
+ #[test]
+ fn test_list2() {
+ let value: error::Result<Value> = de::from_slice(b"\x82\x01\x82\x02\x81\x03");
+ assert_eq!(
+ value.unwrap(),
+ Value::Array(vec![
+ Value::Integer(1),
+ Value::Array(vec![
+ Value::Integer(2),
+ Value::Array(vec![Value::Integer(3)])
+ ])
+ ])
+ );
+ }
+
+ #[test]
+ fn test_object() {
+ let value: error::Result<Value> = de::from_slice(b"\xa5aaaAabaBacaCadaDaeaE");
+ let mut object = BTreeMap::new();
+ object.insert(Value::Text("a".to_owned()), Value::Text("A".to_owned()));
+ object.insert(Value::Text("b".to_owned()), Value::Text("B".to_owned()));
+ object.insert(Value::Text("c".to_owned()), Value::Text("C".to_owned()));
+ object.insert(Value::Text("d".to_owned()), Value::Text("D".to_owned()));
+ object.insert(Value::Text("e".to_owned()), Value::Text("E".to_owned()));
+ assert_eq!(value.unwrap(), Value::Map(object));
+ }
+
+ #[test]
+ fn test_indefinite_object() {
+ let value: error::Result<Value> = de::from_slice(b"\xbfaa\x01ab\x9f\x02\x03\xff\xff");
+ let mut object = BTreeMap::new();
+ object.insert(Value::Text("a".to_owned()), Value::Integer(1));
+ object.insert(
+ Value::Text("b".to_owned()),
+ Value::Array(vec![Value::Integer(2), Value::Integer(3)]),
+ );
+ assert_eq!(value.unwrap(), Value::Map(object));
+ }
+
+ #[test]
+ fn test_indefinite_list() {
+ let value: error::Result<Value> = de::from_slice(b"\x9f\x01\x02\x03\xff");
+ assert_eq!(
+ value.unwrap(),
+ Value::Array(vec![
+ Value::Integer(1),
+ Value::Integer(2),
+ Value::Integer(3)
+ ])
+ );
+ }
+
+ #[test]
+ fn test_indefinite_string() {
+ let value: error::Result<Value> =
+ de::from_slice(b"\x7f\x65Mary \x64Had \x62a \x67Little \x60\x64Lamb\xff");
+ assert_eq!(
+ value.unwrap(),
+ Value::Text("Mary Had a Little Lamb".to_owned())
+ );
+ }
+
+ #[test]
+ fn test_indefinite_byte_string() {
+ let value: error::Result<Value> = de::from_slice(b"\x5f\x42\x01\x23\x42\x45\x67\xff");
+ assert_eq!(value.unwrap(), Value::Bytes(b"\x01#Eg".to_vec()));
+ }
+
+ #[test]
+ fn test_multiple_indefinite_strings() {
+ let input = b"\x82\x7f\x65Mary \x64Had \x62a \x67Little \x60\x64Lamb\xff\x5f\x42\x01\x23\x42\x45\x67\xff";
+ _test_multiple_indefinite_strings(de::from_slice(input));
+ _test_multiple_indefinite_strings(de::from_mut_slice(input.to_vec().as_mut()));
+ let mut buf = [0u8; 64];
+ _test_multiple_indefinite_strings(de::from_slice_with_scratch(input, &mut buf));
+ }
+ fn _test_multiple_indefinite_strings(value: error::Result<Value>) {
+ // This assures that buffer rewinding in infinite buffers works as intended.
+ assert_eq!(
+ value.unwrap(),
+ Value::Array(vec![
+ Value::Text("Mary Had a Little Lamb".to_owned()),
+ Value::Bytes(b"\x01#Eg".to_vec())
+ ])
+ );
+ }
+
+ #[test]
+ fn test_float() {
+ let value: error::Result<Value> = de::from_slice(b"\xfa\x47\xc3\x50\x00");
+ assert_eq!(value.unwrap(), Value::Float(100000.0));
+ }
+
+ #[test]
+ fn test_self_describing() {
+ let value: error::Result<Value> =
+ de::from_slice(&[0xd9, 0xd9, 0xf7, 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
+ let expected = Value::Text("foobar".to_owned());
+ let strip_tags = |x: Value| {
+ if let Value::Tag(_, inner) = x {
+ *inner
+ } else {
+ x
+ }
+ };
+ assert_eq!(strip_tags(value.unwrap()), expected);
+ }
+
+ #[test]
+ fn test_f16() {
+ let mut x: Value = de::from_slice(&[0xf9, 0x41, 0x00]).unwrap();
+ assert_eq!(x, Value::Float(2.5));
+ x = de::from_slice(&[0xf9, 0x41, 0x90]).unwrap();
+ assert_eq!(x, Value::Float(2.78125));
+ x = de::from_slice(&[0xf9, 0x50, 0x90]).unwrap();
+ assert_eq!(x, Value::Float(36.5));
+ x = de::from_slice(&[0xf9, 0xd0, 0x90]).unwrap();
+ assert_eq!(x, Value::Float(-36.5));
+ }
+
+ #[test]
+ fn test_crazy_list() {
+ let slice = b"\x88\x1b\x00\x00\x00\x1c\xbe\x99\x1d\xc7\x3b\x00\x7a\xcf\x51\xdc\x51\x70\xdb\x3a\x1b\x3a\x06\xdd\xf5\xf6\xf7\xfb\x41\x76\x5e\xb1\xf8\x00\x00\x00\xf9\x7c\x00";
+ let value: Vec<Value> = de::from_slice(slice).unwrap();
+ assert_eq!(
+ value,
+ vec![
+ Value::Integer(123456789959),
+ Value::Integer(-34567897654325468),
+ Value::Integer(-456787678),
+ Value::Bool(true),
+ Value::Null,
+ Value::Null,
+ Value::Float(23456543.5),
+ Value::Float(::std::f64::INFINITY)
+ ]
+ );
+ }
+
+ #[test]
+ fn test_nan() {
+ let value: f64 = de::from_slice(b"\xf9\x7e\x00").unwrap();
+ assert!(value.is_nan());
+ }
+
+ #[test]
+ fn test_32f16() {
+ let value: f32 = de::from_slice(b"\xf9\x50\x00").unwrap();
+ assert_eq!(value, 32.0f32);
+ }
+
+ #[test]
+ // The file was reported as not working by user kie0tauB
+ // but it parses to a cbor value.
+ fn test_kietaub_file() {
+ let file = include_bytes!("kietaub.cbor");
+ let value_result: error::Result<Value> = de::from_slice(file);
+ value_result.unwrap();
+ }
+
+ #[test]
+ fn test_option_roundtrip() {
+ let obj1 = Some(10u32);
+
+ let v = to_vec(&obj1).unwrap();
+ let obj2: Result<Option<u32>, _> = serde_cbor::de::from_reader(&v[..]);
+ println!("{:?}", obj2);
+
+ assert_eq!(obj1, obj2.unwrap());
+ }
+
+ #[test]
+ fn test_option_none_roundtrip() {
+ let obj1 = None;
+
+ let v = to_vec(&obj1).unwrap();
+ println!("{:?}", v);
+ let obj2: Result<Option<u32>, _> = serde_cbor::de::from_reader(&v[..]);
+
+ assert_eq!(obj1, obj2.unwrap());
+ }
+
+ #[test]
+ fn test_variable_length_map() {
+ let slice = b"\xbf\x67\x6d\x65\x73\x73\x61\x67\x65\x64\x70\x6f\x6e\x67\xff";
+ let value: Value = de::from_slice(slice).unwrap();
+ let mut map = BTreeMap::new();
+ map.insert(
+ Value::Text("message".to_string()),
+ Value::Text("pong".to_string()),
+ );
+ assert_eq!(value, Value::Map(map))
+ }
+
+ #[test]
+ fn test_object_determinism_roundtrip() {
+ let expected = b"\xa2aa\x01ab\x82\x02\x03";
+
+ // 0.1% chance of not catching failure
+ for _ in 0..10 {
+ assert_eq!(
+ &to_vec(&de::from_slice::<Value>(expected).unwrap()).unwrap(),
+ expected
+ );
+ }
+ }
+
+ #[test]
+ fn stream_deserializer() {
+ let slice = b"\x01\x66foobar";
+ let mut it = Deserializer::from_slice(slice).into_iter::<Value>();
+ assert_eq!(Value::Integer(1), it.next().unwrap().unwrap());
+ assert_eq!(
+ Value::Text("foobar".to_string()),
+ it.next().unwrap().unwrap()
+ );
+ assert!(it.next().is_none());
+ }
+
+ #[test]
+ fn stream_deserializer_eof() {
+ let slice = b"\x01\x66foob";
+ let mut it = Deserializer::from_slice(slice).into_iter::<Value>();
+ assert_eq!(Value::Integer(1), it.next().unwrap().unwrap());
+ assert!(it.next().unwrap().unwrap_err().is_eof());
+ }
+
+ #[test]
+ fn stream_deserializer_eof_in_indefinite() {
+ let slice = b"\x7f\x65Mary \x64Had \x62a \x60\x67Little \x60\x64Lamb\xff";
+ let indices: &[usize] = &[
+ 2, // announcement but no data
+ 10, // mid-buffer EOF
+ 12, // neither new element nor end marker
+ ];
+ for end_of_slice in indices {
+ let mut it = Deserializer::from_slice(&slice[..*end_of_slice]).into_iter::<Value>();
+ assert!(it.next().unwrap().unwrap_err().is_eof());
+
+ let mut mutcopy = slice[..*end_of_slice].to_vec();
+ let mut it = Deserializer::from_mut_slice(mutcopy.as_mut()).into_iter::<Value>();
+ assert!(it.next().unwrap().unwrap_err().is_eof());
+
+ let mut buf = [0u8; 64];
+ let mut it = Deserializer::from_slice_with_scratch(&slice[..*end_of_slice], &mut buf)
+ .into_iter::<Value>();
+ assert!(it.next().unwrap().unwrap_err().is_eof());
+ }
+ }
+
+ #[test]
+ fn crash() {
+ let file = include_bytes!("crash.cbor");
+ let value_result: error::Result<Value> = de::from_slice(file);
+ assert_eq!(
+ value_result.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ }
+
+ fn from_slice_stream<'a, T>(slice: &'a [u8]) -> error::Result<(&'a [u8], T)>
+ where
+ T: serde_de::Deserialize<'a>,
+ {
+ let mut deserializer = Deserializer::from_slice(slice);
+ let value = serde_de::Deserialize::deserialize(&mut deserializer)?;
+ let rest = &slice[deserializer.byte_offset()..];
+
+ Ok((rest, value))
+ }
+
+ #[test]
+ fn test_slice_offset() {
+ let v: Vec<u8> = vec![
+ 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72, 0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72,
+ ];
+ let (rest, value): (&[u8], String) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(value, "foobar");
+ assert_eq!(rest, &[0x66, 0x66, 0x6f, 0x6f, 0x62, 0x61, 0x72]);
+ let (rest, value): (&[u8], String) = from_slice_stream(rest).unwrap();
+ assert_eq!(value, "foobar");
+ assert_eq!(rest, &[]);
+ }
+
+ #[derive(Debug, Copy, Clone)]
+ struct Options {
+ standard: bool,
+ legacy: bool,
+ packed: bool,
+ named: bool,
+ }
+
+ impl Default for Options {
+ fn default() -> Self {
+ Options {
+ standard: true,
+ legacy: true,
+ packed: true,
+ named: true,
+ }
+ }
+ }
+
+ impl Options {
+ fn no_standard(self) -> Self {
+ Options {
+ standard: false,
+ ..self
+ }
+ }
+
+ fn no_legacy(self) -> Self {
+ Options {
+ legacy: false,
+ ..self
+ }
+ }
+
+ fn no_packed(self) -> Self {
+ Options {
+ packed: false,
+ ..self
+ }
+ }
+
+ fn no_named(self) -> Self {
+ Options {
+ named: false,
+ ..self
+ }
+ }
+ }
+
+ fn from_slice_stream_options<'a, T>(
+ slice: &'a [u8],
+ options: Options,
+ ) -> error::Result<(&'a [u8], T)>
+ where
+ T: serde_de::Deserialize<'a>,
+ {
+ let deserializer = Deserializer::from_slice(slice);
+ let deserializer = if !options.packed {
+ deserializer.disable_packed_format()
+ } else {
+ deserializer
+ };
+ let deserializer = if !options.named {
+ deserializer.disable_named_format()
+ } else {
+ deserializer
+ };
+ let deserializer = if !options.standard {
+ deserializer.disable_standard_enums()
+ } else {
+ deserializer
+ };
+ let mut deserializer = if !options.legacy {
+ deserializer.disable_legacy_enums()
+ } else {
+ deserializer
+ };
+ let value = serde_de::Deserialize::deserialize(&mut deserializer)?;
+ let rest = &slice[deserializer.byte_offset()..];
+
+ Ok((rest, value))
+ }
+
+ #[test]
+ fn test_deserializer_enums() {
+ #[derive(Debug, PartialEq, Deserialize)]
+ enum Enum {
+ Unit,
+ NewType(i32),
+ Tuple(String, bool),
+ Struct { x: i32, y: i32 },
+ }
+
+ // This is the format used in serde >= 0.10
+ //
+ // Serialization of Enum::NewType(10)
+ let v: Vec<u8> = vec![
+ 0xa1, // map 1pair
+ 0x67, 0x4e, 0x65, 0x77, 0x54, 0x79, 0x70, 0x65, // utf8 string: NewType
+ 0x1a, // u32
+ 0x00, 0x00, 0x00, 0x0a, // 10 (dec)
+ ];
+ let (_rest, value): (&[u8], Enum) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(value, Enum::NewType(10));
+ let (_rest, value): (&[u8], Enum) =
+ from_slice_stream_options(&v[..], Options::default().no_legacy()).unwrap();
+ assert_eq!(value, Enum::NewType(10));
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_standard());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_standard().no_legacy());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ // Serialization of Enum::Unit
+ let v: Vec<u8> = vec![
+ 0x64, 0x55, 0x6e, 0x69, 0x74, // utf8 string: Unit
+ ];
+ let (_rest, value): (&[u8], Enum) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(value, Enum::Unit);
+ let (_rest, value): (&[u8], Enum) =
+ from_slice_stream_options(&v[..], Options::default().no_legacy()).unwrap();
+ assert_eq!(value, Enum::Unit);
+ let (_rest, value): (&[u8], Enum) =
+ from_slice_stream_options(&v[..], Options::default().no_standard()).unwrap();
+ assert_eq!(value, Enum::Unit);
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_legacy().no_standard());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+
+ // This is the format used in serde <= 0.9
+ let v: Vec<u8> = vec![
+ 0x82, // array 2 items
+ 0x67, 0x4e, 0x65, 0x77, 0x54, 0x79, 0x70, 0x65, // utf8 string: NewType
+ 0x1a, // u32
+ 0x00, 0x00, 0x00, 0x0a, // 10 (dec)
+ ];
+ let (_rest, value): (&[u8], Enum) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(value, Enum::NewType(10));
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_legacy());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_standard());
+ assert_eq!(value.unwrap().1, Enum::NewType(10));
+ let value: error::Result<(&[u8], Enum)> =
+ from_slice_stream_options(&v[..], Options::default().no_standard().no_legacy());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ }
+
+ #[test]
+ fn test_packed_deserialization() {
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct User {
+ user_id: u32,
+ password_hash: [u8; 4],
+ }
+
+ // unpacked
+ let v: Vec<u8> = vec![
+ 0xa2, // map 2pair
+ 0x67, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, // utf8 string: user_id
+ 0x0a, // integer: 10
+ // utf8 string: password_hash
+ 0x6d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68,
+ 0x84, 0x01, 0x02, 0x03, 0x04, // 4 byte array [1, 2, 3, 4]
+ ];
+
+ let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let (_rest, value): (&[u8], User) =
+ from_slice_stream_options(&v[..], Options::default().no_packed()).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let value: error::Result<(&[u8], User)> =
+ from_slice_stream_options(&v[..], Options::default().no_named());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+
+ // unpacked - indefinite length
+ let v: Vec<u8> = vec![
+ 0xbf, // map to be followed by a break
+ 0x67, 0x75, 0x73, 0x65, 0x72, 0x5f, 0x69, 0x64, // utf8 string: user_id
+ 0x0a, // integer: 10
+ // utf8 string: password_hash
+ 0x6d, 0x70, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x5f, 0x68, 0x61, 0x73, 0x68,
+ 0x84, 0x01, 0x02, 0x03, 0x04, // 4 byte array [1, 2, 3, 4]
+ 0xff, // break
+ ];
+
+ let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let (_rest, value): (&[u8], User) =
+ from_slice_stream_options(&v[..], Options::default().no_packed()).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let value: error::Result<(&[u8], User)> =
+ from_slice_stream_options(&v[..], Options::default().no_named());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+
+ // packed
+ let v: Vec<u8> = vec![
+ 0xa2, // map 2pair
+ 0x00, // index 0
+ 0x0a, // integer: 10
+ 0x01, // index 1
+ 0x84, 0x01, 0x02, 0x03, 0x04, // 4 byte array [1, 2, 3, 4]
+ ];
+
+ let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let (_rest, value): (&[u8], User) =
+ from_slice_stream_options(&v[..], Options::default().no_named()).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let value: error::Result<(&[u8], User)> =
+ from_slice_stream_options(&v[..], Options::default().no_packed());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+
+ // packed - indefinite length
+ let v: Vec<u8> = vec![
+ 0xbf, // map, to be followed by a break
+ 0x00, // index 0
+ 0x0a, // integer: 10
+ 0x01, // index 1
+ 0x84, 0x01, 0x02, 0x03, 0x04, // 4 byte array [1, 2, 3, 4]
+ 0xff, // break
+ ];
+
+ let (_rest, value): (&[u8], User) = from_slice_stream(&v[..]).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let (_rest, value): (&[u8], User) =
+ from_slice_stream_options(&v[..], Options::default().no_named()).unwrap();
+ assert_eq!(
+ value,
+ User {
+ user_id: 10,
+ password_hash: [1, 2, 3, 4],
+ }
+ );
+ let value: error::Result<(&[u8], User)> =
+ from_slice_stream_options(&v[..], Options::default().no_packed());
+ assert_eq!(
+ value.unwrap_err().classify(),
+ serde_cbor::error::Category::Syntax
+ );
+ }
+
+ use serde_cbor::{de::from_slice, ser::to_vec_packed};
+ use std::net::{IpAddr, Ipv4Addr};
+ #[test]
+ fn test_ipaddr_deserialization() {
+ let ip = IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1));
+ let buf = to_vec_packed(&ip).unwrap();
+ let deserialized_ip = from_slice::<IpAddr>(&buf).unwrap();
+ assert_eq!(ip, deserialized_ip);
+
+ let buf = to_vec(&ip).unwrap();
+ let deserialized_ip = from_slice::<IpAddr>(&buf).unwrap();
+ assert_eq!(ip, deserialized_ip);
+ }
+
+ #[test]
+ fn attempt_stack_overflow() {
+ // Create a tag 17, followed by 999 more tag 17:
+ // 17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(17(...
+ // This causes deep recursion in the decoder and may
+ // exhaust the stack and therfore result in a stack overflow.
+ let input = vec![0xd1; 1000];
+ let err = serde_cbor::from_slice::<serde_cbor::Value>(&input).expect_err("recursion limit");
+ assert!(err.is_syntax());
+ }
+}
diff --git a/third_party/rust/serde_cbor/tests/enum.rs b/third_party/rust/serde_cbor/tests/enum.rs
new file mode 100644
index 0000000000..630500d6b5
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/enum.rs
@@ -0,0 +1,236 @@
+use serde::Serialize;
+use serde_cbor;
+use serde_cbor::ser::{Serializer, SliceWrite};
+
+#[macro_use]
+extern crate serde_derive;
+
+#[test]
+fn test_simple_data_enum_roundtrip() {
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ enum DataEnum {
+ A(u32),
+ B(f32),
+ }
+
+ let a = DataEnum::A(42);
+
+ let mut slice = [0u8; 64];
+ let writer = SliceWrite::new(&mut slice);
+ let mut serializer = Serializer::new(writer);
+ a.serialize(&mut serializer).unwrap();
+ let writer = serializer.into_inner();
+ let end = writer.bytes_written();
+ let slice = writer.into_inner();
+ let deserialized: DataEnum =
+ serde_cbor::de::from_slice_with_scratch(&slice[..end], &mut []).unwrap();
+ assert_eq!(a, deserialized);
+}
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use std::collections::BTreeMap;
+
+ use serde_cbor::ser::{IoWrite, Serializer};
+ use serde_cbor::value::Value;
+ use serde_cbor::{from_slice, to_vec};
+
+ pub fn to_vec_legacy<T>(value: &T) -> serde_cbor::Result<Vec<u8>>
+ where
+ T: serde::ser::Serialize,
+ {
+ let mut vec = Vec::new();
+ value.serialize(&mut Serializer::new(&mut IoWrite::new(&mut vec)).legacy_enums())?;
+ Ok(vec)
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+ enum Enum {
+ A,
+ B,
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+ struct EnumStruct {
+ e: Enum,
+ }
+
+ #[test]
+ fn test_enum() {
+ let enum_struct = EnumStruct { e: Enum::B };
+ let raw = &to_vec(&enum_struct).unwrap();
+ println!("raw enum {:?}", raw);
+ let re: EnumStruct = from_slice(raw).unwrap();
+ assert_eq!(enum_struct, re);
+ }
+
+ #[repr(u16)]
+ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+ enum ReprEnum {
+ A,
+ B,
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+ struct ReprEnumStruct {
+ e: ReprEnum,
+ }
+
+ #[test]
+ fn test_repr_enum() {
+ let repr_enum_struct = ReprEnumStruct { e: ReprEnum::B };
+ let re: ReprEnumStruct = from_slice(&to_vec(&repr_enum_struct).unwrap()).unwrap();
+ assert_eq!(repr_enum_struct, re);
+ }
+
+ #[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
+ enum DataEnum {
+ A(u32),
+ B(bool, u8),
+ C { x: u8, y: String },
+ }
+
+ #[test]
+ fn test_data_enum() {
+ let data_enum_a = DataEnum::A(4);
+ let re_a: DataEnum = from_slice(&to_vec(&data_enum_a).unwrap()).unwrap();
+ assert_eq!(data_enum_a, re_a);
+ let data_enum_b = DataEnum::B(true, 42);
+ let re_b: DataEnum = from_slice(&to_vec(&data_enum_b).unwrap()).unwrap();
+ assert_eq!(data_enum_b, re_b);
+ let data_enum_c = DataEnum::C {
+ x: 3,
+ y: "foo".to_owned(),
+ };
+ println!("{:?}", &to_vec(&data_enum_c).unwrap());
+ let re_c: DataEnum = from_slice(&to_vec(&data_enum_c).unwrap()).unwrap();
+ assert_eq!(data_enum_c, re_c);
+ }
+
+ #[test]
+ fn test_serialize() {
+ assert_eq!(to_vec_legacy(&Enum::A).unwrap(), &[97, 65]);
+ assert_eq!(to_vec_legacy(&Enum::B).unwrap(), &[97, 66]);
+ assert_eq!(
+ to_vec_legacy(&DataEnum::A(42)).unwrap(),
+ &[130, 97, 65, 24, 42]
+ );
+ assert_eq!(
+ to_vec_legacy(&DataEnum::B(true, 9)).unwrap(),
+ &[131, 97, 66, 245, 9]
+ );
+ }
+
+ #[test]
+ fn test_newtype_struct() {
+ #[derive(Debug, Deserialize, Serialize, PartialEq, Eq)]
+ pub struct Newtype(u8);
+ assert_eq!(to_vec(&142u8).unwrap(), to_vec(&Newtype(142u8)).unwrap());
+ assert_eq!(from_slice::<Newtype>(&[24, 142]).unwrap(), Newtype(142));
+ }
+
+ #[derive(Deserialize, PartialEq, Debug)]
+ enum Foo {
+ #[serde(rename = "require")]
+ Require,
+ }
+
+ #[test]
+ fn test_variable_length_array() {
+ let slice = b"\x9F\x67\x72\x65\x71\x75\x69\x72\x65\xFF";
+ let value: Vec<Foo> = from_slice(slice).unwrap();
+ assert_eq!(value, [Foo::Require]);
+ }
+
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ enum Bar {
+ Empty,
+ Number(i32),
+ Flag(String, bool),
+ Point { x: i32, y: i32 },
+ }
+
+ #[test]
+ fn test_enum_as_map() {
+ // unit variants serialize like bare strings
+ let empty_s = to_vec_legacy(&Bar::Empty).unwrap();
+ let empty_str_s = to_vec_legacy(&"Empty").unwrap();
+ assert_eq!(empty_s, empty_str_s);
+
+ // tuple-variants serialize like ["<variant>", values..]
+ let number_s = to_vec_legacy(&Bar::Number(42)).unwrap();
+ let number_vec = vec![Value::Text("Number".to_string()), Value::Integer(42)];
+ let number_vec_s = to_vec_legacy(&number_vec).unwrap();
+ assert_eq!(number_s, number_vec_s);
+
+ let flag_s = to_vec_legacy(&Bar::Flag("foo".to_string(), true)).unwrap();
+ let flag_vec = vec![
+ Value::Text("Flag".to_string()),
+ Value::Text("foo".to_string()),
+ Value::Bool(true),
+ ];
+ let flag_vec_s = to_vec_legacy(&flag_vec).unwrap();
+ assert_eq!(flag_s, flag_vec_s);
+
+ // struct-variants serialize like ["<variant>", {struct..}]
+ let point_s = to_vec_legacy(&Bar::Point { x: 5, y: -5 }).unwrap();
+ let mut struct_map = BTreeMap::new();
+ struct_map.insert(Value::Text("x".to_string()), Value::Integer(5));
+ struct_map.insert(Value::Text("y".to_string()), Value::Integer(-5));
+ let point_vec = vec![
+ Value::Text("Point".to_string()),
+ Value::Map(struct_map.clone()),
+ ];
+ let point_vec_s = to_vec_legacy(&point_vec).unwrap();
+ assert_eq!(point_s, point_vec_s);
+
+ // enum_as_map matches serde_json's default serialization for enums.
+
+ // unit variants still serialize like bare strings
+ let empty_s = to_vec(&Bar::Empty).unwrap();
+ assert_eq!(empty_s, empty_str_s);
+
+ // 1-element tuple variants serialize like {"<variant>": value}
+ let number_s = to_vec(&Bar::Number(42)).unwrap();
+ let mut number_map = BTreeMap::new();
+ number_map.insert("Number", 42);
+ let number_map_s = to_vec(&number_map).unwrap();
+ assert_eq!(number_s, number_map_s);
+
+ // multi-element tuple variants serialize like {"<variant>": [values..]}
+ let flag_s = to_vec(&Bar::Flag("foo".to_string(), true)).unwrap();
+ let mut flag_map = BTreeMap::new();
+ flag_map.insert(
+ "Flag",
+ vec![Value::Text("foo".to_string()), Value::Bool(true)],
+ );
+ let flag_map_s = to_vec(&flag_map).unwrap();
+ assert_eq!(flag_s, flag_map_s);
+
+ // struct-variants serialize like {"<variant>", {struct..}}
+ let point_s = to_vec(&Bar::Point { x: 5, y: -5 }).unwrap();
+ let mut point_map = BTreeMap::new();
+ point_map.insert("Point", Value::Map(struct_map));
+ let point_map_s = to_vec(&point_map).unwrap();
+ assert_eq!(point_s, point_map_s);
+
+ // deserialization of all encodings should just work
+ let empty_str_ds = from_slice(&empty_str_s).unwrap();
+ assert_eq!(Bar::Empty, empty_str_ds);
+
+ let number_vec_ds = from_slice(&number_vec_s).unwrap();
+ assert_eq!(Bar::Number(42), number_vec_ds);
+ let number_map_ds = from_slice(&number_map_s).unwrap();
+ assert_eq!(Bar::Number(42), number_map_ds);
+
+ let flag_vec_ds = from_slice(&flag_vec_s).unwrap();
+ assert_eq!(Bar::Flag("foo".to_string(), true), flag_vec_ds);
+ let flag_map_ds = from_slice(&flag_map_s).unwrap();
+ assert_eq!(Bar::Flag("foo".to_string(), true), flag_map_ds);
+
+ let point_vec_ds = from_slice(&point_vec_s).unwrap();
+ assert_eq!(Bar::Point { x: 5, y: -5 }, point_vec_ds);
+ let point_map_ds = from_slice(&point_map_s).unwrap();
+ assert_eq!(Bar::Point { x: 5, y: -5 }, point_map_ds);
+ }
+}
diff --git a/third_party/rust/serde_cbor/tests/kietaub.cbor b/third_party/rust/serde_cbor/tests/kietaub.cbor
new file mode 100644
index 0000000000..866a093132
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/kietaub.cbor
Binary files differ
diff --git a/third_party/rust/serde_cbor/tests/ser.rs b/third_party/rust/serde_cbor/tests/ser.rs
new file mode 100644
index 0000000000..d374ce2faf
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/ser.rs
@@ -0,0 +1,254 @@
+use serde::Serialize;
+use serde_cbor::ser::{Serializer, SliceWrite};
+
+#[test]
+fn test_str() {
+ serialize_and_compare("foobar", b"ffoobar");
+}
+
+#[test]
+fn test_list() {
+ serialize_and_compare(&[1, 2, 3], b"\x83\x01\x02\x03");
+}
+
+#[test]
+fn test_float() {
+ serialize_and_compare(12.3f64, b"\xfb@(\x99\x99\x99\x99\x99\x9a");
+}
+
+#[test]
+fn test_integer() {
+ // u8
+ serialize_and_compare(24, b"\x18\x18");
+ // i8
+ serialize_and_compare(-5, b"\x24");
+ // i16
+ serialize_and_compare(-300, b"\x39\x01\x2b");
+ // i32
+ serialize_and_compare(-23567997, b"\x3a\x01\x67\x9e\x7c");
+ // u64
+ serialize_and_compare(::core::u64::MAX, b"\x1b\xff\xff\xff\xff\xff\xff\xff\xff");
+}
+
+fn serialize_and_compare<T: Serialize>(value: T, expected: &[u8]) {
+ let mut slice = [0u8; 64];
+ let writer = SliceWrite::new(&mut slice);
+ let mut serializer = Serializer::new(writer);
+ value.serialize(&mut serializer).unwrap();
+ let writer = serializer.into_inner();
+ let end = writer.bytes_written();
+ let slice = writer.into_inner();
+ assert_eq!(&slice[..end], expected);
+}
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use serde::Serializer;
+ use serde_cbor::ser;
+ use serde_cbor::{from_slice, to_vec};
+ use std::collections::BTreeMap;
+
+ #[test]
+ fn test_string() {
+ let value = "foobar".to_owned();
+ assert_eq!(&to_vec(&value).unwrap()[..], b"ffoobar");
+ }
+
+ #[test]
+ fn test_list() {
+ let value = vec![1, 2, 3];
+ assert_eq!(&to_vec(&value).unwrap()[..], b"\x83\x01\x02\x03");
+ }
+
+ #[test]
+ fn test_object() {
+ let mut object = BTreeMap::new();
+ object.insert("a".to_owned(), "A".to_owned());
+ object.insert("b".to_owned(), "B".to_owned());
+ object.insert("c".to_owned(), "C".to_owned());
+ object.insert("d".to_owned(), "D".to_owned());
+ object.insert("e".to_owned(), "E".to_owned());
+ let vec = to_vec(&object).unwrap();
+ let test_object = from_slice(&vec[..]).unwrap();
+ assert_eq!(object, test_object);
+ }
+
+ #[test]
+ fn test_object_list_keys() {
+ let mut object = BTreeMap::new();
+ object.insert(vec![0i64], ());
+ object.insert(vec![100i64], ());
+ object.insert(vec![-1i64], ());
+ object.insert(vec![-2i64], ());
+ object.insert(vec![0i64, 0i64], ());
+ object.insert(vec![0i64, -1i64], ());
+ let vec = to_vec(&serde_cbor::value::to_value(object.clone()).unwrap()).unwrap();
+ assert_eq!(
+ vec![
+ 166, 129, 0, 246, 129, 24, 100, 246, 129, 32, 246, 129, 33, 246, 130, 0, 0, 246,
+ 130, 0, 32, 246
+ ],
+ vec
+ );
+ let test_object = from_slice(&vec[..]).unwrap();
+ assert_eq!(object, test_object);
+ }
+
+ #[test]
+ fn test_object_object_keys() {
+ use std::iter::FromIterator;
+ let mut object = BTreeMap::new();
+ let keys = vec![
+ vec!["a"],
+ vec!["b"],
+ vec!["c"],
+ vec!["d"],
+ vec!["aa"],
+ vec!["a", "aa"],
+ ]
+ .into_iter()
+ .map(|v| BTreeMap::from_iter(v.into_iter().map(|s| (s.to_owned(), ()))));
+
+ for key in keys {
+ object.insert(key, ());
+ }
+ let vec = to_vec(&serde_cbor::value::to_value(object.clone()).unwrap()).unwrap();
+ assert_eq!(
+ vec![
+ 166, 161, 97, 97, 246, 246, 161, 97, 98, 246, 246, 161, 97, 99, 246, 246, 161, 97,
+ 100, 246, 246, 161, 98, 97, 97, 246, 246, 162, 97, 97, 246, 98, 97, 97, 246, 246
+ ],
+ vec
+ );
+ let test_object = from_slice(&vec[..]).unwrap();
+ assert_eq!(object, test_object);
+ }
+
+ #[test]
+ fn test_float() {
+ let vec = to_vec(&12.3f64).unwrap();
+ assert_eq!(vec, b"\xfb@(\x99\x99\x99\x99\x99\x9a");
+ }
+
+ #[test]
+ fn test_f32() {
+ let vec = to_vec(&4000.5f32).unwrap();
+ assert_eq!(vec, b"\xfa\x45\x7a\x08\x00");
+ }
+
+ #[test]
+ fn test_infinity() {
+ let vec = to_vec(&::std::f64::INFINITY).unwrap();
+ assert_eq!(vec, b"\xf9|\x00");
+ }
+
+ #[test]
+ fn test_neg_infinity() {
+ let vec = to_vec(&::std::f64::NEG_INFINITY).unwrap();
+ assert_eq!(vec, b"\xf9\xfc\x00");
+ }
+
+ #[test]
+ fn test_nan() {
+ let vec = to_vec(&::std::f32::NAN).unwrap();
+ assert_eq!(vec, b"\xf9\x7e\x00");
+ }
+
+ #[test]
+ fn test_integer() {
+ // u8
+ let vec = to_vec(&24).unwrap();
+ assert_eq!(vec, b"\x18\x18");
+ // i8
+ let vec = to_vec(&-5).unwrap();
+ assert_eq!(vec, b"\x24");
+ // i16
+ let vec = to_vec(&-300).unwrap();
+ assert_eq!(vec, b"\x39\x01\x2b");
+ // i32
+ let vec = to_vec(&-23567997).unwrap();
+ assert_eq!(vec, b"\x3a\x01\x67\x9e\x7c");
+ // u64
+ let vec = to_vec(&::std::u64::MAX).unwrap();
+ assert_eq!(vec, b"\x1b\xff\xff\xff\xff\xff\xff\xff\xff");
+ }
+
+ #[test]
+ fn test_self_describing() {
+ let mut vec = Vec::new();
+ {
+ let mut serializer = ser::Serializer::new(&mut vec);
+ serializer.self_describe().unwrap();
+ serializer.serialize_u64(9).unwrap();
+ }
+ assert_eq!(vec, b"\xd9\xd9\xf7\x09");
+ }
+
+ #[test]
+ fn test_ip_addr() {
+ use std::net::Ipv4Addr;
+
+ let addr = Ipv4Addr::new(8, 8, 8, 8);
+ let vec = to_vec(&addr).unwrap();
+ println!("{:?}", vec);
+ assert_eq!(vec.len(), 5);
+ let test_addr: Ipv4Addr = from_slice(&vec).unwrap();
+ assert_eq!(addr, test_addr);
+ }
+
+ /// Test all of CBOR's fixed-length byte string types
+ #[test]
+ fn test_byte_string() {
+ // Very short byte strings have 1-byte headers
+ let short = vec![0, 1, 2, 255];
+ let mut short_s = Vec::new();
+ serde_cbor::Serializer::new(&mut short_s)
+ .serialize_bytes(&short)
+ .unwrap();
+ assert_eq!(&short_s[..], [0x44, 0, 1, 2, 255]);
+
+ // byte strings > 23 bytes have 2-byte headers
+ let medium = vec![
+ 0u8, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 255,
+ ];
+ let mut medium_s = Vec::new();
+ serde_cbor::Serializer::new(&mut medium_s)
+ .serialize_bytes(&medium)
+ .unwrap();
+ assert_eq!(
+ &medium_s[..],
+ [
+ 0x58, 24, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 255
+ ]
+ );
+
+ // byte strings > 256 bytes have 3-byte headers
+ let long_vec = (0..256).map(|i| (i & 0xFF) as u8).collect::<Vec<_>>();
+ let mut long_s = Vec::new();
+ serde_cbor::Serializer::new(&mut long_s)
+ .serialize_bytes(&long_vec)
+ .unwrap();
+ assert_eq!(&long_s[0..3], [0x59, 1, 0]);
+ assert_eq!(&long_s[3..], &long_vec[..]);
+
+ // byte strings > 2^16 bytes have 5-byte headers
+ let very_long_vec = (0..65536).map(|i| (i & 0xFF) as u8).collect::<Vec<_>>();
+ let mut very_long_s = Vec::new();
+ serde_cbor::Serializer::new(&mut very_long_s)
+ .serialize_bytes(&very_long_vec)
+ .unwrap();
+ assert_eq!(&very_long_s[0..5], [0x5a, 0, 1, 0, 0]);
+ assert_eq!(&very_long_s[5..], &very_long_vec[..]);
+
+ // byte strings > 2^32 bytes have 9-byte headers, but they take too much RAM
+ // to test in Travis.
+ }
+
+ #[test]
+ fn test_half() {
+ let vec = to_vec(&42.5f32).unwrap();
+ assert_eq!(vec, b"\xF9\x51\x50");
+ assert_eq!(from_slice::<f32>(&vec[..]).unwrap(), 42.5f32);
+ }
+}
diff --git a/third_party/rust/serde_cbor/tests/std_types.rs b/third_party/rust/serde_cbor/tests/std_types.rs
new file mode 100644
index 0000000000..7a7ded484c
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/std_types.rs
@@ -0,0 +1,186 @@
+#[macro_use]
+extern crate serde_derive;
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use std::u8;
+
+ use serde_cbor::de::from_mut_slice;
+ use serde_cbor::ser::{to_vec, to_vec_packed};
+ use serde_cbor::{from_reader, from_slice};
+
+ fn to_binary(s: &'static str) -> Vec<u8> {
+ assert!(s.len() % 2 == 0);
+ let mut b = Vec::with_capacity(s.len() / 2);
+ for i in 0..s.len() / 2 {
+ b.push(u8::from_str_radix(&s[i * 2..(i + 1) * 2], 16).unwrap());
+ }
+ b
+ }
+
+ macro_rules! testcase {
+ ($name:ident, f64, $expr:expr, $s:expr) => {
+ #[test]
+ fn $name() {
+ let expr: f64 = $expr;
+ let mut serialized = to_binary($s);
+ assert_eq!(to_vec(&expr).unwrap(), serialized);
+ let parsed: f64 = from_slice(&serialized[..]).unwrap();
+ if !expr.is_nan() {
+ assert_eq!(expr, parsed);
+ } else {
+ assert!(parsed.is_nan())
+ }
+
+ let parsed: f64 = from_reader(&mut &serialized[..]).unwrap();
+ if !expr.is_nan() {
+ assert_eq!(expr, parsed);
+ } else {
+ assert!(parsed.is_nan())
+ }
+
+ let parsed: f64 = from_mut_slice(&mut serialized[..]).unwrap();
+ if !expr.is_nan() {
+ assert_eq!(expr, parsed);
+ } else {
+ assert!(parsed.is_nan())
+ }
+ }
+ };
+ ($name:ident, $ty:ty, $expr:expr, $s:expr) => {
+ #[test]
+ fn $name() {
+ let expr: $ty = $expr;
+ let mut serialized = to_binary($s);
+ assert_eq!(
+ to_vec(&expr).expect("ser1 works"),
+ serialized,
+ "serialization differs"
+ );
+ let parsed: $ty = from_slice(&serialized[..]).expect("de1 works");
+ assert_eq!(parsed, expr, "parsed result differs");
+ let packed = &to_vec_packed(&expr).expect("serializing packed")[..];
+ let parsed_from_packed: $ty = from_slice(packed).expect("parsing packed");
+ assert_eq!(parsed_from_packed, expr, "packed roundtrip fail");
+
+ let parsed: $ty = from_reader(&mut &serialized[..]).unwrap();
+ assert_eq!(parsed, expr, "parsed result differs");
+ let mut packed = to_vec_packed(&expr).expect("serializing packed");
+ let parsed_from_packed: $ty =
+ from_reader(&mut &packed[..]).expect("parsing packed");
+ assert_eq!(parsed_from_packed, expr, "packed roundtrip fail");
+
+ let parsed: $ty = from_mut_slice(&mut serialized[..]).unwrap();
+ assert_eq!(parsed, expr, "parsed result differs");
+ let parsed_from_packed: $ty =
+ from_mut_slice(&mut packed[..]).expect("parsing packed");
+ assert_eq!(parsed_from_packed, expr, "packed roundtrip fail");
+ }
+ };
+ }
+
+ testcase!(test_bool_false, bool, false, "f4");
+ testcase!(test_bool_true, bool, true, "f5");
+ testcase!(test_isize_neg_256, isize, -256, "38ff");
+ testcase!(test_isize_neg_257, isize, -257, "390100");
+ testcase!(test_isize_255, isize, 255, "18ff");
+ testcase!(test_i8_5, i8, 5, "05");
+ testcase!(test_i8_23, i8, 23, "17");
+ testcase!(test_i8_24, i8, 24, "1818");
+ testcase!(test_i8_neg_128, i8, -128, "387f");
+ testcase!(test_u32_98745874, u32, 98745874, "1a05e2be12");
+ testcase!(test_f32_1234_point_5, f32, 1234.5, "fa449a5000");
+ testcase!(test_f64_12345_point_6, f64, 12345.6, "fb40c81ccccccccccd");
+ testcase!(test_f64_nan, f64, ::std::f64::NAN, "f97e00");
+ testcase!(test_f64_infinity, f64, ::std::f64::INFINITY, "f97c00");
+ testcase!(test_f64_neg_infinity, f64, -::std::f64::INFINITY, "f9fc00");
+ testcase!(test_char_null, char, '\x00', "6100");
+ testcase!(test_char_broken_heart, char, '💔', "64f09f9294");
+ testcase!(
+ test_str_pangram_de,
+ String,
+ "aâø↓é".to_owned(),
+ "6a61c3a2c3b8e28693c3a9"
+ );
+ testcase!(test_unit, (), (), "f6");
+
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct UnitStruct;
+ testcase!(test_unit_struct, UnitStruct, UnitStruct, "f6");
+
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct NewtypeStruct(bool);
+ testcase!(
+ test_newtype_struct,
+ NewtypeStruct,
+ NewtypeStruct(true),
+ "f5"
+ );
+
+ testcase!(test_option_none, Option<u8>, None, "f6");
+ testcase!(test_option_some, Option<u8>, Some(42), "182a");
+
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct Person {
+ name: String,
+ year_of_birth: u16,
+ profession: Option<String>,
+ }
+
+ testcase!(test_person_struct,
+ Person,
+ Person {
+ name: "Grace Hopper".to_string(),
+ year_of_birth: 1906,
+ profession: Some("computer scientist".to_string()),
+ },
+ "a3646e616d656c477261636520486f707065726d796561725f6f665f62697274681907726a70726f66657373696f6e72636f6d707574657220736369656e74697374");
+
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct OptionalPerson {
+ name: String,
+ #[serde(skip_serializing_if = "Option::is_none")]
+ year_of_birth: Option<u16>,
+ profession: Option<String>,
+ }
+
+ testcase!(test_optional_person_struct,
+ OptionalPerson,
+ OptionalPerson {
+ name: "Grace Hopper".to_string(),
+ year_of_birth: None,
+ profession: Some("computer scientist".to_string()),
+ },
+ "a2646e616d656c477261636520486f707065726a70726f66657373696f6e72636f6d707574657220736369656e74697374");
+
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ enum Color {
+ Red,
+ Blue,
+ Yellow,
+ Other(u64),
+ Alpha(u64, u8),
+ }
+
+ testcase!(test_color_enum, Color, Color::Blue, "64426c7565");
+ testcase!(
+ test_color_enum_transparent,
+ Color,
+ Color::Other(42),
+ "a1654f74686572182a"
+ );
+ testcase!(
+ test_color_enum_with_alpha,
+ Color,
+ Color::Alpha(234567, 60),
+ "a165416c706861821a00039447183c"
+ );
+ testcase!(test_i128_a, i128, -1i128, "20");
+ testcase!(
+ test_i128_b,
+ i128,
+ -18446744073709551616i128,
+ "3BFFFFFFFFFFFFFFFF"
+ );
+ testcase!(test_u128, u128, 17, "11");
+}
diff --git a/third_party/rust/serde_cbor/tests/tags.rs b/third_party/rust/serde_cbor/tests/tags.rs
new file mode 100644
index 0000000000..92534c023d
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/tags.rs
@@ -0,0 +1,48 @@
+#[cfg(feature = "tags")]
+mod tagtests {
+ use serde_cbor::value::Value;
+ use serde_cbor::{from_slice, to_vec};
+
+ fn decode_hex(s: &str) -> std::result::Result<Vec<u8>, std::num::ParseIntError> {
+ (0..s.len())
+ .step_by(2)
+ .map(|i| u8::from_str_radix(&s[i..i + 2], 16))
+ .collect()
+ }
+
+ // get bytes from http://cbor.me/ trees
+ fn parse_cbor_me(example: &str) -> std::result::Result<Vec<u8>, std::num::ParseIntError> {
+ let hex = example
+ .split("\n")
+ .flat_map(|line| line.split("#").take(1))
+ .collect::<Vec<&str>>()
+ .join("")
+ .replace(" ", "");
+ decode_hex(&hex)
+ }
+
+ #[test]
+ fn tagged_cbor_roundtrip() {
+ let data = r#"
+C1 # tag(1)
+ 82 # array(2)
+ C2 # tag(2)
+ 63 # text(3)
+ 666F6F # "foo"
+ C3 # tag(3)
+ A1 # map(1)
+ C4 # tag(4)
+ 61 # text(1)
+ 61 # "a"
+ C5 # tag(5)
+ 61 # text(1)
+ 62 # "b"
+ "#;
+ let bytes1 = parse_cbor_me(&data).unwrap();
+ let value1: Value = from_slice(&bytes1).unwrap();
+ let bytes2 = to_vec(&value1).unwrap();
+ let value2: Value = from_slice(&bytes2).unwrap();
+ assert_eq!(bytes1, bytes2);
+ assert_eq!(value1, value2);
+ }
+}
diff --git a/third_party/rust/serde_cbor/tests/value.rs b/third_party/rust/serde_cbor/tests/value.rs
new file mode 100644
index 0000000000..554d74266c
--- /dev/null
+++ b/third_party/rust/serde_cbor/tests/value.rs
@@ -0,0 +1,100 @@
+#[macro_use]
+extern crate serde_derive;
+
+#[cfg(feature = "std")]
+mod std_tests {
+ use serde_cbor;
+
+ use std::collections::BTreeMap;
+
+ #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
+ struct TupleStruct(String, i32, u64);
+
+ #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
+ struct UnitStruct;
+
+ #[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
+ struct Struct<'a> {
+ tuple_struct: TupleStruct,
+ tuple: (String, f32, f64),
+ map: BTreeMap<String, String>,
+ bytes: &'a [u8],
+ array: Vec<String>,
+ unit_array: Vec<UnitStruct>,
+ }
+
+ use serde_cbor::value::Value;
+ use std::iter::FromIterator;
+
+ #[test]
+ fn serde() {
+ let tuple_struct = TupleStruct(format!("test"), -60, 3000);
+
+ let tuple = (format!("hello"), -50.0040957, -12.094635556478);
+
+ let map = BTreeMap::from_iter(
+ [
+ (format!("key1"), format!("value1")),
+ (format!("key2"), format!("value2")),
+ (format!("key3"), format!("value3")),
+ (format!("key4"), format!("value4")),
+ ]
+ .iter()
+ .cloned(),
+ );
+
+ let bytes = b"test byte string";
+
+ let array = vec![format!("one"), format!("two"), format!("three")];
+ let unit_array = vec![UnitStruct, UnitStruct, UnitStruct];
+
+ let data = Struct {
+ tuple_struct,
+ tuple,
+ map,
+ bytes,
+ array,
+ unit_array,
+ };
+
+ let value = serde_cbor::value::to_value(data.clone()).unwrap();
+ println!("{:?}", value);
+
+ let data_ser = serde_cbor::to_vec(&value).unwrap();
+ let data_de_value: Value = serde_cbor::from_slice(&data_ser).unwrap();
+
+ fn as_object(value: &Value) -> &BTreeMap<Value, Value> {
+ if let Value::Map(ref v) = value {
+ return v;
+ }
+ panic!()
+ }
+
+ for ((k1, v1), (k2, v2)) in as_object(&value)
+ .iter()
+ .zip(as_object(&data_de_value).iter())
+ {
+ assert_eq!(k1, k2);
+ assert_eq!(v1, v2);
+ }
+
+ assert_eq!(value, data_de_value);
+ }
+
+ #[derive(Debug, Deserialize, Serialize)]
+ struct SmallStruct {
+ spam: u32,
+ eggs: u32,
+ }
+
+ #[test]
+ fn small_struct() {
+ // Test whether the packed format works.
+ // Field names should not be serialized,
+ // instead field indizes are serialized.
+ let value = SmallStruct { spam: 17, eggs: 42 };
+ let data = serde_cbor::ser::to_vec_packed(&value).unwrap();
+ let reference = b"\xa2\x00\x11\x01\x18\x2a";
+ assert_eq!(data, reference);
+ }
+}
diff --git a/third_party/rust/serde_derive/.cargo-checksum.json b/third_party/rust/serde_derive/.cargo-checksum.json
new file mode 100644
index 0000000000..4f033d7fe2
--- /dev/null
+++ b/third_party/rust/serde_derive/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"72ed2b0578c6c4fbbd14ab2062502092990c48f4687a01a4a07d7fdbb6330756","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"3c12b60b6c77a201665344a7612b42392e77ddc3e907f5a14e3f3a4bb6c4692e","build.rs":"d9a0df0c4dd552ff7fd0c3b3828cb1fff4fc4ab15bd98539881929b76b98003b","crates-io.md":"ee22254ee64c3189eef3e707c8d75dc66a8df2a7ee9e518d95238950780ec387","src/bound.rs":"268b4995a5d0a129dcbd6e32ef11f587bd271df3f6c4f7230ed54bc99f5ce871","src/de.rs":"b28c2fcf5214d33ba1dc855b60634db18608a26f39f9f92bbedf62c456fa8d10","src/dummy.rs":"cb154465020973be8ab6079ab8574df46f38fbe028a5561cd6b1a8bfa1a35478","src/fragment.rs":"5548ba65a53d90a296f60c1328a7a7fb040db467f59c2f5210b2fb320457145d","src/internals/ast.rs":"b019865eef92c1ddbb9029423ac22179f132dc655a51c09fb2a42f4aaef172fd","src/internals/attr.rs":"778074380c4e353b77e03aff9edf15fda9e15a0e7ec25cdfc51d79a26636ddef","src/internals/case.rs":"9492f0c5142d7b7e8cd39c86d13a855e5ce4489425adb2b96aed89e1b7851ac0","src/internals/check.rs":"6b84278b034a156784fc56153df3def1660bcfcfde0cd59f8facce1750717c7d","src/internals/ctxt.rs":"6fa544ae52914498a62a395818ebdc1b36ac2fb5903c60afb741a864ad559f1c","src/internals/mod.rs":"f32138ff19d57eb00f88ba11f6b015efab2102657804f71ebbf386a3698dad91","src/internals/receiver.rs":"cd125ba4a3dd6250ed4737555c58627bffd630a536cd7223068eed7c10a170d8","src/internals/respan.rs":"899753859c58ce5f532a3ec4584796a52f13ed5a0533191e48c953ba5c1b52ff","src/internals/symbol.rs":"3c9ce461773b7df3bb64d82aa5a0d93052c3bb0e60209db6c0b5c10ee9cfc9cf","src/lib.rs":"6a80c0114dcf9924cbbbc03f443cfd0d299be9f89ba6c4fdc2867d990aba5063","src/pretend.rs":"4aa53bf6c1350fbcfc8c4997f720cde61a8eb3aab73bb8c101b0f0a74901892b","src/ser.rs":"8f9ffe1d8bcd28bd40e8d94d688547fa1d518cc722d0292f47d951152c406dd9","src/this.rs":"a2c128955324c2994ed7cdc3fe4eeceb7ad8a0f9d071665a8378c85c8df64ce2","src/try.rs":"b171b0088c23ebf4bfa07ba457881b41ac5e547d55dd16f737ea988d34badf61"},"package":"af487d118eecd09402d70a5d72551860e788df87b464af30e5ea6a38c75c541e"} \ No newline at end of file
diff --git a/third_party/rust/serde_derive/Cargo.toml b/third_party/rust/serde_derive/Cargo.toml
new file mode 100644
index 0000000000..6258d9df1d
--- /dev/null
+++ b/third_party/rust/serde_derive/Cargo.toml
@@ -0,0 +1,63 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+rust-version = "1.31"
+name = "serde_derive"
+version = "1.0.152"
+authors = [
+ "Erick Tryzelaar <erick.tryzelaar@gmail.com>",
+ "David Tolnay <dtolnay@gmail.com>",
+]
+include = [
+ "build.rs",
+ "src/**/*.rs",
+ "crates-io.md",
+ "README.md",
+ "LICENSE-APACHE",
+ "LICENSE-MIT",
+]
+description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
+homepage = "https://serde.rs"
+documentation = "https://serde.rs/derive.html"
+readme = "crates-io.md"
+keywords = [
+ "serde",
+ "serialization",
+ "no_std",
+ "derive",
+]
+categories = ["no-std"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/serde-rs/serde"
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+name = "serde_derive"
+proc-macro = true
+
+[dependencies.proc-macro2]
+version = "1.0"
+
+[dependencies.quote]
+version = "1.0"
+
+[dependencies.syn]
+version = "1.0.104"
+
+[dev-dependencies.serde]
+version = "1.0"
+
+[features]
+default = []
+deserialize_in_place = []
diff --git a/third_party/rust/serde_derive/LICENSE-APACHE b/third_party/rust/serde_derive/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/serde_derive/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/third_party/rust/serde_derive/LICENSE-MIT b/third_party/rust/serde_derive/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/third_party/rust/serde_derive/LICENSE-MIT
@@ -0,0 +1,23 @@
+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.
diff --git a/third_party/rust/serde_derive/README.md b/third_party/rust/serde_derive/README.md
new file mode 100644
index 0000000000..c3f6575ef0
--- /dev/null
+++ b/third_party/rust/serde_derive/README.md
@@ -0,0 +1,114 @@
+# Serde &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.13+]][Rust 1.13] [![serde_derive: rustc 1.31+]][Rust 1.31]
+
+[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master
+[actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster
+[Latest Version]: https://img.shields.io/crates/v/serde.svg
+[crates.io]: https://crates.io/crates/serde
+[serde: rustc 1.13+]: https://img.shields.io/badge/serde-rustc_1.13+-lightgray.svg
+[serde_derive: rustc 1.31+]: https://img.shields.io/badge/serde_derive-rustc_1.31+-lightgray.svg
+[Rust 1.13]: https://blog.rust-lang.org/2016/11/10/Rust-1.13.html
+[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.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/derive.html)
+- [Examples](https://serde.rs/examples.html)
+- [API documentation](https://docs.rs/serde)
+- [Release notes](https://github.com/serde-rs/serde/releases)
+
+## Serde in action
+
+<details>
+<summary>
+Click to show Cargo.toml.
+<a href="https://play.rust-lang.org/?edition=2018&gist=72755f28f99afc95e01d63174b28c1f5" 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. The "derive" feature is only required when
+# using #[derive(Serialize, Deserialize)] to make Serde work with structs
+# and enums defined in your crate.
+serde = { version = "1.0", features = ["derive"] }
+
+# 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
+use serde::{Serialize, Deserialize};
+
+#[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 is one of the most widely used Rust libraries so any place that Rustaceans
+congregate will be able to help you out. For chat, consider trying the
+[#rust-questions] or [#rust-beginners] channels of the unofficial community
+Discord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or
+[#beginners] channels of the official Rust Project Discord (invite:
+<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
+asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
+[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
+[Discourse forum][discourse]. It's acceptable to file a support issue in this
+repo but they tend not to get as many eyes as any of the above and may get
+closed without a response after some time.
+
+[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
+[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
+[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
+[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
+[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
+[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
+[/r/rust]: https://www.reddit.com/r/rust
+[discourse]: https://users.rust-lang.org
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+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.
+</sub>
diff --git a/third_party/rust/serde_derive/build.rs b/third_party/rust/serde_derive/build.rs
new file mode 100644
index 0000000000..1249dab597
--- /dev/null
+++ b/third_party/rust/serde_derive/build.rs
@@ -0,0 +1,38 @@
+use std::env;
+use std::process::Command;
+use std::str;
+
+// The rustc-cfg strings below are *not* public API. Please let us know by
+// opening a GitHub issue if your build environment requires some way to enable
+// these cfgs other than by executing our build script.
+fn main() {
+ println!("cargo:rerun-if-changed=build.rs");
+
+ let minor = match rustc_minor_version() {
+ Some(minor) => minor,
+ None => return,
+ };
+
+ // Underscore const names stabilized in Rust 1.37:
+ // https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#using-unnamed-const-items-for-macros
+ if minor < 37 {
+ println!("cargo:rustc-cfg=no_underscore_consts");
+ }
+
+ // The ptr::addr_of! macro stabilized in Rust 1.51:
+ // https://blog.rust-lang.org/2021/03/25/Rust-1.51.0.html#stabilized-apis
+ if minor < 51 {
+ println!("cargo:rustc-cfg=no_ptr_addr_of");
+ }
+}
+
+fn rustc_minor_version() -> Option<u32> {
+ let rustc = env::var_os("RUSTC")?;
+ let output = Command::new(rustc).arg("--version").output().ok()?;
+ let version = str::from_utf8(&output.stdout).ok()?;
+ let mut pieces = version.split('.');
+ if pieces.next() != Some("rustc 1") {
+ return None;
+ }
+ pieces.next()?.parse().ok()
+}
diff --git a/third_party/rust/serde_derive/crates-io.md b/third_party/rust/serde_derive/crates-io.md
new file mode 100644
index 0000000000..6e0ec280cf
--- /dev/null
+++ b/third_party/rust/serde_derive/crates-io.md
@@ -0,0 +1,65 @@
+<!-- Serde readme rendered on crates.io -->
+
+**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/derive.html)
+- [Examples](https://serde.rs/examples.html)
+- [API documentation](https://docs.rs/serde)
+- [Release notes](https://github.com/serde-rs/serde/releases)
+
+## Serde in action
+
+```rust
+use serde::{Serialize, Deserialize};
+
+#[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 is one of the most widely used Rust libraries so any place that Rustaceans
+congregate will be able to help you out. For chat, consider trying the
+[#rust-questions] or [#rust-beginners] channels of the unofficial community
+Discord (invite: <https://discord.gg/rust-lang-community>, the [#rust-usage] or
+[#beginners] channels of the official Rust Project Discord (invite:
+<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
+asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
+[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
+[Discourse forum][discourse]. It's acceptable to file a support issue in this
+repo but they tend not to get as many eyes as any of the above and may get
+closed without a response after some time.
+
+[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
+[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
+[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
+[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
+[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
+[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
+[/r/rust]: https://www.reddit.com/r/rust
+[discourse]: https://users.rust-lang.org
diff --git a/third_party/rust/serde_derive/src/bound.rs b/third_party/rust/serde_derive/src/bound.rs
new file mode 100644
index 0000000000..74c95069c3
--- /dev/null
+++ b/third_party/rust/serde_derive/src/bound.rs
@@ -0,0 +1,406 @@
+use std::collections::HashSet;
+
+use syn;
+use syn::punctuated::{Pair, Punctuated};
+
+use internals::ast::{Container, Data};
+use internals::{attr, ungroup};
+
+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(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()
+ .predicates
+ .extend(predicates.iter().cloned());
+ generics
+}
+
+pub fn with_where_predicates_from_fields(
+ cont: &Container,
+ generics: &syn::Generics,
+ from_field: fn(&attr::Field) -> Option<&[syn::WherePredicate]>,
+) -> syn::Generics {
+ let predicates = cont
+ .data
+ .all_fields()
+ .filter_map(|field| from_field(&field.attrs))
+ .flat_map(<[syn::WherePredicate]>::to_vec);
+
+ let mut generics = generics.clone();
+ 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(variants) => variants,
+ Data::Struct(_, _) => {
+ return generics.clone();
+ }
+ };
+
+ let predicates = variants
+ .iter()
+ .filter_map(|variant| from_variant(&variant.attrs))
+ .flat_map(<[syn::WherePredicate]>::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(
+ cont: &Container,
+ generics: &syn::Generics,
+ filter: fn(&attr::Field, Option<&attr::Variant>) -> bool,
+ bound: &syn::Path,
+) -> 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_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_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> FindTyParams<'ast> {
+ fn visit_field(&mut self, field: &'ast syn::Field) {
+ if let syn::Type::Path(ty) = ungroup(&field.ty) {
+ if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() {
+ 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.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_type_params.contains(id) {
+ self.relevant_type_params.insert(id.clone());
+ }
+ }
+ for segment in &path.segments {
+ self.visit_path_segment(segment);
+ }
+ }
+
+ // Everything below is simply traversing the syntax tree.
+
+ fn visit_type(&mut self, ty: &'ast syn::Type) {
+ match ty {
+ syn::Type::Array(ty) => self.visit_type(&ty.elem),
+ syn::Type::BareFn(ty) => {
+ for arg in &ty.inputs {
+ self.visit_type(&arg.ty);
+ }
+ self.visit_return_type(&ty.output);
+ }
+ syn::Type::Group(ty) => self.visit_type(&ty.elem),
+ syn::Type::ImplTrait(ty) => {
+ for bound in &ty.bounds {
+ self.visit_type_param_bound(bound);
+ }
+ }
+ syn::Type::Macro(ty) => self.visit_macro(&ty.mac),
+ syn::Type::Paren(ty) => self.visit_type(&ty.elem),
+ syn::Type::Path(ty) => {
+ if let Some(qself) = &ty.qself {
+ self.visit_type(&qself.ty);
+ }
+ self.visit_path(&ty.path);
+ }
+ syn::Type::Ptr(ty) => self.visit_type(&ty.elem),
+ syn::Type::Reference(ty) => self.visit_type(&ty.elem),
+ syn::Type::Slice(ty) => self.visit_type(&ty.elem),
+ syn::Type::TraitObject(ty) => {
+ for bound in &ty.bounds {
+ self.visit_type_param_bound(bound);
+ }
+ }
+ syn::Type::Tuple(ty) => {
+ for elem in &ty.elems {
+ self.visit_type(elem);
+ }
+ }
+
+ syn::Type::Infer(_) | syn::Type::Never(_) | syn::Type::Verbatim(_) => {}
+
+ #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
+ _ => {}
+ }
+ }
+
+ fn visit_path_segment(&mut self, segment: &'ast syn::PathSegment) {
+ self.visit_path_arguments(&segment.arguments);
+ }
+
+ fn visit_path_arguments(&mut self, arguments: &'ast syn::PathArguments) {
+ match arguments {
+ syn::PathArguments::None => {}
+ syn::PathArguments::AngleBracketed(arguments) => {
+ for arg in &arguments.args {
+ match arg {
+ syn::GenericArgument::Type(arg) => self.visit_type(arg),
+ syn::GenericArgument::Binding(arg) => self.visit_type(&arg.ty),
+ syn::GenericArgument::Lifetime(_)
+ | syn::GenericArgument::Constraint(_)
+ | syn::GenericArgument::Const(_) => {}
+ }
+ }
+ }
+ syn::PathArguments::Parenthesized(arguments) => {
+ for argument in &arguments.inputs {
+ self.visit_type(argument);
+ }
+ self.visit_return_type(&arguments.output);
+ }
+ }
+ }
+
+ fn visit_return_type(&mut self, return_type: &'ast syn::ReturnType) {
+ match return_type {
+ syn::ReturnType::Default => {}
+ syn::ReturnType::Type(_, output) => self.visit_type(output),
+ }
+ }
+
+ fn visit_type_param_bound(&mut self, bound: &'ast syn::TypeParamBound) {
+ match bound {
+ syn::TypeParamBound::Trait(bound) => self.visit_path(&bound.path),
+ syn::TypeParamBound::Lifetime(_) => {}
+ }
+ }
+
+ // 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: &'ast syn::Macro) {}
+ }
+
+ let all_type_params = generics
+ .type_params()
+ .map(|param| param.ident.clone())
+ .collect();
+
+ let mut visitor = FindTyParams {
+ all_type_params,
+ relevant_type_params: HashSet::new(),
+ associated_type_usage: Vec::new(),
+ };
+ match &cont.data {
+ Data::Enum(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 {
+ visitor.visit_field(field.original);
+ }
+ }
+ }
+ Data::Struct(_, fields) => {
+ for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
+ 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
+ .type_params()
+ .map(|param| param.ident.clone())
+ .filter(|id| relevant_type_params.contains(id))
+ .map(|id| syn::TypePath {
+ qself: None,
+ path: id.into(),
+ })
+ .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(bounded_ty),
+ colon_token: <Token![:]>::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(),
+ })
+ });
+
+ let mut generics = generics.clone();
+ 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()
+ .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: <Token![:]>::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(),
+ }));
+ 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.clone(),
+ colon_token: None,
+ bounds: Punctuated::new(),
+ };
+
+ let params = Some(syn::GenericParam::Lifetime(def))
+ .into_iter()
+ .chain(generics.params.iter().cloned().map(|mut param| {
+ match &mut param {
+ syn::GenericParam::Lifetime(param) => {
+ param.bounds.push(bound.clone());
+ }
+ syn::GenericParam::Type(param) => {
+ param
+ .bounds
+ .push(syn::TypeParamBound::Lifetime(bound.clone()));
+ }
+ syn::GenericParam::Const(_) => {}
+ }
+ param
+ }))
+ .collect();
+
+ syn::Generics {
+ 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.clone(),
+ arguments: syn::PathArguments::AngleBracketed(
+ syn::AngleBracketedGenericArguments {
+ colon2_token: None,
+ lt_token: <Token![<]>::default(),
+ args: cont
+ .generics
+ .params
+ .iter()
+ .map(|param| match param {
+ syn::GenericParam::Type(param) => {
+ syn::GenericArgument::Type(syn::Type::Path(syn::TypePath {
+ qself: None,
+ path: param.ident.clone().into(),
+ }))
+ }
+ syn::GenericParam::Lifetime(param) => {
+ syn::GenericArgument::Lifetime(param.lifetime.clone())
+ }
+ syn::GenericParam::Const(_) => {
+ panic!("Serde does not support const generics yet");
+ }
+ })
+ .collect(),
+ gt_token: <Token![>]>::default(),
+ },
+ ),
+ }]
+ .into_iter()
+ .collect(),
+ },
+ })
+}
diff --git a/third_party/rust/serde_derive/src/de.rs b/third_party/rust/serde_derive/src/de.rs
new file mode 100644
index 0000000000..a703adaf7d
--- /dev/null
+++ b/third_party/rust/serde_derive/src/de.rs
@@ -0,0 +1,3142 @@
+use proc_macro2::{Literal, Span, TokenStream};
+use quote::ToTokens;
+use syn::punctuated::Punctuated;
+use syn::spanned::Spanned;
+use syn::{self, Ident, Index, Member};
+
+use bound;
+use dummy;
+use fragment::{Expr, Fragment, Match, Stmts};
+use internals::ast::{Container, Data, Field, Style, Variant};
+use internals::{attr, replace_receiver, ungroup, Ctxt, Derive};
+use pretend;
+use this;
+
+use std::collections::BTreeSet;
+use std::ptr;
+
+pub fn expand_derive_deserialize(
+ input: &mut syn::DeriveInput,
+) -> Result<TokenStream, Vec<syn::Error>> {
+ replace_receiver(input);
+
+ let ctxt = Ctxt::new();
+ let cont = match Container::from_ast(&ctxt, input, Derive::Deserialize) {
+ Some(cont) => cont,
+ None => return Err(ctxt.check().unwrap_err()),
+ };
+ precondition(&ctxt, &cont);
+ ctxt.check()?;
+
+ let ident = &cont.ident;
+ let params = Parameters::new(&cont);
+ let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
+ let body = Stmts(deserialize_body(&cont, &params));
+ let delife = params.borrowed.de_lifetime();
+ let serde = cont.attrs.serde_path();
+
+ let impl_block = if let Some(remote) = cont.attrs.remote() {
+ let vis = &input.vis;
+ let used = pretend::pretend_used(&cont, params.is_packed);
+ quote! {
+ impl #de_impl_generics #ident #ty_generics #where_clause {
+ #vis fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<#remote #ty_generics, __D::Error>
+ where
+ __D: #serde::Deserializer<#delife>,
+ {
+ #used
+ #body
+ }
+ }
+ }
+ } else {
+ let fn_deserialize_in_place = deserialize_in_place_body(&cont, &params);
+
+ quote! {
+ #[automatically_derived]
+ impl #de_impl_generics #serde::Deserialize<#delife> for #ident #ty_generics #where_clause {
+ fn deserialize<__D>(__deserializer: __D) -> #serde::__private::Result<Self, __D::Error>
+ where
+ __D: #serde::Deserializer<#delife>,
+ {
+ #body
+ }
+
+ #fn_deserialize_in_place
+ }
+ }
+ };
+
+ Ok(dummy::wrap_in_const(
+ cont.attrs.custom_serde_path(),
+ "DESERIALIZE",
+ ident,
+ impl_block,
+ ))
+}
+
+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(_, fields) = &cont.data {
+ if let Some(last) = fields.last() {
+ if let syn::Type::Slice(_) = ungroup(last.ty) {
+ cx.error_spanned_by(
+ cont.original,
+ "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_spanned_by(
+ &param.lifetime,
+ "cannot deserialize when there is a lifetime parameter called 'de",
+ );
+ return;
+ }
+ }
+ }
+}
+
+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 (does not include generic parameters) or `some::remote::Path` for
+ /// remote types.
+ this_type: syn::Path,
+
+ /// Same as `this_type` but using `::<T>` for generic parameters for use in
+ /// expression position.
+ this_value: syn::Path,
+
+ /// Generics including any explicit and inferred bounds for the impl.
+ generics: syn::Generics,
+
+ /// Lifetimes borrowed from the deserializer. These will become bounds on
+ /// the `'de` lifetime of the deserializer.
+ borrowed: BorrowedLifetimes,
+
+ /// At least one field has a serde(getter) attribute, implying that the
+ /// remote type has a private field.
+ has_getter: bool,
+
+ /// Type has a repr(packed) attribute.
+ is_packed: bool,
+}
+
+impl Parameters {
+ fn new(cont: &Container) -> Self {
+ let local = cont.ident.clone();
+ let this_type = this::this_type(cont);
+ let this_value = this::this_value(cont);
+ let borrowed = borrowed_lifetimes(cont);
+ let generics = build_generics(cont, &borrowed);
+ let has_getter = cont.data.has_getter();
+ let is_packed = cont.attrs.is_packed();
+
+ Parameters {
+ local,
+ this_type,
+ this_value,
+ generics,
+ borrowed,
+ has_getter,
+ is_packed,
+ }
+ }
+
+ /// Type name to use in error messages and `&'static str` arguments to
+ /// various Deserializer methods.
+ fn type_name(&self) -> String {
+ self.this_type.segments.last().unwrap().ident.to_string()
+ }
+}
+
+// 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::__private::Default),
+ ),
+ attr::Default::None | attr::Default::Path(_) => generics,
+ };
+
+ let delife = borrowed.de_lifetime();
+ let generics = bound::with_bound(
+ cont,
+ &generics,
+ needs_deserialize_bound,
+ &parse_quote!(_serde::Deserialize<#delife>),
+ );
+
+ bound::with_bound(
+ cont,
+ &generics,
+ requires_default,
+ &parse_quote!(_serde::__private::Default),
+ )
+ }
+ }
+}
+
+// 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.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 {
+ false
+ }
+}
+
+enum BorrowedLifetimes {
+ Borrowed(BTreeSet<syn::Lifetime>),
+ Static,
+}
+
+impl BorrowedLifetimes {
+ fn de_lifetime(&self) -> syn::Lifetime {
+ match *self {
+ BorrowedLifetimes::Borrowed(_) => syn::Lifetime::new("'de", Span::call_site()),
+ BorrowedLifetimes::Static => syn::Lifetime::new("'static", Span::call_site()),
+ }
+ }
+
+ fn de_lifetime_def(&self) -> Option<syn::LifetimeDef> {
+ match self {
+ BorrowedLifetimes::Borrowed(bounds) => Some(syn::LifetimeDef {
+ attrs: Vec::new(),
+ lifetime: syn::Lifetime::new("'de", Span::call_site()),
+ colon_token: None,
+ bounds: bounds.iter().cloned().collect(),
+ }),
+ BorrowedLifetimes::Static => None,
+ }
+ }
+}
+
+// The union of lifetimes borrowed by each field of the container.
+//
+// These turn into bounds on the `'de` lifetime of the Deserialize impl. If
+// lifetimes `'a` and `'b` are borrowed but `'c` is not, the impl is:
+//
+// impl<'de: 'a + 'b, 'a, 'b, 'c> Deserialize<'de> for S<'a, 'b, 'c>
+//
+// If any borrowed lifetime is `'static`, then `'de: 'static` would be redundant
+// and we use plain `'static` instead of `'de`.
+fn borrowed_lifetimes(cont: &Container) -> BorrowedLifetimes {
+ let mut lifetimes = BTreeSet::new();
+ for field in cont.data.all_fields() {
+ if !field.attrs.skip_deserializing() {
+ lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned());
+ }
+ }
+ if lifetimes.iter().any(|b| b.to_string() == "'static") {
+ BorrowedLifetimes::Static
+ } else {
+ BorrowedLifetimes::Borrowed(lifetimes)
+ }
+}
+
+fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment {
+ if cont.attrs.transparent() {
+ deserialize_transparent(cont, params)
+ } else if let Some(type_from) = cont.attrs.type_from() {
+ deserialize_from(type_from)
+ } else if let Some(type_try_from) = cont.attrs.type_try_from() {
+ deserialize_try_from(type_try_from)
+ } else if let attr::Identifier::No = cont.attrs.identifier() {
+ match &cont.data {
+ Data::Enum(variants) => deserialize_enum(params, variants, &cont.attrs),
+ Data::Struct(Style::Struct, fields) => {
+ deserialize_struct(None, params, fields, &cont.attrs, None, &Untagged::No)
+ }
+ Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => {
+ deserialize_tuple(None, params, fields, &cont.attrs, None)
+ }
+ Data::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs),
+ }
+ } else {
+ match &cont.data {
+ Data::Enum(variants) => deserialize_custom_identifier(params, variants, &cont.attrs),
+ Data::Struct(_, _) => unreachable!("checked in serde_derive_internals"),
+ }
+ }
+}
+
+#[cfg(feature = "deserialize_in_place")]
+fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<Stmts> {
+ // Only remote derives have getters, and we do not generate
+ // deserialize_in_place for remote derives.
+ assert!(!params.has_getter);
+
+ if cont.attrs.transparent()
+ || cont.attrs.type_from().is_some()
+ || cont.attrs.type_try_from().is_some()
+ || cont.attrs.identifier().is_some()
+ || cont
+ .data
+ .all_fields()
+ .all(|f| f.attrs.deserialize_with().is_some())
+ {
+ return None;
+ }
+
+ let code = match &cont.data {
+ Data::Struct(Style::Struct, fields) => {
+ deserialize_struct_in_place(None, params, fields, &cont.attrs, None)?
+ }
+ Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => {
+ deserialize_tuple_in_place(None, params, fields, &cont.attrs, None)
+ }
+ Data::Enum(_) | Data::Struct(Style::Unit, _) => {
+ return None;
+ }
+ };
+
+ 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::__private::Result<(), __D::Error>
+ where
+ __D: _serde::Deserializer<#delife>,
+ {
+ #stmts
+ }
+ };
+
+ Some(Stmts(fn_deserialize_in_place))
+}
+
+#[cfg(not(feature = "deserialize_in_place"))]
+fn deserialize_in_place_body(_cont: &Container, _params: &Parameters) -> Option<Stmts> {
+ None
+}
+
+fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
+ let fields = match &cont.data {
+ Data::Struct(_, fields) => fields,
+ Data::Enum(_) => unreachable!(),
+ };
+
+ let this_value = &params.this_value;
+ let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap();
+
+ let path = match transparent_field.attrs.deserialize_with() {
+ Some(path) => quote!(#path),
+ None => {
+ let span = transparent_field.original.span();
+ quote_spanned!(span=> _serde::Deserialize::deserialize)
+ }
+ };
+
+ let assign = fields.iter().map(|field| {
+ let member = &field.member;
+ if ptr::eq(field, transparent_field) {
+ quote!(#member: __transparent)
+ } else {
+ let value = match field.attrs.default() {
+ attr::Default::Default => quote!(_serde::__private::Default::default()),
+ attr::Default::Path(path) => quote!(#path()),
+ attr::Default::None => quote!(_serde::__private::PhantomData),
+ };
+ quote!(#member: #value)
+ }
+ });
+
+ quote_block! {
+ _serde::__private::Result::map(
+ #path(__deserializer),
+ |__transparent| #this_value { #(#assign),* })
+ }
+}
+
+fn deserialize_from(type_from: &syn::Type) -> Fragment {
+ quote_block! {
+ _serde::__private::Result::map(
+ <#type_from as _serde::Deserialize>::deserialize(__deserializer),
+ _serde::__private::From::from)
+ }
+}
+
+fn deserialize_try_from(type_try_from: &syn::Type) -> Fragment {
+ quote_block! {
+ _serde::__private::Result::and_then(
+ <#type_try_from as _serde::Deserialize>::deserialize(__deserializer),
+ |v| _serde::__private::TryFrom::try_from(v).map_err(_serde::de::Error::custom))
+ }
+}
+
+fn deserialize_unit_struct(params: &Parameters, cattrs: &attr::Container) -> Fragment {
+ let this_type = &params.this_type;
+ let this_value = &params.this_value;
+ let type_name = cattrs.name().deserialize_name();
+
+ let expecting = format!("unit struct {}", params.type_name());
+ let expecting = cattrs.expecting().unwrap_or(&expecting);
+
+ quote_block! {
+ struct __Visitor;
+
+ impl<'de> _serde::de::Visitor<'de> for __Visitor {
+ type Value = #this_type;
+
+ fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
+ _serde::__private::Formatter::write_str(__formatter, #expecting)
+ }
+
+ #[inline]
+ fn visit_unit<__E>(self) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(#this_value)
+ }
+ }
+
+ _serde::Deserializer::deserialize_unit_struct(__deserializer, #type_name, __Visitor)
+ }
+}
+
+fn deserialize_tuple(
+ variant_ident: Option<&syn::Ident>,
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+ deserializer: Option<TokenStream>,
+) -> Fragment {
+ let this_type = &params.this_type;
+ let this_value = &params.this_value;
+ 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 = &params.local;
+ quote!(#local)
+ } else {
+ quote!(#this_value)
+ };
+
+ let is_enum = variant_ident.is_some();
+ let type_path = match variant_ident {
+ Some(variant_ident) => quote!(#construct::#variant_ident),
+ None => construct,
+ };
+ let expecting = match variant_ident {
+ Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident),
+ None => format!("tuple struct {}", params.type_name()),
+ };
+ let expecting = cattrs.expecting().unwrap_or(&expecting);
+
+ 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, expecting,
+ ));
+
+ let visitor_expr = quote! {
+ __Visitor {
+ marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData,
+ }
+ };
+ let dispatch = if let Some(deserializer) = deserializer {
+ quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr))
+ } else if is_enum {
+ quote!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr))
+ } else if nfields == 1 {
+ let type_name = cattrs.name().deserialize_name();
+ quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr))
+ } else {
+ let type_name = cattrs.name().deserialize_name();
+ quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr))
+ };
+
+ let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
+ let visitor_var = if all_skipped {
+ quote!(_)
+ } else {
+ quote!(mut __seq)
+ };
+
+ quote_block! {
+ struct __Visitor #de_impl_generics #where_clause {
+ marker: _serde::__private::PhantomData<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData<&#delife ()>,
+ }
+
+ impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
+ type Value = #this_type #ty_generics;
+
+ fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
+ _serde::__private::Formatter::write_str(__formatter, #expecting)
+ }
+
+ #visit_newtype_struct
+
+ #[inline]
+ fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result<Self::Value, __A::Error>
+ where
+ __A: _serde::de::SeqAccess<#delife>,
+ {
+ #visit_seq
+ }
+ }
+
+ #dispatch
+ }
+}
+
+#[cfg(feature = "deserialize_in_place")]
+fn deserialize_tuple_in_place(
+ variant_ident: Option<syn::Ident>,
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+ deserializer: Option<TokenStream>,
+) -> Fragment {
+ let this_type = &params.this_type;
+ 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());
+
+ let is_enum = variant_ident.is_some();
+ let expecting = match variant_ident {
+ Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident),
+ None => format!("tuple struct {}", params.type_name()),
+ };
+ let expecting = cattrs.expecting().unwrap_or(&expecting);
+
+ 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, cattrs, expecting));
+
+ let visitor_expr = quote! {
+ __Visitor {
+ place: __place,
+ lifetime: _serde::__private::PhantomData,
+ }
+ };
+
+ let dispatch = if let Some(deserializer) = deserializer {
+ quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr))
+ } else if is_enum {
+ quote!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr))
+ } else if nfields == 1 {
+ let type_name = cattrs.name().deserialize_name();
+ quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr))
+ } else {
+ let type_name = cattrs.name().deserialize_name();
+ quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr))
+ };
+
+ let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
+ let visitor_var = if all_skipped {
+ quote!(_)
+ } else {
+ quote!(mut __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();
+
+ quote_block! {
+ struct __Visitor #in_place_impl_generics #where_clause {
+ place: &#place_life mut #this_type #ty_generics,
+ lifetime: _serde::__private::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::__private::Formatter) -> _serde::__private::fmt::Result {
+ _serde::__private::Formatter::write_str(__formatter, #expecting)
+ }
+
+ #visit_newtype_struct
+
+ #[inline]
+ fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result<Self::Value, __A::Error>
+ where
+ __A: _serde::de::SeqAccess<#delife>,
+ {
+ #visit_seq
+ }
+ }
+
+ #dispatch
+ }
+}
+
+fn deserialize_seq(
+ type_path: &TokenStream,
+ params: &Parameters,
+ fields: &[Field],
+ is_struct: bool,
+ cattrs: &attr::Container,
+ expecting: &str,
+) -> Fragment {
+ let vars = (0..fields.len()).map(field_i as fn(_) -> _);
+
+ let deserialized_count = fields
+ .iter()
+ .filter(|field| !field.attrs.skip_deserializing())
+ .count();
+ let expecting = if deserialized_count == 1 {
+ format!("{} with 1 element", expecting)
+ } else {
+ format!("{} with {} elements", expecting, deserialized_count)
+ };
+ let expecting = cattrs.expecting().unwrap_or(&expecting);
+
+ 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 span = field.original.span();
+ 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::__private::Option::map(
+ try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)),
+ |__wrap| __wrap.value)
+ })
+ }
+ };
+ let value_if_none = match field.attrs.default() {
+ attr::Default::Default => quote!(_serde::__private::Default::default()),
+ attr::Default::Path(path) => quote!(#path()),
+ attr::Default::None => quote!(
+ return _serde::__private::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
+ ),
+ };
+ let assign = quote! {
+ let #var = match #visit {
+ _serde::__private::Some(__value) => __value,
+ _serde::__private::None => {
+ #value_if_none
+ }
+ };
+ };
+ index_in_seq += 1;
+ assign
+ }
+ });
+
+ let mut result = if is_struct {
+ let names = fields.iter().map(|f| &f.member);
+ quote! {
+ #type_path { #( #names: #vars ),* }
+ }
+ } else {
+ quote! {
+ #type_path ( #(#vars),* )
+ }
+ };
+
+ if params.has_getter {
+ let this_type = &params.this_type;
+ let (_, ty_generics, _) = params.generics.split_for_impl();
+ result = quote! {
+ _serde::__private::Into::<#this_type #ty_generics>::into(#result)
+ };
+ }
+
+ let let_default = match cattrs.default() {
+ attr::Default::Default => Some(quote!(
+ let __default: Self::Value = _serde::__private::Default::default();
+ )),
+ attr::Default::Path(path) => Some(quote!(
+ let __default: Self::Value = #path();
+ )),
+ attr::Default::None => {
+ // We don't need the default value, to prevent an unused variable warning
+ // we'll leave the line empty.
+ None
+ }
+ };
+
+ quote_block! {
+ #let_default
+ #(#let_values)*
+ _serde::__private::Ok(#result)
+ }
+}
+
+#[cfg(feature = "deserialize_in_place")]
+fn deserialize_seq_in_place(
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+ expecting: &str,
+) -> Fragment {
+ let deserialized_count = fields
+ .iter()
+ .filter(|field| !field.attrs.skip_deserializing())
+ .count();
+ let expecting = if deserialized_count == 1 {
+ format!("{} with 1 element", expecting)
+ } else {
+ format!("{} with {} elements", expecting, deserialized_count)
+ };
+ let expecting = cattrs.expecting().unwrap_or(&expecting);
+
+ let mut index_in_seq = 0usize;
+ let write_values = fields.iter().map(|field| {
+ let member = &field.member;
+
+ if field.attrs.skip_deserializing() {
+ let default = Expr(expr_is_missing(field, cattrs));
+ quote! {
+ self.place.#member = #default;
+ }
+ } else {
+ let value_if_none = match field.attrs.default() {
+ attr::Default::Default => quote!(
+ self.place.#member = _serde::__private::Default::default();
+ ),
+ attr::Default::Path(path) => quote!(
+ self.place.#member = #path();
+ ),
+ attr::Default::None => quote!(
+ return _serde::__private::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
+ ),
+ };
+ let write = match field.attrs.deserialize_with() {
+ None => {
+ quote! {
+ if let _serde::__private::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
+ _serde::__private::de::InPlaceSeed(&mut self.place.#member)))
+ {
+ #value_if_none
+ }
+ }
+ }
+ 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::__private::Some(__wrap) => {
+ self.place.#member = __wrap.value;
+ }
+ _serde::__private::None => {
+ #value_if_none
+ }
+ }
+ })
+ }
+ };
+ index_in_seq += 1;
+ write
+ }
+ });
+
+ let this_type = &params.this_type;
+ let (_, ty_generics, _) = params.generics.split_for_impl();
+ let let_default = match cattrs.default() {
+ attr::Default::Default => Some(quote!(
+ let __default: #this_type #ty_generics = _serde::__private::Default::default();
+ )),
+ attr::Default::Path(path) => Some(quote!(
+ let __default: #this_type #ty_generics = #path();
+ )),
+ attr::Default::None => {
+ // We don't need the default value, to prevent an unused variable warning
+ // we'll leave the line empty.
+ None
+ }
+ };
+
+ quote_block! {
+ #let_default
+ #(#write_values)*
+ _serde::__private::Ok(())
+ }
+}
+
+fn deserialize_newtype_struct(
+ type_path: &TokenStream,
+ params: &Parameters,
+ field: &Field,
+) -> TokenStream {
+ let delife = params.borrowed.de_lifetime();
+ let field_ty = field.ty;
+
+ let value = match field.attrs.deserialize_with() {
+ None => {
+ let span = field.original.span();
+ let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
+ quote! {
+ try!(#func(__e))
+ }
+ }
+ Some(path) => {
+ quote! {
+ try!(#path(__e))
+ }
+ }
+ };
+
+ let mut result = quote!(#type_path(__field0));
+ if params.has_getter {
+ let this_type = &params.this_type;
+ let (_, ty_generics, _) = params.generics.split_for_impl();
+ result = quote! {
+ _serde::__private::Into::<#this_type #ty_generics>::into(#result)
+ };
+ }
+
+ quote! {
+ #[inline]
+ fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error>
+ where
+ __E: _serde::Deserializer<#delife>,
+ {
+ let __field0: #field_ty = #value;
+ _serde::__private::Ok(#result)
+ }
+ }
+}
+
+#[cfg(feature = "deserialize_in_place")]
+fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> TokenStream {
+ // 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();
+
+ quote! {
+ #[inline]
+ fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::__private::Result<Self::Value, __E::Error>
+ where
+ __E: _serde::Deserializer<#delife>,
+ {
+ _serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
+ }
+ }
+}
+
+enum Untagged {
+ Yes,
+ No,
+}
+
+fn deserialize_struct(
+ variant_ident: Option<&syn::Ident>,
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+ deserializer: Option<TokenStream>,
+ untagged: &Untagged,
+) -> Fragment {
+ let is_enum = variant_ident.is_some();
+
+ let this_type = &params.this_type;
+ let this_value = &params.this_value;
+ 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 = &params.local;
+ quote!(#local)
+ } else {
+ quote!(#this_value)
+ };
+
+ 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 expecting = cattrs.expecting().unwrap_or(&expecting);
+
+ 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);
+ let visit_map = Stmts(visit_map);
+
+ let visitor_expr = quote! {
+ __Visitor {
+ marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
+ lifetime: _serde::__private::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)
+ }
+ } else {
+ let type_name = cattrs.name().deserialize_name();
+ quote! {
+ _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
+ }
+ };
+
+ let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
+ let visitor_var = if all_skipped {
+ quote!(_)
+ } else {
+ quote!(mut __seq)
+ };
+
+ // 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::__private::Result<Self::Value, __A::Error>
+ 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_type #ty_generics;
+
+ fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::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::__private::PhantomData<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData<&#delife ()>,
+ }
+
+ impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
+ type Value = #this_type #ty_generics;
+
+ fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
+ _serde::__private::Formatter::write_str(__formatter, #expecting)
+ }
+
+ #visit_seq
+
+ #[inline]
+ fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error>
+ 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>,
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+ deserializer: Option<TokenStream>,
+) -> Option<Fragment> {
+ let is_enum = variant_ident.is_some();
+
+ // for now we do not support in_place deserialization for structs that
+ // are represented as map.
+ if cattrs.has_flatten() {
+ return None;
+ }
+
+ let this_type = &params.this_type;
+ let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
+ 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 expecting = cattrs.expecting().unwrap_or(&expecting);
+
+ let visit_seq = Stmts(deserialize_seq_in_place(params, fields, 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,
+ lifetime: _serde::__private::PhantomData,
+ }
+ };
+ let dispatch = if let Some(deserializer) = deserializer {
+ quote! {
+ _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr)
+ }
+ } else if is_enum {
+ quote! {
+ _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr)
+ }
+ } else {
+ let type_name = cattrs.name().deserialize_name();
+ quote! {
+ _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
+ }
+ };
+
+ let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
+ let visitor_var = if all_skipped {
+ quote!(_)
+ } else {
+ quote!(mut __seq)
+ };
+
+ let visit_seq = quote! {
+ #[inline]
+ fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result<Self::Value, __A::Error>
+ 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();
+
+ Some(quote_block! {
+ #field_visitor
+
+ struct __Visitor #in_place_impl_generics #where_clause {
+ place: &#place_life mut #this_type #ty_generics,
+ lifetime: _serde::__private::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::__private::Formatter) -> _serde::__private::fmt::Result {
+ _serde::__private::Formatter::write_str(__formatter, #expecting)
+ }
+
+ #visit_seq
+
+ #[inline]
+ fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error>
+ where
+ __A: _serde::de::MapAccess<#delife>,
+ {
+ #visit_map
+ }
+ }
+
+ #fields_stmt
+
+ #dispatch
+ })
+}
+
+fn deserialize_enum(
+ params: &Parameters,
+ variants: &[Variant],
+ cattrs: &attr::Container,
+) -> Fragment {
+ match cattrs.tag() {
+ attr::TagType::External => deserialize_externally_tagged_enum(params, variants, cattrs),
+ attr::TagType::Internal { tag } => {
+ deserialize_internally_tagged_enum(params, variants, cattrs, tag)
+ }
+ attr::TagType::Adjacent { tag, content } => {
+ deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content)
+ }
+ attr::TagType::None => deserialize_untagged_enum(params, variants, cattrs),
+ }
+}
+
+fn prepare_enum_variant_enum(
+ variants: &[Variant],
+ cattrs: &attr::Container,
+) -> (TokenStream, Stmts) {
+ let mut deserialized_variants = variants
+ .iter()
+ .enumerate()
+ .filter(|&(_, variant)| !variant.attrs.skip_deserializing());
+
+ let variant_names_idents: Vec<_> = deserialized_variants
+ .clone()
+ .map(|(i, variant)| {
+ (
+ variant.attrs.name().deserialize_name(),
+ field_i(i),
+ variant.attrs.aliases(),
+ )
+ })
+ .collect();
+
+ let other_idx = deserialized_variants.position(|(_, variant)| variant.attrs.other());
+
+ let variants_stmt = {
+ let variant_names = variant_names_idents.iter().map(|(name, _, _)| name);
+ quote! {
+ const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
+ }
+ };
+
+ let variant_visitor = Stmts(deserialize_generated_identifier(
+ &variant_names_idents,
+ cattrs,
+ true,
+ other_idx,
+ ));
+
+ (variants_stmt, variant_visitor)
+}
+
+fn deserialize_externally_tagged_enum(
+ params: &Parameters,
+ variants: &[Variant],
+ cattrs: &attr::Container,
+) -> Fragment {
+ let this_type = &params.this_type;
+ let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
+ split_with_de_lifetime(params);
+ let delife = params.borrowed.de_lifetime();
+
+ let type_name = cattrs.name().deserialize_name();
+ let expecting = format!("enum {}", params.type_name());
+ let expecting = cattrs.expecting().unwrap_or(&expecting);
+
+ let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
+
+ // Match arms to extract a variant from a string
+ 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,
+ ));
+
+ quote! {
+ (__Field::#variant_name, __variant) => #block
+ }
+ });
+
+ let all_skipped = variants
+ .iter()
+ .all(|variant| variant.attrs.skip_deserializing());
+ let match_variant = if all_skipped {
+ // This is an empty enum like `enum Impossible {}` or an enum in which
+ // all variants have `#[serde(skip_deserializing)]`.
+ quote! {
+ // FIXME: Once we drop support for Rust 1.15:
+ // let _serde::__private::Err(__err) = _serde::de::EnumAccess::variant::<__Field>(__data);
+ // _serde::__private::Err(__err)
+ _serde::__private::Result::map(
+ _serde::de::EnumAccess::variant::<__Field>(__data),
+ |(__impossible, _)| match __impossible {})
+ }
+ } else {
+ quote! {
+ match try!(_serde::de::EnumAccess::variant(__data)) {
+ #(#variant_arms)*
+ }
+ }
+ };
+
+ quote_block! {
+ #variant_visitor
+
+ struct __Visitor #de_impl_generics #where_clause {
+ marker: _serde::__private::PhantomData<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData<&#delife ()>,
+ }
+
+ impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
+ type Value = #this_type #ty_generics;
+
+ fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
+ _serde::__private::Formatter::write_str(__formatter, #expecting)
+ }
+
+ fn visit_enum<__A>(self, __data: __A) -> _serde::__private::Result<Self::Value, __A::Error>
+ where
+ __A: _serde::de::EnumAccess<#delife>,
+ {
+ #match_variant
+ }
+ }
+
+ #variants_stmt
+
+ _serde::Deserializer::deserialize_enum(
+ __deserializer,
+ #type_name,
+ VARIANTS,
+ __Visitor {
+ marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData,
+ },
+ )
+ }
+}
+
+fn deserialize_internally_tagged_enum(
+ params: &Parameters,
+ variants: &[Variant],
+ cattrs: &attr::Container,
+ tag: &str,
+) -> Fragment {
+ let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
+
+ // Match arms to extract a variant from a string
+ 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_internally_tagged_variant(
+ params,
+ variant,
+ cattrs,
+ quote! {
+ _serde::__private::de::ContentDeserializer::<__D::Error>::new(__tagged.content)
+ },
+ ));
+
+ quote! {
+ __Field::#variant_name => #block
+ }
+ });
+
+ let expecting = format!("internally tagged enum {}", params.type_name());
+ let expecting = cattrs.expecting().unwrap_or(&expecting);
+
+ quote_block! {
+ #variant_visitor
+
+ #variants_stmt
+
+ let __tagged = try!(_serde::Deserializer::deserialize_any(
+ __deserializer,
+ _serde::__private::de::TaggedContentVisitor::<__Field>::new(#tag, #expecting)));
+
+ match __tagged.tag {
+ #(#variant_arms)*
+ }
+ }
+}
+
+fn deserialize_adjacently_tagged_enum(
+ params: &Parameters,
+ variants: &[Variant],
+ cattrs: &attr::Container,
+ tag: &str,
+ content: &str,
+) -> Fragment {
+ let this_type = &params.this_type;
+ let this_value = &params.this_value;
+ let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
+ split_with_de_lifetime(params);
+ let delife = params.borrowed.de_lifetime();
+
+ let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
+
+ let variant_arms: &Vec<_> = &variants
+ .iter()
+ .enumerate()
+ .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
+ .map(|(i, variant)| {
+ let variant_index = field_i(i);
+
+ let block = Match(deserialize_untagged_variant(
+ params,
+ variant,
+ cattrs,
+ quote!(__deserializer),
+ ));
+
+ quote! {
+ __Field::#variant_index => #block
+ }
+ })
+ .collect();
+
+ let expecting = format!("adjacently tagged enum {}", params.type_name());
+ let expecting = cattrs.expecting().unwrap_or(&expecting);
+ let type_name = cattrs.name().deserialize_name();
+ let deny_unknown_fields = cattrs.deny_unknown_fields();
+
+ // If unknown fields are allowed, we pick the visitor that can step over
+ // those. Otherwise we pick the visitor that fails on unknown keys.
+ let field_visitor_ty = if deny_unknown_fields {
+ quote! { _serde::__private::de::TagOrContentFieldVisitor }
+ } else {
+ quote! { _serde::__private::de::TagContentOtherFieldVisitor }
+ };
+
+ let tag_or_content = quote! {
+ #field_visitor_ty {
+ tag: #tag,
+ content: #content,
+ }
+ };
+
+ let mut missing_content = quote! {
+ _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
+ };
+ let mut missing_content_fallthrough = quote!();
+ let missing_content_arms = variants
+ .iter()
+ .enumerate()
+ .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
+ .filter_map(|(i, variant)| {
+ let variant_index = field_i(i);
+ let variant_ident = &variant.ident;
+
+ let arm = match variant.style {
+ Style::Unit => quote! {
+ _serde::__private::Ok(#this_value::#variant_ident)
+ },
+ Style::Newtype if variant.attrs.deserialize_with().is_none() => {
+ let span = variant.original.span();
+ let func = quote_spanned!(span=> _serde::__private::de::missing_field);
+ quote! {
+ #func(#content).map(#this_value::#variant_ident)
+ }
+ }
+ _ => {
+ missing_content_fallthrough = quote!(_ => #missing_content);
+ return None;
+ }
+ };
+ Some(quote! {
+ __Field::#variant_index => #arm,
+ })
+ })
+ .collect::<Vec<_>>();
+ if !missing_content_arms.is_empty() {
+ missing_content = quote! {
+ match __field {
+ #(#missing_content_arms)*
+ #missing_content_fallthrough
+ }
+ };
+ }
+
+ // Advance the map by one key, returning early in case of error.
+ let next_key = quote! {
+ try!(_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content))
+ };
+
+ // When allowing unknown fields, we want to transparently step through keys
+ // we don't care about until we find `tag`, `content`, or run out of keys.
+ let next_relevant_key = if deny_unknown_fields {
+ next_key
+ } else {
+ quote!({
+ let mut __rk : _serde::__private::Option<_serde::__private::de::TagOrContentField> = _serde::__private::None;
+ while let _serde::__private::Some(__k) = #next_key {
+ match __k {
+ _serde::__private::de::TagContentOtherField::Other => {
+ let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map));
+ continue;
+ },
+ _serde::__private::de::TagContentOtherField::Tag => {
+ __rk = _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag);
+ break;
+ }
+ _serde::__private::de::TagContentOtherField::Content => {
+ __rk = _serde::__private::Some(_serde::__private::de::TagOrContentField::Content);
+ break;
+ }
+ }
+ }
+
+ __rk
+ })
+ };
+
+ // Step through remaining keys, looking for duplicates of previously-seen
+ // keys. When unknown fields are denied, any key that isn't a duplicate will
+ // at this point immediately produce an error.
+ let visit_remaining_keys = quote! {
+ match #next_relevant_key {
+ _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => {
+ _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag))
+ }
+ _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => {
+ _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content))
+ }
+ _serde::__private::None => _serde::__private::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::__private::PhantomData<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData<&#delife ()>,
+ }
+
+ impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause {
+ type Value = #this_type #ty_generics;
+
+ fn deserialize<__D>(self, __deserializer: __D) -> _serde::__private::Result<Self::Value, __D::Error>
+ where
+ __D: _serde::Deserializer<#delife>,
+ {
+ match self.field {
+ #(#variant_arms)*
+ }
+ }
+ }
+
+ struct __Visitor #de_impl_generics #where_clause {
+ marker: _serde::__private::PhantomData<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData<&#delife ()>,
+ }
+
+ impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
+ type Value = #this_type #ty_generics;
+
+ fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
+ _serde::__private::Formatter::write_str(__formatter, #expecting)
+ }
+
+ fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error>
+ where
+ __A: _serde::de::MapAccess<#delife>,
+ {
+ // Visit the first relevant key.
+ match #next_relevant_key {
+ // First key is the tag.
+ _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => {
+ // Parse the tag.
+ let __field = try!(_serde::de::MapAccess::next_value(&mut __map));
+ // Visit the second key.
+ match #next_relevant_key {
+ // Second key is a duplicate of the tag.
+ _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => {
+ _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag))
+ }
+ // Second key is the content.
+ _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => {
+ let __ret = try!(_serde::de::MapAccess::next_value_seed(&mut __map,
+ __Seed {
+ field: __field,
+ marker: _serde::__private::PhantomData,
+ lifetime: _serde::__private::PhantomData,
+ }));
+ // Visit remaining keys, looking for duplicates.
+ #visit_remaining_keys
+ }
+ // There is no second key; might be okay if the we have a unit variant.
+ _serde::__private::None => #missing_content
+ }
+ }
+ // First key is the content.
+ _serde::__private::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::__private::Some(_serde::__private::de::TagOrContentField::Tag) => {
+ let __deserializer = _serde::__private::de::ContentDeserializer::<__A::Error>::new(__content);
+ #finish_content_then_tag
+ }
+ // Second key is a duplicate of the content.
+ _serde::__private::Some(_serde::__private::de::TagOrContentField::Content) => {
+ _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content))
+ }
+ // There is no second key.
+ _serde::__private::None => {
+ _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#tag))
+ }
+ }
+ }
+ // There is no first key.
+ _serde::__private::None => {
+ _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#tag))
+ }
+ }
+ }
+
+ fn visit_seq<__A>(self, mut __seq: __A) -> _serde::__private::Result<Self::Value, __A::Error>
+ where
+ __A: _serde::de::SeqAccess<#delife>,
+ {
+ // Visit the first element - the tag.
+ match try!(_serde::de::SeqAccess::next_element(&mut __seq)) {
+ _serde::__private::Some(__field) => {
+ // Visit the second element - the content.
+ match try!(_serde::de::SeqAccess::next_element_seed(
+ &mut __seq,
+ __Seed {
+ field: __field,
+ marker: _serde::__private::PhantomData,
+ lifetime: _serde::__private::PhantomData,
+ },
+ )) {
+ _serde::__private::Some(__ret) => _serde::__private::Ok(__ret),
+ // There is no second element.
+ _serde::__private::None => {
+ _serde::__private::Err(_serde::de::Error::invalid_length(1, &self))
+ }
+ }
+ }
+ // There is no first element.
+ _serde::__private::None => {
+ _serde::__private::Err(_serde::de::Error::invalid_length(0, &self))
+ }
+ }
+ }
+ }
+
+ const FIELDS: &'static [&'static str] = &[#tag, #content];
+ _serde::Deserializer::deserialize_struct(
+ __deserializer,
+ #type_name,
+ FIELDS,
+ __Visitor {
+ marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData,
+ },
+ )
+ }
+}
+
+fn deserialize_untagged_enum(
+ params: &Parameters,
+ variants: &[Variant],
+ cattrs: &attr::Container,
+) -> Fragment {
+ let attempts = variants
+ .iter()
+ .filter(|variant| !variant.attrs.skip_deserializing())
+ .map(|variant| {
+ Expr(deserialize_untagged_variant(
+ params,
+ variant,
+ cattrs,
+ quote!(
+ _serde::__private::de::ContentRefDeserializer::<__D::Error>::new(&__content)
+ ),
+ ))
+ });
+
+ // TODO this message could be better by saving the errors from the failed
+ // attempts. The heuristic used by TOML was to count the number of fields
+ // processed before an error, and use the error that happened after the
+ // largest number of fields. I'm not sure I like that. Maybe it would be
+ // better to save all the errors and combine them into one message that
+ // explains why none of the variants matched.
+ let fallthrough_msg = format!(
+ "data did not match any variant of untagged enum {}",
+ params.type_name()
+ );
+ let fallthrough_msg = cattrs.expecting().unwrap_or(&fallthrough_msg);
+
+ quote_block! {
+ let __content = try!(<_serde::__private::de::Content as _serde::Deserialize>::deserialize(__deserializer));
+
+ #(
+ if let _serde::__private::Ok(__ok) = #attempts {
+ return _serde::__private::Ok(__ok);
+ }
+ )*
+
+ _serde::__private::Err(_serde::de::Error::custom(#fallthrough_msg))
+ }
+}
+
+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);
+ return quote_block! {
+ #wrapper
+ _serde::__private::Result::map(
+ _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn)
+ };
+ }
+
+ let variant_ident = &variant.ident;
+
+ match variant.style {
+ Style::Unit => {
+ let this_value = &params.this_value;
+ quote_block! {
+ try!(_serde::de::VariantAccess::unit_variant(__variant));
+ _serde::__private::Ok(#this_value::#variant_ident)
+ }
+ }
+ Style::Newtype => deserialize_externally_tagged_newtype_variant(
+ variant_ident,
+ params,
+ &variant.fields[0],
+ cattrs,
+ ),
+ Style::Tuple => {
+ deserialize_tuple(Some(variant_ident), params, &variant.fields, cattrs, None)
+ }
+ Style::Struct => deserialize_struct(
+ Some(variant_ident),
+ params,
+ &variant.fields,
+ cattrs,
+ None,
+ &Untagged::No,
+ ),
+ }
+}
+
+// Generates significant part of the visit_seq and visit_map bodies of visitors
+// for the variants of internally tagged enum.
+fn deserialize_internally_tagged_variant(
+ params: &Parameters,
+ variant: &Variant,
+ cattrs: &attr::Container,
+ deserializer: TokenStream,
+) -> Fragment {
+ if variant.attrs.deserialize_with().is_some() {
+ return deserialize_untagged_variant(params, variant, cattrs, deserializer);
+ }
+
+ let variant_ident = &variant.ident;
+
+ match effective_style(variant) {
+ Style::Unit => {
+ let this_value = &params.this_value;
+ let type_name = params.type_name();
+ let variant_name = variant.ident.to_string();
+ let default = variant.fields.get(0).map(|field| {
+ let default = Expr(expr_is_missing(field, cattrs));
+ quote!((#default))
+ });
+ quote_block! {
+ try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::__private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name)));
+ _serde::__private::Ok(#this_value::#variant_ident #default)
+ }
+ }
+ Style::Newtype => deserialize_untagged_newtype_variant(
+ variant_ident,
+ params,
+ &variant.fields[0],
+ &deserializer,
+ ),
+ Style::Struct => deserialize_struct(
+ Some(variant_ident),
+ params,
+ &variant.fields,
+ cattrs,
+ Some(deserializer),
+ &Untagged::No,
+ ),
+ Style::Tuple => unreachable!("checked in serde_derive_internals"),
+ }
+}
+
+fn deserialize_untagged_variant(
+ params: &Parameters,
+ variant: &Variant,
+ cattrs: &attr::Container,
+ deserializer: TokenStream,
+) -> Fragment {
+ if let Some(path) = variant.attrs.deserialize_with() {
+ let unwrap_fn = unwrap_to_variant_closure(params, variant, false);
+ return quote_block! {
+ _serde::__private::Result::map(#path(#deserializer), #unwrap_fn)
+ };
+ }
+
+ let variant_ident = &variant.ident;
+
+ match effective_style(variant) {
+ Style::Unit => {
+ let this_value = &params.this_value;
+ let type_name = params.type_name();
+ let variant_name = variant.ident.to_string();
+ let default = variant.fields.get(0).map(|field| {
+ let default = Expr(expr_is_missing(field, cattrs));
+ quote!((#default))
+ });
+ quote_expr! {
+ match _serde::Deserializer::deserialize_any(
+ #deserializer,
+ _serde::__private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
+ ) {
+ _serde::__private::Ok(()) => _serde::__private::Ok(#this_value::#variant_ident #default),
+ _serde::__private::Err(__err) => _serde::__private::Err(__err),
+ }
+ }
+ }
+ Style::Newtype => deserialize_untagged_newtype_variant(
+ variant_ident,
+ params,
+ &variant.fields[0],
+ &deserializer,
+ ),
+ Style::Tuple => deserialize_tuple(
+ Some(variant_ident),
+ params,
+ &variant.fields,
+ cattrs,
+ Some(deserializer),
+ ),
+ Style::Struct => deserialize_struct(
+ Some(variant_ident),
+ params,
+ &variant.fields,
+ cattrs,
+ Some(deserializer),
+ &Untagged::Yes,
+ ),
+ }
+}
+
+fn deserialize_externally_tagged_newtype_variant(
+ variant_ident: &syn::Ident,
+ params: &Parameters,
+ field: &Field,
+ cattrs: &attr::Container,
+) -> Fragment {
+ let this_value = &params.this_value;
+
+ if field.attrs.skip_deserializing() {
+ let default = Expr(expr_is_missing(field, cattrs));
+ return quote_block! {
+ try!(_serde::de::VariantAccess::unit_variant(__variant));
+ _serde::__private::Ok(#this_value::#variant_ident(#default))
+ };
+ }
+
+ match field.attrs.deserialize_with() {
+ None => {
+ let field_ty = field.ty;
+ let span = field.original.span();
+ let func =
+ quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>);
+ quote_expr! {
+ _serde::__private::Result::map(#func(__variant), #this_value::#variant_ident)
+ }
+ }
+ Some(path) => {
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
+ quote_block! {
+ #wrapper
+ _serde::__private::Result::map(
+ _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant),
+ |__wrapper| #this_value::#variant_ident(__wrapper.value))
+ }
+ }
+ }
+}
+
+fn deserialize_untagged_newtype_variant(
+ variant_ident: &syn::Ident,
+ params: &Parameters,
+ field: &Field,
+ deserializer: &TokenStream,
+) -> Fragment {
+ let this_value = &params.this_value;
+ let field_ty = field.ty;
+ match field.attrs.deserialize_with() {
+ None => {
+ let span = field.original.span();
+ let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
+ quote_expr! {
+ _serde::__private::Result::map(#func(#deserializer), #this_value::#variant_ident)
+ }
+ }
+ Some(path) => {
+ quote_block! {
+ let __value: _serde::__private::Result<#field_ty, _> = #path(#deserializer);
+ _serde::__private::Result::map(__value, #this_value::#variant_ident)
+ }
+ }
+ }
+}
+
+fn deserialize_generated_identifier(
+ fields: &[(String, Ident, Vec<String>)],
+ cattrs: &attr::Container,
+ is_variant: bool,
+ other_idx: Option<usize>,
+) -> Fragment {
+ let this_value = quote!(__Field);
+ let field_idents: &Vec<_> = &fields.iter().map(|(_, ident, _)| ident).collect();
+
+ let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() {
+ let ignore_variant = quote!(__other(_serde::__private::de::Content<'de>),);
+ let fallthrough = quote!(_serde::__private::Ok(__Field::__other(__value)));
+ (Some(ignore_variant), Some(fallthrough))
+ } else if let Some(other_idx) = other_idx {
+ let ignore_variant = fields[other_idx].1.clone();
+ let fallthrough = quote!(_serde::__private::Ok(__Field::#ignore_variant));
+ (None, Some(fallthrough))
+ } else if is_variant || cattrs.deny_unknown_fields() {
+ (None, None)
+ } else {
+ let ignore_variant = quote!(__ignore,);
+ let fallthrough = quote!(_serde::__private::Ok(__Field::__ignore));
+ (Some(ignore_variant), Some(fallthrough))
+ };
+
+ let visitor_impl = Stmts(deserialize_identifier(
+ &this_value,
+ fields,
+ is_variant,
+ fallthrough,
+ None,
+ !is_variant && cattrs.has_flatten(),
+ None,
+ ));
+
+ let lifetime = if !is_variant && cattrs.has_flatten() {
+ Some(quote!(<'de>))
+ } else {
+ None
+ };
+
+ quote_block! {
+ #[allow(non_camel_case_types)]
+ enum __Field #lifetime {
+ #(#field_idents,)*
+ #ignore_variant
+ }
+
+ struct __FieldVisitor;
+
+ impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
+ type Value = __Field #lifetime;
+
+ #visitor_impl
+ }
+
+ impl<'de> _serde::Deserialize<'de> for __Field #lifetime {
+ #[inline]
+ fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
+ where
+ __D: _serde::Deserializer<'de>,
+ {
+ _serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
+ }
+ }
+ }
+}
+
+// Generates `Deserialize::deserialize` body for an enum with
+// `serde(field_identifier)` or `serde(variant_identifier)` attribute.
+fn deserialize_custom_identifier(
+ params: &Parameters,
+ variants: &[Variant],
+ cattrs: &attr::Container,
+) -> Fragment {
+ let is_variant = match cattrs.identifier() {
+ attr::Identifier::Variant => true,
+ attr::Identifier::Field => false,
+ attr::Identifier::No => unreachable!(),
+ };
+
+ let this_type = params.this_type.to_token_stream();
+ let this_value = params.this_value.to_token_stream();
+
+ let (ordinary, fallthrough, fallthrough_borrowed) = if let Some(last) = variants.last() {
+ let last_ident = &last.ident;
+ if last.attrs.other() {
+ // Process `serde(other)` attribute. It would always be found on the
+ // last variant (checked in `check_identifier`), so all preceding
+ // are ordinary variants.
+ let ordinary = &variants[..variants.len() - 1];
+ let fallthrough = quote!(_serde::__private::Ok(#this_value::#last_ident));
+ (ordinary, Some(fallthrough), None)
+ } else if let Style::Newtype = last.style {
+ let ordinary = &variants[..variants.len() - 1];
+ let fallthrough = |value| {
+ quote! {
+ _serde::__private::Result::map(
+ _serde::Deserialize::deserialize(
+ _serde::__private::de::IdentifierDeserializer::from(#value)
+ ),
+ #this_value::#last_ident)
+ }
+ };
+ (
+ ordinary,
+ Some(fallthrough(quote!(__value))),
+ Some(fallthrough(quote!(_serde::__private::de::Borrowed(
+ __value
+ )))),
+ )
+ } else {
+ (variants, None, None)
+ }
+ } else {
+ (variants, None, None)
+ };
+
+ let names_idents: Vec<_> = ordinary
+ .iter()
+ .map(|variant| {
+ (
+ variant.attrs.name().deserialize_name(),
+ variant.ident.clone(),
+ variant.attrs.aliases(),
+ )
+ })
+ .collect();
+
+ let names = names_idents.iter().map(|(name, _, _)| name);
+
+ let names_const = if fallthrough.is_some() {
+ None
+ } else if is_variant {
+ let variants = quote! {
+ const VARIANTS: &'static [&'static str] = &[ #(#names),* ];
+ };
+ Some(variants)
+ } else {
+ let fields = quote! {
+ const FIELDS: &'static [&'static str] = &[ #(#names),* ];
+ };
+ Some(fields)
+ };
+
+ let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
+ split_with_de_lifetime(params);
+ let delife = params.borrowed.de_lifetime();
+ let visitor_impl = Stmts(deserialize_identifier(
+ &this_value,
+ &names_idents,
+ is_variant,
+ fallthrough,
+ fallthrough_borrowed,
+ false,
+ cattrs.expecting(),
+ ));
+
+ quote_block! {
+ #names_const
+
+ struct __FieldVisitor #de_impl_generics #where_clause {
+ marker: _serde::__private::PhantomData<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData<&#delife ()>,
+ }
+
+ impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause {
+ type Value = #this_type #ty_generics;
+
+ #visitor_impl
+ }
+
+ let __visitor = __FieldVisitor {
+ marker: _serde::__private::PhantomData::<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData,
+ };
+ _serde::Deserializer::deserialize_identifier(__deserializer, __visitor)
+ }
+}
+
+fn deserialize_identifier(
+ this_value: &TokenStream,
+ fields: &[(String, Ident, Vec<String>)],
+ is_variant: bool,
+ fallthrough: Option<TokenStream>,
+ fallthrough_borrowed: Option<TokenStream>,
+ collect_other_fields: bool,
+ expecting: Option<&str>,
+) -> Fragment {
+ let mut flat_fields = Vec::new();
+ for (_, ident, aliases) in fields {
+ flat_fields.extend(aliases.iter().map(|alias| (alias, ident)));
+ }
+
+ let field_strs: &Vec<_> = &flat_fields.iter().map(|(name, _)| name).collect();
+ let field_bytes: &Vec<_> = &flat_fields
+ .iter()
+ .map(|(name, _)| Literal::byte_string(name.as_bytes()))
+ .collect();
+
+ let constructors: &Vec<_> = &flat_fields
+ .iter()
+ .map(|(_, ident)| quote!(#this_value::#ident))
+ .collect();
+ let main_constructors: &Vec<_> = &fields
+ .iter()
+ .map(|(_, ident, _)| quote!(#this_value::#ident))
+ .collect();
+
+ let expecting = expecting.unwrap_or(if is_variant {
+ "variant identifier"
+ } else {
+ "field identifier"
+ });
+
+ let index_expecting = if is_variant { "variant" } else { "field" };
+
+ let bytes_to_str = if fallthrough.is_some() || collect_other_fields {
+ None
+ } else {
+ Some(quote! {
+ let __value = &_serde::__private::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 {
+ (
+ Some(quote! {
+ let __value = _serde::__private::de::Content::String(_serde::__private::ToString::to_string(__value));
+ }),
+ 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_tokens;
+ let fallthrough_arm = if let Some(fallthrough) = &fallthrough {
+ fallthrough
+ } else if is_variant {
+ fallthrough_arm_tokens = quote! {
+ _serde::__private::Err(_serde::de::Error::unknown_variant(__value, VARIANTS))
+ };
+ &fallthrough_arm_tokens
+ } else {
+ fallthrough_arm_tokens = quote! {
+ _serde::__private::Err(_serde::de::Error::unknown_field(__value, FIELDS))
+ };
+ &fallthrough_arm_tokens
+ };
+
+ let u64_fallthrough_arm_tokens;
+ let u64_fallthrough_arm = if let Some(fallthrough) = &fallthrough {
+ fallthrough
+ } else {
+ let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
+ u64_fallthrough_arm_tokens = quote! {
+ _serde::__private::Err(_serde::de::Error::invalid_value(
+ _serde::de::Unexpected::Unsigned(__value),
+ &#fallthrough_msg,
+ ))
+ };
+ &u64_fallthrough_arm_tokens
+ };
+
+ let variant_indices = 0_u64..;
+ let visit_other = if collect_other_fields {
+ quote! {
+ fn visit_bool<__E>(self, __value: bool) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Bool(__value)))
+ }
+
+ fn visit_i8<__E>(self, __value: i8) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I8(__value)))
+ }
+
+ fn visit_i16<__E>(self, __value: i16) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I16(__value)))
+ }
+
+ fn visit_i32<__E>(self, __value: i32) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I32(__value)))
+ }
+
+ fn visit_i64<__E>(self, __value: i64) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::I64(__value)))
+ }
+
+ fn visit_u8<__E>(self, __value: u8) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U8(__value)))
+ }
+
+ fn visit_u16<__E>(self, __value: u16) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U16(__value)))
+ }
+
+ fn visit_u32<__E>(self, __value: u32) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U32(__value)))
+ }
+
+ fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::U64(__value)))
+ }
+
+ fn visit_f32<__E>(self, __value: f32) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::F32(__value)))
+ }
+
+ fn visit_f64<__E>(self, __value: f64) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::F64(__value)))
+ }
+
+ fn visit_char<__E>(self, __value: char) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Char(__value)))
+ }
+
+ fn visit_unit<__E>(self) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ _serde::__private::Ok(__Field::__other(_serde::__private::de::Content::Unit))
+ }
+ }
+ } else {
+ quote! {
+ fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ match __value {
+ #(
+ #variant_indices => _serde::__private::Ok(#main_constructors),
+ )*
+ _ => #u64_fallthrough_arm,
+ }
+ }
+ }
+ };
+
+ let visit_borrowed = if fallthrough_borrowed.is_some() || collect_other_fields {
+ let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(fallthrough_arm);
+ Some(quote! {
+ fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ match __value {
+ #(
+ #field_strs => _serde::__private::Ok(#constructors),
+ )*
+ _ => {
+ #value_as_borrowed_str_content
+ #fallthrough_borrowed_arm
+ }
+ }
+ }
+
+ fn visit_borrowed_bytes<__E>(self, __value: &'de [u8]) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ match __value {
+ #(
+ #field_bytes => _serde::__private::Ok(#constructors),
+ )*
+ _ => {
+ #bytes_to_str
+ #value_as_borrowed_bytes_content
+ #fallthrough_borrowed_arm
+ }
+ }
+ }
+ })
+ } else {
+ None
+ };
+
+ quote_block! {
+ fn expecting(&self, __formatter: &mut _serde::__private::Formatter) -> _serde::__private::fmt::Result {
+ _serde::__private::Formatter::write_str(__formatter, #expecting)
+ }
+
+ #visit_other
+
+ fn visit_str<__E>(self, __value: &str) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ match __value {
+ #(
+ #field_strs => _serde::__private::Ok(#constructors),
+ )*
+ _ => {
+ #value_as_str_content
+ #fallthrough_arm
+ }
+ }
+ }
+
+ fn visit_bytes<__E>(self, __value: &[u8]) -> _serde::__private::Result<Self::Value, __E>
+ where
+ __E: _serde::de::Error,
+ {
+ match __value {
+ #(
+ #field_bytes => _serde::__private::Ok(#constructors),
+ )*
+ _ => {
+ #bytes_to_str
+ #value_as_bytes_content
+ #fallthrough_arm
+ }
+ }
+ }
+
+ #visit_borrowed
+ }
+}
+
+fn deserialize_struct_as_struct_visitor(
+ struct_path: &TokenStream,
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+) -> (Fragment, Option<Fragment>, Fragment) {
+ assert!(!cattrs.has_flatten());
+
+ let field_names_idents: Vec<_> = fields
+ .iter()
+ .enumerate()
+ .filter(|&(_, field)| !field.attrs.skip_deserializing())
+ .map(|(i, field)| {
+ (
+ field.attrs.name().deserialize_name(),
+ field_i(i),
+ field.attrs.aliases(),
+ )
+ })
+ .collect();
+
+ let fields_stmt = {
+ let field_names = field_names_idents.iter().map(|(name, _, _)| name);
+ quote_block! {
+ const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
+ }
+ };
+
+ let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
+
+ let visit_map = deserialize_map(struct_path, params, fields, cattrs);
+
+ (field_visitor, Some(fields_stmt), visit_map)
+}
+
+fn deserialize_struct_as_map_visitor(
+ struct_path: &TokenStream,
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+) -> (Fragment, Option<Fragment>, Fragment) {
+ let field_names_idents: Vec<_> = fields
+ .iter()
+ .enumerate()
+ .filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
+ .map(|(i, field)| {
+ (
+ field.attrs.name().deserialize_name(),
+ field_i(i),
+ field.attrs.aliases(),
+ )
+ })
+ .collect();
+
+ let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
+
+ let visit_map = deserialize_map(struct_path, params, fields, cattrs);
+
+ (field_visitor, None, visit_map)
+}
+
+fn deserialize_map(
+ struct_path: &TokenStream,
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+) -> Fragment {
+ // Create the field names for the fields.
+ let fields_names: Vec<_> = fields
+ .iter()
+ .enumerate()
+ .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, name)| {
+ let field_ty = field.ty;
+ quote! {
+ let mut #name: _serde::__private::Option<#field_ty> = _serde::__private::None;
+ }
+ });
+
+ // Collect contents for flatten fields into a buffer
+ let let_collect = if cattrs.has_flatten() {
+ Some(quote! {
+ let mut __collect = _serde::__private::Vec::<_serde::__private::Option<(
+ _serde::__private::de::Content,
+ _serde::__private::de::Content
+ )>>::new();
+ })
+ } else {
+ None
+ };
+
+ // Match arms to extract a value for a field.
+ let value_arms = fields_names
+ .iter()
+ .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
+ .map(|(field, name)| {
+ let deser_name = field.attrs.name().deserialize_name();
+
+ let visit = match field.attrs.deserialize_with() {
+ None => {
+ let field_ty = field.ty;
+ let span = field.original.span();
+ 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
+ match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) {
+ _serde::__private::Ok(__wrapper) => __wrapper.value,
+ _serde::__private::Err(__err) => {
+ return _serde::__private::Err(__err);
+ }
+ }
+ })
+ }
+ };
+ quote! {
+ __Field::#name => {
+ if _serde::__private::Option::is_some(&#name) {
+ return _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name));
+ }
+ #name = _serde::__private::Some(#visit);
+ }
+ }
+ });
+
+ // Visit ignored values to consume them
+ let ignored_arm = if cattrs.has_flatten() {
+ Some(quote! {
+ __Field::__other(__name) => {
+ __collect.push(_serde::__private::Some((
+ __name,
+ try!(_serde::de::MapAccess::next_value(&mut __map)))));
+ }
+ })
+ } else if cattrs.deny_unknown_fields() {
+ None
+ } else {
+ Some(quote! {
+ _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); }
+ })
+ };
+
+ let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
+ let match_keys = if cattrs.deny_unknown_fields() && all_skipped {
+ quote! {
+ // FIXME: Once we drop support for Rust 1.15:
+ // let _serde::__private::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map));
+ _serde::__private::Option::map(
+ try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)),
+ |__impossible| match __impossible {});
+ }
+ } else {
+ quote! {
+ while let _serde::__private::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) {
+ match __key {
+ #(#value_arms)*
+ #ignored_arm
+ }
+ }
+ }
+ };
+
+ let extract_values = fields_names
+ .iter()
+ .filter(|&&(field, _)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
+ .map(|(field, name)| {
+ let missing_expr = Match(expr_is_missing(field, cattrs));
+
+ quote! {
+ let #name = match #name {
+ _serde::__private::Some(#name) => #name,
+ _serde::__private::None => #missing_expr
+ };
+ }
+ });
+
+ let extract_collected = fields_names
+ .iter()
+ .filter(|&&(field, _)| field.attrs.flatten() && !field.attrs.skip_deserializing())
+ .map(|(field, name)| {
+ let field_ty = field.ty;
+ let func = match field.attrs.deserialize_with() {
+ None => {
+ let span = field.original.span();
+ quote_spanned!(span=> _serde::de::Deserialize::deserialize)
+ }
+ Some(path) => quote!(#path),
+ };
+ quote! {
+ let #name: #field_ty = try!(#func(
+ _serde::__private::de::FlatMapDeserializer(
+ &mut __collect,
+ _serde::__private::PhantomData)));
+ }
+ });
+
+ let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() {
+ Some(quote! {
+ if let _serde::__private::Some(_serde::__private::Some((__key, _))) =
+ __collect.into_iter().filter(_serde::__private::Option::is_some).next()
+ {
+ if let _serde::__private::Some(__key) = __key.as_str() {
+ return _serde::__private::Err(
+ _serde::de::Error::custom(format_args!("unknown field `{}`", &__key)));
+ } else {
+ return _serde::__private::Err(
+ _serde::de::Error::custom(format_args!("unexpected map key")));
+ }
+ }
+ })
+ } else {
+ None
+ };
+
+ let result = fields_names.iter().map(|(field, name)| {
+ let member = &field.member;
+ if field.attrs.skip_deserializing() {
+ let value = Expr(expr_is_missing(field, cattrs));
+ quote!(#member: #value)
+ } else {
+ quote!(#member: #name)
+ }
+ });
+
+ let let_default = match cattrs.default() {
+ attr::Default::Default => Some(quote!(
+ let __default: Self::Value = _serde::__private::Default::default();
+ )),
+ attr::Default::Path(path) => Some(quote!(
+ let __default: Self::Value = #path();
+ )),
+ 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!(#struct_path { #(#result),* });
+ if params.has_getter {
+ let this_type = &params.this_type;
+ let (_, ty_generics, _) = params.generics.split_for_impl();
+ result = quote! {
+ _serde::__private::Into::<#this_type #ty_generics>::into(#result)
+ };
+ }
+
+ quote_block! {
+ #(#let_values)*
+
+ #let_collect
+
+ #match_keys
+
+ #let_default
+
+ #(#extract_values)*
+
+ #(#extract_collected)*
+
+ #collected_deny_unknown_fields
+
+ _serde::__private::Ok(#result)
+ }
+}
+
+#[cfg(feature = "deserialize_in_place")]
+fn deserialize_struct_as_struct_in_place_visitor(
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+) -> (Fragment, Fragment, Fragment) {
+ assert!(!cattrs.has_flatten());
+
+ let field_names_idents: Vec<_> = fields
+ .iter()
+ .enumerate()
+ .filter(|&(_, field)| !field.attrs.skip_deserializing())
+ .map(|(i, field)| {
+ (
+ field.attrs.name().deserialize_name(),
+ field_i(i),
+ field.attrs.aliases(),
+ )
+ })
+ .collect();
+
+ let fields_stmt = {
+ let field_names = field_names_idents.iter().map(|(name, _, _)| name);
+ quote_block! {
+ const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
+ }
+ };
+
+ let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
+
+ let visit_map = deserialize_map_in_place(params, fields, cattrs);
+
+ (field_visitor, fields_stmt, visit_map)
+}
+
+#[cfg(feature = "deserialize_in_place")]
+fn deserialize_map_in_place(
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+) -> Fragment {
+ assert!(!cattrs.has_flatten());
+
+ // Create the field names for the fields.
+ let fields_names: Vec<_> = fields
+ .iter()
+ .enumerate()
+ .map(|(i, field)| (field, field_i(i)))
+ .collect();
+
+ // For deserialize_in_place, declare booleans for each field that will be
+ // deserialized.
+ let let_flags = fields_names
+ .iter()
+ .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+ .map(|(_, name)| {
+ quote! {
+ let mut #name: bool = false;
+ }
+ });
+
+ // Match arms to extract a value for a field.
+ let value_arms_from = fields_names
+ .iter()
+ .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+ .map(|(field, name)| {
+ let deser_name = field.attrs.name().deserialize_name();
+ let member = &field.member;
+
+ 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.#member)))
+ }
+ }
+ Some(path) => {
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
+ quote!({
+ #wrapper
+ self.place.#member = match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) {
+ _serde::__private::Ok(__wrapper) => __wrapper.value,
+ _serde::__private::Err(__err) => {
+ return _serde::__private::Err(__err);
+ }
+ };
+ })
+ }
+ };
+ quote! {
+ __Field::#name => {
+ if #name {
+ return _serde::__private::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name));
+ }
+ #visit;
+ #name = true;
+ }
+ }
+ });
+
+ // Visit ignored values to consume them
+ let ignored_arm = if cattrs.deny_unknown_fields() {
+ None
+ } else {
+ Some(quote! {
+ _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); }
+ })
+ };
+
+ let all_skipped = fields.iter().all(|field| field.attrs.skip_deserializing());
+
+ let match_keys = if cattrs.deny_unknown_fields() && all_skipped {
+ quote! {
+ // FIXME: Once we drop support for Rust 1.15:
+ // let _serde::__private::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map));
+ _serde::__private::Option::map(
+ try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)),
+ |__impossible| match __impossible {});
+ }
+ } else {
+ quote! {
+ while let _serde::__private::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) {
+ match __key {
+ #(#value_arms_from)*
+ #ignored_arm
+ }
+ }
+ }
+ };
+
+ let check_flags = fields_names
+ .iter()
+ .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+ .map(|(field, 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.
+ 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 member = &field.member;
+ let missing_expr = Expr(missing_expr);
+ quote! {
+ if !#name {
+ self.place.#member = #missing_expr;
+ };
+ }
+ }
+ });
+
+ let this_type = &params.this_type;
+ let (_, _, ty_generics, _) = split_with_de_lifetime(params);
+
+ let let_default = match cattrs.default() {
+ attr::Default::Default => Some(quote!(
+ let __default: #this_type #ty_generics = _serde::__private::Default::default();
+ )),
+ attr::Default::Path(path) => Some(quote!(
+ let __default: #this_type #ty_generics = #path();
+ )),
+ attr::Default::None => {
+ // We don't need the default value, to prevent an unused variable warning
+ // we'll leave the line empty.
+ None
+ }
+ };
+
+ quote_block! {
+ #(#let_flags)*
+
+ #match_keys
+
+ #let_default
+
+ #(#check_flags)*
+
+ _serde::__private::Ok(())
+ }
+}
+
+fn field_i(i: usize) -> Ident {
+ Ident::new(&format!("__field{}", i), Span::call_site())
+}
+
+/// This function wraps the expression in `#[serde(deserialize_with = "...")]`
+/// in a trait to prevent it from accessing the internal `Deserialize` state.
+fn wrap_deserialize_with(
+ params: &Parameters,
+ value_ty: &TokenStream,
+ deserialize_with: &syn::ExprPath,
+) -> (TokenStream, TokenStream) {
+ let this_type = &params.this_type;
+ let (de_impl_generics, de_ty_generics, ty_generics, where_clause) =
+ split_with_de_lifetime(params);
+ let delife = params.borrowed.de_lifetime();
+
+ let wrapper = quote! {
+ struct __DeserializeWith #de_impl_generics #where_clause {
+ value: #value_ty,
+ phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
+ lifetime: _serde::__private::PhantomData<&#delife ()>,
+ }
+
+ impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause {
+ fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
+ where
+ __D: _serde::Deserializer<#delife>,
+ {
+ _serde::__private::Ok(__DeserializeWith {
+ value: try!(#deserialize_with(__deserializer)),
+ phantom: _serde::__private::PhantomData,
+ lifetime: _serde::__private::PhantomData,
+ })
+ }
+ }
+ };
+
+ let wrapper_ty = quote!(__DeserializeWith #de_ty_generics);
+
+ (wrapper, wrapper_ty)
+}
+
+fn wrap_deserialize_field_with(
+ params: &Parameters,
+ field_ty: &syn::Type,
+ deserialize_with: &syn::ExprPath,
+) -> (TokenStream, TokenStream) {
+ wrap_deserialize_with(params, &quote!(#field_ty), deserialize_with)
+}
+
+fn wrap_deserialize_variant_with(
+ params: &Parameters,
+ variant: &Variant,
+ deserialize_with: &syn::ExprPath,
+) -> (TokenStream, TokenStream, TokenStream) {
+ let field_tys = variant.fields.iter().map(|field| field.ty);
+ let (wrapper, wrapper_ty) =
+ wrap_deserialize_with(params, &quote!((#(#field_tys),*)), deserialize_with);
+
+ let unwrap_fn = unwrap_to_variant_closure(params, variant, true);
+
+ (wrapper, wrapper_ty, unwrap_fn)
+}
+
+// Generates closure that converts single input parameter to the final value.
+fn unwrap_to_variant_closure(
+ params: &Parameters,
+ variant: &Variant,
+ with_wrapper: bool,
+) -> TokenStream {
+ let this_value = &params.this_value;
+ let variant_ident = &variant.ident;
+
+ let (arg, wrapper) = if with_wrapper {
+ (quote! { __wrap }, quote! { __wrap.value })
+ } else {
+ let field_tys = variant.fields.iter().map(|field| field.ty);
+ (quote! { __wrap: (#(#field_tys),*) }, quote! { __wrap })
+ };
+
+ let field_access = (0..variant.fields.len()).map(|n| {
+ Member::Unnamed(Index {
+ index: n as u32,
+ span: Span::call_site(),
+ })
+ });
+
+ match variant.style {
+ Style::Struct if variant.fields.len() == 1 => {
+ let member = &variant.fields[0].member;
+ quote! {
+ |#arg| #this_value::#variant_ident { #member: #wrapper }
+ }
+ }
+ Style::Struct => {
+ let members = variant.fields.iter().map(|field| &field.member);
+ quote! {
+ |#arg| #this_value::#variant_ident { #(#members: #wrapper.#field_access),* }
+ }
+ }
+ Style::Tuple => quote! {
+ |#arg| #this_value::#variant_ident(#(#wrapper.#field_access),*)
+ },
+ Style::Newtype => quote! {
+ |#arg| #this_value::#variant_ident(#wrapper)
+ },
+ Style::Unit => quote! {
+ |#arg| #this_value::#variant_ident
+ },
+ }
+}
+
+fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
+ match field.attrs.default() {
+ attr::Default::Default => {
+ let span = field.original.span();
+ let func = quote_spanned!(span=> _serde::__private::Default::default);
+ return quote_expr!(#func());
+ }
+ attr::Default::Path(path) => {
+ return quote_expr!(#path());
+ }
+ attr::Default::None => { /* below */ }
+ }
+
+ match *cattrs.default() {
+ attr::Default::Default | attr::Default::Path(_) => {
+ let member = &field.member;
+ return quote_expr!(__default.#member);
+ }
+ attr::Default::None => { /* below */ }
+ }
+
+ let name = field.attrs.name().deserialize_name();
+ match field.attrs.deserialize_with() {
+ None => {
+ let span = field.original.span();
+ let func = quote_spanned!(span=> _serde::__private::de::missing_field);
+ quote_expr! {
+ try!(#func(#name))
+ }
+ }
+ Some(_) => {
+ quote_expr! {
+ return _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#name))
+ }
+ }
+ }
+}
+
+fn effective_style(variant: &Variant) -> Style {
+ match variant.style {
+ Style::Newtype if variant.fields[0].attrs.skip_deserializing() => Style::Unit,
+ other => other,
+ }
+}
+
+struct DeImplGenerics<'a>(&'a Parameters);
+#[cfg(feature = "deserialize_in_place")]
+struct InPlaceImplGenerics<'a>(&'a Parameters);
+
+impl<'a> ToTokens for DeImplGenerics<'a> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let mut generics = self.0.generics.clone();
+ if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
+ generics.params = Some(syn::GenericParam::Lifetime(de_lifetime))
+ .into_iter()
+ .chain(generics.params)
+ .collect();
+ }
+ let (impl_generics, _, _) = generics.split_for_impl();
+ impl_generics.to_tokens(tokens);
+ }
+}
+
+#[cfg(feature = "deserialize_in_place")]
+impl<'a> ToTokens for InPlaceImplGenerics<'a> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let place_lifetime = place_lifetime();
+ let mut generics = self.0.generics.clone();
+
+ // Add lifetime for `&'place mut Self, and `'a: 'place`
+ for param in &mut generics.params {
+ match param {
+ syn::GenericParam::Lifetime(param) => {
+ param.bounds.push(place_lifetime.lifetime.clone());
+ }
+ syn::GenericParam::Type(param) => {
+ param.bounds.push(syn::TypeParamBound::Lifetime(
+ place_lifetime.lifetime.clone(),
+ ));
+ }
+ syn::GenericParam::Const(_) => {}
+ }
+ }
+ generics.params = Some(syn::GenericParam::Lifetime(place_lifetime))
+ .into_iter()
+ .chain(generics.params)
+ .collect();
+ if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
+ generics.params = Some(syn::GenericParam::Lifetime(de_lifetime))
+ .into_iter()
+ .chain(generics.params)
+ .collect();
+ }
+ let (impl_generics, _, _) = generics.split_for_impl();
+ impl_generics.to_tokens(tokens);
+ }
+}
+
+#[cfg(feature = "deserialize_in_place")]
+impl<'a> DeImplGenerics<'a> {
+ fn in_place(self) -> InPlaceImplGenerics<'a> {
+ InPlaceImplGenerics(self.0)
+ }
+}
+
+struct DeTypeGenerics<'a>(&'a Parameters);
+#[cfg(feature = "deserialize_in_place")]
+struct InPlaceTypeGenerics<'a>(&'a Parameters);
+
+impl<'a> ToTokens for DeTypeGenerics<'a> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let mut generics = self.0.generics.clone();
+ if self.0.borrowed.de_lifetime_def().is_some() {
+ let def = syn::LifetimeDef {
+ attrs: Vec::new(),
+ lifetime: syn::Lifetime::new("'de", Span::call_site()),
+ colon_token: None,
+ bounds: Punctuated::new(),
+ };
+ generics.params = Some(syn::GenericParam::Lifetime(def))
+ .into_iter()
+ .chain(generics.params)
+ .collect();
+ }
+ let (_, ty_generics, _) = generics.split_for_impl();
+ ty_generics.to_tokens(tokens);
+ }
+}
+
+#[cfg(feature = "deserialize_in_place")]
+impl<'a> ToTokens for InPlaceTypeGenerics<'a> {
+ fn to_tokens(&self, tokens: &mut TokenStream) {
+ let mut generics = self.0.generics.clone();
+ generics.params = Some(syn::GenericParam::Lifetime(place_lifetime()))
+ .into_iter()
+ .chain(generics.params)
+ .collect();
+
+ if self.0.borrowed.de_lifetime_def().is_some() {
+ let def = syn::LifetimeDef {
+ attrs: Vec::new(),
+ lifetime: syn::Lifetime::new("'de", Span::call_site()),
+ colon_token: None,
+ bounds: Punctuated::new(),
+ };
+ generics.params = Some(syn::GenericParam::Lifetime(def))
+ .into_iter()
+ .chain(generics.params)
+ .collect();
+ }
+ let (_, ty_generics, _) = generics.split_for_impl();
+ ty_generics.to_tokens(tokens);
+ }
+}
+
+#[cfg(feature = "deserialize_in_place")]
+impl<'a> DeTypeGenerics<'a> {
+ fn in_place(self) -> InPlaceTypeGenerics<'a> {
+ InPlaceTypeGenerics(self.0)
+ }
+}
+
+#[cfg(feature = "deserialize_in_place")]
+fn place_lifetime() -> syn::LifetimeDef {
+ syn::LifetimeDef {
+ attrs: Vec::new(),
+ lifetime: syn::Lifetime::new("'place", Span::call_site()),
+ colon_token: None,
+ bounds: Punctuated::new(),
+ }
+}
+
+fn split_with_de_lifetime(
+ params: &Parameters,
+) -> (
+ DeImplGenerics,
+ DeTypeGenerics,
+ syn::TypeGenerics,
+ Option<&syn::WhereClause>,
+) {
+ let de_impl_generics = DeImplGenerics(params);
+ let de_ty_generics = DeTypeGenerics(params);
+ let (_, ty_generics, where_clause) = params.generics.split_for_impl();
+ (de_impl_generics, de_ty_generics, ty_generics, where_clause)
+}
diff --git a/third_party/rust/serde_derive/src/dummy.rs b/third_party/rust/serde_derive/src/dummy.rs
new file mode 100644
index 0000000000..a02bd37626
--- /dev/null
+++ b/third_party/rust/serde_derive/src/dummy.rs
@@ -0,0 +1,48 @@
+use proc_macro2::{Ident, TokenStream};
+use quote::format_ident;
+
+use syn;
+use try;
+
+pub fn wrap_in_const(
+ serde_path: Option<&syn::Path>,
+ trait_: &str,
+ ty: &Ident,
+ code: TokenStream,
+) -> TokenStream {
+ let try_replacement = try::replacement();
+
+ let dummy_const = if cfg!(no_underscore_consts) {
+ format_ident!("_IMPL_{}_FOR_{}", trait_, unraw(ty))
+ } else {
+ format_ident!("_")
+ };
+
+ let use_serde = match serde_path {
+ Some(path) => quote! {
+ use #path as _serde;
+ },
+ None => quote! {
+ #[allow(unused_extern_crates, clippy::useless_attribute)]
+ extern crate serde as _serde;
+ },
+ };
+
+ quote! {
+ #[doc(hidden)]
+ #[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
+ const #dummy_const: () = {
+ #use_serde
+ #try_replacement
+ #code
+ };
+ }
+}
+
+#[allow(deprecated)]
+fn unraw(ident: &Ident) -> String {
+ // str::trim_start_matches was added in 1.30, trim_left_matches deprecated
+ // in 1.33. We currently support rustc back to 1.15 so we need to continue
+ // to use the deprecated one.
+ ident.to_string().trim_left_matches("r#").to_owned()
+}
diff --git a/third_party/rust/serde_derive/src/fragment.rs b/third_party/rust/serde_derive/src/fragment.rs
new file mode 100644
index 0000000000..324504aa46
--- /dev/null
+++ b/third_party/rust/serde_derive/src/fragment.rs
@@ -0,0 +1,74 @@
+use proc_macro2::TokenStream;
+use quote::ToTokens;
+use syn::token;
+
+pub enum Fragment {
+ /// Tokens that can be used as an expression.
+ Expr(TokenStream),
+ /// Tokens that can be used inside a block. The surrounding curly braces are
+ /// not part of these tokens.
+ Block(TokenStream),
+}
+
+macro_rules! quote_expr {
+ ($($tt:tt)*) => {
+ $crate::fragment::Fragment::Expr(quote!($($tt)*))
+ }
+}
+
+macro_rules! quote_block {
+ ($($tt:tt)*) => {
+ $crate::fragment::Fragment::Block(quote!($($tt)*))
+ }
+}
+
+/// Interpolate a fragment in place of an expression. This involves surrounding
+/// Block fragments in curly braces.
+pub struct Expr(pub Fragment);
+impl ToTokens for Expr {
+ fn to_tokens(&self, out: &mut TokenStream) {
+ match &self.0 {
+ Fragment::Expr(expr) => expr.to_tokens(out),
+ Fragment::Block(block) => {
+ token::Brace::default().surround(out, |out| block.to_tokens(out));
+ }
+ }
+ }
+}
+
+/// Interpolate a fragment as the statements of a block.
+pub struct Stmts(pub Fragment);
+impl ToTokens for Stmts {
+ fn to_tokens(&self, out: &mut TokenStream) {
+ match &self.0 {
+ Fragment::Expr(expr) => expr.to_tokens(out),
+ Fragment::Block(block) => block.to_tokens(out),
+ }
+ }
+}
+
+/// Interpolate a fragment as the value part of a `match` expression. This
+/// involves putting a comma after expressions and curly braces around blocks.
+pub struct Match(pub Fragment);
+impl ToTokens for Match {
+ fn to_tokens(&self, out: &mut TokenStream) {
+ match &self.0 {
+ Fragment::Expr(expr) => {
+ expr.to_tokens(out);
+ <Token![,]>::default().to_tokens(out);
+ }
+ Fragment::Block(block) => {
+ token::Brace::default().surround(out, |out| block.to_tokens(out));
+ }
+ }
+ }
+}
+
+impl AsRef<TokenStream> for Fragment {
+ fn as_ref(&self) -> &TokenStream {
+ match self {
+ Fragment::Expr(expr) => expr,
+ Fragment::Block(block) => block,
+ }
+ }
+}
diff --git a/third_party/rust/serde_derive/src/internals/ast.rs b/third_party/rust/serde_derive/src/internals/ast.rs
new file mode 100644
index 0000000000..2a6950b2a7
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/ast.rs
@@ -0,0 +1,202 @@
+//! A Serde ast, parsed from the Syn ast and ready to generate Rust code.
+
+use internals::attr;
+use internals::check;
+use internals::{Ctxt, Derive};
+use syn;
+use syn::punctuated::Punctuated;
+
+/// A source data structure annotated with `#[derive(Serialize)]` and/or `#[derive(Deserialize)]`,
+/// parsed into an internal representation.
+pub struct Container<'a> {
+ /// The struct or enum name (without generics).
+ pub ident: syn::Ident,
+ /// Attributes on the structure, parsed for Serde.
+ pub attrs: attr::Container,
+ /// The contents of the struct or enum.
+ pub data: Data<'a>,
+ /// Any generics on the struct or enum.
+ pub generics: &'a syn::Generics,
+ /// Original input.
+ pub original: &'a syn::DeriveInput,
+}
+
+/// The fields of a struct or enum.
+///
+/// Analogous to `syn::Data`.
+pub enum Data<'a> {
+ Enum(Vec<Variant<'a>>),
+ Struct(Style, Vec<Field<'a>>),
+}
+
+/// A variant of an enum.
+pub struct Variant<'a> {
+ pub ident: syn::Ident,
+ pub attrs: attr::Variant,
+ pub style: Style,
+ pub fields: Vec<Field<'a>>,
+ pub original: &'a syn::Variant,
+}
+
+/// A field of a struct.
+pub struct Field<'a> {
+ pub member: syn::Member,
+ pub attrs: attr::Field,
+ pub ty: &'a syn::Type,
+ pub original: &'a syn::Field,
+}
+
+#[derive(Copy, Clone)]
+pub enum Style {
+ /// Named fields.
+ Struct,
+ /// Many unnamed fields.
+ Tuple,
+ /// One unnamed field.
+ Newtype,
+ /// No fields.
+ Unit,
+}
+
+impl<'a> Container<'a> {
+ /// Convert the raw Syn ast into a parsed container object, collecting errors in `cx`.
+ pub fn from_ast(
+ cx: &Ctxt,
+ item: &'a syn::DeriveInput,
+ derive: Derive,
+ ) -> Option<Container<'a>> {
+ let mut attrs = attr::Container::from_ast(cx, item);
+
+ let mut data = match &item.data {
+ syn::Data::Enum(data) => Data::Enum(enum_from_ast(cx, &data.variants, attrs.default())),
+ syn::Data::Struct(data) => {
+ let (style, fields) = struct_from_ast(cx, &data.fields, None, attrs.default());
+ Data::Struct(style, fields)
+ }
+ syn::Data::Union(_) => {
+ cx.error_spanned_by(item, "Serde does not support derive for unions");
+ return None;
+ }
+ };
+
+ let mut has_flatten = false;
+ match &mut data {
+ Data::Enum(variants) => {
+ for variant in variants {
+ variant.attrs.rename_by_rules(attrs.rename_all_rules());
+ for field in &mut variant.fields {
+ if field.attrs.flatten() {
+ has_flatten = true;
+ }
+ field
+ .attrs
+ .rename_by_rules(variant.attrs.rename_all_rules());
+ }
+ }
+ }
+ Data::Struct(_, fields) => {
+ for field in fields {
+ if field.attrs.flatten() {
+ has_flatten = true;
+ }
+ field.attrs.rename_by_rules(attrs.rename_all_rules());
+ }
+ }
+ }
+
+ if has_flatten {
+ attrs.mark_has_flatten();
+ }
+
+ let mut item = Container {
+ ident: item.ident.clone(),
+ attrs,
+ data,
+ generics: &item.generics,
+ original: item,
+ };
+ check::check(cx, &mut item, derive);
+ Some(item)
+ }
+}
+
+impl<'a> Data<'a> {
+ pub fn all_fields(&'a self) -> Box<Iterator<Item = &'a Field<'a>> + 'a> {
+ match self {
+ Data::Enum(variants) => {
+ Box::new(variants.iter().flat_map(|variant| variant.fields.iter()))
+ }
+ Data::Struct(_, fields) => Box::new(fields.iter()),
+ }
+ }
+
+ pub fn has_getter(&self) -> bool {
+ self.all_fields().any(|f| f.attrs.getter().is_some())
+ }
+}
+
+fn enum_from_ast<'a>(
+ cx: &Ctxt,
+ variants: &'a Punctuated<syn::Variant, Token![,]>,
+ container_default: &attr::Default,
+) -> Vec<Variant<'a>> {
+ 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.clone(),
+ attrs,
+ style,
+ fields,
+ original: variant,
+ }
+ })
+ .collect()
+}
+
+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(fields) => (
+ Style::Struct,
+ fields_from_ast(cx, &fields.named, attrs, container_default),
+ ),
+ syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => (
+ Style::Newtype,
+ fields_from_ast(cx, &fields.unnamed, attrs, container_default),
+ ),
+ syn::Fields::Unnamed(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 {
+ member: match &field.ident {
+ Some(ident) => syn::Member::Named(ident.clone()),
+ None => syn::Member::Unnamed(i.into()),
+ },
+ attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
+ ty: &field.ty,
+ original: field,
+ })
+ .collect()
+}
diff --git a/third_party/rust/serde_derive/src/internals/attr.rs b/third_party/rust/serde_derive/src/internals/attr.rs
new file mode 100644
index 0000000000..dc532484d2
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/attr.rs
@@ -0,0 +1,1952 @@
+use internals::respan::respan;
+use internals::symbol::*;
+use internals::{ungroup, Ctxt};
+use proc_macro2::{Spacing, Span, TokenStream, TokenTree};
+use quote::ToTokens;
+use std::borrow::Cow;
+use std::collections::BTreeSet;
+use syn;
+use syn::parse::{self, Parse, ParseStream};
+use syn::punctuated::Punctuated;
+use syn::Ident;
+use syn::Meta::{List, NameValue, Path};
+use syn::NestedMeta::{Lit, 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;
+
+struct Attr<'c, T> {
+ cx: &'c Ctxt,
+ name: Symbol,
+ tokens: TokenStream,
+ value: Option<T>,
+}
+
+impl<'c, T> Attr<'c, T> {
+ fn none(cx: &'c Ctxt, name: Symbol) -> Self {
+ Attr {
+ cx,
+ name,
+ tokens: TokenStream::new(),
+ value: None,
+ }
+ }
+
+ fn set<A: ToTokens>(&mut self, obj: A, value: T) {
+ let tokens = obj.into_token_stream();
+
+ if self.value.is_some() {
+ self.cx
+ .error_spanned_by(tokens, format!("duplicate serde attribute `{}`", self.name));
+ } else {
+ self.tokens = tokens;
+ self.value = Some(value);
+ }
+ }
+
+ fn set_opt<A: ToTokens>(&mut self, obj: A, value: Option<T>) {
+ if let Some(value) = value {
+ self.set(obj, 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
+ }
+
+ fn get_with_tokens(self) -> Option<(TokenStream, T)> {
+ match self.value {
+ Some(v) => Some((self.tokens, v)),
+ None => None,
+ }
+ }
+}
+
+struct BoolAttr<'c>(Attr<'c, ()>);
+
+impl<'c> BoolAttr<'c> {
+ fn none(cx: &'c Ctxt, name: Symbol) -> Self {
+ BoolAttr(Attr::none(cx, name))
+ }
+
+ fn set_true<A: ToTokens>(&mut self, obj: A) {
+ self.0.set(obj, ());
+ }
+
+ fn get(&self) -> bool {
+ self.0.value.is_some()
+ }
+}
+
+struct VecAttr<'c, T> {
+ cx: &'c Ctxt,
+ name: Symbol,
+ first_dup_tokens: TokenStream,
+ values: Vec<T>,
+}
+
+impl<'c, T> VecAttr<'c, T> {
+ fn none(cx: &'c Ctxt, name: Symbol) -> Self {
+ VecAttr {
+ cx,
+ name,
+ first_dup_tokens: TokenStream::new(),
+ values: Vec::new(),
+ }
+ }
+
+ fn insert<A: ToTokens>(&mut self, obj: A, value: T) {
+ if self.values.len() == 1 {
+ self.first_dup_tokens = obj.into_token_stream();
+ }
+ self.values.push(value);
+ }
+
+ fn at_most_one(mut self) -> Result<Option<T>, ()> {
+ if self.values.len() > 1 {
+ let dup_token = self.first_dup_tokens;
+ self.cx.error_spanned_by(
+ dup_token,
+ format!("duplicate serde attribute `{}`", self.name),
+ );
+ Err(())
+ } else {
+ Ok(self.values.pop())
+ }
+ }
+
+ fn get(self) -> Vec<T> {
+ self.values
+ }
+}
+
+pub struct Name {
+ serialize: String,
+ serialize_renamed: bool,
+ deserialize: String,
+ deserialize_renamed: bool,
+ deserialize_aliases: Vec<String>,
+}
+
+#[allow(deprecated)]
+fn unraw(ident: &Ident) -> String {
+ // str::trim_start_matches was added in 1.30, trim_left_matches deprecated
+ // in 1.33. We currently support rustc back to 1.15 so we need to continue
+ // to use the deprecated one.
+ ident.to_string().trim_left_matches("r#").to_owned()
+}
+
+impl Name {
+ fn from_attrs(
+ source_name: String,
+ ser_name: Attr<String>,
+ de_name: Attr<String>,
+ de_aliases: Option<VecAttr<String>>,
+ ) -> Name {
+ let deserialize_aliases = match de_aliases {
+ Some(de_aliases) => {
+ let mut alias_list = BTreeSet::new();
+ for alias_name in de_aliases.get() {
+ alias_list.insert(alias_name);
+ }
+ alias_list.into_iter().collect()
+ }
+ None => Vec::new(),
+ };
+
+ 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();
+ Name {
+ serialize: ser_name.unwrap_or_else(|| source_name.clone()),
+ serialize_renamed: ser_renamed,
+ deserialize: de_name.unwrap_or(source_name),
+ deserialize_renamed: de_renamed,
+ deserialize_aliases,
+ }
+ }
+
+ /// 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()
+ }
+
+ fn deserialize_aliases(&self) -> Vec<String> {
+ let mut aliases = self.deserialize_aliases.clone();
+ let main_name = self.deserialize_name();
+ if !aliases.contains(&main_name) {
+ aliases.push(main_name);
+ }
+ aliases
+ }
+}
+
+pub struct RenameAllRules {
+ serialize: RenameRule,
+ deserialize: RenameRule,
+}
+
+/// Represents struct or enum attribute information.
+pub struct Container {
+ name: Name,
+ transparent: bool,
+ deny_unknown_fields: bool,
+ default: Default,
+ rename_all_rules: RenameAllRules,
+ ser_bound: Option<Vec<syn::WherePredicate>>,
+ de_bound: Option<Vec<syn::WherePredicate>>,
+ tag: TagType,
+ type_from: Option<syn::Type>,
+ type_try_from: Option<syn::Type>,
+ type_into: Option<syn::Type>,
+ remote: Option<syn::Path>,
+ identifier: Identifier,
+ has_flatten: bool,
+ serde_path: Option<syn::Path>,
+ is_packed: bool,
+ /// Error message generated when type can't be deserialized
+ expecting: Option<String>,
+}
+
+/// Styles of representing an enum.
+pub enum TagType {
+ /// 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 transparent = BoolAttr::none(cx, TRANSPARENT);
+ let mut deny_unknown_fields = BoolAttr::none(cx, DENY_UNKNOWN_FIELDS);
+ let mut default = Attr::none(cx, DEFAULT);
+ let mut rename_all_ser_rule = Attr::none(cx, RENAME_ALL);
+ let mut rename_all_de_rule = 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_try_from = Attr::none(cx, TRY_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);
+ let mut serde_path = Attr::none(cx, CRATE);
+ let mut expecting = Attr::none(cx, EXPECTING);
+
+ for meta_item in item
+ .attrs
+ .iter()
+ .flat_map(|attr| get_serde_meta_items(cx, attr))
+ .flatten()
+ {
+ match &meta_item {
+ // Parse `#[serde(rename = "foo")]`
+ Meta(NameValue(m)) if m.path == RENAME => {
+ if let Ok(s) = get_lit_str(cx, RENAME, &m.lit) {
+ ser_name.set(&m.path, s.value());
+ de_name.set(&m.path, s.value());
+ }
+ }
+
+ // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
+ Meta(List(m)) if m.path == RENAME => {
+ if let Ok((ser, de)) = get_renames(cx, &m.nested) {
+ ser_name.set_opt(&m.path, ser.map(syn::LitStr::value));
+ de_name.set_opt(&m.path, de.map(syn::LitStr::value));
+ }
+ }
+
+ // Parse `#[serde(rename_all = "foo")]`
+ Meta(NameValue(m)) if m.path == RENAME_ALL => {
+ if let Ok(s) = get_lit_str(cx, RENAME_ALL, &m.lit) {
+ match RenameRule::from_str(&s.value()) {
+ Ok(rename_rule) => {
+ rename_all_ser_rule.set(&m.path, rename_rule);
+ rename_all_de_rule.set(&m.path, rename_rule);
+ }
+ Err(err) => cx.error_spanned_by(s, err),
+ }
+ }
+ }
+
+ // Parse `#[serde(rename_all(serialize = "foo", deserialize = "bar"))]`
+ Meta(List(m)) if m.path == RENAME_ALL => {
+ if let Ok((ser, de)) = get_renames(cx, &m.nested) {
+ if let Some(ser) = ser {
+ match RenameRule::from_str(&ser.value()) {
+ Ok(rename_rule) => rename_all_ser_rule.set(&m.path, rename_rule),
+ Err(err) => cx.error_spanned_by(ser, err),
+ }
+ }
+ if let Some(de) = de {
+ match RenameRule::from_str(&de.value()) {
+ Ok(rename_rule) => rename_all_de_rule.set(&m.path, rename_rule),
+ Err(err) => cx.error_spanned_by(de, err),
+ }
+ }
+ }
+ }
+
+ // Parse `#[serde(transparent)]`
+ Meta(Path(word)) if word == TRANSPARENT => {
+ transparent.set_true(word);
+ }
+
+ // Parse `#[serde(deny_unknown_fields)]`
+ Meta(Path(word)) if word == DENY_UNKNOWN_FIELDS => {
+ deny_unknown_fields.set_true(word);
+ }
+
+ // Parse `#[serde(default)]`
+ Meta(Path(word)) if word == DEFAULT => match &item.data {
+ syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
+ syn::Fields::Named(_) => {
+ default.set(word, Default::Default);
+ }
+ syn::Fields::Unnamed(_) | syn::Fields::Unit => cx.error_spanned_by(
+ fields,
+ "#[serde(default)] can only be used on structs with named fields",
+ ),
+ },
+ syn::Data::Enum(syn::DataEnum { enum_token, .. }) => cx.error_spanned_by(
+ enum_token,
+ "#[serde(default)] can only be used on structs with named fields",
+ ),
+ syn::Data::Union(syn::DataUnion { union_token, .. }) => cx.error_spanned_by(
+ union_token,
+ "#[serde(default)] can only be used on structs with named fields",
+ ),
+ },
+
+ // Parse `#[serde(default = "...")]`
+ Meta(NameValue(m)) if m.path == DEFAULT => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, DEFAULT, &m.lit) {
+ match &item.data {
+ syn::Data::Struct(syn::DataStruct { fields, .. }) => {
+ match fields {
+ syn::Fields::Named(_) => {
+ default.set(&m.path, Default::Path(path));
+ }
+ syn::Fields::Unnamed(_) | syn::Fields::Unit => cx
+ .error_spanned_by(
+ fields,
+ "#[serde(default = \"...\")] can only be used on structs with named fields",
+ ),
+ }
+ }
+ syn::Data::Enum(syn::DataEnum { enum_token, .. }) => cx
+ .error_spanned_by(
+ enum_token,
+ "#[serde(default = \"...\")] can only be used on structs with named fields",
+ ),
+ syn::Data::Union(syn::DataUnion {
+ union_token, ..
+ }) => cx.error_spanned_by(
+ union_token,
+ "#[serde(default = \"...\")] can only be used on structs with named fields",
+ ),
+ }
+ }
+ }
+
+ // Parse `#[serde(bound = "T: SomeBound")]`
+ Meta(NameValue(m)) if m.path == BOUND => {
+ if let Ok(where_predicates) = parse_lit_into_where(cx, BOUND, BOUND, &m.lit) {
+ ser_bound.set(&m.path, where_predicates.clone());
+ de_bound.set(&m.path, where_predicates);
+ }
+ }
+
+ // Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
+ Meta(List(m)) if m.path == BOUND => {
+ if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
+ ser_bound.set_opt(&m.path, ser);
+ de_bound.set_opt(&m.path, de);
+ }
+ }
+
+ // Parse `#[serde(untagged)]`
+ Meta(Path(word)) if word == UNTAGGED => match item.data {
+ syn::Data::Enum(_) => {
+ untagged.set_true(word);
+ }
+ syn::Data::Struct(syn::DataStruct { struct_token, .. }) => {
+ cx.error_spanned_by(
+ struct_token,
+ "#[serde(untagged)] can only be used on enums",
+ );
+ }
+ syn::Data::Union(syn::DataUnion { union_token, .. }) => {
+ cx.error_spanned_by(
+ union_token,
+ "#[serde(untagged)] can only be used on enums",
+ );
+ }
+ },
+
+ // Parse `#[serde(tag = "type")]`
+ Meta(NameValue(m)) if m.path == TAG => {
+ if let Ok(s) = get_lit_str(cx, TAG, &m.lit) {
+ match &item.data {
+ syn::Data::Enum(_) => {
+ internal_tag.set(&m.path, s.value());
+ }
+ syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
+ syn::Fields::Named(_) => {
+ internal_tag.set(&m.path, s.value());
+ }
+ syn::Fields::Unnamed(_) | syn::Fields::Unit => {
+ cx.error_spanned_by(
+ fields,
+ "#[serde(tag = \"...\")] can only be used on enums and structs with named fields",
+ );
+ }
+ },
+ syn::Data::Union(syn::DataUnion { union_token, .. }) => {
+ cx.error_spanned_by(
+ union_token,
+ "#[serde(tag = \"...\")] can only be used on enums and structs with named fields",
+ );
+ }
+ }
+ }
+ }
+
+ // Parse `#[serde(content = "c")]`
+ Meta(NameValue(m)) if m.path == CONTENT => {
+ if let Ok(s) = get_lit_str(cx, CONTENT, &m.lit) {
+ match &item.data {
+ syn::Data::Enum(_) => {
+ content.set(&m.path, s.value());
+ }
+ syn::Data::Struct(syn::DataStruct { struct_token, .. }) => {
+ cx.error_spanned_by(
+ struct_token,
+ "#[serde(content = \"...\")] can only be used on enums",
+ );
+ }
+ syn::Data::Union(syn::DataUnion { union_token, .. }) => {
+ cx.error_spanned_by(
+ union_token,
+ "#[serde(content = \"...\")] can only be used on enums",
+ );
+ }
+ }
+ }
+ }
+
+ // Parse `#[serde(from = "Type")]
+ Meta(NameValue(m)) if m.path == FROM => {
+ if let Ok(from_ty) = parse_lit_into_ty(cx, FROM, &m.lit) {
+ type_from.set_opt(&m.path, Some(from_ty));
+ }
+ }
+
+ // Parse `#[serde(try_from = "Type")]
+ Meta(NameValue(m)) if m.path == TRY_FROM => {
+ if let Ok(try_from_ty) = parse_lit_into_ty(cx, TRY_FROM, &m.lit) {
+ type_try_from.set_opt(&m.path, Some(try_from_ty));
+ }
+ }
+
+ // Parse `#[serde(into = "Type")]
+ Meta(NameValue(m)) if m.path == INTO => {
+ if let Ok(into_ty) = parse_lit_into_ty(cx, INTO, &m.lit) {
+ type_into.set_opt(&m.path, Some(into_ty));
+ }
+ }
+
+ // Parse `#[serde(remote = "...")]`
+ Meta(NameValue(m)) if m.path == REMOTE => {
+ if let Ok(path) = parse_lit_into_path(cx, REMOTE, &m.lit) {
+ if is_primitive_path(&path, "Self") {
+ remote.set(&m.path, item.ident.clone().into());
+ } else {
+ remote.set(&m.path, path);
+ }
+ }
+ }
+
+ // Parse `#[serde(field_identifier)]`
+ Meta(Path(word)) if word == FIELD_IDENTIFIER => {
+ field_identifier.set_true(word);
+ }
+
+ // Parse `#[serde(variant_identifier)]`
+ Meta(Path(word)) if word == VARIANT_IDENTIFIER => {
+ variant_identifier.set_true(word);
+ }
+
+ // Parse `#[serde(crate = "foo")]`
+ Meta(NameValue(m)) if m.path == CRATE => {
+ if let Ok(path) = parse_lit_into_path(cx, CRATE, &m.lit) {
+ serde_path.set(&m.path, path);
+ }
+ }
+
+ // Parse `#[serde(expecting = "a message")]`
+ Meta(NameValue(m)) if m.path == EXPECTING => {
+ if let Ok(s) = get_lit_str(cx, EXPECTING, &m.lit) {
+ expecting.set(&m.path, s.value());
+ }
+ }
+
+ Meta(meta_item) => {
+ let path = meta_item
+ .path()
+ .into_token_stream()
+ .to_string()
+ .replace(' ', "");
+ cx.error_spanned_by(
+ meta_item.path(),
+ format!("unknown serde container attribute `{}`", path),
+ );
+ }
+
+ Lit(lit) => {
+ cx.error_spanned_by(lit, "unexpected literal in serde container attribute");
+ }
+ }
+ }
+
+ let mut is_packed = false;
+ for attr in &item.attrs {
+ if attr.path.is_ident("repr") {
+ let _ = attr.parse_args_with(|input: ParseStream| {
+ while let Some(token) = input.parse()? {
+ if let TokenTree::Ident(ident) = token {
+ is_packed |= ident == "packed";
+ }
+ }
+ Ok(())
+ });
+ }
+ }
+
+ Container {
+ name: Name::from_attrs(unraw(&item.ident), ser_name, de_name, None),
+ transparent: transparent.get(),
+ deny_unknown_fields: deny_unknown_fields.get(),
+ default: default.get().unwrap_or(Default::None),
+ rename_all_rules: RenameAllRules {
+ serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
+ deserialize: rename_all_de_rule.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_try_from: type_try_from.get(),
+ type_into: type_into.get(),
+ remote: remote.get(),
+ identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
+ has_flatten: false,
+ serde_path: serde_path.get(),
+ is_packed,
+ expecting: expecting.get(),
+ }
+ }
+
+ pub fn name(&self) -> &Name {
+ &self.name
+ }
+
+ pub fn rename_all_rules(&self) -> &RenameAllRules {
+ &self.rename_all_rules
+ }
+
+ pub fn transparent(&self) -> bool {
+ self.transparent
+ }
+
+ 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) -> &TagType {
+ &self.tag
+ }
+
+ pub fn type_from(&self) -> Option<&syn::Type> {
+ self.type_from.as_ref()
+ }
+
+ pub fn type_try_from(&self) -> Option<&syn::Type> {
+ self.type_try_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 is_packed(&self) -> bool {
+ self.is_packed
+ }
+
+ 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;
+ }
+
+ pub fn custom_serde_path(&self) -> Option<&syn::Path> {
+ self.serde_path.as_ref()
+ }
+
+ pub fn serde_path(&self) -> Cow<syn::Path> {
+ self.custom_serde_path()
+ .map_or_else(|| Cow::Owned(parse_quote!(_serde)), Cow::Borrowed)
+ }
+
+ /// Error message generated when type can't be deserialized.
+ /// If `None`, default message will be used
+ pub fn expecting(&self) -> Option<&str> {
+ self.expecting.as_ref().map(String::as_ref)
+ }
+}
+
+fn decide_tag(
+ cx: &Ctxt,
+ item: &syn::DeriveInput,
+ untagged: BoolAttr,
+ internal_tag: Attr<String>,
+ content: Attr<String>,
+) -> TagType {
+ match (
+ untagged.0.get_with_tokens(),
+ internal_tag.get_with_tokens(),
+ content.get_with_tokens(),
+ ) {
+ (None, None, None) => TagType::External,
+ (Some(_), None, None) => TagType::None,
+ (None, Some((_, tag)), None) => {
+ // Check that there are no tuple variants.
+ if let syn::Data::Enum(data) = &item.data {
+ for variant in &data.variants {
+ match &variant.fields {
+ syn::Fields::Named(_) | syn::Fields::Unit => {}
+ syn::Fields::Unnamed(fields) => {
+ if fields.unnamed.len() != 1 {
+ cx.error_spanned_by(
+ variant,
+ "#[serde(tag = \"...\")] cannot be used with tuple variants",
+ );
+ break;
+ }
+ }
+ }
+ }
+ }
+ TagType::Internal { tag }
+ }
+ (Some((untagged_tokens, _)), Some((tag_tokens, _)), None) => {
+ cx.error_spanned_by(
+ untagged_tokens,
+ "enum cannot be both untagged and internally tagged",
+ );
+ cx.error_spanned_by(
+ tag_tokens,
+ "enum cannot be both untagged and internally tagged",
+ );
+ TagType::External // doesn't matter, will error
+ }
+ (None, None, Some((content_tokens, _))) => {
+ cx.error_spanned_by(
+ content_tokens,
+ "#[serde(tag = \"...\", content = \"...\")] must be used together",
+ );
+ TagType::External
+ }
+ (Some((untagged_tokens, _)), None, Some((content_tokens, _))) => {
+ cx.error_spanned_by(
+ untagged_tokens,
+ "untagged enum cannot have #[serde(content = \"...\")]",
+ );
+ cx.error_spanned_by(
+ content_tokens,
+ "untagged enum cannot have #[serde(content = \"...\")]",
+ );
+ TagType::External
+ }
+ (None, Some((_, tag)), Some((_, content))) => TagType::Adjacent { tag, content },
+ (Some((untagged_tokens, _)), Some((tag_tokens, _)), Some((content_tokens, _))) => {
+ cx.error_spanned_by(
+ untagged_tokens,
+ "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]",
+ );
+ cx.error_spanned_by(
+ tag_tokens,
+ "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]",
+ );
+ cx.error_spanned_by(
+ content_tokens,
+ "untagged enum cannot have #[serde(tag = \"...\", content = \"...\")]",
+ );
+ TagType::External
+ }
+ }
+}
+
+fn decide_identifier(
+ cx: &Ctxt,
+ item: &syn::DeriveInput,
+ field_identifier: BoolAttr,
+ variant_identifier: BoolAttr,
+) -> Identifier {
+ match (
+ &item.data,
+ field_identifier.0.get_with_tokens(),
+ variant_identifier.0.get_with_tokens(),
+ ) {
+ (_, None, None) => Identifier::No,
+ (_, Some((field_identifier_tokens, _)), Some((variant_identifier_tokens, _))) => {
+ cx.error_spanned_by(
+ field_identifier_tokens,
+ "#[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set",
+ );
+ cx.error_spanned_by(
+ variant_identifier_tokens,
+ "#[serde(field_identifier)] and #[serde(variant_identifier)] cannot both be set",
+ );
+ Identifier::No
+ }
+ (syn::Data::Enum(_), Some(_), None) => Identifier::Field,
+ (syn::Data::Enum(_), None, Some(_)) => Identifier::Variant,
+ (syn::Data::Struct(syn::DataStruct { struct_token, .. }), Some(_), None) => {
+ cx.error_spanned_by(
+ struct_token,
+ "#[serde(field_identifier)] can only be used on an enum",
+ );
+ Identifier::No
+ }
+ (syn::Data::Union(syn::DataUnion { union_token, .. }), Some(_), None) => {
+ cx.error_spanned_by(
+ union_token,
+ "#[serde(field_identifier)] can only be used on an enum",
+ );
+ Identifier::No
+ }
+ (syn::Data::Struct(syn::DataStruct { struct_token, .. }), None, Some(_)) => {
+ cx.error_spanned_by(
+ struct_token,
+ "#[serde(variant_identifier)] can only be used on an enum",
+ );
+ Identifier::No
+ }
+ (syn::Data::Union(syn::DataUnion { union_token, .. }), None, Some(_)) => {
+ cx.error_spanned_by(
+ union_token,
+ "#[serde(variant_identifier)] can only be used on an enum",
+ );
+ Identifier::No
+ }
+ }
+}
+
+/// Represents variant attribute information
+pub struct Variant {
+ name: Name,
+ rename_all_rules: RenameAllRules,
+ 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 de_aliases = VecAttr::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_ser_rule = Attr::none(cx, RENAME_ALL);
+ let mut rename_all_de_rule = 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_item in variant
+ .attrs
+ .iter()
+ .flat_map(|attr| get_serde_meta_items(cx, attr))
+ .flatten()
+ {
+ match &meta_item {
+ // Parse `#[serde(rename = "foo")]`
+ Meta(NameValue(m)) if m.path == RENAME => {
+ if let Ok(s) = get_lit_str(cx, RENAME, &m.lit) {
+ ser_name.set(&m.path, s.value());
+ de_name.set_if_none(s.value());
+ de_aliases.insert(&m.path, s.value());
+ }
+ }
+
+ // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
+ Meta(List(m)) if m.path == RENAME => {
+ if let Ok((ser, de)) = get_multiple_renames(cx, &m.nested) {
+ ser_name.set_opt(&m.path, ser.map(syn::LitStr::value));
+ for de_value in de {
+ de_name.set_if_none(de_value.value());
+ de_aliases.insert(&m.path, de_value.value());
+ }
+ }
+ }
+
+ // Parse `#[serde(alias = "foo")]`
+ Meta(NameValue(m)) if m.path == ALIAS => {
+ if let Ok(s) = get_lit_str(cx, ALIAS, &m.lit) {
+ de_aliases.insert(&m.path, s.value());
+ }
+ }
+
+ // Parse `#[serde(rename_all = "foo")]`
+ Meta(NameValue(m)) if m.path == RENAME_ALL => {
+ if let Ok(s) = get_lit_str(cx, RENAME_ALL, &m.lit) {
+ match RenameRule::from_str(&s.value()) {
+ Ok(rename_rule) => {
+ rename_all_ser_rule.set(&m.path, rename_rule);
+ rename_all_de_rule.set(&m.path, rename_rule);
+ }
+ Err(err) => cx.error_spanned_by(s, err),
+ }
+ }
+ }
+
+ // Parse `#[serde(rename_all(serialize = "foo", deserialize = "bar"))]`
+ Meta(List(m)) if m.path == RENAME_ALL => {
+ if let Ok((ser, de)) = get_renames(cx, &m.nested) {
+ if let Some(ser) = ser {
+ match RenameRule::from_str(&ser.value()) {
+ Ok(rename_rule) => rename_all_ser_rule.set(&m.path, rename_rule),
+ Err(err) => cx.error_spanned_by(ser, err),
+ }
+ }
+ if let Some(de) = de {
+ match RenameRule::from_str(&de.value()) {
+ Ok(rename_rule) => rename_all_de_rule.set(&m.path, rename_rule),
+ Err(err) => cx.error_spanned_by(de, err),
+ }
+ }
+ }
+ }
+
+ // Parse `#[serde(skip)]`
+ Meta(Path(word)) if word == SKIP => {
+ skip_serializing.set_true(word);
+ skip_deserializing.set_true(word);
+ }
+
+ // Parse `#[serde(skip_deserializing)]`
+ Meta(Path(word)) if word == SKIP_DESERIALIZING => {
+ skip_deserializing.set_true(word);
+ }
+
+ // Parse `#[serde(skip_serializing)]`
+ Meta(Path(word)) if word == SKIP_SERIALIZING => {
+ skip_serializing.set_true(word);
+ }
+
+ // Parse `#[serde(other)]`
+ Meta(Path(word)) if word == OTHER => {
+ other.set_true(word);
+ }
+
+ // Parse `#[serde(bound = "T: SomeBound")]`
+ Meta(NameValue(m)) if m.path == BOUND => {
+ if let Ok(where_predicates) = parse_lit_into_where(cx, BOUND, BOUND, &m.lit) {
+ ser_bound.set(&m.path, where_predicates.clone());
+ de_bound.set(&m.path, where_predicates);
+ }
+ }
+
+ // Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
+ Meta(List(m)) if m.path == BOUND => {
+ if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
+ ser_bound.set_opt(&m.path, ser);
+ de_bound.set_opt(&m.path, de);
+ }
+ }
+
+ // Parse `#[serde(with = "...")]`
+ Meta(NameValue(m)) if m.path == WITH => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, WITH, &m.lit) {
+ let mut ser_path = path.clone();
+ ser_path
+ .path
+ .segments
+ .push(Ident::new("serialize", Span::call_site()).into());
+ serialize_with.set(&m.path, ser_path);
+ let mut de_path = path;
+ de_path
+ .path
+ .segments
+ .push(Ident::new("deserialize", Span::call_site()).into());
+ deserialize_with.set(&m.path, de_path);
+ }
+ }
+
+ // Parse `#[serde(serialize_with = "...")]`
+ Meta(NameValue(m)) if m.path == SERIALIZE_WITH => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, SERIALIZE_WITH, &m.lit) {
+ serialize_with.set(&m.path, path);
+ }
+ }
+
+ // Parse `#[serde(deserialize_with = "...")]`
+ Meta(NameValue(m)) if m.path == DESERIALIZE_WITH => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &m.lit) {
+ deserialize_with.set(&m.path, path);
+ }
+ }
+
+ // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
+ Meta(m) if m.path() == BORROW => match &variant.fields {
+ syn::Fields::Unnamed(fields) if fields.unnamed.len() == 1 => {
+ borrow.set(m.path(), m.clone());
+ }
+ _ => {
+ cx.error_spanned_by(
+ variant,
+ "#[serde(borrow)] may only be used on newtype variants",
+ );
+ }
+ },
+
+ Meta(meta_item) => {
+ let path = meta_item
+ .path()
+ .into_token_stream()
+ .to_string()
+ .replace(' ', "");
+ cx.error_spanned_by(
+ meta_item.path(),
+ format!("unknown serde variant attribute `{}`", path),
+ );
+ }
+
+ Lit(lit) => {
+ cx.error_spanned_by(lit, "unexpected literal in serde variant attribute");
+ }
+ }
+ }
+
+ Variant {
+ name: Name::from_attrs(unraw(&variant.ident), ser_name, de_name, Some(de_aliases)),
+ rename_all_rules: RenameAllRules {
+ serialize: rename_all_ser_rule.get().unwrap_or(RenameRule::None),
+ deserialize: rename_all_de_rule.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 aliases(&self) -> Vec<String> {
+ self.name.deserialize_aliases()
+ }
+
+ pub fn rename_by_rules(&mut self, rules: &RenameAllRules) {
+ if !self.name.serialize_renamed {
+ self.name.serialize = rules.serialize.apply_to_variant(&self.name.serialize);
+ }
+ if !self.name.deserialize_renamed {
+ self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
+ }
+ }
+
+ pub fn rename_all_rules(&self) -> &RenameAllRules {
+ &self.rename_all_rules
+ }
+
+ 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,
+ 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,
+ transparent: 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 {
+ 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 de_aliases = VecAttr::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(ident) => unraw(ident),
+ None => index.to_string(),
+ };
+
+ let variant_borrow = attrs
+ .and_then(|variant| variant.borrow.as_ref())
+ .map(|borrow| Meta(borrow.clone()));
+
+ for meta_item in field
+ .attrs
+ .iter()
+ .flat_map(|attr| get_serde_meta_items(cx, attr))
+ .flatten()
+ .chain(variant_borrow)
+ {
+ match &meta_item {
+ // Parse `#[serde(rename = "foo")]`
+ Meta(NameValue(m)) if m.path == RENAME => {
+ if let Ok(s) = get_lit_str(cx, RENAME, &m.lit) {
+ ser_name.set(&m.path, s.value());
+ de_name.set_if_none(s.value());
+ de_aliases.insert(&m.path, s.value());
+ }
+ }
+
+ // Parse `#[serde(rename(serialize = "foo", deserialize = "bar"))]`
+ Meta(List(m)) if m.path == RENAME => {
+ if let Ok((ser, de)) = get_multiple_renames(cx, &m.nested) {
+ ser_name.set_opt(&m.path, ser.map(syn::LitStr::value));
+ for de_value in de {
+ de_name.set_if_none(de_value.value());
+ de_aliases.insert(&m.path, de_value.value());
+ }
+ }
+ }
+
+ // Parse `#[serde(alias = "foo")]`
+ Meta(NameValue(m)) if m.path == ALIAS => {
+ if let Ok(s) = get_lit_str(cx, ALIAS, &m.lit) {
+ de_aliases.insert(&m.path, s.value());
+ }
+ }
+
+ // Parse `#[serde(default)]`
+ Meta(Path(word)) if word == DEFAULT => {
+ default.set(word, Default::Default);
+ }
+
+ // Parse `#[serde(default = "...")]`
+ Meta(NameValue(m)) if m.path == DEFAULT => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, DEFAULT, &m.lit) {
+ default.set(&m.path, Default::Path(path));
+ }
+ }
+
+ // Parse `#[serde(skip_serializing)]`
+ Meta(Path(word)) if word == SKIP_SERIALIZING => {
+ skip_serializing.set_true(word);
+ }
+
+ // Parse `#[serde(skip_deserializing)]`
+ Meta(Path(word)) if word == SKIP_DESERIALIZING => {
+ skip_deserializing.set_true(word);
+ }
+
+ // Parse `#[serde(skip)]`
+ Meta(Path(word)) if word == SKIP => {
+ skip_serializing.set_true(word);
+ skip_deserializing.set_true(word);
+ }
+
+ // Parse `#[serde(skip_serializing_if = "...")]`
+ Meta(NameValue(m)) if m.path == SKIP_SERIALIZING_IF => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, SKIP_SERIALIZING_IF, &m.lit) {
+ skip_serializing_if.set(&m.path, path);
+ }
+ }
+
+ // Parse `#[serde(serialize_with = "...")]`
+ Meta(NameValue(m)) if m.path == SERIALIZE_WITH => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, SERIALIZE_WITH, &m.lit) {
+ serialize_with.set(&m.path, path);
+ }
+ }
+
+ // Parse `#[serde(deserialize_with = "...")]`
+ Meta(NameValue(m)) if m.path == DESERIALIZE_WITH => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, DESERIALIZE_WITH, &m.lit) {
+ deserialize_with.set(&m.path, path);
+ }
+ }
+
+ // Parse `#[serde(with = "...")]`
+ Meta(NameValue(m)) if m.path == WITH => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, WITH, &m.lit) {
+ let mut ser_path = path.clone();
+ ser_path
+ .path
+ .segments
+ .push(Ident::new("serialize", Span::call_site()).into());
+ serialize_with.set(&m.path, ser_path);
+ let mut de_path = path;
+ de_path
+ .path
+ .segments
+ .push(Ident::new("deserialize", Span::call_site()).into());
+ deserialize_with.set(&m.path, de_path);
+ }
+ }
+
+ // Parse `#[serde(bound = "T: SomeBound")]`
+ Meta(NameValue(m)) if m.path == BOUND => {
+ if let Ok(where_predicates) = parse_lit_into_where(cx, BOUND, BOUND, &m.lit) {
+ ser_bound.set(&m.path, where_predicates.clone());
+ de_bound.set(&m.path, where_predicates);
+ }
+ }
+
+ // Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
+ Meta(List(m)) if m.path == BOUND => {
+ if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
+ ser_bound.set_opt(&m.path, ser);
+ de_bound.set_opt(&m.path, de);
+ }
+ }
+
+ // Parse `#[serde(borrow)]`
+ Meta(Path(word)) if word == BORROW => {
+ if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
+ borrowed_lifetimes.set(word, borrowable);
+ }
+ }
+
+ // Parse `#[serde(borrow = "'a + 'b")]`
+ Meta(NameValue(m)) if m.path == BORROW => {
+ if let Ok(lifetimes) = parse_lit_into_lifetimes(cx, BORROW, &m.lit) {
+ if let Ok(borrowable) = borrowable_lifetimes(cx, &ident, field) {
+ for lifetime in &lifetimes {
+ if !borrowable.contains(lifetime) {
+ cx.error_spanned_by(
+ field,
+ format!(
+ "field `{}` does not have lifetime {}",
+ ident, lifetime
+ ),
+ );
+ }
+ }
+ borrowed_lifetimes.set(&m.path, lifetimes);
+ }
+ }
+ }
+
+ // Parse `#[serde(getter = "...")]`
+ Meta(NameValue(m)) if m.path == GETTER => {
+ if let Ok(path) = parse_lit_into_expr_path(cx, GETTER, &m.lit) {
+ getter.set(&m.path, path);
+ }
+ }
+
+ // Parse `#[serde(flatten)]`
+ Meta(Path(word)) if word == FLATTEN => {
+ flatten.set_true(word);
+ }
+
+ Meta(meta_item) => {
+ let path = meta_item
+ .path()
+ .into_token_stream()
+ .to_string()
+ .replace(' ', "");
+ cx.error_spanned_by(
+ meta_item.path(),
+ format!("unknown serde field attribute `{}`", path),
+ );
+ }
+
+ Lit(lit) => {
+ cx.error_spanned_by(lit, "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(),
+ };
+ let span = Span::call_site();
+ path.segments.push(Ident::new("_serde", span).into());
+ path.segments.push(Ident::new("__private", span).into());
+ path.segments.push(Ident::new("de", span).into());
+ path.segments
+ .push(Ident::new("borrow_cow_str", span).into());
+ let expr = syn::ExprPath {
+ attrs: Vec::new(),
+ qself: None,
+ 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(),
+ };
+ let span = Span::call_site();
+ path.segments.push(Ident::new("_serde", span).into());
+ path.segments.push(Ident::new("__private", span).into());
+ path.segments.push(Ident::new("de", span).into());
+ path.segments
+ .push(Ident::new("borrow_cow_bytes", span).into());
+ let expr = syn::ExprPath {
+ attrs: Vec::new(),
+ qself: None,
+ 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);
+ }
+
+ Field {
+ name: Name::from_attrs(ident, ser_name, de_name, Some(de_aliases)),
+ 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,
+ getter: getter.get(),
+ flatten: flatten.get(),
+ transparent: false,
+ }
+ }
+
+ pub fn name(&self) -> &Name {
+ &self.name
+ }
+
+ pub fn aliases(&self) -> Vec<String> {
+ self.name.deserialize_aliases()
+ }
+
+ pub fn rename_by_rules(&mut self, rules: &RenameAllRules) {
+ if !self.name.serialize_renamed {
+ self.name.serialize = rules.serialize.apply_to_field(&self.name.serialize);
+ }
+ if !self.name.deserialize_renamed {
+ self.name.deserialize = rules.deserialize.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
+ }
+
+ pub fn transparent(&self) -> bool {
+ self.transparent
+ }
+
+ pub fn mark_transparent(&mut self) {
+ self.transparent = true;
+ }
+}
+
+type SerAndDe<T> = (Option<T>, Option<T>);
+
+fn get_ser_and_de<'a, 'b, T, F>(
+ cx: &'b Ctxt,
+ attr_name: Symbol,
+ metas: &'a Punctuated<syn::NestedMeta, Token![,]>,
+ f: F,
+) -> Result<(VecAttr<'b, T>, VecAttr<'b, T>), ()>
+where
+ T: 'a,
+ F: Fn(&Ctxt, Symbol, Symbol, &'a syn::Lit) -> Result<T, ()>,
+{
+ let mut ser_meta = VecAttr::none(cx, attr_name);
+ let mut de_meta = VecAttr::none(cx, attr_name);
+
+ for meta in metas {
+ match meta {
+ Meta(NameValue(meta)) if meta.path == SERIALIZE => {
+ if let Ok(v) = f(cx, attr_name, SERIALIZE, &meta.lit) {
+ ser_meta.insert(&meta.path, v);
+ }
+ }
+
+ Meta(NameValue(meta)) if meta.path == DESERIALIZE => {
+ if let Ok(v) = f(cx, attr_name, DESERIALIZE, &meta.lit) {
+ de_meta.insert(&meta.path, v);
+ }
+ }
+
+ _ => {
+ cx.error_spanned_by(
+ meta,
+ format!(
+ "malformed {0} attribute, expected `{0}(serialize = ..., deserialize = ...)`",
+ attr_name
+ ),
+ );
+ return Err(());
+ }
+ }
+ }
+
+ Ok((ser_meta, de_meta))
+}
+
+fn get_renames<'a>(
+ cx: &Ctxt,
+ items: &'a Punctuated<syn::NestedMeta, Token![,]>,
+) -> Result<SerAndDe<&'a syn::LitStr>, ()> {
+ let (ser, de) = get_ser_and_de(cx, RENAME, items, get_lit_str2)?;
+ Ok((ser.at_most_one()?, de.at_most_one()?))
+}
+
+fn get_multiple_renames<'a>(
+ cx: &Ctxt,
+ items: &'a Punctuated<syn::NestedMeta, Token![,]>,
+) -> Result<(Option<&'a syn::LitStr>, Vec<&'a syn::LitStr>), ()> {
+ let (ser, de) = get_ser_and_de(cx, RENAME, items, get_lit_str2)?;
+ Ok((ser.at_most_one()?, de.get()))
+}
+
+fn get_where_predicates(
+ cx: &Ctxt,
+ items: &Punctuated<syn::NestedMeta, Token![,]>,
+) -> Result<SerAndDe<Vec<syn::WherePredicate>>, ()> {
+ let (ser, de) = get_ser_and_de(cx, BOUND, items, parse_lit_into_where)?;
+ Ok((ser.at_most_one()?, de.at_most_one()?))
+}
+
+pub fn get_serde_meta_items(cx: &Ctxt, attr: &syn::Attribute) -> Result<Vec<syn::NestedMeta>, ()> {
+ if attr.path != SERDE {
+ return Ok(Vec::new());
+ }
+
+ match attr.parse_meta() {
+ Ok(List(meta)) => Ok(meta.nested.into_iter().collect()),
+ Ok(other) => {
+ cx.error_spanned_by(other, "expected #[serde(...)]");
+ Err(())
+ }
+ Err(err) => {
+ cx.syn_error(err);
+ Err(())
+ }
+ }
+}
+
+fn get_lit_str<'a>(cx: &Ctxt, attr_name: Symbol, lit: &'a syn::Lit) -> Result<&'a syn::LitStr, ()> {
+ get_lit_str2(cx, attr_name, attr_name, lit)
+}
+
+fn get_lit_str2<'a>(
+ cx: &Ctxt,
+ attr_name: Symbol,
+ meta_item_name: Symbol,
+ lit: &'a syn::Lit,
+) -> Result<&'a syn::LitStr, ()> {
+ if let syn::Lit::Str(lit) = lit {
+ Ok(lit)
+ } else {
+ cx.error_spanned_by(
+ lit,
+ format!(
+ "expected serde {} attribute to be a string: `{} = \"...\"`",
+ attr_name, meta_item_name
+ ),
+ );
+ Err(())
+ }
+}
+
+fn parse_lit_into_path(cx: &Ctxt, attr_name: Symbol, lit: &syn::Lit) -> Result<syn::Path, ()> {
+ let string = get_lit_str(cx, attr_name, lit)?;
+ parse_lit_str(string).map_err(|_| {
+ cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()));
+ })
+}
+
+fn parse_lit_into_expr_path(
+ cx: &Ctxt,
+ attr_name: Symbol,
+ lit: &syn::Lit,
+) -> Result<syn::ExprPath, ()> {
+ let string = get_lit_str(cx, attr_name, lit)?;
+ parse_lit_str(string).map_err(|_| {
+ cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()));
+ })
+}
+
+fn parse_lit_into_where(
+ cx: &Ctxt,
+ attr_name: Symbol,
+ meta_item_name: Symbol,
+ lit: &syn::Lit,
+) -> Result<Vec<syn::WherePredicate>, ()> {
+ let string = get_lit_str2(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_spanned_by(lit, err))
+}
+
+fn parse_lit_into_ty(cx: &Ctxt, attr_name: Symbol, lit: &syn::Lit) -> Result<syn::Type, ()> {
+ let string = get_lit_str(cx, attr_name, lit)?;
+
+ parse_lit_str(string).map_err(|_| {
+ cx.error_spanned_by(
+ lit,
+ 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: Symbol,
+ lit: &syn::Lit,
+) -> Result<BTreeSet<syn::Lifetime>, ()> {
+ let string = get_lit_str(cx, attr_name, lit)?;
+ if string.value().is_empty() {
+ cx.error_spanned_by(lit, "at least one lifetime must be borrowed");
+ return Err(());
+ }
+
+ struct BorrowedLifetimes(Punctuated<syn::Lifetime, Token![+]>);
+
+ impl Parse for BorrowedLifetimes {
+ fn parse(input: ParseStream) -> parse::Result<Self> {
+ Punctuated::parse_separated_nonempty(input).map(BorrowedLifetimes)
+ }
+ }
+
+ if let Ok(BorrowedLifetimes(lifetimes)) = parse_lit_str(string) {
+ let mut set = BTreeSet::new();
+ for lifetime in lifetimes {
+ if !set.insert(lifetime.clone()) {
+ cx.error_spanned_by(lit, format!("duplicate borrowed lifetime `{}`", lifetime));
+ }
+ }
+ return Ok(set);
+ }
+
+ cx.error_spanned_by(
+ lit,
+ 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 ungroup(ty) {
+ syn::Type::Path(ty) => &ty.path,
+ _ => {
+ return false;
+ }
+ };
+ let seg = match path.segments.last() {
+ Some(seg) => seg,
+ None => {
+ return false;
+ }
+ };
+ let args = match &seg.arguments {
+ syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args,
+ _ => {
+ return false;
+ }
+ };
+ seg.ident == "Cow"
+ && args.len() == 2
+ && match (&args[0], &args[1]) {
+ (syn::GenericArgument::Lifetime(_), syn::GenericArgument::Type(arg)) => elem(arg),
+ _ => false,
+ }
+}
+
+fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
+ let path = match ungroup(ty) {
+ syn::Type::Path(ty) => &ty.path,
+ _ => {
+ return false;
+ }
+ };
+ let seg = match path.segments.last() {
+ Some(seg) => seg,
+ None => {
+ return false;
+ }
+ };
+ let args = match &seg.arguments {
+ syn::PathArguments::AngleBracketed(bracketed) => &bracketed.args,
+ _ => {
+ return false;
+ }
+ };
+ seg.ident == "Option"
+ && args.len() == 1
+ && match &args[0] {
+ syn::GenericArgument::Type(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 ungroup(ty) {
+ syn::Type::Reference(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 ungroup(ty) {
+ syn::Type::Slice(ty) => is_primitive_type(&ty.elem, "u8"),
+ _ => false,
+ }
+}
+
+fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool {
+ match ungroup(ty) {
+ syn::Type::Path(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,
+ field: &syn::Field,
+) -> Result<BTreeSet<syn::Lifetime>, ()> {
+ let mut lifetimes = BTreeSet::new();
+ collect_lifetimes(&field.ty, &mut lifetimes);
+ if lifetimes.is_empty() {
+ cx.error_spanned_by(
+ field,
+ 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(ty) => {
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Array(ty) => {
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Ptr(ty) => {
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Reference(ty) => {
+ out.extend(ty.lifetime.iter().cloned());
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Tuple(ty) => {
+ for elem in &ty.elems {
+ collect_lifetimes(elem, out);
+ }
+ }
+ syn::Type::Path(ty) => {
+ if let Some(qself) = &ty.qself {
+ collect_lifetimes(&qself.ty, out);
+ }
+ for seg in &ty.path.segments {
+ if let syn::PathArguments::AngleBracketed(bracketed) = &seg.arguments {
+ for arg in &bracketed.args {
+ match arg {
+ syn::GenericArgument::Lifetime(lifetime) => {
+ out.insert(lifetime.clone());
+ }
+ syn::GenericArgument::Type(ty) => {
+ collect_lifetimes(ty, out);
+ }
+ syn::GenericArgument::Binding(binding) => {
+ collect_lifetimes(&binding.ty, out);
+ }
+ syn::GenericArgument::Constraint(_)
+ | syn::GenericArgument::Const(_) => {}
+ }
+ }
+ }
+ }
+ }
+ syn::Type::Paren(ty) => {
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Group(ty) => {
+ collect_lifetimes(&ty.elem, out);
+ }
+ syn::Type::Macro(ty) => {
+ collect_lifetimes_from_tokens(ty.mac.tokens.clone(), out);
+ }
+ syn::Type::BareFn(_)
+ | syn::Type::Never(_)
+ | syn::Type::TraitObject(_)
+ | syn::Type::ImplTrait(_)
+ | syn::Type::Infer(_)
+ | syn::Type::Verbatim(_) => {}
+
+ #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
+ _ => {}
+ }
+}
+
+fn collect_lifetimes_from_tokens(tokens: TokenStream, out: &mut BTreeSet<syn::Lifetime>) {
+ let mut iter = tokens.into_iter();
+ while let Some(tt) = iter.next() {
+ match &tt {
+ TokenTree::Punct(op) if op.as_char() == '\'' && op.spacing() == Spacing::Joint => {
+ if let Some(TokenTree::Ident(ident)) = iter.next() {
+ out.insert(syn::Lifetime {
+ apostrophe: op.span(),
+ ident,
+ });
+ }
+ }
+ TokenTree::Group(group) => {
+ let tokens = group.stream();
+ collect_lifetimes_from_tokens(tokens, out);
+ }
+ _ => {}
+ }
+ }
+}
+
+fn parse_lit_str<T>(s: &syn::LitStr) -> parse::Result<T>
+where
+ T: Parse,
+{
+ let tokens = spanned_tokens(s)?;
+ syn::parse2(tokens)
+}
+
+fn spanned_tokens(s: &syn::LitStr) -> parse::Result<TokenStream> {
+ let stream = syn::parse_str(&s.value())?;
+ Ok(respan(stream, s.span()))
+}
diff --git a/third_party/rust/serde_derive/src/internals/case.rs b/third_party/rust/serde_derive/src/internals/case.rs
new file mode 100644
index 0000000000..554505160e
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/case.rs
@@ -0,0 +1,197 @@
+//! Code to convert the Rust-styled field/variant (e.g. `my_field`, `MyType`) to the
+//! case of the source (e.g. `my-field`, `MY_FIELD`).
+
+// 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::fmt::{self, Debug, Display};
+
+use self::RenameRule::*;
+
+/// The different possible ways to change case of fields in a struct, or variants in an enum.
+#[derive(Copy, Clone, 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,
+}
+
+static RENAME_RULES: &[(&str, RenameRule)] = &[
+ ("lowercase", LowerCase),
+ ("UPPERCASE", UpperCase),
+ ("PascalCase", PascalCase),
+ ("camelCase", CamelCase),
+ ("snake_case", SnakeCase),
+ ("SCREAMING_SNAKE_CASE", ScreamingSnakeCase),
+ ("kebab-case", KebabCase),
+ ("SCREAMING-KEBAB-CASE", ScreamingKebabCase),
+];
+
+impl RenameRule {
+ pub fn from_str(rename_all_str: &str) -> Result<Self, ParseError> {
+ for (name, rule) in RENAME_RULES {
+ if rename_all_str == *name {
+ return Ok(*rule);
+ }
+ }
+ Err(ParseError {
+ unknown: rename_all_str,
+ })
+ }
+
+ /// Apply a renaming rule to an enum variant, returning the version expected in the source.
+ 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('_', "-"),
+ }
+ }
+
+ /// Apply a renaming rule to a struct field, returning the version expected in the source.
+ 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('_', "-"),
+ }
+ }
+}
+
+pub struct ParseError<'a> {
+ unknown: &'a str,
+}
+
+impl<'a> Display for ParseError<'a> {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str("unknown rename rule `rename_all = ")?;
+ Debug::fmt(self.unknown, f)?;
+ f.write_str("`, expected one of ")?;
+ for (i, (name, _rule)) in RENAME_RULES.iter().enumerate() {
+ if i > 0 {
+ f.write_str(", ")?;
+ }
+ Debug::fmt(name, f)?;
+ }
+ Ok(())
+ }
+}
+
+#[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);
+ }
+}
diff --git a/third_party/rust/serde_derive/src/internals/check.rs b/third_party/rust/serde_derive/src/internals/check.rs
new file mode 100644
index 0000000000..eb1297aa73
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/check.rs
@@ -0,0 +1,443 @@
+use internals::ast::{Container, Data, Field, Style};
+use internals::attr::{Identifier, TagType};
+use internals::{ungroup, Ctxt, Derive};
+use syn::{Member, Type};
+
+/// 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: &mut Container, derive: Derive) {
+ check_remote_generic(cx, cont);
+ 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);
+ check_transparent(cx, cont, derive);
+ check_from_and_try_from(cx, cont);
+}
+
+/// Remote derive definition type must have either all of the generics of the
+/// remote type:
+///
+/// #[serde(remote = "Generic")]
+/// struct Generic<T> {…}
+///
+/// or none of them, i.e. defining impls for one concrete instantiation of the
+/// remote type only:
+///
+/// #[serde(remote = "Generic<T>")]
+/// struct ConcreteDef {…}
+///
+fn check_remote_generic(cx: &Ctxt, cont: &Container) {
+ if let Some(remote) = cont.attrs.remote() {
+ let local_has_generic = !cont.generics.params.is_empty();
+ let remote_has_generic = !remote.segments.last().unwrap().arguments.is_none();
+ if local_has_generic && remote_has_generic {
+ cx.error_spanned_by(remote, "remove generic parameters from this path");
+ }
+ }
+}
+
+/// 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_spanned_by(
+ cont.original,
+ "#[serde(getter = \"...\")] is not allowed in an enum",
+ );
+ }
+ }
+ Data::Struct(_, _) => {
+ if cont.data.has_getter() && cont.attrs.remote().is_none() {
+ cx.error_spanned_by(
+ cont.original,
+ "#[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(variants) => {
+ for variant in variants {
+ for field in &variant.fields {
+ check_flatten_field(cx, variant.style, field);
+ }
+ }
+ }
+ Data::Struct(style, 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_spanned_by(
+ field.original,
+ "#[serde(flatten)] cannot be used on tuple structs",
+ );
+ }
+ Style::Newtype => {
+ cx.error_spanned_by(
+ field.original,
+ "#[serde(flatten)] cannot be used on newtype structs",
+ );
+ }
+ _ => {}
+ }
+}
+
+/// The `other` attribute must be used at most once and it must be the last
+/// variant of an enum.
+///
+/// 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(variants) => variants,
+ Data::Struct(_, _) => {
+ return;
+ }
+ };
+
+ for (i, variant) in variants.iter().enumerate() {
+ match (
+ variant.style,
+ cont.attrs.identifier(),
+ variant.attrs.other(),
+ cont.attrs.tag(),
+ ) {
+ // The `other` attribute may not be used in a variant_identifier.
+ (_, Identifier::Variant, true, _) => {
+ cx.error_spanned_by(
+ variant.original,
+ "#[serde(other)] may not be used on a variant identifier",
+ );
+ }
+
+ // Variant with `other` attribute cannot appear in untagged enum
+ (_, Identifier::No, true, &TagType::None) => {
+ cx.error_spanned_by(
+ variant.original,
+ "#[serde(other)] cannot appear on untagged enum",
+ );
+ }
+
+ // Variant with `other` attribute must be the last one.
+ (Style::Unit, Identifier::Field, true, _) | (Style::Unit, Identifier::No, true, _) => {
+ if i < variants.len() - 1 {
+ cx.error_spanned_by(
+ variant.original,
+ "#[serde(other)] must be on the last variant",
+ );
+ }
+ }
+
+ // Variant with `other` attribute must be a unit variant.
+ (_, Identifier::Field, true, _) | (_, Identifier::No, true, _) => {
+ cx.error_spanned_by(
+ variant.original,
+ "#[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_spanned_by(
+ variant.original,
+ format!("`{}` must be the last variant", variant.ident),
+ );
+ }
+ }
+
+ (_, Identifier::Field, false, _) => {
+ cx.error_spanned_by(
+ variant.original,
+ "#[serde(field_identifier)] may only contain unit variants",
+ );
+ }
+
+ (_, Identifier::Variant, false, _) => {
+ cx.error_spanned_by(
+ variant.original,
+ "#[serde(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(variants) => variants,
+ Data::Struct(_, _) => {
+ return;
+ }
+ };
+
+ for variant in variants.iter() {
+ if variant.attrs.serialize_with().is_some() {
+ if variant.attrs.skip_serializing() {
+ cx.error_spanned_by(
+ variant.original,
+ format!(
+ "variant `{}` cannot have both #[serde(serialize_with)] and #[serde(skip_serializing)]",
+ variant.ident
+ ),
+ );
+ }
+
+ for field in &variant.fields {
+ let member = member_message(&field.member);
+
+ if field.attrs.skip_serializing() {
+ cx.error_spanned_by(
+ variant.original,
+ format!(
+ "variant `{}` cannot have both #[serde(serialize_with)] and a field {} marked with #[serde(skip_serializing)]",
+ variant.ident, member
+ ),
+ );
+ }
+
+ if field.attrs.skip_serializing_if().is_some() {
+ cx.error_spanned_by(
+ variant.original,
+ format!(
+ "variant `{}` cannot have both #[serde(serialize_with)] and a field {} marked with #[serde(skip_serializing_if)]",
+ variant.ident, member
+ ),
+ );
+ }
+ }
+ }
+
+ if variant.attrs.deserialize_with().is_some() {
+ if variant.attrs.skip_deserializing() {
+ cx.error_spanned_by(
+ variant.original,
+ format!(
+ "variant `{}` cannot have both #[serde(deserialize_with)] and #[serde(skip_deserializing)]",
+ variant.ident
+ ),
+ );
+ }
+
+ for field in &variant.fields {
+ if field.attrs.skip_deserializing() {
+ let member = member_message(&field.member);
+
+ cx.error_spanned_by(
+ variant.original,
+ format!(
+ "variant `{}` cannot have both #[serde(deserialize_with)] and a field {} marked with #[serde(skip_deserializing)]",
+ variant.ident, member
+ ),
+ );
+ }
+ }
+ }
+ }
+}
+
+/// 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(variants) => variants,
+ Data::Struct(_, _) => return,
+ };
+
+ let tag = match cont.attrs.tag() {
+ TagType::Internal { tag } => tag.as_str(),
+ TagType::External | TagType::Adjacent { .. } | TagType::None => return,
+ };
+
+ let diagnose_conflict = || {
+ cx.error_spanned_by(
+ cont.original,
+ format!("variant field name `{}` conflicts with internal tag", tag),
+ );
+ };
+
+ 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();
+
+ if check_ser && ser_name == tag {
+ diagnose_conflict();
+ return;
+ }
+
+ for de_name in field.attrs.aliases() {
+ if 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() {
+ TagType::Adjacent { tag, content } => (tag, content),
+ TagType::Internal { .. } | TagType::External | TagType::None => return,
+ };
+
+ if type_tag == content_tag {
+ cx.error_spanned_by(
+ cont.original,
+ format!(
+ "enum tags `{}` for type and content conflict with each other",
+ type_tag
+ ),
+ );
+ }
+}
+
+/// Enums and unit structs cannot be transparent.
+fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
+ if !cont.attrs.transparent() {
+ return;
+ }
+
+ if cont.attrs.type_from().is_some() {
+ cx.error_spanned_by(
+ cont.original,
+ "#[serde(transparent)] is not allowed with #[serde(from = \"...\")]",
+ );
+ }
+
+ if cont.attrs.type_try_from().is_some() {
+ cx.error_spanned_by(
+ cont.original,
+ "#[serde(transparent)] is not allowed with #[serde(try_from = \"...\")]",
+ );
+ }
+
+ if cont.attrs.type_into().is_some() {
+ cx.error_spanned_by(
+ cont.original,
+ "#[serde(transparent)] is not allowed with #[serde(into = \"...\")]",
+ );
+ }
+
+ let fields = match &mut cont.data {
+ Data::Enum(_) => {
+ cx.error_spanned_by(
+ cont.original,
+ "#[serde(transparent)] is not allowed on an enum",
+ );
+ return;
+ }
+ Data::Struct(Style::Unit, _) => {
+ cx.error_spanned_by(
+ cont.original,
+ "#[serde(transparent)] is not allowed on a unit struct",
+ );
+ return;
+ }
+ Data::Struct(_, fields) => fields,
+ };
+
+ let mut transparent_field = None;
+
+ for field in fields {
+ if allow_transparent(field, derive) {
+ if transparent_field.is_some() {
+ cx.error_spanned_by(
+ cont.original,
+ "#[serde(transparent)] requires struct to have at most one transparent field",
+ );
+ return;
+ }
+ transparent_field = Some(field);
+ }
+ }
+
+ match transparent_field {
+ Some(transparent_field) => transparent_field.attrs.mark_transparent(),
+ None => match derive {
+ Derive::Serialize => {
+ cx.error_spanned_by(
+ cont.original,
+ "#[serde(transparent)] requires at least one field that is not skipped",
+ );
+ }
+ Derive::Deserialize => {
+ cx.error_spanned_by(
+ cont.original,
+ "#[serde(transparent)] requires at least one field that is neither skipped nor has a default",
+ );
+ }
+ },
+ }
+}
+
+fn member_message(member: &Member) -> String {
+ match member {
+ Member::Named(ident) => format!("`{}`", ident),
+ Member::Unnamed(i) => format!("#{}", i.index),
+ }
+}
+
+fn allow_transparent(field: &Field, derive: Derive) -> bool {
+ if let Type::Path(ty) = ungroup(field.ty) {
+ if let Some(seg) = ty.path.segments.last() {
+ if seg.ident == "PhantomData" {
+ return false;
+ }
+ }
+ }
+
+ match derive {
+ Derive::Serialize => !field.attrs.skip_serializing(),
+ Derive::Deserialize => !field.attrs.skip_deserializing() && field.attrs.default().is_none(),
+ }
+}
+
+fn check_from_and_try_from(cx: &Ctxt, cont: &mut Container) {
+ if cont.attrs.type_from().is_some() && cont.attrs.type_try_from().is_some() {
+ cx.error_spanned_by(
+ cont.original,
+ "#[serde(from = \"...\")] and #[serde(try_from = \"...\")] conflict with each other",
+ );
+ }
+}
diff --git a/third_party/rust/serde_derive/src/internals/ctxt.rs b/third_party/rust/serde_derive/src/internals/ctxt.rs
new file mode 100644
index 0000000000..d692c2a449
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/ctxt.rs
@@ -0,0 +1,62 @@
+use quote::ToTokens;
+use std::cell::RefCell;
+use std::fmt::Display;
+use std::thread;
+use syn;
+
+/// A type to collect errors together and format them.
+///
+/// Dropping this object will cause a panic. It must be consumed using `check`.
+///
+/// References can be shared since this type uses run-time exclusive mut checking.
+#[derive(Default)]
+pub struct Ctxt {
+ // The contents will be set to `None` during checking. This is so that checking can be
+ // enforced.
+ errors: RefCell<Option<Vec<syn::Error>>>,
+}
+
+impl Ctxt {
+ /// Create a new context object.
+ ///
+ /// This object contains no errors, but will still trigger a panic if it is not `check`ed.
+ pub fn new() -> Self {
+ Ctxt {
+ errors: RefCell::new(Some(Vec::new())),
+ }
+ }
+
+ /// Add an error to the context object with a tokenenizable object.
+ ///
+ /// The object is used for spanning in error messages.
+ pub fn error_spanned_by<A: ToTokens, T: Display>(&self, obj: A, msg: T) {
+ self.errors
+ .borrow_mut()
+ .as_mut()
+ .unwrap()
+ // Curb monomorphization from generating too many identical methods.
+ .push(syn::Error::new_spanned(obj.into_token_stream(), msg));
+ }
+
+ /// Add one of Syn's parse errors.
+ pub fn syn_error(&self, err: syn::Error) {
+ self.errors.borrow_mut().as_mut().unwrap().push(err);
+ }
+
+ /// Consume this object, producing a formatted error string if there are errors.
+ pub fn check(self) -> Result<(), Vec<syn::Error>> {
+ let errors = self.errors.borrow_mut().take().unwrap();
+ match errors.len() {
+ 0 => Ok(()),
+ _ => Err(errors),
+ }
+ }
+}
+
+impl Drop for Ctxt {
+ fn drop(&mut self) {
+ if !thread::panicking() && self.errors.borrow().is_some() {
+ panic!("forgot to check for errors");
+ }
+ }
+}
diff --git a/third_party/rust/serde_derive/src/internals/mod.rs b/third_party/rust/serde_derive/src/internals/mod.rs
new file mode 100644
index 0000000000..5e9f416c46
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/mod.rs
@@ -0,0 +1,28 @@
+pub mod ast;
+pub mod attr;
+
+mod ctxt;
+pub use self::ctxt::Ctxt;
+
+mod receiver;
+pub use self::receiver::replace_receiver;
+
+mod case;
+mod check;
+mod respan;
+mod symbol;
+
+use syn::Type;
+
+#[derive(Copy, Clone)]
+pub enum Derive {
+ Serialize,
+ Deserialize,
+}
+
+pub fn ungroup(mut ty: &Type) -> &Type {
+ while let Type::Group(group) = ty {
+ ty = &group.elem;
+ }
+ ty
+}
diff --git a/third_party/rust/serde_derive/src/internals/receiver.rs b/third_party/rust/serde_derive/src/internals/receiver.rs
new file mode 100644
index 0000000000..b08c670968
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/receiver.rs
@@ -0,0 +1,285 @@
+use internals::respan::respan;
+use proc_macro2::Span;
+use quote::ToTokens;
+use std::mem;
+use syn::punctuated::Punctuated;
+use syn::{
+ parse_quote, Data, DeriveInput, Expr, ExprPath, GenericArgument, GenericParam, Generics, Macro,
+ Path, PathArguments, QSelf, ReturnType, Type, TypeParamBound, TypePath, WherePredicate,
+};
+
+pub fn replace_receiver(input: &mut DeriveInput) {
+ let self_ty = {
+ let ident = &input.ident;
+ let ty_generics = input.generics.split_for_impl().1;
+ parse_quote!(#ident #ty_generics)
+ };
+ let mut visitor = ReplaceReceiver(&self_ty);
+ visitor.visit_generics_mut(&mut input.generics);
+ visitor.visit_data_mut(&mut input.data);
+}
+
+struct ReplaceReceiver<'a>(&'a TypePath);
+
+impl ReplaceReceiver<'_> {
+ fn self_ty(&self, span: Span) -> TypePath {
+ let tokens = self.0.to_token_stream();
+ let respanned = respan(tokens, span);
+ syn::parse2(respanned).unwrap()
+ }
+
+ fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) {
+ if path.leading_colon.is_some() || path.segments[0].ident != "Self" {
+ return;
+ }
+
+ if path.segments.len() == 1 {
+ self.self_to_expr_path(path);
+ return;
+ }
+
+ let span = path.segments[0].ident.span();
+ *qself = Some(QSelf {
+ lt_token: Token![<](span),
+ ty: Box::new(Type::Path(self.self_ty(span))),
+ position: 0,
+ as_token: None,
+ gt_token: Token![>](span),
+ });
+
+ path.leading_colon = Some(**path.segments.pairs().next().unwrap().punct().unwrap());
+
+ let segments = mem::replace(&mut path.segments, Punctuated::new());
+ path.segments = segments.into_pairs().skip(1).collect();
+ }
+
+ fn self_to_expr_path(&self, path: &mut Path) {
+ let self_ty = self.self_ty(path.segments[0].ident.span());
+ let variant = mem::replace(path, self_ty.path);
+ for segment in &mut path.segments {
+ if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments {
+ if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() {
+ bracketed.colon2_token = Some(<Token![::]>::default());
+ }
+ }
+ }
+ if variant.segments.len() > 1 {
+ path.segments.push_punct(<Token![::]>::default());
+ path.segments.extend(variant.segments.into_pairs().skip(1));
+ }
+ }
+}
+
+impl ReplaceReceiver<'_> {
+ // `Self` -> `Receiver`
+ fn visit_type_mut(&mut self, ty: &mut Type) {
+ let span = if let Type::Path(node) = ty {
+ if node.qself.is_none() && node.path.is_ident("Self") {
+ node.path.segments[0].ident.span()
+ } else {
+ self.visit_type_path_mut(node);
+ return;
+ }
+ } else {
+ self.visit_type_mut_impl(ty);
+ return;
+ };
+ *ty = self.self_ty(span).into();
+ }
+
+ // `Self::Assoc` -> `<Receiver>::Assoc`
+ fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
+ if ty.qself.is_none() {
+ self.self_to_qself(&mut ty.qself, &mut ty.path);
+ }
+ self.visit_type_path_mut_impl(ty);
+ }
+
+ // `Self::method` -> `<Receiver>::method`
+ fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) {
+ if expr.qself.is_none() {
+ self.self_to_qself(&mut expr.qself, &mut expr.path);
+ }
+ self.visit_expr_path_mut_impl(expr);
+ }
+
+ // Everything below is simply traversing the syntax tree.
+
+ fn visit_type_mut_impl(&mut self, ty: &mut Type) {
+ match ty {
+ Type::Array(ty) => {
+ self.visit_type_mut(&mut ty.elem);
+ self.visit_expr_mut(&mut ty.len);
+ }
+ Type::BareFn(ty) => {
+ for arg in &mut ty.inputs {
+ self.visit_type_mut(&mut arg.ty);
+ }
+ self.visit_return_type_mut(&mut ty.output);
+ }
+ Type::Group(ty) => self.visit_type_mut(&mut ty.elem),
+ Type::ImplTrait(ty) => {
+ for bound in &mut ty.bounds {
+ self.visit_type_param_bound_mut(bound);
+ }
+ }
+ Type::Macro(ty) => self.visit_macro_mut(&mut ty.mac),
+ Type::Paren(ty) => self.visit_type_mut(&mut ty.elem),
+ Type::Path(ty) => {
+ if let Some(qself) = &mut ty.qself {
+ self.visit_type_mut(&mut qself.ty);
+ }
+ self.visit_path_mut(&mut ty.path);
+ }
+ Type::Ptr(ty) => self.visit_type_mut(&mut ty.elem),
+ Type::Reference(ty) => self.visit_type_mut(&mut ty.elem),
+ Type::Slice(ty) => self.visit_type_mut(&mut ty.elem),
+ Type::TraitObject(ty) => {
+ for bound in &mut ty.bounds {
+ self.visit_type_param_bound_mut(bound);
+ }
+ }
+ Type::Tuple(ty) => {
+ for elem in &mut ty.elems {
+ self.visit_type_mut(elem);
+ }
+ }
+
+ Type::Infer(_) | Type::Never(_) | Type::Verbatim(_) => {}
+
+ #[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
+ _ => {}
+ }
+ }
+
+ fn visit_type_path_mut_impl(&mut self, ty: &mut TypePath) {
+ if let Some(qself) = &mut ty.qself {
+ self.visit_type_mut(&mut qself.ty);
+ }
+ self.visit_path_mut(&mut ty.path);
+ }
+
+ fn visit_expr_path_mut_impl(&mut self, expr: &mut ExprPath) {
+ if let Some(qself) = &mut expr.qself {
+ self.visit_type_mut(&mut qself.ty);
+ }
+ self.visit_path_mut(&mut expr.path);
+ }
+
+ fn visit_path_mut(&mut self, path: &mut Path) {
+ for segment in &mut path.segments {
+ self.visit_path_arguments_mut(&mut segment.arguments);
+ }
+ }
+
+ fn visit_path_arguments_mut(&mut self, arguments: &mut PathArguments) {
+ match arguments {
+ PathArguments::None => {}
+ PathArguments::AngleBracketed(arguments) => {
+ for arg in &mut arguments.args {
+ match arg {
+ GenericArgument::Type(arg) => self.visit_type_mut(arg),
+ GenericArgument::Binding(arg) => self.visit_type_mut(&mut arg.ty),
+ GenericArgument::Lifetime(_)
+ | GenericArgument::Constraint(_)
+ | GenericArgument::Const(_) => {}
+ }
+ }
+ }
+ PathArguments::Parenthesized(arguments) => {
+ for argument in &mut arguments.inputs {
+ self.visit_type_mut(argument);
+ }
+ self.visit_return_type_mut(&mut arguments.output);
+ }
+ }
+ }
+
+ fn visit_return_type_mut(&mut self, return_type: &mut ReturnType) {
+ match return_type {
+ ReturnType::Default => {}
+ ReturnType::Type(_, output) => self.visit_type_mut(output),
+ }
+ }
+
+ fn visit_type_param_bound_mut(&mut self, bound: &mut TypeParamBound) {
+ match bound {
+ TypeParamBound::Trait(bound) => self.visit_path_mut(&mut bound.path),
+ TypeParamBound::Lifetime(_) => {}
+ }
+ }
+
+ fn visit_generics_mut(&mut self, generics: &mut Generics) {
+ for param in &mut generics.params {
+ match param {
+ GenericParam::Type(param) => {
+ for bound in &mut param.bounds {
+ self.visit_type_param_bound_mut(bound);
+ }
+ }
+ GenericParam::Lifetime(_) | GenericParam::Const(_) => {}
+ }
+ }
+ if let Some(where_clause) = &mut generics.where_clause {
+ for predicate in &mut where_clause.predicates {
+ match predicate {
+ WherePredicate::Type(predicate) => {
+ self.visit_type_mut(&mut predicate.bounded_ty);
+ for bound in &mut predicate.bounds {
+ self.visit_type_param_bound_mut(bound);
+ }
+ }
+ WherePredicate::Lifetime(_) | WherePredicate::Eq(_) => {}
+ }
+ }
+ }
+ }
+
+ fn visit_data_mut(&mut self, data: &mut Data) {
+ match data {
+ Data::Struct(data) => {
+ for field in &mut data.fields {
+ self.visit_type_mut(&mut field.ty);
+ }
+ }
+ Data::Enum(data) => {
+ for variant in &mut data.variants {
+ for field in &mut variant.fields {
+ self.visit_type_mut(&mut field.ty);
+ }
+ }
+ }
+ Data::Union(_) => {}
+ }
+ }
+
+ fn visit_expr_mut(&mut self, expr: &mut Expr) {
+ match expr {
+ Expr::Binary(expr) => {
+ self.visit_expr_mut(&mut expr.left);
+ self.visit_expr_mut(&mut expr.right);
+ }
+ Expr::Call(expr) => {
+ self.visit_expr_mut(&mut expr.func);
+ for arg in &mut expr.args {
+ self.visit_expr_mut(arg);
+ }
+ }
+ Expr::Cast(expr) => {
+ self.visit_expr_mut(&mut expr.expr);
+ self.visit_type_mut(&mut expr.ty);
+ }
+ Expr::Field(expr) => self.visit_expr_mut(&mut expr.base),
+ Expr::Index(expr) => {
+ self.visit_expr_mut(&mut expr.expr);
+ self.visit_expr_mut(&mut expr.index);
+ }
+ Expr::Paren(expr) => self.visit_expr_mut(&mut expr.expr),
+ Expr::Path(expr) => self.visit_expr_path_mut(expr),
+ Expr::Unary(expr) => self.visit_expr_mut(&mut expr.expr),
+ _ => {}
+ }
+ }
+
+ fn visit_macro_mut(&mut self, _mac: &mut Macro) {}
+}
diff --git a/third_party/rust/serde_derive/src/internals/respan.rs b/third_party/rust/serde_derive/src/internals/respan.rs
new file mode 100644
index 0000000000..dcec7017b3
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/respan.rs
@@ -0,0 +1,16 @@
+use proc_macro2::{Group, Span, TokenStream, TokenTree};
+
+pub(crate) fn respan(stream: TokenStream, span: Span) -> TokenStream {
+ stream
+ .into_iter()
+ .map(|token| respan_token(token, span))
+ .collect()
+}
+
+fn respan_token(mut token: TokenTree, span: Span) -> TokenTree {
+ if let TokenTree::Group(g) = &mut token {
+ *g = Group::new(g.delimiter(), respan(g.stream(), span));
+ }
+ token.set_span(span);
+ token
+}
diff --git a/third_party/rust/serde_derive/src/internals/symbol.rs b/third_party/rust/serde_derive/src/internals/symbol.rs
new file mode 100644
index 0000000000..1fedd2754a
--- /dev/null
+++ b/third_party/rust/serde_derive/src/internals/symbol.rs
@@ -0,0 +1,68 @@
+use std::fmt::{self, Display};
+use syn::{Ident, Path};
+
+#[derive(Copy, Clone)]
+pub struct Symbol(&'static str);
+
+pub const ALIAS: Symbol = Symbol("alias");
+pub const BORROW: Symbol = Symbol("borrow");
+pub const BOUND: Symbol = Symbol("bound");
+pub const CONTENT: Symbol = Symbol("content");
+pub const CRATE: Symbol = Symbol("crate");
+pub const DEFAULT: Symbol = Symbol("default");
+pub const DENY_UNKNOWN_FIELDS: Symbol = Symbol("deny_unknown_fields");
+pub const DESERIALIZE: Symbol = Symbol("deserialize");
+pub const DESERIALIZE_WITH: Symbol = Symbol("deserialize_with");
+pub const FIELD_IDENTIFIER: Symbol = Symbol("field_identifier");
+pub const FLATTEN: Symbol = Symbol("flatten");
+pub const FROM: Symbol = Symbol("from");
+pub const GETTER: Symbol = Symbol("getter");
+pub const INTO: Symbol = Symbol("into");
+pub const OTHER: Symbol = Symbol("other");
+pub const REMOTE: Symbol = Symbol("remote");
+pub const RENAME: Symbol = Symbol("rename");
+pub const RENAME_ALL: Symbol = Symbol("rename_all");
+pub const SERDE: Symbol = Symbol("serde");
+pub const SERIALIZE: Symbol = Symbol("serialize");
+pub const SERIALIZE_WITH: Symbol = Symbol("serialize_with");
+pub const SKIP: Symbol = Symbol("skip");
+pub const SKIP_DESERIALIZING: Symbol = Symbol("skip_deserializing");
+pub const SKIP_SERIALIZING: Symbol = Symbol("skip_serializing");
+pub const SKIP_SERIALIZING_IF: Symbol = Symbol("skip_serializing_if");
+pub const TAG: Symbol = Symbol("tag");
+pub const TRANSPARENT: Symbol = Symbol("transparent");
+pub const TRY_FROM: Symbol = Symbol("try_from");
+pub const UNTAGGED: Symbol = Symbol("untagged");
+pub const VARIANT_IDENTIFIER: Symbol = Symbol("variant_identifier");
+pub const WITH: Symbol = Symbol("with");
+pub const EXPECTING: Symbol = Symbol("expecting");
+
+impl PartialEq<Symbol> for Ident {
+ fn eq(&self, word: &Symbol) -> bool {
+ self == word.0
+ }
+}
+
+impl<'a> PartialEq<Symbol> for &'a Ident {
+ fn eq(&self, word: &Symbol) -> bool {
+ *self == word.0
+ }
+}
+
+impl PartialEq<Symbol> for Path {
+ fn eq(&self, word: &Symbol) -> bool {
+ self.is_ident(word.0)
+ }
+}
+
+impl<'a> PartialEq<Symbol> for &'a Path {
+ fn eq(&self, word: &Symbol) -> bool {
+ self.is_ident(word.0)
+ }
+}
+
+impl Display for Symbol {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(self.0)
+ }
+}
diff --git a/third_party/rust/serde_derive/src/lib.rs b/third_party/rust/serde_derive/src/lib.rs
new file mode 100644
index 0000000000..4100789118
--- /dev/null
+++ b/third_party/rust/serde_derive/src/lib.rs
@@ -0,0 +1,109 @@
+//! This crate provides Serde's two derive macros.
+//!
+//! ```edition2018
+//! # use serde_derive::{Serialize, Deserialize};
+//! #
+//! #[derive(Serialize, Deserialize)]
+//! # struct S;
+//! #
+//! # 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.152")]
+#![allow(unknown_lints, bare_trait_objects)]
+// Ignored clippy lints
+#![allow(
+ // clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054
+ clippy::branches_sharing_code,
+ clippy::cognitive_complexity,
+ // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7575
+ clippy::collapsible_match,
+ clippy::derive_partial_eq_without_eq,
+ clippy::enum_variant_names,
+ // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6797
+ clippy::manual_map,
+ clippy::match_like_matches_macro,
+ clippy::needless_pass_by_value,
+ clippy::too_many_arguments,
+ clippy::trivially_copy_pass_by_ref,
+ clippy::used_underscore_binding,
+ clippy::wildcard_in_or_patterns,
+ // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
+ clippy::unnested_or_patterns,
+)]
+// Ignored clippy_pedantic lints
+#![allow(
+ clippy::cast_possible_truncation,
+ clippy::checked_conversions,
+ clippy::doc_markdown,
+ clippy::enum_glob_use,
+ clippy::indexing_slicing,
+ clippy::items_after_statements,
+ clippy::manual_assert,
+ clippy::map_err_ignore,
+ clippy::match_same_arms,
+ // clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
+ clippy::match_wildcard_for_single_variants,
+ clippy::module_name_repetitions,
+ clippy::must_use_candidate,
+ clippy::option_if_let_else,
+ clippy::similar_names,
+ clippy::single_match_else,
+ clippy::struct_excessive_bools,
+ clippy::too_many_lines,
+ clippy::unseparated_literal_suffix,
+ clippy::unused_self,
+ clippy::use_self,
+ clippy::wildcard_imports
+)]
+#![cfg_attr(all(test, exhaustive), feature(non_exhaustive_omitted_patterns_lint))]
+
+#[macro_use]
+extern crate quote;
+#[macro_use]
+extern crate syn;
+
+extern crate proc_macro;
+extern crate proc_macro2;
+
+mod internals;
+
+use proc_macro::TokenStream;
+use syn::DeriveInput;
+
+#[macro_use]
+mod bound;
+#[macro_use]
+mod fragment;
+
+mod de;
+mod dummy;
+mod pretend;
+mod ser;
+mod this;
+mod try;
+
+#[proc_macro_derive(Serialize, attributes(serde))]
+pub fn derive_serialize(input: TokenStream) -> TokenStream {
+ let mut input = parse_macro_input!(input as DeriveInput);
+ ser::expand_derive_serialize(&mut input)
+ .unwrap_or_else(to_compile_errors)
+ .into()
+}
+
+#[proc_macro_derive(Deserialize, attributes(serde))]
+pub fn derive_deserialize(input: TokenStream) -> TokenStream {
+ let mut input = parse_macro_input!(input as DeriveInput);
+ de::expand_derive_deserialize(&mut input)
+ .unwrap_or_else(to_compile_errors)
+ .into()
+}
+
+fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream {
+ let compile_errors = errors.iter().map(syn::Error::to_compile_error);
+ quote!(#(#compile_errors)*)
+}
diff --git a/third_party/rust/serde_derive/src/pretend.rs b/third_party/rust/serde_derive/src/pretend.rs
new file mode 100644
index 0000000000..d7b953d638
--- /dev/null
+++ b/third_party/rust/serde_derive/src/pretend.rs
@@ -0,0 +1,201 @@
+use proc_macro2::TokenStream;
+use quote::format_ident;
+
+use internals::ast::{Container, Data, Field, Style, Variant};
+
+// 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, is_packed: bool) -> TokenStream {
+ let pretend_fields = pretend_fields_used(cont, is_packed);
+ 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: __v0, b: __v1 }) => {}
+// _ => {}
+// }
+//
+// For packed structs on sufficiently new rustc, expands to:
+//
+// match None::<&T> {
+// Some(__v @ T { a: _, b: _ }) => {
+// let _ = addr_of!(__v.a);
+// let _ = addr_of!(__v.b);
+// }
+// _ => {}
+// }
+//
+// For packed structs on older rustc, we assume Sized and !Drop, and expand to:
+//
+// match None::<T> {
+// Some(T { a: __v0, b: __v1 }) => {}
+// _ => {}
+// }
+//
+// For enums, expands to the following but only including struct variants:
+//
+// match None::<&T> {
+// Some(T::A { a: __v0 }) => {}
+// Some(T::B { b: __v0 }) => {}
+// _ => {}
+// }
+//
+fn pretend_fields_used(cont: &Container, is_packed: bool) -> TokenStream {
+ match &cont.data {
+ Data::Enum(variants) => pretend_fields_used_enum(cont, variants),
+ Data::Struct(Style::Struct, fields) => {
+ if is_packed {
+ pretend_fields_used_struct_packed(cont, fields)
+ } else {
+ pretend_fields_used_struct(cont, fields)
+ }
+ }
+ Data::Struct(_, _) => quote!(),
+ }
+}
+
+fn pretend_fields_used_struct(cont: &Container, fields: &[Field]) -> TokenStream {
+ let type_ident = &cont.ident;
+ let (_, ty_generics, _) = cont.generics.split_for_impl();
+
+ let members = fields.iter().map(|field| &field.member);
+ let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
+
+ quote! {
+ match _serde::__private::None::<&#type_ident #ty_generics> {
+ _serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {}
+ _ => {}
+ }
+ }
+}
+
+fn pretend_fields_used_struct_packed(cont: &Container, fields: &[Field]) -> TokenStream {
+ let type_ident = &cont.ident;
+ let (_, ty_generics, _) = cont.generics.split_for_impl();
+
+ let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>();
+
+ #[cfg(not(no_ptr_addr_of))]
+ {
+ quote! {
+ match _serde::__private::None::<&#type_ident #ty_generics> {
+ _serde::__private::Some(__v @ #type_ident { #(#members: _),* }) => {
+ #(
+ let _ = _serde::__private::ptr::addr_of!(__v.#members);
+ )*
+ }
+ _ => {}
+ }
+ }
+ }
+
+ #[cfg(no_ptr_addr_of)]
+ {
+ let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
+
+ quote! {
+ match _serde::__private::None::<#type_ident #ty_generics> {
+ _serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {}
+ _ => {}
+ }
+ }
+ }
+}
+
+fn pretend_fields_used_enum(cont: &Container, variants: &[Variant]) -> TokenStream {
+ let type_ident = &cont.ident;
+ let (_, ty_generics, _) = cont.generics.split_for_impl();
+
+ let patterns = variants
+ .iter()
+ .filter_map(|variant| match variant.style {
+ Style::Struct => {
+ let variant_ident = &variant.ident;
+ let members = variant.fields.iter().map(|field| &field.member);
+ let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
+ Some(quote!(#type_ident::#variant_ident { #(#members: #placeholders),* }))
+ }
+ _ => None,
+ })
+ .collect::<Vec<_>>();
+
+ quote! {
+ match _serde::__private::None::<&#type_ident #ty_generics> {
+ #(
+ _serde::__private::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) -> TokenStream {
+ let variants = match &cont.data {
+ Data::Enum(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| format_ident!("__v{}", i))
+ .collect::<Vec<_>>();
+
+ let pat = match variant.style {
+ Style::Struct => {
+ let members = variant.fields.iter().map(|field| &field.member);
+ quote!({ #(#members: #placeholders),* })
+ }
+ Style::Tuple | Style::Newtype => quote!(( #(#placeholders),* )),
+ Style::Unit => quote!(),
+ };
+
+ quote! {
+ match _serde::__private::None {
+ _serde::__private::Some((#(#placeholders,)*)) => {
+ let _ = #type_ident::#variant_ident #turbofish #pat;
+ }
+ _ => {}
+ }
+ }
+ });
+
+ quote!(#(#cases)*)
+}
diff --git a/third_party/rust/serde_derive/src/ser.rs b/third_party/rust/serde_derive/src/ser.rs
new file mode 100644
index 0000000000..43695dd0c3
--- /dev/null
+++ b/third_party/rust/serde_derive/src/ser.rs
@@ -0,0 +1,1340 @@
+use proc_macro2::{Span, TokenStream};
+use syn::spanned::Spanned;
+use syn::{self, Ident, Index, Member};
+
+use bound;
+use dummy;
+use fragment::{Fragment, Match, Stmts};
+use internals::ast::{Container, Data, Field, Style, Variant};
+use internals::{attr, replace_receiver, Ctxt, Derive};
+use pretend;
+use this;
+
+pub fn expand_derive_serialize(
+ input: &mut syn::DeriveInput,
+) -> Result<TokenStream, Vec<syn::Error>> {
+ replace_receiver(input);
+
+ let ctxt = Ctxt::new();
+ let cont = match Container::from_ast(&ctxt, input, Derive::Serialize) {
+ Some(cont) => cont,
+ None => return Err(ctxt.check().unwrap_err()),
+ };
+ precondition(&ctxt, &cont);
+ ctxt.check()?;
+
+ let ident = &cont.ident;
+ let params = Parameters::new(&cont);
+ let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
+ let body = Stmts(serialize_body(&cont, &params));
+ let serde = cont.attrs.serde_path();
+
+ let impl_block = if let Some(remote) = cont.attrs.remote() {
+ let vis = &input.vis;
+ let used = pretend::pretend_used(&cont, params.is_packed);
+ quote! {
+ impl #impl_generics #ident #ty_generics #where_clause {
+ #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::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::__private::Result<__S::Ok, __S::Error>
+ where
+ __S: #serde::Serializer,
+ {
+ #body
+ }
+ }
+ }
+ };
+
+ Ok(dummy::wrap_in_const(
+ cont.attrs.custom_serde_path(),
+ "SERIALIZE",
+ ident,
+ impl_block,
+ ))
+}
+
+fn precondition(cx: &Ctxt, cont: &Container) {
+ match cont.attrs.identifier() {
+ attr::Identifier::No => {}
+ attr::Identifier::Field => {
+ cx.error_spanned_by(cont.original, "field identifiers cannot be serialized");
+ }
+ attr::Identifier::Variant => {
+ cx.error_spanned_by(cont.original, "variant identifiers cannot be serialized");
+ }
+ }
+}
+
+struct Parameters {
+ /// Variable holding the value being serialized. Either `self` for local
+ /// types or `__self` for remote types.
+ self_var: Ident,
+
+ /// Path to the type the impl is for. Either a single `Ident` for local
+ /// types (does not include generic parameters) or `some::remote::Path` for
+ /// remote types.
+ this_type: syn::Path,
+
+ /// Same as `this_type` but using `::<T>` for generic parameters for use in
+ /// expression position.
+ this_value: syn::Path,
+
+ /// Generics including any explicit and inferred bounds for the impl.
+ generics: syn::Generics,
+
+ /// Type has a `serde(remote = "...")` attribute.
+ is_remote: bool,
+
+ /// Type has a repr(packed) attribute.
+ is_packed: bool,
+}
+
+impl Parameters {
+ fn new(cont: &Container) -> Self {
+ let is_remote = cont.attrs.remote().is_some();
+ let self_var = if is_remote {
+ Ident::new("__self", Span::call_site())
+ } else {
+ Ident::new("self", Span::call_site())
+ };
+
+ let this_type = this::this_type(cont);
+ let this_value = this::this_value(cont);
+ let is_packed = cont.attrs.is_packed();
+ let generics = build_generics(cont);
+
+ Parameters {
+ self_var,
+ this_type,
+ this_value,
+ generics,
+ is_remote,
+ is_packed,
+ }
+ }
+
+ /// Type name to use in error messages and `&'static str` arguments to
+ /// various Serializer methods.
+ fn type_name(&self) -> String {
+ self.this_type.segments.last().unwrap().ident.to_string()
+ }
+}
+
+// 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 '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.skip_serializing()
+ && variant.serialize_with().is_none()
+ && variant.ser_bound().is_none()
+ })
+}
+
+fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
+ if cont.attrs.transparent() {
+ serialize_transparent(cont, params)
+ } else if let Some(type_into) = cont.attrs.type_into() {
+ serialize_into(params, type_into)
+ } else {
+ match &cont.data {
+ Data::Enum(variants) => serialize_enum(params, variants, &cont.attrs),
+ Data::Struct(Style::Struct, fields) => serialize_struct(params, fields, &cont.attrs),
+ Data::Struct(Style::Tuple, fields) => {
+ serialize_tuple_struct(params, fields, &cont.attrs)
+ }
+ Data::Struct(Style::Newtype, fields) => {
+ serialize_newtype_struct(params, &fields[0], &cont.attrs)
+ }
+ Data::Struct(Style::Unit, _) => serialize_unit_struct(&cont.attrs),
+ }
+ }
+}
+
+fn serialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
+ let fields = match &cont.data {
+ Data::Struct(_, fields) => fields,
+ Data::Enum(_) => unreachable!(),
+ };
+
+ let self_var = &params.self_var;
+ let transparent_field = fields.iter().find(|f| f.attrs.transparent()).unwrap();
+ let member = &transparent_field.member;
+
+ let path = match transparent_field.attrs.serialize_with() {
+ Some(path) => quote!(#path),
+ None => {
+ let span = transparent_field.original.span();
+ quote_spanned!(span=> _serde::Serialize::serialize)
+ }
+ };
+
+ quote_block! {
+ #path(&#self_var.#member, __serializer)
+ }
+}
+
+fn serialize_into(params: &Parameters, type_into: &syn::Type) -> Fragment {
+ let self_var = &params.self_var;
+ quote_block! {
+ _serde::Serialize::serialize(
+ &_serde::__private::Into::<#type_into>::into(_serde::__private::Clone::clone(#self_var)),
+ __serializer)
+ }
+}
+
+fn serialize_unit_struct(cattrs: &attr::Container) -> Fragment {
+ let type_name = cattrs.name().serialize_name();
+
+ quote_expr! {
+ _serde::Serializer::serialize_unit_struct(__serializer, #type_name)
+ }
+}
+
+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(),
+ }),
+ );
+ 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 type_name = cattrs.name().serialize_name();
+
+ let mut serialized_fields = fields
+ .iter()
+ .enumerate()
+ .filter(|(_, 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_value()));
+
+ if cattrs.has_flatten() {
+ serialize_struct_as_map(params, fields, cattrs)
+ } else {
+ serialize_struct_as_struct(params, fields, cattrs)
+ }
+}
+
+fn serialize_struct_tag_field(cattrs: &attr::Container, struct_trait: &StructTrait) -> TokenStream {
+ match cattrs.tag() {
+ attr::TagType::Internal { tag } => {
+ let type_name = cattrs.name().serialize_name();
+ let func = struct_trait.serialize_field(Span::call_site());
+ quote! {
+ try!(#func(&mut __serde_state, #tag, #type_name));
+ }
+ }
+ _ => quote! {},
+ }
+}
+
+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 tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeStruct);
+ let tag_field_exists = !tag_field.is_empty();
+
+ let mut serialized_fields = fields
+ .iter()
+ .filter(|&field| !field.attrs.skip_serializing())
+ .peekable();
+
+ let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
+
+ let len = serialized_fields
+ .map(|field| match field.attrs.skip_serializing_if() {
+ None => quote!(1),
+ Some(path) => {
+ let field_expr = get_member(params, field, &field.member);
+ quote!(if #path(#field_expr) { 0 } else { 1 })
+ }
+ })
+ .fold(
+ quote!(#tag_field_exists as usize),
+ |sum, expr| quote!(#sum + #expr),
+ );
+
+ quote_block! {
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len));
+ #tag_field
+ #(#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);
+
+ let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeMap);
+ let tag_field_exists = !tag_field.is_empty();
+
+ let mut serialized_fields = fields
+ .iter()
+ .filter(|&field| !field.attrs.skip_serializing())
+ .peekable();
+
+ let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
+
+ let len = if cattrs.has_flatten() {
+ quote!(_serde::__private::None)
+ } else {
+ let len = serialized_fields
+ .map(|field| match field.attrs.skip_serializing_if() {
+ None => quote!(1),
+ Some(path) => {
+ let field_expr = get_member(params, field, &field.member);
+ quote!(if #path(#field_expr) { 0 } else { 1 })
+ }
+ })
+ .fold(
+ quote!(#tag_field_exists as usize),
+ |sum, expr| quote!(#sum + #expr),
+ );
+ quote!(_serde::__private::Some(#len))
+ };
+
+ quote_block! {
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(__serializer, #len));
+ #tag_field
+ #(#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_value()));
+
+ 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();
+
+ quote_expr! {
+ match *#self_var {
+ #(#arms)*
+ }
+ }
+}
+
+fn serialize_variant(
+ params: &Parameters,
+ variant: &Variant,
+ variant_index: u32,
+ cattrs: &attr::Container,
+) -> TokenStream {
+ let this_value = &params.this_value;
+ let variant_ident = &variant.ident;
+
+ if variant.attrs.skip_serializing() {
+ let skipped_msg = format!(
+ "the enum variant {}::{} cannot be serialized",
+ params.type_name(),
+ variant_ident
+ );
+ let skipped_err = quote! {
+ _serde::__private::Err(_serde::ser::Error::custom(#skipped_msg))
+ };
+ let fields_pat = match variant.style {
+ Style::Unit => quote!(),
+ Style::Newtype | Style::Tuple => quote!((..)),
+ Style::Struct => quote!({ .. }),
+ };
+ quote! {
+ #this_value::#variant_ident #fields_pat => #skipped_err,
+ }
+ } else {
+ // variant wasn't skipped
+ let case = match variant.style {
+ Style::Unit => {
+ quote! {
+ #this_value::#variant_ident
+ }
+ }
+ Style::Newtype => {
+ quote! {
+ #this_value::#variant_ident(ref __field0)
+ }
+ }
+ Style::Tuple => {
+ let field_names = (0..variant.fields.len())
+ .map(|i| Ident::new(&format!("__field{}", i), Span::call_site()));
+ quote! {
+ #this_value::#variant_ident(#(ref #field_names),*)
+ }
+ }
+ Style::Struct => {
+ let members = variant.fields.iter().map(|f| &f.member);
+ quote! {
+ #this_value::#variant_ident { #(ref #members),* }
+ }
+ }
+ };
+
+ let body = Match(match cattrs.tag() {
+ attr::TagType::External => {
+ serialize_externally_tagged_variant(params, variant, variant_index, cattrs)
+ }
+ attr::TagType::Internal { tag } => {
+ serialize_internally_tagged_variant(params, variant, cattrs, tag)
+ }
+ attr::TagType::Adjacent { tag, content } => {
+ serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content)
+ }
+ attr::TagType::None => serialize_untagged_variant(params, variant, cattrs),
+ });
+
+ quote! {
+ #case => #body
+ }
+ }
+}
+
+fn serialize_externally_tagged_variant(
+ params: &Parameters,
+ variant: &Variant,
+ variant_index: u32,
+ cattrs: &attr::Container,
+) -> Fragment {
+ let type_name = cattrs.name().serialize_name();
+ let variant_name = variant.attrs.name().serialize_name();
+
+ if let Some(path) = variant.attrs.serialize_with() {
+ let ser = wrap_serialize_variant_with(params, path, variant);
+ return quote_expr! {
+ _serde::Serializer::serialize_newtype_variant(
+ __serializer,
+ #type_name,
+ #variant_index,
+ #variant_name,
+ #ser,
+ )
+ };
+ }
+
+ match effective_style(variant) {
+ Style::Unit => {
+ quote_expr! {
+ _serde::Serializer::serialize_unit_variant(
+ __serializer,
+ #type_name,
+ #variant_index,
+ #variant_name,
+ )
+ }
+ }
+ 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);
+ }
+
+ let span = field.original.span();
+ let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_variant);
+ quote_expr! {
+ #func(
+ __serializer,
+ #type_name,
+ #variant_index,
+ #variant_name,
+ #field_expr,
+ )
+ }
+ }
+ Style::Tuple => serialize_tuple_variant(
+ TupleVariant::ExternallyTagged {
+ type_name,
+ variant_index,
+ variant_name,
+ },
+ params,
+ &variant.fields,
+ ),
+ Style::Struct => serialize_struct_variant(
+ StructVariant::ExternallyTagged {
+ variant_index,
+ variant_name,
+ },
+ params,
+ &variant.fields,
+ &type_name,
+ ),
+ }
+}
+
+fn serialize_internally_tagged_variant(
+ params: &Parameters,
+ variant: &Variant,
+ cattrs: &attr::Container,
+ tag: &str,
+) -> Fragment {
+ let type_name = cattrs.name().serialize_name();
+ let variant_name = variant.attrs.name().serialize_name();
+
+ let enum_ident_str = params.type_name();
+ let variant_ident_str = variant.ident.to_string();
+
+ if let Some(path) = variant.attrs.serialize_with() {
+ let ser = wrap_serialize_variant_with(params, path, variant);
+ return quote_expr! {
+ _serde::__private::ser::serialize_tagged_newtype(
+ __serializer,
+ #enum_ident_str,
+ #variant_ident_str,
+ #tag,
+ #variant_name,
+ #ser,
+ )
+ };
+ }
+
+ match effective_style(variant) {
+ Style::Unit => {
+ quote_block! {
+ let mut __struct = try!(_serde::Serializer::serialize_struct(
+ __serializer, #type_name, 1));
+ try!(_serde::ser::SerializeStruct::serialize_field(
+ &mut __struct, #tag, #variant_name));
+ _serde::ser::SerializeStruct::end(__struct)
+ }
+ }
+ 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);
+ }
+
+ let span = field.original.span();
+ let func = quote_spanned!(span=> _serde::__private::ser::serialize_tagged_newtype);
+ quote_expr! {
+ #func(
+ __serializer,
+ #enum_ident_str,
+ #variant_ident_str,
+ #tag,
+ #variant_name,
+ #field_expr,
+ )
+ }
+ }
+ Style::Struct => serialize_struct_variant(
+ StructVariant::InternallyTagged { tag, variant_name },
+ params,
+ &variant.fields,
+ &type_name,
+ ),
+ Style::Tuple => unreachable!("checked in serde_derive_internals"),
+ }
+}
+
+fn serialize_adjacently_tagged_variant(
+ params: &Parameters,
+ variant: &Variant,
+ cattrs: &attr::Container,
+ tag: &str,
+ content: &str,
+) -> Fragment {
+ let this_type = &params.this_type;
+ let type_name = cattrs.name().serialize_name();
+ let variant_name = variant.attrs.name().serialize_name();
+
+ let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() {
+ let ser = wrap_serialize_variant_with(params, path, variant);
+ quote_expr! {
+ _serde::Serialize::serialize(#ser, __serializer)
+ }
+ } else {
+ match effective_style(variant) {
+ Style::Unit => {
+ return quote_block! {
+ let mut __struct = try!(_serde::Serializer::serialize_struct(
+ __serializer, #type_name, 1));
+ try!(_serde::ser::SerializeStruct::serialize_field(
+ &mut __struct, #tag, #variant_name));
+ _serde::ser::SerializeStruct::end(__struct)
+ };
+ }
+ 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);
+ }
+
+ let span = field.original.span();
+ let func = quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field);
+ 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!(#func(
+ &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,
+ &variant_name,
+ ),
+ }
+ });
+
+ let fields_ty = variant.fields.iter().map(|f| &f.ty);
+ let fields_ident: &Vec<_> = &match variant.style {
+ Style::Unit => {
+ if variant.attrs.serialize_with().is_some() {
+ vec![]
+ } else {
+ unreachable!()
+ }
+ }
+ Style::Newtype => vec![Member::Named(Ident::new("__field0", Span::call_site()))],
+ Style::Tuple => (0..variant.fields.len())
+ .map(|i| Member::Named(Ident::new(&format!("__field{}", i), Span::call_site())))
+ .collect(),
+ Style::Struct => variant.fields.iter().map(|f| f.member.clone()).collect(),
+ };
+
+ let (_, ty_generics, where_clause) = params.generics.split_for_impl();
+
+ let wrapper_generics = if fields_ident.is_empty() {
+ params.generics.clone()
+ } else {
+ bound::with_lifetime_bound(&params.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::__private::PhantomData<#this_type #ty_generics>,
+ }
+
+ impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
+ fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
+ where
+ __S: _serde::Serializer,
+ {
+ // Elements that have skip_serializing will be unused.
+ #[allow(unused_variables)]
+ let (#(#fields_ident,)*) = self.data;
+ #inner
+ }
+ }
+
+ 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, &__AdjacentlyTagged {
+ data: (#(#fields_ident,)*),
+ phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
+ }));
+ _serde::ser::SerializeStruct::end(__struct)
+ }
+}
+
+fn serialize_untagged_variant(
+ params: &Parameters,
+ variant: &Variant,
+ cattrs: &attr::Container,
+) -> Fragment {
+ if let Some(path) = variant.attrs.serialize_with() {
+ let ser = wrap_serialize_variant_with(params, path, variant);
+ return quote_expr! {
+ _serde::Serialize::serialize(#ser, __serializer)
+ };
+ }
+
+ match effective_style(variant) {
+ Style::Unit => {
+ quote_expr! {
+ _serde::Serializer::serialize_unit(__serializer)
+ }
+ }
+ 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);
+ }
+
+ let span = field.original.span();
+ let func = quote_spanned!(span=> _serde::Serialize::serialize);
+ quote_expr! {
+ #func(#field_expr, __serializer)
+ }
+ }
+ Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
+ Style::Struct => {
+ let type_name = cattrs.name().serialize_name();
+ serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, &type_name)
+ }
+ }
+}
+
+enum TupleVariant {
+ ExternallyTagged {
+ type_name: String,
+ variant_index: u32,
+ variant_name: String,
+ },
+ Untagged,
+}
+
+fn serialize_tuple_variant(
+ context: TupleVariant,
+ params: &Parameters,
+ fields: &[Field],
+) -> 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 mut serialized_fields = fields
+ .iter()
+ .enumerate()
+ .filter(|(_, 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! {
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_variant(
+ __serializer,
+ #type_name,
+ #variant_index,
+ #variant_name,
+ #len));
+ #(#serialize_stmts)*
+ _serde::ser::SerializeTupleVariant::end(__serde_state)
+ }
+ }
+ TupleVariant::Untagged => {
+ quote_block! {
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple(
+ __serializer,
+ #len));
+ #(#serialize_stmts)*
+ _serde::ser::SerializeTuple::end(__serde_state)
+ }
+ }
+ }
+}
+
+enum StructVariant<'a> {
+ ExternallyTagged {
+ variant_index: u32,
+ variant_name: String,
+ },
+ InternallyTagged {
+ tag: &'a str,
+ variant_name: String,
+ },
+ Untagged,
+}
+
+fn serialize_struct_variant(
+ context: StructVariant,
+ 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
+ }
+ };
+
+ 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());
+
+ let len = serialized_fields
+ .map(|field| {
+ let member = &field.member;
+
+ match field.attrs.skip_serializing_if() {
+ Some(path) => quote!(if #path(#member) { 0 } else { 1 }),
+ None => quote!(1),
+ }
+ })
+ .fold(quote!(0), |sum, expr| quote!(#sum + #expr));
+
+ match context {
+ StructVariant::ExternallyTagged {
+ variant_index,
+ variant_name,
+ } => {
+ quote_block! {
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct_variant(
+ __serializer,
+ #name,
+ #variant_index,
+ #variant_name,
+ #len,
+ ));
+ #(#serialize_fields)*
+ _serde::ser::SerializeStructVariant::end(__serde_state)
+ }
+ }
+ StructVariant::InternallyTagged { tag, variant_name } => {
+ quote_block! {
+ let mut __serde_state = try!(_serde::Serializer::serialize_struct(
+ __serializer,
+ #name,
+ #len + 1,
+ ));
+ try!(_serde::ser::SerializeStruct::serialize_field(
+ &mut __serde_state,
+ #tag,
+ #variant_name,
+ ));
+ #(#serialize_fields)*
+ _serde::ser::SerializeStruct::end(__serde_state)
+ }
+ }
+ StructVariant::Untagged => {
+ quote_block! {
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(
+ __serializer,
+ #name,
+ #len,
+ ));
+ #(#serialize_fields)*
+ _serde::ser::SerializeStruct::end(__serde_state)
+ }
+ }
+ }
+}
+
+fn serialize_struct_variant_with_flatten(
+ context: StructVariant,
+ 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_type = &params.this_type;
+ let fields_ty = fields.iter().map(|f| &f.ty);
+ let members = &fields.iter().map(|f| &f.member).collect::<Vec<_>>();
+
+ let (_, ty_generics, where_clause) = params.generics.split_for_impl();
+ let wrapper_generics = bound::with_lifetime_bound(&params.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::__private::PhantomData<#this_type #ty_generics>,
+ }
+
+ impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
+ fn serialize<__S>(&self, __serializer: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
+ where
+ __S: _serde::Serializer,
+ {
+ let (#(#members,)*) = self.data;
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
+ __serializer,
+ _serde::__private::None));
+ #(#serialize_fields)*
+ _serde::ser::SerializeMap::end(__serde_state)
+ }
+ }
+
+ _serde::Serializer::serialize_newtype_variant(
+ __serializer,
+ #name,
+ #variant_index,
+ #variant_name,
+ &__EnumFlatten {
+ data: (#(#members,)*),
+ phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
+ })
+ }
+ }
+ StructVariant::InternallyTagged { tag, variant_name } => {
+ quote_block! {
+ let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(
+ __serializer,
+ _serde::__private::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::__private::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<TokenStream> {
+ fields
+ .iter()
+ .enumerate()
+ .filter(|(_, 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(),
+ }),
+ )
+ };
+
+ let skip = field
+ .attrs
+ .skip_serializing_if()
+ .map(|path| quote!(#path(#field_expr)));
+
+ 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 = tuple_trait.serialize_element(span);
+ let ser = quote! {
+ try!(#func(&mut __serde_state, #field_expr));
+ };
+
+ match skip {
+ None => ser,
+ Some(skip) => quote!(if !#skip { #ser }),
+ }
+ })
+ .collect()
+}
+
+fn serialize_struct_visitor(
+ fields: &[Field],
+ params: &Parameters,
+ is_enum: bool,
+ struct_trait: &StructTrait,
+) -> Vec<TokenStream> {
+ fields
+ .iter()
+ .filter(|&field| !field.attrs.skip_serializing())
+ .map(|field| {
+ let member = &field.member;
+
+ let mut field_expr = if is_enum {
+ quote!(#member)
+ } else {
+ get_member(params, field, member)
+ };
+
+ let key_expr = field.attrs.name().serialize_name();
+
+ let skip = field
+ .attrs
+ .skip_serializing_if()
+ .map(|path| quote!(#path(#field_expr)));
+
+ 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 ser = if field.attrs.flatten() {
+ let func = quote_spanned!(span=> _serde::Serialize::serialize);
+ quote! {
+ try!(#func(&#field_expr, _serde::__private::ser::FlatMapSerializer(&mut __serde_state)));
+ }
+ } else {
+ let func = struct_trait.serialize_field(span);
+ quote! {
+ try!(#func(&mut __serde_state, #key_expr, #field_expr));
+ }
+ };
+
+ match skip {
+ None => ser,
+ Some(skip) => {
+ if let Some(skip_func) = struct_trait.skip_field(span) {
+ quote! {
+ if !#skip {
+ #ser
+ } else {
+ try!(#skip_func(&mut __serde_state, #key_expr));
+ }
+ }
+ } else {
+ quote! {
+ if !#skip {
+ #ser
+ }
+ }
+ }
+ }
+ }
+ })
+ .collect()
+}
+
+fn wrap_serialize_field_with(
+ params: &Parameters,
+ field_ty: &syn::Type,
+ serialize_with: &syn::ExprPath,
+ field_expr: &TokenStream,
+) -> TokenStream {
+ wrap_serialize_with(params, serialize_with, &[field_ty], &[quote!(#field_expr)])
+}
+
+fn wrap_serialize_variant_with(
+ params: &Parameters,
+ serialize_with: &syn::ExprPath,
+ variant: &Variant,
+) -> TokenStream {
+ let field_tys: Vec<_> = variant.fields.iter().map(|field| field.ty).collect();
+ let field_exprs: Vec<_> = variant
+ .fields
+ .iter()
+ .map(|field| {
+ let id = match &field.member {
+ Member::Named(ident) => ident.clone(),
+ Member::Unnamed(member) => {
+ Ident::new(&format!("__field{}", member.index), Span::call_site())
+ }
+ };
+ quote!(#id)
+ })
+ .collect();
+ wrap_serialize_with(
+ params,
+ serialize_with,
+ field_tys.as_slice(),
+ field_exprs.as_slice(),
+ )
+}
+
+fn wrap_serialize_with(
+ params: &Parameters,
+ serialize_with: &syn::ExprPath,
+ field_tys: &[&syn::Type],
+ field_exprs: &[TokenStream],
+) -> TokenStream {
+ let this_type = &params.this_type;
+ let (_, ty_generics, where_clause) = params.generics.split_for_impl();
+
+ let wrapper_generics = if field_exprs.is_empty() {
+ params.generics.clone()
+ } else {
+ bound::with_lifetime_bound(&params.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(),
+ })
+ });
+
+ quote!({
+ struct __SerializeWith #wrapper_impl_generics #where_clause {
+ values: (#(&'__a #field_tys, )*),
+ phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
+ }
+
+ impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
+ fn serialize<__S>(&self, __s: __S) -> _serde::__private::Result<__S::Ok, __S::Error>
+ where
+ __S: _serde::Serializer,
+ {
+ #serialize_with(#(self.values.#field_access, )* __s)
+ }
+ }
+
+ &__SerializeWith {
+ values: (#(#field_exprs, )*),
+ phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
+ }
+ })
+}
+
+// Serialization of an empty struct results in code like:
+//
+// let mut __serde_state = try!(serializer.serialize_struct("S", 0));
+// _serde::ser::SerializeStruct::end(__serde_state)
+//
+// where we want to omit the `mut` to avoid a warning.
+fn mut_if(is_mut: bool) -> Option<TokenStream> {
+ if is_mut {
+ Some(quote!(mut))
+ } else {
+ None
+ }
+}
+
+fn get_member(params: &Parameters, field: &Field, member: &Member) -> TokenStream {
+ let self_var = &params.self_var;
+ match (params.is_remote, field.attrs.getter()) {
+ (false, None) => {
+ if params.is_packed {
+ quote!(&{#self_var.#member})
+ } else {
+ quote!(&#self_var.#member)
+ }
+ }
+ (true, None) => {
+ let inner = if params.is_packed {
+ quote!(&{#self_var.#member})
+ } else {
+ 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(_)) => {
+ unreachable!("getter is only allowed for remote impls");
+ }
+ }
+}
+
+fn effective_style(variant: &Variant) -> Style {
+ match variant.style {
+ Style::Newtype if variant.fields[0].attrs.skip_serializing() => Style::Unit,
+ other => other,
+ }
+}
+
+enum StructTrait {
+ SerializeMap,
+ SerializeStruct,
+ SerializeStructVariant,
+}
+
+impl StructTrait {
+ fn serialize_field(&self, span: Span) -> TokenStream {
+ match *self {
+ StructTrait::SerializeMap => {
+ quote_spanned!(span=> _serde::ser::SerializeMap::serialize_entry)
+ }
+ StructTrait::SerializeStruct => {
+ quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field)
+ }
+ StructTrait::SerializeStructVariant => {
+ quote_spanned!(span=> _serde::ser::SerializeStructVariant::serialize_field)
+ }
+ }
+ }
+
+ fn skip_field(&self, span: Span) -> Option<TokenStream> {
+ 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))
+ }
+ }
+ }
+}
+
+enum TupleTrait {
+ SerializeTuple,
+ SerializeTupleStruct,
+ SerializeTupleVariant,
+}
+
+impl TupleTrait {
+ fn serialize_element(&self, span: Span) -> TokenStream {
+ match *self {
+ TupleTrait::SerializeTuple => {
+ quote_spanned!(span=> _serde::ser::SerializeTuple::serialize_element)
+ }
+ TupleTrait::SerializeTupleStruct => {
+ quote_spanned!(span=> _serde::ser::SerializeTupleStruct::serialize_field)
+ }
+ TupleTrait::SerializeTupleVariant => {
+ quote_spanned!(span=> _serde::ser::SerializeTupleVariant::serialize_field)
+ }
+ }
+ }
+}
diff --git a/third_party/rust/serde_derive/src/this.rs b/third_party/rust/serde_derive/src/this.rs
new file mode 100644
index 0000000000..32731d0896
--- /dev/null
+++ b/third_party/rust/serde_derive/src/this.rs
@@ -0,0 +1,32 @@
+use internals::ast::Container;
+use syn::{Path, PathArguments, Token};
+
+pub fn this_type(cont: &Container) -> Path {
+ if let Some(remote) = cont.attrs.remote() {
+ let mut this = remote.clone();
+ for segment in &mut this.segments {
+ if let PathArguments::AngleBracketed(arguments) = &mut segment.arguments {
+ arguments.colon2_token = None;
+ }
+ }
+ this
+ } else {
+ Path::from(cont.ident.clone())
+ }
+}
+
+pub fn this_value(cont: &Container) -> Path {
+ if let Some(remote) = cont.attrs.remote() {
+ let mut this = remote.clone();
+ for segment in &mut this.segments {
+ if let PathArguments::AngleBracketed(arguments) = &mut segment.arguments {
+ if arguments.colon2_token.is_none() {
+ arguments.colon2_token = Some(Token![::](arguments.lt_token.span));
+ }
+ }
+ }
+ this
+ } else {
+ Path::from(cont.ident.clone())
+ }
+}
diff --git a/third_party/rust/serde_derive/src/try.rs b/third_party/rust/serde_derive/src/try.rs
new file mode 100644
index 0000000000..48cceebaaf
--- /dev/null
+++ b/third_party/rust/serde_derive/src/try.rs
@@ -0,0 +1,24 @@
+use proc_macro2::{Punct, Spacing, TokenStream};
+
+// 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() -> TokenStream {
+ // Cannot pass `$expr` to `quote!` prior to Rust 1.17.0 so interpolate it.
+ let dollar = Punct::new('$', Spacing::Alone);
+
+ quote! {
+ #[allow(unused_macros)]
+ macro_rules! try {
+ (#dollar __expr:expr) => {
+ match #dollar __expr {
+ _serde::__private::Ok(__val) => __val,
+ _serde::__private::Err(__err) => {
+ return _serde::__private::Err(__err);
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/third_party/rust/serde_json/.cargo-checksum.json b/third_party/rust/serde_json/.cargo-checksum.json
new file mode 100644
index 0000000000..369b6fe170
--- /dev/null
+++ b/third_party/rust/serde_json/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CONTRIBUTING.md":"f5270cafba66223a7b51ffc0d286075a17bb7cd88762fc80d333d3102629f4d8","Cargo.toml":"547ec897b43d41db797423629543e838ee4e08c6a4196a0756b5be0ef178adc1","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"1e5a86e6b5e79f92f9e7226d9a8ba16d4ec70567d153c9cacebcb582770378a1","build.rs":"0dd97b63a07aa2d4bbb4c7d0e73b521da130769da9f49f28a7b63332781eb3de","src/de.rs":"5dba95fc6a564917289bf1e404d59c74f95772f22ec92cb91d55053b65e93032","src/error.rs":"abb92a9bf62cb7f47141a733a9fd66ec8c369615d7e6f633d3536fd2a5ac74a2","src/features_check/error.rs":"d7359f864afbfe105a38abea9f563dc423036ebc4c956a5695a4beef144dc7ec","src/features_check/mod.rs":"2209f8d5c46b50c8a3b8dc22338dcaf0135d192e8b05d2f456cbe6a73104e958","src/io/core.rs":"9a4146802391fd202a36bebbf3b14b715ae09d8828cbe8e06a01214c470ebf5c","src/io/mod.rs":"fd1ed5080495cab21117f6f7d3c2c9e3687cad0c69a0cd087b08a145a9e672da","src/iter.rs":"f832c469cd7999d26ba9b76baa69b257a212a7edb3dfdf9b1d1bb35e8da85fa9","src/lexical/algorithm.rs":"4fbeb1994049348d1fc388dd1a29e481f8abb8fe1e28bfebf50f3bbce5fa5fbe","src/lexical/bhcomp.rs":"b7c68d74c0055eb67ec2c1bcf27bbc28bef8f1bbc43db8eb94ba69892230add6","src/lexical/bignum.rs":"4230cde10dc8eae456a713cf90ec4e48dff4b1d0c542621ce7f00f39ade2645e","src/lexical/cached.rs":"0e127398691f8042c19cde209e7f4b0161f0f3150342430145929f711e6fdac8","src/lexical/cached_float80.rs":"0f8f74a22cb7d871322a9893bffd0255ca10bf9dffd13afb2462dd3d7f51805f","src/lexical/digit.rs":"a265b9072194a62a67dfc4df3c86d4213097cf3f82280d025e0012a5a262fd9d","src/lexical/errors.rs":"6bc993febceb7dd96ac1c8c5c53b5f5a30297016c0f813ed8ff8d7938d01534d","src/lexical/exponent.rs":"387e945b97dc7ba48a7091c50d228a0dde3a1c4145703d4ab9c31191a91693b0","src/lexical/float.rs":"fe356213c92a049f4bef2f58bc0e3a26866ca06b8c1d74d0f961c5b883852cad","src/lexical/large_powers.rs":"34537f5c701afce1ec2a1fd3c14950381b2e27c9ad74f002c91f3708e8da9ca5","src/lexical/large_powers32.rs":"d533037c6141e6671102aee490c9cdeaba81e667ddca781b2b99db2c455e4a1a","src/lexical/large_powers64.rs":"745dd7c0cbe499eec027ef586248881011d9df20c7efab7929c1807b59886ba1","src/lexical/math.rs":"27e22b724cdf990cdacd0ccfc3749e6e2eb7529d43ebf6e95b1999560b9e199a","src/lexical/mod.rs":"4b4c5228779c0f135a4cb018700e3bcd495da48b74421a86f6b8b304acdef924","src/lexical/num.rs":"cf705c62612e31d704f43d94a633ea1243c6befad7ef5792e2e881a7fd21e809","src/lexical/parse.rs":"c2bfac4c70a19938ced61e991f4ec606764887cf12bac1a0978b5b5318a56aac","src/lexical/rounding.rs":"697207248ba17b7f4965aedb11d276261ada5b06d9c6265d8fd6246664ff6e3c","src/lexical/shift.rs":"bc1ed053dd63d45ac9c35302f18de9f00d94027f28af4ab749c9248439de832a","src/lexical/small_powers.rs":"4608dd218b8002435db7e1ec79d2d0fef5f47ae257b93353326d52ecc80cccda","src/lib.rs":"f055ef570d978397cfae0d814ddbbf2372b8839ab4ffe8fc4c3308c9b2a332de","src/macros.rs":"c9f23156faec8d5216d72b6a97eebd768efb3f75870a6e2beed824308587b998","src/map.rs":"14fa16650b462ef138bebe1d18cb296b0e1ff404f12f2c212f72ed7c969b3a12","src/number.rs":"425f528c5ec2fcb4dd3c87a633d0b2cd505f7a305a40dffa1f022a643eda938b","src/raw.rs":"6d46836486b8d1c58f2aff563285400b1b0ec163eee34e7be78e0fa7a99aa0e8","src/read.rs":"49b4b1d067b6485cbded28fb961666ab5df82c36661af722dbae756efb6b2891","src/ser.rs":"566ae0b1860861ad70efd17fb0f6ae326e76d60453b6538c783a40d4ce616851","src/value/de.rs":"78f938d960e285f671f3b86ed173d598a815690a14512d6daa94dee43d3ce4cf","src/value/from.rs":"2dcfed837b040447a61eae50bd3938106b090f8a292206aea686022767006625","src/value/index.rs":"8a99d8d50f5674181ced22f6e81dc529eaecb01e543e30346e51fe42cb4b8a5f","src/value/mod.rs":"81c62fcb50e92b2f424e361328df5b02621756781bf80b8e26fd3d13473b57cd","src/value/partial_eq.rs":"95de799d57f7f4310b64a9488c0a7286dee76dba4329cb69a96298a887e58586","src/value/ser.rs":"5ea04bdf30c1c79baeab66b922908b47f1910b07d2f4ed0927a9a2c1ef3fbf60","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/debug.rs":"a8451217c1e127ad6e653ef11e0513525ee350e1e37dd575758a8ee9301b28fb","tests/lexical.rs":"383e06283e15e1db7c6b818da3c84a3afa0059f6e9fc994b069919d81346ab91","tests/lexical/algorithm.rs":"da378df9ee24bfa033968d5c94e91b58e52c39bf6c825dec51c3eb7250cc5874","tests/lexical/exponent.rs":"26ea92abc654a6a88a8281552bca2f76ea1fa4c17d66a1dd6defe14f7d89b666","tests/lexical/float.rs":"0440f2d85c993bcccd925096d7f4136bf624ffd66b3c7ee565d158390685eb11","tests/lexical/math.rs":"4874be2103be5fbe8b8015354414df271ffa00fd815546fc077f15fb4d7a5a37","tests/lexical/num.rs":"6e650c40de85ed72ac06b6bf1487ba161f3824e26d827df6cfdf2bbdb8d05a05","tests/lexical/parse.rs":"17c73e0a59d462716d974b8dd23a291eb6efdc3a933248874e5eab7e7209d67f","tests/lexical/rounding.rs":"6c56e39ba534616c1b2146e8efa6eb57aed322e683bf23183cd32a61fae6447e","tests/macros/mod.rs":"93aa1d54af20bc2c55b6ae8db73c1414cda2626eb9fa7bd57b9d613a3c6e6a19","tests/map.rs":"dcc5212242e4e93703c4335d54f5603b0211b33d6fb5ab410bb630cda6d46b09","tests/regression.rs":"86731134bfb9bb693d9a4fc62393027de80a8bf031109ea6c7ea475b1ebdde8d","tests/regression/issue520.rs":"d146be3472db902b48127d65fe83aa9f698143aca9074c83cd1a9d5dd28e3ec3","tests/regression/issue795.rs":"582e2e7c68113f05a4b1d2cb556a2df7cc77f2ce8164a32c5cc58ae68abb60ec","tests/regression/issue845.rs":"8bd64588fc344e119d0e9e5e7604236e7c168c574b0692033f15278e216a6b9c","tests/regression/issue953.rs":"b2cddc761f5ca6639900c173765a8a5868528a896924e5e925db2696469208f7","tests/stream.rs":"c7d91014538ecd8f495b196d40e999ab2745f2e69fa2ff9e52521605dc6ce856","tests/test.rs":"b9154ff63261cecd6f04443ce3580d285af16f77cdc2c87239408cb8e06009dc","tests/ui/missing_colon.rs":"d07e0c34d98eb43465f0a0310f2c0b5d5b0d26d243b352a1c6bbe6ad3b27eda9","tests/ui/missing_colon.stderr":"3732fd8f4e57b84efc07170cda5f9c5b2b17c707e23c1659222b5a46f652a8d8","tests/ui/missing_comma.rs":"b8a9662f99c3e6dd2b6417892c37640578ce91d3a8365bf10c1f686a3227aa87","tests/ui/missing_comma.stderr":"eae626cf93c97abd105066e624ca4e8cb096784413b9d2564cf9414a8492bc4d","tests/ui/missing_value.rs":"bca25d67127fb88e7c191c7b03af5a4ce8a9abb630f3d2e6a6c1e77e213dc9a4","tests/ui/missing_value.stderr":"b0df8add5cf74e5df30eedd3ca347e4862c04a01c54d802ff45392f2032065b1","tests/ui/not_found.rs":"d0a7adb309879ff65aee115b52cc33d36f4bad353cf97c4effc34a6128c2bee3","tests/ui/not_found.stderr":"359b751c0c21fab6d460daef4d5f73a265f7769c9b578f98ea3cb6cbf2387643","tests/ui/parse_expr.rs":"32e6d51f528db3d1ab0ed1e24765b865be393565c26f77413c5aa39d601ac563","tests/ui/parse_expr.stderr":"4fcd0a014fbce31c9266bab8527d6e6b6806a0e21d9e0275ce713137856073ce","tests/ui/parse_key.rs":"18829b2af320d5cf8a0a5cd3aaf84c7e92cc874651c30e45a3acafb76c2d8b93","tests/ui/parse_key.stderr":"fcb44e060b804a4762b7291e128c41d7010ffa8ab820b8828fd13fbe6d405ca6","tests/ui/unexpected_after_array_element.rs":"a343fc3104431720bdfcf330bcc3cfcd98c8dec3e951133b495242478b0b7eb3","tests/ui/unexpected_after_array_element.stderr":"8df615998fa3057bb9ed865981a35cdbb771625337048f0ad3fba7734e607adf","tests/ui/unexpected_after_map_entry.rs":"6e3bd2def435ca610e346bbc75cdbaf61963eb2ef1885bb5f76781ba1fac37ef","tests/ui/unexpected_after_map_entry.stderr":"b1985c89075ab48b2158bd1705ed766d37854b3d4620ab257cc8bc319d224f17","tests/ui/unexpected_colon.rs":"a313cff3fed4be4c33f1eda5d0c5c98147fb835a56d36470d9f367352c1d61ef","tests/ui/unexpected_colon.stderr":"b2288742fa6a4a7eb65d2ae899bcfed8795b57bd04958da227d60928a8df26c5","tests/ui/unexpected_comma.rs":"55a8b684bde1ce905837cce719fd457d8898b61cebc27e5b420d05cb6be97256","tests/ui/unexpected_comma.stderr":"4c103ca63ff15e2ca659242cc0eae0612bf050e7580da62f1cf50de8082aa7dc"},"package":"cad406b69c91885b5107daf2c29572f6c8cdb3c66826821e286c533490c0bc76"} \ No newline at end of file
diff --git a/third_party/rust/serde_json/CONTRIBUTING.md b/third_party/rust/serde_json/CONTRIBUTING.md
new file mode 100644
index 0000000000..26e15783a1
--- /dev/null
+++ b/third_party/rust/serde_json/CONTRIBUTING.md
@@ -0,0 +1,46 @@
+# Contributing to Serde
+
+Serde welcomes contribution from everyone in the form of suggestions, bug
+reports, pull requests, and feedback. This document gives some guidance if you
+are thinking of helping us.
+
+## Submitting bug reports and feature requests
+
+Serde development is spread across lots of repositories. In general, prefer to
+open issues against the main [serde-rs/serde] repository unless the topic is
+clearly specific to JSON.
+
+[serde-rs/serde]: https://github.com/serde-rs/serde
+
+When reporting a bug or asking for help, please include enough details so that
+the people helping you can reproduce the behavior you are seeing. For some tips
+on how to approach this, read about how to produce a [Minimal, Complete, and
+Verifiable example].
+
+[Minimal, Complete, and Verifiable example]: https://stackoverflow.com/help/mcve
+
+When making a feature request, please make it clear what problem you intend to
+solve with the feature, any ideas for how Serde could support solving that
+problem, any possible alternatives, and any disadvantages.
+
+## Running the test suite
+
+We encourage you to check that the test suite passes locally before submitting a
+pull request with your changes. If anything does not pass, typically it will be
+easier to iterate and fix it locally than waiting for the CI servers to run
+tests for you.
+
+The test suite requires a nightly compiler.
+
+```sh
+# Run the full test suite, including doc test and compile-tests
+cargo test
+```
+
+## Conduct
+
+In all Serde-related forums, we follow the [Rust Code of Conduct]. For
+escalation or moderation issues please contact Erick (erick.tryzelaar@gmail.com)
+instead of the Rust moderation team.
+
+[Rust Code of Conduct]: https://www.rust-lang.org/policies/code-of-conduct
diff --git a/third_party/rust/serde_json/Cargo.toml b/third_party/rust/serde_json/Cargo.toml
new file mode 100644
index 0000000000..cff28cd7b2
--- /dev/null
+++ b/third_party/rust/serde_json/Cargo.toml
@@ -0,0 +1,109 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+rust-version = "1.36"
+name = "serde_json"
+version = "1.0.93"
+authors = [
+ "Erick Tryzelaar <erick.tryzelaar@gmail.com>",
+ "David Tolnay <dtolnay@gmail.com>",
+]
+description = "A JSON serialization file format"
+documentation = "https://docs.rs/serde_json"
+readme = "README.md"
+keywords = [
+ "json",
+ "serde",
+ "serialization",
+]
+categories = [
+ "encoding",
+ "parser-implementations",
+ "no-std",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/serde-rs/json"
+
+[package.metadata.docs.rs]
+features = [
+ "raw_value",
+ "unbounded_depth",
+]
+targets = ["x86_64-unknown-linux-gnu"]
+rustdoc-args = [
+ "--cfg",
+ "docsrs",
+]
+
+[package.metadata.playground]
+features = ["raw_value"]
+
+[lib]
+doc-scrape-examples = false
+
+[dependencies.indexmap]
+version = "1.5.2"
+features = ["std"]
+optional = true
+
+[dependencies.itoa]
+version = "1.0"
+
+[dependencies.ryu]
+version = "1.0"
+
+[dependencies.serde]
+version = "1.0.100"
+default-features = false
+
+[dev-dependencies.automod]
+version = "1.0"
+
+[dev-dependencies.indoc]
+version = "2.0"
+
+[dev-dependencies.ref-cast]
+version = "1.0"
+
+[dev-dependencies.rustversion]
+version = "1.0"
+
+[dev-dependencies.serde]
+version = "1.0.100"
+features = ["derive"]
+
+[dev-dependencies.serde_bytes]
+version = "0.11"
+
+[dev-dependencies.serde_derive]
+version = "1.0"
+
+[dev-dependencies.serde_stacker]
+version = "0.1"
+
+[dev-dependencies.trybuild]
+version = "1.0.49"
+features = ["diff"]
+
+[features]
+alloc = ["serde/alloc"]
+arbitrary_precision = []
+default = ["std"]
+float_roundtrip = []
+preserve_order = [
+ "indexmap",
+ "std",
+]
+raw_value = []
+std = ["serde/std"]
+unbounded_depth = []
diff --git a/third_party/rust/serde_json/LICENSE-APACHE b/third_party/rust/serde_json/LICENSE-APACHE
new file mode 100644
index 0000000000..1b5ec8b78e
--- /dev/null
+++ b/third_party/rust/serde_json/LICENSE-APACHE
@@ -0,0 +1,176 @@
+ 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
diff --git a/third_party/rust/serde_json/LICENSE-MIT b/third_party/rust/serde_json/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/third_party/rust/serde_json/LICENSE-MIT
@@ -0,0 +1,23 @@
+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.
diff --git a/third_party/rust/serde_json/README.md b/third_party/rust/serde_json/README.md
new file mode 100644
index 0000000000..d704979247
--- /dev/null
+++ b/third_party/rust/serde_json/README.md
@@ -0,0 +1,390 @@
+# Serde JSON &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![Rustc Version 1.36+]][rustc]
+
+[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/json/ci.yml?branch=master
+[actions]: https://github.com/serde-rs/json/actions?query=branch%3Amaster
+[Latest Version]: https://img.shields.io/crates/v/serde_json.svg
+[crates.io]: https://crates.io/crates/serde\_json
+[Rustc Version 1.36+]: https://img.shields.io/badge/rustc-1.36+-lightgray.svg
+[rustc]: https://blog.rust-lang.org/2019/07/04/Rust-1.36.0.html
+
+**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
+
+---
+
+```toml
+[dependencies]
+serde_json = "1.0"
+```
+
+You may be looking for:
+
+- [JSON API documentation](https://docs.rs/serde_json)
+- [Serde API documentation](https://docs.rs/serde)
+- [Detailed documentation about Serde](https://serde.rs/)
+- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
+- [Release notes](https://github.com/serde-rs/json/releases)
+
+JSON is a ubiquitous open-standard format that uses human-readable text to
+transmit data objects consisting of key-value pairs.
+
+```json
+{
+ "name": "John Doe",
+ "age": 43,
+ "address": {
+ "street": "10 Downing Street",
+ "city": "London"
+ },
+ "phones": [
+ "+44 1234567",
+ "+44 2345678"
+ ]
+}
+```
+
+There are three common ways that you might find yourself needing to work with
+JSON data in Rust.
+
+ - **As text data.** An unprocessed string of JSON data that you receive on an
+ HTTP endpoint, read from a file, or prepare to send to a remote server.
+ - **As an untyped or loosely typed representation.** Maybe you want to check
+ that some JSON data is valid before passing it on, but without knowing the
+ structure of what it contains. Or you want to do very basic manipulations
+ like insert a key in a particular spot.
+ - **As a strongly typed Rust data structure.** When you expect all or most of
+ your data to conform to a particular structure and want to get real work done
+ without JSON's loosey-goosey nature tripping you up.
+
+Serde JSON provides efficient, flexible, safe ways of converting data between
+each of these representations.
+
+## Operating on untyped JSON values
+
+Any valid JSON data can be manipulated in the following recursive enum
+representation. This data structure is [`serde_json::Value`][value].
+
+```rust
+enum Value {
+ Null,
+ Bool(bool),
+ Number(Number),
+ String(String),
+ Array(Vec<Value>),
+ Object(Map<String, Value>),
+}
+```
+
+A string of JSON data can be parsed into a `serde_json::Value` by the
+[`serde_json::from_str`][from_str] function. There is also
+[`from_slice`][from_slice] for parsing from a byte slice &[u8] and
+[`from_reader`][from_reader] for parsing from any `io::Read` like a File or a
+TCP stream.
+
+<div align="right">
+<a href="https://play.rust-lang.org/?edition=2018&gist=d69d8e3156d4bb81c4461b60b772ab72" target="_blank">
+<img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png">
+</a>
+</div>
+
+```rust
+use serde_json::{Result, Value};
+
+fn untyped_example() -> Result<()> {
+ // Some JSON input data as a &str. Maybe this comes from the user.
+ let data = r#"
+ {
+ "name": "John Doe",
+ "age": 43,
+ "phones": [
+ "+44 1234567",
+ "+44 2345678"
+ ]
+ }"#;
+
+ // Parse the string of data into serde_json::Value.
+ let v: Value = serde_json::from_str(data)?;
+
+ // Access parts of the data by indexing with square brackets.
+ println!("Please call {} at the number {}", v["name"], v["phones"][0]);
+
+ Ok(())
+}
+```
+
+The result of square bracket indexing like `v["name"]` is a borrow of the data
+at that index, so the type is `&Value`. A JSON map can be indexed with string
+keys, while a JSON array can be indexed with integer keys. If the type of the
+data is not right for the type with which it is being indexed, or if a map does
+not contain the key being indexed, or if the index into a vector is out of
+bounds, the returned element is `Value::Null`.
+
+When a `Value` is printed, it is printed as a JSON string. So in the code above,
+the output looks like `Please call "John Doe" at the number "+44 1234567"`. The
+quotation marks appear because `v["name"]` is a `&Value` containing a JSON
+string and its JSON representation is `"John Doe"`. Printing as a plain string
+without quotation marks involves converting from a JSON string to a Rust string
+with [`as_str()`] or avoiding the use of `Value` as described in the following
+section.
+
+[`as_str()`]: https://docs.rs/serde_json/1/serde_json/enum.Value.html#method.as_str
+
+The `Value` representation is sufficient for very basic tasks but can be tedious
+to work with for anything more significant. Error handling is verbose to
+implement correctly, for example imagine trying to detect the presence of
+unrecognized fields in the input data. The compiler is powerless to help you
+when you make a mistake, for example imagine typoing `v["name"]` as `v["nmae"]`
+in one of the dozens of places it is used in your code.
+
+## Parsing JSON as strongly typed data structures
+
+Serde provides a powerful way of mapping JSON data into Rust data structures
+largely automatically.
+
+<div align="right">
+<a href="https://play.rust-lang.org/?edition=2018&gist=15cfab66d38ff8a15a9cf1d8d897ac68" target="_blank">
+<img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png">
+</a>
+</div>
+
+```rust
+use serde::{Deserialize, Serialize};
+use serde_json::Result;
+
+#[derive(Serialize, Deserialize)]
+struct Person {
+ name: String,
+ age: u8,
+ phones: Vec<String>,
+}
+
+fn typed_example() -> Result<()> {
+ // Some JSON input data as a &str. Maybe this comes from the user.
+ let data = r#"
+ {
+ "name": "John Doe",
+ "age": 43,
+ "phones": [
+ "+44 1234567",
+ "+44 2345678"
+ ]
+ }"#;
+
+ // Parse the string of data into a Person object. This is exactly the
+ // same function as the one that produced serde_json::Value above, but
+ // now we are asking it for a Person as output.
+ let p: Person = serde_json::from_str(data)?;
+
+ // Do things just like with any other Rust data structure.
+ println!("Please call {} at the number {}", p.name, p.phones[0]);
+
+ Ok(())
+}
+```
+
+This is the same `serde_json::from_str` function as before, but this time we
+assign the return value to a variable of type `Person` so Serde will
+automatically interpret the input data as a `Person` and produce informative
+error messages if the layout does not conform to what a `Person` is expected to
+look like.
+
+Any type that implements Serde's `Deserialize` trait can be deserialized this
+way. This includes built-in Rust standard library types like `Vec<T>` and
+`HashMap<K, V>`, as well as any structs or enums annotated with
+`#[derive(Deserialize)]`.
+
+Once we have `p` of type `Person`, our IDE and the Rust compiler can help us use
+it correctly like they do for any other Rust code. The IDE can autocomplete
+field names to prevent typos, which was impossible in the `serde_json::Value`
+representation. And the Rust compiler can check that when we write
+`p.phones[0]`, then `p.phones` is guaranteed to be a `Vec<String>` so indexing
+into it makes sense and produces a `String`.
+
+The necessary setup for using Serde's derive macros is explained on the *[Using
+derive]* page of the Serde site.
+
+[Using derive]: https://serde.rs/derive.html
+
+## Constructing JSON values
+
+Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value`
+objects with very natural JSON syntax.
+
+<div align="right">
+<a href="https://play.rust-lang.org/?edition=2018&gist=6ccafad431d72b62e77cc34c8e879b24" target="_blank">
+<img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png">
+</a>
+</div>
+
+```rust
+use serde_json::json;
+
+fn main() {
+ // The type of `john` is `serde_json::Value`
+ let john = json!({
+ "name": "John Doe",
+ "age": 43,
+ "phones": [
+ "+44 1234567",
+ "+44 2345678"
+ ]
+ });
+
+ println!("first phone number: {}", john["phones"][0]);
+
+ // Convert to a string of JSON and print it out
+ println!("{}", john.to_string());
+}
+```
+
+The `Value::to_string()` function converts a `serde_json::Value` into a `String`
+of JSON text.
+
+One neat thing about the `json!` macro is that variables and expressions can be
+interpolated directly into the JSON value as you are building it. Serde will
+check at compile time that the value you are interpolating is able to be
+represented as JSON.
+
+<div align="right">
+<a href="https://play.rust-lang.org/?edition=2018&gist=f9101a6e61dfc9e02c6a67f315ed24f2" target="_blank">
+<img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png">
+</a>
+</div>
+
+```rust
+let full_name = "John Doe";
+let age_last_year = 42;
+
+// The type of `john` is `serde_json::Value`
+let john = json!({
+ "name": full_name,
+ "age": age_last_year + 1,
+ "phones": [
+ format!("+44 {}", random_phone())
+ ]
+});
+```
+
+This is amazingly convenient, but we have the problem we had before with
+`Value`: the IDE and Rust compiler cannot help us if we get it wrong. Serde JSON
+provides a better way of serializing strongly-typed data structures into JSON
+text.
+
+## Creating JSON by serializing data structures
+
+A data structure can be converted to a JSON string by
+[`serde_json::to_string`][to_string]. There is also
+[`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and
+[`serde_json::to_writer`][to_writer] which serializes to any `io::Write`
+such as a File or a TCP stream.
+
+<div align="right">
+<a href="https://play.rust-lang.org/?edition=2018&gist=3472242a08ed2ff88a944f2a2283b0ee" target="_blank">
+<img align="center" width="85" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/runtab.png">
+</a>
+</div>
+
+```rust
+use serde::{Deserialize, Serialize};
+use serde_json::Result;
+
+#[derive(Serialize, Deserialize)]
+struct Address {
+ street: String,
+ city: String,
+}
+
+fn print_an_address() -> Result<()> {
+ // Some data structure.
+ let address = Address {
+ street: "10 Downing Street".to_owned(),
+ city: "London".to_owned(),
+ };
+
+ // Serialize it to a JSON string.
+ let j = serde_json::to_string(&address)?;
+
+ // Print, write to a file, or send to an HTTP server.
+ println!("{}", j);
+
+ Ok(())
+}
+```
+
+Any type that implements Serde's `Serialize` trait can be serialized this way.
+This includes built-in Rust standard library types like `Vec<T>` and `HashMap<K,
+V>`, as well as any structs or enums annotated with `#[derive(Serialize)]`.
+
+## Performance
+
+It is fast. You should expect in the ballpark of 500 to 1000 megabytes per
+second deserialization and 600 to 900 megabytes per second serialization,
+depending on the characteristics of your data. This is competitive with the
+fastest C and C++ JSON libraries or even 30% faster for many use cases.
+Benchmarks live in the [serde-rs/json-benchmark] repo.
+
+[serde-rs/json-benchmark]: https://github.com/serde-rs/json-benchmark
+
+## Getting help
+
+Serde is one of the most widely used Rust libraries, so any place that
+Rustaceans congregate will be able to help you out. For chat, consider trying
+the [#rust-questions] or [#rust-beginners] channels of the unofficial community
+Discord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or
+[#beginners] channels of the official Rust Project Discord (invite:
+<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
+asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
+[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
+[Discourse forum][discourse]. It's acceptable to file a support issue in this
+repo, but they tend not to get as many eyes as any of the above and may get
+closed without a response after some time.
+
+[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
+[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
+[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
+[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
+[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
+[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
+[/r/rust]: https://www.reddit.com/r/rust
+[discourse]: https://users.rust-lang.org
+
+## No-std support
+
+As long as there is a memory allocator, it is possible to use serde_json without
+the rest of the Rust standard library. Disable the default "std" feature and
+enable the "alloc" feature:
+
+```toml
+[dependencies]
+serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
+```
+
+For JSON support in Serde without a memory allocator, please see the
+[`serde-json-core`] crate.
+
+[`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core
+
+[value]: https://docs.rs/serde_json/1/serde_json/value/enum.Value.html
+[from_str]: https://docs.rs/serde_json/1/serde_json/de/fn.from_str.html
+[from_slice]: https://docs.rs/serde_json/1/serde_json/de/fn.from_slice.html
+[from_reader]: https://docs.rs/serde_json/1/serde_json/de/fn.from_reader.html
+[to_string]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_string.html
+[to_vec]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_vec.html
+[to_writer]: https://docs.rs/serde_json/1/serde_json/ser/fn.to_writer.html
+[macro]: https://docs.rs/serde_json/1/serde_json/macro.json.html
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
+be dual licensed as above, without any additional terms or conditions.
+</sub>
diff --git a/third_party/rust/serde_json/build.rs b/third_party/rust/serde_json/build.rs
new file mode 100644
index 0000000000..0e12602e46
--- /dev/null
+++ b/third_party/rust/serde_json/build.rs
@@ -0,0 +1,54 @@
+use std::env;
+use std::process::Command;
+use std::str::{self, FromStr};
+
+fn main() {
+ println!("cargo:rerun-if-changed=build.rs");
+
+ // Decide ideal limb width for arithmetic in the float parser. Refer to
+ // src/lexical/math.rs for where this has an effect.
+ let target_arch = env::var("CARGO_CFG_TARGET_ARCH").unwrap();
+ match target_arch.as_str() {
+ "aarch64" | "mips64" | "powerpc64" | "x86_64" => {
+ println!("cargo:rustc-cfg=limb_width_64");
+ }
+ _ => {
+ println!("cargo:rustc-cfg=limb_width_32");
+ }
+ }
+
+ let minor = match rustc_minor_version() {
+ Some(minor) => minor,
+ None => return,
+ };
+
+ // BTreeMap::get_key_value
+ // https://blog.rust-lang.org/2019/12/19/Rust-1.40.0.html#additions-to-the-standard-library
+ if minor < 40 {
+ println!("cargo:rustc-cfg=no_btreemap_get_key_value");
+ }
+
+ // BTreeMap::remove_entry
+ // https://blog.rust-lang.org/2020/07/16/Rust-1.45.0.html#library-changes
+ if minor < 45 {
+ println!("cargo:rustc-cfg=no_btreemap_remove_entry");
+ }
+
+ // BTreeMap::retain
+ // https://blog.rust-lang.org/2021/06/17/Rust-1.53.0.html#stabilized-apis
+ if minor < 53 {
+ println!("cargo:rustc-cfg=no_btreemap_retain");
+ }
+}
+
+fn rustc_minor_version() -> Option<u32> {
+ let rustc = env::var_os("RUSTC")?;
+ let output = Command::new(rustc).arg("--version").output().ok()?;
+ let version = str::from_utf8(&output.stdout).ok()?;
+ let mut pieces = version.split('.');
+ if pieces.next() != Some("rustc 1") {
+ return None;
+ }
+ let next = pieces.next()?;
+ u32::from_str(next).ok()
+}
diff --git a/third_party/rust/serde_json/src/de.rs b/third_party/rust/serde_json/src/de.rs
new file mode 100644
index 0000000000..88d0f2624d
--- /dev/null
+++ b/third_party/rust/serde_json/src/de.rs
@@ -0,0 +1,2606 @@
+//! Deserialize JSON data to a Rust data structure.
+
+use crate::error::{Error, ErrorCode, Result};
+#[cfg(feature = "float_roundtrip")]
+use crate::lexical;
+use crate::number::Number;
+use crate::read::{self, Fused, Reference};
+use alloc::string::String;
+use alloc::vec::Vec;
+#[cfg(feature = "float_roundtrip")]
+use core::iter;
+use core::iter::FusedIterator;
+use core::marker::PhantomData;
+use core::result;
+use core::str::FromStr;
+use serde::de::{self, Expected, Unexpected};
+use serde::forward_to_deserialize_any;
+
+#[cfg(feature = "arbitrary_precision")]
+use crate::number::NumberDeserializer;
+
+pub use crate::read::{Read, SliceRead, StrRead};
+
+#[cfg(feature = "std")]
+pub use crate::read::IoRead;
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// A structure that deserializes JSON into Rust values.
+pub struct Deserializer<R> {
+ read: R,
+ scratch: Vec<u8>,
+ remaining_depth: u8,
+ #[cfg(feature = "float_roundtrip")]
+ single_precision: bool,
+ #[cfg(feature = "unbounded_depth")]
+ disable_recursion_limit: bool,
+}
+
+impl<'de, R> Deserializer<R>
+where
+ R: read::Read<'de>,
+{
+ /// Create a JSON deserializer from one of the possible serde_json input
+ /// sources.
+ ///
+ /// Typically it is more convenient to use one of these methods instead:
+ ///
+ /// - Deserializer::from_str
+ /// - Deserializer::from_slice
+ /// - Deserializer::from_reader
+ pub fn new(read: R) -> Self {
+ Deserializer {
+ read,
+ scratch: Vec::new(),
+ remaining_depth: 128,
+ #[cfg(feature = "float_roundtrip")]
+ single_precision: false,
+ #[cfg(feature = "unbounded_depth")]
+ disable_recursion_limit: false,
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<R> Deserializer<read::IoRead<R>>
+where
+ R: crate::io::Read,
+{
+ /// Creates a JSON deserializer from an `io::Read`.
+ ///
+ /// Reader-based deserializers do not support deserializing borrowed types
+ /// like `&str`, since the `std::io::Read` trait has no non-copying methods
+ /// -- everything it does involves copying bytes out of the data source.
+ pub fn from_reader(reader: R) -> Self {
+ Deserializer::new(read::IoRead::new(reader))
+ }
+}
+
+impl<'a> Deserializer<read::SliceRead<'a>> {
+ /// Creates a JSON deserializer from a `&[u8]`.
+ pub fn from_slice(bytes: &'a [u8]) -> Self {
+ Deserializer::new(read::SliceRead::new(bytes))
+ }
+}
+
+impl<'a> Deserializer<read::StrRead<'a>> {
+ /// Creates a JSON deserializer from a `&str`.
+ pub fn from_str(s: &'a str) -> Self {
+ Deserializer::new(read::StrRead::new(s))
+ }
+}
+
+macro_rules! overflow {
+ ($a:ident * 10 + $b:ident, $c:expr) => {
+ match $c {
+ c => $a >= c / 10 && ($a > c / 10 || $b > c % 10),
+ }
+ };
+}
+
+pub(crate) enum ParserNumber {
+ F64(f64),
+ U64(u64),
+ I64(i64),
+ #[cfg(feature = "arbitrary_precision")]
+ String(String),
+}
+
+impl ParserNumber {
+ fn visit<'de, V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self {
+ ParserNumber::F64(x) => visitor.visit_f64(x),
+ ParserNumber::U64(x) => visitor.visit_u64(x),
+ ParserNumber::I64(x) => visitor.visit_i64(x),
+ #[cfg(feature = "arbitrary_precision")]
+ ParserNumber::String(x) => visitor.visit_map(NumberDeserializer { number: x.into() }),
+ }
+ }
+
+ fn invalid_type(self, exp: &dyn Expected) -> Error {
+ match self {
+ ParserNumber::F64(x) => de::Error::invalid_type(Unexpected::Float(x), exp),
+ ParserNumber::U64(x) => de::Error::invalid_type(Unexpected::Unsigned(x), exp),
+ ParserNumber::I64(x) => de::Error::invalid_type(Unexpected::Signed(x), exp),
+ #[cfg(feature = "arbitrary_precision")]
+ ParserNumber::String(_) => de::Error::invalid_type(Unexpected::Other("number"), exp),
+ }
+ }
+}
+
+impl<'de, R: Read<'de>> Deserializer<R> {
+ /// The `Deserializer::end` method should be called after a value has been fully deserialized.
+ /// This allows the `Deserializer` to validate that the input stream is at the end or that it
+ /// only has trailing whitespace.
+ pub fn end(&mut self) -> Result<()> {
+ match tri!(self.parse_whitespace()) {
+ Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
+ None => Ok(()),
+ }
+ }
+
+ /// Turn a JSON deserializer into an iterator over values of type T.
+ pub fn into_iter<T>(self) -> StreamDeserializer<'de, R, T>
+ where
+ T: de::Deserialize<'de>,
+ {
+ // This cannot be an implementation of std::iter::IntoIterator because
+ // we need the caller to choose what T is.
+ let offset = self.read.byte_offset();
+ StreamDeserializer {
+ de: self,
+ offset,
+ failed: false,
+ output: PhantomData,
+ lifetime: PhantomData,
+ }
+ }
+
+ /// Parse arbitrarily deep JSON structures without any consideration for
+ /// overflowing the stack.
+ ///
+ /// You will want to provide some other way to protect against stack
+ /// overflows, such as by wrapping your Deserializer in the dynamically
+ /// growing stack adapter provided by the serde_stacker crate. Additionally
+ /// you will need to be careful around other recursive operations on the
+ /// parsed result which may overflow the stack after deserialization has
+ /// completed, including, but not limited to, Display and Debug and Drop
+ /// impls.
+ ///
+ /// *This method is only available if serde_json is built with the
+ /// `"unbounded_depth"` feature.*
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde::Deserialize;
+ /// use serde_json::Value;
+ ///
+ /// fn main() {
+ /// let mut json = String::new();
+ /// for _ in 0..10000 {
+ /// json = format!("[{}]", json);
+ /// }
+ ///
+ /// let mut deserializer = serde_json::Deserializer::from_str(&json);
+ /// deserializer.disable_recursion_limit();
+ /// let deserializer = serde_stacker::Deserializer::new(&mut deserializer);
+ /// let value = Value::deserialize(deserializer).unwrap();
+ ///
+ /// carefully_drop_nested_arrays(value);
+ /// }
+ ///
+ /// fn carefully_drop_nested_arrays(value: Value) {
+ /// let mut stack = vec![value];
+ /// while let Some(value) = stack.pop() {
+ /// if let Value::Array(array) = value {
+ /// stack.extend(array);
+ /// }
+ /// }
+ /// }
+ /// ```
+ #[cfg(feature = "unbounded_depth")]
+ #[cfg_attr(docsrs, doc(cfg(feature = "unbounded_depth")))]
+ pub fn disable_recursion_limit(&mut self) {
+ self.disable_recursion_limit = true;
+ }
+
+ fn peek(&mut self) -> Result<Option<u8>> {
+ self.read.peek()
+ }
+
+ fn peek_or_null(&mut self) -> Result<u8> {
+ Ok(tri!(self.peek()).unwrap_or(b'\x00'))
+ }
+
+ fn eat_char(&mut self) {
+ self.read.discard();
+ }
+
+ fn next_char(&mut self) -> Result<Option<u8>> {
+ self.read.next()
+ }
+
+ fn next_char_or_null(&mut self) -> Result<u8> {
+ Ok(tri!(self.next_char()).unwrap_or(b'\x00'))
+ }
+
+ /// Error caused by a byte from next_char().
+ #[cold]
+ fn error(&self, reason: ErrorCode) -> Error {
+ let position = self.read.position();
+ Error::syntax(reason, position.line, position.column)
+ }
+
+ /// Error caused by a byte from peek().
+ #[cold]
+ fn peek_error(&self, reason: ErrorCode) -> Error {
+ let position = self.read.peek_position();
+ Error::syntax(reason, position.line, position.column)
+ }
+
+ /// Returns the first non-whitespace byte without consuming it, or `None` if
+ /// EOF is encountered.
+ fn parse_whitespace(&mut self) -> Result<Option<u8>> {
+ loop {
+ match tri!(self.peek()) {
+ Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') => {
+ self.eat_char();
+ }
+ other => {
+ return Ok(other);
+ }
+ }
+ }
+ }
+
+ #[cold]
+ fn peek_invalid_type(&mut self, exp: &dyn Expected) -> Error {
+ let err = match self.peek_or_null().unwrap_or(b'\x00') {
+ b'n' => {
+ self.eat_char();
+ if let Err(err) = self.parse_ident(b"ull") {
+ return err;
+ }
+ de::Error::invalid_type(Unexpected::Unit, exp)
+ }
+ b't' => {
+ self.eat_char();
+ if let Err(err) = self.parse_ident(b"rue") {
+ return err;
+ }
+ de::Error::invalid_type(Unexpected::Bool(true), exp)
+ }
+ b'f' => {
+ self.eat_char();
+ if let Err(err) = self.parse_ident(b"alse") {
+ return err;
+ }
+ de::Error::invalid_type(Unexpected::Bool(false), exp)
+ }
+ b'-' => {
+ self.eat_char();
+ match self.parse_any_number(false) {
+ Ok(n) => n.invalid_type(exp),
+ Err(err) => return err,
+ }
+ }
+ b'0'..=b'9' => match self.parse_any_number(true) {
+ Ok(n) => n.invalid_type(exp),
+ Err(err) => return err,
+ },
+ b'"' => {
+ self.eat_char();
+ self.scratch.clear();
+ match self.read.parse_str(&mut self.scratch) {
+ Ok(s) => de::Error::invalid_type(Unexpected::Str(&s), exp),
+ Err(err) => return err,
+ }
+ }
+ b'[' => de::Error::invalid_type(Unexpected::Seq, exp),
+ b'{' => de::Error::invalid_type(Unexpected::Map, exp),
+ _ => self.peek_error(ErrorCode::ExpectedSomeValue),
+ };
+
+ self.fix_position(err)
+ }
+
+ fn deserialize_number<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let peek = match tri!(self.parse_whitespace()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let value = match peek {
+ b'-' => {
+ self.eat_char();
+ tri!(self.parse_integer(false)).visit(visitor)
+ }
+ b'0'..=b'9' => tri!(self.parse_integer(true)).visit(visitor),
+ _ => Err(self.peek_invalid_type(&visitor)),
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ fn scan_integer128(&mut self, buf: &mut String) -> Result<()> {
+ match tri!(self.next_char_or_null()) {
+ b'0' => {
+ buf.push('0');
+ // There can be only one leading '0'.
+ match tri!(self.peek_or_null()) {
+ b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)),
+ _ => Ok(()),
+ }
+ }
+ c @ b'1'..=b'9' => {
+ buf.push(c as char);
+ while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
+ buf.push(c as char);
+ }
+ Ok(())
+ }
+ _ => Err(self.error(ErrorCode::InvalidNumber)),
+ }
+ }
+
+ #[cold]
+ fn fix_position(&self, err: Error) -> Error {
+ err.fix_position(move |code| self.error(code))
+ }
+
+ fn parse_ident(&mut self, ident: &[u8]) -> Result<()> {
+ for expected in ident {
+ match tri!(self.next_char()) {
+ None => {
+ return Err(self.error(ErrorCode::EofWhileParsingValue));
+ }
+ Some(next) => {
+ if next != *expected {
+ return Err(self.error(ErrorCode::ExpectedSomeIdent));
+ }
+ }
+ }
+ }
+
+ Ok(())
+ }
+
+ fn parse_integer(&mut self, positive: bool) -> Result<ParserNumber> {
+ let next = match tri!(self.next_char()) {
+ Some(b) => b,
+ None => {
+ return Err(self.error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ match next {
+ b'0' => {
+ // There can be only one leading '0'.
+ match tri!(self.peek_or_null()) {
+ b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)),
+ _ => self.parse_number(positive, 0),
+ }
+ }
+ c @ b'1'..=b'9' => {
+ let mut significand = (c - b'0') as u64;
+
+ loop {
+ match tri!(self.peek_or_null()) {
+ c @ b'0'..=b'9' => {
+ let digit = (c - b'0') as u64;
+
+ // We need to be careful with overflow. If we can,
+ // try to keep the number as a `u64` until we grow
+ // too large. At that point, switch to parsing the
+ // value as a `f64`.
+ if overflow!(significand * 10 + digit, u64::max_value()) {
+ return Ok(ParserNumber::F64(tri!(
+ self.parse_long_integer(positive, significand),
+ )));
+ }
+
+ self.eat_char();
+ significand = significand * 10 + digit;
+ }
+ _ => {
+ return self.parse_number(positive, significand);
+ }
+ }
+ }
+ }
+ _ => Err(self.error(ErrorCode::InvalidNumber)),
+ }
+ }
+
+ fn parse_number(&mut self, positive: bool, significand: u64) -> Result<ParserNumber> {
+ Ok(match tri!(self.peek_or_null()) {
+ b'.' => ParserNumber::F64(tri!(self.parse_decimal(positive, significand, 0))),
+ b'e' | b'E' => ParserNumber::F64(tri!(self.parse_exponent(positive, significand, 0))),
+ _ => {
+ if positive {
+ ParserNumber::U64(significand)
+ } else {
+ let neg = (significand as i64).wrapping_neg();
+
+ // Convert into a float if we underflow, or on `-0`.
+ if neg >= 0 {
+ ParserNumber::F64(-(significand as f64))
+ } else {
+ ParserNumber::I64(neg)
+ }
+ }
+ }
+ })
+ }
+
+ fn parse_decimal(
+ &mut self,
+ positive: bool,
+ mut significand: u64,
+ exponent_before_decimal_point: i32,
+ ) -> Result<f64> {
+ self.eat_char();
+
+ let mut exponent_after_decimal_point = 0;
+ while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
+ let digit = (c - b'0') as u64;
+
+ if overflow!(significand * 10 + digit, u64::max_value()) {
+ let exponent = exponent_before_decimal_point + exponent_after_decimal_point;
+ return self.parse_decimal_overflow(positive, significand, exponent);
+ }
+
+ self.eat_char();
+ significand = significand * 10 + digit;
+ exponent_after_decimal_point -= 1;
+ }
+
+ // Error if there is not at least one digit after the decimal point.
+ if exponent_after_decimal_point == 0 {
+ match tri!(self.peek()) {
+ Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)),
+ None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
+ }
+ }
+
+ let exponent = exponent_before_decimal_point + exponent_after_decimal_point;
+ match tri!(self.peek_or_null()) {
+ b'e' | b'E' => self.parse_exponent(positive, significand, exponent),
+ _ => self.f64_from_parts(positive, significand, exponent),
+ }
+ }
+
+ fn parse_exponent(
+ &mut self,
+ positive: bool,
+ significand: u64,
+ starting_exp: i32,
+ ) -> Result<f64> {
+ self.eat_char();
+
+ let positive_exp = match tri!(self.peek_or_null()) {
+ b'+' => {
+ self.eat_char();
+ true
+ }
+ b'-' => {
+ self.eat_char();
+ false
+ }
+ _ => true,
+ };
+
+ let next = match tri!(self.next_char()) {
+ Some(b) => b,
+ None => {
+ return Err(self.error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ // Make sure a digit follows the exponent place.
+ let mut exp = match next {
+ c @ b'0'..=b'9' => (c - b'0') as i32,
+ _ => {
+ return Err(self.error(ErrorCode::InvalidNumber));
+ }
+ };
+
+ while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
+ let digit = (c - b'0') as i32;
+
+ if overflow!(exp * 10 + digit, i32::max_value()) {
+ let zero_significand = significand == 0;
+ return self.parse_exponent_overflow(positive, zero_significand, positive_exp);
+ }
+
+ exp = exp * 10 + digit;
+ }
+
+ let final_exp = if positive_exp {
+ starting_exp.saturating_add(exp)
+ } else {
+ starting_exp.saturating_sub(exp)
+ };
+
+ self.f64_from_parts(positive, significand, final_exp)
+ }
+
+ #[cfg(feature = "float_roundtrip")]
+ fn f64_from_parts(&mut self, positive: bool, significand: u64, exponent: i32) -> Result<f64> {
+ let f = if self.single_precision {
+ lexical::parse_concise_float::<f32>(significand, exponent) as f64
+ } else {
+ lexical::parse_concise_float::<f64>(significand, exponent)
+ };
+
+ if f.is_infinite() {
+ Err(self.error(ErrorCode::NumberOutOfRange))
+ } else {
+ Ok(if positive { f } else { -f })
+ }
+ }
+
+ #[cfg(not(feature = "float_roundtrip"))]
+ fn f64_from_parts(
+ &mut self,
+ positive: bool,
+ significand: u64,
+ mut exponent: i32,
+ ) -> Result<f64> {
+ let mut f = significand as f64;
+ loop {
+ match POW10.get(exponent.wrapping_abs() as usize) {
+ Some(&pow) => {
+ if exponent >= 0 {
+ f *= pow;
+ if f.is_infinite() {
+ return Err(self.error(ErrorCode::NumberOutOfRange));
+ }
+ } else {
+ f /= pow;
+ }
+ break;
+ }
+ None => {
+ if f == 0.0 {
+ break;
+ }
+ if exponent >= 0 {
+ return Err(self.error(ErrorCode::NumberOutOfRange));
+ }
+ f /= 1e308;
+ exponent += 308;
+ }
+ }
+ }
+ Ok(if positive { f } else { -f })
+ }
+
+ #[cfg(feature = "float_roundtrip")]
+ #[cold]
+ #[inline(never)]
+ fn parse_long_integer(&mut self, positive: bool, partial_significand: u64) -> Result<f64> {
+ // To deserialize floats we'll first push the integer and fraction
+ // parts, both as byte strings, into the scratch buffer and then feed
+ // both slices to lexical's parser. For example if the input is
+ // `12.34e5` we'll push b"1234" into scratch and then pass b"12" and
+ // b"34" to lexical. `integer_end` will be used to track where to split
+ // the scratch buffer.
+ //
+ // Note that lexical expects the integer part to contain *no* leading
+ // zeroes and the fraction part to contain *no* trailing zeroes. The
+ // first requirement is already handled by the integer parsing logic.
+ // The second requirement will be enforced just before passing the
+ // slices to lexical in f64_long_from_parts.
+ self.scratch.clear();
+ self.scratch
+ .extend_from_slice(itoa::Buffer::new().format(partial_significand).as_bytes());
+
+ loop {
+ match tri!(self.peek_or_null()) {
+ c @ b'0'..=b'9' => {
+ self.scratch.push(c);
+ self.eat_char();
+ }
+ b'.' => {
+ self.eat_char();
+ return self.parse_long_decimal(positive, self.scratch.len());
+ }
+ b'e' | b'E' => {
+ return self.parse_long_exponent(positive, self.scratch.len());
+ }
+ _ => {
+ return self.f64_long_from_parts(positive, self.scratch.len(), 0);
+ }
+ }
+ }
+ }
+
+ #[cfg(not(feature = "float_roundtrip"))]
+ #[cold]
+ #[inline(never)]
+ fn parse_long_integer(&mut self, positive: bool, significand: u64) -> Result<f64> {
+ let mut exponent = 0;
+ loop {
+ match tri!(self.peek_or_null()) {
+ b'0'..=b'9' => {
+ self.eat_char();
+ // This could overflow... if your integer is gigabytes long.
+ // Ignore that possibility.
+ exponent += 1;
+ }
+ b'.' => {
+ return self.parse_decimal(positive, significand, exponent);
+ }
+ b'e' | b'E' => {
+ return self.parse_exponent(positive, significand, exponent);
+ }
+ _ => {
+ return self.f64_from_parts(positive, significand, exponent);
+ }
+ }
+ }
+ }
+
+ #[cfg(feature = "float_roundtrip")]
+ #[cold]
+ fn parse_long_decimal(&mut self, positive: bool, integer_end: usize) -> Result<f64> {
+ let mut at_least_one_digit = integer_end < self.scratch.len();
+ while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.scratch.push(c);
+ self.eat_char();
+ at_least_one_digit = true;
+ }
+
+ if !at_least_one_digit {
+ match tri!(self.peek()) {
+ Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)),
+ None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
+ }
+ }
+
+ match tri!(self.peek_or_null()) {
+ b'e' | b'E' => self.parse_long_exponent(positive, integer_end),
+ _ => self.f64_long_from_parts(positive, integer_end, 0),
+ }
+ }
+
+ #[cfg(feature = "float_roundtrip")]
+ fn parse_long_exponent(&mut self, positive: bool, integer_end: usize) -> Result<f64> {
+ self.eat_char();
+
+ let positive_exp = match tri!(self.peek_or_null()) {
+ b'+' => {
+ self.eat_char();
+ true
+ }
+ b'-' => {
+ self.eat_char();
+ false
+ }
+ _ => true,
+ };
+
+ let next = match tri!(self.next_char()) {
+ Some(b) => b,
+ None => {
+ return Err(self.error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ // Make sure a digit follows the exponent place.
+ let mut exp = match next {
+ c @ b'0'..=b'9' => (c - b'0') as i32,
+ _ => {
+ return Err(self.error(ErrorCode::InvalidNumber));
+ }
+ };
+
+ while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
+ let digit = (c - b'0') as i32;
+
+ if overflow!(exp * 10 + digit, i32::max_value()) {
+ let zero_significand = self.scratch.iter().all(|&digit| digit == b'0');
+ return self.parse_exponent_overflow(positive, zero_significand, positive_exp);
+ }
+
+ exp = exp * 10 + digit;
+ }
+
+ let final_exp = if positive_exp { exp } else { -exp };
+
+ self.f64_long_from_parts(positive, integer_end, final_exp)
+ }
+
+ // This cold code should not be inlined into the middle of the hot
+ // decimal-parsing loop above.
+ #[cfg(feature = "float_roundtrip")]
+ #[cold]
+ #[inline(never)]
+ fn parse_decimal_overflow(
+ &mut self,
+ positive: bool,
+ significand: u64,
+ exponent: i32,
+ ) -> Result<f64> {
+ let mut buffer = itoa::Buffer::new();
+ let significand = buffer.format(significand);
+ let fraction_digits = -exponent as usize;
+ self.scratch.clear();
+ if let Some(zeros) = fraction_digits.checked_sub(significand.len() + 1) {
+ self.scratch.extend(iter::repeat(b'0').take(zeros + 1));
+ }
+ self.scratch.extend_from_slice(significand.as_bytes());
+ let integer_end = self.scratch.len() - fraction_digits;
+ self.parse_long_decimal(positive, integer_end)
+ }
+
+ #[cfg(not(feature = "float_roundtrip"))]
+ #[cold]
+ #[inline(never)]
+ fn parse_decimal_overflow(
+ &mut self,
+ positive: bool,
+ significand: u64,
+ exponent: i32,
+ ) -> Result<f64> {
+ // The next multiply/add would overflow, so just ignore all further
+ // digits.
+ while let b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
+ }
+
+ match tri!(self.peek_or_null()) {
+ b'e' | b'E' => self.parse_exponent(positive, significand, exponent),
+ _ => self.f64_from_parts(positive, significand, exponent),
+ }
+ }
+
+ // This cold code should not be inlined into the middle of the hot
+ // exponent-parsing loop above.
+ #[cold]
+ #[inline(never)]
+ fn parse_exponent_overflow(
+ &mut self,
+ positive: bool,
+ zero_significand: bool,
+ positive_exp: bool,
+ ) -> Result<f64> {
+ // Error instead of +/- infinity.
+ if !zero_significand && positive_exp {
+ return Err(self.error(ErrorCode::NumberOutOfRange));
+ }
+
+ while let b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
+ }
+ Ok(if positive { 0.0 } else { -0.0 })
+ }
+
+ #[cfg(feature = "float_roundtrip")]
+ fn f64_long_from_parts(
+ &mut self,
+ positive: bool,
+ integer_end: usize,
+ exponent: i32,
+ ) -> Result<f64> {
+ let integer = &self.scratch[..integer_end];
+ let fraction = &self.scratch[integer_end..];
+
+ let f = if self.single_precision {
+ lexical::parse_truncated_float::<f32>(integer, fraction, exponent) as f64
+ } else {
+ lexical::parse_truncated_float::<f64>(integer, fraction, exponent)
+ };
+
+ if f.is_infinite() {
+ Err(self.error(ErrorCode::NumberOutOfRange))
+ } else {
+ Ok(if positive { f } else { -f })
+ }
+ }
+
+ fn parse_any_signed_number(&mut self) -> Result<ParserNumber> {
+ let peek = match tri!(self.peek()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let value = match peek {
+ b'-' => {
+ self.eat_char();
+ self.parse_any_number(false)
+ }
+ b'0'..=b'9' => self.parse_any_number(true),
+ _ => Err(self.peek_error(ErrorCode::InvalidNumber)),
+ };
+
+ let value = match tri!(self.peek()) {
+ Some(_) => Err(self.peek_error(ErrorCode::InvalidNumber)),
+ None => value,
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ // The de::Error impl creates errors with unknown line and column.
+ // Fill in the position here by looking at the current index in the
+ // input. There is no way to tell whether this should call `error`
+ // or `peek_error` so pick the one that seems correct more often.
+ // Worst case, the position is off by one character.
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ #[cfg(not(feature = "arbitrary_precision"))]
+ fn parse_any_number(&mut self, positive: bool) -> Result<ParserNumber> {
+ self.parse_integer(positive)
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ fn parse_any_number(&mut self, positive: bool) -> Result<ParserNumber> {
+ let mut buf = String::with_capacity(16);
+ if !positive {
+ buf.push('-');
+ }
+ self.scan_integer(&mut buf)?;
+ if positive {
+ if let Ok(unsigned) = buf.parse() {
+ return Ok(ParserNumber::U64(unsigned));
+ }
+ } else {
+ if let Ok(signed) = buf.parse() {
+ return Ok(ParserNumber::I64(signed));
+ }
+ }
+ Ok(ParserNumber::String(buf))
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ fn scan_or_eof(&mut self, buf: &mut String) -> Result<u8> {
+ match tri!(self.next_char()) {
+ Some(b) => {
+ buf.push(b as char);
+ Ok(b)
+ }
+ None => Err(self.error(ErrorCode::EofWhileParsingValue)),
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ fn scan_integer(&mut self, buf: &mut String) -> Result<()> {
+ match tri!(self.scan_or_eof(buf)) {
+ b'0' => {
+ // There can be only one leading '0'.
+ match tri!(self.peek_or_null()) {
+ b'0'..=b'9' => Err(self.peek_error(ErrorCode::InvalidNumber)),
+ _ => self.scan_number(buf),
+ }
+ }
+ b'1'..=b'9' => loop {
+ match tri!(self.peek_or_null()) {
+ c @ b'0'..=b'9' => {
+ self.eat_char();
+ buf.push(c as char);
+ }
+ _ => {
+ return self.scan_number(buf);
+ }
+ }
+ },
+ _ => Err(self.error(ErrorCode::InvalidNumber)),
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ fn scan_number(&mut self, buf: &mut String) -> Result<()> {
+ match tri!(self.peek_or_null()) {
+ b'.' => self.scan_decimal(buf),
+ e @ b'e' | e @ b'E' => self.scan_exponent(e as char, buf),
+ _ => Ok(()),
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ fn scan_decimal(&mut self, buf: &mut String) -> Result<()> {
+ self.eat_char();
+ buf.push('.');
+
+ let mut at_least_one_digit = false;
+ while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
+ buf.push(c as char);
+ at_least_one_digit = true;
+ }
+
+ if !at_least_one_digit {
+ match tri!(self.peek()) {
+ Some(_) => return Err(self.peek_error(ErrorCode::InvalidNumber)),
+ None => return Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
+ }
+ }
+
+ match tri!(self.peek_or_null()) {
+ e @ b'e' | e @ b'E' => self.scan_exponent(e as char, buf),
+ _ => Ok(()),
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ fn scan_exponent(&mut self, e: char, buf: &mut String) -> Result<()> {
+ self.eat_char();
+ buf.push(e);
+
+ match tri!(self.peek_or_null()) {
+ b'+' => {
+ self.eat_char();
+ buf.push('+');
+ }
+ b'-' => {
+ self.eat_char();
+ buf.push('-');
+ }
+ _ => {}
+ }
+
+ // Make sure a digit follows the exponent place.
+ match tri!(self.scan_or_eof(buf)) {
+ b'0'..=b'9' => {}
+ _ => {
+ return Err(self.error(ErrorCode::InvalidNumber));
+ }
+ }
+
+ while let c @ b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
+ buf.push(c as char);
+ }
+
+ Ok(())
+ }
+
+ fn parse_object_colon(&mut self) -> Result<()> {
+ match tri!(self.parse_whitespace()) {
+ Some(b':') => {
+ self.eat_char();
+ Ok(())
+ }
+ Some(_) => Err(self.peek_error(ErrorCode::ExpectedColon)),
+ None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
+ }
+ }
+
+ fn end_seq(&mut self) -> Result<()> {
+ match tri!(self.parse_whitespace()) {
+ Some(b']') => {
+ self.eat_char();
+ Ok(())
+ }
+ Some(b',') => {
+ self.eat_char();
+ match self.parse_whitespace() {
+ Ok(Some(b']')) => Err(self.peek_error(ErrorCode::TrailingComma)),
+ _ => Err(self.peek_error(ErrorCode::TrailingCharacters)),
+ }
+ }
+ Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
+ None => Err(self.peek_error(ErrorCode::EofWhileParsingList)),
+ }
+ }
+
+ fn end_map(&mut self) -> Result<()> {
+ match tri!(self.parse_whitespace()) {
+ Some(b'}') => {
+ self.eat_char();
+ Ok(())
+ }
+ Some(b',') => Err(self.peek_error(ErrorCode::TrailingComma)),
+ Some(_) => Err(self.peek_error(ErrorCode::TrailingCharacters)),
+ None => Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
+ }
+ }
+
+ fn ignore_value(&mut self) -> Result<()> {
+ self.scratch.clear();
+ let mut enclosing = None;
+
+ loop {
+ let peek = match tri!(self.parse_whitespace()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let frame = match peek {
+ b'n' => {
+ self.eat_char();
+ tri!(self.parse_ident(b"ull"));
+ None
+ }
+ b't' => {
+ self.eat_char();
+ tri!(self.parse_ident(b"rue"));
+ None
+ }
+ b'f' => {
+ self.eat_char();
+ tri!(self.parse_ident(b"alse"));
+ None
+ }
+ b'-' => {
+ self.eat_char();
+ tri!(self.ignore_integer());
+ None
+ }
+ b'0'..=b'9' => {
+ tri!(self.ignore_integer());
+ None
+ }
+ b'"' => {
+ self.eat_char();
+ tri!(self.read.ignore_str());
+ None
+ }
+ frame @ b'[' | frame @ b'{' => {
+ self.scratch.extend(enclosing.take());
+ self.eat_char();
+ Some(frame)
+ }
+ _ => return Err(self.peek_error(ErrorCode::ExpectedSomeValue)),
+ };
+
+ let (mut accept_comma, mut frame) = match frame {
+ Some(frame) => (false, frame),
+ None => match enclosing.take() {
+ Some(frame) => (true, frame),
+ None => match self.scratch.pop() {
+ Some(frame) => (true, frame),
+ None => return Ok(()),
+ },
+ },
+ };
+
+ loop {
+ match tri!(self.parse_whitespace()) {
+ Some(b',') if accept_comma => {
+ self.eat_char();
+ break;
+ }
+ Some(b']') if frame == b'[' => {}
+ Some(b'}') if frame == b'{' => {}
+ Some(_) => {
+ if accept_comma {
+ return Err(self.peek_error(match frame {
+ b'[' => ErrorCode::ExpectedListCommaOrEnd,
+ b'{' => ErrorCode::ExpectedObjectCommaOrEnd,
+ _ => unreachable!(),
+ }));
+ } else {
+ break;
+ }
+ }
+ None => {
+ return Err(self.peek_error(match frame {
+ b'[' => ErrorCode::EofWhileParsingList,
+ b'{' => ErrorCode::EofWhileParsingObject,
+ _ => unreachable!(),
+ }));
+ }
+ }
+
+ self.eat_char();
+ frame = match self.scratch.pop() {
+ Some(frame) => frame,
+ None => return Ok(()),
+ };
+ accept_comma = true;
+ }
+
+ if frame == b'{' {
+ match tri!(self.parse_whitespace()) {
+ Some(b'"') => self.eat_char(),
+ Some(_) => return Err(self.peek_error(ErrorCode::KeyMustBeAString)),
+ None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
+ }
+ tri!(self.read.ignore_str());
+ match tri!(self.parse_whitespace()) {
+ Some(b':') => self.eat_char(),
+ Some(_) => return Err(self.peek_error(ErrorCode::ExpectedColon)),
+ None => return Err(self.peek_error(ErrorCode::EofWhileParsingObject)),
+ }
+ }
+
+ enclosing = Some(frame);
+ }
+ }
+
+ fn ignore_integer(&mut self) -> Result<()> {
+ match tri!(self.next_char_or_null()) {
+ b'0' => {
+ // There can be only one leading '0'.
+ if let b'0'..=b'9' = tri!(self.peek_or_null()) {
+ return Err(self.peek_error(ErrorCode::InvalidNumber));
+ }
+ }
+ b'1'..=b'9' => {
+ while let b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
+ }
+ }
+ _ => {
+ return Err(self.error(ErrorCode::InvalidNumber));
+ }
+ }
+
+ match tri!(self.peek_or_null()) {
+ b'.' => self.ignore_decimal(),
+ b'e' | b'E' => self.ignore_exponent(),
+ _ => Ok(()),
+ }
+ }
+
+ fn ignore_decimal(&mut self) -> Result<()> {
+ self.eat_char();
+
+ let mut at_least_one_digit = false;
+ while let b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
+ at_least_one_digit = true;
+ }
+
+ if !at_least_one_digit {
+ return Err(self.peek_error(ErrorCode::InvalidNumber));
+ }
+
+ match tri!(self.peek_or_null()) {
+ b'e' | b'E' => self.ignore_exponent(),
+ _ => Ok(()),
+ }
+ }
+
+ fn ignore_exponent(&mut self) -> Result<()> {
+ self.eat_char();
+
+ match tri!(self.peek_or_null()) {
+ b'+' | b'-' => self.eat_char(),
+ _ => {}
+ }
+
+ // Make sure a digit follows the exponent place.
+ match tri!(self.next_char_or_null()) {
+ b'0'..=b'9' => {}
+ _ => {
+ return Err(self.error(ErrorCode::InvalidNumber));
+ }
+ }
+
+ while let b'0'..=b'9' = tri!(self.peek_or_null()) {
+ self.eat_char();
+ }
+
+ Ok(())
+ }
+
+ #[cfg(feature = "raw_value")]
+ fn deserialize_raw_value<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.parse_whitespace()?;
+ self.read.begin_raw_buffering();
+ self.ignore_value()?;
+ self.read.end_raw_buffering(visitor)
+ }
+}
+
+impl FromStr for Number {
+ type Err = Error;
+
+ fn from_str(s: &str) -> result::Result<Self, Self::Err> {
+ Deserializer::from_str(s)
+ .parse_any_signed_number()
+ .map(Into::into)
+ }
+}
+
+#[cfg(not(feature = "float_roundtrip"))]
+static POW10: [f64; 309] = [
+ 1e000, 1e001, 1e002, 1e003, 1e004, 1e005, 1e006, 1e007, 1e008, 1e009, //
+ 1e010, 1e011, 1e012, 1e013, 1e014, 1e015, 1e016, 1e017, 1e018, 1e019, //
+ 1e020, 1e021, 1e022, 1e023, 1e024, 1e025, 1e026, 1e027, 1e028, 1e029, //
+ 1e030, 1e031, 1e032, 1e033, 1e034, 1e035, 1e036, 1e037, 1e038, 1e039, //
+ 1e040, 1e041, 1e042, 1e043, 1e044, 1e045, 1e046, 1e047, 1e048, 1e049, //
+ 1e050, 1e051, 1e052, 1e053, 1e054, 1e055, 1e056, 1e057, 1e058, 1e059, //
+ 1e060, 1e061, 1e062, 1e063, 1e064, 1e065, 1e066, 1e067, 1e068, 1e069, //
+ 1e070, 1e071, 1e072, 1e073, 1e074, 1e075, 1e076, 1e077, 1e078, 1e079, //
+ 1e080, 1e081, 1e082, 1e083, 1e084, 1e085, 1e086, 1e087, 1e088, 1e089, //
+ 1e090, 1e091, 1e092, 1e093, 1e094, 1e095, 1e096, 1e097, 1e098, 1e099, //
+ 1e100, 1e101, 1e102, 1e103, 1e104, 1e105, 1e106, 1e107, 1e108, 1e109, //
+ 1e110, 1e111, 1e112, 1e113, 1e114, 1e115, 1e116, 1e117, 1e118, 1e119, //
+ 1e120, 1e121, 1e122, 1e123, 1e124, 1e125, 1e126, 1e127, 1e128, 1e129, //
+ 1e130, 1e131, 1e132, 1e133, 1e134, 1e135, 1e136, 1e137, 1e138, 1e139, //
+ 1e140, 1e141, 1e142, 1e143, 1e144, 1e145, 1e146, 1e147, 1e148, 1e149, //
+ 1e150, 1e151, 1e152, 1e153, 1e154, 1e155, 1e156, 1e157, 1e158, 1e159, //
+ 1e160, 1e161, 1e162, 1e163, 1e164, 1e165, 1e166, 1e167, 1e168, 1e169, //
+ 1e170, 1e171, 1e172, 1e173, 1e174, 1e175, 1e176, 1e177, 1e178, 1e179, //
+ 1e180, 1e181, 1e182, 1e183, 1e184, 1e185, 1e186, 1e187, 1e188, 1e189, //
+ 1e190, 1e191, 1e192, 1e193, 1e194, 1e195, 1e196, 1e197, 1e198, 1e199, //
+ 1e200, 1e201, 1e202, 1e203, 1e204, 1e205, 1e206, 1e207, 1e208, 1e209, //
+ 1e210, 1e211, 1e212, 1e213, 1e214, 1e215, 1e216, 1e217, 1e218, 1e219, //
+ 1e220, 1e221, 1e222, 1e223, 1e224, 1e225, 1e226, 1e227, 1e228, 1e229, //
+ 1e230, 1e231, 1e232, 1e233, 1e234, 1e235, 1e236, 1e237, 1e238, 1e239, //
+ 1e240, 1e241, 1e242, 1e243, 1e244, 1e245, 1e246, 1e247, 1e248, 1e249, //
+ 1e250, 1e251, 1e252, 1e253, 1e254, 1e255, 1e256, 1e257, 1e258, 1e259, //
+ 1e260, 1e261, 1e262, 1e263, 1e264, 1e265, 1e266, 1e267, 1e268, 1e269, //
+ 1e270, 1e271, 1e272, 1e273, 1e274, 1e275, 1e276, 1e277, 1e278, 1e279, //
+ 1e280, 1e281, 1e282, 1e283, 1e284, 1e285, 1e286, 1e287, 1e288, 1e289, //
+ 1e290, 1e291, 1e292, 1e293, 1e294, 1e295, 1e296, 1e297, 1e298, 1e299, //
+ 1e300, 1e301, 1e302, 1e303, 1e304, 1e305, 1e306, 1e307, 1e308,
+];
+
+macro_rules! deserialize_number {
+ ($method:ident) => {
+ fn $method<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+ };
+}
+
+#[cfg(not(feature = "unbounded_depth"))]
+macro_rules! if_checking_recursion_limit {
+ ($($body:tt)*) => {
+ $($body)*
+ };
+}
+
+#[cfg(feature = "unbounded_depth")]
+macro_rules! if_checking_recursion_limit {
+ ($this:ident $($body:tt)*) => {
+ if !$this.disable_recursion_limit {
+ $this $($body)*
+ }
+ };
+}
+
+macro_rules! check_recursion {
+ ($this:ident $($body:tt)*) => {
+ if_checking_recursion_limit! {
+ $this.remaining_depth -= 1;
+ if $this.remaining_depth == 0 {
+ return Err($this.peek_error(ErrorCode::RecursionLimitExceeded));
+ }
+ }
+
+ $this $($body)*
+
+ if_checking_recursion_limit! {
+ $this.remaining_depth += 1;
+ }
+ };
+}
+
+impl<'de, 'a, R: Read<'de>> de::Deserializer<'de> for &'a mut Deserializer<R> {
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let peek = match tri!(self.parse_whitespace()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let value = match peek {
+ b'n' => {
+ self.eat_char();
+ tri!(self.parse_ident(b"ull"));
+ visitor.visit_unit()
+ }
+ b't' => {
+ self.eat_char();
+ tri!(self.parse_ident(b"rue"));
+ visitor.visit_bool(true)
+ }
+ b'f' => {
+ self.eat_char();
+ tri!(self.parse_ident(b"alse"));
+ visitor.visit_bool(false)
+ }
+ b'-' => {
+ self.eat_char();
+ tri!(self.parse_any_number(false)).visit(visitor)
+ }
+ b'0'..=b'9' => tri!(self.parse_any_number(true)).visit(visitor),
+ b'"' => {
+ self.eat_char();
+ self.scratch.clear();
+ match tri!(self.read.parse_str(&mut self.scratch)) {
+ Reference::Borrowed(s) => visitor.visit_borrowed_str(s),
+ Reference::Copied(s) => visitor.visit_str(s),
+ }
+ }
+ b'[' => {
+ check_recursion! {
+ self.eat_char();
+ let ret = visitor.visit_seq(SeqAccess::new(self));
+ }
+
+ match (ret, self.end_seq()) {
+ (Ok(ret), Ok(())) => Ok(ret),
+ (Err(err), _) | (_, Err(err)) => Err(err),
+ }
+ }
+ b'{' => {
+ check_recursion! {
+ self.eat_char();
+ let ret = visitor.visit_map(MapAccess::new(self));
+ }
+
+ match (ret, self.end_map()) {
+ (Ok(ret), Ok(())) => Ok(ret),
+ (Err(err), _) | (_, Err(err)) => Err(err),
+ }
+ }
+ _ => Err(self.peek_error(ErrorCode::ExpectedSomeValue)),
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ // The de::Error impl creates errors with unknown line and column.
+ // Fill in the position here by looking at the current index in the
+ // input. There is no way to tell whether this should call `error`
+ // or `peek_error` so pick the one that seems correct more often.
+ // Worst case, the position is off by one character.
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let peek = match tri!(self.parse_whitespace()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let value = match peek {
+ b't' => {
+ self.eat_char();
+ tri!(self.parse_ident(b"rue"));
+ visitor.visit_bool(true)
+ }
+ b'f' => {
+ self.eat_char();
+ tri!(self.parse_ident(b"alse"));
+ visitor.visit_bool(false)
+ }
+ _ => Err(self.peek_invalid_type(&visitor)),
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ deserialize_number!(deserialize_i8);
+ deserialize_number!(deserialize_i16);
+ deserialize_number!(deserialize_i32);
+ deserialize_number!(deserialize_i64);
+ deserialize_number!(deserialize_u8);
+ deserialize_number!(deserialize_u16);
+ deserialize_number!(deserialize_u32);
+ deserialize_number!(deserialize_u64);
+ #[cfg(not(feature = "float_roundtrip"))]
+ deserialize_number!(deserialize_f32);
+ deserialize_number!(deserialize_f64);
+
+ #[cfg(feature = "float_roundtrip")]
+ fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.single_precision = true;
+ let val = self.deserialize_number(visitor);
+ self.single_precision = false;
+ val
+ }
+
+ fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let mut buf = String::new();
+
+ match tri!(self.parse_whitespace()) {
+ Some(b'-') => {
+ self.eat_char();
+ buf.push('-');
+ }
+ Some(_) => {}
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ tri!(self.scan_integer128(&mut buf));
+
+ let value = match buf.parse() {
+ Ok(int) => visitor.visit_i128(int),
+ Err(_) => {
+ return Err(self.error(ErrorCode::NumberOutOfRange));
+ }
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match tri!(self.parse_whitespace()) {
+ Some(b'-') => {
+ return Err(self.peek_error(ErrorCode::NumberOutOfRange));
+ }
+ Some(_) => {}
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ }
+
+ let mut buf = String::new();
+ tri!(self.scan_integer128(&mut buf));
+
+ let value = match buf.parse() {
+ Ok(int) => visitor.visit_u128(int),
+ Err(_) => {
+ return Err(self.error(ErrorCode::NumberOutOfRange));
+ }
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let peek = match tri!(self.parse_whitespace()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let value = match peek {
+ b'"' => {
+ self.eat_char();
+ self.scratch.clear();
+ match tri!(self.read.parse_str(&mut self.scratch)) {
+ Reference::Borrowed(s) => visitor.visit_borrowed_str(s),
+ Reference::Copied(s) => visitor.visit_str(s),
+ }
+ }
+ _ => Err(self.peek_invalid_type(&visitor)),
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ /// Parses a JSON string as bytes. Note that this function does not check
+ /// whether the bytes represent a valid UTF-8 string.
+ ///
+ /// The relevant part of the JSON specification is Section 8.2 of [RFC
+ /// 7159]:
+ ///
+ /// > When all the strings represented in a JSON text are composed entirely
+ /// > of Unicode characters (however escaped), then that JSON text is
+ /// > interoperable in the sense that all software implementations that
+ /// > parse it will agree on the contents of names and of string values in
+ /// > objects and arrays.
+ /// >
+ /// > However, the ABNF in this specification allows member names and string
+ /// > values to contain bit sequences that cannot encode Unicode characters;
+ /// > for example, "\uDEAD" (a single unpaired UTF-16 surrogate). Instances
+ /// > of this have been observed, for example, when a library truncates a
+ /// > UTF-16 string without checking whether the truncation split a
+ /// > surrogate pair. The behavior of software that receives JSON texts
+ /// > containing such values is unpredictable; for example, implementations
+ /// > might return different values for the length of a string value or even
+ /// > suffer fatal runtime exceptions.
+ ///
+ /// [RFC 7159]: https://tools.ietf.org/html/rfc7159
+ ///
+ /// The behavior of serde_json is specified to fail on non-UTF-8 strings
+ /// when deserializing into Rust UTF-8 string types such as String, and
+ /// succeed with non-UTF-8 bytes when deserializing using this method.
+ ///
+ /// Escape sequences are processed as usual, and for `\uXXXX` escapes it is
+ /// still checked if the hex number represents a valid Unicode code point.
+ ///
+ /// # Examples
+ ///
+ /// You can use this to parse JSON strings containing invalid UTF-8 bytes,
+ /// or unpaired surrogates.
+ ///
+ /// ```
+ /// use serde_bytes::ByteBuf;
+ ///
+ /// fn look_at_bytes() -> Result<(), serde_json::Error> {
+ /// let json_data = b"\"some bytes: \xe5\x00\xe5\"";
+ /// let bytes: ByteBuf = serde_json::from_slice(json_data)?;
+ ///
+ /// assert_eq!(b'\xe5', bytes[12]);
+ /// assert_eq!(b'\0', bytes[13]);
+ /// assert_eq!(b'\xe5', bytes[14]);
+ ///
+ /// Ok(())
+ /// }
+ /// #
+ /// # look_at_bytes().unwrap();
+ /// ```
+ ///
+ /// Backslash escape sequences like `\n` are still interpreted and required
+ /// to be valid. `\u` escape sequences are required to represent a valid
+ /// Unicode code point or lone surrogate.
+ ///
+ /// ```
+ /// use serde_bytes::ByteBuf;
+ ///
+ /// fn look_at_bytes() -> Result<(), serde_json::Error> {
+ /// let json_data = b"\"lone surrogate: \\uD801\"";
+ /// let bytes: ByteBuf = serde_json::from_slice(json_data)?;
+ /// let expected = b"lone surrogate: \xED\xA0\x81";
+ /// assert_eq!(expected, bytes.as_slice());
+ /// Ok(())
+ /// }
+ /// #
+ /// # look_at_bytes();
+ /// ```
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let peek = match tri!(self.parse_whitespace()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let value = match peek {
+ b'"' => {
+ self.eat_char();
+ self.scratch.clear();
+ match tri!(self.read.parse_str_raw(&mut self.scratch)) {
+ Reference::Borrowed(b) => visitor.visit_borrowed_bytes(b),
+ Reference::Copied(b) => visitor.visit_bytes(b),
+ }
+ }
+ b'[' => self.deserialize_seq(visitor),
+ _ => Err(self.peek_invalid_type(&visitor)),
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ #[inline]
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.deserialize_bytes(visitor)
+ }
+
+ /// Parses a `null` as a None, and any other values as a `Some(...)`.
+ #[inline]
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match tri!(self.parse_whitespace()) {
+ Some(b'n') => {
+ self.eat_char();
+ tri!(self.parse_ident(b"ull"));
+ visitor.visit_none()
+ }
+ _ => visitor.visit_some(self),
+ }
+ }
+
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let peek = match tri!(self.parse_whitespace()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let value = match peek {
+ b'n' => {
+ self.eat_char();
+ tri!(self.parse_ident(b"ull"));
+ visitor.visit_unit()
+ }
+ _ => Err(self.peek_invalid_type(&visitor)),
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.deserialize_unit(visitor)
+ }
+
+ /// Parses a newtype struct as the underlying value.
+ #[inline]
+ fn deserialize_newtype_struct<V>(self, name: &str, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ #[cfg(feature = "raw_value")]
+ {
+ if name == crate::raw::TOKEN {
+ return self.deserialize_raw_value(visitor);
+ }
+ }
+
+ let _ = name;
+ visitor.visit_newtype_struct(self)
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let peek = match tri!(self.parse_whitespace()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let value = match peek {
+ b'[' => {
+ check_recursion! {
+ self.eat_char();
+ let ret = visitor.visit_seq(SeqAccess::new(self));
+ }
+
+ match (ret, self.end_seq()) {
+ (Ok(ret), Ok(())) => Ok(ret),
+ (Err(err), _) | (_, Err(err)) => Err(err),
+ }
+ }
+ _ => Err(self.peek_invalid_type(&visitor)),
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_tuple_struct<V>(
+ self,
+ _name: &'static str,
+ _len: usize,
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let peek = match tri!(self.parse_whitespace()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let value = match peek {
+ b'{' => {
+ check_recursion! {
+ self.eat_char();
+ let ret = visitor.visit_map(MapAccess::new(self));
+ }
+
+ match (ret, self.end_map()) {
+ (Ok(ret), Ok(())) => Ok(ret),
+ (Err(err), _) | (_, Err(err)) => Err(err),
+ }
+ }
+ _ => Err(self.peek_invalid_type(&visitor)),
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ _name: &'static str,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ let peek = match tri!(self.parse_whitespace()) {
+ Some(b) => b,
+ None => {
+ return Err(self.peek_error(ErrorCode::EofWhileParsingValue));
+ }
+ };
+
+ let value = match peek {
+ b'[' => {
+ check_recursion! {
+ self.eat_char();
+ let ret = visitor.visit_seq(SeqAccess::new(self));
+ }
+
+ match (ret, self.end_seq()) {
+ (Ok(ret), Ok(())) => Ok(ret),
+ (Err(err), _) | (_, Err(err)) => Err(err),
+ }
+ }
+ b'{' => {
+ check_recursion! {
+ self.eat_char();
+ let ret = visitor.visit_map(MapAccess::new(self));
+ }
+
+ match (ret, self.end_map()) {
+ (Ok(ret), Ok(())) => Ok(ret),
+ (Err(err), _) | (_, Err(err)) => Err(err),
+ }
+ }
+ _ => Err(self.peek_invalid_type(&visitor)),
+ };
+
+ match value {
+ Ok(value) => Ok(value),
+ Err(err) => Err(self.fix_position(err)),
+ }
+ }
+
+ /// Parses an enum as an object like `{"$KEY":$VALUE}`, where $VALUE is either a straight
+ /// value, a `[..]`, or a `{..}`.
+ #[inline]
+ fn deserialize_enum<V>(
+ self,
+ _name: &str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ match tri!(self.parse_whitespace()) {
+ Some(b'{') => {
+ check_recursion! {
+ self.eat_char();
+ let value = tri!(visitor.visit_enum(VariantAccess::new(self)));
+ }
+
+ match tri!(self.parse_whitespace()) {
+ Some(b'}') => {
+ self.eat_char();
+ Ok(value)
+ }
+ Some(_) => Err(self.error(ErrorCode::ExpectedSomeValue)),
+ None => Err(self.error(ErrorCode::EofWhileParsingObject)),
+ }
+ }
+ Some(b'"') => visitor.visit_enum(UnitVariantAccess::new(self)),
+ Some(_) => Err(self.peek_error(ErrorCode::ExpectedSomeValue)),
+ None => Err(self.peek_error(ErrorCode::EofWhileParsingValue)),
+ }
+ }
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ tri!(self.ignore_value());
+ visitor.visit_unit()
+ }
+}
+
+struct SeqAccess<'a, R: 'a> {
+ de: &'a mut Deserializer<R>,
+ first: bool,
+}
+
+impl<'a, R: 'a> SeqAccess<'a, R> {
+ fn new(de: &'a mut Deserializer<R>) -> Self {
+ SeqAccess { de, first: true }
+ }
+}
+
+impl<'de, 'a, R: Read<'de> + 'a> de::SeqAccess<'de> for SeqAccess<'a, R> {
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ let peek = match tri!(self.de.parse_whitespace()) {
+ Some(b']') => {
+ return Ok(None);
+ }
+ Some(b',') if !self.first => {
+ self.de.eat_char();
+ tri!(self.de.parse_whitespace())
+ }
+ Some(b) => {
+ if self.first {
+ self.first = false;
+ Some(b)
+ } else {
+ return Err(self.de.peek_error(ErrorCode::ExpectedListCommaOrEnd));
+ }
+ }
+ None => {
+ return Err(self.de.peek_error(ErrorCode::EofWhileParsingList));
+ }
+ };
+
+ match peek {
+ Some(b']') => Err(self.de.peek_error(ErrorCode::TrailingComma)),
+ Some(_) => Ok(Some(tri!(seed.deserialize(&mut *self.de)))),
+ None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)),
+ }
+ }
+}
+
+struct MapAccess<'a, R: 'a> {
+ de: &'a mut Deserializer<R>,
+ first: bool,
+}
+
+impl<'a, R: 'a> MapAccess<'a, R> {
+ fn new(de: &'a mut Deserializer<R>) -> Self {
+ MapAccess { de, first: true }
+ }
+}
+
+impl<'de, 'a, R: Read<'de> + 'a> de::MapAccess<'de> for MapAccess<'a, R> {
+ type Error = Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
+ where
+ K: de::DeserializeSeed<'de>,
+ {
+ let peek = match tri!(self.de.parse_whitespace()) {
+ Some(b'}') => {
+ return Ok(None);
+ }
+ Some(b',') if !self.first => {
+ self.de.eat_char();
+ tri!(self.de.parse_whitespace())
+ }
+ Some(b) => {
+ if self.first {
+ self.first = false;
+ Some(b)
+ } else {
+ return Err(self.de.peek_error(ErrorCode::ExpectedObjectCommaOrEnd));
+ }
+ }
+ None => {
+ return Err(self.de.peek_error(ErrorCode::EofWhileParsingObject));
+ }
+ };
+
+ match peek {
+ Some(b'"') => seed.deserialize(MapKey { de: &mut *self.de }).map(Some),
+ Some(b'}') => Err(self.de.peek_error(ErrorCode::TrailingComma)),
+ Some(_) => Err(self.de.peek_error(ErrorCode::KeyMustBeAString)),
+ None => Err(self.de.peek_error(ErrorCode::EofWhileParsingValue)),
+ }
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ tri!(self.de.parse_object_colon());
+
+ seed.deserialize(&mut *self.de)
+ }
+}
+
+struct VariantAccess<'a, R: 'a> {
+ de: &'a mut Deserializer<R>,
+}
+
+impl<'a, R: 'a> VariantAccess<'a, R> {
+ fn new(de: &'a mut Deserializer<R>) -> Self {
+ VariantAccess { de }
+ }
+}
+
+impl<'de, 'a, R: Read<'de> + 'a> de::EnumAccess<'de> for VariantAccess<'a, R> {
+ type Error = Error;
+ type Variant = Self;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self)>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let val = tri!(seed.deserialize(&mut *self.de));
+ tri!(self.de.parse_object_colon());
+ Ok((val, self))
+ }
+}
+
+impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for VariantAccess<'a, R> {
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<()> {
+ de::Deserialize::deserialize(self.de)
+ }
+
+ fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(self.de)
+ }
+
+ fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ de::Deserializer::deserialize_seq(self.de, visitor)
+ }
+
+ fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ de::Deserializer::deserialize_struct(self.de, "", fields, visitor)
+ }
+}
+
+struct UnitVariantAccess<'a, R: 'a> {
+ de: &'a mut Deserializer<R>,
+}
+
+impl<'a, R: 'a> UnitVariantAccess<'a, R> {
+ fn new(de: &'a mut Deserializer<R>) -> Self {
+ UnitVariantAccess { de }
+ }
+}
+
+impl<'de, 'a, R: Read<'de> + 'a> de::EnumAccess<'de> for UnitVariantAccess<'a, R> {
+ type Error = Error;
+ type Variant = Self;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self)>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let variant = tri!(seed.deserialize(&mut *self.de));
+ Ok((variant, self))
+ }
+}
+
+impl<'de, 'a, R: Read<'de> + 'a> de::VariantAccess<'de> for UnitVariantAccess<'a, R> {
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<()> {
+ Ok(())
+ }
+
+ fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"newtype variant",
+ ))
+ }
+
+ fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"tuple variant",
+ ))
+ }
+
+ fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"struct variant",
+ ))
+ }
+}
+
+/// Only deserialize from this after peeking a '"' byte! Otherwise it may
+/// deserialize invalid JSON successfully.
+struct MapKey<'a, R: 'a> {
+ de: &'a mut Deserializer<R>,
+}
+
+macro_rules! deserialize_integer_key {
+ ($method:ident => $visit:ident) => {
+ fn $method<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.de.eat_char();
+ self.de.scratch.clear();
+ let string = tri!(self.de.read.parse_str(&mut self.de.scratch));
+ match (string.parse(), string) {
+ (Ok(integer), _) => visitor.$visit(integer),
+ (Err(_), Reference::Borrowed(s)) => visitor.visit_borrowed_str(s),
+ (Err(_), Reference::Copied(s)) => visitor.visit_str(s),
+ }
+ }
+ };
+}
+
+impl<'de, 'a, R> de::Deserializer<'de> for MapKey<'a, R>
+where
+ R: Read<'de>,
+{
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.de.eat_char();
+ self.de.scratch.clear();
+ match tri!(self.de.read.parse_str(&mut self.de.scratch)) {
+ Reference::Borrowed(s) => visitor.visit_borrowed_str(s),
+ Reference::Copied(s) => visitor.visit_str(s),
+ }
+ }
+
+ deserialize_integer_key!(deserialize_i8 => visit_i8);
+ deserialize_integer_key!(deserialize_i16 => visit_i16);
+ deserialize_integer_key!(deserialize_i32 => visit_i32);
+ deserialize_integer_key!(deserialize_i64 => visit_i64);
+ deserialize_integer_key!(deserialize_i128 => visit_i128);
+ deserialize_integer_key!(deserialize_u8 => visit_u8);
+ deserialize_integer_key!(deserialize_u16 => visit_u16);
+ deserialize_integer_key!(deserialize_u32 => visit_u32);
+ deserialize_integer_key!(deserialize_u64 => visit_u64);
+ deserialize_integer_key!(deserialize_u128 => visit_u128);
+
+ #[inline]
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ // Map keys cannot be null.
+ visitor.visit_some(self)
+ }
+
+ #[inline]
+ fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ #[cfg(feature = "raw_value")]
+ {
+ if name == crate::raw::TOKEN {
+ return self.de.deserialize_raw_value(visitor);
+ }
+ }
+
+ let _ = name;
+ visitor.visit_newtype_struct(self)
+ }
+
+ #[inline]
+ fn deserialize_enum<V>(
+ self,
+ name: &'static str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.de.deserialize_enum(name, variants, visitor)
+ }
+
+ #[inline]
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.de.deserialize_bytes(visitor)
+ }
+
+ #[inline]
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.de.deserialize_bytes(visitor)
+ }
+
+ forward_to_deserialize_any! {
+ bool f32 f64 char str string unit unit_struct seq tuple tuple_struct map
+ struct identifier ignored_any
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// Iterator that deserializes a stream into multiple JSON values.
+///
+/// A stream deserializer can be created from any JSON deserializer using the
+/// `Deserializer::into_iter` method.
+///
+/// The data can consist of any JSON value. Values need to be a self-delineating value e.g.
+/// arrays, objects, or strings, or be followed by whitespace or a self-delineating value.
+///
+/// ```
+/// use serde_json::{Deserializer, Value};
+///
+/// fn main() {
+/// let data = "{\"k\": 3}1\"cool\"\"stuff\" 3{} [0, 1, 2]";
+///
+/// let stream = Deserializer::from_str(data).into_iter::<Value>();
+///
+/// for value in stream {
+/// println!("{}", value.unwrap());
+/// }
+/// }
+/// ```
+pub struct StreamDeserializer<'de, R, T> {
+ de: Deserializer<R>,
+ offset: usize,
+ failed: bool,
+ output: PhantomData<T>,
+ lifetime: PhantomData<&'de ()>,
+}
+
+impl<'de, R, T> StreamDeserializer<'de, R, T>
+where
+ R: read::Read<'de>,
+ T: de::Deserialize<'de>,
+{
+ /// Create a JSON stream deserializer from one of the possible serde_json
+ /// input sources.
+ ///
+ /// Typically it is more convenient to use one of these methods instead:
+ ///
+ /// - Deserializer::from_str(...).into_iter()
+ /// - Deserializer::from_slice(...).into_iter()
+ /// - Deserializer::from_reader(...).into_iter()
+ pub fn new(read: R) -> Self {
+ let offset = read.byte_offset();
+ StreamDeserializer {
+ de: Deserializer::new(read),
+ offset,
+ failed: false,
+ output: PhantomData,
+ lifetime: PhantomData,
+ }
+ }
+
+ /// Returns the number of bytes so far deserialized into a successful `T`.
+ ///
+ /// If a stream deserializer returns an EOF error, new data can be joined to
+ /// `old_data[stream.byte_offset()..]` to try again.
+ ///
+ /// ```
+ /// let data = b"[0] [1] [";
+ ///
+ /// let de = serde_json::Deserializer::from_slice(data);
+ /// let mut stream = de.into_iter::<Vec<i32>>();
+ /// assert_eq!(0, stream.byte_offset());
+ ///
+ /// println!("{:?}", stream.next()); // [0]
+ /// assert_eq!(3, stream.byte_offset());
+ ///
+ /// println!("{:?}", stream.next()); // [1]
+ /// assert_eq!(7, stream.byte_offset());
+ ///
+ /// println!("{:?}", stream.next()); // error
+ /// assert_eq!(8, stream.byte_offset());
+ ///
+ /// // If err.is_eof(), can join the remaining data to new data and continue.
+ /// let remaining = &data[stream.byte_offset()..];
+ /// ```
+ ///
+ /// *Note:* In the future this method may be changed to return the number of
+ /// bytes so far deserialized into a successful T *or* syntactically valid
+ /// JSON skipped over due to a type error. See [serde-rs/json#70] for an
+ /// example illustrating this.
+ ///
+ /// [serde-rs/json#70]: https://github.com/serde-rs/json/issues/70
+ pub fn byte_offset(&self) -> usize {
+ self.offset
+ }
+
+ fn peek_end_of_value(&mut self) -> Result<()> {
+ match tri!(self.de.peek()) {
+ Some(b' ') | Some(b'\n') | Some(b'\t') | Some(b'\r') | Some(b'"') | Some(b'[')
+ | Some(b']') | Some(b'{') | Some(b'}') | Some(b',') | Some(b':') | None => Ok(()),
+ Some(_) => {
+ let position = self.de.read.peek_position();
+ Err(Error::syntax(
+ ErrorCode::TrailingCharacters,
+ position.line,
+ position.column,
+ ))
+ }
+ }
+ }
+}
+
+impl<'de, R, T> Iterator for StreamDeserializer<'de, R, T>
+where
+ R: Read<'de>,
+ T: de::Deserialize<'de>,
+{
+ type Item = Result<T>;
+
+ fn next(&mut self) -> Option<Result<T>> {
+ if R::should_early_return_if_failed && self.failed {
+ return None;
+ }
+
+ // skip whitespaces, if any
+ // this helps with trailing whitespaces, since whitespaces between
+ // values are handled for us.
+ match self.de.parse_whitespace() {
+ Ok(None) => {
+ self.offset = self.de.read.byte_offset();
+ None
+ }
+ Ok(Some(b)) => {
+ // If the value does not have a clear way to show the end of the value
+ // (like numbers, null, true etc.) we have to look for whitespace or
+ // the beginning of a self-delineated value.
+ let self_delineated_value = match b {
+ b'[' | b'"' | b'{' => true,
+ _ => false,
+ };
+ self.offset = self.de.read.byte_offset();
+ let result = de::Deserialize::deserialize(&mut self.de);
+
+ Some(match result {
+ Ok(value) => {
+ self.offset = self.de.read.byte_offset();
+ if self_delineated_value {
+ Ok(value)
+ } else {
+ self.peek_end_of_value().map(|_| value)
+ }
+ }
+ Err(e) => {
+ self.de.read.set_failed(&mut self.failed);
+ Err(e)
+ }
+ })
+ }
+ Err(e) => {
+ self.de.read.set_failed(&mut self.failed);
+ Some(Err(e))
+ }
+ }
+ }
+}
+
+impl<'de, R, T> FusedIterator for StreamDeserializer<'de, R, T>
+where
+ R: Read<'de> + Fused,
+ T: de::Deserialize<'de>,
+{
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+fn from_trait<'de, R, T>(read: R) -> Result<T>
+where
+ R: Read<'de>,
+ T: de::Deserialize<'de>,
+{
+ let mut de = Deserializer::new(read);
+ let value = tri!(de::Deserialize::deserialize(&mut de));
+
+ // Make sure the whole stream has been consumed.
+ tri!(de.end());
+ Ok(value)
+}
+
+/// Deserialize an instance of type `T` from an IO stream of JSON.
+///
+/// The content of the IO stream is deserialized directly from the stream
+/// without being buffered in memory by serde_json.
+///
+/// When reading from a source against which short reads are not efficient, such
+/// as a [`File`], you will want to apply your own buffering because serde_json
+/// will not buffer the input. See [`std::io::BufReader`].
+///
+/// It is expected that the input stream ends after the deserialized object.
+/// If the stream does not end, such as in the case of a persistent socket connection,
+/// this function will not return. It is possible instead to deserialize from a prefix of an input
+/// stream without looking for EOF by managing your own [`Deserializer`].
+///
+/// Note that counter to intuition, this function is usually slower than
+/// reading a file completely into memory and then applying [`from_str`]
+/// or [`from_slice`] on it. See [issue #160].
+///
+/// [`File`]: https://doc.rust-lang.org/std/fs/struct.File.html
+/// [`std::io::BufReader`]: https://doc.rust-lang.org/std/io/struct.BufReader.html
+/// [`from_str`]: ./fn.from_str.html
+/// [`from_slice`]: ./fn.from_slice.html
+/// [issue #160]: https://github.com/serde-rs/json/issues/160
+///
+/// # Example
+///
+/// Reading the contents of a file.
+///
+/// ```
+/// use serde::Deserialize;
+///
+/// use std::error::Error;
+/// use std::fs::File;
+/// use std::io::BufReader;
+/// use std::path::Path;
+///
+/// #[derive(Deserialize, Debug)]
+/// struct User {
+/// fingerprint: String,
+/// location: String,
+/// }
+///
+/// fn read_user_from_file<P: AsRef<Path>>(path: P) -> Result<User, Box<dyn Error>> {
+/// // Open the file in read-only mode with buffer.
+/// let file = File::open(path)?;
+/// let reader = BufReader::new(file);
+///
+/// // Read the JSON contents of the file as an instance of `User`.
+/// let u = serde_json::from_reader(reader)?;
+///
+/// // Return the `User`.
+/// Ok(u)
+/// }
+///
+/// fn main() {
+/// # }
+/// # fn fake_main() {
+/// let u = read_user_from_file("test.json").unwrap();
+/// println!("{:#?}", u);
+/// }
+/// ```
+///
+/// Reading from a persistent socket connection.
+///
+/// ```
+/// use serde::Deserialize;
+///
+/// use std::error::Error;
+/// use std::net::{TcpListener, TcpStream};
+///
+/// #[derive(Deserialize, Debug)]
+/// struct User {
+/// fingerprint: String,
+/// location: String,
+/// }
+///
+/// fn read_user_from_stream(tcp_stream: TcpStream) -> Result<User, Box<dyn Error>> {
+/// let mut de = serde_json::Deserializer::from_reader(tcp_stream);
+/// let u = User::deserialize(&mut de)?;
+///
+/// Ok(u)
+/// }
+///
+/// fn main() {
+/// # }
+/// # fn fake_main() {
+/// let listener = TcpListener::bind("127.0.0.1:4000").unwrap();
+///
+/// for stream in listener.incoming() {
+/// println!("{:#?}", read_user_from_stream(stream.unwrap()));
+/// }
+/// }
+/// ```
+///
+/// # Errors
+///
+/// This conversion can fail if the structure of the input does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the input
+/// contains something other than a JSON map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the JSON map or some number is too big to fit in the expected primitive
+/// type.
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub fn from_reader<R, T>(rdr: R) -> Result<T>
+where
+ R: crate::io::Read,
+ T: de::DeserializeOwned,
+{
+ from_trait(read::IoRead::new(rdr))
+}
+
+/// Deserialize an instance of type `T` from bytes of JSON text.
+///
+/// # Example
+///
+/// ```
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize, Debug)]
+/// struct User {
+/// fingerprint: String,
+/// location: String,
+/// }
+///
+/// fn main() {
+/// // The type of `j` is `&[u8]`
+/// let j = b"
+/// {
+/// \"fingerprint\": \"0xF9BA143B95FF6D82\",
+/// \"location\": \"Menlo Park, CA\"
+/// }";
+///
+/// let u: User = serde_json::from_slice(j).unwrap();
+/// println!("{:#?}", u);
+/// }
+/// ```
+///
+/// # Errors
+///
+/// This conversion can fail if the structure of the input does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the input
+/// contains something other than a JSON map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the JSON map or some number is too big to fit in the expected primitive
+/// type.
+pub fn from_slice<'a, T>(v: &'a [u8]) -> Result<T>
+where
+ T: de::Deserialize<'a>,
+{
+ from_trait(read::SliceRead::new(v))
+}
+
+/// Deserialize an instance of type `T` from a string of JSON text.
+///
+/// # Example
+///
+/// ```
+/// use serde::Deserialize;
+///
+/// #[derive(Deserialize, Debug)]
+/// struct User {
+/// fingerprint: String,
+/// location: String,
+/// }
+///
+/// fn main() {
+/// // The type of `j` is `&str`
+/// let j = "
+/// {
+/// \"fingerprint\": \"0xF9BA143B95FF6D82\",
+/// \"location\": \"Menlo Park, CA\"
+/// }";
+///
+/// let u: User = serde_json::from_str(j).unwrap();
+/// println!("{:#?}", u);
+/// }
+/// ```
+///
+/// # Errors
+///
+/// This conversion can fail if the structure of the input does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the input
+/// contains something other than a JSON map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the JSON map or some number is too big to fit in the expected primitive
+/// type.
+pub fn from_str<'a, T>(s: &'a str) -> Result<T>
+where
+ T: de::Deserialize<'a>,
+{
+ from_trait(read::StrRead::new(s))
+}
diff --git a/third_party/rust/serde_json/src/error.rs b/third_party/rust/serde_json/src/error.rs
new file mode 100644
index 0000000000..1875ef08b0
--- /dev/null
+++ b/third_party/rust/serde_json/src/error.rs
@@ -0,0 +1,445 @@
+//! When serializing or deserializing JSON goes wrong.
+
+use crate::io;
+use alloc::boxed::Box;
+use alloc::string::{String, ToString};
+use core::fmt::{self, Debug, Display};
+use core::result;
+use core::str::FromStr;
+use serde::{de, ser};
+#[cfg(feature = "std")]
+use std::error;
+
+/// This type represents all possible errors that can occur when serializing or
+/// deserializing JSON data.
+pub struct Error {
+ /// This `Box` allows us to keep the size of `Error` as small as possible. A
+ /// larger `Error` type was substantially slower due to all the functions
+ /// that pass around `Result<T, Error>`.
+ err: Box<ErrorImpl>,
+}
+
+/// Alias for a `Result` with the error type `serde_json::Error`.
+pub type Result<T> = result::Result<T, Error>;
+
+impl Error {
+ /// One-based line number at which the error was detected.
+ ///
+ /// Characters in the first line of the input (before the first newline
+ /// character) are in line 1.
+ pub fn line(&self) -> usize {
+ self.err.line
+ }
+
+ /// One-based column number at which the error was detected.
+ ///
+ /// The first character in the input and any characters immediately
+ /// following a newline character are in column 1.
+ ///
+ /// Note that errors may occur in column 0, for example if a read from an IO
+ /// stream fails immediately following a previously read newline character.
+ pub fn column(&self) -> usize {
+ self.err.column
+ }
+
+ /// Categorizes the cause of this error.
+ ///
+ /// - `Category::Io` - failure to read or write bytes on an IO stream
+ /// - `Category::Syntax` - input that is not syntactically valid JSON
+ /// - `Category::Data` - input data that is semantically incorrect
+ /// - `Category::Eof` - unexpected end of the input data
+ pub fn classify(&self) -> Category {
+ match self.err.code {
+ ErrorCode::Message(_) => Category::Data,
+ ErrorCode::Io(_) => Category::Io,
+ ErrorCode::EofWhileParsingList
+ | ErrorCode::EofWhileParsingObject
+ | ErrorCode::EofWhileParsingString
+ | ErrorCode::EofWhileParsingValue => Category::Eof,
+ ErrorCode::ExpectedColon
+ | ErrorCode::ExpectedListCommaOrEnd
+ | ErrorCode::ExpectedObjectCommaOrEnd
+ | ErrorCode::ExpectedSomeIdent
+ | ErrorCode::ExpectedSomeValue
+ | ErrorCode::InvalidEscape
+ | ErrorCode::InvalidNumber
+ | ErrorCode::NumberOutOfRange
+ | ErrorCode::InvalidUnicodeCodePoint
+ | ErrorCode::ControlCharacterWhileParsingString
+ | ErrorCode::KeyMustBeAString
+ | ErrorCode::LoneLeadingSurrogateInHexEscape
+ | ErrorCode::TrailingComma
+ | ErrorCode::TrailingCharacters
+ | ErrorCode::UnexpectedEndOfHexEscape
+ | ErrorCode::RecursionLimitExceeded => Category::Syntax,
+ }
+ }
+
+ /// Returns true if this error was caused by a failure to read or write
+ /// bytes on an IO stream.
+ pub fn is_io(&self) -> bool {
+ self.classify() == Category::Io
+ }
+
+ /// Returns true if this error was caused by input that was not
+ /// syntactically valid JSON.
+ pub fn is_syntax(&self) -> bool {
+ self.classify() == Category::Syntax
+ }
+
+ /// Returns true if this error was caused by input data that was
+ /// semantically incorrect.
+ ///
+ /// For example, JSON containing a number is semantically incorrect when the
+ /// type being deserialized into holds a String.
+ pub fn is_data(&self) -> bool {
+ self.classify() == Category::Data
+ }
+
+ /// Returns true if this error was caused by prematurely reaching the end of
+ /// the input data.
+ ///
+ /// Callers that process streaming input may be interested in retrying the
+ /// deserialization once more data is available.
+ pub fn is_eof(&self) -> bool {
+ self.classify() == Category::Eof
+ }
+}
+
+/// Categorizes the cause of a `serde_json::Error`.
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum Category {
+ /// The error was caused by a failure to read or write bytes on an IO
+ /// stream.
+ Io,
+
+ /// The error was caused by input that was not syntactically valid JSON.
+ Syntax,
+
+ /// The error was caused by input data that was semantically incorrect.
+ ///
+ /// For example, JSON containing a number is semantically incorrect when the
+ /// type being deserialized into holds a String.
+ Data,
+
+ /// The error was caused by prematurely reaching the end of the input data.
+ ///
+ /// Callers that process streaming input may be interested in retrying the
+ /// deserialization once more data is available.
+ Eof,
+}
+
+#[cfg(feature = "std")]
+#[allow(clippy::fallible_impl_from)]
+impl From<Error> for io::Error {
+ /// Convert a `serde_json::Error` into an `io::Error`.
+ ///
+ /// JSON syntax and data errors are turned into `InvalidData` IO errors.
+ /// EOF errors are turned into `UnexpectedEof` IO errors.
+ ///
+ /// ```
+ /// use std::io;
+ ///
+ /// enum MyError {
+ /// Io(io::Error),
+ /// Json(serde_json::Error),
+ /// }
+ ///
+ /// impl From<serde_json::Error> for MyError {
+ /// fn from(err: serde_json::Error) -> MyError {
+ /// use serde_json::error::Category;
+ /// match err.classify() {
+ /// Category::Io => {
+ /// MyError::Io(err.into())
+ /// }
+ /// Category::Syntax | Category::Data | Category::Eof => {
+ /// MyError::Json(err)
+ /// }
+ /// }
+ /// }
+ /// }
+ /// ```
+ fn from(j: Error) -> Self {
+ if let ErrorCode::Io(err) = j.err.code {
+ err
+ } else {
+ match j.classify() {
+ Category::Io => unreachable!(),
+ Category::Syntax | Category::Data => io::Error::new(io::ErrorKind::InvalidData, j),
+ Category::Eof => io::Error::new(io::ErrorKind::UnexpectedEof, j),
+ }
+ }
+ }
+}
+
+struct ErrorImpl {
+ code: ErrorCode,
+ line: usize,
+ column: usize,
+}
+
+pub(crate) enum ErrorCode {
+ /// Catchall for syntax error messages
+ Message(Box<str>),
+
+ /// Some IO error occurred while serializing or deserializing.
+ Io(io::Error),
+
+ /// EOF while parsing a list.
+ EofWhileParsingList,
+
+ /// EOF while parsing an object.
+ EofWhileParsingObject,
+
+ /// EOF while parsing a string.
+ EofWhileParsingString,
+
+ /// EOF while parsing a JSON value.
+ EofWhileParsingValue,
+
+ /// Expected this character to be a `':'`.
+ ExpectedColon,
+
+ /// Expected this character to be either a `','` or a `']'`.
+ ExpectedListCommaOrEnd,
+
+ /// Expected this character to be either a `','` or a `'}'`.
+ ExpectedObjectCommaOrEnd,
+
+ /// Expected to parse either a `true`, `false`, or a `null`.
+ ExpectedSomeIdent,
+
+ /// Expected this character to start a JSON value.
+ ExpectedSomeValue,
+
+ /// Invalid hex escape code.
+ InvalidEscape,
+
+ /// Invalid number.
+ InvalidNumber,
+
+ /// Number is bigger than the maximum value of its type.
+ NumberOutOfRange,
+
+ /// Invalid unicode code point.
+ InvalidUnicodeCodePoint,
+
+ /// Control character found while parsing a string.
+ ControlCharacterWhileParsingString,
+
+ /// Object key is not a string.
+ KeyMustBeAString,
+
+ /// Lone leading surrogate in hex escape.
+ LoneLeadingSurrogateInHexEscape,
+
+ /// JSON has a comma after the last value in an array or map.
+ TrailingComma,
+
+ /// JSON has non-whitespace trailing characters after the value.
+ TrailingCharacters,
+
+ /// Unexpected end of hex escape.
+ UnexpectedEndOfHexEscape,
+
+ /// Encountered nesting of JSON maps and arrays more than 128 layers deep.
+ RecursionLimitExceeded,
+}
+
+impl Error {
+ #[cold]
+ pub(crate) fn syntax(code: ErrorCode, line: usize, column: usize) -> Self {
+ Error {
+ err: Box::new(ErrorImpl { code, line, column }),
+ }
+ }
+
+ // Not public API. Should be pub(crate).
+ //
+ // Update `eager_json` crate when this function changes.
+ #[doc(hidden)]
+ #[cold]
+ pub fn io(error: io::Error) -> Self {
+ Error {
+ err: Box::new(ErrorImpl {
+ code: ErrorCode::Io(error),
+ line: 0,
+ column: 0,
+ }),
+ }
+ }
+
+ #[cold]
+ pub(crate) fn fix_position<F>(self, f: F) -> Self
+ where
+ F: FnOnce(ErrorCode) -> Error,
+ {
+ if self.err.line == 0 {
+ f(self.err.code)
+ } else {
+ self
+ }
+ }
+}
+
+impl Display for ErrorCode {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ ErrorCode::Message(msg) => f.write_str(msg),
+ ErrorCode::Io(err) => Display::fmt(err, f),
+ ErrorCode::EofWhileParsingList => f.write_str("EOF while parsing a list"),
+ ErrorCode::EofWhileParsingObject => f.write_str("EOF while parsing an object"),
+ ErrorCode::EofWhileParsingString => f.write_str("EOF while parsing a string"),
+ ErrorCode::EofWhileParsingValue => f.write_str("EOF while parsing a value"),
+ ErrorCode::ExpectedColon => f.write_str("expected `:`"),
+ ErrorCode::ExpectedListCommaOrEnd => f.write_str("expected `,` or `]`"),
+ ErrorCode::ExpectedObjectCommaOrEnd => f.write_str("expected `,` or `}`"),
+ ErrorCode::ExpectedSomeIdent => f.write_str("expected ident"),
+ ErrorCode::ExpectedSomeValue => f.write_str("expected value"),
+ ErrorCode::InvalidEscape => f.write_str("invalid escape"),
+ ErrorCode::InvalidNumber => f.write_str("invalid number"),
+ ErrorCode::NumberOutOfRange => f.write_str("number out of range"),
+ ErrorCode::InvalidUnicodeCodePoint => f.write_str("invalid unicode code point"),
+ ErrorCode::ControlCharacterWhileParsingString => {
+ f.write_str("control character (\\u0000-\\u001F) found while parsing a string")
+ }
+ ErrorCode::KeyMustBeAString => f.write_str("key must be a string"),
+ ErrorCode::LoneLeadingSurrogateInHexEscape => {
+ f.write_str("lone leading surrogate in hex escape")
+ }
+ ErrorCode::TrailingComma => f.write_str("trailing comma"),
+ ErrorCode::TrailingCharacters => f.write_str("trailing characters"),
+ ErrorCode::UnexpectedEndOfHexEscape => f.write_str("unexpected end of hex escape"),
+ ErrorCode::RecursionLimitExceeded => f.write_str("recursion limit exceeded"),
+ }
+ }
+}
+
+impl serde::de::StdError for Error {
+ #[cfg(feature = "std")]
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+ match &self.err.code {
+ ErrorCode::Io(err) => Some(err),
+ _ => None,
+ }
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&*self.err, f)
+ }
+}
+
+impl Display for ErrorImpl {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ if self.line == 0 {
+ Display::fmt(&self.code, f)
+ } else {
+ write!(
+ f,
+ "{} at line {} column {}",
+ self.code, self.line, self.column
+ )
+ }
+ }
+}
+
+// Remove two layers of verbosity from the debug representation. Humans often
+// end up seeing this representation because it is what unwrap() shows.
+impl Debug for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ write!(
+ f,
+ "Error({:?}, line: {}, column: {})",
+ self.err.code.to_string(),
+ self.err.line,
+ self.err.column
+ )
+ }
+}
+
+impl de::Error for Error {
+ #[cold]
+ fn custom<T: Display>(msg: T) -> Error {
+ make_error(msg.to_string())
+ }
+
+ #[cold]
+ fn invalid_type(unexp: de::Unexpected, exp: &dyn de::Expected) -> Self {
+ if let de::Unexpected::Unit = unexp {
+ Error::custom(format_args!("invalid type: null, expected {}", exp))
+ } else {
+ Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
+ }
+ }
+}
+
+impl ser::Error for Error {
+ #[cold]
+ fn custom<T: Display>(msg: T) -> Error {
+ make_error(msg.to_string())
+ }
+}
+
+// Parse our own error message that looks like "{} at line {} column {}" to work
+// around erased-serde round-tripping the error through de::Error::custom.
+fn make_error(mut msg: String) -> Error {
+ let (line, column) = parse_line_col(&mut msg).unwrap_or((0, 0));
+ Error {
+ err: Box::new(ErrorImpl {
+ code: ErrorCode::Message(msg.into_boxed_str()),
+ line,
+ column,
+ }),
+ }
+}
+
+fn parse_line_col(msg: &mut String) -> Option<(usize, usize)> {
+ let start_of_suffix = match msg.rfind(" at line ") {
+ Some(index) => index,
+ None => return None,
+ };
+
+ // Find start and end of line number.
+ let start_of_line = start_of_suffix + " at line ".len();
+ let mut end_of_line = start_of_line;
+ while starts_with_digit(&msg[end_of_line..]) {
+ end_of_line += 1;
+ }
+
+ if !msg[end_of_line..].starts_with(" column ") {
+ return None;
+ }
+
+ // Find start and end of column number.
+ let start_of_column = end_of_line + " column ".len();
+ let mut end_of_column = start_of_column;
+ while starts_with_digit(&msg[end_of_column..]) {
+ end_of_column += 1;
+ }
+
+ if end_of_column < msg.len() {
+ return None;
+ }
+
+ // Parse numbers.
+ let line = match usize::from_str(&msg[start_of_line..end_of_line]) {
+ Ok(line) => line,
+ Err(_) => return None,
+ };
+ let column = match usize::from_str(&msg[start_of_column..end_of_column]) {
+ Ok(column) => column,
+ Err(_) => return None,
+ };
+
+ msg.truncate(start_of_suffix);
+ Some((line, column))
+}
+
+fn starts_with_digit(slice: &str) -> bool {
+ match slice.as_bytes().first() {
+ None => false,
+ Some(&byte) => byte >= b'0' && byte <= b'9',
+ }
+}
diff --git a/third_party/rust/serde_json/src/features_check/error.rs b/third_party/rust/serde_json/src/features_check/error.rs
new file mode 100644
index 0000000000..22e58235c7
--- /dev/null
+++ b/third_party/rust/serde_json/src/features_check/error.rs
@@ -0,0 +1 @@
+"serde_json requires that either `std` (default) or `alloc` feature is enabled"
diff --git a/third_party/rust/serde_json/src/features_check/mod.rs b/third_party/rust/serde_json/src/features_check/mod.rs
new file mode 100644
index 0000000000..d12032cef8
--- /dev/null
+++ b/third_party/rust/serde_json/src/features_check/mod.rs
@@ -0,0 +1,13 @@
+//! Shows a user-friendly compiler error on incompatible selected features.
+
+#[allow(unused_macros)]
+macro_rules! hide_from_rustfmt {
+ ($mod:item) => {
+ $mod
+ };
+}
+
+#[cfg(not(any(feature = "std", feature = "alloc")))]
+hide_from_rustfmt! {
+ mod error;
+}
diff --git a/third_party/rust/serde_json/src/io/core.rs b/third_party/rust/serde_json/src/io/core.rs
new file mode 100644
index 0000000000..465ab8b249
--- /dev/null
+++ b/third_party/rust/serde_json/src/io/core.rs
@@ -0,0 +1,79 @@
+//! Reimplements core logic and types from `std::io` in an `alloc`-friendly
+//! fashion.
+
+use alloc::vec::Vec;
+use core::fmt::{self, Display};
+use core::result;
+
+pub enum ErrorKind {
+ Other,
+}
+
+// IO errors can never occur in no-std mode. All our no-std IO implementations
+// are infallible.
+pub struct Error;
+
+impl Display for Error {
+ fn fmt(&self, _formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ unreachable!()
+ }
+}
+
+impl Error {
+ pub(crate) fn new(_kind: ErrorKind, _error: &'static str) -> Error {
+ Error
+ }
+}
+
+pub type Result<T> = result::Result<T, Error>;
+
+pub trait Write {
+ fn write(&mut self, buf: &[u8]) -> Result<usize>;
+
+ fn write_all(&mut self, buf: &[u8]) -> Result<()> {
+ // All our Write impls in no_std mode always write the whole buffer in
+ // one call infallibly.
+ let result = self.write(buf);
+ debug_assert!(result.is_ok());
+ debug_assert_eq!(result.unwrap_or(0), buf.len());
+ Ok(())
+ }
+
+ fn flush(&mut self) -> Result<()>;
+}
+
+impl<W: Write> Write for &mut W {
+ #[inline]
+ fn write(&mut self, buf: &[u8]) -> Result<usize> {
+ (*self).write(buf)
+ }
+
+ #[inline]
+ fn write_all(&mut self, buf: &[u8]) -> Result<()> {
+ (*self).write_all(buf)
+ }
+
+ #[inline]
+ fn flush(&mut self) -> Result<()> {
+ (*self).flush()
+ }
+}
+
+impl Write for Vec<u8> {
+ #[inline]
+ fn write(&mut self, buf: &[u8]) -> Result<usize> {
+ self.extend_from_slice(buf);
+ Ok(buf.len())
+ }
+
+ #[inline]
+ fn write_all(&mut self, buf: &[u8]) -> Result<()> {
+ self.extend_from_slice(buf);
+ Ok(())
+ }
+
+ #[inline]
+ fn flush(&mut self) -> Result<()> {
+ Ok(())
+ }
+}
diff --git a/third_party/rust/serde_json/src/io/mod.rs b/third_party/rust/serde_json/src/io/mod.rs
new file mode 100644
index 0000000000..9dee4a0685
--- /dev/null
+++ b/third_party/rust/serde_json/src/io/mod.rs
@@ -0,0 +1,20 @@
+//! A tiny, `no_std`-friendly facade around `std::io`.
+//! Reexports types from `std` when available; otherwise reimplements and
+//! provides some of the core logic.
+//!
+//! The main reason that `std::io` hasn't found itself reexported as part of
+//! the `core` crate is the `std::io::{Read, Write}` traits' reliance on
+//! `std::io::Error`, which may contain internally a heap-allocated `Box<Error>`
+//! and/or now relying on OS-specific `std::backtrace::Backtrace`.
+
+pub use self::imp::{Error, ErrorKind, Result, Write};
+
+#[cfg(not(feature = "std"))]
+#[path = "core.rs"]
+mod imp;
+
+#[cfg(feature = "std")]
+use std::io as imp;
+
+#[cfg(feature = "std")]
+pub use std::io::{Bytes, Read};
diff --git a/third_party/rust/serde_json/src/iter.rs b/third_party/rust/serde_json/src/iter.rs
new file mode 100644
index 0000000000..9792916dcc
--- /dev/null
+++ b/third_party/rust/serde_json/src/iter.rs
@@ -0,0 +1,70 @@
+use crate::io;
+
+pub struct LineColIterator<I> {
+ iter: I,
+
+ /// Index of the current line. Characters in the first line of the input
+ /// (before the first newline character) are in line 1.
+ line: usize,
+
+ /// Index of the current column. The first character in the input and any
+ /// characters immediately following a newline character are in column 1.
+ /// The column is 0 immediately after a newline character has been read.
+ col: usize,
+
+ /// Byte offset of the start of the current line. This is the sum of lengths
+ /// of all previous lines. Keeping track of things this way allows efficient
+ /// computation of the current line, column, and byte offset while only
+ /// updating one of the counters in `next()` in the common case.
+ start_of_line: usize,
+}
+
+impl<I> LineColIterator<I>
+where
+ I: Iterator<Item = io::Result<u8>>,
+{
+ pub fn new(iter: I) -> LineColIterator<I> {
+ LineColIterator {
+ iter,
+ line: 1,
+ col: 0,
+ start_of_line: 0,
+ }
+ }
+
+ pub fn line(&self) -> usize {
+ self.line
+ }
+
+ pub fn col(&self) -> usize {
+ self.col
+ }
+
+ pub fn byte_offset(&self) -> usize {
+ self.start_of_line + self.col
+ }
+}
+
+impl<I> Iterator for LineColIterator<I>
+where
+ I: Iterator<Item = io::Result<u8>>,
+{
+ type Item = io::Result<u8>;
+
+ fn next(&mut self) -> Option<io::Result<u8>> {
+ match self.iter.next() {
+ None => None,
+ Some(Ok(b'\n')) => {
+ self.start_of_line += self.col + 1;
+ self.line += 1;
+ self.col = 0;
+ Some(Ok(b'\n'))
+ }
+ Some(Ok(c)) => {
+ self.col += 1;
+ Some(Ok(c))
+ }
+ Some(Err(e)) => Some(Err(e)),
+ }
+ }
+}
diff --git a/third_party/rust/serde_json/src/lexical/algorithm.rs b/third_party/rust/serde_json/src/lexical/algorithm.rs
new file mode 100644
index 0000000000..a2cbf18aff
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/algorithm.rs
@@ -0,0 +1,193 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Algorithms to efficiently convert strings to floats.
+
+use super::bhcomp::*;
+use super::cached::*;
+use super::errors::*;
+use super::float::ExtendedFloat;
+use super::num::*;
+use super::small_powers::*;
+
+// FAST
+// ----
+
+/// Convert mantissa to exact value for a non-base2 power.
+///
+/// Returns the resulting float and if the value can be represented exactly.
+pub(crate) fn fast_path<F>(mantissa: u64, exponent: i32) -> Option<F>
+where
+ F: Float,
+{
+ // `mantissa >> (F::MANTISSA_SIZE+1) != 0` effectively checks if the
+ // value has a no bits above the hidden bit, which is what we want.
+ let (min_exp, max_exp) = F::exponent_limit();
+ let shift_exp = F::mantissa_limit();
+ let mantissa_size = F::MANTISSA_SIZE + 1;
+ if mantissa == 0 {
+ Some(F::ZERO)
+ } else if mantissa >> mantissa_size != 0 {
+ // Would require truncation of the mantissa.
+ None
+ } else if exponent == 0 {
+ // 0 exponent, same as value, exact representation.
+ let float = F::as_cast(mantissa);
+ Some(float)
+ } else if exponent >= min_exp && exponent <= max_exp {
+ // Value can be exactly represented, return the value.
+ // Do not use powi, since powi can incrementally introduce
+ // error.
+ let float = F::as_cast(mantissa);
+ Some(float.pow10(exponent))
+ } else if exponent >= 0 && exponent <= max_exp + shift_exp {
+ // Check to see if we have a disguised fast-path, where the
+ // number of digits in the mantissa is very small, but and
+ // so digits can be shifted from the exponent to the mantissa.
+ // https://www.exploringbinary.com/fast-path-decimal-to-floating-point-conversion/
+ let small_powers = POW10_64;
+ let shift = exponent - max_exp;
+ let power = small_powers[shift as usize];
+
+ // Compute the product of the power, if it overflows,
+ // prematurely return early, otherwise, if we didn't overshoot,
+ // we can get an exact value.
+ let value = mantissa.checked_mul(power)?;
+ if value >> mantissa_size != 0 {
+ None
+ } else {
+ // Use powi, since it's correct, and faster on
+ // the fast-path.
+ let float = F::as_cast(value);
+ Some(float.pow10(max_exp))
+ }
+ } else {
+ // Cannot be exactly represented, exponent too small or too big,
+ // would require truncation.
+ None
+ }
+}
+
+// MODERATE
+// --------
+
+/// Multiply the floating-point by the exponent.
+///
+/// Multiply by pre-calculated powers of the base, modify the extended-
+/// float, and return if new value and if the value can be represented
+/// accurately.
+fn multiply_exponent_extended<F>(fp: &mut ExtendedFloat, exponent: i32, truncated: bool) -> bool
+where
+ F: Float,
+{
+ let powers = ExtendedFloat::get_powers();
+ let exponent = exponent.saturating_add(powers.bias);
+ let small_index = exponent % powers.step;
+ let large_index = exponent / powers.step;
+ if exponent < 0 {
+ // Guaranteed underflow (assign 0).
+ fp.mant = 0;
+ true
+ } else if large_index as usize >= powers.large.len() {
+ // Overflow (assign infinity)
+ fp.mant = 1 << 63;
+ fp.exp = 0x7FF;
+ true
+ } else {
+ // Within the valid exponent range, multiply by the large and small
+ // exponents and return the resulting value.
+
+ // Track errors to as a factor of unit in last-precision.
+ let mut errors: u32 = 0;
+ if truncated {
+ errors += u64::error_halfscale();
+ }
+
+ // Multiply by the small power.
+ // Check if we can directly multiply by an integer, if not,
+ // use extended-precision multiplication.
+ match fp
+ .mant
+ .overflowing_mul(powers.get_small_int(small_index as usize))
+ {
+ // Overflow, multiplication unsuccessful, go slow path.
+ (_, true) => {
+ fp.normalize();
+ fp.imul(&powers.get_small(small_index as usize));
+ errors += u64::error_halfscale();
+ }
+ // No overflow, multiplication successful.
+ (mant, false) => {
+ fp.mant = mant;
+ fp.normalize();
+ }
+ }
+
+ // Multiply by the large power
+ fp.imul(&powers.get_large(large_index as usize));
+ if errors > 0 {
+ errors += 1;
+ }
+ errors += u64::error_halfscale();
+
+ // Normalize the floating point (and the errors).
+ let shift = fp.normalize();
+ errors <<= shift;
+
+ u64::error_is_accurate::<F>(errors, fp)
+ }
+}
+
+/// Create a precise native float using an intermediate extended-precision float.
+///
+/// Return the float approximation and if the value can be accurately
+/// represented with mantissa bits of precision.
+#[inline]
+pub(crate) fn moderate_path<F>(
+ mantissa: u64,
+ exponent: i32,
+ truncated: bool,
+) -> (ExtendedFloat, bool)
+where
+ F: Float,
+{
+ let mut fp = ExtendedFloat {
+ mant: mantissa,
+ exp: 0,
+ };
+ let valid = multiply_exponent_extended::<F>(&mut fp, exponent, truncated);
+ (fp, valid)
+}
+
+// FALLBACK
+// --------
+
+/// Fallback path when the fast path does not work.
+///
+/// Uses the moderate path, if applicable, otherwise, uses the slow path
+/// as required.
+pub(crate) fn fallback_path<F>(
+ integer: &[u8],
+ fraction: &[u8],
+ mantissa: u64,
+ exponent: i32,
+ mantissa_exponent: i32,
+ truncated: bool,
+) -> F
+where
+ F: Float,
+{
+ // Moderate path (use an extended 80-bit representation).
+ let (fp, valid) = moderate_path::<F>(mantissa, mantissa_exponent, truncated);
+ if valid {
+ return fp.into_float::<F>();
+ }
+
+ // Slow path, fast path didn't work.
+ let b = fp.into_downward_float::<F>();
+ if b.is_special() {
+ // We have a non-finite number, we get to leave early.
+ b
+ } else {
+ bhcomp(b, integer, fraction, exponent)
+ }
+}
diff --git a/third_party/rust/serde_json/src/lexical/bhcomp.rs b/third_party/rust/serde_json/src/lexical/bhcomp.rs
new file mode 100644
index 0000000000..1f2a7bbdee
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/bhcomp.rs
@@ -0,0 +1,218 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Compare the mantissa to the halfway representation of the float.
+//!
+//! Compares the actual significant digits of the mantissa to the
+//! theoretical digits from `b+h`, scaled into the proper range.
+
+use super::bignum::*;
+use super::digit::*;
+use super::exponent::*;
+use super::float::*;
+use super::math::*;
+use super::num::*;
+use super::rounding::*;
+use core::{cmp, mem};
+
+// MANTISSA
+
+/// Parse the full mantissa into a big integer.
+///
+/// Max digits is the maximum number of digits plus one.
+fn parse_mantissa<F>(integer: &[u8], fraction: &[u8]) -> Bigint
+where
+ F: Float,
+{
+ // Main loop
+ let small_powers = POW10_LIMB;
+ let step = small_powers.len() - 2;
+ let max_digits = F::MAX_DIGITS - 1;
+ let mut counter = 0;
+ let mut value: Limb = 0;
+ let mut i: usize = 0;
+ let mut result = Bigint::default();
+
+ // Iteratively process all the data in the mantissa.
+ for &digit in integer.iter().chain(fraction) {
+ // We've parsed the max digits using small values, add to bignum
+ if counter == step {
+ result.imul_small(small_powers[counter]);
+ result.iadd_small(value);
+ counter = 0;
+ value = 0;
+ }
+
+ value *= 10;
+ value += as_limb(to_digit(digit).unwrap());
+
+ i += 1;
+ counter += 1;
+ if i == max_digits {
+ break;
+ }
+ }
+
+ // We will always have a remainder, as long as we entered the loop
+ // once, or counter % step is 0.
+ if counter != 0 {
+ result.imul_small(small_powers[counter]);
+ result.iadd_small(value);
+ }
+
+ // If we have any remaining digits after the last value, we need
+ // to add a 1 after the rest of the array, it doesn't matter where,
+ // just move it up. This is good for the worst-possible float
+ // representation. We also need to return an index.
+ // Since we already trimmed trailing zeros, we know there has
+ // to be a non-zero digit if there are any left.
+ if i < integer.len() + fraction.len() {
+ result.imul_small(10);
+ result.iadd_small(1);
+ }
+
+ result
+}
+
+// FLOAT OPS
+
+/// Calculate `b` from a a representation of `b` as a float.
+#[inline]
+pub(super) fn b_extended<F: Float>(f: F) -> ExtendedFloat {
+ ExtendedFloat::from_float(f)
+}
+
+/// Calculate `b+h` from a a representation of `b` as a float.
+#[inline]
+pub(super) fn bh_extended<F: Float>(f: F) -> ExtendedFloat {
+ // None of these can overflow.
+ let b = b_extended(f);
+ ExtendedFloat {
+ mant: (b.mant << 1) + 1,
+ exp: b.exp - 1,
+ }
+}
+
+// ROUNDING
+
+/// Custom round-nearest, tie-event algorithm for bhcomp.
+#[inline]
+fn round_nearest_tie_even(fp: &mut ExtendedFloat, shift: i32, is_truncated: bool) {
+ let (mut is_above, mut is_halfway) = round_nearest(fp, shift);
+ if is_halfway && is_truncated {
+ is_above = true;
+ is_halfway = false;
+ }
+ tie_even(fp, is_above, is_halfway);
+}
+
+// BHCOMP
+
+/// Calculate the mantissa for a big integer with a positive exponent.
+fn large_atof<F>(mantissa: Bigint, exponent: i32) -> F
+where
+ F: Float,
+{
+ let bits = mem::size_of::<u64>() * 8;
+
+ // Simple, we just need to multiply by the power of the radix.
+ // Now, we can calculate the mantissa and the exponent from this.
+ // The binary exponent is the binary exponent for the mantissa
+ // shifted to the hidden bit.
+ let mut bigmant = mantissa;
+ bigmant.imul_pow10(exponent as u32);
+
+ // Get the exact representation of the float from the big integer.
+ let (mant, is_truncated) = bigmant.hi64();
+ let exp = bigmant.bit_length() as i32 - bits as i32;
+ let mut fp = ExtendedFloat { mant, exp };
+ fp.round_to_native::<F, _>(|fp, shift| round_nearest_tie_even(fp, shift, is_truncated));
+ into_float(fp)
+}
+
+/// Calculate the mantissa for a big integer with a negative exponent.
+///
+/// This invokes the comparison with `b+h`.
+fn small_atof<F>(mantissa: Bigint, exponent: i32, f: F) -> F
+where
+ F: Float,
+{
+ // Get the significant digits and radix exponent for the real digits.
+ let mut real_digits = mantissa;
+ let real_exp = exponent;
+ debug_assert!(real_exp < 0);
+
+ // Get the significant digits and the binary exponent for `b+h`.
+ let theor = bh_extended(f);
+ let mut theor_digits = Bigint::from_u64(theor.mant);
+ let theor_exp = theor.exp;
+
+ // We need to scale the real digits and `b+h` digits to be the same
+ // order. We currently have `real_exp`, in `radix`, that needs to be
+ // shifted to `theor_digits` (since it is negative), and `theor_exp`
+ // to either `theor_digits` or `real_digits` as a power of 2 (since it
+ // may be positive or negative). Try to remove as many powers of 2
+ // as possible. All values are relative to `theor_digits`, that is,
+ // reflect the power you need to multiply `theor_digits` by.
+
+ // Can remove a power-of-two, since the radix is 10.
+ // Both are on opposite-sides of equation, can factor out a
+ // power of two.
+ //
+ // Example: 10^-10, 2^-10 -> ( 0, 10, 0)
+ // Example: 10^-10, 2^-15 -> (-5, 10, 0)
+ // Example: 10^-10, 2^-5 -> ( 5, 10, 0)
+ // Example: 10^-10, 2^5 -> (15, 10, 0)
+ let binary_exp = theor_exp - real_exp;
+ let halfradix_exp = -real_exp;
+ let radix_exp = 0;
+
+ // Carry out our multiplication.
+ if halfradix_exp != 0 {
+ theor_digits.imul_pow5(halfradix_exp as u32);
+ }
+ if radix_exp != 0 {
+ theor_digits.imul_pow10(radix_exp as u32);
+ }
+ if binary_exp > 0 {
+ theor_digits.imul_pow2(binary_exp as u32);
+ } else if binary_exp < 0 {
+ real_digits.imul_pow2(-binary_exp as u32);
+ }
+
+ // Compare real digits to theoretical digits and round the float.
+ match real_digits.compare(&theor_digits) {
+ cmp::Ordering::Greater => f.next_positive(),
+ cmp::Ordering::Less => f,
+ cmp::Ordering::Equal => f.round_positive_even(),
+ }
+}
+
+/// Calculate the exact value of the float.
+///
+/// Note: fraction must not have trailing zeros.
+pub(crate) fn bhcomp<F>(b: F, integer: &[u8], mut fraction: &[u8], exponent: i32) -> F
+where
+ F: Float,
+{
+ // Calculate the number of integer digits and use that to determine
+ // where the significant digits start in the fraction.
+ let integer_digits = integer.len();
+ let fraction_digits = fraction.len();
+ let digits_start = if integer_digits == 0 {
+ let start = fraction.iter().take_while(|&x| *x == b'0').count();
+ fraction = &fraction[start..];
+ start
+ } else {
+ 0
+ };
+ let sci_exp = scientific_exponent(exponent, integer_digits, digits_start);
+ let count = F::MAX_DIGITS.min(integer_digits + fraction_digits - digits_start);
+ let scaled_exponent = sci_exp + 1 - count as i32;
+
+ let mantissa = parse_mantissa::<F>(integer, fraction);
+ if scaled_exponent >= 0 {
+ large_atof(mantissa, scaled_exponent)
+ } else {
+ small_atof(mantissa, scaled_exponent, b)
+ }
+}
diff --git a/third_party/rust/serde_json/src/lexical/bignum.rs b/third_party/rust/serde_json/src/lexical/bignum.rs
new file mode 100644
index 0000000000..f9551f534f
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/bignum.rs
@@ -0,0 +1,33 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Big integer type definition.
+
+use super::math::*;
+use alloc::vec::Vec;
+
+/// Storage for a big integer type.
+#[derive(Clone, PartialEq, Eq)]
+pub(crate) struct Bigint {
+ /// Internal storage for the Bigint, in little-endian order.
+ pub(crate) data: Vec<Limb>,
+}
+
+impl Default for Bigint {
+ fn default() -> Self {
+ Bigint {
+ data: Vec::with_capacity(20),
+ }
+ }
+}
+
+impl Math for Bigint {
+ #[inline]
+ fn data(&self) -> &Vec<Limb> {
+ &self.data
+ }
+
+ #[inline]
+ fn data_mut(&mut self) -> &mut Vec<Limb> {
+ &mut self.data
+ }
+}
diff --git a/third_party/rust/serde_json/src/lexical/cached.rs b/third_party/rust/serde_json/src/lexical/cached.rs
new file mode 100644
index 0000000000..ef5a9fe54d
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/cached.rs
@@ -0,0 +1,82 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Cached powers trait for extended-precision floats.
+
+use super::cached_float80;
+use super::float::ExtendedFloat;
+
+// POWERS
+
+/// Precalculated powers that uses two-separate arrays for memory-efficiency.
+#[doc(hidden)]
+pub(crate) struct ExtendedFloatArray {
+ // Pre-calculated mantissa for the powers.
+ pub mant: &'static [u64],
+ // Pre-calculated binary exponents for the powers.
+ pub exp: &'static [i32],
+}
+
+/// Allow indexing of values without bounds checking
+impl ExtendedFloatArray {
+ #[inline]
+ pub fn get_extended_float(&self, index: usize) -> ExtendedFloat {
+ let mant = self.mant[index];
+ let exp = self.exp[index];
+ ExtendedFloat { mant, exp }
+ }
+
+ #[inline]
+ pub fn len(&self) -> usize {
+ self.mant.len()
+ }
+}
+
+// MODERATE PATH POWERS
+
+/// Precalculated powers of base N for the moderate path.
+#[doc(hidden)]
+pub(crate) struct ModeratePathPowers {
+ // Pre-calculated small powers.
+ pub small: ExtendedFloatArray,
+ // Pre-calculated large powers.
+ pub large: ExtendedFloatArray,
+ /// Pre-calculated small powers as 64-bit integers
+ pub small_int: &'static [u64],
+ // Step between large powers and number of small powers.
+ pub step: i32,
+ // Exponent bias for the large powers.
+ pub bias: i32,
+}
+
+/// Allow indexing of values without bounds checking
+impl ModeratePathPowers {
+ #[inline]
+ pub fn get_small(&self, index: usize) -> ExtendedFloat {
+ self.small.get_extended_float(index)
+ }
+
+ #[inline]
+ pub fn get_large(&self, index: usize) -> ExtendedFloat {
+ self.large.get_extended_float(index)
+ }
+
+ #[inline]
+ pub fn get_small_int(&self, index: usize) -> u64 {
+ self.small_int[index]
+ }
+}
+
+// CACHED EXTENDED POWERS
+
+/// Cached powers as a trait for a floating-point type.
+pub(crate) trait ModeratePathCache {
+ /// Get cached powers.
+ fn get_powers() -> &'static ModeratePathPowers;
+}
+
+impl ModeratePathCache for ExtendedFloat {
+ #[inline]
+ fn get_powers() -> &'static ModeratePathPowers {
+ cached_float80::get_powers()
+ }
+}
diff --git a/third_party/rust/serde_json/src/lexical/cached_float80.rs b/third_party/rust/serde_json/src/lexical/cached_float80.rs
new file mode 100644
index 0000000000..9beda3ddb1
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/cached_float80.rs
@@ -0,0 +1,206 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Cached exponents for basen values with 80-bit extended floats.
+//!
+//! Exact versions of base**n as an extended-precision float, with both
+//! large and small powers. Use the large powers to minimize the amount
+//! of compounded error.
+//!
+//! These values were calculated using Python, using the arbitrary-precision
+//! integer to calculate exact extended-representation of each value.
+//! These values are all normalized.
+
+use super::cached::{ExtendedFloatArray, ModeratePathPowers};
+
+// LOW-LEVEL
+// ---------
+
+// BASE10
+
+const BASE10_SMALL_MANTISSA: [u64; 10] = [
+ 9223372036854775808, // 10^0
+ 11529215046068469760, // 10^1
+ 14411518807585587200, // 10^2
+ 18014398509481984000, // 10^3
+ 11258999068426240000, // 10^4
+ 14073748835532800000, // 10^5
+ 17592186044416000000, // 10^6
+ 10995116277760000000, // 10^7
+ 13743895347200000000, // 10^8
+ 17179869184000000000, // 10^9
+];
+const BASE10_SMALL_EXPONENT: [i32; 10] = [
+ -63, // 10^0
+ -60, // 10^1
+ -57, // 10^2
+ -54, // 10^3
+ -50, // 10^4
+ -47, // 10^5
+ -44, // 10^6
+ -40, // 10^7
+ -37, // 10^8
+ -34, // 10^9
+];
+const BASE10_LARGE_MANTISSA: [u64; 66] = [
+ 11555125961253852697, // 10^-350
+ 13451937075301367670, // 10^-340
+ 15660115838168849784, // 10^-330
+ 18230774251475056848, // 10^-320
+ 10611707258198326947, // 10^-310
+ 12353653155963782858, // 10^-300
+ 14381545078898527261, // 10^-290
+ 16742321987285426889, // 10^-280
+ 9745314011399999080, // 10^-270
+ 11345038669416679861, // 10^-260
+ 13207363278391631158, // 10^-250
+ 15375394465392026070, // 10^-240
+ 17899314949046850752, // 10^-230
+ 10418772551374772303, // 10^-220
+ 12129047596099288555, // 10^-210
+ 14120069793541087484, // 10^-200
+ 16437924692338667210, // 10^-190
+ 9568131466127621947, // 10^-180
+ 11138771039116687545, // 10^-170
+ 12967236152753102995, // 10^-160
+ 15095849699286165408, // 10^-150
+ 17573882009934360870, // 10^-140
+ 10229345649675443343, // 10^-130
+ 11908525658859223294, // 10^-120
+ 13863348470604074297, // 10^-110
+ 16139061738043178685, // 10^-100
+ 9394170331095332911, // 10^-90
+ 10936253623915059621, // 10^-80
+ 12731474852090538039, // 10^-70
+ 14821387422376473014, // 10^-60
+ 17254365866976409468, // 10^-50
+ 10043362776618689222, // 10^-40
+ 11692013098647223345, // 10^-30
+ 13611294676837538538, // 10^-20
+ 15845632502852867518, // 10^-10
+ 9223372036854775808, // 10^0
+ 10737418240000000000, // 10^10
+ 12500000000000000000, // 10^20
+ 14551915228366851806, // 10^30
+ 16940658945086006781, // 10^40
+ 9860761315262647567, // 10^50
+ 11479437019748901445, // 10^60
+ 13363823550460978230, // 10^70
+ 15557538194652854267, // 10^80
+ 18111358157653424735, // 10^90
+ 10542197943230523224, // 10^100
+ 12272733663244316382, // 10^110
+ 14287342391028437277, // 10^120
+ 16632655625031838749, // 10^130
+ 9681479787123295682, // 10^140
+ 11270725851789228247, // 10^150
+ 13120851772591970218, // 10^160
+ 15274681817498023410, // 10^170
+ 17782069995880619867, // 10^180
+ 10350527006597618960, // 10^190
+ 12049599325514420588, // 10^200
+ 14027579833653779454, // 10^210
+ 16330252207878254650, // 10^220
+ 9505457831475799117, // 10^230
+ 11065809325636130661, // 10^240
+ 12882297539194266616, // 10^250
+ 14996968138956309548, // 10^260
+ 17458768723248864463, // 10^270
+ 10162340898095201970, // 10^280
+ 11830521861667747109, // 10^290
+ 13772540099066387756, // 10^300
+];
+const BASE10_LARGE_EXPONENT: [i32; 66] = [
+ -1226, // 10^-350
+ -1193, // 10^-340
+ -1160, // 10^-330
+ -1127, // 10^-320
+ -1093, // 10^-310
+ -1060, // 10^-300
+ -1027, // 10^-290
+ -994, // 10^-280
+ -960, // 10^-270
+ -927, // 10^-260
+ -894, // 10^-250
+ -861, // 10^-240
+ -828, // 10^-230
+ -794, // 10^-220
+ -761, // 10^-210
+ -728, // 10^-200
+ -695, // 10^-190
+ -661, // 10^-180
+ -628, // 10^-170
+ -595, // 10^-160
+ -562, // 10^-150
+ -529, // 10^-140
+ -495, // 10^-130
+ -462, // 10^-120
+ -429, // 10^-110
+ -396, // 10^-100
+ -362, // 10^-90
+ -329, // 10^-80
+ -296, // 10^-70
+ -263, // 10^-60
+ -230, // 10^-50
+ -196, // 10^-40
+ -163, // 10^-30
+ -130, // 10^-20
+ -97, // 10^-10
+ -63, // 10^0
+ -30, // 10^10
+ 3, // 10^20
+ 36, // 10^30
+ 69, // 10^40
+ 103, // 10^50
+ 136, // 10^60
+ 169, // 10^70
+ 202, // 10^80
+ 235, // 10^90
+ 269, // 10^100
+ 302, // 10^110
+ 335, // 10^120
+ 368, // 10^130
+ 402, // 10^140
+ 435, // 10^150
+ 468, // 10^160
+ 501, // 10^170
+ 534, // 10^180
+ 568, // 10^190
+ 601, // 10^200
+ 634, // 10^210
+ 667, // 10^220
+ 701, // 10^230
+ 734, // 10^240
+ 767, // 10^250
+ 800, // 10^260
+ 833, // 10^270
+ 867, // 10^280
+ 900, // 10^290
+ 933, // 10^300
+];
+const BASE10_SMALL_INT_POWERS: [u64; 10] = [
+ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
+];
+const BASE10_STEP: i32 = 10;
+const BASE10_BIAS: i32 = 350;
+
+// HIGH LEVEL
+// ----------
+
+const BASE10_POWERS: ModeratePathPowers = ModeratePathPowers {
+ small: ExtendedFloatArray {
+ mant: &BASE10_SMALL_MANTISSA,
+ exp: &BASE10_SMALL_EXPONENT,
+ },
+ large: ExtendedFloatArray {
+ mant: &BASE10_LARGE_MANTISSA,
+ exp: &BASE10_LARGE_EXPONENT,
+ },
+ small_int: &BASE10_SMALL_INT_POWERS,
+ step: BASE10_STEP,
+ bias: BASE10_BIAS,
+};
+
+/// Get powers from base.
+pub(crate) fn get_powers() -> &'static ModeratePathPowers {
+ &BASE10_POWERS
+}
diff --git a/third_party/rust/serde_json/src/lexical/digit.rs b/third_party/rust/serde_json/src/lexical/digit.rs
new file mode 100644
index 0000000000..882aa9eef2
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/digit.rs
@@ -0,0 +1,15 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Helpers to convert and add digits from characters.
+
+// Convert u8 to digit.
+#[inline]
+pub(crate) fn to_digit(c: u8) -> Option<u32> {
+ (c as char).to_digit(10)
+}
+
+// Add digit to mantissa.
+#[inline]
+pub(crate) fn add_digit(value: u64, digit: u32) -> Option<u64> {
+ value.checked_mul(10)?.checked_add(digit as u64)
+}
diff --git a/third_party/rust/serde_json/src/lexical/errors.rs b/third_party/rust/serde_json/src/lexical/errors.rs
new file mode 100644
index 0000000000..cad4bd3d58
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/errors.rs
@@ -0,0 +1,133 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Estimate the error in an 80-bit approximation of a float.
+//!
+//! This estimates the error in a floating-point representation.
+//!
+//! This implementation is loosely based off the Golang implementation,
+//! found here:
+//! https://golang.org/src/strconv/atof.go
+
+use super::float::*;
+use super::num::*;
+use super::rounding::*;
+
+pub(crate) trait FloatErrors {
+ /// Get the full error scale.
+ fn error_scale() -> u32;
+ /// Get the half error scale.
+ fn error_halfscale() -> u32;
+ /// Determine if the number of errors is tolerable for float precision.
+ fn error_is_accurate<F: Float>(count: u32, fp: &ExtendedFloat) -> bool;
+}
+
+/// Check if the error is accurate with a round-nearest rounding scheme.
+#[inline]
+fn nearest_error_is_accurate(errors: u64, fp: &ExtendedFloat, extrabits: u64) -> bool {
+ // Round-to-nearest, need to use the halfway point.
+ if extrabits == 65 {
+ // Underflow, we have a shift larger than the mantissa.
+ // Representation is valid **only** if the value is close enough
+ // overflow to the next bit within errors. If it overflows,
+ // the representation is **not** valid.
+ !fp.mant.overflowing_add(errors).1
+ } else {
+ let mask: u64 = lower_n_mask(extrabits);
+ let extra: u64 = fp.mant & mask;
+
+ // Round-to-nearest, need to check if we're close to halfway.
+ // IE, b10100 | 100000, where `|` signifies the truncation point.
+ let halfway: u64 = lower_n_halfway(extrabits);
+ let cmp1 = halfway.wrapping_sub(errors) < extra;
+ let cmp2 = extra < halfway.wrapping_add(errors);
+
+ // If both comparisons are true, we have significant rounding error,
+ // and the value cannot be exactly represented. Otherwise, the
+ // representation is valid.
+ !(cmp1 && cmp2)
+ }
+}
+
+impl FloatErrors for u64 {
+ #[inline]
+ fn error_scale() -> u32 {
+ 8
+ }
+
+ #[inline]
+ fn error_halfscale() -> u32 {
+ u64::error_scale() / 2
+ }
+
+ #[inline]
+ fn error_is_accurate<F: Float>(count: u32, fp: &ExtendedFloat) -> bool {
+ // Determine if extended-precision float is a good approximation.
+ // If the error has affected too many units, the float will be
+ // inaccurate, or if the representation is too close to halfway
+ // that any operations could affect this halfway representation.
+ // See the documentation for dtoa for more information.
+ let bias = -(F::EXPONENT_BIAS - F::MANTISSA_SIZE);
+ let denormal_exp = bias - 63;
+ // This is always a valid u32, since (denormal_exp - fp.exp)
+ // will always be positive and the significand size is {23, 52}.
+ let extrabits = if fp.exp <= denormal_exp {
+ 64 - F::MANTISSA_SIZE + denormal_exp - fp.exp
+ } else {
+ 63 - F::MANTISSA_SIZE
+ };
+
+ // Our logic is as follows: we want to determine if the actual
+ // mantissa and the errors during calculation differ significantly
+ // from the rounding point. The rounding point for round-nearest
+ // is the halfway point, IE, this when the truncated bits start
+ // with b1000..., while the rounding point for the round-toward
+ // is when the truncated bits are equal to 0.
+ // To do so, we can check whether the rounding point +/- the error
+ // are >/< the actual lower n bits.
+ //
+ // For whether we need to use signed or unsigned types for this
+ // analysis, see this example, using u8 rather than u64 to simplify
+ // things.
+ //
+ // # Comparisons
+ // cmp1 = (halfway - errors) < extra
+ // cmp1 = extra < (halfway + errors)
+ //
+ // # Large Extrabits, Low Errors
+ //
+ // extrabits = 8
+ // halfway = 0b10000000
+ // extra = 0b10000010
+ // errors = 0b00000100
+ // halfway - errors = 0b01111100
+ // halfway + errors = 0b10000100
+ //
+ // Unsigned:
+ // halfway - errors = 124
+ // halfway + errors = 132
+ // extra = 130
+ // cmp1 = true
+ // cmp2 = true
+ // Signed:
+ // halfway - errors = 124
+ // halfway + errors = -124
+ // extra = -126
+ // cmp1 = false
+ // cmp2 = true
+ //
+ // # Conclusion
+ //
+ // Since errors will always be small, and since we want to detect
+ // if the representation is accurate, we need to use an **unsigned**
+ // type for comparisons.
+
+ let extrabits = extrabits as u64;
+ let errors = count as u64;
+ if extrabits > 65 {
+ // Underflow, we have a literal 0.
+ return true;
+ }
+
+ nearest_error_is_accurate(errors, fp, extrabits)
+ }
+}
diff --git a/third_party/rust/serde_json/src/lexical/exponent.rs b/third_party/rust/serde_json/src/lexical/exponent.rs
new file mode 100644
index 0000000000..6fc51977ed
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/exponent.rs
@@ -0,0 +1,50 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Utilities to calculate exponents.
+
+/// Convert usize into i32 without overflow.
+///
+/// This is needed to ensure when adjusting the exponent relative to
+/// the mantissa we do not overflow for comically-long exponents.
+#[inline]
+fn into_i32(value: usize) -> i32 {
+ if value > i32::max_value() as usize {
+ i32::max_value()
+ } else {
+ value as i32
+ }
+}
+
+// EXPONENT CALCULATION
+
+// Calculate the scientific notation exponent without overflow.
+//
+// For example, 0.1 would be -1, and 10 would be 1 in base 10.
+#[inline]
+pub(crate) fn scientific_exponent(
+ exponent: i32,
+ integer_digits: usize,
+ fraction_start: usize,
+) -> i32 {
+ if integer_digits == 0 {
+ let fraction_start = into_i32(fraction_start);
+ exponent.saturating_sub(fraction_start).saturating_sub(1)
+ } else {
+ let integer_shift = into_i32(integer_digits - 1);
+ exponent.saturating_add(integer_shift)
+ }
+}
+
+// Calculate the mantissa exponent without overflow.
+//
+// Remove the number of digits that contributed to the mantissa past
+// the dot, and add the number of truncated digits from the mantissa,
+// to calculate the scaling factor for the mantissa from a raw exponent.
+#[inline]
+pub(crate) fn mantissa_exponent(exponent: i32, fraction_digits: usize, truncated: usize) -> i32 {
+ if fraction_digits > truncated {
+ exponent.saturating_sub(into_i32(fraction_digits - truncated))
+ } else {
+ exponent.saturating_add(into_i32(truncated - fraction_digits))
+ }
+}
diff --git a/third_party/rust/serde_json/src/lexical/float.rs b/third_party/rust/serde_json/src/lexical/float.rs
new file mode 100644
index 0000000000..2d434a29cb
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/float.rs
@@ -0,0 +1,183 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+// FLOAT TYPE
+
+use super::num::*;
+use super::rounding::*;
+use super::shift::*;
+
+/// Extended precision floating-point type.
+///
+/// Private implementation, exposed only for testing purposes.
+#[doc(hidden)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq)]
+pub(crate) struct ExtendedFloat {
+ /// Mantissa for the extended-precision float.
+ pub mant: u64,
+ /// Binary exponent for the extended-precision float.
+ pub exp: i32,
+}
+
+impl ExtendedFloat {
+ // PROPERTIES
+
+ // OPERATIONS
+
+ /// Multiply two normalized extended-precision floats, as if by `a*b`.
+ ///
+ /// The precision is maximal when the numbers are normalized, however,
+ /// decent precision will occur as long as both values have high bits
+ /// set. The result is not normalized.
+ ///
+ /// Algorithm:
+ /// 1. Non-signed multiplication of mantissas (requires 2x as many bits as input).
+ /// 2. Normalization of the result (not done here).
+ /// 3. Addition of exponents.
+ pub(crate) fn mul(&self, b: &ExtendedFloat) -> ExtendedFloat {
+ // Logic check, values must be decently normalized prior to multiplication.
+ debug_assert!((self.mant & u64::HIMASK != 0) && (b.mant & u64::HIMASK != 0));
+
+ // Extract high-and-low masks.
+ let ah = self.mant >> u64::HALF;
+ let al = self.mant & u64::LOMASK;
+ let bh = b.mant >> u64::HALF;
+ let bl = b.mant & u64::LOMASK;
+
+ // Get our products
+ let ah_bl = ah * bl;
+ let al_bh = al * bh;
+ let al_bl = al * bl;
+ let ah_bh = ah * bh;
+
+ let mut tmp = (ah_bl & u64::LOMASK) + (al_bh & u64::LOMASK) + (al_bl >> u64::HALF);
+ // round up
+ tmp += 1 << (u64::HALF - 1);
+
+ ExtendedFloat {
+ mant: ah_bh + (ah_bl >> u64::HALF) + (al_bh >> u64::HALF) + (tmp >> u64::HALF),
+ exp: self.exp + b.exp + u64::FULL,
+ }
+ }
+
+ /// Multiply in-place, as if by `a*b`.
+ ///
+ /// The result is not normalized.
+ #[inline]
+ pub(crate) fn imul(&mut self, b: &ExtendedFloat) {
+ *self = self.mul(b);
+ }
+
+ // NORMALIZE
+
+ /// Normalize float-point number.
+ ///
+ /// Shift the mantissa so the number of leading zeros is 0, or the value
+ /// itself is 0.
+ ///
+ /// Get the number of bytes shifted.
+ #[inline]
+ pub(crate) fn normalize(&mut self) -> u32 {
+ // Note:
+ // Using the cltz intrinsic via leading_zeros is way faster (~10x)
+ // than shifting 1-bit at a time, via while loop, and also way
+ // faster (~2x) than an unrolled loop that checks at 32, 16, 4,
+ // 2, and 1 bit.
+ //
+ // Using a modulus of pow2 (which will get optimized to a bitwise
+ // and with 0x3F or faster) is slightly slower than an if/then,
+ // however, removing the if/then will likely optimize more branched
+ // code as it removes conditional logic.
+
+ // Calculate the number of leading zeros, and then zero-out
+ // any overflowing bits, to avoid shl overflow when self.mant == 0.
+ let shift = if self.mant == 0 {
+ 0
+ } else {
+ self.mant.leading_zeros()
+ };
+ shl(self, shift as i32);
+ shift
+ }
+
+ // ROUND
+
+ /// Lossy round float-point number to native mantissa boundaries.
+ #[inline]
+ pub(crate) fn round_to_native<F, Algorithm>(&mut self, algorithm: Algorithm)
+ where
+ F: Float,
+ Algorithm: FnOnce(&mut ExtendedFloat, i32),
+ {
+ round_to_native::<F, _>(self, algorithm);
+ }
+
+ // FROM
+
+ /// Create extended float from native float.
+ #[inline]
+ pub fn from_float<F: Float>(f: F) -> ExtendedFloat {
+ from_float(f)
+ }
+
+ // INTO
+
+ /// Convert into default-rounded, lower-precision native float.
+ #[inline]
+ pub(crate) fn into_float<F: Float>(mut self) -> F {
+ self.round_to_native::<F, _>(round_nearest_tie_even);
+ into_float(self)
+ }
+
+ /// Convert into downward-rounded, lower-precision native float.
+ #[inline]
+ pub(crate) fn into_downward_float<F: Float>(mut self) -> F {
+ self.round_to_native::<F, _>(round_downward);
+ into_float(self)
+ }
+}
+
+// FROM FLOAT
+
+// Import ExtendedFloat from native float.
+#[inline]
+pub(crate) fn from_float<F>(f: F) -> ExtendedFloat
+where
+ F: Float,
+{
+ ExtendedFloat {
+ mant: u64::as_cast(f.mantissa()),
+ exp: f.exponent(),
+ }
+}
+
+// INTO FLOAT
+
+// Export extended-precision float to native float.
+//
+// The extended-precision float must be in native float representation,
+// with overflow/underflow appropriately handled.
+#[inline]
+pub(crate) fn into_float<F>(fp: ExtendedFloat) -> F
+where
+ F: Float,
+{
+ // Export floating-point number.
+ if fp.mant == 0 || fp.exp < F::DENORMAL_EXPONENT {
+ // sub-denormal, underflow
+ F::ZERO
+ } else if fp.exp >= F::MAX_EXPONENT {
+ // overflow
+ F::from_bits(F::INFINITY_BITS)
+ } else {
+ // calculate the exp and fraction bits, and return a float from bits.
+ let exp: u64;
+ if (fp.exp == F::DENORMAL_EXPONENT) && (fp.mant & F::HIDDEN_BIT_MASK.as_u64()) == 0 {
+ exp = 0;
+ } else {
+ exp = (fp.exp + F::EXPONENT_BIAS) as u64;
+ }
+ let exp = exp << F::MANTISSA_SIZE;
+ let mant = fp.mant & F::MANTISSA_MASK.as_u64();
+ F::from_bits(F::Unsigned::as_cast(mant | exp))
+ }
+}
diff --git a/third_party/rust/serde_json/src/lexical/large_powers.rs b/third_party/rust/serde_json/src/lexical/large_powers.rs
new file mode 100644
index 0000000000..c63ce1cf21
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/large_powers.rs
@@ -0,0 +1,9 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Precalculated large powers for limbs.
+
+#[cfg(limb_width_32)]
+pub(crate) use super::large_powers32::*;
+
+#[cfg(limb_width_64)]
+pub(crate) use super::large_powers64::*;
diff --git a/third_party/rust/serde_json/src/lexical/large_powers32.rs b/third_party/rust/serde_json/src/lexical/large_powers32.rs
new file mode 100644
index 0000000000..7991197262
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/large_powers32.rs
@@ -0,0 +1,183 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Precalculated large powers for 32-bit limbs.
+
+/// Large powers (&[u32]) for base5 operations.
+const POW5_1: [u32; 1] = [5];
+const POW5_2: [u32; 1] = [25];
+const POW5_3: [u32; 1] = [625];
+const POW5_4: [u32; 1] = [390625];
+const POW5_5: [u32; 2] = [2264035265, 35];
+const POW5_6: [u32; 3] = [2242703233, 762134875, 1262];
+const POW5_7: [u32; 5] = [3211403009, 1849224548, 3668416493, 3913284084, 1593091];
+const POW5_8: [u32; 10] = [
+ 781532673, 64985353, 253049085, 594863151, 3553621484, 3288652808, 3167596762, 2788392729,
+ 3911132675, 590,
+];
+const POW5_9: [u32; 19] = [
+ 2553183233, 3201533787, 3638140786, 303378311, 1809731782, 3477761648, 3583367183, 649228654,
+ 2915460784, 487929380, 1011012442, 1677677582, 3428152256, 1710878487, 1438394610, 2161952759,
+ 4100910556, 1608314830, 349175,
+];
+const POW5_10: [u32; 38] = [
+ 4234999809, 2012377703, 2408924892, 1570150255, 3090844311, 3273530073, 1187251475, 2498123591,
+ 3364452033, 1148564857, 687371067, 2854068671, 1883165473, 505794538, 2988060450, 3159489326,
+ 2531348317, 3215191468, 849106862, 3892080979, 3288073877, 2242451748, 4183778142, 2995818208,
+ 2477501924, 325481258, 2487842652, 1774082830, 1933815724, 2962865281, 1168579910, 2724829000,
+ 2360374019, 2315984659, 2360052375, 3251779801, 1664357844, 28,
+];
+const POW5_11: [u32; 75] = [
+ 689565697, 4116392818, 1853628763, 516071302, 2568769159, 365238920, 336250165, 1283268122,
+ 3425490969, 248595470, 2305176814, 2111925499, 507770399, 2681111421, 589114268, 591287751,
+ 1708941527, 4098957707, 475844916, 3378731398, 2452339615, 2817037361, 2678008327, 1656645978,
+ 2383430340, 73103988, 448667107, 2329420453, 3124020241, 3625235717, 3208634035, 2412059158,
+ 2981664444, 4117622508, 838560765, 3069470027, 270153238, 1802868219, 3692709886, 2161737865,
+ 2159912357, 2585798786, 837488486, 4237238160, 2540319504, 3798629246, 3748148874, 1021550776,
+ 2386715342, 1973637538, 1823520457, 1146713475, 833971519, 3277251466, 905620390, 26278816,
+ 2680483154, 2294040859, 373297482, 5996609, 4109575006, 512575049, 917036550, 1942311753,
+ 2816916778, 3248920332, 1192784020, 3537586671, 2456567643, 2925660628, 759380297, 888447942,
+ 3559939476, 3654687237, 805,
+];
+const POW5_12: [u32; 149] = [
+ 322166785, 3809044581, 2994556223, 1239584207, 3962455841, 4001882964, 3053876612, 915114683,
+ 2783289745, 785739093, 4253185907, 3931164994, 1370983858, 2553556126, 3360742076, 2255410929,
+ 422849554, 2457422215, 3539495362, 1720790602, 1908931983, 1470596141, 592794347, 4219465164,
+ 4085652704, 941661409, 2534650953, 885063988, 2355909854, 2812815516, 767256131, 3821757683,
+ 2155151105, 3817418473, 281116564, 2834395026, 2821201622, 2524625843, 1511330880, 2572352493,
+ 330571332, 2951088579, 2730271766, 4044456479, 4212286644, 2444937588, 3603420843, 2387148597,
+ 1142537539, 3299235429, 1751012624, 861228086, 2873722519, 230498814, 1023297821, 2553128038,
+ 3421129895, 2651917435, 2042981258, 1606787143, 2228751918, 447345732, 1930371132, 1784132011,
+ 3612538790, 2275925090, 2487567871, 1080427616, 2009179183, 3383506781, 3899054063, 1950782960,
+ 2168622213, 2717674390, 3616636027, 2079341593, 1530129217, 1461057425, 2406264415, 3674671357,
+ 2972036238, 2019354295, 1455849819, 1866918619, 1324269294, 424891864, 2722422332, 2641594816,
+ 1400249021, 3482963993, 3734946379, 225889849, 1891545473, 777383150, 3589824633, 4117601611,
+ 4220028667, 334453379, 1083130821, 1060342180, 4208163139, 1489826908, 4163762246, 1096580926,
+ 689301528, 2336054516, 1782865703, 4175148410, 3398369392, 2329412588, 3001580596, 59740741,
+ 3202189932, 3351895776, 246185302, 718535188, 3772647488, 4151666556, 4055698133, 2461934110,
+ 2281316281, 3466396836, 3536023465, 1064267812, 2955456354, 2423805422, 3627960790, 1325057500,
+ 3876919979, 2009959531, 175455101, 184092852, 2358785571, 3842977831, 2485266289, 487121622,
+ 4159252710, 4075707558, 459389244, 300652075, 2521346588, 3458976673, 888631636, 2076098096,
+ 3844514585, 2363697580, 3729421522, 3051115477, 649395,
+];
+const POW5_13: [u32; 298] = [
+ 711442433, 3564261005, 2399042279, 4170849936, 4010295575, 1423987028, 330414929, 1349249065,
+ 4213813618, 3852031822, 4040843590, 2154565331, 3094013374, 1159028371, 3227065538, 2115927092,
+ 2085102554, 488590542, 2609619432, 3602898805, 3812736528, 3269439096, 23816114, 253984538,
+ 1035905997, 2942969204, 3400787671, 338562688, 1637191975, 740509713, 2264962817, 3410753922,
+ 4162231428, 2282041228, 1759373012, 3155367777, 4278913285, 1420532801, 1981002276, 438054990,
+ 1006507643, 1142697287, 1332538012, 2029019521, 3949305784, 818392641, 2491288846, 2716584663,
+ 3648886102, 556814413, 444795339, 4071412999, 1066321706, 4253169466, 2510832316, 672091442,
+ 4083256000, 2165985028, 1841538484, 3549854235, 364431512, 3707648143, 1162785440, 2268641545,
+ 281340310, 735693841, 848809228, 1700785200, 2919703985, 4094234344, 58530286, 965505005,
+ 1000010347, 3381961808, 3040089923, 1973852082, 2890971585, 1019960210, 4292895237, 2821887841,
+ 3756675650, 3951282907, 3885870583, 1008791145, 503998487, 1881258362, 1949332730, 392996726,
+ 2012973814, 3970014187, 2461725150, 2942547730, 3728066699, 2766901132, 3778532841, 1085564064,
+ 2278673896, 1116879805, 3448726271, 774279411, 157211670, 1506320155, 531168605, 1362654525,
+ 956967721, 2148871960, 769186085, 4186232894, 2055679604, 3248365487, 3981268013, 3975787984,
+ 2489510517, 3309046495, 212771124, 933418041, 3371839114, 562115198, 1853601831, 757336096,
+ 1354633440, 1486083256, 2872126393, 522920738, 1141587749, 3210903262, 1926940553, 3054024853,
+ 2021162538, 2262742000, 1877899947, 3147002868, 669840763, 4158174590, 4238502559, 1023731922,
+ 3386840011, 829588074, 3449720188, 2835142880, 2999162007, 813056473, 482949569, 638108879,
+ 3067201471, 1026714238, 4004452838, 2383667807, 3999477803, 771648919, 630660440, 3827121348,
+ 176185980, 2878191002, 2666149832, 3909811063, 2429163983, 2665690412, 907266128, 4269332098,
+ 2022665808, 1527122180, 3072053668, 1072477492, 3006022924, 549664855, 2800340954, 37352654,
+ 1212772743, 2711280533, 3029527946, 2511120040, 1305308377, 3474662224, 4226330922, 442988428,
+ 954940108, 3274548099, 4212288177, 2688499880, 3982226758, 3922609956, 1279948029, 1939943640,
+ 3650489901, 2733364929, 2494263275, 1864579964, 1225941120, 2390465139, 1267503249, 3533240729,
+ 904410805, 2842550015, 2517736241, 1796069820, 3335274381, 673539835, 1924694759, 3598098235,
+ 2792633405, 16535707, 3703535497, 3592841791, 2929082877, 1317622811, 294990855, 1396706563,
+ 2383271770, 3853857605, 277813677, 277580220, 1101318484, 3761974115, 1132150143, 2544692622,
+ 3419825776, 743770306, 1695464553, 1548693232, 2421159615, 2575672031, 2678971806, 1591267897,
+ 626546738, 3823443129, 267710932, 1455435162, 2353985540, 3248523795, 335348168, 3872552561,
+ 2814522612, 2634118860, 3503767026, 1301019273, 1414467789, 722985138, 3070909565, 4253482569,
+ 3744939841, 558142907, 2229819389, 13833173, 77003966, 2763671364, 3905603970, 2931990126,
+ 2280419384, 1879090457, 2934846267, 4284933164, 2331863845, 62191163, 3178861020, 1522063815,
+ 785672270, 1215568492, 2936443917, 802972489, 2956820173, 3916732783, 2893572089, 1391232801,
+ 3168640330, 2396859648, 894950918, 1103583736, 961991865, 2807302642, 305977505, 3054505899,
+ 1048256994, 781017659, 2459278754, 3164823415, 537658277, 905753687, 464963300, 4149131560,
+ 1029507924, 2278300961, 1231291503, 414073408, 3630740085, 2345841814, 475358196, 3258243317,
+ 4167625072, 4178911231, 2927355042, 655438830, 3138378018, 623200562, 2785714112, 273403236,
+ 807993669, 98,
+];
+const POW5_14: [u32; 595] = [
+ 1691320321, 2671006246, 1682531301, 2072858707, 1240508969, 3108358191, 1125119096, 2470144952,
+ 1610099978, 1690632660, 1941696884, 2663506355, 1006364675, 3909158537, 4147711374, 1072663936,
+ 4078768933, 745751659, 4123687570, 471458681, 655028926, 4113407388, 3945524552, 985625313,
+ 1254424514, 2127508744, 570530434, 945388122, 3194649404, 2589065070, 2731705399, 202030749,
+ 2090780394, 3348662271, 1481754777, 1130635472, 4025144705, 1924486271, 2578567861, 125491448,
+ 1558036315, 994248173, 3817216711, 763950077, 1030439870, 959586474, 3845661701, 483795093,
+ 1637944470, 2275463649, 3398804829, 1758016486, 2665513698, 2004912571, 1094885097, 4223064276,
+ 3307819021, 651121777, 1757003305, 3603542336, 129917786, 2215974994, 3042386306, 2205352757,
+ 3944939700, 3710987569, 97967515, 1217242524, 930630949, 3660328512, 1787663098, 1784141600,
+ 2500542892, 4034561586, 3444961378, 785043562, 3869499367, 885623728, 2625011087, 3053789617,
+ 1965731793, 3900511934, 2648823592, 3851062028, 3321968688, 799195417, 1011847510, 1369129160,
+ 1348009103, 2876796955, 2915408967, 3305284948, 263399535, 1715990604, 2645821294, 1587844552,
+ 2624912049, 3035631499, 2306636348, 3499275462, 675152704, 854794152, 4004972748, 1739996642,
+ 1333476491, 4012621867, 3658792931, 3297985728, 2864481726, 3066357406, 785287846, 1671499798,
+ 433044045, 1919608025, 264833858, 3999983367, 1116778570, 1301982149, 4213901070, 4081649357,
+ 536169226, 1389008649, 188923873, 373495152, 2551132278, 1800758715, 3951840330, 2632334454,
+ 3118778225, 1034046547, 1862428410, 3037609062, 1994608505, 29051798, 2571685694, 264151332,
+ 2260643090, 2717535964, 3508441116, 3283713017, 1903365635, 923575694, 1219598101, 2288281570,
+ 3676533911, 1014136356, 555142354, 2389170030, 4185108175, 884862419, 836141292, 2957159173,
+ 1997444768, 4233903127, 2876184692, 3089125070, 1480848293, 1097600237, 299700527, 2507669891,
+ 2982628312, 2114881043, 2529576251, 2812279824, 2987750993, 4241938954, 2204775591, 1037094060,
+ 829315638, 1231047149, 52608178, 3735136637, 3455232602, 962039123, 488286513, 50685385,
+ 3516451821, 843975207, 1572355722, 675489076, 2428445672, 1555117248, 3708476086, 10375249,
+ 4172112346, 2117510871, 2227658327, 3187664554, 3050656558, 328034318, 3179601324, 1247769761,
+ 3439263953, 1431538938, 2962525068, 1213366289, 3813013550, 2651093719, 1860661503, 3933716208,
+ 264320617, 789980519, 2257856172, 102000748, 977269860, 1113845122, 3008928583, 1461738106,
+ 557786285, 2926560363, 1038106190, 3643478847, 828004507, 457818698, 1933056971, 373408056,
+ 2076808229, 3160935130, 2781854874, 2519636100, 177606000, 4237103862, 3977834316, 1621936232,
+ 2599050516, 319893558, 3343370366, 765044144, 976657331, 7026264, 294277429, 3829376742,
+ 3029627280, 2705178718, 3614653880, 230519152, 3288033233, 293525479, 3805751881, 3227511198,
+ 2520308544, 3648103003, 1111086184, 437622105, 2232033852, 3239146386, 584244184, 1450926016,
+ 2462430443, 3226534010, 298582169, 4214576928, 1762099469, 964985185, 1585788148, 1641127666,
+ 787006566, 2315956284, 3258232694, 2275058964, 2541003317, 1508235863, 2613339827, 4080647514,
+ 1152057965, 3149266279, 731345410, 914737650, 65395712, 1884566942, 1379520432, 2611027720,
+ 4163073378, 2619704967, 2746552541, 1388822415, 3005141199, 843440249, 4288674003, 3136174279,
+ 4051522914, 4144149433, 3427566947, 3419023197, 3758479825, 3893877676, 96899594, 1657725776,
+ 253618880, 434129337, 1499045748, 2996992534, 4036042074, 2110713869, 906222950, 928326225,
+ 2541827893, 1604330202, 226792470, 4022228930, 815850898, 1466012310, 3377712199, 292769859,
+ 2822055597, 3225701344, 3052947004, 385831222, 705324593, 4030158636, 3540280538, 2982120874,
+ 2136414455, 255762046, 3852783591, 3262064164, 2358991588, 3756586117, 4143612643, 3326743817,
+ 2897365738, 807711264, 3719310016, 3721264861, 3627337076, 944539331, 3640975513, 3712525681,
+ 1162911839, 2008243316, 2179489649, 2867584109, 261861553, 3570253908, 2062868357, 2220328623,
+ 3857004679, 3744109002, 4138041873, 1451860932, 2364975637, 2802161722, 2680106834, 753401584,
+ 1223182946, 1245401957, 4163377735, 3565815922, 2216942838, 4036140094, 71979081, 3924559643,
+ 400477238, 551750683, 1174153235, 859969898, 1185921017, 1711399735, 812991545, 4051735761,
+ 3549118738, 1631653329, 3631835958, 3648867800, 1206500363, 2155893137, 361030362, 3454286017,
+ 2505909489, 1083595169, 453595313, 1510564703, 1706163902, 1632924345, 1381875722, 1661526119,
+ 1082778324, 3571910052, 1140625929, 851544870, 1145546234, 2938573139, 907528924, 1304752338,
+ 1764668294, 1788942063, 1700368828, 104979467, 1413911959, 3327497828, 1956384744, 1272712474,
+ 2815637534, 3307809377, 1320574940, 1111968962, 4073107827, 434096622, 169451929, 3201183459,
+ 3331028877, 2852366972, 3369830128, 2924794558, 3106537952, 3739481231, 1612955817, 4138608722,
+ 2721281595, 2755775390, 843505117, 982234295, 1157276611, 814674632, 4246504726, 3532006708,
+ 992340967, 1647538031, 204696133, 193866982, 3899126129, 300851698, 1379496684, 1759463683,
+ 1354782756, 1374637239, 3410883240, 1073406229, 3038431791, 1053909855, 3607043270, 173719711,
+ 3733903830, 171820911, 1573050589, 932781534, 4183534770, 2158849555, 372245998, 3573073830,
+ 841339264, 2759200520, 1610547277, 2603293319, 3890906486, 1557138278, 3964109906, 677238797,
+ 537994297, 1124184993, 4287078344, 4207654540, 2943022776, 2977947524, 3255359985, 4098397558,
+ 2274666217, 2915862060, 243524940, 2467726756, 2869020032, 507521339, 3403121914, 522051455,
+ 1803903108, 3471254194, 473535371, 1948602036, 3352095732, 3116527002, 1795743673, 775867940,
+ 2551469548, 3757442064, 3162525227, 3765412747, 3040105484, 1927625810, 48214767, 2997207130,
+ 1342349989, 2536583992, 1501320191, 3592287317, 887432730, 967585477, 3334212779, 948663609,
+ 1064513472, 15386372, 2465931737, 3230242590, 3036652803, 2063155087, 1927500726, 2821790499,
+ 2187774383, 501520074, 3688568496, 3606711121, 2576459247, 3176542345, 378322447, 156541411,
+ 1400607301, 1406179107, 677848877, 2253753529, 193196070, 4207435024, 4166396241, 509467541,
+ 2906024136, 1221753746, 3375413222, 431327897, 2749265123, 2848827671, 3412997614, 2051920238,
+ 1283516885, 1300498239, 1957256104, 2634010560, 3531900395, 360276850, 1461184973, 2012063967,
+ 2873572430, 2914608609, 4289554777, 1539331673, 1859532928, 4213441063, 538215691, 3512720863,
+ 4258743698, 3040408445, 982396546, 343095663, 4138069496, 1021581857, 214185242, 1968079460,
+ 2864275059, 3347192726, 4096783459, 3259169450, 3707808869, 142485006, 399610869, 230556456,
+ 2219467721, 4191227798, 2242548189, 3136366572, 179755707, 3464881829, 452317775, 3887426070,
+ 3446430233, 1473370015, 1576807208, 3964523248, 419325089, 2373067114, 1596072055, 1928415752,
+ 3635452689, 1005598891, 3335462724, 3290848636, 3669078247, 1178176812, 2110774376, 3068593619,
+ 1253036518, 908857731, 3631223047, 4138506423, 2903592318, 3596915748, 3289036113, 3721512676,
+ 2704409359, 3386016968, 3676268074, 2185259502, 1096257611, 3360076717, 3548676554, 170167319,
+ 3360064287, 3899940843, 9640,
+];
+
+pub(crate) const POW5: [&'static [u32]; 14] = [
+ &POW5_1, &POW5_2, &POW5_3, &POW5_4, &POW5_5, &POW5_6, &POW5_7, &POW5_8, &POW5_9, &POW5_10,
+ &POW5_11, &POW5_12, &POW5_13, &POW5_14,
+];
diff --git a/third_party/rust/serde_json/src/lexical/large_powers64.rs b/third_party/rust/serde_json/src/lexical/large_powers64.rs
new file mode 100644
index 0000000000..ee36561088
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/large_powers64.rs
@@ -0,0 +1,625 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Precalculated large powers for 64-bit limbs.
+
+/// Large powers (&[u64]) for base5 operations.
+const POW5_1: [u64; 1] = [5];
+const POW5_2: [u64; 1] = [25];
+const POW5_3: [u64; 1] = [625];
+const POW5_4: [u64; 1] = [390625];
+const POW5_5: [u64; 1] = [152587890625];
+const POW5_6: [u64; 2] = [3273344365508751233, 1262];
+const POW5_7: [u64; 3] = [7942358959831785217, 16807427164405733357, 1593091];
+const POW5_8: [u64; 5] = [
+ 279109966635548161,
+ 2554917779393558781,
+ 14124656261812188652,
+ 11976055582626787546,
+ 2537941837315,
+];
+const POW5_9: [u64; 10] = [
+ 13750482914757213185,
+ 1302999927698857842,
+ 14936872543252795590,
+ 2788415840139466767,
+ 2095640732773017264,
+ 7205570348933370714,
+ 7348167152523113408,
+ 9285516396840364274,
+ 6907659600622710236,
+ 349175,
+];
+const POW5_10: [u64; 19] = [
+ 8643096425819600897,
+ 6743743997439985372,
+ 14059704609098336919,
+ 10729359125898331411,
+ 4933048501514368705,
+ 12258131603170554683,
+ 2172371001088594721,
+ 13569903330219142946,
+ 13809142207969578845,
+ 16716360519037769646,
+ 9631256923806107285,
+ 12866941232305103710,
+ 1397931361048440292,
+ 7619627737732970332,
+ 12725409486282665900,
+ 11703051443360963910,
+ 9947078370803086083,
+ 13966287901448440471,
+ 121923442132,
+];
+const POW5_11: [u64; 38] = [
+ 17679772531488845825,
+ 2216509366347768155,
+ 1568689219195129479,
+ 5511594616325588277,
+ 1067709417009240089,
+ 9070650952098657518,
+ 11515285870634858015,
+ 2539561553659505564,
+ 17604889300961091799,
+ 14511540856854204724,
+ 12099083339557485471,
+ 7115240299237943815,
+ 313979240050606788,
+ 10004784664717172195,
+ 15570268847930131473,
+ 10359715202835930803,
+ 17685054012115162812,
+ 13183273382855797757,
+ 7743260039872919062,
+ 9284593436392572926,
+ 11105921222066415013,
+ 18198799323400703846,
+ 16314988383739458320,
+ 4387527177871570570,
+ 8476708682254672590,
+ 4925096874831034057,
+ 14075687868072027455,
+ 112866656203221926,
+ 9852830467773230418,
+ 25755239915196746,
+ 2201493076310172510,
+ 8342165458688466438,
+ 13954006576066379050,
+ 15193819059903295636,
+ 12565616718911389531,
+ 3815854855847885129,
+ 15696762163583540628,
+ 805,
+];
+const POW5_12: [u64; 75] = [
+ 16359721904723189761,
+ 5323973632697650495,
+ 17187956456762001185,
+ 3930387638628283780,
+ 3374723710406992273,
+ 16884225088663222131,
+ 10967440051041439154,
+ 9686916182456720060,
+ 10554548046311730194,
+ 7390739362393647554,
+ 6316162333127736719,
+ 18122464886584070891,
+ 4044404959645932768,
+ 3801320885861987401,
+ 12080950653257274590,
+ 16414324262488991299,
+ 16395687498836410113,
+ 12173633940896186260,
+ 10843185433142632150,
+ 11048169832730399808,
+ 12674828934734683716,
+ 17370808310130582550,
+ 10500926985433408692,
+ 10252725158410704555,
+ 14170108270502067523,
+ 3698946465517688080,
+ 989984870770509463,
+ 10965601426733943069,
+ 11389898658438335655,
+ 6901098232861256586,
+ 1921335291173932590,
+ 7662788640922083388,
+ 9775023833308395430,
+ 4640401278902814207,
+ 14532050972198413359,
+ 8378549018693130223,
+ 11672322628395371653,
+ 8930704142764178555,
+ 6275193859483102017,
+ 15782593304269205087,
+ 8673060659034172558,
+ 8018354414354334043,
+ 1824896661540749038,
+ 11345563346725559868,
+ 14959216444480821949,
+ 970189517688324683,
+ 3338835207603007873,
+ 17684964260791738489,
+ 1436466329061721851,
+ 4554134986752476101,
+ 6398757850768963907,
+ 4709779218751158342,
+ 10033277748582410264,
+ 17932125878679265063,
+ 10004750887749091440,
+ 256584531835386932,
+ 14396282740722731628,
+ 3086085133731396950,
+ 17831272085689600064,
+ 10573926491412564693,
+ 14888061047859191737,
+ 4570995450261499817,
+ 10410165022312935266,
+ 5691078631447480790,
+ 8632710455805418155,
+ 790672778942823293,
+ 16505464105756800547,
+ 2092171438149740401,
+ 17505030673829275878,
+ 1291290830058928444,
+ 14856191690683232796,
+ 8916773426496500052,
+ 10152003807578858265,
+ 13104441193763861714,
+ 649395,
+];
+const POW5_13: [u64; 149] = [
+ 15308384451594534913,
+ 17913664074042735335,
+ 6115977719198531863,
+ 5794980608663993169,
+ 16544350702855106930,
+ 9253787637781258566,
+ 4977988951675168190,
+ 9087837664087448770,
+ 2098480401110016986,
+ 15474332540882100712,
+ 14042133997396540944,
+ 1090855284423485362,
+ 12639956485351058381,
+ 1454115676006639319,
+ 3180465001342538023,
+ 14649076551958697729,
+ 9801292446545910916,
+ 13552201410826594004,
+ 6101141927469189381,
+ 1881431857880609316,
+ 4907847477899433595,
+ 8714572486973123228,
+ 3514969632331374520,
+ 11667642286891470094,
+ 2391499697425323350,
+ 17486585679659076043,
+ 18267223761882105642,
+ 2886610765822313148,
+ 9302834862968900288,
+ 15246507846733637044,
+ 15924227519624562840,
+ 9743741243284697760,
+ 3159780987244964246,
+ 7304816812369628428,
+ 17584602612559717809,
+ 4146812420657846766,
+ 14525415362681041515,
+ 8477630142371600195,
+ 4380695748062263745,
+ 12119915994367943173,
+ 16970630866565485122,
+ 4332724980155264503,
+ 8079943140620527639,
+ 1687908087554405626,
+ 17051081099834002166,
+ 12638146269730763230,
+ 11883749876933445771,
+ 4662462156371383785,
+ 4796962238316531176,
+ 3325504751659868927,
+ 6469595803187862550,
+ 5852556621152583005,
+ 9229334792448387881,
+ 17979733373938620709,
+ 13951623534175792756,
+ 17075879371091039277,
+ 14212246479457938037,
+ 4008999959804158260,
+ 2414266395366403722,
+ 3252733766253918247,
+ 6382678985007829216,
+ 2245927470982310841,
+ 13790724502051307301,
+ 13116936866733148041,
+ 9718402891306794538,
+ 13516274400356104875,
+ 17859223875778049403,
+ 4396895129099725471,
+ 3563053650368467915,
+ 12176845952536972668,
+ 3492050964335269015,
+ 2740656767075170753,
+ 4409704077614761919,
+ 10237775279597492710,
+ 3314206875098230827,
+ 16437361028114095448,
+ 12361736225407656572,
+ 16792510651790145480,
+ 11449053143229929935,
+ 18336641737580333136,
+ 6558939822118891088,
+ 4606255756908155300,
+ 2360792578991605004,
+ 160428430149144538,
+ 11644861220729221511,
+ 10785178451159739786,
+ 14923560618031934681,
+ 1902620814992781610,
+ 14064076995338910412,
+ 11547019064112212657,
+ 16847481479966225734,
+ 8331994491163145469,
+ 11739712981738851885,
+ 8008309968651120619,
+ 10266969595459035264,
+ 15175153381217702033,
+ 12208659352573720245,
+ 7714061140750342961,
+ 2892831567213510541,
+ 15453714249045017319,
+ 71020323573871677,
+ 15431137995750602633,
+ 5659146884637671933,
+ 5998809010488554503,
+ 16552192379299157850,
+ 1192197967194298797,
+ 16157555793424861524,
+ 10929371590994640255,
+ 3194469143425738352,
+ 6651586784672005225,
+ 11062427140788057791,
+ 6834443579468668318,
+ 16421563197797455922,
+ 6251046422506172884,
+ 13952303462156793860,
+ 16632486601871393224,
+ 11313454360291325172,
+ 5587835232504462834,
+ 3105197524618514637,
+ 18268568531031972989,
+ 2397205535804309313,
+ 59413027864729597,
+ 11869878125348715710,
+ 12592801707270523266,
+ 8070632061321113656,
+ 18403647807860650811,
+ 267109013517069093,
+ 6537214311028855260,
+ 5220826919973709902,
+ 3448740582779163661,
+ 16822239213112884941,
+ 5975299384311048185,
+ 10294433804430712138,
+ 4739856055412448774,
+ 12057273038326387897,
+ 13119002941950056609,
+ 3354445304051737058,
+ 13592813067499314594,
+ 3890182464434078629,
+ 17820384357466425060,
+ 9785228118969879380,
+ 1778431746734556271,
+ 10075313876350055029,
+ 13994048489400919028,
+ 17948287074199726448,
+ 2815088342305858722,
+ 2676626035777198370,
+ 1174257960026283968,
+ 421714788677,
+];
+const POW5_14: [u64; 298] = [
+ 11471884475673051137,
+ 8902860357476377573,
+ 13350296775839230505,
+ 10609191786344608888,
+ 7261211985859587338,
+ 11439672689354862964,
+ 16789708072300570627,
+ 4607056528866348430,
+ 3202978990421512997,
+ 2024899620433984146,
+ 17666950207239811774,
+ 4233228489390288200,
+ 9137580478688460738,
+ 4060411066587388546,
+ 11119949806060600124,
+ 867715462473090103,
+ 14382394941384869610,
+ 4856042377419278489,
+ 8265605599571137921,
+ 538981667666252469,
+ 4270263388700786523,
+ 3281140600308898503,
+ 4121392524544394174,
+ 2077884106245940229,
+ 9773041957329767574,
+ 7550623316597646685,
+ 8611033926449791714,
+ 18137922955420802793,
+ 2796546741236224013,
+ 15477096484628446761,
+ 9517540128113714010,
+ 9471917970500821378,
+ 15938570248662483124,
+ 5228016831978462619,
+ 15720991252586974501,
+ 7662829825220776698,
+ 17328310068068434348,
+ 3371736428170309730,
+ 3803724952191098855,
+ 13115926536504376719,
+ 16752571196153442257,
+ 16540185467776259880,
+ 3432518182450051120,
+ 5880364967211798870,
+ 12355748840305392783,
+ 14196090758536469575,
+ 7370123524686686319,
+ 6819740424617592686,
+ 13037938013537368753,
+ 15029273671291927100,
+ 3671312928327205696,
+ 7473228676544792780,
+ 17234079691312938123,
+ 14164740848093544419,
+ 13169904779481875902,
+ 7179036968465894054,
+ 8244653688947194445,
+ 17179797746073799490,
+ 5591970751047577674,
+ 17530550506268329742,
+ 5965746721852312330,
+ 1604149463243472865,
+ 7734199791463116918,
+ 11305790396015856714,
+ 4441196105025505137,
+ 13046431581185664762,
+ 124776524294606713,
+ 1134521334706523966,
+ 11671728093344476434,
+ 14103440020972933148,
+ 3966727403013869059,
+ 9828094508409132821,
+ 4355682486381147287,
+ 10261407143988481234,
+ 3800455155249557199,
+ 12700901937937547500,
+ 18184475466894579360,
+ 13267691151779895412,
+ 4714157123477697445,
+ 10770360171308585263,
+ 9083344917597998040,
+ 12078649873810212155,
+ 18218989082046199377,
+ 4454285072780637351,
+ 5287307245618354742,
+ 16042289702059031730,
+ 4131926574212754010,
+ 217692071448455473,
+ 3624845916216282093,
+ 2901203491797614218,
+ 6679177724033967080,
+ 44561358851332790,
+ 9094639944041587162,
+ 13690915012276084311,
+ 1408896670826320686,
+ 5359130319612337580,
+ 6148412925099835601,
+ 5211368532286409612,
+ 11386360825549027374,
+ 16895182466965795071,
+ 3392940493846427241,
+ 438089879085393580,
+ 4783928372776399972,
+ 6278117363595909959,
+ 12569481049412674733,
+ 15648622492570893902,
+ 1966316336235305115,
+ 1603775390515993547,
+ 13576113010204316709,
+ 10821754650102840474,
+ 18198222517222903152,
+ 6966163076615302988,
+ 1373932372410129684,
+ 3285839581819684990,
+ 30177575069719475,
+ 16447047871247307061,
+ 11618654126674833808,
+ 990072222556306872,
+ 1260682336135768017,
+ 13862055046689532489,
+ 15668483092844698432,
+ 1879572630092764264,
+ 13912027797058626108,
+ 6231679788219816920,
+ 13857858054844167403,
+ 18101470072534728857,
+ 4144579812461609229,
+ 7048589655616599284,
+ 9946956499532694630,
+ 9771303850109874038,
+ 6477823708780339765,
+ 17526247621747041971,
+ 13525995675852669549,
+ 3928768291901239810,
+ 8094153383078124544,
+ 11214278667728965552,
+ 11251547162596832610,
+ 5964946855123292381,
+ 3622548288590237903,
+ 13469765967150053587,
+ 17798986288523466082,
+ 14684592818807932259,
+ 16724077276802963921,
+ 7119877993753121290,
+ 1864571304902781632,
+ 12871984921385213812,
+ 9065447042604670298,
+ 3987130777300360550,
+ 6890545752116901685,
+ 17275341711601865750,
+ 6296474927799264658,
+ 1257436973037243463,
+ 13854281781965301421,
+ 1657132483318662716,
+ 17309399540017292849,
+ 12808111630089217242,
+ 1098489625264462071,
+ 14010458905686364135,
+ 16134414519481621220,
+ 14288255900328821475,
+ 3469093466388187882,
+ 15982710881468295872,
+ 4056765540058056052,
+ 15945176389096104089,
+ 8625339365793505375,
+ 12316179968863788913,
+ 15334123773538054321,
+ 9536238824220581765,
+ 16080825720106203271,
+ 6235695225418121745,
+ 12035192956458019349,
+ 3235835166714703698,
+ 5348960676912581218,
+ 15315062772709464647,
+ 17335089708021308662,
+ 16855855317958414409,
+ 2369751139431140406,
+ 3693542588628609043,
+ 7350405893393987577,
+ 17402072586341663801,
+ 7007897690013647122,
+ 15671767872059304758,
+ 9259490518292347915,
+ 14836045474406130394,
+ 4654005815464502513,
+ 6487825998330548401,
+ 7013356660323385022,
+ 7136200343936679946,
+ 15341236858676437716,
+ 3657357368867197449,
+ 12621075530054608378,
+ 5603868621997066972,
+ 7683447656788439942,
+ 450883379216880060,
+ 14291494350184945047,
+ 5466258454997635048,
+ 14206933098432772126,
+ 4775870327277641692,
+ 1864430798867181939,
+ 13748978265070608793,
+ 12250822864261576589,
+ 12561896977498605296,
+ 16060949594257359328,
+ 17775189113543311529,
+ 11835965177892927035,
+ 4218664174878121437,
+ 3499000902478111683,
+ 15169853304359126294,
+ 7076121963053575143,
+ 832652347668916805,
+ 1292148207755194737,
+ 7556838978364207852,
+ 5904021986723518500,
+ 4610244652288570024,
+ 4526508363195533871,
+ 746120481022614726,
+ 737965197247830486,
+ 4006266184415762653,
+ 9272188239892688050,
+ 15346235246415709678,
+ 11850675997347533184,
+ 11181059668610842701,
+ 6687857983250662774,
+ 2908718488661492818,
+ 4828337780126983225,
+ 18071738646453002184,
+ 12790187227727197880,
+ 17602483480871623153,
+ 12523532189621855977,
+ 10598805712727696716,
+ 2179787555896149376,
+ 2242193929457337594,
+ 14908923241136742532,
+ 8369182018012550027,
+ 13385381554043022324,
+ 3332327430110633913,
+ 16138090784046208492,
+ 16172324607469047339,
+ 8279089815915615244,
+ 12872906602736235247,
+ 10894545290539475621,
+ 15428756545851905023,
+ 4155747980686992922,
+ 4074479178894544043,
+ 66083965608603584,
+ 13873786284662268377,
+ 8861183628277687555,
+ 12119497911296021430,
+ 2154012318305274287,
+ 15490706314503067312,
+ 13643145488710608367,
+ 672340241093017103,
+ 6039493278284091973,
+ 9679797700977436461,
+ 18070795828318171174,
+ 2188146431134935377,
+ 5247392385741514952,
+ 1852539214842869734,
+ 12235621681634112739,
+ 8812930319623534062,
+ 5585597406294108629,
+ 11312989214475901864,
+ 1547377291787797995,
+ 8641748937186208205,
+ 12518148659168623694,
+ 6611379197521520985,
+ 18096591571068008576,
+ 15087021227100112139,
+ 13058454842015958418,
+ 1473584652966833794,
+ 4387660670140018168,
+ 8452836916843525402,
+ 14376083294443363955,
+ 13998026203969090659,
+ 611968444648172645,
+ 990232438801273845,
+ 18001186324715561929,
+ 13470591857250177501,
+ 14881554140239420091,
+ 16696367836720124495,
+ 6328076032778459673,
+ 17027497695968504616,
+ 10192245646262428833,
+ 8282482589527318647,
+ 4319014353374321425,
+ 14134087271041670980,
+ 5060230880114618599,
+ 13179509240430058600,
+ 3903514232614801894,
+ 17774749744702165255,
+ 15448635507030969726,
+ 15983775238358480209,
+ 14542832143965487887,
+ 9385618098039514666,
+ 14431419612662304843,
+ 730863073501675978,
+ 16750118380379734815,
+ 9640,
+];
+
+pub(crate) const POW5: [&[u64]; 14] = [
+ &POW5_1, &POW5_2, &POW5_3, &POW5_4, &POW5_5, &POW5_6, &POW5_7, &POW5_8, &POW5_9, &POW5_10,
+ &POW5_11, &POW5_12, &POW5_13, &POW5_14,
+];
diff --git a/third_party/rust/serde_json/src/lexical/math.rs b/third_party/rust/serde_json/src/lexical/math.rs
new file mode 100644
index 0000000000..37cc1d24ad
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/math.rs
@@ -0,0 +1,886 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Building-blocks for arbitrary-precision math.
+//!
+//! These algorithms assume little-endian order for the large integer
+//! buffers, so for a `vec![0, 1, 2, 3]`, `3` is the most significant limb,
+//! and `0` is the least significant limb.
+
+use super::large_powers;
+use super::num::*;
+use super::small_powers::*;
+use alloc::vec::Vec;
+use core::{cmp, iter, mem};
+
+// ALIASES
+// -------
+
+// Type for a single limb of the big integer.
+//
+// A limb is analogous to a digit in base10, except, it stores 32-bit
+// or 64-bit numbers instead.
+//
+// This should be all-known 64-bit platforms supported by Rust.
+// https://forge.rust-lang.org/platform-support.html
+//
+// Platforms where native 128-bit multiplication is explicitly supported:
+// - x86_64 (Supported via `MUL`).
+// - mips64 (Supported via `DMULTU`, which `HI` and `LO` can be read-from).
+//
+// Platforms where native 64-bit multiplication is supported and
+// you can extract hi-lo for 64-bit multiplications.
+// aarch64 (Requires `UMULH` and `MUL` to capture high and low bits).
+// powerpc64 (Requires `MULHDU` and `MULLD` to capture high and low bits).
+//
+// Platforms where native 128-bit multiplication is not supported,
+// requiring software emulation.
+// sparc64 (`UMUL` only supported double-word arguments).
+
+// 32-BIT LIMB
+#[cfg(limb_width_32)]
+pub type Limb = u32;
+
+#[cfg(limb_width_32)]
+pub const POW5_LIMB: &[Limb] = &POW5_32;
+
+#[cfg(limb_width_32)]
+pub const POW10_LIMB: &[Limb] = &POW10_32;
+
+#[cfg(limb_width_32)]
+type Wide = u64;
+
+// 64-BIT LIMB
+#[cfg(limb_width_64)]
+pub type Limb = u64;
+
+#[cfg(limb_width_64)]
+pub const POW5_LIMB: &[Limb] = &POW5_64;
+
+#[cfg(limb_width_64)]
+pub const POW10_LIMB: &[Limb] = &POW10_64;
+
+#[cfg(limb_width_64)]
+type Wide = u128;
+
+/// Cast to limb type.
+#[inline]
+pub(crate) fn as_limb<T: Integer>(t: T) -> Limb {
+ Limb::as_cast(t)
+}
+
+/// Cast to wide type.
+#[inline]
+fn as_wide<T: Integer>(t: T) -> Wide {
+ Wide::as_cast(t)
+}
+
+// SPLIT
+// -----
+
+/// Split u64 into limbs, in little-endian order.
+#[inline]
+#[cfg(limb_width_32)]
+fn split_u64(x: u64) -> [Limb; 2] {
+ [as_limb(x), as_limb(x >> 32)]
+}
+
+/// Split u64 into limbs, in little-endian order.
+#[inline]
+#[cfg(limb_width_64)]
+fn split_u64(x: u64) -> [Limb; 1] {
+ [as_limb(x)]
+}
+
+// HI64
+// ----
+
+// NONZERO
+
+/// Check if any of the remaining bits are non-zero.
+#[inline]
+pub fn nonzero<T: Integer>(x: &[T], rindex: usize) -> bool {
+ let len = x.len();
+ let slc = &x[..len - rindex];
+ slc.iter().rev().any(|&x| x != T::ZERO)
+}
+
+/// Shift 64-bit integer to high 64-bits.
+#[inline]
+fn u64_to_hi64_1(r0: u64) -> (u64, bool) {
+ debug_assert!(r0 != 0);
+ let ls = r0.leading_zeros();
+ (r0 << ls, false)
+}
+
+/// Shift 2 64-bit integers to high 64-bits.
+#[inline]
+fn u64_to_hi64_2(r0: u64, r1: u64) -> (u64, bool) {
+ debug_assert!(r0 != 0);
+ let ls = r0.leading_zeros();
+ let rs = 64 - ls;
+ let v = match ls {
+ 0 => r0,
+ _ => (r0 << ls) | (r1 >> rs),
+ };
+ let n = r1 << ls != 0;
+ (v, n)
+}
+
+/// Trait to export the high 64-bits from a little-endian slice.
+trait Hi64<T>: AsRef<[T]> {
+ /// Get the hi64 bits from a 1-limb slice.
+ fn hi64_1(&self) -> (u64, bool);
+
+ /// Get the hi64 bits from a 2-limb slice.
+ fn hi64_2(&self) -> (u64, bool);
+
+ /// Get the hi64 bits from a 3-limb slice.
+ fn hi64_3(&self) -> (u64, bool);
+
+ /// High-level exporter to extract the high 64 bits from a little-endian slice.
+ #[inline]
+ fn hi64(&self) -> (u64, bool) {
+ match self.as_ref().len() {
+ 0 => (0, false),
+ 1 => self.hi64_1(),
+ 2 => self.hi64_2(),
+ _ => self.hi64_3(),
+ }
+ }
+}
+
+impl Hi64<u32> for [u32] {
+ #[inline]
+ fn hi64_1(&self) -> (u64, bool) {
+ debug_assert!(self.len() == 1);
+ let r0 = self[0] as u64;
+ u64_to_hi64_1(r0)
+ }
+
+ #[inline]
+ fn hi64_2(&self) -> (u64, bool) {
+ debug_assert!(self.len() == 2);
+ let r0 = (self[1] as u64) << 32;
+ let r1 = self[0] as u64;
+ u64_to_hi64_1(r0 | r1)
+ }
+
+ #[inline]
+ fn hi64_3(&self) -> (u64, bool) {
+ debug_assert!(self.len() >= 3);
+ let r0 = self[self.len() - 1] as u64;
+ let r1 = (self[self.len() - 2] as u64) << 32;
+ let r2 = self[self.len() - 3] as u64;
+ let (v, n) = u64_to_hi64_2(r0, r1 | r2);
+ (v, n || nonzero(self, 3))
+ }
+}
+
+impl Hi64<u64> for [u64] {
+ #[inline]
+ fn hi64_1(&self) -> (u64, bool) {
+ debug_assert!(self.len() == 1);
+ let r0 = self[0];
+ u64_to_hi64_1(r0)
+ }
+
+ #[inline]
+ fn hi64_2(&self) -> (u64, bool) {
+ debug_assert!(self.len() >= 2);
+ let r0 = self[self.len() - 1];
+ let r1 = self[self.len() - 2];
+ let (v, n) = u64_to_hi64_2(r0, r1);
+ (v, n || nonzero(self, 2))
+ }
+
+ #[inline]
+ fn hi64_3(&self) -> (u64, bool) {
+ self.hi64_2()
+ }
+}
+
+// SCALAR
+// ------
+
+// Scalar-to-scalar operations, for building-blocks for arbitrary-precision
+// operations.
+
+mod scalar {
+ use super::*;
+
+ // ADDITION
+
+ /// Add two small integers and return the resulting value and if overflow happens.
+ #[inline]
+ pub fn add(x: Limb, y: Limb) -> (Limb, bool) {
+ x.overflowing_add(y)
+ }
+
+ /// AddAssign two small integers and return if overflow happens.
+ #[inline]
+ pub fn iadd(x: &mut Limb, y: Limb) -> bool {
+ let t = add(*x, y);
+ *x = t.0;
+ t.1
+ }
+
+ // SUBTRACTION
+
+ /// Subtract two small integers and return the resulting value and if overflow happens.
+ #[inline]
+ pub fn sub(x: Limb, y: Limb) -> (Limb, bool) {
+ x.overflowing_sub(y)
+ }
+
+ /// SubAssign two small integers and return if overflow happens.
+ #[inline]
+ pub fn isub(x: &mut Limb, y: Limb) -> bool {
+ let t = sub(*x, y);
+ *x = t.0;
+ t.1
+ }
+
+ // MULTIPLICATION
+
+ /// Multiply two small integers (with carry) (and return the overflow contribution).
+ ///
+ /// Returns the (low, high) components.
+ #[inline]
+ pub fn mul(x: Limb, y: Limb, carry: Limb) -> (Limb, Limb) {
+ // Cannot overflow, as long as wide is 2x as wide. This is because
+ // the following is always true:
+ // `Wide::max_value() - (Narrow::max_value() * Narrow::max_value()) >= Narrow::max_value()`
+ let z: Wide = as_wide(x) * as_wide(y) + as_wide(carry);
+ let bits = mem::size_of::<Limb>() * 8;
+ (as_limb(z), as_limb(z >> bits))
+ }
+
+ /// Multiply two small integers (with carry) (and return if overflow happens).
+ #[inline]
+ pub fn imul(x: &mut Limb, y: Limb, carry: Limb) -> Limb {
+ let t = mul(*x, y, carry);
+ *x = t.0;
+ t.1
+ }
+} // scalar
+
+// SMALL
+// -----
+
+// Large-to-small operations, to modify a big integer from a native scalar.
+
+mod small {
+ use super::*;
+
+ // MULTIPLICATIION
+
+ /// ADDITION
+
+ /// Implied AddAssign implementation for adding a small integer to bigint.
+ ///
+ /// Allows us to choose a start-index in x to store, to allow incrementing
+ /// from a non-zero start.
+ #[inline]
+ pub fn iadd_impl(x: &mut Vec<Limb>, y: Limb, xstart: usize) {
+ if x.len() <= xstart {
+ x.push(y);
+ } else {
+ // Initial add
+ let mut carry = scalar::iadd(&mut x[xstart], y);
+
+ // Increment until overflow stops occurring.
+ let mut size = xstart + 1;
+ while carry && size < x.len() {
+ carry = scalar::iadd(&mut x[size], 1);
+ size += 1;
+ }
+
+ // If we overflowed the buffer entirely, need to add 1 to the end
+ // of the buffer.
+ if carry {
+ x.push(1);
+ }
+ }
+ }
+
+ /// AddAssign small integer to bigint.
+ #[inline]
+ pub fn iadd(x: &mut Vec<Limb>, y: Limb) {
+ iadd_impl(x, y, 0);
+ }
+
+ // SUBTRACTION
+
+ /// SubAssign small integer to bigint.
+ /// Does not do overflowing subtraction.
+ #[inline]
+ pub fn isub_impl(x: &mut Vec<Limb>, y: Limb, xstart: usize) {
+ debug_assert!(x.len() > xstart && (x[xstart] >= y || x.len() > xstart + 1));
+
+ // Initial subtraction
+ let mut carry = scalar::isub(&mut x[xstart], y);
+
+ // Increment until overflow stops occurring.
+ let mut size = xstart + 1;
+ while carry && size < x.len() {
+ carry = scalar::isub(&mut x[size], 1);
+ size += 1;
+ }
+ normalize(x);
+ }
+
+ // MULTIPLICATION
+
+ /// MulAssign small integer to bigint.
+ #[inline]
+ pub fn imul(x: &mut Vec<Limb>, y: Limb) {
+ // Multiply iteratively over all elements, adding the carry each time.
+ let mut carry: Limb = 0;
+ for xi in x.iter_mut() {
+ carry = scalar::imul(xi, y, carry);
+ }
+
+ // Overflow of value, add to end.
+ if carry != 0 {
+ x.push(carry);
+ }
+ }
+
+ /// Mul small integer to bigint.
+ #[inline]
+ pub fn mul(x: &[Limb], y: Limb) -> Vec<Limb> {
+ let mut z = Vec::<Limb>::default();
+ z.extend_from_slice(x);
+ imul(&mut z, y);
+ z
+ }
+
+ /// MulAssign by a power.
+ ///
+ /// Theoretically...
+ ///
+ /// Use an exponentiation by squaring method, since it reduces the time
+ /// complexity of the multiplication to ~`O(log(n))` for the squaring,
+ /// and `O(n*m)` for the result. Since `m` is typically a lower-order
+ /// factor, this significantly reduces the number of multiplications
+ /// we need to do. Iteratively multiplying by small powers follows
+ /// the nth triangular number series, which scales as `O(p^2)`, but
+ /// where `p` is `n+m`. In short, it scales very poorly.
+ ///
+ /// Practically....
+ ///
+ /// Exponentiation by Squaring:
+ /// running 2 tests
+ /// test bigcomp_f32_lexical ... bench: 1,018 ns/iter (+/- 78)
+ /// test bigcomp_f64_lexical ... bench: 3,639 ns/iter (+/- 1,007)
+ ///
+ /// Exponentiation by Iterative Small Powers:
+ /// running 2 tests
+ /// test bigcomp_f32_lexical ... bench: 518 ns/iter (+/- 31)
+ /// test bigcomp_f64_lexical ... bench: 583 ns/iter (+/- 47)
+ ///
+ /// Exponentiation by Iterative Large Powers (of 2):
+ /// running 2 tests
+ /// test bigcomp_f32_lexical ... bench: 671 ns/iter (+/- 31)
+ /// test bigcomp_f64_lexical ... bench: 1,394 ns/iter (+/- 47)
+ ///
+ /// Even using worst-case scenarios, exponentiation by squaring is
+ /// significantly slower for our workloads. Just multiply by small powers,
+ /// in simple cases, and use precalculated large powers in other cases.
+ pub fn imul_pow5(x: &mut Vec<Limb>, n: u32) {
+ use super::large::KARATSUBA_CUTOFF;
+
+ let small_powers = POW5_LIMB;
+ let large_powers = large_powers::POW5;
+
+ if n == 0 {
+ // No exponent, just return.
+ // The 0-index of the large powers is `2^0`, which is 1, so we want
+ // to make sure we don't take that path with a literal 0.
+ return;
+ }
+
+ // We want to use the asymptotically faster algorithm if we're going
+ // to be using Karabatsu multiplication sometime during the result,
+ // otherwise, just use exponentiation by squaring.
+ let bit_length = 32 - n.leading_zeros() as usize;
+ debug_assert!(bit_length != 0 && bit_length <= large_powers.len());
+ if x.len() + large_powers[bit_length - 1].len() < 2 * KARATSUBA_CUTOFF {
+ // We can use iterative small powers to make this faster for the
+ // easy cases.
+
+ // Multiply by the largest small power until n < step.
+ let step = small_powers.len() - 1;
+ let power = small_powers[step];
+ let mut n = n as usize;
+ while n >= step {
+ imul(x, power);
+ n -= step;
+ }
+
+ // Multiply by the remainder.
+ imul(x, small_powers[n]);
+ } else {
+ // In theory, this code should be asymptotically a lot faster,
+ // in practice, our small::imul seems to be the limiting step,
+ // and large imul is slow as well.
+
+ // Multiply by higher order powers.
+ let mut idx: usize = 0;
+ let mut bit: usize = 1;
+ let mut n = n as usize;
+ while n != 0 {
+ if n & bit != 0 {
+ debug_assert!(idx < large_powers.len());
+ large::imul(x, large_powers[idx]);
+ n ^= bit;
+ }
+ idx += 1;
+ bit <<= 1;
+ }
+ }
+ }
+
+ // BIT LENGTH
+
+ /// Get number of leading zero bits in the storage.
+ #[inline]
+ pub fn leading_zeros(x: &[Limb]) -> usize {
+ x.last().map_or(0, |x| x.leading_zeros() as usize)
+ }
+
+ /// Calculate the bit-length of the big-integer.
+ #[inline]
+ pub fn bit_length(x: &[Limb]) -> usize {
+ let bits = mem::size_of::<Limb>() * 8;
+ // Avoid overflowing, calculate via total number of bits
+ // minus leading zero bits.
+ let nlz = leading_zeros(x);
+ bits.checked_mul(x.len())
+ .map_or_else(usize::max_value, |v| v - nlz)
+ }
+
+ // SHL
+
+ /// Shift-left bits inside a buffer.
+ ///
+ /// Assumes `n < Limb::BITS`, IE, internally shifting bits.
+ #[inline]
+ pub fn ishl_bits(x: &mut Vec<Limb>, n: usize) {
+ // Need to shift by the number of `bits % Limb::BITS)`.
+ let bits = mem::size_of::<Limb>() * 8;
+ debug_assert!(n < bits);
+ if n == 0 {
+ return;
+ }
+
+ // Internally, for each item, we shift left by n, and add the previous
+ // right shifted limb-bits.
+ // For example, we transform (for u8) shifted left 2, to:
+ // b10100100 b01000010
+ // b10 b10010001 b00001000
+ let rshift = bits - n;
+ let lshift = n;
+ let mut prev: Limb = 0;
+ for xi in x.iter_mut() {
+ let tmp = *xi;
+ *xi <<= lshift;
+ *xi |= prev >> rshift;
+ prev = tmp;
+ }
+
+ // Always push the carry, even if it creates a non-normal result.
+ let carry = prev >> rshift;
+ if carry != 0 {
+ x.push(carry);
+ }
+ }
+
+ /// Shift-left `n` digits inside a buffer.
+ ///
+ /// Assumes `n` is not 0.
+ #[inline]
+ pub fn ishl_limbs(x: &mut Vec<Limb>, n: usize) {
+ debug_assert!(n != 0);
+ if !x.is_empty() {
+ x.reserve(n);
+ x.splice(..0, iter::repeat(0).take(n));
+ }
+ }
+
+ /// Shift-left buffer by n bits.
+ #[inline]
+ pub fn ishl(x: &mut Vec<Limb>, n: usize) {
+ let bits = mem::size_of::<Limb>() * 8;
+ // Need to pad with zeros for the number of `bits / Limb::BITS`,
+ // and shift-left with carry for `bits % Limb::BITS`.
+ let rem = n % bits;
+ let div = n / bits;
+ ishl_bits(x, rem);
+ if div != 0 {
+ ishl_limbs(x, div);
+ }
+ }
+
+ // NORMALIZE
+
+ /// Normalize the container by popping any leading zeros.
+ #[inline]
+ pub fn normalize(x: &mut Vec<Limb>) {
+ // Remove leading zero if we cause underflow. Since we're dividing
+ // by a small power, we have at max 1 int removed.
+ while x.last() == Some(&0) {
+ x.pop();
+ }
+ }
+} // small
+
+// LARGE
+// -----
+
+// Large-to-large operations, to modify a big integer from a native scalar.
+
+mod large {
+ use super::*;
+
+ // RELATIVE OPERATORS
+
+ /// Compare `x` to `y`, in little-endian order.
+ #[inline]
+ pub fn compare(x: &[Limb], y: &[Limb]) -> cmp::Ordering {
+ if x.len() > y.len() {
+ cmp::Ordering::Greater
+ } else if x.len() < y.len() {
+ cmp::Ordering::Less
+ } else {
+ let iter = x.iter().rev().zip(y.iter().rev());
+ for (&xi, &yi) in iter {
+ if xi > yi {
+ return cmp::Ordering::Greater;
+ } else if xi < yi {
+ return cmp::Ordering::Less;
+ }
+ }
+ // Equal case.
+ cmp::Ordering::Equal
+ }
+ }
+
+ /// Check if x is less than y.
+ #[inline]
+ pub fn less(x: &[Limb], y: &[Limb]) -> bool {
+ compare(x, y) == cmp::Ordering::Less
+ }
+
+ /// Check if x is greater than or equal to y.
+ #[inline]
+ pub fn greater_equal(x: &[Limb], y: &[Limb]) -> bool {
+ !less(x, y)
+ }
+
+ // ADDITION
+
+ /// Implied AddAssign implementation for bigints.
+ ///
+ /// Allows us to choose a start-index in x to store, so we can avoid
+ /// padding the buffer with zeros when not needed, optimized for vectors.
+ pub fn iadd_impl(x: &mut Vec<Limb>, y: &[Limb], xstart: usize) {
+ // The effective x buffer is from `xstart..x.len()`, so we need to treat
+ // that as the current range. If the effective y buffer is longer, need
+ // to resize to that, + the start index.
+ if y.len() > x.len() - xstart {
+ x.resize(y.len() + xstart, 0);
+ }
+
+ // Iteratively add elements from y to x.
+ let mut carry = false;
+ for (xi, yi) in x[xstart..].iter_mut().zip(y.iter()) {
+ // Only one op of the two can overflow, since we added at max
+ // Limb::max_value() + Limb::max_value(). Add the previous carry,
+ // and store the current carry for the next.
+ let mut tmp = scalar::iadd(xi, *yi);
+ if carry {
+ tmp |= scalar::iadd(xi, 1);
+ }
+ carry = tmp;
+ }
+
+ // Overflow from the previous bit.
+ if carry {
+ small::iadd_impl(x, 1, y.len() + xstart);
+ }
+ }
+
+ /// AddAssign bigint to bigint.
+ #[inline]
+ pub fn iadd(x: &mut Vec<Limb>, y: &[Limb]) {
+ iadd_impl(x, y, 0);
+ }
+
+ /// Add bigint to bigint.
+ #[inline]
+ pub fn add(x: &[Limb], y: &[Limb]) -> Vec<Limb> {
+ let mut z = Vec::<Limb>::default();
+ z.extend_from_slice(x);
+ iadd(&mut z, y);
+ z
+ }
+
+ // SUBTRACTION
+
+ /// SubAssign bigint to bigint.
+ pub fn isub(x: &mut Vec<Limb>, y: &[Limb]) {
+ // Basic underflow checks.
+ debug_assert!(greater_equal(x, y));
+
+ // Iteratively add elements from y to x.
+ let mut carry = false;
+ for (xi, yi) in x.iter_mut().zip(y.iter()) {
+ // Only one op of the two can overflow, since we added at max
+ // Limb::max_value() + Limb::max_value(). Add the previous carry,
+ // and store the current carry for the next.
+ let mut tmp = scalar::isub(xi, *yi);
+ if carry {
+ tmp |= scalar::isub(xi, 1);
+ }
+ carry = tmp;
+ }
+
+ if carry {
+ small::isub_impl(x, 1, y.len());
+ } else {
+ small::normalize(x);
+ }
+ }
+
+ // MULTIPLICATION
+
+ /// Number of digits to bottom-out to asymptotically slow algorithms.
+ ///
+ /// Karatsuba tends to out-perform long-multiplication at ~320-640 bits,
+ /// so we go halfway, while Newton division tends to out-perform
+ /// Algorithm D at ~1024 bits. We can toggle this for optimal performance.
+ pub const KARATSUBA_CUTOFF: usize = 32;
+
+ /// Grade-school multiplication algorithm.
+ ///
+ /// Slow, naive algorithm, using limb-bit bases and just shifting left for
+ /// each iteration. This could be optimized with numerous other algorithms,
+ /// but it's extremely simple, and works in O(n*m) time, which is fine
+ /// by me. Each iteration, of which there are `m` iterations, requires
+ /// `n` multiplications, and `n` additions, or grade-school multiplication.
+ fn long_mul(x: &[Limb], y: &[Limb]) -> Vec<Limb> {
+ // Using the immutable value, multiply by all the scalars in y, using
+ // the algorithm defined above. Use a single buffer to avoid
+ // frequent reallocations. Handle the first case to avoid a redundant
+ // addition, since we know y.len() >= 1.
+ let mut z: Vec<Limb> = small::mul(x, y[0]);
+ z.resize(x.len() + y.len(), 0);
+
+ // Handle the iterative cases.
+ for (i, &yi) in y[1..].iter().enumerate() {
+ let zi: Vec<Limb> = small::mul(x, yi);
+ iadd_impl(&mut z, &zi, i + 1);
+ }
+
+ small::normalize(&mut z);
+
+ z
+ }
+
+ /// Split two buffers into halfway, into (lo, hi).
+ #[inline]
+ pub fn karatsuba_split(z: &[Limb], m: usize) -> (&[Limb], &[Limb]) {
+ (&z[..m], &z[m..])
+ }
+
+ /// Karatsuba multiplication algorithm with roughly equal input sizes.
+ ///
+ /// Assumes `y.len() >= x.len()`.
+ fn karatsuba_mul(x: &[Limb], y: &[Limb]) -> Vec<Limb> {
+ if y.len() <= KARATSUBA_CUTOFF {
+ // Bottom-out to long division for small cases.
+ long_mul(x, y)
+ } else if x.len() < y.len() / 2 {
+ karatsuba_uneven_mul(x, y)
+ } else {
+ // Do our 3 multiplications.
+ let m = y.len() / 2;
+ let (xl, xh) = karatsuba_split(x, m);
+ let (yl, yh) = karatsuba_split(y, m);
+ let sumx = add(xl, xh);
+ let sumy = add(yl, yh);
+ let z0 = karatsuba_mul(xl, yl);
+ let mut z1 = karatsuba_mul(&sumx, &sumy);
+ let z2 = karatsuba_mul(xh, yh);
+ // Properly scale z1, which is `z1 - z2 - zo`.
+ isub(&mut z1, &z2);
+ isub(&mut z1, &z0);
+
+ // Create our result, which is equal to, in little-endian order:
+ // [z0, z1 - z2 - z0, z2]
+ // z1 must be shifted m digits (2^(32m)) over.
+ // z2 must be shifted 2*m digits (2^(64m)) over.
+ let len = z0.len().max(m + z1.len()).max(2 * m + z2.len());
+ let mut result = z0;
+ result.reserve_exact(len - result.len());
+ iadd_impl(&mut result, &z1, m);
+ iadd_impl(&mut result, &z2, 2 * m);
+
+ result
+ }
+ }
+
+ /// Karatsuba multiplication algorithm where y is substantially larger than x.
+ ///
+ /// Assumes `y.len() >= x.len()`.
+ fn karatsuba_uneven_mul(x: &[Limb], mut y: &[Limb]) -> Vec<Limb> {
+ let mut result = Vec::<Limb>::default();
+ result.resize(x.len() + y.len(), 0);
+
+ // This effectively is like grade-school multiplication between
+ // two numbers, except we're using splits on `y`, and the intermediate
+ // step is a Karatsuba multiplication.
+ let mut start = 0;
+ while !y.is_empty() {
+ let m = x.len().min(y.len());
+ let (yl, yh) = karatsuba_split(y, m);
+ let prod = karatsuba_mul(x, yl);
+ iadd_impl(&mut result, &prod, start);
+ y = yh;
+ start += m;
+ }
+ small::normalize(&mut result);
+
+ result
+ }
+
+ /// Forwarder to the proper Karatsuba algorithm.
+ #[inline]
+ fn karatsuba_mul_fwd(x: &[Limb], y: &[Limb]) -> Vec<Limb> {
+ if x.len() < y.len() {
+ karatsuba_mul(x, y)
+ } else {
+ karatsuba_mul(y, x)
+ }
+ }
+
+ /// MulAssign bigint to bigint.
+ #[inline]
+ pub fn imul(x: &mut Vec<Limb>, y: &[Limb]) {
+ if y.len() == 1 {
+ small::imul(x, y[0]);
+ } else {
+ // We're not really in a condition where using Karatsuba
+ // multiplication makes sense, so we're just going to use long
+ // division. ~20% speedup compared to:
+ // *x = karatsuba_mul_fwd(x, y);
+ *x = karatsuba_mul_fwd(x, y);
+ }
+ }
+} // large
+
+// TRAITS
+// ------
+
+/// Traits for shared operations for big integers.
+///
+/// None of these are implemented using normal traits, since these
+/// are very expensive operations, and we want to deliberately
+/// and explicitly use these functions.
+pub(crate) trait Math: Clone + Sized + Default {
+ // DATA
+
+ /// Get access to the underlying data
+ fn data(&self) -> &Vec<Limb>;
+
+ /// Get access to the underlying data
+ fn data_mut(&mut self) -> &mut Vec<Limb>;
+
+ // RELATIVE OPERATIONS
+
+ /// Compare self to y.
+ #[inline]
+ fn compare(&self, y: &Self) -> cmp::Ordering {
+ large::compare(self.data(), y.data())
+ }
+
+ // PROPERTIES
+
+ /// Get the high 64-bits from the bigint and if there are remaining bits.
+ #[inline]
+ fn hi64(&self) -> (u64, bool) {
+ self.data().as_slice().hi64()
+ }
+
+ /// Calculate the bit-length of the big-integer.
+ /// Returns usize::max_value() if the value overflows,
+ /// IE, if `self.data().len() > usize::max_value() / 8`.
+ #[inline]
+ fn bit_length(&self) -> usize {
+ small::bit_length(self.data())
+ }
+
+ // INTEGER CONVERSIONS
+
+ /// Create new big integer from u64.
+ #[inline]
+ fn from_u64(x: u64) -> Self {
+ let mut v = Self::default();
+ let slc = split_u64(x);
+ v.data_mut().extend_from_slice(&slc);
+ v.normalize();
+ v
+ }
+
+ // NORMALIZE
+
+ /// Normalize the integer, so any leading zero values are removed.
+ #[inline]
+ fn normalize(&mut self) {
+ small::normalize(self.data_mut());
+ }
+
+ // ADDITION
+
+ /// AddAssign small integer.
+ #[inline]
+ fn iadd_small(&mut self, y: Limb) {
+ small::iadd(self.data_mut(), y);
+ }
+
+ // MULTIPLICATION
+
+ /// MulAssign small integer.
+ #[inline]
+ fn imul_small(&mut self, y: Limb) {
+ small::imul(self.data_mut(), y);
+ }
+
+ /// Multiply by a power of 2.
+ #[inline]
+ fn imul_pow2(&mut self, n: u32) {
+ self.ishl(n as usize);
+ }
+
+ /// Multiply by a power of 5.
+ #[inline]
+ fn imul_pow5(&mut self, n: u32) {
+ small::imul_pow5(self.data_mut(), n);
+ }
+
+ /// MulAssign by a power of 10.
+ #[inline]
+ fn imul_pow10(&mut self, n: u32) {
+ self.imul_pow5(n);
+ self.imul_pow2(n);
+ }
+
+ // SHIFTS
+
+ /// Shift-left the entire buffer n bits.
+ #[inline]
+ fn ishl(&mut self, n: usize) {
+ small::ishl(self.data_mut(), n);
+ }
+}
diff --git a/third_party/rust/serde_json/src/lexical/mod.rs b/third_party/rust/serde_json/src/lexical/mod.rs
new file mode 100644
index 0000000000..b1a45e218d
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/mod.rs
@@ -0,0 +1,38 @@
+// The code in this module is derived from the `lexical` crate by @Alexhuszagh
+// which the author condensed into this minimal subset for use in serde_json.
+// For the serde_json use case we care more about reliably round tripping all
+// possible floating point values than about parsing any arbitrarily long string
+// of digits with perfect accuracy, as the latter would take a high cost in
+// compile time and performance.
+//
+// Dual licensed as MIT and Apache 2.0 just like the rest of serde_json, but
+// copyright Alexander Huszagh.
+
+//! Fast, minimal float-parsing algorithm.
+
+// MODULES
+pub(crate) mod algorithm;
+mod bhcomp;
+mod bignum;
+mod cached;
+mod cached_float80;
+mod digit;
+mod errors;
+pub(crate) mod exponent;
+pub(crate) mod float;
+mod large_powers;
+pub(crate) mod math;
+pub(crate) mod num;
+pub(crate) mod parse;
+pub(crate) mod rounding;
+mod shift;
+mod small_powers;
+
+#[cfg(limb_width_32)]
+mod large_powers32;
+
+#[cfg(limb_width_64)]
+mod large_powers64;
+
+// API
+pub use self::parse::{parse_concise_float, parse_truncated_float};
diff --git a/third_party/rust/serde_json/src/lexical/num.rs b/third_party/rust/serde_json/src/lexical/num.rs
new file mode 100644
index 0000000000..e47e003419
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/num.rs
@@ -0,0 +1,440 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Utilities for Rust numbers.
+
+use core::ops;
+
+/// Precalculated values of radix**i for i in range [0, arr.len()-1].
+/// Each value can be **exactly** represented as that type.
+const F32_POW10: [f32; 11] = [
+ 1.0,
+ 10.0,
+ 100.0,
+ 1000.0,
+ 10000.0,
+ 100000.0,
+ 1000000.0,
+ 10000000.0,
+ 100000000.0,
+ 1000000000.0,
+ 10000000000.0,
+];
+
+/// Precalculated values of radix**i for i in range [0, arr.len()-1].
+/// Each value can be **exactly** represented as that type.
+const F64_POW10: [f64; 23] = [
+ 1.0,
+ 10.0,
+ 100.0,
+ 1000.0,
+ 10000.0,
+ 100000.0,
+ 1000000.0,
+ 10000000.0,
+ 100000000.0,
+ 1000000000.0,
+ 10000000000.0,
+ 100000000000.0,
+ 1000000000000.0,
+ 10000000000000.0,
+ 100000000000000.0,
+ 1000000000000000.0,
+ 10000000000000000.0,
+ 100000000000000000.0,
+ 1000000000000000000.0,
+ 10000000000000000000.0,
+ 100000000000000000000.0,
+ 1000000000000000000000.0,
+ 10000000000000000000000.0,
+];
+
+/// Type that can be converted to primitive with `as`.
+pub trait AsPrimitive: Sized + Copy + PartialOrd {
+ fn as_u32(self) -> u32;
+ fn as_u64(self) -> u64;
+ fn as_u128(self) -> u128;
+ fn as_usize(self) -> usize;
+ fn as_f32(self) -> f32;
+ fn as_f64(self) -> f64;
+}
+
+macro_rules! as_primitive_impl {
+ ($($ty:ident)*) => {
+ $(
+ impl AsPrimitive for $ty {
+ #[inline]
+ fn as_u32(self) -> u32 {
+ self as u32
+ }
+
+ #[inline]
+ fn as_u64(self) -> u64 {
+ self as u64
+ }
+
+ #[inline]
+ fn as_u128(self) -> u128 {
+ self as u128
+ }
+
+ #[inline]
+ fn as_usize(self) -> usize {
+ self as usize
+ }
+
+ #[inline]
+ fn as_f32(self) -> f32 {
+ self as f32
+ }
+
+ #[inline]
+ fn as_f64(self) -> f64 {
+ self as f64
+ }
+ }
+ )*
+ };
+}
+
+as_primitive_impl! { u32 u64 u128 usize f32 f64 }
+
+/// An interface for casting between machine scalars.
+pub trait AsCast: AsPrimitive {
+ /// Creates a number from another value that can be converted into
+ /// a primitive via the `AsPrimitive` trait.
+ fn as_cast<N: AsPrimitive>(n: N) -> Self;
+}
+
+macro_rules! as_cast_impl {
+ ($ty:ident, $method:ident) => {
+ impl AsCast for $ty {
+ #[inline]
+ fn as_cast<N: AsPrimitive>(n: N) -> Self {
+ n.$method()
+ }
+ }
+ };
+}
+
+as_cast_impl!(u32, as_u32);
+as_cast_impl!(u64, as_u64);
+as_cast_impl!(u128, as_u128);
+as_cast_impl!(usize, as_usize);
+as_cast_impl!(f32, as_f32);
+as_cast_impl!(f64, as_f64);
+
+/// Numerical type trait.
+pub trait Number: AsCast + ops::Add<Output = Self> {}
+
+macro_rules! number_impl {
+ ($($ty:ident)*) => {
+ $(
+ impl Number for $ty {}
+ )*
+ };
+}
+
+number_impl! { u32 u64 u128 usize f32 f64 }
+
+/// Defines a trait that supports integral operations.
+pub trait Integer: Number + ops::BitAnd<Output = Self> + ops::Shr<i32, Output = Self> {
+ const ZERO: Self;
+}
+
+macro_rules! integer_impl {
+ ($($ty:tt)*) => {
+ $(
+ impl Integer for $ty {
+ const ZERO: Self = 0;
+ }
+ )*
+ };
+}
+
+integer_impl! { u32 u64 u128 usize }
+
+/// Type trait for the mantissa type.
+pub trait Mantissa: Integer {
+ /// Mask to extract the high bits from the integer.
+ const HIMASK: Self;
+ /// Mask to extract the low bits from the integer.
+ const LOMASK: Self;
+ /// Full size of the integer, in bits.
+ const FULL: i32;
+ /// Half size of the integer, in bits.
+ const HALF: i32 = Self::FULL / 2;
+}
+
+impl Mantissa for u64 {
+ const HIMASK: u64 = 0xFFFFFFFF00000000;
+ const LOMASK: u64 = 0x00000000FFFFFFFF;
+ const FULL: i32 = 64;
+}
+
+/// Get exact exponent limit for radix.
+pub trait Float: Number {
+ /// Unsigned type of the same size.
+ type Unsigned: Integer;
+
+ /// Literal zero.
+ const ZERO: Self;
+ /// Maximum number of digits that can contribute in the mantissa.
+ ///
+ /// We can exactly represent a float in radix `b` from radix 2 if
+ /// `b` is divisible by 2. This function calculates the exact number of
+ /// digits required to exactly represent that float.
+ ///
+ /// According to the "Handbook of Floating Point Arithmetic",
+ /// for IEEE754, with emin being the min exponent, p2 being the
+ /// precision, and b being the radix, the number of digits follows as:
+ ///
+ /// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋`
+ ///
+ /// For f32, this follows as:
+ /// emin = -126
+ /// p2 = 24
+ ///
+ /// For f64, this follows as:
+ /// emin = -1022
+ /// p2 = 53
+ ///
+ /// In Python:
+ /// `-emin + p2 + math.floor((emin+1)*math.log(2, b) - math.log(1-2**(-p2), b))`
+ ///
+ /// This was used to calculate the maximum number of digits for [2, 36].
+ const MAX_DIGITS: usize;
+
+ // MASKS
+
+ /// Bitmask for the sign bit.
+ const SIGN_MASK: Self::Unsigned;
+ /// Bitmask for the exponent, including the hidden bit.
+ const EXPONENT_MASK: Self::Unsigned;
+ /// Bitmask for the hidden bit in exponent, which is an implicit 1 in the fraction.
+ const HIDDEN_BIT_MASK: Self::Unsigned;
+ /// Bitmask for the mantissa (fraction), excluding the hidden bit.
+ const MANTISSA_MASK: Self::Unsigned;
+
+ // PROPERTIES
+
+ /// Positive infinity as bits.
+ const INFINITY_BITS: Self::Unsigned;
+ /// Positive infinity as bits.
+ const NEGATIVE_INFINITY_BITS: Self::Unsigned;
+ /// Size of the significand (mantissa) without hidden bit.
+ const MANTISSA_SIZE: i32;
+ /// Bias of the exponet
+ const EXPONENT_BIAS: i32;
+ /// Exponent portion of a denormal float.
+ const DENORMAL_EXPONENT: i32;
+ /// Maximum exponent value in float.
+ const MAX_EXPONENT: i32;
+
+ // ROUNDING
+
+ /// Default number of bits to shift (or 64 - mantissa size - 1).
+ const DEFAULT_SHIFT: i32;
+ /// Mask to determine if a full-carry occurred (1 in bit above hidden bit).
+ const CARRY_MASK: u64;
+
+ /// Get min and max exponent limits (exact) from radix.
+ fn exponent_limit() -> (i32, i32);
+
+ /// Get the number of digits that can be shifted from exponent to mantissa.
+ fn mantissa_limit() -> i32;
+
+ // Re-exported methods from std.
+ fn pow10(self, n: i32) -> Self;
+ fn from_bits(u: Self::Unsigned) -> Self;
+ fn to_bits(self) -> Self::Unsigned;
+ fn is_sign_positive(self) -> bool;
+ fn is_sign_negative(self) -> bool;
+
+ /// Returns true if the float is a denormal.
+ #[inline]
+ fn is_denormal(self) -> bool {
+ self.to_bits() & Self::EXPONENT_MASK == Self::Unsigned::ZERO
+ }
+
+ /// Returns true if the float is a NaN or Infinite.
+ #[inline]
+ fn is_special(self) -> bool {
+ self.to_bits() & Self::EXPONENT_MASK == Self::EXPONENT_MASK
+ }
+
+ /// Returns true if the float is infinite.
+ #[inline]
+ fn is_inf(self) -> bool {
+ self.is_special() && (self.to_bits() & Self::MANTISSA_MASK) == Self::Unsigned::ZERO
+ }
+
+ /// Get exponent component from the float.
+ #[inline]
+ fn exponent(self) -> i32 {
+ if self.is_denormal() {
+ return Self::DENORMAL_EXPONENT;
+ }
+
+ let bits = self.to_bits();
+ let biased_e = ((bits & Self::EXPONENT_MASK) >> Self::MANTISSA_SIZE).as_u32();
+ biased_e as i32 - Self::EXPONENT_BIAS
+ }
+
+ /// Get mantissa (significand) component from float.
+ #[inline]
+ fn mantissa(self) -> Self::Unsigned {
+ let bits = self.to_bits();
+ let s = bits & Self::MANTISSA_MASK;
+ if !self.is_denormal() {
+ s + Self::HIDDEN_BIT_MASK
+ } else {
+ s
+ }
+ }
+
+ /// Get next greater float for a positive float.
+ /// Value must be >= 0.0 and < INFINITY.
+ #[inline]
+ fn next_positive(self) -> Self {
+ debug_assert!(self.is_sign_positive() && !self.is_inf());
+ Self::from_bits(self.to_bits() + Self::Unsigned::as_cast(1u32))
+ }
+
+ /// Round a positive number to even.
+ #[inline]
+ fn round_positive_even(self) -> Self {
+ if self.mantissa() & Self::Unsigned::as_cast(1u32) == Self::Unsigned::as_cast(1u32) {
+ self.next_positive()
+ } else {
+ self
+ }
+ }
+}
+
+impl Float for f32 {
+ type Unsigned = u32;
+
+ const ZERO: f32 = 0.0;
+ const MAX_DIGITS: usize = 114;
+ const SIGN_MASK: u32 = 0x80000000;
+ const EXPONENT_MASK: u32 = 0x7F800000;
+ const HIDDEN_BIT_MASK: u32 = 0x00800000;
+ const MANTISSA_MASK: u32 = 0x007FFFFF;
+ const INFINITY_BITS: u32 = 0x7F800000;
+ const NEGATIVE_INFINITY_BITS: u32 = Self::INFINITY_BITS | Self::SIGN_MASK;
+ const MANTISSA_SIZE: i32 = 23;
+ const EXPONENT_BIAS: i32 = 127 + Self::MANTISSA_SIZE;
+ const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
+ const MAX_EXPONENT: i32 = 0xFF - Self::EXPONENT_BIAS;
+ const DEFAULT_SHIFT: i32 = u64::FULL - f32::MANTISSA_SIZE - 1;
+ const CARRY_MASK: u64 = 0x1000000;
+
+ #[inline]
+ fn exponent_limit() -> (i32, i32) {
+ (-10, 10)
+ }
+
+ #[inline]
+ fn mantissa_limit() -> i32 {
+ 7
+ }
+
+ #[inline]
+ fn pow10(self, n: i32) -> f32 {
+ // Check the exponent is within bounds in debug builds.
+ debug_assert!({
+ let (min, max) = Self::exponent_limit();
+ n >= min && n <= max
+ });
+
+ if n > 0 {
+ self * F32_POW10[n as usize]
+ } else {
+ self / F32_POW10[-n as usize]
+ }
+ }
+
+ #[inline]
+ fn from_bits(u: u32) -> f32 {
+ f32::from_bits(u)
+ }
+
+ #[inline]
+ fn to_bits(self) -> u32 {
+ f32::to_bits(self)
+ }
+
+ #[inline]
+ fn is_sign_positive(self) -> bool {
+ f32::is_sign_positive(self)
+ }
+
+ #[inline]
+ fn is_sign_negative(self) -> bool {
+ f32::is_sign_negative(self)
+ }
+}
+
+impl Float for f64 {
+ type Unsigned = u64;
+
+ const ZERO: f64 = 0.0;
+ const MAX_DIGITS: usize = 769;
+ const SIGN_MASK: u64 = 0x8000000000000000;
+ const EXPONENT_MASK: u64 = 0x7FF0000000000000;
+ const HIDDEN_BIT_MASK: u64 = 0x0010000000000000;
+ const MANTISSA_MASK: u64 = 0x000FFFFFFFFFFFFF;
+ const INFINITY_BITS: u64 = 0x7FF0000000000000;
+ const NEGATIVE_INFINITY_BITS: u64 = Self::INFINITY_BITS | Self::SIGN_MASK;
+ const MANTISSA_SIZE: i32 = 52;
+ const EXPONENT_BIAS: i32 = 1023 + Self::MANTISSA_SIZE;
+ const DENORMAL_EXPONENT: i32 = 1 - Self::EXPONENT_BIAS;
+ const MAX_EXPONENT: i32 = 0x7FF - Self::EXPONENT_BIAS;
+ const DEFAULT_SHIFT: i32 = u64::FULL - f64::MANTISSA_SIZE - 1;
+ const CARRY_MASK: u64 = 0x20000000000000;
+
+ #[inline]
+ fn exponent_limit() -> (i32, i32) {
+ (-22, 22)
+ }
+
+ #[inline]
+ fn mantissa_limit() -> i32 {
+ 15
+ }
+
+ #[inline]
+ fn pow10(self, n: i32) -> f64 {
+ // Check the exponent is within bounds in debug builds.
+ debug_assert!({
+ let (min, max) = Self::exponent_limit();
+ n >= min && n <= max
+ });
+
+ if n > 0 {
+ self * F64_POW10[n as usize]
+ } else {
+ self / F64_POW10[-n as usize]
+ }
+ }
+
+ #[inline]
+ fn from_bits(u: u64) -> f64 {
+ f64::from_bits(u)
+ }
+
+ #[inline]
+ fn to_bits(self) -> u64 {
+ f64::to_bits(self)
+ }
+
+ #[inline]
+ fn is_sign_positive(self) -> bool {
+ f64::is_sign_positive(self)
+ }
+
+ #[inline]
+ fn is_sign_negative(self) -> bool {
+ f64::is_sign_negative(self)
+ }
+}
diff --git a/third_party/rust/serde_json/src/lexical/parse.rs b/third_party/rust/serde_json/src/lexical/parse.rs
new file mode 100644
index 0000000000..e3d7f1e871
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/parse.rs
@@ -0,0 +1,83 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+use super::algorithm::*;
+use super::bhcomp::*;
+use super::digit::*;
+use super::exponent::*;
+use super::num::*;
+
+// PARSERS
+// -------
+
+/// Parse float for which the entire integer and fraction parts fit into a 64
+/// bit mantissa.
+pub fn parse_concise_float<F>(mantissa: u64, mant_exp: i32) -> F
+where
+ F: Float,
+{
+ if let Some(float) = fast_path(mantissa, mant_exp) {
+ return float;
+ }
+
+ // Moderate path (use an extended 80-bit representation).
+ let truncated = false;
+ let (fp, valid) = moderate_path::<F>(mantissa, mant_exp, truncated);
+ if valid {
+ return fp.into_float::<F>();
+ }
+
+ let b = fp.into_downward_float::<F>();
+ if b.is_special() {
+ // We have a non-finite number, we get to leave early.
+ return b;
+ }
+
+ // Slow path, fast path didn't work.
+ let mut buffer = itoa::Buffer::new();
+ let integer = buffer.format(mantissa).as_bytes();
+ let fraction = &[];
+ bhcomp(b, integer, fraction, mant_exp)
+}
+
+/// Parse float from extracted float components.
+///
+/// * `integer` - Slice containing the integer digits.
+/// * `fraction` - Slice containing the fraction digits.
+/// * `exponent` - Parsed, 32-bit exponent.
+///
+/// Precondition: The integer must not have leading zeros.
+pub fn parse_truncated_float<F>(integer: &[u8], mut fraction: &[u8], exponent: i32) -> F
+where
+ F: Float,
+{
+ // Trim trailing zeroes from the fraction part.
+ while fraction.last() == Some(&b'0') {
+ fraction = &fraction[..fraction.len() - 1];
+ }
+
+ // Calculate the number of truncated digits.
+ let mut truncated = 0;
+ let mut mantissa: u64 = 0;
+ let mut iter = integer.iter().chain(fraction);
+ for &c in &mut iter {
+ mantissa = match add_digit(mantissa, to_digit(c).unwrap()) {
+ Some(v) => v,
+ None => {
+ truncated = 1 + iter.count();
+ break;
+ }
+ };
+ }
+
+ let mant_exp = mantissa_exponent(exponent, fraction.len(), truncated);
+ let is_truncated = true;
+
+ fallback_path(
+ integer,
+ fraction,
+ mantissa,
+ exponent,
+ mant_exp,
+ is_truncated,
+ )
+}
diff --git a/third_party/rust/serde_json/src/lexical/rounding.rs b/third_party/rust/serde_json/src/lexical/rounding.rs
new file mode 100644
index 0000000000..6ec1292aa5
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/rounding.rs
@@ -0,0 +1,231 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Defines rounding schemes for floating-point numbers.
+
+use super::float::ExtendedFloat;
+use super::num::*;
+use super::shift::*;
+use core::mem;
+
+// MASKS
+
+/// Calculate a scalar factor of 2 above the halfway point.
+#[inline]
+pub(crate) fn nth_bit(n: u64) -> u64 {
+ let bits: u64 = mem::size_of::<u64>() as u64 * 8;
+ debug_assert!(n < bits, "nth_bit() overflow in shl.");
+
+ 1 << n
+}
+
+/// Generate a bitwise mask for the lower `n` bits.
+#[inline]
+pub(crate) fn lower_n_mask(n: u64) -> u64 {
+ let bits: u64 = mem::size_of::<u64>() as u64 * 8;
+ debug_assert!(n <= bits, "lower_n_mask() overflow in shl.");
+
+ if n == bits {
+ u64::max_value()
+ } else {
+ (1 << n) - 1
+ }
+}
+
+/// Calculate the halfway point for the lower `n` bits.
+#[inline]
+pub(crate) fn lower_n_halfway(n: u64) -> u64 {
+ let bits: u64 = mem::size_of::<u64>() as u64 * 8;
+ debug_assert!(n <= bits, "lower_n_halfway() overflow in shl.");
+
+ if n == 0 {
+ 0
+ } else {
+ nth_bit(n - 1)
+ }
+}
+
+/// Calculate a bitwise mask with `n` 1 bits starting at the `bit` position.
+#[inline]
+pub(crate) fn internal_n_mask(bit: u64, n: u64) -> u64 {
+ let bits: u64 = mem::size_of::<u64>() as u64 * 8;
+ debug_assert!(bit <= bits, "internal_n_halfway() overflow in shl.");
+ debug_assert!(n <= bits, "internal_n_halfway() overflow in shl.");
+ debug_assert!(bit >= n, "internal_n_halfway() overflow in sub.");
+
+ lower_n_mask(bit) ^ lower_n_mask(bit - n)
+}
+
+// NEAREST ROUNDING
+
+// Shift right N-bytes and round to the nearest.
+//
+// Return if we are above halfway and if we are halfway.
+#[inline]
+pub(crate) fn round_nearest(fp: &mut ExtendedFloat, shift: i32) -> (bool, bool) {
+ // Extract the truncated bits using mask.
+ // Calculate if the value of the truncated bits are either above
+ // the mid-way point, or equal to it.
+ //
+ // For example, for 4 truncated bytes, the mask would be b1111
+ // and the midway point would be b1000.
+ let mask: u64 = lower_n_mask(shift as u64);
+ let halfway: u64 = lower_n_halfway(shift as u64);
+
+ let truncated_bits = fp.mant & mask;
+ let is_above = truncated_bits > halfway;
+ let is_halfway = truncated_bits == halfway;
+
+ // Bit shift so the leading bit is in the hidden bit.
+ overflowing_shr(fp, shift);
+
+ (is_above, is_halfway)
+}
+
+// Tie rounded floating point to event.
+#[inline]
+pub(crate) fn tie_even(fp: &mut ExtendedFloat, is_above: bool, is_halfway: bool) {
+ // Extract the last bit after shifting (and determine if it is odd).
+ let is_odd = fp.mant & 1 == 1;
+
+ // Calculate if we need to roundup.
+ // We need to roundup if we are above halfway, or if we are odd
+ // and at half-way (need to tie-to-even).
+ if is_above || (is_odd && is_halfway) {
+ fp.mant += 1;
+ }
+}
+
+// Shift right N-bytes and round nearest, tie-to-even.
+//
+// Floating-point arithmetic uses round to nearest, ties to even,
+// which rounds to the nearest value, if the value is halfway in between,
+// round to an even value.
+#[inline]
+pub(crate) fn round_nearest_tie_even(fp: &mut ExtendedFloat, shift: i32) {
+ let (is_above, is_halfway) = round_nearest(fp, shift);
+ tie_even(fp, is_above, is_halfway);
+}
+
+// DIRECTED ROUNDING
+
+// Shift right N-bytes and round towards a direction.
+//
+// Return if we have any truncated bytes.
+#[inline]
+fn round_toward(fp: &mut ExtendedFloat, shift: i32) -> bool {
+ let mask: u64 = lower_n_mask(shift as u64);
+ let truncated_bits = fp.mant & mask;
+
+ // Bit shift so the leading bit is in the hidden bit.
+ overflowing_shr(fp, shift);
+
+ truncated_bits != 0
+}
+
+// Round down.
+#[inline]
+fn downard(_: &mut ExtendedFloat, _: bool) {}
+
+// Shift right N-bytes and round toward zero.
+//
+// Floating-point arithmetic defines round toward zero, which rounds
+// towards positive zero.
+#[inline]
+pub(crate) fn round_downward(fp: &mut ExtendedFloat, shift: i32) {
+ // Bit shift so the leading bit is in the hidden bit.
+ // No rounding schemes, so we just ignore everything else.
+ let is_truncated = round_toward(fp, shift);
+ downard(fp, is_truncated);
+}
+
+// ROUND TO FLOAT
+
+// Shift the ExtendedFloat fraction to the fraction bits in a native float.
+//
+// Floating-point arithmetic uses round to nearest, ties to even,
+// which rounds to the nearest value, if the value is halfway in between,
+// round to an even value.
+#[inline]
+pub(crate) fn round_to_float<F, Algorithm>(fp: &mut ExtendedFloat, algorithm: Algorithm)
+where
+ F: Float,
+ Algorithm: FnOnce(&mut ExtendedFloat, i32),
+{
+ // Calculate the difference to allow a single calculation
+ // rather than a loop, to minimize the number of ops required.
+ // This does underflow detection.
+ let final_exp = fp.exp + F::DEFAULT_SHIFT;
+ if final_exp < F::DENORMAL_EXPONENT {
+ // We would end up with a denormal exponent, try to round to more
+ // digits. Only shift right if we can avoid zeroing out the value,
+ // which requires the exponent diff to be < M::BITS. The value
+ // is already normalized, so we shouldn't have any issue zeroing
+ // out the value.
+ let diff = F::DENORMAL_EXPONENT - fp.exp;
+ if diff <= u64::FULL {
+ // We can avoid underflow, can get a valid representation.
+ algorithm(fp, diff);
+ } else {
+ // Certain underflow, assign literal 0s.
+ fp.mant = 0;
+ fp.exp = 0;
+ }
+ } else {
+ algorithm(fp, F::DEFAULT_SHIFT);
+ }
+
+ if fp.mant & F::CARRY_MASK == F::CARRY_MASK {
+ // Roundup carried over to 1 past the hidden bit.
+ shr(fp, 1);
+ }
+}
+
+// AVOID OVERFLOW/UNDERFLOW
+
+// Avoid overflow for large values, shift left as needed.
+//
+// Shift until a 1-bit is in the hidden bit, if the mantissa is not 0.
+#[inline]
+pub(crate) fn avoid_overflow<F>(fp: &mut ExtendedFloat)
+where
+ F: Float,
+{
+ // Calculate the difference to allow a single calculation
+ // rather than a loop, minimizing the number of ops required.
+ if fp.exp >= F::MAX_EXPONENT {
+ let diff = fp.exp - F::MAX_EXPONENT;
+ if diff <= F::MANTISSA_SIZE {
+ // Our overflow mask needs to start at the hidden bit, or at
+ // `F::MANTISSA_SIZE+1`, and needs to have `diff+1` bits set,
+ // to see if our value overflows.
+ let bit = (F::MANTISSA_SIZE + 1) as u64;
+ let n = (diff + 1) as u64;
+ let mask = internal_n_mask(bit, n);
+ if (fp.mant & mask) == 0 {
+ // If we have no 1-bit in the hidden-bit position,
+ // which is index 0, we need to shift 1.
+ let shift = diff + 1;
+ shl(fp, shift);
+ }
+ }
+ }
+}
+
+// ROUND TO NATIVE
+
+// Round an extended-precision float to a native float representation.
+#[inline]
+pub(crate) fn round_to_native<F, Algorithm>(fp: &mut ExtendedFloat, algorithm: Algorithm)
+where
+ F: Float,
+ Algorithm: FnOnce(&mut ExtendedFloat, i32),
+{
+ // Shift all the way left, to ensure a consistent representation.
+ // The following right-shifts do not work for a non-normalized number.
+ fp.normalize();
+
+ // Round so the fraction is in a native mantissa representation,
+ // and avoid overflow/underflow.
+ round_to_float::<F, _>(fp, algorithm);
+ avoid_overflow::<F>(fp);
+}
diff --git a/third_party/rust/serde_json/src/lexical/shift.rs b/third_party/rust/serde_json/src/lexical/shift.rs
new file mode 100644
index 0000000000..a0bae01e0f
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/shift.rs
@@ -0,0 +1,46 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Bit-shift helpers.
+
+use super::float::ExtendedFloat;
+use core::mem;
+
+// Shift extended-precision float right `shift` bytes.
+#[inline]
+pub(crate) fn shr(fp: &mut ExtendedFloat, shift: i32) {
+ let bits: u64 = mem::size_of::<u64>() as u64 * 8;
+ debug_assert!((shift as u64) < bits, "shr() overflow in shift right.");
+
+ fp.mant >>= shift;
+ fp.exp += shift;
+}
+
+// Shift extended-precision float right `shift` bytes.
+//
+// Accepts when the shift is the same as the type size, and
+// sets the value to 0.
+#[inline]
+pub(crate) fn overflowing_shr(fp: &mut ExtendedFloat, shift: i32) {
+ let bits: u64 = mem::size_of::<u64>() as u64 * 8;
+ debug_assert!(
+ (shift as u64) <= bits,
+ "overflowing_shr() overflow in shift right."
+ );
+
+ fp.mant = if shift as u64 == bits {
+ 0
+ } else {
+ fp.mant >> shift
+ };
+ fp.exp += shift;
+}
+
+// Shift extended-precision float left `shift` bytes.
+#[inline]
+pub(crate) fn shl(fp: &mut ExtendedFloat, shift: i32) {
+ let bits: u64 = mem::size_of::<u64>() as u64 * 8;
+ debug_assert!((shift as u64) < bits, "shl() overflow in shift left.");
+
+ fp.mant <<= shift;
+ fp.exp -= shift;
+}
diff --git a/third_party/rust/serde_json/src/lexical/small_powers.rs b/third_party/rust/serde_json/src/lexical/small_powers.rs
new file mode 100644
index 0000000000..219d826116
--- /dev/null
+++ b/third_party/rust/serde_json/src/lexical/small_powers.rs
@@ -0,0 +1,70 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+//! Pre-computed small powers.
+
+// 32 BIT
+#[cfg(limb_width_32)]
+pub(crate) const POW5_32: [u32; 14] = [
+ 1, 5, 25, 125, 625, 3125, 15625, 78125, 390625, 1953125, 9765625, 48828125, 244140625,
+ 1220703125,
+];
+
+#[cfg(limb_width_32)]
+pub(crate) const POW10_32: [u32; 10] = [
+ 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000,
+];
+
+// 64 BIT
+#[cfg(limb_width_64)]
+pub(crate) const POW5_64: [u64; 28] = [
+ 1,
+ 5,
+ 25,
+ 125,
+ 625,
+ 3125,
+ 15625,
+ 78125,
+ 390625,
+ 1953125,
+ 9765625,
+ 48828125,
+ 244140625,
+ 1220703125,
+ 6103515625,
+ 30517578125,
+ 152587890625,
+ 762939453125,
+ 3814697265625,
+ 19073486328125,
+ 95367431640625,
+ 476837158203125,
+ 2384185791015625,
+ 11920928955078125,
+ 59604644775390625,
+ 298023223876953125,
+ 1490116119384765625,
+ 7450580596923828125,
+];
+pub(crate) const POW10_64: [u64; 20] = [
+ 1,
+ 10,
+ 100,
+ 1000,
+ 10000,
+ 100000,
+ 1000000,
+ 10000000,
+ 100000000,
+ 1000000000,
+ 10000000000,
+ 100000000000,
+ 1000000000000,
+ 10000000000000,
+ 100000000000000,
+ 1000000000000000,
+ 10000000000000000,
+ 100000000000000000,
+ 1000000000000000000,
+ 10000000000000000000,
+];
diff --git a/third_party/rust/serde_json/src/lib.rs b/third_party/rust/serde_json/src/lib.rs
new file mode 100644
index 0000000000..48d0fe2191
--- /dev/null
+++ b/third_party/rust/serde_json/src/lib.rs
@@ -0,0 +1,421 @@
+//! # Serde JSON
+//!
+//! JSON is a ubiquitous open-standard format that uses human-readable text to
+//! transmit data objects consisting of key-value pairs.
+//!
+//! ```json
+//! {
+//! "name": "John Doe",
+//! "age": 43,
+//! "address": {
+//! "street": "10 Downing Street",
+//! "city": "London"
+//! },
+//! "phones": [
+//! "+44 1234567",
+//! "+44 2345678"
+//! ]
+//! }
+//! ```
+//!
+//! There are three common ways that you might find yourself needing to work
+//! with JSON data in Rust.
+//!
+//! - **As text data.** An unprocessed string of JSON data that you receive on
+//! an HTTP endpoint, read from a file, or prepare to send to a remote
+//! server.
+//! - **As an untyped or loosely typed representation.** Maybe you want to
+//! check that some JSON data is valid before passing it on, but without
+//! knowing the structure of what it contains. Or you want to do very basic
+//! manipulations like insert a key in a particular spot.
+//! - **As a strongly typed Rust data structure.** When you expect all or most
+//! of your data to conform to a particular structure and want to get real
+//! work done without JSON's loosey-goosey nature tripping you up.
+//!
+//! Serde JSON provides efficient, flexible, safe ways of converting data
+//! between each of these representations.
+//!
+//! # Operating on untyped JSON values
+//!
+//! Any valid JSON data can be manipulated in the following recursive enum
+//! representation. This data structure is [`serde_json::Value`][value].
+//!
+//! ```
+//! # use serde_json::{Number, Map};
+//! #
+//! # #[allow(dead_code)]
+//! enum Value {
+//! Null,
+//! Bool(bool),
+//! Number(Number),
+//! String(String),
+//! Array(Vec<Value>),
+//! Object(Map<String, Value>),
+//! }
+//! ```
+//!
+//! A string of JSON data can be parsed into a `serde_json::Value` by the
+//! [`serde_json::from_str`][from_str] function. There is also
+//! [`from_slice`][from_slice] for parsing from a byte slice &[u8] and
+//! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or
+//! a TCP stream.
+//!
+//! ```
+//! use serde_json::{Result, Value};
+//!
+//! fn untyped_example() -> Result<()> {
+//! // Some JSON input data as a &str. Maybe this comes from the user.
+//! let data = r#"
+//! {
+//! "name": "John Doe",
+//! "age": 43,
+//! "phones": [
+//! "+44 1234567",
+//! "+44 2345678"
+//! ]
+//! }"#;
+//!
+//! // Parse the string of data into serde_json::Value.
+//! let v: Value = serde_json::from_str(data)?;
+//!
+//! // Access parts of the data by indexing with square brackets.
+//! println!("Please call {} at the number {}", v["name"], v["phones"][0]);
+//!
+//! Ok(())
+//! }
+//! #
+//! # fn main() {
+//! # untyped_example().unwrap();
+//! # }
+//! ```
+//!
+//! The result of square bracket indexing like `v["name"]` is a borrow of the
+//! data at that index, so the type is `&Value`. A JSON map can be indexed with
+//! string keys, while a JSON array can be indexed with integer keys. If the
+//! type of the data is not right for the type with which it is being indexed,
+//! or if a map does not contain the key being indexed, or if the index into a
+//! vector is out of bounds, the returned element is `Value::Null`.
+//!
+//! When a `Value` is printed, it is printed as a JSON string. So in the code
+//! above, the output looks like `Please call "John Doe" at the number "+44
+//! 1234567"`. The quotation marks appear because `v["name"]` is a `&Value`
+//! containing a JSON string and its JSON representation is `"John Doe"`.
+//! Printing as a plain string without quotation marks involves converting from
+//! a JSON string to a Rust string with [`as_str()`] or avoiding the use of
+//! `Value` as described in the following section.
+//!
+//! [`as_str()`]: crate::Value::as_str
+//!
+//! The `Value` representation is sufficient for very basic tasks but can be
+//! tedious to work with for anything more significant. Error handling is
+//! verbose to implement correctly, for example imagine trying to detect the
+//! presence of unrecognized fields in the input data. The compiler is powerless
+//! to help you when you make a mistake, for example imagine typoing `v["name"]`
+//! as `v["nmae"]` in one of the dozens of places it is used in your code.
+//!
+//! # Parsing JSON as strongly typed data structures
+//!
+//! Serde provides a powerful way of mapping JSON data into Rust data structures
+//! largely automatically.
+//!
+//! ```
+//! use serde::{Deserialize, Serialize};
+//! use serde_json::Result;
+//!
+//! #[derive(Serialize, Deserialize)]
+//! struct Person {
+//! name: String,
+//! age: u8,
+//! phones: Vec<String>,
+//! }
+//!
+//! fn typed_example() -> Result<()> {
+//! // Some JSON input data as a &str. Maybe this comes from the user.
+//! let data = r#"
+//! {
+//! "name": "John Doe",
+//! "age": 43,
+//! "phones": [
+//! "+44 1234567",
+//! "+44 2345678"
+//! ]
+//! }"#;
+//!
+//! // Parse the string of data into a Person object. This is exactly the
+//! // same function as the one that produced serde_json::Value above, but
+//! // now we are asking it for a Person as output.
+//! let p: Person = serde_json::from_str(data)?;
+//!
+//! // Do things just like with any other Rust data structure.
+//! println!("Please call {} at the number {}", p.name, p.phones[0]);
+//!
+//! Ok(())
+//! }
+//! #
+//! # fn main() {
+//! # typed_example().unwrap();
+//! # }
+//! ```
+//!
+//! This is the same `serde_json::from_str` function as before, but this time we
+//! assign the return value to a variable of type `Person` so Serde will
+//! automatically interpret the input data as a `Person` and produce informative
+//! error messages if the layout does not conform to what a `Person` is expected
+//! to look like.
+//!
+//! Any type that implements Serde's `Deserialize` trait can be deserialized
+//! this way. This includes built-in Rust standard library types like `Vec<T>`
+//! and `HashMap<K, V>`, as well as any structs or enums annotated with
+//! `#[derive(Deserialize)]`.
+//!
+//! Once we have `p` of type `Person`, our IDE and the Rust compiler can help us
+//! use it correctly like they do for any other Rust code. The IDE can
+//! autocomplete field names to prevent typos, which was impossible in the
+//! `serde_json::Value` representation. And the Rust compiler can check that
+//! when we write `p.phones[0]`, then `p.phones` is guaranteed to be a
+//! `Vec<String>` so indexing into it makes sense and produces a `String`.
+//!
+//! # Constructing JSON values
+//!
+//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value`
+//! objects with very natural JSON syntax.
+//!
+//! ```
+//! use serde_json::json;
+//!
+//! fn main() {
+//! // The type of `john` is `serde_json::Value`
+//! let john = json!({
+//! "name": "John Doe",
+//! "age": 43,
+//! "phones": [
+//! "+44 1234567",
+//! "+44 2345678"
+//! ]
+//! });
+//!
+//! println!("first phone number: {}", john["phones"][0]);
+//!
+//! // Convert to a string of JSON and print it out
+//! println!("{}", john.to_string());
+//! }
+//! ```
+//!
+//! The `Value::to_string()` function converts a `serde_json::Value` into a
+//! `String` of JSON text.
+//!
+//! One neat thing about the `json!` macro is that variables and expressions can
+//! be interpolated directly into the JSON value as you are building it. Serde
+//! will check at compile time that the value you are interpolating is able to
+//! be represented as JSON.
+//!
+//! ```
+//! # use serde_json::json;
+//! #
+//! # fn random_phone() -> u16 { 0 }
+//! #
+//! let full_name = "John Doe";
+//! let age_last_year = 42;
+//!
+//! // The type of `john` is `serde_json::Value`
+//! let john = json!({
+//! "name": full_name,
+//! "age": age_last_year + 1,
+//! "phones": [
+//! format!("+44 {}", random_phone())
+//! ]
+//! });
+//! ```
+//!
+//! This is amazingly convenient, but we have the problem we had before with
+//! `Value`: the IDE and Rust compiler cannot help us if we get it wrong. Serde
+//! JSON provides a better way of serializing strongly-typed data structures
+//! into JSON text.
+//!
+//! # Creating JSON by serializing data structures
+//!
+//! A data structure can be converted to a JSON string by
+//! [`serde_json::to_string`][to_string]. There is also
+//! [`serde_json::to_vec`][to_vec] which serializes to a `Vec<u8>` and
+//! [`serde_json::to_writer`][to_writer] which serializes to any `io::Write`
+//! such as a File or a TCP stream.
+//!
+//! ```
+//! use serde::{Deserialize, Serialize};
+//! use serde_json::Result;
+//!
+//! #[derive(Serialize, Deserialize)]
+//! struct Address {
+//! street: String,
+//! city: String,
+//! }
+//!
+//! fn print_an_address() -> Result<()> {
+//! // Some data structure.
+//! let address = Address {
+//! street: "10 Downing Street".to_owned(),
+//! city: "London".to_owned(),
+//! };
+//!
+//! // Serialize it to a JSON string.
+//! let j = serde_json::to_string(&address)?;
+//!
+//! // Print, write to a file, or send to an HTTP server.
+//! println!("{}", j);
+//!
+//! Ok(())
+//! }
+//! #
+//! # fn main() {
+//! # print_an_address().unwrap();
+//! # }
+//! ```
+//!
+//! Any type that implements Serde's `Serialize` trait can be serialized this
+//! way. This includes built-in Rust standard library types like `Vec<T>` and
+//! `HashMap<K, V>`, as well as any structs or enums annotated with
+//! `#[derive(Serialize)]`.
+//!
+//! # No-std support
+//!
+//! As long as there is a memory allocator, it is possible to use serde_json
+//! without the rest of the Rust standard library. Disable the default "std"
+//! feature and enable the "alloc" feature:
+//!
+//! ```toml
+//! [dependencies]
+//! serde_json = { version = "1.0", default-features = false, features = ["alloc"] }
+//! ```
+//!
+//! For JSON support in Serde without a memory allocator, please see the
+//! [`serde-json-core`] crate.
+//!
+//! [value]: crate::value::Value
+//! [from_str]: crate::de::from_str
+//! [from_slice]: crate::de::from_slice
+//! [from_reader]: crate::de::from_reader
+//! [to_string]: crate::ser::to_string
+//! [to_vec]: crate::ser::to_vec
+//! [to_writer]: crate::ser::to_writer
+//! [macro]: crate::json
+//! [`serde-json-core`]: https://github.com/rust-embedded-community/serde-json-core
+
+#![doc(html_root_url = "https://docs.rs/serde_json/1.0.93")]
+// Ignored clippy lints
+#![allow(
+ clippy::collapsible_else_if,
+ clippy::comparison_chain,
+ clippy::deprecated_cfg_attr,
+ clippy::doc_markdown,
+ clippy::excessive_precision,
+ clippy::explicit_auto_deref,
+ clippy::float_cmp,
+ clippy::manual_range_contains,
+ clippy::match_like_matches_macro,
+ clippy::match_single_binding,
+ clippy::needless_doctest_main,
+ clippy::needless_late_init,
+ // clippy bug: https://github.com/rust-lang/rust-clippy/issues/8366
+ clippy::ptr_arg,
+ clippy::return_self_not_must_use,
+ clippy::transmute_ptr_to_ptr,
+ clippy::unnecessary_wraps,
+ // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
+ clippy::unnested_or_patterns,
+)]
+// Ignored clippy_pedantic lints
+#![allow(
+ // buggy
+ clippy::iter_not_returning_iterator, // https://github.com/rust-lang/rust-clippy/issues/8285
+ // Deserializer::from_str, into_iter
+ clippy::should_implement_trait,
+ // integer and float ser/de requires these sorts of casts
+ clippy::cast_possible_truncation,
+ clippy::cast_possible_wrap,
+ clippy::cast_precision_loss,
+ clippy::cast_sign_loss,
+ // correctly used
+ clippy::enum_glob_use,
+ clippy::if_not_else,
+ clippy::integer_division,
+ clippy::map_err_ignore,
+ clippy::match_same_arms,
+ clippy::similar_names,
+ clippy::unused_self,
+ clippy::wildcard_imports,
+ // things are often more readable this way
+ clippy::cast_lossless,
+ clippy::module_name_repetitions,
+ clippy::redundant_else,
+ clippy::shadow_unrelated,
+ clippy::single_match_else,
+ clippy::too_many_lines,
+ clippy::unreadable_literal,
+ clippy::unseparated_literal_suffix,
+ clippy::use_self,
+ clippy::zero_prefixed_literal,
+ // we support older compilers
+ clippy::checked_conversions,
+ clippy::mem_replace_with_default,
+ // noisy
+ clippy::missing_errors_doc,
+ clippy::must_use_candidate,
+)]
+#![allow(non_upper_case_globals)]
+#![deny(missing_docs)]
+#![cfg_attr(not(feature = "std"), no_std)]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+
+extern crate alloc;
+
+#[cfg(feature = "std")]
+#[doc(inline)]
+pub use crate::de::from_reader;
+#[doc(inline)]
+pub use crate::de::{from_slice, from_str, Deserializer, StreamDeserializer};
+#[doc(inline)]
+pub use crate::error::{Error, Result};
+#[doc(inline)]
+pub use crate::ser::{to_string, to_string_pretty, to_vec, to_vec_pretty};
+#[cfg(feature = "std")]
+#[doc(inline)]
+pub use crate::ser::{to_writer, to_writer_pretty, Serializer};
+#[doc(inline)]
+pub use crate::value::{from_value, to_value, Map, Number, Value};
+
+// We only use our own error type; no need for From conversions provided by the
+// standard library's try! macro. This reduces lines of LLVM IR by 4%.
+macro_rules! tri {
+ ($e:expr $(,)?) => {
+ match $e {
+ core::result::Result::Ok(val) => val,
+ core::result::Result::Err(err) => return core::result::Result::Err(err),
+ }
+ };
+}
+
+#[macro_use]
+mod macros;
+
+pub mod de;
+pub mod error;
+pub mod map;
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub mod ser;
+#[cfg(not(feature = "std"))]
+mod ser;
+pub mod value;
+
+mod features_check;
+
+mod io;
+#[cfg(feature = "std")]
+mod iter;
+#[cfg(feature = "float_roundtrip")]
+mod lexical;
+mod number;
+mod read;
+
+#[cfg(feature = "raw_value")]
+mod raw;
diff --git a/third_party/rust/serde_json/src/macros.rs b/third_party/rust/serde_json/src/macros.rs
new file mode 100644
index 0000000000..5287998b46
--- /dev/null
+++ b/third_party/rust/serde_json/src/macros.rs
@@ -0,0 +1,303 @@
+/// Construct a `serde_json::Value` from a JSON literal.
+///
+/// ```
+/// # use serde_json::json;
+/// #
+/// let value = json!({
+/// "code": 200,
+/// "success": true,
+/// "payload": {
+/// "features": [
+/// "serde",
+/// "json"
+/// ]
+/// }
+/// });
+/// ```
+///
+/// Variables or expressions can be interpolated into the JSON literal. Any type
+/// interpolated into an array element or object value must implement Serde's
+/// `Serialize` trait, while any type interpolated into a object key must
+/// implement `Into<String>`. If the `Serialize` implementation of the
+/// interpolated type decides to fail, or if the interpolated type contains a
+/// map with non-string keys, the `json!` macro will panic.
+///
+/// ```
+/// # use serde_json::json;
+/// #
+/// let code = 200;
+/// let features = vec!["serde", "json"];
+///
+/// let value = json!({
+/// "code": code,
+/// "success": code == 200,
+/// "payload": {
+/// features[0]: features[1]
+/// }
+/// });
+/// ```
+///
+/// Trailing commas are allowed inside both arrays and objects.
+///
+/// ```
+/// # use serde_json::json;
+/// #
+/// let value = json!([
+/// "notice",
+/// "the",
+/// "trailing",
+/// "comma -->",
+/// ]);
+/// ```
+#[macro_export(local_inner_macros)]
+macro_rules! json {
+ // Hide distracting implementation details from the generated rustdoc.
+ ($($json:tt)+) => {
+ json_internal!($($json)+)
+ };
+}
+
+// Rocket relies on this because they export their own `json!` with a different
+// doc comment than ours, and various Rust bugs prevent them from calling our
+// `json!` from their `json!` so they call `json_internal!` directly. Check with
+// @SergioBenitez before making breaking changes to this macro.
+//
+// Changes are fine as long as `json_internal!` does not call any new helper
+// macros and can still be invoked as `json_internal!($($json)+)`.
+#[macro_export(local_inner_macros)]
+#[doc(hidden)]
+macro_rules! json_internal {
+ //////////////////////////////////////////////////////////////////////////
+ // TT muncher for parsing the inside of an array [...]. Produces a vec![...]
+ // of the elements.
+ //
+ // Must be invoked as: json_internal!(@array [] $($tt)*)
+ //////////////////////////////////////////////////////////////////////////
+
+ // Done with trailing comma.
+ (@array [$($elems:expr,)*]) => {
+ json_internal_vec![$($elems,)*]
+ };
+
+ // Done without trailing comma.
+ (@array [$($elems:expr),*]) => {
+ json_internal_vec![$($elems),*]
+ };
+
+ // Next element is `null`.
+ (@array [$($elems:expr,)*] null $($rest:tt)*) => {
+ json_internal!(@array [$($elems,)* json_internal!(null)] $($rest)*)
+ };
+
+ // Next element is `true`.
+ (@array [$($elems:expr,)*] true $($rest:tt)*) => {
+ json_internal!(@array [$($elems,)* json_internal!(true)] $($rest)*)
+ };
+
+ // Next element is `false`.
+ (@array [$($elems:expr,)*] false $($rest:tt)*) => {
+ json_internal!(@array [$($elems,)* json_internal!(false)] $($rest)*)
+ };
+
+ // Next element is an array.
+ (@array [$($elems:expr,)*] [$($array:tt)*] $($rest:tt)*) => {
+ json_internal!(@array [$($elems,)* json_internal!([$($array)*])] $($rest)*)
+ };
+
+ // Next element is a map.
+ (@array [$($elems:expr,)*] {$($map:tt)*} $($rest:tt)*) => {
+ json_internal!(@array [$($elems,)* json_internal!({$($map)*})] $($rest)*)
+ };
+
+ // Next element is an expression followed by comma.
+ (@array [$($elems:expr,)*] $next:expr, $($rest:tt)*) => {
+ json_internal!(@array [$($elems,)* json_internal!($next),] $($rest)*)
+ };
+
+ // Last element is an expression with no trailing comma.
+ (@array [$($elems:expr,)*] $last:expr) => {
+ json_internal!(@array [$($elems,)* json_internal!($last)])
+ };
+
+ // Comma after the most recent element.
+ (@array [$($elems:expr),*] , $($rest:tt)*) => {
+ json_internal!(@array [$($elems,)*] $($rest)*)
+ };
+
+ // Unexpected token after most recent element.
+ (@array [$($elems:expr),*] $unexpected:tt $($rest:tt)*) => {
+ json_unexpected!($unexpected)
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // TT muncher for parsing the inside of an object {...}. Each entry is
+ // inserted into the given map variable.
+ //
+ // Must be invoked as: json_internal!(@object $map () ($($tt)*) ($($tt)*))
+ //
+ // We require two copies of the input tokens so that we can match on one
+ // copy and trigger errors on the other copy.
+ //////////////////////////////////////////////////////////////////////////
+
+ // Done.
+ (@object $object:ident () () ()) => {};
+
+ // Insert the current entry followed by trailing comma.
+ (@object $object:ident [$($key:tt)+] ($value:expr) , $($rest:tt)*) => {
+ let _ = $object.insert(($($key)+).into(), $value);
+ json_internal!(@object $object () ($($rest)*) ($($rest)*));
+ };
+
+ // Current entry followed by unexpected token.
+ (@object $object:ident [$($key:tt)+] ($value:expr) $unexpected:tt $($rest:tt)*) => {
+ json_unexpected!($unexpected);
+ };
+
+ // Insert the last entry without trailing comma.
+ (@object $object:ident [$($key:tt)+] ($value:expr)) => {
+ let _ = $object.insert(($($key)+).into(), $value);
+ };
+
+ // Next value is `null`.
+ (@object $object:ident ($($key:tt)+) (: null $($rest:tt)*) $copy:tt) => {
+ json_internal!(@object $object [$($key)+] (json_internal!(null)) $($rest)*);
+ };
+
+ // Next value is `true`.
+ (@object $object:ident ($($key:tt)+) (: true $($rest:tt)*) $copy:tt) => {
+ json_internal!(@object $object [$($key)+] (json_internal!(true)) $($rest)*);
+ };
+
+ // Next value is `false`.
+ (@object $object:ident ($($key:tt)+) (: false $($rest:tt)*) $copy:tt) => {
+ json_internal!(@object $object [$($key)+] (json_internal!(false)) $($rest)*);
+ };
+
+ // Next value is an array.
+ (@object $object:ident ($($key:tt)+) (: [$($array:tt)*] $($rest:tt)*) $copy:tt) => {
+ json_internal!(@object $object [$($key)+] (json_internal!([$($array)*])) $($rest)*);
+ };
+
+ // Next value is a map.
+ (@object $object:ident ($($key:tt)+) (: {$($map:tt)*} $($rest:tt)*) $copy:tt) => {
+ json_internal!(@object $object [$($key)+] (json_internal!({$($map)*})) $($rest)*);
+ };
+
+ // Next value is an expression followed by comma.
+ (@object $object:ident ($($key:tt)+) (: $value:expr , $($rest:tt)*) $copy:tt) => {
+ json_internal!(@object $object [$($key)+] (json_internal!($value)) , $($rest)*);
+ };
+
+ // Last value is an expression with no trailing comma.
+ (@object $object:ident ($($key:tt)+) (: $value:expr) $copy:tt) => {
+ json_internal!(@object $object [$($key)+] (json_internal!($value)));
+ };
+
+ // Missing value for last entry. Trigger a reasonable error message.
+ (@object $object:ident ($($key:tt)+) (:) $copy:tt) => {
+ // "unexpected end of macro invocation"
+ json_internal!();
+ };
+
+ // Missing colon and value for last entry. Trigger a reasonable error
+ // message.
+ (@object $object:ident ($($key:tt)+) () $copy:tt) => {
+ // "unexpected end of macro invocation"
+ json_internal!();
+ };
+
+ // Misplaced colon. Trigger a reasonable error message.
+ (@object $object:ident () (: $($rest:tt)*) ($colon:tt $($copy:tt)*)) => {
+ // Takes no arguments so "no rules expected the token `:`".
+ json_unexpected!($colon);
+ };
+
+ // Found a comma inside a key. Trigger a reasonable error message.
+ (@object $object:ident ($($key:tt)*) (, $($rest:tt)*) ($comma:tt $($copy:tt)*)) => {
+ // Takes no arguments so "no rules expected the token `,`".
+ json_unexpected!($comma);
+ };
+
+ // Key is fully parenthesized. This avoids clippy double_parens false
+ // positives because the parenthesization may be necessary here.
+ (@object $object:ident () (($key:expr) : $($rest:tt)*) $copy:tt) => {
+ json_internal!(@object $object ($key) (: $($rest)*) (: $($rest)*));
+ };
+
+ // Refuse to absorb colon token into key expression.
+ (@object $object:ident ($($key:tt)*) (: $($unexpected:tt)+) $copy:tt) => {
+ json_expect_expr_comma!($($unexpected)+);
+ };
+
+ // Munch a token into the current key.
+ (@object $object:ident ($($key:tt)*) ($tt:tt $($rest:tt)*) $copy:tt) => {
+ json_internal!(@object $object ($($key)* $tt) ($($rest)*) ($($rest)*));
+ };
+
+ //////////////////////////////////////////////////////////////////////////
+ // The main implementation.
+ //
+ // Must be invoked as: json_internal!($($json)+)
+ //////////////////////////////////////////////////////////////////////////
+
+ (null) => {
+ $crate::Value::Null
+ };
+
+ (true) => {
+ $crate::Value::Bool(true)
+ };
+
+ (false) => {
+ $crate::Value::Bool(false)
+ };
+
+ ([]) => {
+ $crate::Value::Array(json_internal_vec![])
+ };
+
+ ([ $($tt:tt)+ ]) => {
+ $crate::Value::Array(json_internal!(@array [] $($tt)+))
+ };
+
+ ({}) => {
+ $crate::Value::Object($crate::Map::new())
+ };
+
+ ({ $($tt:tt)+ }) => {
+ $crate::Value::Object({
+ let mut object = $crate::Map::new();
+ json_internal!(@object object () ($($tt)+) ($($tt)+));
+ object
+ })
+ };
+
+ // Any Serialize type: numbers, strings, struct literals, variables etc.
+ // Must be below every other rule.
+ ($other:expr) => {
+ $crate::to_value(&$other).unwrap()
+ };
+}
+
+// The json_internal macro above cannot invoke vec directly because it uses
+// local_inner_macros. A vec invocation there would resolve to $crate::vec.
+// Instead invoke vec here outside of local_inner_macros.
+#[macro_export]
+#[doc(hidden)]
+macro_rules! json_internal_vec {
+ ($($content:tt)*) => {
+ vec![$($content)*]
+ };
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! json_unexpected {
+ () => {};
+}
+
+#[macro_export]
+#[doc(hidden)]
+macro_rules! json_expect_expr_comma {
+ ($e:expr , $($tt:tt)*) => {};
+}
diff --git a/third_party/rust/serde_json/src/map.rs b/third_party/rust/serde_json/src/map.rs
new file mode 100644
index 0000000000..3e8a3814c9
--- /dev/null
+++ b/third_party/rust/serde_json/src/map.rs
@@ -0,0 +1,940 @@
+//! A map of String to serde_json::Value.
+//!
+//! By default the map is backed by a [`BTreeMap`]. Enable the `preserve_order`
+//! feature of serde_json to use [`IndexMap`] instead.
+//!
+//! [`BTreeMap`]: https://doc.rust-lang.org/std/collections/struct.BTreeMap.html
+//! [`IndexMap`]: https://docs.rs/indexmap/*/indexmap/map/struct.IndexMap.html
+
+use crate::value::Value;
+use alloc::string::String;
+use core::borrow::Borrow;
+use core::fmt::{self, Debug};
+use core::hash::Hash;
+use core::iter::{FromIterator, FusedIterator};
+#[cfg(feature = "preserve_order")]
+use core::mem;
+use core::ops;
+use serde::de;
+
+#[cfg(not(feature = "preserve_order"))]
+use alloc::collections::{btree_map, BTreeMap};
+#[cfg(feature = "preserve_order")]
+use indexmap::{self, IndexMap};
+
+/// Represents a JSON key/value type.
+pub struct Map<K, V> {
+ map: MapImpl<K, V>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type MapImpl<K, V> = BTreeMap<K, V>;
+#[cfg(feature = "preserve_order")]
+type MapImpl<K, V> = IndexMap<K, V>;
+
+impl Map<String, Value> {
+ /// Makes a new empty Map.
+ #[inline]
+ pub fn new() -> Self {
+ Map {
+ map: MapImpl::new(),
+ }
+ }
+
+ /// Makes a new empty Map with the given initial capacity.
+ #[inline]
+ pub fn with_capacity(capacity: usize) -> Self {
+ Map {
+ #[cfg(not(feature = "preserve_order"))]
+ map: {
+ // does not support with_capacity
+ let _ = capacity;
+ BTreeMap::new()
+ },
+ #[cfg(feature = "preserve_order")]
+ map: IndexMap::with_capacity(capacity),
+ }
+ }
+
+ /// Clears the map, removing all values.
+ #[inline]
+ pub fn clear(&mut self) {
+ self.map.clear();
+ }
+
+ /// Returns a reference to the value corresponding to the key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but the ordering
+ /// on the borrowed form *must* match the ordering on the key type.
+ #[inline]
+ pub fn get<Q>(&self, key: &Q) -> Option<&Value>
+ where
+ String: Borrow<Q>,
+ Q: ?Sized + Ord + Eq + Hash,
+ {
+ self.map.get(key)
+ }
+
+ /// Returns true if the map contains a value for the specified key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but the ordering
+ /// on the borrowed form *must* match the ordering on the key type.
+ #[inline]
+ pub fn contains_key<Q>(&self, key: &Q) -> bool
+ where
+ String: Borrow<Q>,
+ Q: ?Sized + Ord + Eq + Hash,
+ {
+ self.map.contains_key(key)
+ }
+
+ /// Returns a mutable reference to the value corresponding to the key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but the ordering
+ /// on the borrowed form *must* match the ordering on the key type.
+ #[inline]
+ pub fn get_mut<Q>(&mut self, key: &Q) -> Option<&mut Value>
+ where
+ String: Borrow<Q>,
+ Q: ?Sized + Ord + Eq + Hash,
+ {
+ self.map.get_mut(key)
+ }
+
+ /// Returns the key-value pair matching the given key.
+ ///
+ /// The key may be any borrowed form of the map's key type, but the ordering
+ /// on the borrowed form *must* match the ordering on the key type.
+ #[inline]
+ #[cfg(any(feature = "preserve_order", not(no_btreemap_get_key_value)))]
+ pub fn get_key_value<Q>(&self, key: &Q) -> Option<(&String, &Value)>
+ where
+ String: Borrow<Q>,
+ Q: ?Sized + Ord + Eq + Hash,
+ {
+ self.map.get_key_value(key)
+ }
+
+ /// Inserts a key-value pair into the map.
+ ///
+ /// If the map did not have this key present, `None` is returned.
+ ///
+ /// If the map did have this key present, the value is updated, and the old
+ /// value is returned.
+ #[inline]
+ pub fn insert(&mut self, k: String, v: Value) -> Option<Value> {
+ self.map.insert(k, v)
+ }
+
+ /// Removes a key from the map, returning the value at the key if the key
+ /// was previously in the map.
+ ///
+ /// The key may be any borrowed form of the map's key type, but the ordering
+ /// on the borrowed form *must* match the ordering on the key type.
+ #[inline]
+ pub fn remove<Q>(&mut self, key: &Q) -> Option<Value>
+ where
+ String: Borrow<Q>,
+ Q: ?Sized + Ord + Eq + Hash,
+ {
+ #[cfg(feature = "preserve_order")]
+ return self.map.swap_remove(key);
+ #[cfg(not(feature = "preserve_order"))]
+ return self.map.remove(key);
+ }
+
+ /// Removes a key from the map, returning the stored key and value if the
+ /// key was previously in the map.
+ ///
+ /// The key may be any borrowed form of the map's key type, but the ordering
+ /// on the borrowed form *must* match the ordering on the key type.
+ pub fn remove_entry<Q>(&mut self, key: &Q) -> Option<(String, Value)>
+ where
+ String: Borrow<Q>,
+ Q: ?Sized + Ord + Eq + Hash,
+ {
+ #[cfg(any(feature = "preserve_order", not(no_btreemap_remove_entry)))]
+ return self.map.remove_entry(key);
+ #[cfg(all(
+ not(feature = "preserve_order"),
+ no_btreemap_remove_entry,
+ not(no_btreemap_get_key_value),
+ ))]
+ {
+ let (key, _value) = self.map.get_key_value(key)?;
+ let key = key.clone();
+ let value = self.map.remove::<String>(&key)?;
+ Some((key, value))
+ }
+ #[cfg(all(
+ not(feature = "preserve_order"),
+ no_btreemap_remove_entry,
+ no_btreemap_get_key_value,
+ ))]
+ {
+ use core::ops::{Bound, RangeBounds};
+
+ struct Key<'a, Q: ?Sized>(&'a Q);
+
+ impl<'a, Q: ?Sized> RangeBounds<Q> for Key<'a, Q> {
+ fn start_bound(&self) -> Bound<&Q> {
+ Bound::Included(self.0)
+ }
+ fn end_bound(&self) -> Bound<&Q> {
+ Bound::Included(self.0)
+ }
+ }
+
+ let mut range = self.map.range(Key(key));
+ let (key, _value) = range.next()?;
+ let key = key.clone();
+ let value = self.map.remove::<String>(&key)?;
+ Some((key, value))
+ }
+ }
+
+ /// Moves all elements from other into self, leaving other empty.
+ #[inline]
+ pub fn append(&mut self, other: &mut Self) {
+ #[cfg(feature = "preserve_order")]
+ self.map
+ .extend(mem::replace(&mut other.map, MapImpl::default()));
+ #[cfg(not(feature = "preserve_order"))]
+ self.map.append(&mut other.map);
+ }
+
+ /// Gets the given key's corresponding entry in the map for in-place
+ /// manipulation.
+ pub fn entry<S>(&mut self, key: S) -> Entry
+ where
+ S: Into<String>,
+ {
+ #[cfg(not(feature = "preserve_order"))]
+ use alloc::collections::btree_map::Entry as EntryImpl;
+ #[cfg(feature = "preserve_order")]
+ use indexmap::map::Entry as EntryImpl;
+
+ match self.map.entry(key.into()) {
+ EntryImpl::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
+ EntryImpl::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
+ }
+ }
+
+ /// Returns the number of elements in the map.
+ #[inline]
+ pub fn len(&self) -> usize {
+ self.map.len()
+ }
+
+ /// Returns true if the map contains no elements.
+ #[inline]
+ pub fn is_empty(&self) -> bool {
+ self.map.is_empty()
+ }
+
+ /// Gets an iterator over the entries of the map.
+ #[inline]
+ pub fn iter(&self) -> Iter {
+ Iter {
+ iter: self.map.iter(),
+ }
+ }
+
+ /// Gets a mutable iterator over the entries of the map.
+ #[inline]
+ pub fn iter_mut(&mut self) -> IterMut {
+ IterMut {
+ iter: self.map.iter_mut(),
+ }
+ }
+
+ /// Gets an iterator over the keys of the map.
+ #[inline]
+ pub fn keys(&self) -> Keys {
+ Keys {
+ iter: self.map.keys(),
+ }
+ }
+
+ /// Gets an iterator over the values of the map.
+ #[inline]
+ pub fn values(&self) -> Values {
+ Values {
+ iter: self.map.values(),
+ }
+ }
+
+ /// Gets an iterator over mutable values of the map.
+ #[inline]
+ pub fn values_mut(&mut self) -> ValuesMut {
+ ValuesMut {
+ iter: self.map.values_mut(),
+ }
+ }
+
+ /// Retains only the elements specified by the predicate.
+ ///
+ /// In other words, remove all pairs `(k, v)` such that `f(&k, &mut v)`
+ /// returns `false`.
+ #[cfg(not(no_btreemap_retain))]
+ #[inline]
+ pub fn retain<F>(&mut self, f: F)
+ where
+ F: FnMut(&String, &mut Value) -> bool,
+ {
+ self.map.retain(f);
+ }
+}
+
+#[allow(clippy::derivable_impls)] // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7655
+impl Default for Map<String, Value> {
+ #[inline]
+ fn default() -> Self {
+ Map {
+ map: MapImpl::new(),
+ }
+ }
+}
+
+impl Clone for Map<String, Value> {
+ #[inline]
+ fn clone(&self) -> Self {
+ Map {
+ map: self.map.clone(),
+ }
+ }
+
+ #[inline]
+ fn clone_from(&mut self, source: &Self) {
+ self.map.clone_from(&source.map);
+ }
+}
+
+impl PartialEq for Map<String, Value> {
+ #[inline]
+ fn eq(&self, other: &Self) -> bool {
+ self.map.eq(&other.map)
+ }
+}
+
+impl Eq for Map<String, Value> {}
+
+/// Access an element of this map. Panics if the given key is not present in the
+/// map.
+///
+/// ```
+/// # use serde_json::Value;
+/// #
+/// # let val = &Value::String("".to_owned());
+/// # let _ =
+/// match val {
+/// Value::String(s) => Some(s.as_str()),
+/// Value::Array(arr) => arr[0].as_str(),
+/// Value::Object(map) => map["type"].as_str(),
+/// _ => None,
+/// }
+/// # ;
+/// ```
+impl<'a, Q> ops::Index<&'a Q> for Map<String, Value>
+where
+ String: Borrow<Q>,
+ Q: ?Sized + Ord + Eq + Hash,
+{
+ type Output = Value;
+
+ fn index(&self, index: &Q) -> &Value {
+ self.map.index(index)
+ }
+}
+
+/// Mutably access an element of this map. Panics if the given key is not
+/// present in the map.
+///
+/// ```
+/// # use serde_json::json;
+/// #
+/// # let mut map = serde_json::Map::new();
+/// # map.insert("key".to_owned(), serde_json::Value::Null);
+/// #
+/// map["key"] = json!("value");
+/// ```
+impl<'a, Q> ops::IndexMut<&'a Q> for Map<String, Value>
+where
+ String: Borrow<Q>,
+ Q: ?Sized + Ord + Eq + Hash,
+{
+ fn index_mut(&mut self, index: &Q) -> &mut Value {
+ self.map.get_mut(index).expect("no entry found for key")
+ }
+}
+
+impl Debug for Map<String, Value> {
+ #[inline]
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ self.map.fmt(formatter)
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl serde::ser::Serialize for Map<String, Value> {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::ser::Serializer,
+ {
+ use serde::ser::SerializeMap;
+ let mut map = tri!(serializer.serialize_map(Some(self.len())));
+ for (k, v) in self {
+ tri!(map.serialize_entry(k, v));
+ }
+ map.end()
+ }
+}
+
+impl<'de> de::Deserialize<'de> for Map<String, Value> {
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ struct Visitor;
+
+ impl<'de> de::Visitor<'de> for Visitor {
+ type Value = Map<String, Value>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a map")
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(Map::new())
+ }
+
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ #[inline]
+ fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: de::MapAccess<'de>,
+ {
+ let mut values = Map::new();
+
+ while let Some((key, value)) = tri!(visitor.next_entry()) {
+ values.insert(key, value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ deserializer.deserialize_map(Visitor)
+ }
+}
+
+impl FromIterator<(String, Value)> for Map<String, Value> {
+ fn from_iter<T>(iter: T) -> Self
+ where
+ T: IntoIterator<Item = (String, Value)>,
+ {
+ Map {
+ map: FromIterator::from_iter(iter),
+ }
+ }
+}
+
+impl Extend<(String, Value)> for Map<String, Value> {
+ fn extend<T>(&mut self, iter: T)
+ where
+ T: IntoIterator<Item = (String, Value)>,
+ {
+ self.map.extend(iter);
+ }
+}
+
+macro_rules! delegate_iterator {
+ (($name:ident $($generics:tt)*) => $item:ty) => {
+ impl $($generics)* Iterator for $name $($generics)* {
+ type Item = $item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next()
+ }
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+ }
+
+ impl $($generics)* DoubleEndedIterator for $name $($generics)* {
+ #[inline]
+ fn next_back(&mut self) -> Option<Self::Item> {
+ self.iter.next_back()
+ }
+ }
+
+ impl $($generics)* ExactSizeIterator for $name $($generics)* {
+ #[inline]
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+ }
+
+ impl $($generics)* FusedIterator for $name $($generics)* {}
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// A view into a single entry in a map, which may either be vacant or occupied.
+/// This enum is constructed from the [`entry`] method on [`Map`].
+///
+/// [`entry`]: struct.Map.html#method.entry
+/// [`Map`]: struct.Map.html
+pub enum Entry<'a> {
+ /// A vacant Entry.
+ Vacant(VacantEntry<'a>),
+ /// An occupied Entry.
+ Occupied(OccupiedEntry<'a>),
+}
+
+/// A vacant Entry. It is part of the [`Entry`] enum.
+///
+/// [`Entry`]: enum.Entry.html
+pub struct VacantEntry<'a> {
+ vacant: VacantEntryImpl<'a>,
+}
+
+/// An occupied Entry. It is part of the [`Entry`] enum.
+///
+/// [`Entry`]: enum.Entry.html
+pub struct OccupiedEntry<'a> {
+ occupied: OccupiedEntryImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type VacantEntryImpl<'a> = btree_map::VacantEntry<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type VacantEntryImpl<'a> = indexmap::map::VacantEntry<'a, String, Value>;
+
+#[cfg(not(feature = "preserve_order"))]
+type OccupiedEntryImpl<'a> = btree_map::OccupiedEntry<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type OccupiedEntryImpl<'a> = indexmap::map::OccupiedEntry<'a, String, Value>;
+
+impl<'a> Entry<'a> {
+ /// Returns a reference to this entry's key.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// let mut map = serde_json::Map::new();
+ /// assert_eq!(map.entry("serde").key(), &"serde");
+ /// ```
+ pub fn key(&self) -> &String {
+ match self {
+ Entry::Vacant(e) => e.key(),
+ Entry::Occupied(e) => e.key(),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting the default if empty, and
+ /// returns a mutable reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let mut map = serde_json::Map::new();
+ /// map.entry("serde").or_insert(json!(12));
+ ///
+ /// assert_eq!(map["serde"], 12);
+ /// ```
+ pub fn or_insert(self, default: Value) -> &'a mut Value {
+ match self {
+ Entry::Vacant(entry) => entry.insert(default),
+ Entry::Occupied(entry) => entry.into_mut(),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting the result of the default
+ /// function if empty, and returns a mutable reference to the value in the
+ /// entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let mut map = serde_json::Map::new();
+ /// map.entry("serde").or_insert_with(|| json!("hoho"));
+ ///
+ /// assert_eq!(map["serde"], "hoho".to_owned());
+ /// ```
+ pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
+ where
+ F: FnOnce() -> Value,
+ {
+ match self {
+ Entry::Vacant(entry) => entry.insert(default()),
+ Entry::Occupied(entry) => entry.into_mut(),
+ }
+ }
+
+ /// Provides in-place mutable access to an occupied entry before any
+ /// potential inserts into the map.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let mut map = serde_json::Map::new();
+ /// map.entry("serde")
+ /// .and_modify(|e| *e = json!("rust"))
+ /// .or_insert(json!("cpp"));
+ ///
+ /// assert_eq!(map["serde"], "cpp");
+ ///
+ /// map.entry("serde")
+ /// .and_modify(|e| *e = json!("rust"))
+ /// .or_insert(json!("cpp"));
+ ///
+ /// assert_eq!(map["serde"], "rust");
+ /// ```
+ pub fn and_modify<F>(self, f: F) -> Self
+ where
+ F: FnOnce(&mut Value),
+ {
+ match self {
+ Entry::Occupied(mut entry) => {
+ f(entry.get_mut());
+ Entry::Occupied(entry)
+ }
+ Entry::Vacant(entry) => Entry::Vacant(entry),
+ }
+ }
+}
+
+impl<'a> VacantEntry<'a> {
+ /// Gets a reference to the key that would be used when inserting a value
+ /// through the VacantEntry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::map::Entry;
+ ///
+ /// let mut map = serde_json::Map::new();
+ ///
+ /// match map.entry("serde") {
+ /// Entry::Vacant(vacant) => {
+ /// assert_eq!(vacant.key(), &"serde");
+ /// }
+ /// Entry::Occupied(_) => unimplemented!(),
+ /// }
+ /// ```
+ #[inline]
+ pub fn key(&self) -> &String {
+ self.vacant.key()
+ }
+
+ /// Sets the value of the entry with the VacantEntry's key, and returns a
+ /// mutable reference to it.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// use serde_json::map::Entry;
+ ///
+ /// let mut map = serde_json::Map::new();
+ ///
+ /// match map.entry("serde") {
+ /// Entry::Vacant(vacant) => {
+ /// vacant.insert(json!("hoho"));
+ /// }
+ /// Entry::Occupied(_) => unimplemented!(),
+ /// }
+ /// ```
+ #[inline]
+ pub fn insert(self, value: Value) -> &'a mut Value {
+ self.vacant.insert(value)
+ }
+}
+
+impl<'a> OccupiedEntry<'a> {
+ /// Gets a reference to the key in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// use serde_json::map::Entry;
+ ///
+ /// let mut map = serde_json::Map::new();
+ /// map.insert("serde".to_owned(), json!(12));
+ ///
+ /// match map.entry("serde") {
+ /// Entry::Occupied(occupied) => {
+ /// assert_eq!(occupied.key(), &"serde");
+ /// }
+ /// Entry::Vacant(_) => unimplemented!(),
+ /// }
+ /// ```
+ #[inline]
+ pub fn key(&self) -> &String {
+ self.occupied.key()
+ }
+
+ /// Gets a reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// use serde_json::map::Entry;
+ ///
+ /// let mut map = serde_json::Map::new();
+ /// map.insert("serde".to_owned(), json!(12));
+ ///
+ /// match map.entry("serde") {
+ /// Entry::Occupied(occupied) => {
+ /// assert_eq!(occupied.get(), 12);
+ /// }
+ /// Entry::Vacant(_) => unimplemented!(),
+ /// }
+ /// ```
+ #[inline]
+ pub fn get(&self) -> &Value {
+ self.occupied.get()
+ }
+
+ /// Gets a mutable reference to the value in the entry.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// use serde_json::map::Entry;
+ ///
+ /// let mut map = serde_json::Map::new();
+ /// map.insert("serde".to_owned(), json!([1, 2, 3]));
+ ///
+ /// match map.entry("serde") {
+ /// Entry::Occupied(mut occupied) => {
+ /// occupied.get_mut().as_array_mut().unwrap().push(json!(4));
+ /// }
+ /// Entry::Vacant(_) => unimplemented!(),
+ /// }
+ ///
+ /// assert_eq!(map["serde"].as_array().unwrap().len(), 4);
+ /// ```
+ #[inline]
+ pub fn get_mut(&mut self) -> &mut Value {
+ self.occupied.get_mut()
+ }
+
+ /// Converts the entry into a mutable reference to its value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// use serde_json::map::Entry;
+ ///
+ /// let mut map = serde_json::Map::new();
+ /// map.insert("serde".to_owned(), json!([1, 2, 3]));
+ ///
+ /// match map.entry("serde") {
+ /// Entry::Occupied(mut occupied) => {
+ /// occupied.into_mut().as_array_mut().unwrap().push(json!(4));
+ /// }
+ /// Entry::Vacant(_) => unimplemented!(),
+ /// }
+ ///
+ /// assert_eq!(map["serde"].as_array().unwrap().len(), 4);
+ /// ```
+ #[inline]
+ pub fn into_mut(self) -> &'a mut Value {
+ self.occupied.into_mut()
+ }
+
+ /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns
+ /// the entry's old value.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// use serde_json::map::Entry;
+ ///
+ /// let mut map = serde_json::Map::new();
+ /// map.insert("serde".to_owned(), json!(12));
+ ///
+ /// match map.entry("serde") {
+ /// Entry::Occupied(mut occupied) => {
+ /// assert_eq!(occupied.insert(json!(13)), 12);
+ /// assert_eq!(occupied.get(), 13);
+ /// }
+ /// Entry::Vacant(_) => unimplemented!(),
+ /// }
+ /// ```
+ #[inline]
+ pub fn insert(&mut self, value: Value) -> Value {
+ self.occupied.insert(value)
+ }
+
+ /// Takes the value of the entry out of the map, and returns it.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// use serde_json::map::Entry;
+ ///
+ /// let mut map = serde_json::Map::new();
+ /// map.insert("serde".to_owned(), json!(12));
+ ///
+ /// match map.entry("serde") {
+ /// Entry::Occupied(occupied) => {
+ /// assert_eq!(occupied.remove(), 12);
+ /// }
+ /// Entry::Vacant(_) => unimplemented!(),
+ /// }
+ /// ```
+ #[inline]
+ pub fn remove(self) -> Value {
+ #[cfg(feature = "preserve_order")]
+ return self.occupied.swap_remove();
+ #[cfg(not(feature = "preserve_order"))]
+ return self.occupied.remove();
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+impl<'a> IntoIterator for &'a Map<String, Value> {
+ type Item = (&'a String, &'a Value);
+ type IntoIter = Iter<'a>;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ Iter {
+ iter: self.map.iter(),
+ }
+ }
+}
+
+/// An iterator over a serde_json::Map's entries.
+pub struct Iter<'a> {
+ iter: IterImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type IterImpl<'a> = btree_map::Iter<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type IterImpl<'a> = indexmap::map::Iter<'a, String, Value>;
+
+delegate_iterator!((Iter<'a>) => (&'a String, &'a Value));
+
+//////////////////////////////////////////////////////////////////////////////
+
+impl<'a> IntoIterator for &'a mut Map<String, Value> {
+ type Item = (&'a String, &'a mut Value);
+ type IntoIter = IterMut<'a>;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ IterMut {
+ iter: self.map.iter_mut(),
+ }
+ }
+}
+
+/// A mutable iterator over a serde_json::Map's entries.
+pub struct IterMut<'a> {
+ iter: IterMutImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type IterMutImpl<'a> = btree_map::IterMut<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type IterMutImpl<'a> = indexmap::map::IterMut<'a, String, Value>;
+
+delegate_iterator!((IterMut<'a>) => (&'a String, &'a mut Value));
+
+//////////////////////////////////////////////////////////////////////////////
+
+impl IntoIterator for Map<String, Value> {
+ type Item = (String, Value);
+ type IntoIter = IntoIter;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ IntoIter {
+ iter: self.map.into_iter(),
+ }
+ }
+}
+
+/// An owning iterator over a serde_json::Map's entries.
+pub struct IntoIter {
+ iter: IntoIterImpl,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type IntoIterImpl = btree_map::IntoIter<String, Value>;
+#[cfg(feature = "preserve_order")]
+type IntoIterImpl = indexmap::map::IntoIter<String, Value>;
+
+delegate_iterator!((IntoIter) => (String, Value));
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// An iterator over a serde_json::Map's keys.
+pub struct Keys<'a> {
+ iter: KeysImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type KeysImpl<'a> = btree_map::Keys<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type KeysImpl<'a> = indexmap::map::Keys<'a, String, Value>;
+
+delegate_iterator!((Keys<'a>) => &'a String);
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// An iterator over a serde_json::Map's values.
+pub struct Values<'a> {
+ iter: ValuesImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type ValuesImpl<'a> = btree_map::Values<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type ValuesImpl<'a> = indexmap::map::Values<'a, String, Value>;
+
+delegate_iterator!((Values<'a>) => &'a Value);
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// A mutable iterator over a serde_json::Map's values.
+pub struct ValuesMut<'a> {
+ iter: ValuesMutImpl<'a>,
+}
+
+#[cfg(not(feature = "preserve_order"))]
+type ValuesMutImpl<'a> = btree_map::ValuesMut<'a, String, Value>;
+#[cfg(feature = "preserve_order")]
+type ValuesMutImpl<'a> = indexmap::map::ValuesMut<'a, String, Value>;
+
+delegate_iterator!((ValuesMut<'a>) => &'a mut Value);
diff --git a/third_party/rust/serde_json/src/number.rs b/third_party/rust/serde_json/src/number.rs
new file mode 100644
index 0000000000..21a76411cc
--- /dev/null
+++ b/third_party/rust/serde_json/src/number.rs
@@ -0,0 +1,745 @@
+use crate::de::ParserNumber;
+use crate::error::Error;
+#[cfg(feature = "arbitrary_precision")]
+use crate::error::ErrorCode;
+#[cfg(feature = "arbitrary_precision")]
+use alloc::borrow::ToOwned;
+#[cfg(feature = "arbitrary_precision")]
+use alloc::string::{String, ToString};
+use core::fmt::{self, Debug, Display};
+#[cfg(not(feature = "arbitrary_precision"))]
+use core::hash::{Hash, Hasher};
+use serde::de::{self, Unexpected, Visitor};
+#[cfg(feature = "arbitrary_precision")]
+use serde::de::{IntoDeserializer, MapAccess};
+use serde::{forward_to_deserialize_any, Deserialize, Deserializer, Serialize, Serializer};
+
+#[cfg(feature = "arbitrary_precision")]
+pub(crate) const TOKEN: &str = "$serde_json::private::Number";
+
+/// Represents a JSON number, whether integer or floating point.
+#[derive(Clone, PartialEq, Eq, Hash)]
+pub struct Number {
+ n: N,
+}
+
+#[cfg(not(feature = "arbitrary_precision"))]
+#[derive(Copy, Clone)]
+enum N {
+ PosInt(u64),
+ /// Always less than zero.
+ NegInt(i64),
+ /// Always finite.
+ Float(f64),
+}
+
+#[cfg(not(feature = "arbitrary_precision"))]
+impl PartialEq for N {
+ fn eq(&self, other: &Self) -> bool {
+ match (self, other) {
+ (N::PosInt(a), N::PosInt(b)) => a == b,
+ (N::NegInt(a), N::NegInt(b)) => a == b,
+ (N::Float(a), N::Float(b)) => a == b,
+ _ => false,
+ }
+ }
+}
+
+// Implementing Eq is fine since any float values are always finite.
+#[cfg(not(feature = "arbitrary_precision"))]
+impl Eq for N {}
+
+#[cfg(not(feature = "arbitrary_precision"))]
+impl Hash for N {
+ fn hash<H: Hasher>(&self, h: &mut H) {
+ match *self {
+ N::PosInt(i) => i.hash(h),
+ N::NegInt(i) => i.hash(h),
+ N::Float(f) => {
+ if f == 0.0f64 {
+ // There are 2 zero representations, +0 and -0, which
+ // compare equal but have different bits. We use the +0 hash
+ // for both so that hash(+0) == hash(-0).
+ 0.0f64.to_bits().hash(h);
+ } else {
+ f.to_bits().hash(h);
+ }
+ }
+ }
+ }
+}
+
+#[cfg(feature = "arbitrary_precision")]
+type N = String;
+
+impl Number {
+ /// Returns true if the `Number` is an integer between `i64::MIN` and
+ /// `i64::MAX`.
+ ///
+ /// For any Number on which `is_i64` returns true, `as_i64` is guaranteed to
+ /// return the integer value.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let big = i64::max_value() as u64 + 10;
+ /// let v = json!({ "a": 64, "b": big, "c": 256.0 });
+ ///
+ /// assert!(v["a"].is_i64());
+ ///
+ /// // Greater than i64::MAX.
+ /// assert!(!v["b"].is_i64());
+ ///
+ /// // Numbers with a decimal point are not considered integers.
+ /// assert!(!v["c"].is_i64());
+ /// ```
+ #[inline]
+ pub fn is_i64(&self) -> bool {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ match self.n {
+ N::PosInt(v) => v <= i64::max_value() as u64,
+ N::NegInt(_) => true,
+ N::Float(_) => false,
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ self.as_i64().is_some()
+ }
+
+ /// Returns true if the `Number` is an integer between zero and `u64::MAX`.
+ ///
+ /// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to
+ /// return the integer value.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
+ ///
+ /// assert!(v["a"].is_u64());
+ ///
+ /// // Negative integer.
+ /// assert!(!v["b"].is_u64());
+ ///
+ /// // Numbers with a decimal point are not considered integers.
+ /// assert!(!v["c"].is_u64());
+ /// ```
+ #[inline]
+ pub fn is_u64(&self) -> bool {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ match self.n {
+ N::PosInt(_) => true,
+ N::NegInt(_) | N::Float(_) => false,
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ self.as_u64().is_some()
+ }
+
+ /// Returns true if the `Number` can be represented by f64.
+ ///
+ /// For any Number on which `is_f64` returns true, `as_f64` is guaranteed to
+ /// return the floating point value.
+ ///
+ /// Currently this function returns true if and only if both `is_i64` and
+ /// `is_u64` return false but this is not a guarantee in the future.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
+ ///
+ /// assert!(v["a"].is_f64());
+ ///
+ /// // Integers.
+ /// assert!(!v["b"].is_f64());
+ /// assert!(!v["c"].is_f64());
+ /// ```
+ #[inline]
+ pub fn is_f64(&self) -> bool {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ match self.n {
+ N::Float(_) => true,
+ N::PosInt(_) | N::NegInt(_) => false,
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ {
+ for c in self.n.chars() {
+ if c == '.' || c == 'e' || c == 'E' {
+ return self.n.parse::<f64>().ok().map_or(false, f64::is_finite);
+ }
+ }
+ false
+ }
+ }
+
+ /// If the `Number` is an integer, represent it as i64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let big = i64::max_value() as u64 + 10;
+ /// let v = json!({ "a": 64, "b": big, "c": 256.0 });
+ ///
+ /// assert_eq!(v["a"].as_i64(), Some(64));
+ /// assert_eq!(v["b"].as_i64(), None);
+ /// assert_eq!(v["c"].as_i64(), None);
+ /// ```
+ #[inline]
+ pub fn as_i64(&self) -> Option<i64> {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ match self.n {
+ N::PosInt(n) => {
+ if n <= i64::max_value() as u64 {
+ Some(n as i64)
+ } else {
+ None
+ }
+ }
+ N::NegInt(n) => Some(n),
+ N::Float(_) => None,
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ self.n.parse().ok()
+ }
+
+ /// If the `Number` is an integer, represent it as u64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
+ ///
+ /// assert_eq!(v["a"].as_u64(), Some(64));
+ /// assert_eq!(v["b"].as_u64(), None);
+ /// assert_eq!(v["c"].as_u64(), None);
+ /// ```
+ #[inline]
+ pub fn as_u64(&self) -> Option<u64> {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ match self.n {
+ N::PosInt(n) => Some(n),
+ N::NegInt(_) | N::Float(_) => None,
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ self.n.parse().ok()
+ }
+
+ /// Represents the number as f64 if possible. Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
+ ///
+ /// assert_eq!(v["a"].as_f64(), Some(256.0));
+ /// assert_eq!(v["b"].as_f64(), Some(64.0));
+ /// assert_eq!(v["c"].as_f64(), Some(-64.0));
+ /// ```
+ #[inline]
+ pub fn as_f64(&self) -> Option<f64> {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ match self.n {
+ N::PosInt(n) => Some(n as f64),
+ N::NegInt(n) => Some(n as f64),
+ N::Float(n) => Some(n),
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ self.n.parse::<f64>().ok().filter(|float| float.is_finite())
+ }
+
+ /// Converts a finite `f64` to a `Number`. Infinite or NaN values are not JSON
+ /// numbers.
+ ///
+ /// ```
+ /// # use std::f64;
+ /// #
+ /// # use serde_json::Number;
+ /// #
+ /// assert!(Number::from_f64(256.0).is_some());
+ ///
+ /// assert!(Number::from_f64(f64::NAN).is_none());
+ /// ```
+ #[inline]
+ pub fn from_f64(f: f64) -> Option<Number> {
+ if f.is_finite() {
+ let n = {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ {
+ N::Float(f)
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ {
+ ryu::Buffer::new().format_finite(f).to_owned()
+ }
+ };
+ Some(Number { n })
+ } else {
+ None
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ /// Not public API. Only tests use this.
+ #[doc(hidden)]
+ #[inline]
+ pub fn from_string_unchecked(n: String) -> Self {
+ Number { n }
+ }
+}
+
+impl Display for Number {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self.n {
+ N::PosInt(u) => formatter.write_str(itoa::Buffer::new().format(u)),
+ N::NegInt(i) => formatter.write_str(itoa::Buffer::new().format(i)),
+ N::Float(f) => formatter.write_str(ryu::Buffer::new().format_finite(f)),
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ Display::fmt(&self.n, formatter)
+ }
+}
+
+impl Debug for Number {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "Number({})", self)
+ }
+}
+
+impl Serialize for Number {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match self.n {
+ N::PosInt(u) => serializer.serialize_u64(u),
+ N::NegInt(i) => serializer.serialize_i64(i),
+ N::Float(f) => serializer.serialize_f64(f),
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use serde::ser::SerializeStruct;
+
+ let mut s = serializer.serialize_struct(TOKEN, 1)?;
+ s.serialize_field(TOKEN, &self.n)?;
+ s.end()
+ }
+}
+
+impl<'de> Deserialize<'de> for Number {
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<Number, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct NumberVisitor;
+
+ impl<'de> Visitor<'de> for NumberVisitor {
+ type Value = Number;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a JSON number")
+ }
+
+ #[inline]
+ fn visit_i64<E>(self, value: i64) -> Result<Number, E> {
+ Ok(value.into())
+ }
+
+ #[inline]
+ fn visit_u64<E>(self, value: u64) -> Result<Number, E> {
+ Ok(value.into())
+ }
+
+ #[inline]
+ fn visit_f64<E>(self, value: f64) -> Result<Number, E>
+ where
+ E: de::Error,
+ {
+ Number::from_f64(value).ok_or_else(|| de::Error::custom("not a JSON number"))
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ #[inline]
+ fn visit_map<V>(self, mut visitor: V) -> Result<Number, V::Error>
+ where
+ V: de::MapAccess<'de>,
+ {
+ let value = visitor.next_key::<NumberKey>()?;
+ if value.is_none() {
+ return Err(de::Error::invalid_type(Unexpected::Map, &self));
+ }
+ let v: NumberFromString = visitor.next_value()?;
+ Ok(v.value)
+ }
+ }
+
+ deserializer.deserialize_any(NumberVisitor)
+ }
+}
+
+#[cfg(feature = "arbitrary_precision")]
+struct NumberKey;
+
+#[cfg(feature = "arbitrary_precision")]
+impl<'de> de::Deserialize<'de> for NumberKey {
+ fn deserialize<D>(deserializer: D) -> Result<NumberKey, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ struct FieldVisitor;
+
+ impl<'de> de::Visitor<'de> for FieldVisitor {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a valid number field")
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<(), E>
+ where
+ E: de::Error,
+ {
+ if s == TOKEN {
+ Ok(())
+ } else {
+ Err(de::Error::custom("expected field with custom name"))
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(FieldVisitor)?;
+ Ok(NumberKey)
+ }
+}
+
+#[cfg(feature = "arbitrary_precision")]
+pub struct NumberFromString {
+ pub value: Number,
+}
+
+#[cfg(feature = "arbitrary_precision")]
+impl<'de> de::Deserialize<'de> for NumberFromString {
+ fn deserialize<D>(deserializer: D) -> Result<NumberFromString, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ struct Visitor;
+
+ impl<'de> de::Visitor<'de> for Visitor {
+ type Value = NumberFromString;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("string containing a number")
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<NumberFromString, E>
+ where
+ E: de::Error,
+ {
+ let n = tri!(s.parse().map_err(de::Error::custom));
+ Ok(NumberFromString { value: n })
+ }
+ }
+
+ deserializer.deserialize_str(Visitor)
+ }
+}
+
+#[cfg(feature = "arbitrary_precision")]
+fn invalid_number() -> Error {
+ Error::syntax(ErrorCode::InvalidNumber, 0, 0)
+}
+
+macro_rules! deserialize_any {
+ (@expand [$($num_string:tt)*]) => {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.n {
+ N::PosInt(u) => visitor.visit_u64(u),
+ N::NegInt(i) => visitor.visit_i64(i),
+ N::Float(f) => visitor.visit_f64(f),
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where V: Visitor<'de>
+ {
+ if let Some(u) = self.as_u64() {
+ return visitor.visit_u64(u);
+ } else if let Some(i) = self.as_i64() {
+ return visitor.visit_i64(i);
+ } else if let Some(f) = self.as_f64() {
+ if ryu::Buffer::new().format_finite(f) == self.n || f.to_string() == self.n {
+ return visitor.visit_f64(f);
+ }
+ }
+
+ visitor.visit_map(NumberDeserializer {
+ number: Some(self.$($num_string)*),
+ })
+ }
+ };
+
+ (owned) => {
+ deserialize_any!(@expand [n]);
+ };
+
+ (ref) => {
+ deserialize_any!(@expand [n.clone()]);
+ };
+}
+
+macro_rules! deserialize_number {
+ ($deserialize:ident => $visit:ident) => {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_any(visitor)
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.$visit(self.n.parse().map_err(|_| invalid_number())?)
+ }
+ };
+}
+
+impl<'de> Deserializer<'de> for Number {
+ type Error = Error;
+
+ deserialize_any!(owned);
+
+ deserialize_number!(deserialize_i8 => visit_i8);
+ deserialize_number!(deserialize_i16 => visit_i16);
+ deserialize_number!(deserialize_i32 => visit_i32);
+ deserialize_number!(deserialize_i64 => visit_i64);
+ deserialize_number!(deserialize_i128 => visit_i128);
+ deserialize_number!(deserialize_u8 => visit_u8);
+ deserialize_number!(deserialize_u16 => visit_u16);
+ deserialize_number!(deserialize_u32 => visit_u32);
+ deserialize_number!(deserialize_u64 => visit_u64);
+ deserialize_number!(deserialize_u128 => visit_u128);
+ deserialize_number!(deserialize_f32 => visit_f32);
+ deserialize_number!(deserialize_f64 => visit_f64);
+
+ forward_to_deserialize_any! {
+ bool char str string bytes byte_buf option unit unit_struct
+ newtype_struct seq tuple tuple_struct map struct enum identifier
+ ignored_any
+ }
+}
+
+impl<'de, 'a> Deserializer<'de> for &'a Number {
+ type Error = Error;
+
+ deserialize_any!(ref);
+
+ deserialize_number!(deserialize_i8 => visit_i8);
+ deserialize_number!(deserialize_i16 => visit_i16);
+ deserialize_number!(deserialize_i32 => visit_i32);
+ deserialize_number!(deserialize_i64 => visit_i64);
+ deserialize_number!(deserialize_i128 => visit_i128);
+ deserialize_number!(deserialize_u8 => visit_u8);
+ deserialize_number!(deserialize_u16 => visit_u16);
+ deserialize_number!(deserialize_u32 => visit_u32);
+ deserialize_number!(deserialize_u64 => visit_u64);
+ deserialize_number!(deserialize_u128 => visit_u128);
+ deserialize_number!(deserialize_f32 => visit_f32);
+ deserialize_number!(deserialize_f64 => visit_f64);
+
+ forward_to_deserialize_any! {
+ bool char str string bytes byte_buf option unit unit_struct
+ newtype_struct seq tuple tuple_struct map struct enum identifier
+ ignored_any
+ }
+}
+
+#[cfg(feature = "arbitrary_precision")]
+pub(crate) struct NumberDeserializer {
+ pub number: Option<String>,
+}
+
+#[cfg(feature = "arbitrary_precision")]
+impl<'de> MapAccess<'de> for NumberDeserializer {
+ type Error = Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
+ where
+ K: de::DeserializeSeed<'de>,
+ {
+ if self.number.is_none() {
+ return Ok(None);
+ }
+ seed.deserialize(NumberFieldDeserializer).map(Some)
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(self.number.take().unwrap().into_deserializer())
+ }
+}
+
+#[cfg(feature = "arbitrary_precision")]
+struct NumberFieldDeserializer;
+
+#[cfg(feature = "arbitrary_precision")]
+impl<'de> Deserializer<'de> for NumberFieldDeserializer {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_borrowed_str(TOKEN)
+ }
+
+ forward_to_deserialize_any! {
+ bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
+ bytes byte_buf map struct option unit newtype_struct ignored_any
+ unit_struct tuple_struct tuple enum identifier
+ }
+}
+
+impl From<ParserNumber> for Number {
+ fn from(value: ParserNumber) -> Self {
+ let n = match value {
+ ParserNumber::F64(f) => {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ {
+ N::Float(f)
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ {
+ f.to_string()
+ }
+ }
+ ParserNumber::U64(u) => {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ {
+ N::PosInt(u)
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ {
+ u.to_string()
+ }
+ }
+ ParserNumber::I64(i) => {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ {
+ N::NegInt(i)
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ {
+ i.to_string()
+ }
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ ParserNumber::String(s) => s,
+ };
+ Number { n }
+ }
+}
+
+macro_rules! impl_from_unsigned {
+ (
+ $($ty:ty),*
+ ) => {
+ $(
+ impl From<$ty> for Number {
+ #[inline]
+ fn from(u: $ty) -> Self {
+ let n = {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ { N::PosInt(u as u64) }
+ #[cfg(feature = "arbitrary_precision")]
+ {
+ itoa::Buffer::new().format(u).to_owned()
+ }
+ };
+ Number { n }
+ }
+ }
+ )*
+ };
+}
+
+macro_rules! impl_from_signed {
+ (
+ $($ty:ty),*
+ ) => {
+ $(
+ impl From<$ty> for Number {
+ #[inline]
+ fn from(i: $ty) -> Self {
+ let n = {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ {
+ if i < 0 {
+ N::NegInt(i as i64)
+ } else {
+ N::PosInt(i as u64)
+ }
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ {
+ itoa::Buffer::new().format(i).to_owned()
+ }
+ };
+ Number { n }
+ }
+ }
+ )*
+ };
+}
+
+impl_from_unsigned!(u8, u16, u32, u64, usize);
+impl_from_signed!(i8, i16, i32, i64, isize);
+
+#[cfg(feature = "arbitrary_precision")]
+impl_from_unsigned!(u128);
+#[cfg(feature = "arbitrary_precision")]
+impl_from_signed!(i128);
+
+impl Number {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ #[cold]
+ pub(crate) fn unexpected(&self) -> Unexpected {
+ match self.n {
+ N::PosInt(u) => Unexpected::Unsigned(u),
+ N::NegInt(i) => Unexpected::Signed(i),
+ N::Float(f) => Unexpected::Float(f),
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ #[cold]
+ pub(crate) fn unexpected(&self) -> Unexpected {
+ Unexpected::Other("number")
+ }
+}
diff --git a/third_party/rust/serde_json/src/raw.rs b/third_party/rust/serde_json/src/raw.rs
new file mode 100644
index 0000000000..6aa4ffcb61
--- /dev/null
+++ b/third_party/rust/serde_json/src/raw.rs
@@ -0,0 +1,531 @@
+use crate::error::Error;
+use alloc::borrow::ToOwned;
+use alloc::boxed::Box;
+use alloc::string::String;
+use core::fmt::{self, Debug, Display};
+use core::mem;
+use serde::de::value::BorrowedStrDeserializer;
+use serde::de::{
+ self, Deserialize, DeserializeSeed, Deserializer, IntoDeserializer, MapAccess, Unexpected,
+ Visitor,
+};
+use serde::forward_to_deserialize_any;
+use serde::ser::{Serialize, SerializeStruct, Serializer};
+
+/// Reference to a range of bytes encompassing a single valid JSON value in the
+/// input data.
+///
+/// A `RawValue` can be used to defer parsing parts of a payload until later,
+/// or to avoid parsing it at all in the case that part of the payload just
+/// needs to be transferred verbatim into a different output object.
+///
+/// When serializing, a value of this type will retain its original formatting
+/// and will not be minified or pretty-printed.
+///
+/// # Note
+///
+/// `RawValue` is only available if serde\_json is built with the `"raw_value"`
+/// feature.
+///
+/// ```toml
+/// [dependencies]
+/// serde_json = { version = "1.0", features = ["raw_value"] }
+/// ```
+///
+/// # Example
+///
+/// ```
+/// use serde::{Deserialize, Serialize};
+/// use serde_json::{Result, value::RawValue};
+///
+/// #[derive(Deserialize)]
+/// struct Input<'a> {
+/// code: u32,
+/// #[serde(borrow)]
+/// payload: &'a RawValue,
+/// }
+///
+/// #[derive(Serialize)]
+/// struct Output<'a> {
+/// info: (u32, &'a RawValue),
+/// }
+///
+/// // Efficiently rearrange JSON input containing separate "code" and "payload"
+/// // keys into a single "info" key holding an array of code and payload.
+/// //
+/// // This could be done equivalently using serde_json::Value as the type for
+/// // payload, but &RawValue will perform better because it does not require
+/// // memory allocation. The correct range of bytes is borrowed from the input
+/// // data and pasted verbatim into the output.
+/// fn rearrange(input: &str) -> Result<String> {
+/// let input: Input = serde_json::from_str(input)?;
+///
+/// let output = Output {
+/// info: (input.code, input.payload),
+/// };
+///
+/// serde_json::to_string(&output)
+/// }
+///
+/// fn main() -> Result<()> {
+/// let out = rearrange(r#" {"code": 200, "payload": {}} "#)?;
+///
+/// assert_eq!(out, r#"{"info":[200,{}]}"#);
+///
+/// Ok(())
+/// }
+/// ```
+///
+/// # Ownership
+///
+/// The typical usage of `RawValue` will be in the borrowed form:
+///
+/// ```
+/// # use serde::Deserialize;
+/// # use serde_json::value::RawValue;
+/// #
+/// #[derive(Deserialize)]
+/// struct SomeStruct<'a> {
+/// #[serde(borrow)]
+/// raw_value: &'a RawValue,
+/// }
+/// ```
+///
+/// The borrowed form is suitable when deserializing through
+/// [`serde_json::from_str`] and [`serde_json::from_slice`] which support
+/// borrowing from the input data without memory allocation.
+///
+/// When deserializing through [`serde_json::from_reader`] you will need to use
+/// the boxed form of `RawValue` instead. This is almost as efficient but
+/// involves buffering the raw value from the I/O stream into memory.
+///
+/// [`serde_json::from_str`]: ../fn.from_str.html
+/// [`serde_json::from_slice`]: ../fn.from_slice.html
+/// [`serde_json::from_reader`]: ../fn.from_reader.html
+///
+/// ```
+/// # use serde::Deserialize;
+/// # use serde_json::value::RawValue;
+/// #
+/// #[derive(Deserialize)]
+/// struct SomeStruct {
+/// raw_value: Box<RawValue>,
+/// }
+/// ```
+#[cfg_attr(not(doc), repr(transparent))]
+#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))]
+pub struct RawValue {
+ json: str,
+}
+
+impl RawValue {
+ fn from_borrowed(json: &str) -> &Self {
+ unsafe { mem::transmute::<&str, &RawValue>(json) }
+ }
+
+ fn from_owned(json: Box<str>) -> Box<Self> {
+ unsafe { mem::transmute::<Box<str>, Box<RawValue>>(json) }
+ }
+
+ fn into_owned(raw_value: Box<Self>) -> Box<str> {
+ unsafe { mem::transmute::<Box<RawValue>, Box<str>>(raw_value) }
+ }
+}
+
+impl Clone for Box<RawValue> {
+ fn clone(&self) -> Self {
+ (**self).to_owned()
+ }
+}
+
+impl ToOwned for RawValue {
+ type Owned = Box<RawValue>;
+
+ fn to_owned(&self) -> Self::Owned {
+ RawValue::from_owned(self.json.to_owned().into_boxed_str())
+ }
+}
+
+impl Default for Box<RawValue> {
+ fn default() -> Self {
+ RawValue::from_borrowed("null").to_owned()
+ }
+}
+
+impl Debug for RawValue {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter
+ .debug_tuple("RawValue")
+ .field(&format_args!("{}", &self.json))
+ .finish()
+ }
+}
+
+impl Display for RawValue {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(&self.json)
+ }
+}
+
+impl RawValue {
+ /// Convert an owned `String` of JSON data to an owned `RawValue`.
+ ///
+ /// This function is equivalent to `serde_json::from_str::<Box<RawValue>>`
+ /// except that we avoid an allocation and memcpy if both of the following
+ /// are true:
+ ///
+ /// - the input has no leading or trailing whitespace, and
+ /// - the input has capacity equal to its length.
+ pub fn from_string(json: String) -> Result<Box<Self>, Error> {
+ {
+ let borrowed = crate::from_str::<&Self>(&json)?;
+ if borrowed.json.len() < json.len() {
+ return Ok(borrowed.to_owned());
+ }
+ }
+ Ok(Self::from_owned(json.into_boxed_str()))
+ }
+
+ /// Access the JSON text underlying a raw value.
+ ///
+ /// # Example
+ ///
+ /// ```
+ /// use serde::Deserialize;
+ /// use serde_json::{Result, value::RawValue};
+ ///
+ /// #[derive(Deserialize)]
+ /// struct Response<'a> {
+ /// code: u32,
+ /// #[serde(borrow)]
+ /// payload: &'a RawValue,
+ /// }
+ ///
+ /// fn process(input: &str) -> Result<()> {
+ /// let response: Response = serde_json::from_str(input)?;
+ ///
+ /// let payload = response.payload.get();
+ /// if payload.starts_with('{') {
+ /// // handle a payload which is a JSON map
+ /// } else {
+ /// // handle any other type
+ /// }
+ ///
+ /// Ok(())
+ /// }
+ ///
+ /// fn main() -> Result<()> {
+ /// process(r#" {"code": 200, "payload": {}} "#)?;
+ /// Ok(())
+ /// }
+ /// ```
+ pub fn get(&self) -> &str {
+ &self.json
+ }
+}
+
+impl From<Box<RawValue>> for Box<str> {
+ fn from(raw_value: Box<RawValue>) -> Self {
+ RawValue::into_owned(raw_value)
+ }
+}
+
+/// Convert a `T` into a boxed `RawValue`.
+///
+/// # Example
+///
+/// ```
+/// // Upstream crate
+/// # #[derive(Serialize)]
+/// pub struct Thing {
+/// foo: String,
+/// bar: Option<String>,
+/// extra_data: Box<RawValue>,
+/// }
+///
+/// // Local crate
+/// use serde::Serialize;
+/// use serde_json::value::{to_raw_value, RawValue};
+///
+/// #[derive(Serialize)]
+/// struct MyExtraData {
+/// a: u32,
+/// b: u32,
+/// }
+///
+/// let my_thing = Thing {
+/// foo: "FooVal".into(),
+/// bar: None,
+/// extra_data: to_raw_value(&MyExtraData { a: 1, b: 2 }).unwrap(),
+/// };
+/// # assert_eq!(
+/// # serde_json::to_value(my_thing).unwrap(),
+/// # serde_json::json!({
+/// # "foo": "FooVal",
+/// # "bar": null,
+/// # "extra_data": { "a": 1, "b": 2 }
+/// # })
+/// # );
+/// ```
+///
+/// # Errors
+///
+/// This conversion can fail if `T`'s implementation of `Serialize` decides to
+/// fail, or if `T` contains a map with non-string keys.
+///
+/// ```
+/// use std::collections::BTreeMap;
+///
+/// // The keys in this map are vectors, not strings.
+/// let mut map = BTreeMap::new();
+/// map.insert(vec![32, 64], "x86");
+///
+/// println!("{}", serde_json::value::to_raw_value(&map).unwrap_err());
+/// ```
+#[cfg_attr(docsrs, doc(cfg(feature = "raw_value")))]
+pub fn to_raw_value<T>(value: &T) -> Result<Box<RawValue>, Error>
+where
+ T: ?Sized + Serialize,
+{
+ let json_string = crate::to_string(value)?;
+ Ok(RawValue::from_owned(json_string.into_boxed_str()))
+}
+
+pub const TOKEN: &str = "$serde_json::private::RawValue";
+
+impl Serialize for RawValue {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut s = serializer.serialize_struct(TOKEN, 1)?;
+ s.serialize_field(TOKEN, &self.json)?;
+ s.end()
+ }
+}
+
+impl<'de: 'a, 'a> Deserialize<'de> for &'a RawValue {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct ReferenceVisitor;
+
+ impl<'de> Visitor<'de> for ReferenceVisitor {
+ type Value = &'de RawValue;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "any valid JSON value")
+ }
+
+ fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: MapAccess<'de>,
+ {
+ let value = visitor.next_key::<RawKey>()?;
+ if value.is_none() {
+ return Err(de::Error::invalid_type(Unexpected::Map, &self));
+ }
+ visitor.next_value_seed(ReferenceFromString)
+ }
+ }
+
+ deserializer.deserialize_newtype_struct(TOKEN, ReferenceVisitor)
+ }
+}
+
+impl<'de> Deserialize<'de> for Box<RawValue> {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct BoxedVisitor;
+
+ impl<'de> Visitor<'de> for BoxedVisitor {
+ type Value = Box<RawValue>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "any valid JSON value")
+ }
+
+ fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: MapAccess<'de>,
+ {
+ let value = visitor.next_key::<RawKey>()?;
+ if value.is_none() {
+ return Err(de::Error::invalid_type(Unexpected::Map, &self));
+ }
+ visitor.next_value_seed(BoxedFromString)
+ }
+ }
+
+ deserializer.deserialize_newtype_struct(TOKEN, BoxedVisitor)
+ }
+}
+
+struct RawKey;
+
+impl<'de> Deserialize<'de> for RawKey {
+ fn deserialize<D>(deserializer: D) -> Result<RawKey, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct FieldVisitor;
+
+ impl<'de> Visitor<'de> for FieldVisitor {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("raw value")
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<(), E>
+ where
+ E: de::Error,
+ {
+ if s == TOKEN {
+ Ok(())
+ } else {
+ Err(de::Error::custom("unexpected raw value"))
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(FieldVisitor)?;
+ Ok(RawKey)
+ }
+}
+
+pub struct ReferenceFromString;
+
+impl<'de> DeserializeSeed<'de> for ReferenceFromString {
+ type Value = &'de RawValue;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_str(self)
+ }
+}
+
+impl<'de> Visitor<'de> for ReferenceFromString {
+ type Value = &'de RawValue;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("raw value")
+ }
+
+ fn visit_borrowed_str<E>(self, s: &'de str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(RawValue::from_borrowed(s))
+ }
+}
+
+pub struct BoxedFromString;
+
+impl<'de> DeserializeSeed<'de> for BoxedFromString {
+ type Value = Box<RawValue>;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_str(self)
+ }
+}
+
+impl<'de> Visitor<'de> for BoxedFromString {
+ type Value = Box<RawValue>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("raw value")
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(RawValue::from_owned(s.to_owned().into_boxed_str()))
+ }
+
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(RawValue::from_owned(s.into_boxed_str()))
+ }
+}
+
+struct RawKeyDeserializer;
+
+impl<'de> Deserializer<'de> for RawKeyDeserializer {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_borrowed_str(TOKEN)
+ }
+
+ forward_to_deserialize_any! {
+ bool u8 u16 u32 u64 u128 i8 i16 i32 i64 i128 f32 f64 char str string seq
+ bytes byte_buf map struct option unit newtype_struct ignored_any
+ unit_struct tuple_struct tuple enum identifier
+ }
+}
+
+pub struct OwnedRawDeserializer {
+ pub raw_value: Option<String>,
+}
+
+impl<'de> MapAccess<'de> for OwnedRawDeserializer {
+ type Error = Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
+ where
+ K: de::DeserializeSeed<'de>,
+ {
+ if self.raw_value.is_none() {
+ return Ok(None);
+ }
+ seed.deserialize(RawKeyDeserializer).map(Some)
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(self.raw_value.take().unwrap().into_deserializer())
+ }
+}
+
+pub struct BorrowedRawDeserializer<'de> {
+ pub raw_value: Option<&'de str>,
+}
+
+impl<'de> MapAccess<'de> for BorrowedRawDeserializer<'de> {
+ type Error = Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
+ where
+ K: de::DeserializeSeed<'de>,
+ {
+ if self.raw_value.is_none() {
+ return Ok(None);
+ }
+ seed.deserialize(RawKeyDeserializer).map(Some)
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ seed.deserialize(BorrowedStrDeserializer::new(self.raw_value.take().unwrap()))
+ }
+}
diff --git a/third_party/rust/serde_json/src/read.rs b/third_party/rust/serde_json/src/read.rs
new file mode 100644
index 0000000000..fc3a3ca748
--- /dev/null
+++ b/third_party/rust/serde_json/src/read.rs
@@ -0,0 +1,1004 @@
+use crate::error::{Error, ErrorCode, Result};
+use alloc::vec::Vec;
+use core::char;
+use core::cmp;
+use core::ops::Deref;
+use core::str;
+
+#[cfg(feature = "std")]
+use crate::io;
+#[cfg(feature = "std")]
+use crate::iter::LineColIterator;
+
+#[cfg(feature = "raw_value")]
+use crate::raw::BorrowedRawDeserializer;
+#[cfg(all(feature = "raw_value", feature = "std"))]
+use crate::raw::OwnedRawDeserializer;
+#[cfg(feature = "raw_value")]
+use serde::de::Visitor;
+
+/// Trait used by the deserializer for iterating over input. This is manually
+/// "specialized" for iterating over &[u8]. Once feature(specialization) is
+/// stable we can use actual specialization.
+///
+/// This trait is sealed and cannot be implemented for types outside of
+/// `serde_json`.
+pub trait Read<'de>: private::Sealed {
+ #[doc(hidden)]
+ fn next(&mut self) -> Result<Option<u8>>;
+ #[doc(hidden)]
+ fn peek(&mut self) -> Result<Option<u8>>;
+
+ /// Only valid after a call to peek(). Discards the peeked byte.
+ #[doc(hidden)]
+ fn discard(&mut self);
+
+ /// Position of the most recent call to next().
+ ///
+ /// The most recent call was probably next() and not peek(), but this method
+ /// should try to return a sensible result if the most recent call was
+ /// actually peek() because we don't always know.
+ ///
+ /// Only called in case of an error, so performance is not important.
+ #[doc(hidden)]
+ fn position(&self) -> Position;
+
+ /// Position of the most recent call to peek().
+ ///
+ /// The most recent call was probably peek() and not next(), but this method
+ /// should try to return a sensible result if the most recent call was
+ /// actually next() because we don't always know.
+ ///
+ /// Only called in case of an error, so performance is not important.
+ #[doc(hidden)]
+ fn peek_position(&self) -> Position;
+
+ /// Offset from the beginning of the input to the next byte that would be
+ /// returned by next() or peek().
+ #[doc(hidden)]
+ fn byte_offset(&self) -> usize;
+
+ /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped
+ /// string until the next quotation mark using the given scratch space if
+ /// necessary. The scratch space is initially empty.
+ #[doc(hidden)]
+ fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'de, 's, str>>;
+
+ /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped
+ /// string until the next quotation mark using the given scratch space if
+ /// necessary. The scratch space is initially empty.
+ ///
+ /// This function returns the raw bytes in the string with escape sequences
+ /// expanded but without performing unicode validation.
+ #[doc(hidden)]
+ fn parse_str_raw<'s>(
+ &'s mut self,
+ scratch: &'s mut Vec<u8>,
+ ) -> Result<Reference<'de, 's, [u8]>>;
+
+ /// Assumes the previous byte was a quotation mark. Parses a JSON-escaped
+ /// string until the next quotation mark but discards the data.
+ #[doc(hidden)]
+ fn ignore_str(&mut self) -> Result<()>;
+
+ /// Assumes the previous byte was a hex escape sequnce ('\u') in a string.
+ /// Parses next hexadecimal sequence.
+ #[doc(hidden)]
+ fn decode_hex_escape(&mut self) -> Result<u16>;
+
+ /// Switch raw buffering mode on.
+ ///
+ /// This is used when deserializing `RawValue`.
+ #[cfg(feature = "raw_value")]
+ #[doc(hidden)]
+ fn begin_raw_buffering(&mut self);
+
+ /// Switch raw buffering mode off and provides the raw buffered data to the
+ /// given visitor.
+ #[cfg(feature = "raw_value")]
+ #[doc(hidden)]
+ fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>;
+
+ /// Whether StreamDeserializer::next needs to check the failed flag. True
+ /// for IoRead, false for StrRead and SliceRead which can track failure by
+ /// truncating their input slice to avoid the extra check on every next
+ /// call.
+ #[doc(hidden)]
+ const should_early_return_if_failed: bool;
+
+ /// Mark a persistent failure of StreamDeserializer, either by setting the
+ /// flag or by truncating the input data.
+ #[doc(hidden)]
+ fn set_failed(&mut self, failed: &mut bool);
+}
+
+pub struct Position {
+ pub line: usize,
+ pub column: usize,
+}
+
+pub enum Reference<'b, 'c, T>
+where
+ T: ?Sized + 'static,
+{
+ Borrowed(&'b T),
+ Copied(&'c T),
+}
+
+impl<'b, 'c, T> Deref for Reference<'b, 'c, T>
+where
+ T: ?Sized + 'static,
+{
+ type Target = T;
+
+ fn deref(&self) -> &Self::Target {
+ match *self {
+ Reference::Borrowed(b) => b,
+ Reference::Copied(c) => c,
+ }
+ }
+}
+
+/// JSON input source that reads from a std::io input stream.
+#[cfg(feature = "std")]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub struct IoRead<R>
+where
+ R: io::Read,
+{
+ iter: LineColIterator<io::Bytes<R>>,
+ /// Temporary storage of peeked byte.
+ ch: Option<u8>,
+ #[cfg(feature = "raw_value")]
+ raw_buffer: Option<Vec<u8>>,
+}
+
+/// JSON input source that reads from a slice of bytes.
+//
+// This is more efficient than other iterators because peek() can be read-only
+// and we can compute line/col position only if an error happens.
+pub struct SliceRead<'a> {
+ slice: &'a [u8],
+ /// Index of the *next* byte that will be returned by next() or peek().
+ index: usize,
+ #[cfg(feature = "raw_value")]
+ raw_buffering_start_index: usize,
+}
+
+/// JSON input source that reads from a UTF-8 string.
+//
+// Able to elide UTF-8 checks by assuming that the input is valid UTF-8.
+pub struct StrRead<'a> {
+ delegate: SliceRead<'a>,
+ #[cfg(feature = "raw_value")]
+ data: &'a str,
+}
+
+// Prevent users from implementing the Read trait.
+mod private {
+ pub trait Sealed {}
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+impl<R> IoRead<R>
+where
+ R: io::Read,
+{
+ /// Create a JSON input source to read from a std::io input stream.
+ pub fn new(reader: R) -> Self {
+ IoRead {
+ iter: LineColIterator::new(reader.bytes()),
+ ch: None,
+ #[cfg(feature = "raw_value")]
+ raw_buffer: None,
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<R> private::Sealed for IoRead<R> where R: io::Read {}
+
+#[cfg(feature = "std")]
+impl<R> IoRead<R>
+where
+ R: io::Read,
+{
+ fn parse_str_bytes<'s, T, F>(
+ &'s mut self,
+ scratch: &'s mut Vec<u8>,
+ validate: bool,
+ result: F,
+ ) -> Result<T>
+ where
+ T: 's,
+ F: FnOnce(&'s Self, &'s [u8]) -> Result<T>,
+ {
+ loop {
+ let ch = tri!(next_or_eof(self));
+ if !ESCAPE[ch as usize] {
+ scratch.push(ch);
+ continue;
+ }
+ match ch {
+ b'"' => {
+ return result(self, scratch);
+ }
+ b'\\' => {
+ tri!(parse_escape(self, validate, scratch));
+ }
+ _ => {
+ if validate {
+ return error(self, ErrorCode::ControlCharacterWhileParsingString);
+ }
+ scratch.push(ch);
+ }
+ }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+impl<'de, R> Read<'de> for IoRead<R>
+where
+ R: io::Read,
+{
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ match self.ch.take() {
+ Some(ch) => {
+ #[cfg(feature = "raw_value")]
+ {
+ if let Some(buf) = &mut self.raw_buffer {
+ buf.push(ch);
+ }
+ }
+ Ok(Some(ch))
+ }
+ None => match self.iter.next() {
+ Some(Err(err)) => Err(Error::io(err)),
+ Some(Ok(ch)) => {
+ #[cfg(feature = "raw_value")]
+ {
+ if let Some(buf) = &mut self.raw_buffer {
+ buf.push(ch);
+ }
+ }
+ Ok(Some(ch))
+ }
+ None => Ok(None),
+ },
+ }
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ match self.ch {
+ Some(ch) => Ok(Some(ch)),
+ None => match self.iter.next() {
+ Some(Err(err)) => Err(Error::io(err)),
+ Some(Ok(ch)) => {
+ self.ch = Some(ch);
+ Ok(self.ch)
+ }
+ None => Ok(None),
+ },
+ }
+ }
+
+ #[cfg(not(feature = "raw_value"))]
+ #[inline]
+ fn discard(&mut self) {
+ self.ch = None;
+ }
+
+ #[cfg(feature = "raw_value")]
+ fn discard(&mut self) {
+ if let Some(ch) = self.ch.take() {
+ if let Some(buf) = &mut self.raw_buffer {
+ buf.push(ch);
+ }
+ }
+ }
+
+ fn position(&self) -> Position {
+ Position {
+ line: self.iter.line(),
+ column: self.iter.col(),
+ }
+ }
+
+ fn peek_position(&self) -> Position {
+ // The LineColIterator updates its position during peek() so it has the
+ // right one here.
+ self.position()
+ }
+
+ fn byte_offset(&self) -> usize {
+ match self.ch {
+ Some(_) => self.iter.byte_offset() - 1,
+ None => self.iter.byte_offset(),
+ }
+ }
+
+ fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'de, 's, str>> {
+ self.parse_str_bytes(scratch, true, as_str)
+ .map(Reference::Copied)
+ }
+
+ fn parse_str_raw<'s>(
+ &'s mut self,
+ scratch: &'s mut Vec<u8>,
+ ) -> Result<Reference<'de, 's, [u8]>> {
+ self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes))
+ .map(Reference::Copied)
+ }
+
+ fn ignore_str(&mut self) -> Result<()> {
+ loop {
+ let ch = tri!(next_or_eof(self));
+ if !ESCAPE[ch as usize] {
+ continue;
+ }
+ match ch {
+ b'"' => {
+ return Ok(());
+ }
+ b'\\' => {
+ tri!(ignore_escape(self));
+ }
+ _ => {
+ return error(self, ErrorCode::ControlCharacterWhileParsingString);
+ }
+ }
+ }
+ }
+
+ fn decode_hex_escape(&mut self) -> Result<u16> {
+ let mut n = 0;
+ for _ in 0..4 {
+ match decode_hex_val(tri!(next_or_eof(self))) {
+ None => return error(self, ErrorCode::InvalidEscape),
+ Some(val) => {
+ n = (n << 4) + val;
+ }
+ }
+ }
+ Ok(n)
+ }
+
+ #[cfg(feature = "raw_value")]
+ fn begin_raw_buffering(&mut self) {
+ self.raw_buffer = Some(Vec::new());
+ }
+
+ #[cfg(feature = "raw_value")]
+ fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let raw = self.raw_buffer.take().unwrap();
+ let raw = match String::from_utf8(raw) {
+ Ok(raw) => raw,
+ Err(_) => return error(self, ErrorCode::InvalidUnicodeCodePoint),
+ };
+ visitor.visit_map(OwnedRawDeserializer {
+ raw_value: Some(raw),
+ })
+ }
+
+ const should_early_return_if_failed: bool = true;
+
+ #[inline]
+ #[cold]
+ fn set_failed(&mut self, failed: &mut bool) {
+ *failed = true;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+impl<'a> SliceRead<'a> {
+ /// Create a JSON input source to read from a slice of bytes.
+ pub fn new(slice: &'a [u8]) -> Self {
+ SliceRead {
+ slice,
+ index: 0,
+ #[cfg(feature = "raw_value")]
+ raw_buffering_start_index: 0,
+ }
+ }
+
+ fn position_of_index(&self, i: usize) -> Position {
+ let mut position = Position { line: 1, column: 0 };
+ for ch in &self.slice[..i] {
+ match *ch {
+ b'\n' => {
+ position.line += 1;
+ position.column = 0;
+ }
+ _ => {
+ position.column += 1;
+ }
+ }
+ }
+ position
+ }
+
+ /// The big optimization here over IoRead is that if the string contains no
+ /// backslash escape sequences, the returned &str is a slice of the raw JSON
+ /// data so we avoid copying into the scratch space.
+ fn parse_str_bytes<'s, T, F>(
+ &'s mut self,
+ scratch: &'s mut Vec<u8>,
+ validate: bool,
+ result: F,
+ ) -> Result<Reference<'a, 's, T>>
+ where
+ T: ?Sized + 's,
+ F: for<'f> FnOnce(&'s Self, &'f [u8]) -> Result<&'f T>,
+ {
+ // Index of the first byte not yet copied into the scratch space.
+ let mut start = self.index;
+
+ loop {
+ while self.index < self.slice.len() && !ESCAPE[self.slice[self.index] as usize] {
+ self.index += 1;
+ }
+ if self.index == self.slice.len() {
+ return error(self, ErrorCode::EofWhileParsingString);
+ }
+ match self.slice[self.index] {
+ b'"' => {
+ if scratch.is_empty() {
+ // Fast path: return a slice of the raw JSON without any
+ // copying.
+ let borrowed = &self.slice[start..self.index];
+ self.index += 1;
+ return result(self, borrowed).map(Reference::Borrowed);
+ } else {
+ scratch.extend_from_slice(&self.slice[start..self.index]);
+ self.index += 1;
+ return result(self, scratch).map(Reference::Copied);
+ }
+ }
+ b'\\' => {
+ scratch.extend_from_slice(&self.slice[start..self.index]);
+ self.index += 1;
+ tri!(parse_escape(self, validate, scratch));
+ start = self.index;
+ }
+ _ => {
+ self.index += 1;
+ if validate {
+ return error(self, ErrorCode::ControlCharacterWhileParsingString);
+ }
+ }
+ }
+ }
+ }
+}
+
+impl<'a> private::Sealed for SliceRead<'a> {}
+
+impl<'a> Read<'a> for SliceRead<'a> {
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ // `Ok(self.slice.get(self.index).map(|ch| { self.index += 1; *ch }))`
+ // is about 10% slower.
+ Ok(if self.index < self.slice.len() {
+ let ch = self.slice[self.index];
+ self.index += 1;
+ Some(ch)
+ } else {
+ None
+ })
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ // `Ok(self.slice.get(self.index).map(|ch| *ch))` is about 10% slower
+ // for some reason.
+ Ok(if self.index < self.slice.len() {
+ Some(self.slice[self.index])
+ } else {
+ None
+ })
+ }
+
+ #[inline]
+ fn discard(&mut self) {
+ self.index += 1;
+ }
+
+ fn position(&self) -> Position {
+ self.position_of_index(self.index)
+ }
+
+ fn peek_position(&self) -> Position {
+ // Cap it at slice.len() just in case the most recent call was next()
+ // and it returned the last byte.
+ self.position_of_index(cmp::min(self.slice.len(), self.index + 1))
+ }
+
+ fn byte_offset(&self) -> usize {
+ self.index
+ }
+
+ fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'a, 's, str>> {
+ self.parse_str_bytes(scratch, true, as_str)
+ }
+
+ fn parse_str_raw<'s>(
+ &'s mut self,
+ scratch: &'s mut Vec<u8>,
+ ) -> Result<Reference<'a, 's, [u8]>> {
+ self.parse_str_bytes(scratch, false, |_, bytes| Ok(bytes))
+ }
+
+ fn ignore_str(&mut self) -> Result<()> {
+ loop {
+ while self.index < self.slice.len() && !ESCAPE[self.slice[self.index] as usize] {
+ self.index += 1;
+ }
+ if self.index == self.slice.len() {
+ return error(self, ErrorCode::EofWhileParsingString);
+ }
+ match self.slice[self.index] {
+ b'"' => {
+ self.index += 1;
+ return Ok(());
+ }
+ b'\\' => {
+ self.index += 1;
+ tri!(ignore_escape(self));
+ }
+ _ => {
+ return error(self, ErrorCode::ControlCharacterWhileParsingString);
+ }
+ }
+ }
+ }
+
+ fn decode_hex_escape(&mut self) -> Result<u16> {
+ if self.index + 4 > self.slice.len() {
+ self.index = self.slice.len();
+ return error(self, ErrorCode::EofWhileParsingString);
+ }
+
+ let mut n = 0;
+ for _ in 0..4 {
+ let ch = decode_hex_val(self.slice[self.index]);
+ self.index += 1;
+ match ch {
+ None => return error(self, ErrorCode::InvalidEscape),
+ Some(val) => {
+ n = (n << 4) + val;
+ }
+ }
+ }
+ Ok(n)
+ }
+
+ #[cfg(feature = "raw_value")]
+ fn begin_raw_buffering(&mut self) {
+ self.raw_buffering_start_index = self.index;
+ }
+
+ #[cfg(feature = "raw_value")]
+ fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'a>,
+ {
+ let raw = &self.slice[self.raw_buffering_start_index..self.index];
+ let raw = match str::from_utf8(raw) {
+ Ok(raw) => raw,
+ Err(_) => return error(self, ErrorCode::InvalidUnicodeCodePoint),
+ };
+ visitor.visit_map(BorrowedRawDeserializer {
+ raw_value: Some(raw),
+ })
+ }
+
+ const should_early_return_if_failed: bool = false;
+
+ #[inline]
+ #[cold]
+ fn set_failed(&mut self, _failed: &mut bool) {
+ self.slice = &self.slice[..self.index];
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+impl<'a> StrRead<'a> {
+ /// Create a JSON input source to read from a UTF-8 string.
+ pub fn new(s: &'a str) -> Self {
+ StrRead {
+ delegate: SliceRead::new(s.as_bytes()),
+ #[cfg(feature = "raw_value")]
+ data: s,
+ }
+ }
+}
+
+impl<'a> private::Sealed for StrRead<'a> {}
+
+impl<'a> Read<'a> for StrRead<'a> {
+ #[inline]
+ fn next(&mut self) -> Result<Option<u8>> {
+ self.delegate.next()
+ }
+
+ #[inline]
+ fn peek(&mut self) -> Result<Option<u8>> {
+ self.delegate.peek()
+ }
+
+ #[inline]
+ fn discard(&mut self) {
+ self.delegate.discard();
+ }
+
+ fn position(&self) -> Position {
+ self.delegate.position()
+ }
+
+ fn peek_position(&self) -> Position {
+ self.delegate.peek_position()
+ }
+
+ fn byte_offset(&self) -> usize {
+ self.delegate.byte_offset()
+ }
+
+ fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'a, 's, str>> {
+ self.delegate.parse_str_bytes(scratch, true, |_, bytes| {
+ // The deserialization input came in as &str with a UTF-8 guarantee,
+ // and the \u-escapes are checked along the way, so don't need to
+ // check here.
+ Ok(unsafe { str::from_utf8_unchecked(bytes) })
+ })
+ }
+
+ fn parse_str_raw<'s>(
+ &'s mut self,
+ scratch: &'s mut Vec<u8>,
+ ) -> Result<Reference<'a, 's, [u8]>> {
+ self.delegate.parse_str_raw(scratch)
+ }
+
+ fn ignore_str(&mut self) -> Result<()> {
+ self.delegate.ignore_str()
+ }
+
+ fn decode_hex_escape(&mut self) -> Result<u16> {
+ self.delegate.decode_hex_escape()
+ }
+
+ #[cfg(feature = "raw_value")]
+ fn begin_raw_buffering(&mut self) {
+ self.delegate.begin_raw_buffering();
+ }
+
+ #[cfg(feature = "raw_value")]
+ fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'a>,
+ {
+ let raw = &self.data[self.delegate.raw_buffering_start_index..self.delegate.index];
+ visitor.visit_map(BorrowedRawDeserializer {
+ raw_value: Some(raw),
+ })
+ }
+
+ const should_early_return_if_failed: bool = false;
+
+ #[inline]
+ #[cold]
+ fn set_failed(&mut self, failed: &mut bool) {
+ self.delegate.set_failed(failed);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+impl<'a, 'de, R> private::Sealed for &'a mut R where R: Read<'de> {}
+
+impl<'a, 'de, R> Read<'de> for &'a mut R
+where
+ R: Read<'de>,
+{
+ fn next(&mut self) -> Result<Option<u8>> {
+ R::next(self)
+ }
+
+ fn peek(&mut self) -> Result<Option<u8>> {
+ R::peek(self)
+ }
+
+ fn discard(&mut self) {
+ R::discard(self);
+ }
+
+ fn position(&self) -> Position {
+ R::position(self)
+ }
+
+ fn peek_position(&self) -> Position {
+ R::peek_position(self)
+ }
+
+ fn byte_offset(&self) -> usize {
+ R::byte_offset(self)
+ }
+
+ fn parse_str<'s>(&'s mut self, scratch: &'s mut Vec<u8>) -> Result<Reference<'de, 's, str>> {
+ R::parse_str(self, scratch)
+ }
+
+ fn parse_str_raw<'s>(
+ &'s mut self,
+ scratch: &'s mut Vec<u8>,
+ ) -> Result<Reference<'de, 's, [u8]>> {
+ R::parse_str_raw(self, scratch)
+ }
+
+ fn ignore_str(&mut self) -> Result<()> {
+ R::ignore_str(self)
+ }
+
+ fn decode_hex_escape(&mut self) -> Result<u16> {
+ R::decode_hex_escape(self)
+ }
+
+ #[cfg(feature = "raw_value")]
+ fn begin_raw_buffering(&mut self) {
+ R::begin_raw_buffering(self);
+ }
+
+ #[cfg(feature = "raw_value")]
+ fn end_raw_buffering<V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ R::end_raw_buffering(self, visitor)
+ }
+
+ const should_early_return_if_failed: bool = R::should_early_return_if_failed;
+
+ fn set_failed(&mut self, failed: &mut bool) {
+ R::set_failed(self, failed);
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////////
+
+/// Marker for whether StreamDeserializer can implement FusedIterator.
+pub trait Fused: private::Sealed {}
+impl<'a> Fused for SliceRead<'a> {}
+impl<'a> Fused for StrRead<'a> {}
+
+// Lookup table of bytes that must be escaped. A value of true at index i means
+// that byte i requires an escape sequence in the input.
+static ESCAPE: [bool; 256] = {
+ const CT: bool = true; // control character \x00..=\x1F
+ const QU: bool = true; // quote \x22
+ const BS: bool = true; // backslash \x5C
+ const __: bool = false; // allow unescaped
+ [
+ // 1 2 3 4 5 6 7 8 9 A B C D E F
+ CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 0
+ CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, CT, // 1
+ __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4
+ __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F
+ ]
+};
+
+fn next_or_eof<'de, R>(read: &mut R) -> Result<u8>
+where
+ R: ?Sized + Read<'de>,
+{
+ match tri!(read.next()) {
+ Some(b) => Ok(b),
+ None => error(read, ErrorCode::EofWhileParsingString),
+ }
+}
+
+fn peek_or_eof<'de, R>(read: &mut R) -> Result<u8>
+where
+ R: ?Sized + Read<'de>,
+{
+ match tri!(read.peek()) {
+ Some(b) => Ok(b),
+ None => error(read, ErrorCode::EofWhileParsingString),
+ }
+}
+
+fn error<'de, R, T>(read: &R, reason: ErrorCode) -> Result<T>
+where
+ R: ?Sized + Read<'de>,
+{
+ let position = read.position();
+ Err(Error::syntax(reason, position.line, position.column))
+}
+
+fn as_str<'de, 's, R: Read<'de>>(read: &R, slice: &'s [u8]) -> Result<&'s str> {
+ str::from_utf8(slice).or_else(|_| error(read, ErrorCode::InvalidUnicodeCodePoint))
+}
+
+/// Parses a JSON escape sequence and appends it into the scratch space. Assumes
+/// the previous byte read was a backslash.
+fn parse_escape<'de, R: Read<'de>>(
+ read: &mut R,
+ validate: bool,
+ scratch: &mut Vec<u8>,
+) -> Result<()> {
+ let ch = tri!(next_or_eof(read));
+
+ match ch {
+ b'"' => scratch.push(b'"'),
+ b'\\' => scratch.push(b'\\'),
+ b'/' => scratch.push(b'/'),
+ b'b' => scratch.push(b'\x08'),
+ b'f' => scratch.push(b'\x0c'),
+ b'n' => scratch.push(b'\n'),
+ b'r' => scratch.push(b'\r'),
+ b't' => scratch.push(b'\t'),
+ b'u' => {
+ fn encode_surrogate(scratch: &mut Vec<u8>, n: u16) {
+ scratch.extend_from_slice(&[
+ (n >> 12 & 0b0000_1111) as u8 | 0b1110_0000,
+ (n >> 6 & 0b0011_1111) as u8 | 0b1000_0000,
+ (n & 0b0011_1111) as u8 | 0b1000_0000,
+ ]);
+ }
+
+ let c = match tri!(read.decode_hex_escape()) {
+ n @ 0xDC00..=0xDFFF => {
+ return if validate {
+ error(read, ErrorCode::LoneLeadingSurrogateInHexEscape)
+ } else {
+ encode_surrogate(scratch, n);
+ Ok(())
+ };
+ }
+
+ // Non-BMP characters are encoded as a sequence of two hex
+ // escapes, representing UTF-16 surrogates. If deserializing a
+ // utf-8 string the surrogates are required to be paired,
+ // whereas deserializing a byte string accepts lone surrogates.
+ n1 @ 0xD800..=0xDBFF => {
+ if tri!(peek_or_eof(read)) == b'\\' {
+ read.discard();
+ } else {
+ return if validate {
+ read.discard();
+ error(read, ErrorCode::UnexpectedEndOfHexEscape)
+ } else {
+ encode_surrogate(scratch, n1);
+ Ok(())
+ };
+ }
+
+ if tri!(peek_or_eof(read)) == b'u' {
+ read.discard();
+ } else {
+ return if validate {
+ read.discard();
+ error(read, ErrorCode::UnexpectedEndOfHexEscape)
+ } else {
+ encode_surrogate(scratch, n1);
+ // The \ prior to this byte started an escape sequence,
+ // so we need to parse that now. This recursive call
+ // does not blow the stack on malicious input because
+ // the escape is not \u, so it will be handled by one
+ // of the easy nonrecursive cases.
+ parse_escape(read, validate, scratch)
+ };
+ }
+
+ let n2 = tri!(read.decode_hex_escape());
+
+ if n2 < 0xDC00 || n2 > 0xDFFF {
+ return error(read, ErrorCode::LoneLeadingSurrogateInHexEscape);
+ }
+
+ let n = (((n1 - 0xD800) as u32) << 10 | (n2 - 0xDC00) as u32) + 0x1_0000;
+
+ match char::from_u32(n) {
+ Some(c) => c,
+ None => {
+ return error(read, ErrorCode::InvalidUnicodeCodePoint);
+ }
+ }
+ }
+
+ // Every u16 outside of the surrogate ranges above is guaranteed
+ // to be a legal char.
+ n => char::from_u32(n as u32).unwrap(),
+ };
+
+ scratch.extend_from_slice(c.encode_utf8(&mut [0_u8; 4]).as_bytes());
+ }
+ _ => {
+ return error(read, ErrorCode::InvalidEscape);
+ }
+ }
+
+ Ok(())
+}
+
+/// Parses a JSON escape sequence and discards the value. Assumes the previous
+/// byte read was a backslash.
+fn ignore_escape<'de, R>(read: &mut R) -> Result<()>
+where
+ R: ?Sized + Read<'de>,
+{
+ let ch = tri!(next_or_eof(read));
+
+ match ch {
+ b'"' | b'\\' | b'/' | b'b' | b'f' | b'n' | b'r' | b't' => {}
+ b'u' => {
+ // At this point we don't care if the codepoint is valid. We just
+ // want to consume it. We don't actually know what is valid or not
+ // at this point, because that depends on if this string will
+ // ultimately be parsed into a string or a byte buffer in the "real"
+ // parse.
+
+ tri!(read.decode_hex_escape());
+ }
+ _ => {
+ return error(read, ErrorCode::InvalidEscape);
+ }
+ }
+
+ Ok(())
+}
+
+static HEX: [u8; 256] = {
+ const __: u8 = 255; // not a hex digit
+ [
+ // 1 2 3 4 5 6 7 8 9 A B C D E F
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 0
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 1
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2
+ 00, 01, 02, 03, 04, 05, 06, 07, 08, 09, __, __, __, __, __, __, // 3
+ __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, // 4
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 5
+ __, 10, 11, 12, 13, 14, 15, __, __, __, __, __, __, __, __, __, // 6
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F
+ ]
+};
+
+fn decode_hex_val(val: u8) -> Option<u16> {
+ let n = HEX[val as usize] as u16;
+ if n == 255 {
+ None
+ } else {
+ Some(n)
+ }
+}
diff --git a/third_party/rust/serde_json/src/ser.rs b/third_party/rust/serde_json/src/ser.rs
new file mode 100644
index 0000000000..80c2deb0c1
--- /dev/null
+++ b/third_party/rust/serde_json/src/ser.rs
@@ -0,0 +1,2179 @@
+//! Serialize a Rust data structure into JSON data.
+
+use crate::error::{Error, ErrorCode, Result};
+use crate::io;
+use alloc::string::{String, ToString};
+use alloc::vec::Vec;
+use core::fmt::{self, Display};
+use core::num::FpCategory;
+use serde::ser::{self, Impossible, Serialize};
+
+/// A structure for serializing Rust values into JSON.
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub struct Serializer<W, F = CompactFormatter> {
+ writer: W,
+ formatter: F,
+}
+
+impl<W> Serializer<W>
+where
+ W: io::Write,
+{
+ /// Creates a new JSON serializer.
+ #[inline]
+ pub fn new(writer: W) -> Self {
+ Serializer::with_formatter(writer, CompactFormatter)
+ }
+}
+
+impl<'a, W> Serializer<W, PrettyFormatter<'a>>
+where
+ W: io::Write,
+{
+ /// Creates a new JSON pretty print serializer.
+ #[inline]
+ pub fn pretty(writer: W) -> Self {
+ Serializer::with_formatter(writer, PrettyFormatter::new())
+ }
+}
+
+impl<W, F> Serializer<W, F>
+where
+ W: io::Write,
+ F: Formatter,
+{
+ /// Creates a new JSON visitor whose output will be written to the writer
+ /// specified.
+ #[inline]
+ pub fn with_formatter(writer: W, formatter: F) -> Self {
+ Serializer { writer, formatter }
+ }
+
+ /// Unwrap the `Writer` from the `Serializer`.
+ #[inline]
+ pub fn into_inner(self) -> W {
+ self.writer
+ }
+}
+
+impl<'a, W, F> ser::Serializer for &'a mut Serializer<W, F>
+where
+ W: io::Write,
+ F: Formatter,
+{
+ type Ok = ();
+ type Error = Error;
+
+ type SerializeSeq = Compound<'a, W, F>;
+ type SerializeTuple = Compound<'a, W, F>;
+ type SerializeTupleStruct = Compound<'a, W, F>;
+ type SerializeTupleVariant = Compound<'a, W, F>;
+ type SerializeMap = Compound<'a, W, F>;
+ type SerializeStruct = Compound<'a, W, F>;
+ type SerializeStructVariant = Compound<'a, W, F>;
+
+ #[inline]
+ fn serialize_bool(self, value: bool) -> Result<()> {
+ self.formatter
+ .write_bool(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_i8(self, value: i8) -> Result<()> {
+ self.formatter
+ .write_i8(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_i16(self, value: i16) -> Result<()> {
+ self.formatter
+ .write_i16(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_i32(self, value: i32) -> Result<()> {
+ self.formatter
+ .write_i32(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_i64(self, value: i64) -> Result<()> {
+ self.formatter
+ .write_i64(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ fn serialize_i128(self, value: i128) -> Result<()> {
+ self.formatter
+ .write_i128(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_u8(self, value: u8) -> Result<()> {
+ self.formatter
+ .write_u8(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_u16(self, value: u16) -> Result<()> {
+ self.formatter
+ .write_u16(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_u32(self, value: u32) -> Result<()> {
+ self.formatter
+ .write_u32(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_u64(self, value: u64) -> Result<()> {
+ self.formatter
+ .write_u64(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ fn serialize_u128(self, value: u128) -> Result<()> {
+ self.formatter
+ .write_u128(&mut self.writer, value)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_f32(self, value: f32) -> Result<()> {
+ match value.classify() {
+ FpCategory::Nan | FpCategory::Infinite => self
+ .formatter
+ .write_null(&mut self.writer)
+ .map_err(Error::io),
+ _ => self
+ .formatter
+ .write_f32(&mut self.writer, value)
+ .map_err(Error::io),
+ }
+ }
+
+ #[inline]
+ fn serialize_f64(self, value: f64) -> Result<()> {
+ match value.classify() {
+ FpCategory::Nan | FpCategory::Infinite => self
+ .formatter
+ .write_null(&mut self.writer)
+ .map_err(Error::io),
+ _ => self
+ .formatter
+ .write_f64(&mut self.writer, value)
+ .map_err(Error::io),
+ }
+ }
+
+ #[inline]
+ fn serialize_char(self, value: char) -> Result<()> {
+ // A char encoded as UTF-8 takes 4 bytes at most.
+ let mut buf = [0; 4];
+ self.serialize_str(value.encode_utf8(&mut buf))
+ }
+
+ #[inline]
+ fn serialize_str(self, value: &str) -> Result<()> {
+ format_escaped_str(&mut self.writer, &mut self.formatter, value).map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_bytes(self, value: &[u8]) -> Result<()> {
+ use serde::ser::SerializeSeq;
+ let mut seq = tri!(self.serialize_seq(Some(value.len())));
+ for byte in value {
+ tri!(seq.serialize_element(byte));
+ }
+ seq.end()
+ }
+
+ #[inline]
+ fn serialize_unit(self) -> Result<()> {
+ self.formatter
+ .write_null(&mut self.writer)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<()> {
+ self.serialize_str(variant)
+ }
+
+ /// Serialize newtypes without an object wrapper.
+ #[inline]
+ fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ value.serialize(self)
+ }
+
+ #[inline]
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ tri!(self
+ .formatter
+ .begin_object(&mut self.writer)
+ .map_err(Error::io));
+ tri!(self
+ .formatter
+ .begin_object_key(&mut self.writer, true)
+ .map_err(Error::io));
+ tri!(self.serialize_str(variant));
+ tri!(self
+ .formatter
+ .end_object_key(&mut self.writer)
+ .map_err(Error::io));
+ tri!(self
+ .formatter
+ .begin_object_value(&mut self.writer)
+ .map_err(Error::io));
+ tri!(value.serialize(&mut *self));
+ tri!(self
+ .formatter
+ .end_object_value(&mut self.writer)
+ .map_err(Error::io));
+ self.formatter
+ .end_object(&mut self.writer)
+ .map_err(Error::io)
+ }
+
+ #[inline]
+ fn serialize_none(self) -> Result<()> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_some<T>(self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ value.serialize(self)
+ }
+
+ #[inline]
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
+ tri!(self
+ .formatter
+ .begin_array(&mut self.writer)
+ .map_err(Error::io));
+ if len == Some(0) {
+ tri!(self
+ .formatter
+ .end_array(&mut self.writer)
+ .map_err(Error::io));
+ Ok(Compound::Map {
+ ser: self,
+ state: State::Empty,
+ })
+ } else {
+ Ok(Compound::Map {
+ ser: self,
+ state: State::First,
+ })
+ }
+ }
+
+ #[inline]
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
+ self.serialize_seq(Some(len))
+ }
+
+ #[inline]
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ self.serialize_seq(Some(len))
+ }
+
+ #[inline]
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ tri!(self
+ .formatter
+ .begin_object(&mut self.writer)
+ .map_err(Error::io));
+ tri!(self
+ .formatter
+ .begin_object_key(&mut self.writer, true)
+ .map_err(Error::io));
+ tri!(self.serialize_str(variant));
+ tri!(self
+ .formatter
+ .end_object_key(&mut self.writer)
+ .map_err(Error::io));
+ tri!(self
+ .formatter
+ .begin_object_value(&mut self.writer)
+ .map_err(Error::io));
+ self.serialize_seq(Some(len))
+ }
+
+ #[inline]
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
+ tri!(self
+ .formatter
+ .begin_object(&mut self.writer)
+ .map_err(Error::io));
+ if len == Some(0) {
+ tri!(self
+ .formatter
+ .end_object(&mut self.writer)
+ .map_err(Error::io));
+ Ok(Compound::Map {
+ ser: self,
+ state: State::Empty,
+ })
+ } else {
+ Ok(Compound::Map {
+ ser: self,
+ state: State::First,
+ })
+ }
+ }
+
+ #[inline]
+ fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
+ match name {
+ #[cfg(feature = "arbitrary_precision")]
+ crate::number::TOKEN => Ok(Compound::Number { ser: self }),
+ #[cfg(feature = "raw_value")]
+ crate::raw::TOKEN => Ok(Compound::RawValue { ser: self }),
+ _ => self.serialize_map(Some(len)),
+ }
+ }
+
+ #[inline]
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ tri!(self
+ .formatter
+ .begin_object(&mut self.writer)
+ .map_err(Error::io));
+ tri!(self
+ .formatter
+ .begin_object_key(&mut self.writer, true)
+ .map_err(Error::io));
+ tri!(self.serialize_str(variant));
+ tri!(self
+ .formatter
+ .end_object_key(&mut self.writer)
+ .map_err(Error::io));
+ tri!(self
+ .formatter
+ .begin_object_value(&mut self.writer)
+ .map_err(Error::io));
+ self.serialize_map(Some(len))
+ }
+
+ fn collect_str<T>(self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Display,
+ {
+ use self::fmt::Write;
+
+ struct Adapter<'ser, W: 'ser, F: 'ser> {
+ writer: &'ser mut W,
+ formatter: &'ser mut F,
+ error: Option<io::Error>,
+ }
+
+ impl<'ser, W, F> Write for Adapter<'ser, W, F>
+ where
+ W: io::Write,
+ F: Formatter,
+ {
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ debug_assert!(self.error.is_none());
+ match format_escaped_str_contents(self.writer, self.formatter, s) {
+ Ok(()) => Ok(()),
+ Err(err) => {
+ self.error = Some(err);
+ Err(fmt::Error)
+ }
+ }
+ }
+ }
+
+ tri!(self
+ .formatter
+ .begin_string(&mut self.writer)
+ .map_err(Error::io));
+ {
+ let mut adapter = Adapter {
+ writer: &mut self.writer,
+ formatter: &mut self.formatter,
+ error: None,
+ };
+ match write!(adapter, "{}", value) {
+ Ok(()) => debug_assert!(adapter.error.is_none()),
+ Err(fmt::Error) => {
+ return Err(Error::io(adapter.error.expect("there should be an error")));
+ }
+ }
+ }
+ self.formatter
+ .end_string(&mut self.writer)
+ .map_err(Error::io)
+ }
+}
+
+// Not public API. Should be pub(crate).
+#[doc(hidden)]
+#[derive(Eq, PartialEq)]
+pub enum State {
+ Empty,
+ First,
+ Rest,
+}
+
+// Not public API. Should be pub(crate).
+#[doc(hidden)]
+pub enum Compound<'a, W: 'a, F: 'a> {
+ Map {
+ ser: &'a mut Serializer<W, F>,
+ state: State,
+ },
+ #[cfg(feature = "arbitrary_precision")]
+ Number { ser: &'a mut Serializer<W, F> },
+ #[cfg(feature = "raw_value")]
+ RawValue { ser: &'a mut Serializer<W, F> },
+}
+
+impl<'a, W, F> ser::SerializeSeq for Compound<'a, W, F>
+where
+ W: io::Write,
+ F: Formatter,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ match self {
+ Compound::Map { ser, state } => {
+ tri!(ser
+ .formatter
+ .begin_array_value(&mut ser.writer, *state == State::First)
+ .map_err(Error::io));
+ *state = State::Rest;
+ tri!(value.serialize(&mut **ser));
+ ser.formatter
+ .end_array_value(&mut ser.writer)
+ .map_err(Error::io)
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ Compound::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ Compound::RawValue { .. } => unreachable!(),
+ }
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ match self {
+ Compound::Map { ser, state } => match state {
+ State::Empty => Ok(()),
+ _ => ser.formatter.end_array(&mut ser.writer).map_err(Error::io),
+ },
+ #[cfg(feature = "arbitrary_precision")]
+ Compound::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ Compound::RawValue { .. } => unreachable!(),
+ }
+ }
+}
+
+impl<'a, W, F> ser::SerializeTuple for Compound<'a, W, F>
+where
+ W: io::Write,
+ F: Formatter,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ ser::SerializeSeq::end(self)
+ }
+}
+
+impl<'a, W, F> ser::SerializeTupleStruct for Compound<'a, W, F>
+where
+ W: io::Write,
+ F: Formatter,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ ser::SerializeSeq::end(self)
+ }
+}
+
+impl<'a, W, F> ser::SerializeTupleVariant for Compound<'a, W, F>
+where
+ W: io::Write,
+ F: Formatter,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ match self {
+ Compound::Map { ser, state } => {
+ match state {
+ State::Empty => {}
+ _ => tri!(ser.formatter.end_array(&mut ser.writer).map_err(Error::io)),
+ }
+ tri!(ser
+ .formatter
+ .end_object_value(&mut ser.writer)
+ .map_err(Error::io));
+ ser.formatter.end_object(&mut ser.writer).map_err(Error::io)
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ Compound::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ Compound::RawValue { .. } => unreachable!(),
+ }
+ }
+}
+
+impl<'a, W, F> ser::SerializeMap for Compound<'a, W, F>
+where
+ W: io::Write,
+ F: Formatter,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_key<T>(&mut self, key: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ match self {
+ Compound::Map { ser, state } => {
+ tri!(ser
+ .formatter
+ .begin_object_key(&mut ser.writer, *state == State::First)
+ .map_err(Error::io));
+ *state = State::Rest;
+
+ tri!(key.serialize(MapKeySerializer { ser: *ser }));
+
+ ser.formatter
+ .end_object_key(&mut ser.writer)
+ .map_err(Error::io)
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ Compound::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ Compound::RawValue { .. } => unreachable!(),
+ }
+ }
+
+ #[inline]
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ match self {
+ Compound::Map { ser, .. } => {
+ tri!(ser
+ .formatter
+ .begin_object_value(&mut ser.writer)
+ .map_err(Error::io));
+ tri!(value.serialize(&mut **ser));
+ ser.formatter
+ .end_object_value(&mut ser.writer)
+ .map_err(Error::io)
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ Compound::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ Compound::RawValue { .. } => unreachable!(),
+ }
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ match self {
+ Compound::Map { ser, state } => match state {
+ State::Empty => Ok(()),
+ _ => ser.formatter.end_object(&mut ser.writer).map_err(Error::io),
+ },
+ #[cfg(feature = "arbitrary_precision")]
+ Compound::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ Compound::RawValue { .. } => unreachable!(),
+ }
+ }
+}
+
+impl<'a, W, F> ser::SerializeStruct for Compound<'a, W, F>
+where
+ W: io::Write,
+ F: Formatter,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ match self {
+ Compound::Map { .. } => ser::SerializeMap::serialize_entry(self, key, value),
+ #[cfg(feature = "arbitrary_precision")]
+ Compound::Number { ser, .. } => {
+ if key == crate::number::TOKEN {
+ value.serialize(NumberStrEmitter(ser))
+ } else {
+ Err(invalid_number())
+ }
+ }
+ #[cfg(feature = "raw_value")]
+ Compound::RawValue { ser, .. } => {
+ if key == crate::raw::TOKEN {
+ value.serialize(RawValueStrEmitter(ser))
+ } else {
+ Err(invalid_raw_value())
+ }
+ }
+ }
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ match self {
+ Compound::Map { .. } => ser::SerializeMap::end(self),
+ #[cfg(feature = "arbitrary_precision")]
+ Compound::Number { .. } => Ok(()),
+ #[cfg(feature = "raw_value")]
+ Compound::RawValue { .. } => Ok(()),
+ }
+ }
+}
+
+impl<'a, W, F> ser::SerializeStructVariant for Compound<'a, W, F>
+where
+ W: io::Write,
+ F: Formatter,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ match *self {
+ Compound::Map { .. } => ser::SerializeStruct::serialize_field(self, key, value),
+ #[cfg(feature = "arbitrary_precision")]
+ Compound::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ Compound::RawValue { .. } => unreachable!(),
+ }
+ }
+
+ #[inline]
+ fn end(self) -> Result<()> {
+ match self {
+ Compound::Map { ser, state } => {
+ match state {
+ State::Empty => {}
+ _ => tri!(ser.formatter.end_object(&mut ser.writer).map_err(Error::io)),
+ }
+ tri!(ser
+ .formatter
+ .end_object_value(&mut ser.writer)
+ .map_err(Error::io));
+ ser.formatter.end_object(&mut ser.writer).map_err(Error::io)
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ Compound::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ Compound::RawValue { .. } => unreachable!(),
+ }
+ }
+}
+
+struct MapKeySerializer<'a, W: 'a, F: 'a> {
+ ser: &'a mut Serializer<W, F>,
+}
+
+#[cfg(feature = "arbitrary_precision")]
+fn invalid_number() -> Error {
+ Error::syntax(ErrorCode::InvalidNumber, 0, 0)
+}
+
+#[cfg(feature = "raw_value")]
+fn invalid_raw_value() -> Error {
+ Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0)
+}
+
+fn key_must_be_a_string() -> Error {
+ Error::syntax(ErrorCode::KeyMustBeAString, 0, 0)
+}
+
+impl<'a, W, F> ser::Serializer for MapKeySerializer<'a, W, F>
+where
+ W: io::Write,
+ F: Formatter,
+{
+ type Ok = ();
+ type Error = Error;
+
+ #[inline]
+ fn serialize_str(self, value: &str) -> Result<()> {
+ self.ser.serialize_str(value)
+ }
+
+ #[inline]
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<()> {
+ self.ser.serialize_str(variant)
+ }
+
+ #[inline]
+ fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ value.serialize(self)
+ }
+
+ type SerializeSeq = Impossible<(), Error>;
+ type SerializeTuple = Impossible<(), Error>;
+ type SerializeTupleStruct = Impossible<(), Error>;
+ type SerializeTupleVariant = Impossible<(), Error>;
+ type SerializeMap = Impossible<(), Error>;
+ type SerializeStruct = Impossible<(), Error>;
+ type SerializeStructVariant = Impossible<(), Error>;
+
+ fn serialize_bool(self, _value: bool) -> Result<()> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_i8(self, value: i8) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_i8(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
+ }
+
+ fn serialize_i16(self, value: i16) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_i16(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
+ }
+
+ fn serialize_i32(self, value: i32) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_i32(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
+ }
+
+ fn serialize_i64(self, value: i64) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_i64(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
+ }
+
+ fn serialize_i128(self, value: i128) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_i128(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
+ }
+
+ fn serialize_u8(self, value: u8) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_u8(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
+ }
+
+ fn serialize_u16(self, value: u16) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_u16(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
+ }
+
+ fn serialize_u32(self, value: u32) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_u32(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
+ }
+
+ fn serialize_u64(self, value: u64) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_u64(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
+ }
+
+ fn serialize_u128(self, value: u128) -> Result<()> {
+ tri!(self
+ .ser
+ .formatter
+ .begin_string(&mut self.ser.writer)
+ .map_err(Error::io));
+ tri!(self
+ .ser
+ .formatter
+ .write_u128(&mut self.ser.writer, value)
+ .map_err(Error::io));
+ self.ser
+ .formatter
+ .end_string(&mut self.ser.writer)
+ .map_err(Error::io)
+ }
+
+ fn serialize_f32(self, _value: f32) -> Result<()> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_f64(self, _value: f64) -> Result<()> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_char(self, value: char) -> Result<()> {
+ self.ser.serialize_str(&value.to_string())
+ }
+
+ fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_unit(self) -> Result<()> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_none(self) -> Result<()> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_some<T>(self, _value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ Err(key_must_be_a_string())
+ }
+
+ fn collect_str<T>(self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Display,
+ {
+ self.ser.collect_str(value)
+ }
+}
+
+#[cfg(feature = "arbitrary_precision")]
+struct NumberStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer<W, F>);
+
+#[cfg(feature = "arbitrary_precision")]
+impl<'a, W: io::Write, F: Formatter> ser::Serializer for NumberStrEmitter<'a, W, F> {
+ type Ok = ();
+ type Error = Error;
+
+ type SerializeSeq = Impossible<(), Error>;
+ type SerializeTuple = Impossible<(), Error>;
+ type SerializeTupleStruct = Impossible<(), Error>;
+ type SerializeTupleVariant = Impossible<(), Error>;
+ type SerializeMap = Impossible<(), Error>;
+ type SerializeStruct = Impossible<(), Error>;
+ type SerializeStructVariant = Impossible<(), Error>;
+
+ fn serialize_bool(self, _v: bool) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_i8(self, _v: i8) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_i16(self, _v: i16) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_i32(self, _v: i32) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_i64(self, _v: i64) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_i128(self, _v: i128) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_u8(self, _v: u8) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_u16(self, _v: u16) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_u32(self, _v: u32) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_u64(self, _v: u64) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_u128(self, _v: u128) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_f32(self, _v: f32) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_f64(self, _v: f64) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_char(self, _v: char) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_str(self, value: &str) -> Result<()> {
+ let NumberStrEmitter(serializer) = self;
+ serializer
+ .formatter
+ .write_number_str(&mut serializer.writer, value)
+ .map_err(Error::io)
+ }
+
+ fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_none(self) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_some<T>(self, _value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(invalid_number())
+ }
+
+ fn serialize_unit(self) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ ) -> Result<()> {
+ Err(invalid_number())
+ }
+
+ fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(invalid_number())
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(invalid_number())
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
+ Err(invalid_number())
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
+ Err(invalid_number())
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ Err(invalid_number())
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ Err(invalid_number())
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+ Err(invalid_number())
+ }
+
+ fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
+ Err(invalid_number())
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ Err(invalid_number())
+ }
+}
+
+#[cfg(feature = "raw_value")]
+struct RawValueStrEmitter<'a, W: 'a + io::Write, F: 'a + Formatter>(&'a mut Serializer<W, F>);
+
+#[cfg(feature = "raw_value")]
+impl<'a, W: io::Write, F: Formatter> ser::Serializer for RawValueStrEmitter<'a, W, F> {
+ type Ok = ();
+ type Error = Error;
+
+ type SerializeSeq = Impossible<(), Error>;
+ type SerializeTuple = Impossible<(), Error>;
+ type SerializeTupleStruct = Impossible<(), Error>;
+ type SerializeTupleVariant = Impossible<(), Error>;
+ type SerializeMap = Impossible<(), Error>;
+ type SerializeStruct = Impossible<(), Error>;
+ type SerializeStructVariant = Impossible<(), Error>;
+
+ fn serialize_bool(self, _v: bool) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_i8(self, _v: i8) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_i16(self, _v: i16) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_i32(self, _v: i32) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_i64(self, _v: i64) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_i128(self, _v: i128) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_u8(self, _v: u8) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_u16(self, _v: u16) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_u32(self, _v: u32) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_u64(self, _v: u64) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_u128(self, _v: u128) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_f32(self, _v: f32) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_f64(self, _v: f64) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_char(self, _v: char) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_str(self, value: &str) -> Result<()> {
+ let RawValueStrEmitter(serializer) = self;
+ serializer
+ .formatter
+ .write_raw_fragment(&mut serializer.writer, value)
+ .map_err(Error::io)
+ }
+
+ fn serialize_bytes(self, _value: &[u8]) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_none(self) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_some<T>(self, _value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_unit(self) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ ) -> Result<()> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ Err(ser::Error::custom("expected RawValue"))
+ }
+
+ fn collect_str<T>(self, value: &T) -> Result<Self::Ok>
+ where
+ T: ?Sized + Display,
+ {
+ self.serialize_str(&value.to_string())
+ }
+}
+
+/// Represents a character escape code in a type-safe manner.
+pub enum CharEscape {
+ /// An escaped quote `"`
+ Quote,
+ /// An escaped reverse solidus `\`
+ ReverseSolidus,
+ /// An escaped solidus `/`
+ Solidus,
+ /// An escaped backspace character (usually escaped as `\b`)
+ Backspace,
+ /// An escaped form feed character (usually escaped as `\f`)
+ FormFeed,
+ /// An escaped line feed character (usually escaped as `\n`)
+ LineFeed,
+ /// An escaped carriage return character (usually escaped as `\r`)
+ CarriageReturn,
+ /// An escaped tab character (usually escaped as `\t`)
+ Tab,
+ /// An escaped ASCII plane control character (usually escaped as
+ /// `\u00XX` where `XX` are two hex characters)
+ AsciiControl(u8),
+}
+
+impl CharEscape {
+ #[inline]
+ fn from_escape_table(escape: u8, byte: u8) -> CharEscape {
+ match escape {
+ self::BB => CharEscape::Backspace,
+ self::TT => CharEscape::Tab,
+ self::NN => CharEscape::LineFeed,
+ self::FF => CharEscape::FormFeed,
+ self::RR => CharEscape::CarriageReturn,
+ self::QU => CharEscape::Quote,
+ self::BS => CharEscape::ReverseSolidus,
+ self::UU => CharEscape::AsciiControl(byte),
+ _ => unreachable!(),
+ }
+ }
+}
+
+/// This trait abstracts away serializing the JSON control characters, which allows the user to
+/// optionally pretty print the JSON output.
+pub trait Formatter {
+ /// Writes a `null` value to the specified writer.
+ #[inline]
+ fn write_null<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(b"null")
+ }
+
+ /// Writes a `true` or `false` value to the specified writer.
+ #[inline]
+ fn write_bool<W>(&mut self, writer: &mut W, value: bool) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let s = if value {
+ b"true" as &[u8]
+ } else {
+ b"false" as &[u8]
+ };
+ writer.write_all(s)
+ }
+
+ /// Writes an integer value like `-123` to the specified writer.
+ #[inline]
+ fn write_i8<W>(&mut self, writer: &mut W, value: i8) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes an integer value like `-123` to the specified writer.
+ #[inline]
+ fn write_i16<W>(&mut self, writer: &mut W, value: i16) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes an integer value like `-123` to the specified writer.
+ #[inline]
+ fn write_i32<W>(&mut self, writer: &mut W, value: i32) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes an integer value like `-123` to the specified writer.
+ #[inline]
+ fn write_i64<W>(&mut self, writer: &mut W, value: i64) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes an integer value like `-123` to the specified writer.
+ #[inline]
+ fn write_i128<W>(&mut self, writer: &mut W, value: i128) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes an integer value like `123` to the specified writer.
+ #[inline]
+ fn write_u8<W>(&mut self, writer: &mut W, value: u8) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes an integer value like `123` to the specified writer.
+ #[inline]
+ fn write_u16<W>(&mut self, writer: &mut W, value: u16) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes an integer value like `123` to the specified writer.
+ #[inline]
+ fn write_u32<W>(&mut self, writer: &mut W, value: u32) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes an integer value like `123` to the specified writer.
+ #[inline]
+ fn write_u64<W>(&mut self, writer: &mut W, value: u64) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes an integer value like `123` to the specified writer.
+ #[inline]
+ fn write_u128<W>(&mut self, writer: &mut W, value: u128) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = itoa::Buffer::new();
+ let s = buffer.format(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes a floating point value like `-31.26e+12` to the specified writer.
+ #[inline]
+ fn write_f32<W>(&mut self, writer: &mut W, value: f32) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = ryu::Buffer::new();
+ let s = buffer.format_finite(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes a floating point value like `-31.26e+12` to the specified writer.
+ #[inline]
+ fn write_f64<W>(&mut self, writer: &mut W, value: f64) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ let mut buffer = ryu::Buffer::new();
+ let s = buffer.format_finite(value);
+ writer.write_all(s.as_bytes())
+ }
+
+ /// Writes a number that has already been rendered to a string.
+ #[inline]
+ fn write_number_str<W>(&mut self, writer: &mut W, value: &str) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(value.as_bytes())
+ }
+
+ /// Called before each series of `write_string_fragment` and
+ /// `write_char_escape`. Writes a `"` to the specified writer.
+ #[inline]
+ fn begin_string<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(b"\"")
+ }
+
+ /// Called after each series of `write_string_fragment` and
+ /// `write_char_escape`. Writes a `"` to the specified writer.
+ #[inline]
+ fn end_string<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(b"\"")
+ }
+
+ /// Writes a string fragment that doesn't need any escaping to the
+ /// specified writer.
+ #[inline]
+ fn write_string_fragment<W>(&mut self, writer: &mut W, fragment: &str) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(fragment.as_bytes())
+ }
+
+ /// Writes a character escape code to the specified writer.
+ #[inline]
+ fn write_char_escape<W>(&mut self, writer: &mut W, char_escape: CharEscape) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ use self::CharEscape::*;
+
+ let s = match char_escape {
+ Quote => b"\\\"",
+ ReverseSolidus => b"\\\\",
+ Solidus => b"\\/",
+ Backspace => b"\\b",
+ FormFeed => b"\\f",
+ LineFeed => b"\\n",
+ CarriageReturn => b"\\r",
+ Tab => b"\\t",
+ AsciiControl(byte) => {
+ static HEX_DIGITS: [u8; 16] = *b"0123456789abcdef";
+ let bytes = &[
+ b'\\',
+ b'u',
+ b'0',
+ b'0',
+ HEX_DIGITS[(byte >> 4) as usize],
+ HEX_DIGITS[(byte & 0xF) as usize],
+ ];
+ return writer.write_all(bytes);
+ }
+ };
+
+ writer.write_all(s)
+ }
+
+ /// Called before every array. Writes a `[` to the specified
+ /// writer.
+ #[inline]
+ fn begin_array<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(b"[")
+ }
+
+ /// Called after every array. Writes a `]` to the specified
+ /// writer.
+ #[inline]
+ fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(b"]")
+ }
+
+ /// Called before every array value. Writes a `,` if needed to
+ /// the specified writer.
+ #[inline]
+ fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ if first {
+ Ok(())
+ } else {
+ writer.write_all(b",")
+ }
+ }
+
+ /// Called after every array value.
+ #[inline]
+ fn end_array_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ Ok(())
+ }
+
+ /// Called before every object. Writes a `{` to the specified
+ /// writer.
+ #[inline]
+ fn begin_object<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(b"{")
+ }
+
+ /// Called after every object. Writes a `}` to the specified
+ /// writer.
+ #[inline]
+ fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(b"}")
+ }
+
+ /// Called before every object key.
+ #[inline]
+ fn begin_object_key<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ if first {
+ Ok(())
+ } else {
+ writer.write_all(b",")
+ }
+ }
+
+ /// Called after every object key. A `:` should be written to the
+ /// specified writer by either this method or
+ /// `begin_object_value`.
+ #[inline]
+ fn end_object_key<W>(&mut self, _writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ Ok(())
+ }
+
+ /// Called before every object value. A `:` should be written to
+ /// the specified writer by either this method or
+ /// `end_object_key`.
+ #[inline]
+ fn begin_object_value<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(b":")
+ }
+
+ /// Called after every object value.
+ #[inline]
+ fn end_object_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ Ok(())
+ }
+
+ /// Writes a raw JSON fragment that doesn't need any escaping to the
+ /// specified writer.
+ #[inline]
+ fn write_raw_fragment<W>(&mut self, writer: &mut W, fragment: &str) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(fragment.as_bytes())
+ }
+}
+
+/// This structure compacts a JSON value with no extra whitespace.
+#[derive(Clone, Debug)]
+pub struct CompactFormatter;
+
+impl Formatter for CompactFormatter {}
+
+/// This structure pretty prints a JSON value to make it human readable.
+#[derive(Clone, Debug)]
+pub struct PrettyFormatter<'a> {
+ current_indent: usize,
+ has_value: bool,
+ indent: &'a [u8],
+}
+
+impl<'a> PrettyFormatter<'a> {
+ /// Construct a pretty printer formatter that defaults to using two spaces for indentation.
+ pub fn new() -> Self {
+ PrettyFormatter::with_indent(b" ")
+ }
+
+ /// Construct a pretty printer formatter that uses the `indent` string for indentation.
+ pub fn with_indent(indent: &'a [u8]) -> Self {
+ PrettyFormatter {
+ current_indent: 0,
+ has_value: false,
+ indent,
+ }
+ }
+}
+
+impl<'a> Default for PrettyFormatter<'a> {
+ fn default() -> Self {
+ PrettyFormatter::new()
+ }
+}
+
+impl<'a> Formatter for PrettyFormatter<'a> {
+ #[inline]
+ fn begin_array<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ self.current_indent += 1;
+ self.has_value = false;
+ writer.write_all(b"[")
+ }
+
+ #[inline]
+ fn end_array<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ self.current_indent -= 1;
+
+ if self.has_value {
+ tri!(writer.write_all(b"\n"));
+ tri!(indent(writer, self.current_indent, self.indent));
+ }
+
+ writer.write_all(b"]")
+ }
+
+ #[inline]
+ fn begin_array_value<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ tri!(writer.write_all(if first { b"\n" } else { b",\n" }));
+ indent(writer, self.current_indent, self.indent)
+ }
+
+ #[inline]
+ fn end_array_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ self.has_value = true;
+ Ok(())
+ }
+
+ #[inline]
+ fn begin_object<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ self.current_indent += 1;
+ self.has_value = false;
+ writer.write_all(b"{")
+ }
+
+ #[inline]
+ fn end_object<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ self.current_indent -= 1;
+
+ if self.has_value {
+ tri!(writer.write_all(b"\n"));
+ tri!(indent(writer, self.current_indent, self.indent));
+ }
+
+ writer.write_all(b"}")
+ }
+
+ #[inline]
+ fn begin_object_key<W>(&mut self, writer: &mut W, first: bool) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ tri!(writer.write_all(if first { b"\n" } else { b",\n" }));
+ indent(writer, self.current_indent, self.indent)
+ }
+
+ #[inline]
+ fn begin_object_value<W>(&mut self, writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ writer.write_all(b": ")
+ }
+
+ #[inline]
+ fn end_object_value<W>(&mut self, _writer: &mut W) -> io::Result<()>
+ where
+ W: ?Sized + io::Write,
+ {
+ self.has_value = true;
+ Ok(())
+ }
+}
+
+fn format_escaped_str<W, F>(writer: &mut W, formatter: &mut F, value: &str) -> io::Result<()>
+where
+ W: ?Sized + io::Write,
+ F: ?Sized + Formatter,
+{
+ tri!(formatter.begin_string(writer));
+ tri!(format_escaped_str_contents(writer, formatter, value));
+ formatter.end_string(writer)
+}
+
+fn format_escaped_str_contents<W, F>(
+ writer: &mut W,
+ formatter: &mut F,
+ value: &str,
+) -> io::Result<()>
+where
+ W: ?Sized + io::Write,
+ F: ?Sized + Formatter,
+{
+ let bytes = value.as_bytes();
+
+ let mut start = 0;
+
+ for (i, &byte) in bytes.iter().enumerate() {
+ let escape = ESCAPE[byte as usize];
+ if escape == 0 {
+ continue;
+ }
+
+ if start < i {
+ tri!(formatter.write_string_fragment(writer, &value[start..i]));
+ }
+
+ let char_escape = CharEscape::from_escape_table(escape, byte);
+ tri!(formatter.write_char_escape(writer, char_escape));
+
+ start = i + 1;
+ }
+
+ if start == bytes.len() {
+ return Ok(());
+ }
+
+ formatter.write_string_fragment(writer, &value[start..])
+}
+
+const BB: u8 = b'b'; // \x08
+const TT: u8 = b't'; // \x09
+const NN: u8 = b'n'; // \x0A
+const FF: u8 = b'f'; // \x0C
+const RR: u8 = b'r'; // \x0D
+const QU: u8 = b'"'; // \x22
+const BS: u8 = b'\\'; // \x5C
+const UU: u8 = b'u'; // \x00...\x1F except the ones above
+const __: u8 = 0;
+
+// Lookup table of escape sequences. A value of b'x' at index i means that byte
+// i is escaped as "\x" in JSON. A value of 0 means that byte i is not escaped.
+static ESCAPE: [u8; 256] = [
+ // 1 2 3 4 5 6 7 8 9 A B C D E F
+ UU, UU, UU, UU, UU, UU, UU, UU, BB, TT, NN, UU, FF, RR, UU, UU, // 0
+ UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, UU, // 1
+ __, __, QU, __, __, __, __, __, __, __, __, __, __, __, __, __, // 2
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 3
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 4
+ __, __, __, __, __, __, __, __, __, __, __, __, BS, __, __, __, // 5
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 6
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 7
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 8
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // 9
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // A
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // B
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // C
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // D
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // E
+ __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, __, // F
+];
+
+/// Serialize the given data structure as JSON into the IO stream.
+///
+/// # Errors
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// fail, or if `T` contains a map with non-string keys.
+#[inline]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
+where
+ W: io::Write,
+ T: ?Sized + Serialize,
+{
+ let mut ser = Serializer::new(writer);
+ value.serialize(&mut ser)
+}
+
+/// Serialize the given data structure as pretty-printed JSON into the IO
+/// stream.
+///
+/// # Errors
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// fail, or if `T` contains a map with non-string keys.
+#[inline]
+#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
+pub fn to_writer_pretty<W, T>(writer: W, value: &T) -> Result<()>
+where
+ W: io::Write,
+ T: ?Sized + Serialize,
+{
+ let mut ser = Serializer::pretty(writer);
+ value.serialize(&mut ser)
+}
+
+/// Serialize the given data structure as a JSON byte vector.
+///
+/// # Errors
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// fail, or if `T` contains a map with non-string keys.
+#[inline]
+pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
+where
+ T: ?Sized + Serialize,
+{
+ let mut writer = Vec::with_capacity(128);
+ tri!(to_writer(&mut writer, value));
+ Ok(writer)
+}
+
+/// Serialize the given data structure as a pretty-printed JSON byte vector.
+///
+/// # Errors
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// fail, or if `T` contains a map with non-string keys.
+#[inline]
+pub fn to_vec_pretty<T>(value: &T) -> Result<Vec<u8>>
+where
+ T: ?Sized + Serialize,
+{
+ let mut writer = Vec::with_capacity(128);
+ tri!(to_writer_pretty(&mut writer, value));
+ Ok(writer)
+}
+
+/// Serialize the given data structure as a String of JSON.
+///
+/// # Errors
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// fail, or if `T` contains a map with non-string keys.
+#[inline]
+pub fn to_string<T>(value: &T) -> Result<String>
+where
+ T: ?Sized + Serialize,
+{
+ let vec = tri!(to_vec(value));
+ let string = unsafe {
+ // We do not emit invalid UTF-8.
+ String::from_utf8_unchecked(vec)
+ };
+ Ok(string)
+}
+
+/// Serialize the given data structure as a pretty-printed String of JSON.
+///
+/// # Errors
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// fail, or if `T` contains a map with non-string keys.
+#[inline]
+pub fn to_string_pretty<T>(value: &T) -> Result<String>
+where
+ T: ?Sized + Serialize,
+{
+ let vec = tri!(to_vec_pretty(value));
+ let string = unsafe {
+ // We do not emit invalid UTF-8.
+ String::from_utf8_unchecked(vec)
+ };
+ Ok(string)
+}
+
+fn indent<W>(wr: &mut W, n: usize, s: &[u8]) -> io::Result<()>
+where
+ W: ?Sized + io::Write,
+{
+ for _ in 0..n {
+ tri!(wr.write_all(s));
+ }
+
+ Ok(())
+}
diff --git a/third_party/rust/serde_json/src/value/de.rs b/third_party/rust/serde_json/src/value/de.rs
new file mode 100644
index 0000000000..9c266d08ae
--- /dev/null
+++ b/third_party/rust/serde_json/src/value/de.rs
@@ -0,0 +1,1377 @@
+use crate::error::Error;
+use crate::map::Map;
+use crate::number::Number;
+use crate::value::Value;
+use alloc::borrow::{Cow, ToOwned};
+use alloc::string::String;
+#[cfg(feature = "raw_value")]
+use alloc::string::ToString;
+use alloc::vec::{self, Vec};
+use core::fmt;
+use core::slice;
+use core::str::FromStr;
+use serde::de::{
+ self, Deserialize, DeserializeSeed, EnumAccess, Expected, IntoDeserializer, MapAccess,
+ SeqAccess, Unexpected, VariantAccess, Visitor,
+};
+use serde::forward_to_deserialize_any;
+
+#[cfg(feature = "arbitrary_precision")]
+use crate::number::NumberFromString;
+
+impl<'de> Deserialize<'de> for Value {
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<Value, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ struct ValueVisitor;
+
+ impl<'de> Visitor<'de> for ValueVisitor {
+ type Value = Value;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("any valid JSON value")
+ }
+
+ #[inline]
+ fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
+ Ok(Value::Bool(value))
+ }
+
+ #[inline]
+ fn visit_i64<E>(self, value: i64) -> Result<Value, E> {
+ Ok(Value::Number(value.into()))
+ }
+
+ #[inline]
+ fn visit_u64<E>(self, value: u64) -> Result<Value, E> {
+ Ok(Value::Number(value.into()))
+ }
+
+ #[inline]
+ fn visit_f64<E>(self, value: f64) -> Result<Value, E> {
+ Ok(Number::from_f64(value).map_or(Value::Null, Value::Number))
+ }
+
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ #[inline]
+ fn visit_str<E>(self, value: &str) -> Result<Value, E>
+ where
+ E: serde::de::Error,
+ {
+ self.visit_string(String::from(value))
+ }
+
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ #[inline]
+ fn visit_string<E>(self, value: String) -> Result<Value, E> {
+ Ok(Value::String(value))
+ }
+
+ #[inline]
+ fn visit_none<E>(self) -> Result<Value, E> {
+ Ok(Value::Null)
+ }
+
+ #[inline]
+ fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer)
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<Value, E> {
+ Ok(Value::Null)
+ }
+
+ #[inline]
+ fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error>
+ where
+ V: SeqAccess<'de>,
+ {
+ let mut vec = Vec::new();
+
+ while let Some(elem) = tri!(visitor.next_element()) {
+ vec.push(elem);
+ }
+
+ Ok(Value::Array(vec))
+ }
+
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
+ where
+ V: MapAccess<'de>,
+ {
+ match visitor.next_key_seed(KeyClassifier)? {
+ #[cfg(feature = "arbitrary_precision")]
+ Some(KeyClass::Number) => {
+ let number: NumberFromString = visitor.next_value()?;
+ Ok(Value::Number(number.value))
+ }
+ #[cfg(feature = "raw_value")]
+ Some(KeyClass::RawValue) => {
+ let value = visitor.next_value_seed(crate::raw::BoxedFromString)?;
+ crate::from_str(value.get()).map_err(de::Error::custom)
+ }
+ Some(KeyClass::Map(first_key)) => {
+ let mut values = Map::new();
+
+ values.insert(first_key, tri!(visitor.next_value()));
+ while let Some((key, value)) = tri!(visitor.next_entry()) {
+ values.insert(key, value);
+ }
+
+ Ok(Value::Object(values))
+ }
+ None => Ok(Value::Object(Map::new())),
+ }
+ }
+ }
+
+ deserializer.deserialize_any(ValueVisitor)
+ }
+}
+
+impl FromStr for Value {
+ type Err = Error;
+ fn from_str(s: &str) -> Result<Value, Error> {
+ super::super::de::from_str(s)
+ }
+}
+
+macro_rules! deserialize_number {
+ ($method:ident) => {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ fn $method<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Number(n) => n.deserialize_any(visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ fn $method<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Number(n) => n.$method(visitor),
+ _ => self.deserialize_any(visitor),
+ }
+ }
+ };
+}
+
+fn visit_array<'de, V>(array: Vec<Value>, visitor: V) -> Result<V::Value, Error>
+where
+ V: Visitor<'de>,
+{
+ let len = array.len();
+ let mut deserializer = SeqDeserializer::new(array);
+ let seq = tri!(visitor.visit_seq(&mut deserializer));
+ let remaining = deserializer.iter.len();
+ if remaining == 0 {
+ Ok(seq)
+ } else {
+ Err(serde::de::Error::invalid_length(
+ len,
+ &"fewer elements in array",
+ ))
+ }
+}
+
+fn visit_object<'de, V>(object: Map<String, Value>, visitor: V) -> Result<V::Value, Error>
+where
+ V: Visitor<'de>,
+{
+ let len = object.len();
+ let mut deserializer = MapDeserializer::new(object);
+ let map = tri!(visitor.visit_map(&mut deserializer));
+ let remaining = deserializer.iter.len();
+ if remaining == 0 {
+ Ok(map)
+ } else {
+ Err(serde::de::Error::invalid_length(
+ len,
+ &"fewer elements in map",
+ ))
+ }
+}
+
+impl<'de> serde::Deserializer<'de> for Value {
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Null => visitor.visit_unit(),
+ Value::Bool(v) => visitor.visit_bool(v),
+ Value::Number(n) => n.deserialize_any(visitor),
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ Value::String(v) => visitor.visit_string(v),
+ Value::Array(v) => visit_array(v, visitor),
+ Value::Object(v) => visit_object(v, visitor),
+ }
+ }
+
+ deserialize_number!(deserialize_i8);
+ deserialize_number!(deserialize_i16);
+ deserialize_number!(deserialize_i32);
+ deserialize_number!(deserialize_i64);
+ deserialize_number!(deserialize_i128);
+ deserialize_number!(deserialize_u8);
+ deserialize_number!(deserialize_u16);
+ deserialize_number!(deserialize_u32);
+ deserialize_number!(deserialize_u64);
+ deserialize_number!(deserialize_u128);
+ deserialize_number!(deserialize_f32);
+ deserialize_number!(deserialize_f64);
+
+ #[inline]
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Null => visitor.visit_none(),
+ _ => visitor.visit_some(self),
+ }
+ }
+
+ #[inline]
+ fn deserialize_enum<V>(
+ self,
+ _name: &str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ let (variant, value) = match self {
+ Value::Object(value) => {
+ let mut iter = value.into_iter();
+ let (variant, value) = match iter.next() {
+ Some(v) => v,
+ None => {
+ return Err(serde::de::Error::invalid_value(
+ Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ };
+ // enums are encoded in json as maps with a single key:value pair
+ if iter.next().is_some() {
+ return Err(serde::de::Error::invalid_value(
+ Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ (variant, Some(value))
+ }
+ Value::String(variant) => (variant, None),
+ other => {
+ return Err(serde::de::Error::invalid_type(
+ other.unexpected(),
+ &"string or map",
+ ));
+ }
+ };
+
+ visitor.visit_enum(EnumDeserializer { variant, value })
+ }
+
+ #[inline]
+ fn deserialize_newtype_struct<V>(
+ self,
+ name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ #[cfg(feature = "raw_value")]
+ {
+ if name == crate::raw::TOKEN {
+ return visitor.visit_map(crate::raw::OwnedRawDeserializer {
+ raw_value: Some(self.to_string()),
+ });
+ }
+ }
+
+ let _ = name;
+ visitor.visit_newtype_struct(self)
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Bool(v) => visitor.visit_bool(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_string(visitor)
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_string(visitor)
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ Value::String(v) => visitor.visit_string(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_byte_buf(visitor)
+ }
+
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ Value::String(v) => visitor.visit_string(v),
+ Value::Array(v) => visit_array(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Null => visitor.visit_unit(),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_unit(visitor)
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Array(v) => visit_array(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, 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, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Object(v) => visit_object(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ _name: &'static str,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Array(v) => visit_array(v, visitor),
+ Value::Object(v) => visit_object(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_string(visitor)
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ drop(self);
+ visitor.visit_unit()
+ }
+}
+
+struct EnumDeserializer {
+ variant: String,
+ value: Option<Value>,
+}
+
+impl<'de> EnumAccess<'de> for EnumDeserializer {
+ type Error = Error;
+ type Variant = VariantDeserializer;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ let variant = self.variant.into_deserializer();
+ let visitor = VariantDeserializer { value: self.value };
+ seed.deserialize(variant).map(|v| (v, visitor))
+ }
+}
+
+impl<'de> IntoDeserializer<'de, Error> for Value {
+ type Deserializer = Self;
+
+ fn into_deserializer(self) -> Self::Deserializer {
+ self
+ }
+}
+
+struct VariantDeserializer {
+ value: Option<Value>,
+}
+
+impl<'de> VariantAccess<'de> for VariantDeserializer {
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<(), Error> {
+ match self.value {
+ Some(value) => Deserialize::deserialize(value),
+ None => Ok(()),
+ }
+ }
+
+ fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.value {
+ Some(value) => seed.deserialize(value),
+ None => Err(serde::de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"newtype variant",
+ )),
+ }
+ }
+
+ fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.value {
+ Some(Value::Array(v)) => {
+ if v.is_empty() {
+ visitor.visit_unit()
+ } else {
+ visit_array(v, visitor)
+ }
+ }
+ Some(other) => Err(serde::de::Error::invalid_type(
+ other.unexpected(),
+ &"tuple variant",
+ )),
+ None => Err(serde::de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"tuple variant",
+ )),
+ }
+ }
+
+ fn struct_variant<V>(
+ self,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.value {
+ Some(Value::Object(v)) => visit_object(v, visitor),
+ Some(other) => Err(serde::de::Error::invalid_type(
+ other.unexpected(),
+ &"struct variant",
+ )),
+ None => Err(serde::de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"struct variant",
+ )),
+ }
+ }
+}
+
+struct SeqDeserializer {
+ iter: vec::IntoIter<Value>,
+}
+
+impl SeqDeserializer {
+ fn new(vec: Vec<Value>) -> Self {
+ SeqDeserializer {
+ iter: vec.into_iter(),
+ }
+ }
+}
+
+impl<'de> SeqAccess<'de> for SeqDeserializer {
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some(value) => seed.deserialize(value).map(Some),
+ None => Ok(None),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ match self.iter.size_hint() {
+ (lower, Some(upper)) if lower == upper => Some(upper),
+ _ => None,
+ }
+ }
+}
+
+struct MapDeserializer {
+ iter: <Map<String, Value> as IntoIterator>::IntoIter,
+ value: Option<Value>,
+}
+
+impl MapDeserializer {
+ fn new(map: Map<String, Value>) -> Self {
+ MapDeserializer {
+ iter: map.into_iter(),
+ value: None,
+ }
+ }
+}
+
+impl<'de> MapAccess<'de> for MapDeserializer {
+ type Error = Error;
+
+ fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some((key, value)) => {
+ self.value = Some(value);
+ let key_de = MapKeyDeserializer {
+ key: Cow::Owned(key),
+ };
+ seed.deserialize(key_de).map(Some)
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.value.take() {
+ Some(value) => seed.deserialize(value),
+ None => Err(serde::de::Error::custom("value is missing")),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ match self.iter.size_hint() {
+ (lower, Some(upper)) if lower == upper => Some(upper),
+ _ => None,
+ }
+ }
+}
+
+macro_rules! deserialize_value_ref_number {
+ ($method:ident) => {
+ #[cfg(not(feature = "arbitrary_precision"))]
+ fn $method<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Number(n) => n.deserialize_any(visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ #[cfg(feature = "arbitrary_precision")]
+ fn $method<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Number(n) => n.$method(visitor),
+ _ => self.deserialize_any(visitor),
+ }
+ }
+ };
+}
+
+fn visit_array_ref<'de, V>(array: &'de [Value], visitor: V) -> Result<V::Value, Error>
+where
+ V: Visitor<'de>,
+{
+ let len = array.len();
+ let mut deserializer = SeqRefDeserializer::new(array);
+ let seq = tri!(visitor.visit_seq(&mut deserializer));
+ let remaining = deserializer.iter.len();
+ if remaining == 0 {
+ Ok(seq)
+ } else {
+ Err(serde::de::Error::invalid_length(
+ len,
+ &"fewer elements in array",
+ ))
+ }
+}
+
+fn visit_object_ref<'de, V>(object: &'de Map<String, Value>, visitor: V) -> Result<V::Value, Error>
+where
+ V: Visitor<'de>,
+{
+ let len = object.len();
+ let mut deserializer = MapRefDeserializer::new(object);
+ let map = tri!(visitor.visit_map(&mut deserializer));
+ let remaining = deserializer.iter.len();
+ if remaining == 0 {
+ Ok(map)
+ } else {
+ Err(serde::de::Error::invalid_length(
+ len,
+ &"fewer elements in map",
+ ))
+ }
+}
+
+impl<'de> serde::Deserializer<'de> for &'de Value {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Null => visitor.visit_unit(),
+ Value::Bool(v) => visitor.visit_bool(*v),
+ Value::Number(n) => n.deserialize_any(visitor),
+ Value::String(v) => visitor.visit_borrowed_str(v),
+ Value::Array(v) => visit_array_ref(v, visitor),
+ Value::Object(v) => visit_object_ref(v, visitor),
+ }
+ }
+
+ deserialize_value_ref_number!(deserialize_i8);
+ deserialize_value_ref_number!(deserialize_i16);
+ deserialize_value_ref_number!(deserialize_i32);
+ deserialize_value_ref_number!(deserialize_i64);
+ deserialize_number!(deserialize_i128);
+ deserialize_value_ref_number!(deserialize_u8);
+ deserialize_value_ref_number!(deserialize_u16);
+ deserialize_value_ref_number!(deserialize_u32);
+ deserialize_value_ref_number!(deserialize_u64);
+ deserialize_number!(deserialize_u128);
+ deserialize_value_ref_number!(deserialize_f32);
+ deserialize_value_ref_number!(deserialize_f64);
+
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self {
+ Value::Null => visitor.visit_none(),
+ _ => visitor.visit_some(self),
+ }
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ _name: &str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ let (variant, value) = match self {
+ Value::Object(value) => {
+ let mut iter = value.into_iter();
+ let (variant, value) = match iter.next() {
+ Some(v) => v,
+ None => {
+ return Err(serde::de::Error::invalid_value(
+ Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ };
+ // enums are encoded in json as maps with a single key:value pair
+ if iter.next().is_some() {
+ return Err(serde::de::Error::invalid_value(
+ Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ (variant, Some(value))
+ }
+ Value::String(variant) => (variant, None),
+ other => {
+ return Err(serde::de::Error::invalid_type(
+ other.unexpected(),
+ &"string or map",
+ ));
+ }
+ };
+
+ visitor.visit_enum(EnumRefDeserializer { variant, value })
+ }
+
+ #[inline]
+ fn deserialize_newtype_struct<V>(
+ self,
+ name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ #[cfg(feature = "raw_value")]
+ {
+ if name == crate::raw::TOKEN {
+ return visitor.visit_map(crate::raw::OwnedRawDeserializer {
+ raw_value: Some(self.to_string()),
+ });
+ }
+ }
+
+ let _ = name;
+ visitor.visit_newtype_struct(self)
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self {
+ Value::Bool(v) => visitor.visit_bool(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::String(v) => visitor.visit_borrowed_str(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::String(v) => visitor.visit_borrowed_str(v),
+ Value::Array(v) => visit_array_ref(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_bytes(visitor)
+ }
+
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match *self {
+ Value::Null => visitor.visit_unit(),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_unit(visitor)
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Array(v) => visit_array_ref(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, 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, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Object(v) => visit_object_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, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Array(v) => visit_array_ref(v, visitor),
+ Value::Object(v) => visit_object_ref(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_unit()
+ }
+}
+
+struct EnumRefDeserializer<'de> {
+ variant: &'de str,
+ value: Option<&'de Value>,
+}
+
+impl<'de> EnumAccess<'de> for EnumRefDeserializer<'de> {
+ type Error = Error;
+ type Variant = VariantRefDeserializer<'de>;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant), Error>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ let variant = self.variant.into_deserializer();
+ let visitor = VariantRefDeserializer { value: self.value };
+ seed.deserialize(variant).map(|v| (v, visitor))
+ }
+}
+
+struct VariantRefDeserializer<'de> {
+ value: Option<&'de Value>,
+}
+
+impl<'de> VariantAccess<'de> for VariantRefDeserializer<'de> {
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<(), Error> {
+ match self.value {
+ Some(value) => Deserialize::deserialize(value),
+ None => Ok(()),
+ }
+ }
+
+ fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.value {
+ Some(value) => seed.deserialize(value),
+ None => Err(serde::de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"newtype variant",
+ )),
+ }
+ }
+
+ fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.value {
+ Some(Value::Array(v)) => {
+ if v.is_empty() {
+ visitor.visit_unit()
+ } else {
+ visit_array_ref(v, visitor)
+ }
+ }
+ Some(other) => Err(serde::de::Error::invalid_type(
+ other.unexpected(),
+ &"tuple variant",
+ )),
+ None => Err(serde::de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"tuple variant",
+ )),
+ }
+ }
+
+ fn struct_variant<V>(
+ self,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.value {
+ Some(Value::Object(v)) => visit_object_ref(v, visitor),
+ Some(other) => Err(serde::de::Error::invalid_type(
+ other.unexpected(),
+ &"struct variant",
+ )),
+ None => Err(serde::de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"struct variant",
+ )),
+ }
+ }
+}
+
+struct SeqRefDeserializer<'de> {
+ iter: slice::Iter<'de, Value>,
+}
+
+impl<'de> SeqRefDeserializer<'de> {
+ fn new(slice: &'de [Value]) -> Self {
+ SeqRefDeserializer { iter: slice.iter() }
+ }
+}
+
+impl<'de> SeqAccess<'de> for SeqRefDeserializer<'de> {
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some(value) => seed.deserialize(value).map(Some),
+ None => Ok(None),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ match self.iter.size_hint() {
+ (lower, Some(upper)) if lower == upper => Some(upper),
+ _ => None,
+ }
+ }
+}
+
+struct MapRefDeserializer<'de> {
+ iter: <&'de Map<String, Value> as IntoIterator>::IntoIter,
+ value: Option<&'de Value>,
+}
+
+impl<'de> MapRefDeserializer<'de> {
+ fn new(map: &'de Map<String, Value>) -> Self {
+ MapRefDeserializer {
+ iter: map.into_iter(),
+ value: None,
+ }
+ }
+}
+
+impl<'de> MapAccess<'de> for MapRefDeserializer<'de> {
+ type Error = Error;
+
+ fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some((key, value)) => {
+ self.value = Some(value);
+ let key_de = MapKeyDeserializer {
+ key: Cow::Borrowed(&**key),
+ };
+ seed.deserialize(key_de).map(Some)
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.value.take() {
+ Some(value) => seed.deserialize(value),
+ None => Err(serde::de::Error::custom("value is missing")),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ match self.iter.size_hint() {
+ (lower, Some(upper)) if lower == upper => Some(upper),
+ _ => None,
+ }
+ }
+}
+
+struct MapKeyDeserializer<'de> {
+ key: Cow<'de, str>,
+}
+
+macro_rules! deserialize_integer_key {
+ ($method:ident => $visit:ident) => {
+ fn $method<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match (self.key.parse(), self.key) {
+ (Ok(integer), _) => visitor.$visit(integer),
+ (Err(_), Cow::Borrowed(s)) => visitor.visit_borrowed_str(s),
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ (Err(_), Cow::Owned(s)) => visitor.visit_string(s),
+ }
+ }
+ };
+}
+
+impl<'de> serde::Deserializer<'de> for MapKeyDeserializer<'de> {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ BorrowedCowStrDeserializer::new(self.key).deserialize_any(visitor)
+ }
+
+ deserialize_integer_key!(deserialize_i8 => visit_i8);
+ deserialize_integer_key!(deserialize_i16 => visit_i16);
+ deserialize_integer_key!(deserialize_i32 => visit_i32);
+ deserialize_integer_key!(deserialize_i64 => visit_i64);
+ deserialize_integer_key!(deserialize_i128 => visit_i128);
+ deserialize_integer_key!(deserialize_u8 => visit_u8);
+ deserialize_integer_key!(deserialize_u16 => visit_u16);
+ deserialize_integer_key!(deserialize_u32 => visit_u32);
+ deserialize_integer_key!(deserialize_u64 => visit_u64);
+ deserialize_integer_key!(deserialize_u128 => visit_u128);
+
+ #[inline]
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ // Map keys cannot be null.
+ visitor.visit_some(self)
+ }
+
+ #[inline]
+ fn deserialize_newtype_struct<V>(
+ self,
+ _name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_newtype_struct(self)
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ name: &'static str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.key
+ .into_deserializer()
+ .deserialize_enum(name, variants, visitor)
+ }
+
+ forward_to_deserialize_any! {
+ bool f32 f64 char str string bytes byte_buf unit unit_struct seq tuple
+ tuple_struct map struct identifier ignored_any
+ }
+}
+
+struct KeyClassifier;
+
+enum KeyClass {
+ Map(String),
+ #[cfg(feature = "arbitrary_precision")]
+ Number,
+ #[cfg(feature = "raw_value")]
+ RawValue,
+}
+
+impl<'de> DeserializeSeed<'de> for KeyClassifier {
+ type Value = KeyClass;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ deserializer.deserialize_str(self)
+ }
+}
+
+impl<'de> Visitor<'de> for KeyClassifier {
+ type Value = KeyClass;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a string key")
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ match s {
+ #[cfg(feature = "arbitrary_precision")]
+ crate::number::TOKEN => Ok(KeyClass::Number),
+ #[cfg(feature = "raw_value")]
+ crate::raw::TOKEN => Ok(KeyClass::RawValue),
+ _ => Ok(KeyClass::Map(s.to_owned())),
+ }
+ }
+
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ fn visit_string<E>(self, s: String) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ match s.as_str() {
+ #[cfg(feature = "arbitrary_precision")]
+ crate::number::TOKEN => Ok(KeyClass::Number),
+ #[cfg(feature = "raw_value")]
+ crate::raw::TOKEN => Ok(KeyClass::RawValue),
+ _ => Ok(KeyClass::Map(s)),
+ }
+ }
+}
+
+impl Value {
+ #[cold]
+ fn invalid_type<E>(&self, exp: &dyn Expected) -> E
+ where
+ E: serde::de::Error,
+ {
+ serde::de::Error::invalid_type(self.unexpected(), exp)
+ }
+
+ #[cold]
+ fn unexpected(&self) -> Unexpected {
+ match self {
+ Value::Null => Unexpected::Unit,
+ Value::Bool(b) => Unexpected::Bool(*b),
+ Value::Number(n) => n.unexpected(),
+ Value::String(s) => Unexpected::Str(s),
+ Value::Array(_) => Unexpected::Seq,
+ Value::Object(_) => Unexpected::Map,
+ }
+ }
+}
+
+struct BorrowedCowStrDeserializer<'de> {
+ value: Cow<'de, str>,
+}
+
+impl<'de> BorrowedCowStrDeserializer<'de> {
+ fn new(value: Cow<'de, str>) -> Self {
+ BorrowedCowStrDeserializer { value }
+ }
+}
+
+impl<'de> de::Deserializer<'de> for BorrowedCowStrDeserializer<'de> {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.value {
+ Cow::Borrowed(string) => visitor.visit_borrowed_str(string),
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ Cow::Owned(string) => visitor.visit_string(string),
+ }
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ _name: &str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_enum(self)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct identifier ignored_any
+ }
+}
+
+impl<'de> de::EnumAccess<'de> for BorrowedCowStrDeserializer<'de> {
+ type Error = Error;
+ type Variant = UnitOnly;
+
+ fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ let value = seed.deserialize(self)?;
+ Ok((value, UnitOnly))
+ }
+}
+
+struct UnitOnly;
+
+impl<'de> de::VariantAccess<'de> for UnitOnly {
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<(), Error> {
+ Ok(())
+ }
+
+ fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"newtype variant",
+ ))
+ }
+
+ fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"tuple variant",
+ ))
+ }
+
+ fn struct_variant<V>(
+ self,
+ _fields: &'static [&'static str],
+ _visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"struct variant",
+ ))
+ }
+}
diff --git a/third_party/rust/serde_json/src/value/from.rs b/third_party/rust/serde_json/src/value/from.rs
new file mode 100644
index 0000000000..c5a6a3960b
--- /dev/null
+++ b/third_party/rust/serde_json/src/value/from.rs
@@ -0,0 +1,277 @@
+use super::Value;
+use crate::map::Map;
+use crate::number::Number;
+use alloc::borrow::Cow;
+use alloc::string::{String, ToString};
+use alloc::vec::Vec;
+use core::iter::FromIterator;
+
+macro_rules! from_integer {
+ ($($ty:ident)*) => {
+ $(
+ impl From<$ty> for Value {
+ fn from(n: $ty) -> Self {
+ Value::Number(n.into())
+ }
+ }
+ )*
+ };
+}
+
+from_integer! {
+ i8 i16 i32 i64 isize
+ u8 u16 u32 u64 usize
+}
+
+#[cfg(feature = "arbitrary_precision")]
+from_integer! {
+ i128 u128
+}
+
+impl From<f32> for Value {
+ /// Convert 32-bit floating point number to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let f: f32 = 13.37;
+ /// let x: Value = f.into();
+ /// ```
+ fn from(f: f32) -> Self {
+ From::from(f as f64)
+ }
+}
+
+impl From<f64> for Value {
+ /// Convert 64-bit floating point number to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let f: f64 = 13.37;
+ /// let x: Value = f.into();
+ /// ```
+ fn from(f: f64) -> Self {
+ Number::from_f64(f).map_or(Value::Null, Value::Number)
+ }
+}
+
+impl From<bool> for Value {
+ /// Convert boolean to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let b = false;
+ /// let x: Value = b.into();
+ /// ```
+ fn from(f: bool) -> Self {
+ Value::Bool(f)
+ }
+}
+
+impl From<String> for Value {
+ /// Convert `String` to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let s: String = "lorem".to_string();
+ /// let x: Value = s.into();
+ /// ```
+ fn from(f: String) -> Self {
+ Value::String(f)
+ }
+}
+
+impl<'a> From<&'a str> for Value {
+ /// Convert string slice to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let s: &str = "lorem";
+ /// let x: Value = s.into();
+ /// ```
+ fn from(f: &str) -> Self {
+ Value::String(f.to_string())
+ }
+}
+
+impl<'a> From<Cow<'a, str>> for Value {
+ /// Convert copy-on-write string to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ /// use std::borrow::Cow;
+ ///
+ /// let s: Cow<str> = Cow::Borrowed("lorem");
+ /// let x: Value = s.into();
+ /// ```
+ ///
+ /// ```
+ /// use serde_json::Value;
+ /// use std::borrow::Cow;
+ ///
+ /// let s: Cow<str> = Cow::Owned("lorem".to_string());
+ /// let x: Value = s.into();
+ /// ```
+ fn from(f: Cow<'a, str>) -> Self {
+ Value::String(f.into_owned())
+ }
+}
+
+impl From<Number> for Value {
+ /// Convert `Number` to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::{Number, Value};
+ ///
+ /// let n = Number::from(7);
+ /// let x: Value = n.into();
+ /// ```
+ fn from(f: Number) -> Self {
+ Value::Number(f)
+ }
+}
+
+impl From<Map<String, Value>> for Value {
+ /// Convert map (with string keys) to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::{Map, Value};
+ ///
+ /// let mut m = Map::new();
+ /// m.insert("Lorem".to_string(), "ipsum".into());
+ /// let x: Value = m.into();
+ /// ```
+ fn from(f: Map<String, Value>) -> Self {
+ Value::Object(f)
+ }
+}
+
+impl<T: Into<Value>> From<Vec<T>> for Value {
+ /// Convert a `Vec` to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let v = vec!["lorem", "ipsum", "dolor"];
+ /// let x: Value = v.into();
+ /// ```
+ fn from(f: Vec<T>) -> Self {
+ Value::Array(f.into_iter().map(Into::into).collect())
+ }
+}
+
+impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value {
+ /// Convert a slice to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let v: &[&str] = &["lorem", "ipsum", "dolor"];
+ /// let x: Value = v.into();
+ /// ```
+ fn from(f: &'a [T]) -> Self {
+ Value::Array(f.iter().cloned().map(Into::into).collect())
+ }
+}
+
+impl<T: Into<Value>> FromIterator<T> for Value {
+ /// Convert an iteratable type to a `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let v = std::iter::repeat(42).take(5);
+ /// let x: Value = v.collect();
+ /// ```
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"];
+ /// let x: Value = v.into_iter().collect();
+ /// ```
+ ///
+ /// ```
+ /// use std::iter::FromIterator;
+ /// use serde_json::Value;
+ ///
+ /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]);
+ /// ```
+ fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
+ Value::Array(iter.into_iter().map(Into::into).collect())
+ }
+}
+
+impl<K: Into<String>, V: Into<Value>> FromIterator<(K, V)> for Value {
+ /// Convert an iteratable type to a `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let v: Vec<_> = vec![("lorem", 40), ("ipsum", 2)];
+ /// let x: Value = v.into_iter().collect();
+ /// ```
+ fn from_iter<I: IntoIterator<Item = (K, V)>>(iter: I) -> Self {
+ Value::Object(
+ iter.into_iter()
+ .map(|(k, v)| (k.into(), v.into()))
+ .collect(),
+ )
+ }
+}
+
+impl From<()> for Value {
+ /// Convert `()` to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// let u = ();
+ /// let x: Value = u.into();
+ /// ```
+ fn from((): ()) -> Self {
+ Value::Null
+ }
+}
+
+impl<T> From<Option<T>> for Value
+where
+ T: Into<Value>,
+{
+ fn from(opt: Option<T>) -> Self {
+ match opt {
+ None => Value::Null,
+ Some(value) => Into::into(value),
+ }
+ }
+}
diff --git a/third_party/rust/serde_json/src/value/index.rs b/third_party/rust/serde_json/src/value/index.rs
new file mode 100644
index 0000000000..c74042b75a
--- /dev/null
+++ b/third_party/rust/serde_json/src/value/index.rs
@@ -0,0 +1,258 @@
+use super::Value;
+use crate::map::Map;
+use alloc::borrow::ToOwned;
+use alloc::string::String;
+use core::fmt::{self, Display};
+use core::ops;
+
+/// A type that can be used to index into a `serde_json::Value`.
+///
+/// The [`get`] and [`get_mut`] methods of `Value` accept any type that
+/// implements `Index`, as does the [square-bracket indexing operator]. This
+/// trait is implemented for strings which are used as the index into a JSON
+/// map, and for `usize` which is used as the index into a JSON array.
+///
+/// [`get`]: ../enum.Value.html#method.get
+/// [`get_mut`]: ../enum.Value.html#method.get_mut
+/// [square-bracket indexing operator]: ../enum.Value.html#impl-Index%3CI%3E
+///
+/// This trait is sealed and cannot be implemented for types outside of
+/// `serde_json`.
+///
+/// # Examples
+///
+/// ```
+/// # use serde_json::json;
+/// #
+/// let data = json!({ "inner": [1, 2, 3] });
+///
+/// // Data is a JSON map so it can be indexed with a string.
+/// let inner = &data["inner"];
+///
+/// // Inner is a JSON array so it can be indexed with an integer.
+/// let first = &inner[0];
+///
+/// assert_eq!(first, 1);
+/// ```
+pub trait Index: private::Sealed {
+ /// Return None if the key is not already in the array or object.
+ #[doc(hidden)]
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>;
+
+ /// Return None if the key is not already in the array or object.
+ #[doc(hidden)]
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>;
+
+ /// Panic if array index out of bounds. If key is not already in the object,
+ /// insert it with a value of null. Panic if Value is a type that cannot be
+ /// indexed into, except if Value is null then it can be treated as an empty
+ /// object.
+ #[doc(hidden)]
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value;
+}
+
+impl Index for usize {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ match v {
+ Value::Array(vec) => vec.get(*self),
+ _ => None,
+ }
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ match v {
+ Value::Array(vec) => vec.get_mut(*self),
+ _ => None,
+ }
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ match v {
+ Value::Array(vec) => {
+ let len = vec.len();
+ vec.get_mut(*self).unwrap_or_else(|| {
+ panic!(
+ "cannot access index {} of JSON array of length {}",
+ self, len
+ )
+ })
+ }
+ _ => panic!("cannot access index {} of JSON {}", self, Type(v)),
+ }
+ }
+}
+
+impl Index for str {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ match v {
+ Value::Object(map) => map.get(self),
+ _ => None,
+ }
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ match v {
+ Value::Object(map) => map.get_mut(self),
+ _ => None,
+ }
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ if let Value::Null = v {
+ *v = Value::Object(Map::new());
+ }
+ match v {
+ Value::Object(map) => map.entry(self.to_owned()).or_insert(Value::Null),
+ _ => panic!("cannot access key {:?} in JSON {}", self, Type(v)),
+ }
+ }
+}
+
+impl Index for String {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ self[..].index_into(v)
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ self[..].index_into_mut(v)
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ self[..].index_or_insert(v)
+ }
+}
+
+impl<'a, T> Index for &'a T
+where
+ T: ?Sized + Index,
+{
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ (**self).index_into(v)
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ (**self).index_into_mut(v)
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ (**self).index_or_insert(v)
+ }
+}
+
+// Prevent users from implementing the Index trait.
+mod private {
+ pub trait Sealed {}
+ impl Sealed for usize {}
+ impl Sealed for str {}
+ impl Sealed for alloc::string::String {}
+ impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {}
+}
+
+/// Used in panic messages.
+struct Type<'a>(&'a Value);
+
+impl<'a> Display for Type<'a> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match *self.0 {
+ Value::Null => formatter.write_str("null"),
+ Value::Bool(_) => formatter.write_str("boolean"),
+ Value::Number(_) => formatter.write_str("number"),
+ Value::String(_) => formatter.write_str("string"),
+ Value::Array(_) => formatter.write_str("array"),
+ Value::Object(_) => formatter.write_str("object"),
+ }
+ }
+}
+
+// The usual semantics of Index is to panic on invalid indexing.
+//
+// That said, the usual semantics are for things like Vec and BTreeMap which
+// have different use cases than Value. If you are working with a Vec, you know
+// that you are working with a Vec and you can get the len of the Vec and make
+// sure your indices are within bounds. The Value use cases are more
+// loosey-goosey. You got some JSON from an endpoint and you want to pull values
+// out of it. Outside of this Index impl, you already have the option of using
+// value.as_array() and working with the Vec directly, or matching on
+// Value::Array and getting the Vec directly. The Index impl means you can skip
+// that and index directly into the thing using a concise syntax. You don't have
+// to check the type, you don't have to check the len, it is all about what you
+// expect the Value to look like.
+//
+// Basically the use cases that would be well served by panicking here are
+// better served by using one of the other approaches: get and get_mut,
+// as_array, or match. The value of this impl is that it adds a way of working
+// with Value that is not well served by the existing approaches: concise and
+// careless and sometimes that is exactly what you want.
+impl<I> ops::Index<I> for Value
+where
+ I: Index,
+{
+ type Output = Value;
+
+ /// Index into a `serde_json::Value` using the syntax `value[0]` or
+ /// `value["k"]`.
+ ///
+ /// Returns `Value::Null` if the type of `self` does not match the type of
+ /// the index, for example if the index is a string and `self` is an array
+ /// or a number. Also returns `Value::Null` if the given key does not exist
+ /// in the map or the given index is not within the bounds of the array.
+ ///
+ /// For retrieving deeply nested values, you should have a look at the
+ /// `Value::pointer` method.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let data = json!({
+ /// "x": {
+ /// "y": ["z", "zz"]
+ /// }
+ /// });
+ ///
+ /// assert_eq!(data["x"]["y"], json!(["z", "zz"]));
+ /// assert_eq!(data["x"]["y"][0], json!("z"));
+ ///
+ /// assert_eq!(data["a"], json!(null)); // returns null for undefined values
+ /// assert_eq!(data["a"]["b"], json!(null)); // does not panic
+ /// ```
+ fn index(&self, index: I) -> &Value {
+ static NULL: Value = Value::Null;
+ index.index_into(self).unwrap_or(&NULL)
+ }
+}
+
+impl<I> ops::IndexMut<I> for Value
+where
+ I: Index,
+{
+ /// Write into a `serde_json::Value` using the syntax `value[0] = ...` or
+ /// `value["k"] = ...`.
+ ///
+ /// If the index is a number, the value must be an array of length bigger
+ /// than the index. Indexing into a value that is not an array or an array
+ /// that is too small will panic.
+ ///
+ /// If the index is a string, the value must be an object or null which is
+ /// treated like an empty object. If the key is not already present in the
+ /// object, it will be inserted with a value of null. Indexing into a value
+ /// that is neither an object nor null will panic.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let mut data = json!({ "x": 0 });
+ ///
+ /// // replace an existing key
+ /// data["x"] = json!(1);
+ ///
+ /// // insert a new key
+ /// data["y"] = json!([false, false, false]);
+ ///
+ /// // replace an array value
+ /// data["y"][0] = json!(true);
+ ///
+ /// // inserted a deeply nested key
+ /// data["a"]["b"]["c"]["d"] = json!(true);
+ ///
+ /// println!("{}", data);
+ /// ```
+ fn index_mut(&mut self, index: I) -> &mut Value {
+ index.index_or_insert(self)
+ }
+}
diff --git a/third_party/rust/serde_json/src/value/mod.rs b/third_party/rust/serde_json/src/value/mod.rs
new file mode 100644
index 0000000000..470b6b24da
--- /dev/null
+++ b/third_party/rust/serde_json/src/value/mod.rs
@@ -0,0 +1,987 @@
+//! The Value enum, a loosely typed way of representing any valid JSON value.
+//!
+//! # Constructing JSON
+//!
+//! Serde JSON provides a [`json!` macro][macro] to build `serde_json::Value`
+//! objects with very natural JSON syntax.
+//!
+//! ```
+//! use serde_json::json;
+//!
+//! fn main() {
+//! // The type of `john` is `serde_json::Value`
+//! let john = json!({
+//! "name": "John Doe",
+//! "age": 43,
+//! "phones": [
+//! "+44 1234567",
+//! "+44 2345678"
+//! ]
+//! });
+//!
+//! println!("first phone number: {}", john["phones"][0]);
+//!
+//! // Convert to a string of JSON and print it out
+//! println!("{}", john.to_string());
+//! }
+//! ```
+//!
+//! The `Value::to_string()` function converts a `serde_json::Value` into a
+//! `String` of JSON text.
+//!
+//! One neat thing about the `json!` macro is that variables and expressions can
+//! be interpolated directly into the JSON value as you are building it. Serde
+//! will check at compile time that the value you are interpolating is able to
+//! be represented as JSON.
+//!
+//! ```
+//! # use serde_json::json;
+//! #
+//! # fn random_phone() -> u16 { 0 }
+//! #
+//! let full_name = "John Doe";
+//! let age_last_year = 42;
+//!
+//! // The type of `john` is `serde_json::Value`
+//! let john = json!({
+//! "name": full_name,
+//! "age": age_last_year + 1,
+//! "phones": [
+//! format!("+44 {}", random_phone())
+//! ]
+//! });
+//! ```
+//!
+//! A string of JSON data can be parsed into a `serde_json::Value` by the
+//! [`serde_json::from_str`][from_str] function. There is also
+//! [`from_slice`][from_slice] for parsing from a byte slice `&[u8]` and
+//! [`from_reader`][from_reader] for parsing from any `io::Read` like a File or
+//! a TCP stream.
+//!
+//! ```
+//! use serde_json::{json, Value, Error};
+//!
+//! fn untyped_example() -> Result<(), Error> {
+//! // Some JSON input data as a &str. Maybe this comes from the user.
+//! let data = r#"
+//! {
+//! "name": "John Doe",
+//! "age": 43,
+//! "phones": [
+//! "+44 1234567",
+//! "+44 2345678"
+//! ]
+//! }"#;
+//!
+//! // Parse the string of data into serde_json::Value.
+//! let v: Value = serde_json::from_str(data)?;
+//!
+//! // Access parts of the data by indexing with square brackets.
+//! println!("Please call {} at the number {}", v["name"], v["phones"][0]);
+//!
+//! Ok(())
+//! }
+//! #
+//! # untyped_example().unwrap();
+//! ```
+//!
+//! [macro]: crate::json
+//! [from_str]: crate::de::from_str
+//! [from_slice]: crate::de::from_slice
+//! [from_reader]: crate::de::from_reader
+
+use crate::error::Error;
+use crate::io;
+use alloc::string::String;
+use alloc::vec::Vec;
+use core::fmt::{self, Debug, Display};
+use core::mem;
+use core::str;
+use serde::de::DeserializeOwned;
+use serde::ser::Serialize;
+
+pub use self::index::Index;
+pub use self::ser::Serializer;
+pub use crate::map::Map;
+pub use crate::number::Number;
+
+#[cfg(feature = "raw_value")]
+pub use crate::raw::{to_raw_value, RawValue};
+
+/// Represents any valid JSON value.
+///
+/// See the [`serde_json::value` module documentation](self) for usage examples.
+#[derive(Clone, Eq, PartialEq)]
+pub enum Value {
+ /// Represents a JSON null value.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!(null);
+ /// ```
+ Null,
+
+ /// Represents a JSON boolean.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!(true);
+ /// ```
+ Bool(bool),
+
+ /// Represents a JSON number, whether integer or floating point.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!(12.5);
+ /// ```
+ Number(Number),
+
+ /// Represents a JSON string.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!("a string");
+ /// ```
+ String(String),
+
+ /// Represents a JSON array.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!(["an", "array"]);
+ /// ```
+ Array(Vec<Value>),
+
+ /// Represents a JSON object.
+ ///
+ /// By default the map is backed by a BTreeMap. Enable the `preserve_order`
+ /// feature of serde_json to use IndexMap instead, which preserves
+ /// entries in the order they are inserted into the map. In particular, this
+ /// allows JSON data to be deserialized into a Value and serialized to a
+ /// string while retaining the order of map keys in the input.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "an": "object" });
+ /// ```
+ Object(Map<String, Value>),
+}
+
+impl Debug for Value {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ Value::Null => formatter.write_str("Null"),
+ Value::Bool(boolean) => write!(formatter, "Bool({})", boolean),
+ Value::Number(number) => Debug::fmt(number, formatter),
+ Value::String(string) => write!(formatter, "String({:?})", string),
+ Value::Array(vec) => {
+ formatter.write_str("Array ")?;
+ Debug::fmt(vec, formatter)
+ }
+ Value::Object(map) => {
+ formatter.write_str("Object ")?;
+ Debug::fmt(map, formatter)
+ }
+ }
+ }
+}
+
+impl Display for Value {
+ /// Display a JSON value as a string.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let json = json!({ "city": "London", "street": "10 Downing Street" });
+ ///
+ /// // Compact format:
+ /// //
+ /// // {"city":"London","street":"10 Downing Street"}
+ /// let compact = format!("{}", json);
+ /// assert_eq!(compact,
+ /// "{\"city\":\"London\",\"street\":\"10 Downing Street\"}");
+ ///
+ /// // Pretty format:
+ /// //
+ /// // {
+ /// // "city": "London",
+ /// // "street": "10 Downing Street"
+ /// // }
+ /// let pretty = format!("{:#}", json);
+ /// assert_eq!(pretty,
+ /// "{\n \"city\": \"London\",\n \"street\": \"10 Downing Street\"\n}");
+ /// ```
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ struct WriterFormatter<'a, 'b: 'a> {
+ inner: &'a mut fmt::Formatter<'b>,
+ }
+
+ impl<'a, 'b> io::Write for WriterFormatter<'a, 'b> {
+ fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
+ // Safety: the serializer below only emits valid utf8 when using
+ // the default formatter.
+ let s = unsafe { str::from_utf8_unchecked(buf) };
+ tri!(self.inner.write_str(s).map_err(io_error));
+ Ok(buf.len())
+ }
+
+ fn flush(&mut self) -> io::Result<()> {
+ Ok(())
+ }
+ }
+
+ fn io_error(_: fmt::Error) -> io::Error {
+ // Error value does not matter because Display impl just maps it
+ // back to fmt::Error.
+ io::Error::new(io::ErrorKind::Other, "fmt error")
+ }
+
+ let alternate = f.alternate();
+ let mut wr = WriterFormatter { inner: f };
+ if alternate {
+ // {:#}
+ super::ser::to_writer_pretty(&mut wr, self).map_err(|_| fmt::Error)
+ } else {
+ // {}
+ super::ser::to_writer(&mut wr, self).map_err(|_| fmt::Error)
+ }
+ }
+}
+
+fn parse_index(s: &str) -> Option<usize> {
+ if s.starts_with('+') || (s.starts_with('0') && s.len() != 1) {
+ return None;
+ }
+ s.parse().ok()
+}
+
+impl Value {
+ /// Index into a JSON array or map. A string index can be used to access a
+ /// value in a map, and a usize index can be used to access an element of an
+ /// array.
+ ///
+ /// Returns `None` if the type of `self` does not match the type of the
+ /// index, for example if the index is a string and `self` is an array or a
+ /// number. Also returns `None` if the given key does not exist in the map
+ /// or the given index is not within the bounds of the array.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let object = json!({ "A": 65, "B": 66, "C": 67 });
+ /// assert_eq!(*object.get("A").unwrap(), json!(65));
+ ///
+ /// let array = json!([ "A", "B", "C" ]);
+ /// assert_eq!(*array.get(2).unwrap(), json!("C"));
+ ///
+ /// assert_eq!(array.get("A"), None);
+ /// ```
+ ///
+ /// Square brackets can also be used to index into a value in a more concise
+ /// way. This returns `Value::Null` in cases where `get` would have returned
+ /// `None`.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let object = json!({
+ /// "A": ["a", "á", "à"],
+ /// "B": ["b", "bÌ"],
+ /// "C": ["c", "ć", "ć̣", "ḉ"],
+ /// });
+ /// assert_eq!(object["B"][0], json!("b"));
+ ///
+ /// assert_eq!(object["D"], json!(null));
+ /// assert_eq!(object[0]["x"]["y"]["z"], json!(null));
+ /// ```
+ pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
+ index.index_into(self)
+ }
+
+ /// Mutably index into a JSON array or map. A string index can be used to
+ /// access a value in a map, and a usize index can be used to access an
+ /// element of an array.
+ ///
+ /// Returns `None` if the type of `self` does not match the type of the
+ /// index, for example if the index is a string and `self` is an array or a
+ /// number. Also returns `None` if the given key does not exist in the map
+ /// or the given index is not within the bounds of the array.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let mut object = json!({ "A": 65, "B": 66, "C": 67 });
+ /// *object.get_mut("A").unwrap() = json!(69);
+ ///
+ /// let mut array = json!([ "A", "B", "C" ]);
+ /// *array.get_mut(2).unwrap() = json!("D");
+ /// ```
+ pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
+ index.index_into_mut(self)
+ }
+
+ /// Returns true if the `Value` is an Object. Returns false otherwise.
+ ///
+ /// For any Value on which `is_object` returns true, `as_object` and
+ /// `as_object_mut` are guaranteed to return the map representation of the
+ /// object.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let obj = json!({ "a": { "nested": true }, "b": ["an", "array"] });
+ ///
+ /// assert!(obj.is_object());
+ /// assert!(obj["a"].is_object());
+ ///
+ /// // array, not an object
+ /// assert!(!obj["b"].is_object());
+ /// ```
+ pub fn is_object(&self) -> bool {
+ self.as_object().is_some()
+ }
+
+ /// If the `Value` is an Object, returns the associated Map. Returns None
+ /// otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": { "nested": true }, "b": ["an", "array"] });
+ ///
+ /// // The length of `{"nested": true}` is 1 entry.
+ /// assert_eq!(v["a"].as_object().unwrap().len(), 1);
+ ///
+ /// // The array `["an", "array"]` is not an object.
+ /// assert_eq!(v["b"].as_object(), None);
+ /// ```
+ pub fn as_object(&self) -> Option<&Map<String, Value>> {
+ match self {
+ Value::Object(map) => Some(map),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is an Object, returns the associated mutable Map.
+ /// Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let mut v = json!({ "a": { "nested": true } });
+ ///
+ /// v["a"].as_object_mut().unwrap().clear();
+ /// assert_eq!(v, json!({ "a": {} }));
+ /// ```
+ pub fn as_object_mut(&mut self) -> Option<&mut Map<String, Value>> {
+ match self {
+ Value::Object(map) => Some(map),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is an Array. Returns false otherwise.
+ ///
+ /// For any Value on which `is_array` returns true, `as_array` and
+ /// `as_array_mut` are guaranteed to return the vector representing the
+ /// array.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let obj = json!({ "a": ["an", "array"], "b": { "an": "object" } });
+ ///
+ /// assert!(obj["a"].is_array());
+ ///
+ /// // an object, not an array
+ /// assert!(!obj["b"].is_array());
+ /// ```
+ pub fn is_array(&self) -> bool {
+ self.as_array().is_some()
+ }
+
+ /// If the `Value` is an Array, returns the associated vector. Returns None
+ /// otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": ["an", "array"], "b": { "an": "object" } });
+ ///
+ /// // The length of `["an", "array"]` is 2 elements.
+ /// assert_eq!(v["a"].as_array().unwrap().len(), 2);
+ ///
+ /// // The object `{"an": "object"}` is not an array.
+ /// assert_eq!(v["b"].as_array(), None);
+ /// ```
+ pub fn as_array(&self) -> Option<&Vec<Value>> {
+ match self {
+ Value::Array(array) => Some(array),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is an Array, returns the associated mutable vector.
+ /// Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let mut v = json!({ "a": ["an", "array"] });
+ ///
+ /// v["a"].as_array_mut().unwrap().clear();
+ /// assert_eq!(v, json!({ "a": [] }));
+ /// ```
+ pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
+ match self {
+ Value::Array(list) => Some(list),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a String. Returns false otherwise.
+ ///
+ /// For any Value on which `is_string` returns true, `as_str` is guaranteed
+ /// to return the string slice.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": "some string", "b": false });
+ ///
+ /// assert!(v["a"].is_string());
+ ///
+ /// // The boolean `false` is not a string.
+ /// assert!(!v["b"].is_string());
+ /// ```
+ pub fn is_string(&self) -> bool {
+ self.as_str().is_some()
+ }
+
+ /// If the `Value` is a String, returns the associated str. Returns None
+ /// otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": "some string", "b": false });
+ ///
+ /// assert_eq!(v["a"].as_str(), Some("some string"));
+ ///
+ /// // The boolean `false` is not a string.
+ /// assert_eq!(v["b"].as_str(), None);
+ ///
+ /// // JSON values are printed in JSON representation, so strings are in quotes.
+ /// //
+ /// // The value is: "some string"
+ /// println!("The value is: {}", v["a"]);
+ ///
+ /// // Rust strings are printed without quotes.
+ /// //
+ /// // The value is: some string
+ /// println!("The value is: {}", v["a"].as_str().unwrap());
+ /// ```
+ pub fn as_str(&self) -> Option<&str> {
+ match self {
+ Value::String(s) => Some(s),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a Number. Returns false otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": 1, "b": "2" });
+ ///
+ /// assert!(v["a"].is_number());
+ ///
+ /// // The string `"2"` is a string, not a number.
+ /// assert!(!v["b"].is_number());
+ /// ```
+ pub fn is_number(&self) -> bool {
+ match *self {
+ Value::Number(_) => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if the `Value` is an integer between `i64::MIN` and
+ /// `i64::MAX`.
+ ///
+ /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to
+ /// return the integer value.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let big = i64::max_value() as u64 + 10;
+ /// let v = json!({ "a": 64, "b": big, "c": 256.0 });
+ ///
+ /// assert!(v["a"].is_i64());
+ ///
+ /// // Greater than i64::MAX.
+ /// assert!(!v["b"].is_i64());
+ ///
+ /// // Numbers with a decimal point are not considered integers.
+ /// assert!(!v["c"].is_i64());
+ /// ```
+ pub fn is_i64(&self) -> bool {
+ match self {
+ Value::Number(n) => n.is_i64(),
+ _ => false,
+ }
+ }
+
+ /// Returns true if the `Value` is an integer between zero and `u64::MAX`.
+ ///
+ /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to
+ /// return the integer value.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
+ ///
+ /// assert!(v["a"].is_u64());
+ ///
+ /// // Negative integer.
+ /// assert!(!v["b"].is_u64());
+ ///
+ /// // Numbers with a decimal point are not considered integers.
+ /// assert!(!v["c"].is_u64());
+ /// ```
+ pub fn is_u64(&self) -> bool {
+ match self {
+ Value::Number(n) => n.is_u64(),
+ _ => false,
+ }
+ }
+
+ /// Returns true if the `Value` is a number that can be represented by f64.
+ ///
+ /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to
+ /// return the floating point value.
+ ///
+ /// Currently this function returns true if and only if both `is_i64` and
+ /// `is_u64` return false but this is not a guarantee in the future.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
+ ///
+ /// assert!(v["a"].is_f64());
+ ///
+ /// // Integers.
+ /// assert!(!v["b"].is_f64());
+ /// assert!(!v["c"].is_f64());
+ /// ```
+ pub fn is_f64(&self) -> bool {
+ match self {
+ Value::Number(n) => n.is_f64(),
+ _ => false,
+ }
+ }
+
+ /// If the `Value` is an integer, represent it as i64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let big = i64::max_value() as u64 + 10;
+ /// let v = json!({ "a": 64, "b": big, "c": 256.0 });
+ ///
+ /// assert_eq!(v["a"].as_i64(), Some(64));
+ /// assert_eq!(v["b"].as_i64(), None);
+ /// assert_eq!(v["c"].as_i64(), None);
+ /// ```
+ pub fn as_i64(&self) -> Option<i64> {
+ match self {
+ Value::Number(n) => n.as_i64(),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is an integer, represent it as u64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": 64, "b": -64, "c": 256.0 });
+ ///
+ /// assert_eq!(v["a"].as_u64(), Some(64));
+ /// assert_eq!(v["b"].as_u64(), None);
+ /// assert_eq!(v["c"].as_u64(), None);
+ /// ```
+ pub fn as_u64(&self) -> Option<u64> {
+ match self {
+ Value::Number(n) => n.as_u64(),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a number, represent it as f64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": 256.0, "b": 64, "c": -64 });
+ ///
+ /// assert_eq!(v["a"].as_f64(), Some(256.0));
+ /// assert_eq!(v["b"].as_f64(), Some(64.0));
+ /// assert_eq!(v["c"].as_f64(), Some(-64.0));
+ /// ```
+ pub fn as_f64(&self) -> Option<f64> {
+ match self {
+ Value::Number(n) => n.as_f64(),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a Boolean. Returns false otherwise.
+ ///
+ /// For any Value on which `is_boolean` returns true, `as_bool` is
+ /// guaranteed to return the boolean value.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": false, "b": "false" });
+ ///
+ /// assert!(v["a"].is_boolean());
+ ///
+ /// // The string `"false"` is a string, not a boolean.
+ /// assert!(!v["b"].is_boolean());
+ /// ```
+ pub fn is_boolean(&self) -> bool {
+ self.as_bool().is_some()
+ }
+
+ /// If the `Value` is a Boolean, returns the associated bool. Returns None
+ /// otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": false, "b": "false" });
+ ///
+ /// assert_eq!(v["a"].as_bool(), Some(false));
+ ///
+ /// // The string `"false"` is a string, not a boolean.
+ /// assert_eq!(v["b"].as_bool(), None);
+ /// ```
+ pub fn as_bool(&self) -> Option<bool> {
+ match *self {
+ Value::Bool(b) => Some(b),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a Null. Returns false otherwise.
+ ///
+ /// For any Value on which `is_null` returns true, `as_null` is guaranteed
+ /// to return `Some(())`.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": null, "b": false });
+ ///
+ /// assert!(v["a"].is_null());
+ ///
+ /// // The boolean `false` is not null.
+ /// assert!(!v["b"].is_null());
+ /// ```
+ pub fn is_null(&self) -> bool {
+ self.as_null().is_some()
+ }
+
+ /// If the `Value` is a Null, returns (). Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let v = json!({ "a": null, "b": false });
+ ///
+ /// assert_eq!(v["a"].as_null(), Some(()));
+ ///
+ /// // The boolean `false` is not null.
+ /// assert_eq!(v["b"].as_null(), None);
+ /// ```
+ pub fn as_null(&self) -> Option<()> {
+ match *self {
+ Value::Null => Some(()),
+ _ => None,
+ }
+ }
+
+ /// Looks up a value by a JSON Pointer.
+ ///
+ /// JSON Pointer defines a string syntax for identifying a specific value
+ /// within a JavaScript Object Notation (JSON) document.
+ ///
+ /// A Pointer is a Unicode string with the reference tokens separated by `/`.
+ /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The
+ /// addressed value is returned and if there is no such value `None` is
+ /// returned.
+ ///
+ /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901).
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let data = json!({
+ /// "x": {
+ /// "y": ["z", "zz"]
+ /// }
+ /// });
+ ///
+ /// assert_eq!(data.pointer("/x/y/1").unwrap(), &json!("zz"));
+ /// assert_eq!(data.pointer("/a/b/c"), None);
+ /// ```
+ pub fn pointer(&self, pointer: &str) -> Option<&Value> {
+ if pointer.is_empty() {
+ return Some(self);
+ }
+ if !pointer.starts_with('/') {
+ return None;
+ }
+ pointer
+ .split('/')
+ .skip(1)
+ .map(|x| x.replace("~1", "/").replace("~0", "~"))
+ .try_fold(self, |target, token| match target {
+ Value::Object(map) => map.get(&token),
+ Value::Array(list) => parse_index(&token).and_then(|x| list.get(x)),
+ _ => None,
+ })
+ }
+
+ /// Looks up a value by a JSON Pointer and returns a mutable reference to
+ /// that value.
+ ///
+ /// JSON Pointer defines a string syntax for identifying a specific value
+ /// within a JavaScript Object Notation (JSON) document.
+ ///
+ /// A Pointer is a Unicode string with the reference tokens separated by `/`.
+ /// Inside tokens `/` is replaced by `~1` and `~` is replaced by `~0`. The
+ /// addressed value is returned and if there is no such value `None` is
+ /// returned.
+ ///
+ /// For more information read [RFC6901](https://tools.ietf.org/html/rfc6901).
+ ///
+ /// # Example of Use
+ ///
+ /// ```
+ /// use serde_json::Value;
+ ///
+ /// fn main() {
+ /// let s = r#"{"x": 1.0, "y": 2.0}"#;
+ /// let mut value: Value = serde_json::from_str(s).unwrap();
+ ///
+ /// // Check value using read-only pointer
+ /// assert_eq!(value.pointer("/x"), Some(&1.0.into()));
+ /// // Change value with direct assignment
+ /// *value.pointer_mut("/x").unwrap() = 1.5.into();
+ /// // Check that new value was written
+ /// assert_eq!(value.pointer("/x"), Some(&1.5.into()));
+ /// // Or change the value only if it exists
+ /// value.pointer_mut("/x").map(|v| *v = 1.5.into());
+ ///
+ /// // "Steal" ownership of a value. Can replace with any valid Value.
+ /// let old_x = value.pointer_mut("/x").map(Value::take).unwrap();
+ /// assert_eq!(old_x, 1.5);
+ /// assert_eq!(value.pointer("/x").unwrap(), &Value::Null);
+ /// }
+ /// ```
+ pub fn pointer_mut(&mut self, pointer: &str) -> Option<&mut Value> {
+ if pointer.is_empty() {
+ return Some(self);
+ }
+ if !pointer.starts_with('/') {
+ return None;
+ }
+ pointer
+ .split('/')
+ .skip(1)
+ .map(|x| x.replace("~1", "/").replace("~0", "~"))
+ .try_fold(self, |target, token| match target {
+ Value::Object(map) => map.get_mut(&token),
+ Value::Array(list) => parse_index(&token).and_then(move |x| list.get_mut(x)),
+ _ => None,
+ })
+ }
+
+ /// Takes the value out of the `Value`, leaving a `Null` in its place.
+ ///
+ /// ```
+ /// # use serde_json::json;
+ /// #
+ /// let mut v = json!({ "x": "y" });
+ /// assert_eq!(v["x"].take(), json!("y"));
+ /// assert_eq!(v, json!({ "x": null }));
+ /// ```
+ pub fn take(&mut self) -> Value {
+ mem::replace(self, Value::Null)
+ }
+}
+
+/// The default value is `Value::Null`.
+///
+/// This is useful for handling omitted `Value` fields when deserializing.
+///
+/// # Examples
+///
+/// ```
+/// # use serde::Deserialize;
+/// use serde_json::Value;
+///
+/// #[derive(Deserialize)]
+/// struct Settings {
+/// level: i32,
+/// #[serde(default)]
+/// extras: Value,
+/// }
+///
+/// # fn try_main() -> Result<(), serde_json::Error> {
+/// let data = r#" { "level": 42 } "#;
+/// let s: Settings = serde_json::from_str(data)?;
+///
+/// assert_eq!(s.level, 42);
+/// assert_eq!(s.extras, Value::Null);
+/// #
+/// # Ok(())
+/// # }
+/// #
+/// # try_main().unwrap()
+/// ```
+impl Default for Value {
+ fn default() -> Value {
+ Value::Null
+ }
+}
+
+mod de;
+mod from;
+mod index;
+mod partial_eq;
+mod ser;
+
+/// Convert a `T` into `serde_json::Value` which is an enum that can represent
+/// any valid JSON data.
+///
+/// # Example
+///
+/// ```
+/// use serde::Serialize;
+/// use serde_json::json;
+///
+/// use std::error::Error;
+///
+/// #[derive(Serialize)]
+/// struct User {
+/// fingerprint: String,
+/// location: String,
+/// }
+///
+/// fn compare_json_values() -> Result<(), Box<Error>> {
+/// let u = User {
+/// fingerprint: "0xF9BA143B95FF6D82".to_owned(),
+/// location: "Menlo Park, CA".to_owned(),
+/// };
+///
+/// // The type of `expected` is `serde_json::Value`
+/// let expected = json!({
+/// "fingerprint": "0xF9BA143B95FF6D82",
+/// "location": "Menlo Park, CA",
+/// });
+///
+/// let v = serde_json::to_value(u).unwrap();
+/// assert_eq!(v, expected);
+///
+/// Ok(())
+/// }
+/// #
+/// # compare_json_values().unwrap();
+/// ```
+///
+/// # Errors
+///
+/// This conversion can fail if `T`'s implementation of `Serialize` decides to
+/// fail, or if `T` contains a map with non-string keys.
+///
+/// ```
+/// use std::collections::BTreeMap;
+///
+/// fn main() {
+/// // The keys in this map are vectors, not strings.
+/// let mut map = BTreeMap::new();
+/// map.insert(vec![32, 64], "x86");
+///
+/// println!("{}", serde_json::to_value(map).unwrap_err());
+/// }
+/// ```
+// Taking by value is more friendly to iterator adapters, option and result
+// consumers, etc. See https://github.com/serde-rs/json/pull/149.
+pub fn to_value<T>(value: T) -> Result<Value, Error>
+where
+ T: Serialize,
+{
+ value.serialize(Serializer)
+}
+
+/// Interpret a `serde_json::Value` as an instance of type `T`.
+///
+/// # Example
+///
+/// ```
+/// use serde::Deserialize;
+/// use serde_json::json;
+///
+/// #[derive(Deserialize, Debug)]
+/// struct User {
+/// fingerprint: String,
+/// location: String,
+/// }
+///
+/// fn main() {
+/// // The type of `j` is `serde_json::Value`
+/// let j = json!({
+/// "fingerprint": "0xF9BA143B95FF6D82",
+/// "location": "Menlo Park, CA"
+/// });
+///
+/// let u: User = serde_json::from_value(j).unwrap();
+/// println!("{:#?}", u);
+/// }
+/// ```
+///
+/// # Errors
+///
+/// This conversion can fail if the structure of the Value does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the Value
+/// contains something other than a JSON map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the JSON map or some number is too big to fit in the expected primitive
+/// type.
+pub fn from_value<T>(value: Value) -> Result<T, Error>
+where
+ T: DeserializeOwned,
+{
+ T::deserialize(value)
+}
diff --git a/third_party/rust/serde_json/src/value/partial_eq.rs b/third_party/rust/serde_json/src/value/partial_eq.rs
new file mode 100644
index 0000000000..b4ef84c4f3
--- /dev/null
+++ b/third_party/rust/serde_json/src/value/partial_eq.rs
@@ -0,0 +1,95 @@
+use super::Value;
+use alloc::string::String;
+
+fn eq_i64(value: &Value, other: i64) -> bool {
+ value.as_i64().map_or(false, |i| i == other)
+}
+
+fn eq_u64(value: &Value, other: u64) -> bool {
+ value.as_u64().map_or(false, |i| i == other)
+}
+
+fn eq_f64(value: &Value, other: f64) -> bool {
+ value.as_f64().map_or(false, |i| i == other)
+}
+
+fn eq_bool(value: &Value, other: bool) -> bool {
+ value.as_bool().map_or(false, |i| i == other)
+}
+
+fn eq_str(value: &Value, other: &str) -> bool {
+ value.as_str().map_or(false, |i| i == other)
+}
+
+impl PartialEq<str> for Value {
+ fn eq(&self, other: &str) -> bool {
+ eq_str(self, other)
+ }
+}
+
+impl<'a> PartialEq<&'a str> for Value {
+ fn eq(&self, other: &&str) -> bool {
+ eq_str(self, *other)
+ }
+}
+
+impl PartialEq<Value> for str {
+ fn eq(&self, other: &Value) -> bool {
+ eq_str(other, self)
+ }
+}
+
+impl<'a> PartialEq<Value> for &'a str {
+ fn eq(&self, other: &Value) -> bool {
+ eq_str(other, *self)
+ }
+}
+
+impl PartialEq<String> for Value {
+ fn eq(&self, other: &String) -> bool {
+ eq_str(self, other.as_str())
+ }
+}
+
+impl PartialEq<Value> for String {
+ fn eq(&self, other: &Value) -> bool {
+ eq_str(other, self.as_str())
+ }
+}
+
+macro_rules! partialeq_numeric {
+ ($($eq:ident [$($ty:ty)*])*) => {
+ $($(
+ impl PartialEq<$ty> for Value {
+ fn eq(&self, other: &$ty) -> bool {
+ $eq(self, *other as _)
+ }
+ }
+
+ impl PartialEq<Value> for $ty {
+ fn eq(&self, other: &Value) -> bool {
+ $eq(other, *self as _)
+ }
+ }
+
+ impl<'a> PartialEq<$ty> for &'a Value {
+ fn eq(&self, other: &$ty) -> bool {
+ $eq(*self, *other as _)
+ }
+ }
+
+ impl<'a> PartialEq<$ty> for &'a mut Value {
+ fn eq(&self, other: &$ty) -> bool {
+ $eq(*self, *other as _)
+ }
+ }
+ )*)*
+ }
+}
+
+partialeq_numeric! {
+ eq_i64[i8 i16 i32 i64 isize]
+ eq_u64[u8 u16 u32 u64 usize]
+ eq_f64[f32 f64]
+ eq_bool[bool]
+}
diff --git a/third_party/rust/serde_json/src/value/ser.rs b/third_party/rust/serde_json/src/value/ser.rs
new file mode 100644
index 0000000000..a29814e92a
--- /dev/null
+++ b/third_party/rust/serde_json/src/value/ser.rs
@@ -0,0 +1,1044 @@
+use crate::error::{Error, ErrorCode, Result};
+use crate::map::Map;
+use crate::number::Number;
+use crate::value::{to_value, Value};
+use alloc::borrow::ToOwned;
+use alloc::string::{String, ToString};
+use alloc::vec::Vec;
+#[cfg(not(feature = "arbitrary_precision"))]
+use core::convert::TryFrom;
+use core::fmt::Display;
+use core::result;
+use serde::ser::{Impossible, Serialize};
+
+impl Serialize for Value {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> result::Result<S::Ok, S::Error>
+ where
+ S: ::serde::Serializer,
+ {
+ match self {
+ Value::Null => serializer.serialize_unit(),
+ Value::Bool(b) => serializer.serialize_bool(*b),
+ Value::Number(n) => n.serialize(serializer),
+ Value::String(s) => serializer.serialize_str(s),
+ Value::Array(v) => v.serialize(serializer),
+ #[cfg(any(feature = "std", feature = "alloc"))]
+ Value::Object(m) => {
+ use serde::ser::SerializeMap;
+ let mut map = tri!(serializer.serialize_map(Some(m.len())));
+ for (k, v) in m {
+ tri!(map.serialize_entry(k, v));
+ }
+ map.end()
+ }
+ }
+ }
+}
+
+/// Serializer whose output is a `Value`.
+///
+/// This is the serializer that backs [`serde_json::to_value`][crate::to_value].
+/// Unlike the main serde_json serializer which goes from some serializable
+/// value of type `T` to JSON text, this one goes from `T` to
+/// `serde_json::Value`.
+///
+/// The `to_value` function is implementable as:
+///
+/// ```
+/// use serde::Serialize;
+/// use serde_json::{Error, Value};
+///
+/// pub fn to_value<T>(input: T) -> Result<Value, Error>
+/// where
+/// T: Serialize,
+/// {
+/// input.serialize(serde_json::value::Serializer)
+/// }
+/// ```
+pub struct Serializer;
+
+impl serde::Serializer for Serializer {
+ type Ok = Value;
+ type Error = Error;
+
+ type SerializeSeq = SerializeVec;
+ type SerializeTuple = SerializeVec;
+ type SerializeTupleStruct = SerializeVec;
+ type SerializeTupleVariant = SerializeTupleVariant;
+ type SerializeMap = SerializeMap;
+ type SerializeStruct = SerializeMap;
+ type SerializeStructVariant = SerializeStructVariant;
+
+ #[inline]
+ fn serialize_bool(self, value: bool) -> Result<Value> {
+ Ok(Value::Bool(value))
+ }
+
+ #[inline]
+ fn serialize_i8(self, value: i8) -> Result<Value> {
+ self.serialize_i64(value as i64)
+ }
+
+ #[inline]
+ fn serialize_i16(self, value: i16) -> Result<Value> {
+ self.serialize_i64(value as i64)
+ }
+
+ #[inline]
+ fn serialize_i32(self, value: i32) -> Result<Value> {
+ self.serialize_i64(value as i64)
+ }
+
+ fn serialize_i64(self, value: i64) -> Result<Value> {
+ Ok(Value::Number(value.into()))
+ }
+
+ fn serialize_i128(self, value: i128) -> Result<Value> {
+ #[cfg(feature = "arbitrary_precision")]
+ {
+ Ok(Value::Number(value.into()))
+ }
+
+ #[cfg(not(feature = "arbitrary_precision"))]
+ {
+ if let Ok(value) = u64::try_from(value) {
+ Ok(Value::Number(value.into()))
+ } else if let Ok(value) = i64::try_from(value) {
+ Ok(Value::Number(value.into()))
+ } else {
+ Err(Error::syntax(ErrorCode::NumberOutOfRange, 0, 0))
+ }
+ }
+ }
+
+ #[inline]
+ fn serialize_u8(self, value: u8) -> Result<Value> {
+ self.serialize_u64(value as u64)
+ }
+
+ #[inline]
+ fn serialize_u16(self, value: u16) -> Result<Value> {
+ self.serialize_u64(value as u64)
+ }
+
+ #[inline]
+ fn serialize_u32(self, value: u32) -> Result<Value> {
+ self.serialize_u64(value as u64)
+ }
+
+ #[inline]
+ fn serialize_u64(self, value: u64) -> Result<Value> {
+ Ok(Value::Number(value.into()))
+ }
+
+ fn serialize_u128(self, value: u128) -> Result<Value> {
+ #[cfg(feature = "arbitrary_precision")]
+ {
+ Ok(Value::Number(value.into()))
+ }
+
+ #[cfg(not(feature = "arbitrary_precision"))]
+ {
+ if let Ok(value) = u64::try_from(value) {
+ Ok(Value::Number(value.into()))
+ } else {
+ Err(Error::syntax(ErrorCode::NumberOutOfRange, 0, 0))
+ }
+ }
+ }
+
+ #[inline]
+ fn serialize_f32(self, value: f32) -> Result<Value> {
+ self.serialize_f64(value as f64)
+ }
+
+ #[inline]
+ fn serialize_f64(self, value: f64) -> Result<Value> {
+ Ok(Number::from_f64(value).map_or(Value::Null, Value::Number))
+ }
+
+ #[inline]
+ fn serialize_char(self, value: char) -> Result<Value> {
+ let mut s = String::new();
+ s.push(value);
+ Ok(Value::String(s))
+ }
+
+ #[inline]
+ fn serialize_str(self, value: &str) -> Result<Value> {
+ Ok(Value::String(value.to_owned()))
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<Value> {
+ let vec = value.iter().map(|&b| Value::Number(b.into())).collect();
+ Ok(Value::Array(vec))
+ }
+
+ #[inline]
+ fn serialize_unit(self) -> Result<Value> {
+ Ok(Value::Null)
+ }
+
+ #[inline]
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Value> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Value> {
+ self.serialize_str(variant)
+ }
+
+ #[inline]
+ fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Value>
+ where
+ T: ?Sized + Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Value>
+ where
+ T: ?Sized + Serialize,
+ {
+ let mut values = Map::new();
+ values.insert(String::from(variant), tri!(to_value(value)));
+ Ok(Value::Object(values))
+ }
+
+ #[inline]
+ fn serialize_none(self) -> Result<Value> {
+ self.serialize_unit()
+ }
+
+ #[inline]
+ fn serialize_some<T>(self, value: &T) -> Result<Value>
+ where
+ T: ?Sized + Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
+ Ok(SerializeVec {
+ vec: Vec::with_capacity(len.unwrap_or(0)),
+ })
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ Ok(SerializeTupleVariant {
+ name: String::from(variant),
+ vec: Vec::with_capacity(len),
+ })
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+ Ok(SerializeMap::Map {
+ map: Map::new(),
+ next_key: None,
+ })
+ }
+
+ fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
+ match name {
+ #[cfg(feature = "arbitrary_precision")]
+ crate::number::TOKEN => Ok(SerializeMap::Number { out_value: None }),
+ #[cfg(feature = "raw_value")]
+ crate::raw::TOKEN => Ok(SerializeMap::RawValue { out_value: None }),
+ _ => self.serialize_map(Some(len)),
+ }
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ Ok(SerializeStructVariant {
+ name: String::from(variant),
+ map: Map::new(),
+ })
+ }
+
+ fn collect_str<T>(self, value: &T) -> Result<Value>
+ where
+ T: ?Sized + Display,
+ {
+ Ok(Value::String(value.to_string()))
+ }
+}
+
+pub struct SerializeVec {
+ vec: Vec<Value>,
+}
+
+pub struct SerializeTupleVariant {
+ name: String,
+ vec: Vec<Value>,
+}
+
+pub enum SerializeMap {
+ Map {
+ map: Map<String, Value>,
+ next_key: Option<String>,
+ },
+ #[cfg(feature = "arbitrary_precision")]
+ Number { out_value: Option<Value> },
+ #[cfg(feature = "raw_value")]
+ RawValue { out_value: Option<Value> },
+}
+
+pub struct SerializeStructVariant {
+ name: String,
+ map: Map<String, Value>,
+}
+
+impl serde::ser::SerializeSeq for SerializeVec {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ self.vec.push(tri!(to_value(value)));
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value> {
+ Ok(Value::Array(self.vec))
+ }
+}
+
+impl serde::ser::SerializeTuple for SerializeVec {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ serde::ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<Value> {
+ serde::ser::SerializeSeq::end(self)
+ }
+}
+
+impl serde::ser::SerializeTupleStruct for SerializeVec {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ serde::ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<Value> {
+ serde::ser::SerializeSeq::end(self)
+ }
+}
+
+impl serde::ser::SerializeTupleVariant for SerializeTupleVariant {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ self.vec.push(tri!(to_value(value)));
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value> {
+ let mut object = Map::new();
+
+ object.insert(self.name, Value::Array(self.vec));
+
+ Ok(Value::Object(object))
+ }
+}
+
+impl serde::ser::SerializeMap for SerializeMap {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_key<T>(&mut self, key: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ match self {
+ SerializeMap::Map { next_key, .. } => {
+ *next_key = Some(tri!(key.serialize(MapKeySerializer)));
+ Ok(())
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ SerializeMap::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ SerializeMap::RawValue { .. } => unreachable!(),
+ }
+ }
+
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ match self {
+ SerializeMap::Map { map, next_key } => {
+ let key = next_key.take();
+ // Panic because this indicates a bug in the program rather than an
+ // expected failure.
+ let key = key.expect("serialize_value called before serialize_key");
+ map.insert(key, tri!(to_value(value)));
+ Ok(())
+ }
+ #[cfg(feature = "arbitrary_precision")]
+ SerializeMap::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ SerializeMap::RawValue { .. } => unreachable!(),
+ }
+ }
+
+ fn end(self) -> Result<Value> {
+ match self {
+ SerializeMap::Map { map, .. } => Ok(Value::Object(map)),
+ #[cfg(feature = "arbitrary_precision")]
+ SerializeMap::Number { .. } => unreachable!(),
+ #[cfg(feature = "raw_value")]
+ SerializeMap::RawValue { .. } => unreachable!(),
+ }
+ }
+}
+
+struct MapKeySerializer;
+
+fn key_must_be_a_string() -> Error {
+ Error::syntax(ErrorCode::KeyMustBeAString, 0, 0)
+}
+
+impl serde::Serializer for MapKeySerializer {
+ type Ok = String;
+ type Error = Error;
+
+ type SerializeSeq = Impossible<String, Error>;
+ type SerializeTuple = Impossible<String, Error>;
+ type SerializeTupleStruct = Impossible<String, Error>;
+ type SerializeTupleVariant = Impossible<String, Error>;
+ type SerializeMap = Impossible<String, Error>;
+ type SerializeStruct = Impossible<String, Error>;
+ type SerializeStructVariant = Impossible<String, Error>;
+
+ #[inline]
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<String> {
+ Ok(variant.to_owned())
+ }
+
+ #[inline]
+ fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<String>
+ where
+ T: ?Sized + Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_bool(self, _value: bool) -> Result<String> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_i8(self, value: i8) -> Result<String> {
+ Ok(value.to_string())
+ }
+
+ fn serialize_i16(self, value: i16) -> Result<String> {
+ Ok(value.to_string())
+ }
+
+ fn serialize_i32(self, value: i32) -> Result<String> {
+ Ok(value.to_string())
+ }
+
+ fn serialize_i64(self, value: i64) -> Result<String> {
+ Ok(value.to_string())
+ }
+
+ fn serialize_u8(self, value: u8) -> Result<String> {
+ Ok(value.to_string())
+ }
+
+ fn serialize_u16(self, value: u16) -> Result<String> {
+ Ok(value.to_string())
+ }
+
+ fn serialize_u32(self, value: u32) -> Result<String> {
+ Ok(value.to_string())
+ }
+
+ fn serialize_u64(self, value: u64) -> Result<String> {
+ Ok(value.to_string())
+ }
+
+ fn serialize_f32(self, _value: f32) -> Result<String> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_f64(self, _value: f64) -> Result<String> {
+ Err(key_must_be_a_string())
+ }
+
+ #[inline]
+ fn serialize_char(self, value: char) -> Result<String> {
+ Ok({
+ let mut s = String::new();
+ s.push(value);
+ s
+ })
+ }
+
+ #[inline]
+ fn serialize_str(self, value: &str) -> Result<String> {
+ Ok(value.to_owned())
+ }
+
+ fn serialize_bytes(self, _value: &[u8]) -> Result<String> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_unit(self) -> Result<String> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<String> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<String>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_none(self) -> Result<String> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_some<T>(self, _value: &T) -> Result<String>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
+ Err(key_must_be_a_string())
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ Err(key_must_be_a_string())
+ }
+
+ fn collect_str<T>(self, value: &T) -> Result<String>
+ where
+ T: ?Sized + Display,
+ {
+ Ok(value.to_string())
+ }
+}
+
+impl serde::ser::SerializeStruct for SerializeMap {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ match self {
+ SerializeMap::Map { .. } => serde::ser::SerializeMap::serialize_entry(self, key, value),
+ #[cfg(feature = "arbitrary_precision")]
+ SerializeMap::Number { out_value } => {
+ if key == crate::number::TOKEN {
+ *out_value = Some(value.serialize(NumberValueEmitter)?);
+ Ok(())
+ } else {
+ Err(invalid_number())
+ }
+ }
+ #[cfg(feature = "raw_value")]
+ SerializeMap::RawValue { out_value } => {
+ if key == crate::raw::TOKEN {
+ *out_value = Some(value.serialize(RawValueEmitter)?);
+ Ok(())
+ } else {
+ Err(invalid_raw_value())
+ }
+ }
+ }
+ }
+
+ fn end(self) -> Result<Value> {
+ match self {
+ SerializeMap::Map { .. } => serde::ser::SerializeMap::end(self),
+ #[cfg(feature = "arbitrary_precision")]
+ SerializeMap::Number { out_value, .. } => {
+ Ok(out_value.expect("number value was not emitted"))
+ }
+ #[cfg(feature = "raw_value")]
+ SerializeMap::RawValue { out_value, .. } => {
+ Ok(out_value.expect("raw value was not emitted"))
+ }
+ }
+ }
+}
+
+impl serde::ser::SerializeStructVariant for SerializeStructVariant {
+ type Ok = Value;
+ type Error = Error;
+
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + Serialize,
+ {
+ self.map.insert(String::from(key), tri!(to_value(value)));
+ Ok(())
+ }
+
+ fn end(self) -> Result<Value> {
+ let mut object = Map::new();
+
+ object.insert(self.name, Value::Object(self.map));
+
+ Ok(Value::Object(object))
+ }
+}
+
+#[cfg(feature = "arbitrary_precision")]
+struct NumberValueEmitter;
+
+#[cfg(feature = "arbitrary_precision")]
+fn invalid_number() -> Error {
+ Error::syntax(ErrorCode::InvalidNumber, 0, 0)
+}
+
+#[cfg(feature = "arbitrary_precision")]
+impl serde::ser::Serializer for NumberValueEmitter {
+ type Ok = Value;
+ type Error = Error;
+
+ type SerializeSeq = Impossible<Value, Error>;
+ type SerializeTuple = Impossible<Value, Error>;
+ type SerializeTupleStruct = Impossible<Value, Error>;
+ type SerializeTupleVariant = Impossible<Value, Error>;
+ type SerializeMap = Impossible<Value, Error>;
+ type SerializeStruct = Impossible<Value, Error>;
+ type SerializeStructVariant = Impossible<Value, Error>;
+
+ fn serialize_bool(self, _v: bool) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_i8(self, _v: i8) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_i16(self, _v: i16) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_i32(self, _v: i32) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_i64(self, _v: i64) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_u8(self, _v: u8) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_u16(self, _v: u16) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_u32(self, _v: u32) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_u64(self, _v: u64) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_f32(self, _v: f32) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_f64(self, _v: f64) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_char(self, _v: char) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_str(self, value: &str) -> Result<Value> {
+ let n = tri!(value.to_owned().parse());
+ Ok(Value::Number(n))
+ }
+
+ fn serialize_bytes(self, _value: &[u8]) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_none(self) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_some<T>(self, _value: &T) -> Result<Value>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(invalid_number())
+ }
+
+ fn serialize_unit(self) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ ) -> Result<Value> {
+ Err(invalid_number())
+ }
+
+ fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<Value>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(invalid_number())
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<Value>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(invalid_number())
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
+ Err(invalid_number())
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
+ Err(invalid_number())
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ Err(invalid_number())
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ Err(invalid_number())
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+ Err(invalid_number())
+ }
+
+ fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
+ Err(invalid_number())
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ Err(invalid_number())
+ }
+}
+
+#[cfg(feature = "raw_value")]
+struct RawValueEmitter;
+
+#[cfg(feature = "raw_value")]
+fn invalid_raw_value() -> Error {
+ Error::syntax(ErrorCode::ExpectedSomeValue, 0, 0)
+}
+
+#[cfg(feature = "raw_value")]
+impl serde::ser::Serializer for RawValueEmitter {
+ type Ok = Value;
+ type Error = Error;
+
+ type SerializeSeq = Impossible<Value, Error>;
+ type SerializeTuple = Impossible<Value, Error>;
+ type SerializeTupleStruct = Impossible<Value, Error>;
+ type SerializeTupleVariant = Impossible<Value, Error>;
+ type SerializeMap = Impossible<Value, Error>;
+ type SerializeStruct = Impossible<Value, Error>;
+ type SerializeStructVariant = Impossible<Value, Error>;
+
+ fn serialize_bool(self, _v: bool) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_i8(self, _v: i8) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_i16(self, _v: i16) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_i32(self, _v: i32) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_i64(self, _v: i64) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_u8(self, _v: u8) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_u16(self, _v: u16) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_u32(self, _v: u32) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_u64(self, _v: u64) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_f32(self, _v: f32) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_f64(self, _v: f64) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_char(self, _v: char) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_str(self, value: &str) -> Result<Value> {
+ crate::from_str(value)
+ }
+
+ fn serialize_bytes(self, _value: &[u8]) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_none(self) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_some<T>(self, _value: &T) -> Result<Value>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_unit(self) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ ) -> Result<Value> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_newtype_struct<T>(self, _name: &'static str, _value: &T) -> Result<Value>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<Value>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<Self::SerializeStruct> {
+ Err(invalid_raw_value())
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ Err(invalid_raw_value())
+ }
+
+ fn collect_str<T>(self, value: &T) -> Result<Self::Ok>
+ where
+ T: ?Sized + Display,
+ {
+ self.serialize_str(&value.to_string())
+ }
+}
diff --git a/third_party/rust/serde_json/tests/compiletest.rs b/third_party/rust/serde_json/tests/compiletest.rs
new file mode 100644
index 0000000000..7974a6249e
--- /dev/null
+++ b/third_party/rust/serde_json/tests/compiletest.rs
@@ -0,0 +1,7 @@
+#[rustversion::attr(not(nightly), ignore)]
+#[cfg_attr(miri, ignore)]
+#[test]
+fn ui() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/ui/*.rs");
+}
diff --git a/third_party/rust/serde_json/tests/debug.rs b/third_party/rust/serde_json/tests/debug.rs
new file mode 100644
index 0000000000..8ddcf5a381
--- /dev/null
+++ b/third_party/rust/serde_json/tests/debug.rs
@@ -0,0 +1,81 @@
+use indoc::indoc;
+use serde_json::{json, Number, Value};
+
+#[test]
+fn number() {
+ assert_eq!(format!("{:?}", Number::from(1)), "Number(1)");
+ assert_eq!(format!("{:?}", Number::from(-1)), "Number(-1)");
+ assert_eq!(
+ format!("{:?}", Number::from_f64(1.0).unwrap()),
+ "Number(1.0)"
+ );
+}
+
+#[test]
+fn value_null() {
+ assert_eq!(format!("{:?}", json!(null)), "Null");
+}
+
+#[test]
+fn value_bool() {
+ assert_eq!(format!("{:?}", json!(true)), "Bool(true)");
+ assert_eq!(format!("{:?}", json!(false)), "Bool(false)");
+}
+
+#[test]
+fn value_number() {
+ assert_eq!(format!("{:?}", json!(1)), "Number(1)");
+ assert_eq!(format!("{:?}", json!(-1)), "Number(-1)");
+ assert_eq!(format!("{:?}", json!(1.0)), "Number(1.0)");
+ assert_eq!(Number::from_f64(1.0).unwrap().to_string(), "1.0"); // not just "1"
+ assert_eq!(Number::from_f64(12e40).unwrap().to_string(), "1.2e41");
+}
+
+#[test]
+fn value_string() {
+ assert_eq!(format!("{:?}", json!("s")), "String(\"s\")");
+}
+
+#[test]
+fn value_array() {
+ assert_eq!(format!("{:?}", json!([])), "Array []");
+}
+
+#[test]
+fn value_object() {
+ assert_eq!(format!("{:?}", json!({})), "Object {}");
+}
+
+#[test]
+fn error() {
+ let err = serde_json::from_str::<Value>("{0}").unwrap_err();
+ let expected = "Error(\"key must be a string\", line: 1, column: 2)";
+ assert_eq!(format!("{:?}", err), expected);
+}
+
+#[test]
+fn indented() {
+ let j = json!({
+ "Array": [true],
+ "Bool": true,
+ "EmptyArray": [],
+ "EmptyObject": {},
+ "Null": null,
+ "Number": 1,
+ "String": "...",
+ });
+ let expected = indoc! {r#"
+ Object {
+ "Array": Array [
+ Bool(true),
+ ],
+ "Bool": Bool(true),
+ "EmptyArray": Array [],
+ "EmptyObject": Object {},
+ "Null": Null,
+ "Number": Number(1),
+ "String": String("..."),
+ }"#
+ };
+ assert_eq!(format!("{:#?}", j), expected);
+}
diff --git a/third_party/rust/serde_json/tests/lexical.rs b/third_party/rust/serde_json/tests/lexical.rs
new file mode 100644
index 0000000000..6e0f07b8c3
--- /dev/null
+++ b/third_party/rust/serde_json/tests/lexical.rs
@@ -0,0 +1,52 @@
+#![allow(
+ clippy::cast_lossless,
+ clippy::cast_possible_truncation,
+ clippy::cast_possible_wrap,
+ clippy::cast_precision_loss,
+ clippy::cast_sign_loss,
+ clippy::comparison_chain,
+ clippy::doc_markdown,
+ clippy::excessive_precision,
+ clippy::float_cmp,
+ clippy::if_not_else,
+ clippy::module_name_repetitions,
+ clippy::needless_late_init,
+ clippy::shadow_unrelated,
+ clippy::similar_names,
+ clippy::single_match_else,
+ clippy::too_many_lines,
+ clippy::unreadable_literal,
+ clippy::unseparated_literal_suffix,
+ clippy::wildcard_imports
+)]
+
+extern crate alloc;
+
+#[path = "../src/lexical/mod.rs"]
+mod lexical;
+
+mod lib {
+ pub use std::vec::Vec;
+ pub use std::{cmp, iter, mem, ops};
+}
+
+#[path = "lexical/algorithm.rs"]
+mod algorithm;
+
+#[path = "lexical/exponent.rs"]
+mod exponent;
+
+#[path = "lexical/float.rs"]
+mod float;
+
+#[path = "lexical/math.rs"]
+mod math;
+
+#[path = "lexical/num.rs"]
+mod num;
+
+#[path = "lexical/parse.rs"]
+mod parse;
+
+#[path = "lexical/rounding.rs"]
+mod rounding;
diff --git a/third_party/rust/serde_json/tests/lexical/algorithm.rs b/third_party/rust/serde_json/tests/lexical/algorithm.rs
new file mode 100644
index 0000000000..7f3a2c6241
--- /dev/null
+++ b/third_party/rust/serde_json/tests/lexical/algorithm.rs
@@ -0,0 +1,110 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+use crate::lexical::algorithm::*;
+use crate::lexical::num::Float;
+
+#[test]
+fn float_fast_path_test() {
+ // valid
+ let mantissa = (1 << f32::MANTISSA_SIZE) - 1;
+ let (min_exp, max_exp) = f32::exponent_limit();
+ for exp in min_exp..=max_exp {
+ let f = fast_path::<f32>(mantissa, exp);
+ assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp));
+ }
+
+ // Check slightly above valid exponents
+ let f = fast_path::<f32>(123, 15);
+ assert_eq!(f, Some(1.23e+17));
+
+ // Exponent is 1 too high, pushes over the mantissa.
+ let f = fast_path::<f32>(123, 16);
+ assert!(f.is_none());
+
+ // Mantissa is too large, checked_mul should overflow.
+ let f = fast_path::<f32>(mantissa, 11);
+ assert!(f.is_none());
+
+ // invalid exponents
+ let (min_exp, max_exp) = f32::exponent_limit();
+ let f = fast_path::<f32>(mantissa, min_exp - 1);
+ assert!(f.is_none(), "exponent under min_exp");
+
+ let f = fast_path::<f32>(mantissa, max_exp + 1);
+ assert!(f.is_none(), "exponent above max_exp");
+}
+
+#[test]
+fn double_fast_path_test() {
+ // valid
+ let mantissa = (1 << f64::MANTISSA_SIZE) - 1;
+ let (min_exp, max_exp) = f64::exponent_limit();
+ for exp in min_exp..=max_exp {
+ let f = fast_path::<f64>(mantissa, exp);
+ assert!(f.is_some(), "should be valid {:?}.", (mantissa, exp));
+ }
+
+ // invalid exponents
+ let (min_exp, max_exp) = f64::exponent_limit();
+ let f = fast_path::<f64>(mantissa, min_exp - 1);
+ assert!(f.is_none(), "exponent under min_exp");
+
+ let f = fast_path::<f64>(mantissa, max_exp + 1);
+ assert!(f.is_none(), "exponent above max_exp");
+
+ assert_eq!(
+ Some(0.04628372940652459),
+ fast_path::<f64>(4628372940652459, -17)
+ );
+ assert_eq!(None, fast_path::<f64>(26383446160308229, -272));
+}
+
+#[test]
+fn moderate_path_test() {
+ let (f, valid) = moderate_path::<f64>(1234567890, -1, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 123456789.0);
+
+ let (f, valid) = moderate_path::<f64>(1234567891, -1, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 123456789.1);
+
+ let (f, valid) = moderate_path::<f64>(12345678912, -2, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 123456789.12);
+
+ let (f, valid) = moderate_path::<f64>(123456789123, -3, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 123456789.123);
+
+ let (f, valid) = moderate_path::<f64>(1234567891234, -4, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 123456789.1234);
+
+ let (f, valid) = moderate_path::<f64>(12345678912345, -5, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 123456789.12345);
+
+ let (f, valid) = moderate_path::<f64>(123456789123456, -6, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 123456789.123456);
+
+ let (f, valid) = moderate_path::<f64>(1234567891234567, -7, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 123456789.1234567);
+
+ let (f, valid) = moderate_path::<f64>(12345678912345679, -8, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 123456789.12345679);
+
+ let (f, valid) = moderate_path::<f64>(4628372940652459, -17, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 0.04628372940652459);
+
+ let (f, valid) = moderate_path::<f64>(26383446160308229, -272, false);
+ assert!(valid, "should be valid");
+ assert_eq!(f.into_float::<f64>(), 2.6383446160308229e-256);
+
+ let (_, valid) = moderate_path::<f64>(26383446160308230, -272, false);
+ assert!(!valid, "should be invalid");
+}
diff --git a/third_party/rust/serde_json/tests/lexical/exponent.rs b/third_party/rust/serde_json/tests/lexical/exponent.rs
new file mode 100644
index 0000000000..f7a847be38
--- /dev/null
+++ b/third_party/rust/serde_json/tests/lexical/exponent.rs
@@ -0,0 +1,54 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+use crate::lexical::exponent::*;
+
+#[test]
+fn scientific_exponent_test() {
+ // 0 digits in the integer
+ assert_eq!(scientific_exponent(0, 0, 5), -6);
+ assert_eq!(scientific_exponent(10, 0, 5), 4);
+ assert_eq!(scientific_exponent(-10, 0, 5), -16);
+
+ // >0 digits in the integer
+ assert_eq!(scientific_exponent(0, 1, 5), 0);
+ assert_eq!(scientific_exponent(0, 2, 5), 1);
+ assert_eq!(scientific_exponent(0, 2, 20), 1);
+ assert_eq!(scientific_exponent(10, 2, 20), 11);
+ assert_eq!(scientific_exponent(-10, 2, 20), -9);
+
+ // Underflow
+ assert_eq!(
+ scientific_exponent(i32::min_value(), 0, 0),
+ i32::min_value()
+ );
+ assert_eq!(
+ scientific_exponent(i32::min_value(), 0, 5),
+ i32::min_value()
+ );
+
+ // Overflow
+ assert_eq!(
+ scientific_exponent(i32::max_value(), 0, 0),
+ i32::max_value() - 1
+ );
+ assert_eq!(
+ scientific_exponent(i32::max_value(), 5, 0),
+ i32::max_value()
+ );
+}
+
+#[test]
+fn mantissa_exponent_test() {
+ assert_eq!(mantissa_exponent(10, 5, 0), 5);
+ assert_eq!(mantissa_exponent(0, 5, 0), -5);
+ assert_eq!(
+ mantissa_exponent(i32::max_value(), 5, 0),
+ i32::max_value() - 5
+ );
+ assert_eq!(mantissa_exponent(i32::max_value(), 0, 5), i32::max_value());
+ assert_eq!(mantissa_exponent(i32::min_value(), 5, 0), i32::min_value());
+ assert_eq!(
+ mantissa_exponent(i32::min_value(), 0, 5),
+ i32::min_value() + 5
+ );
+}
diff --git a/third_party/rust/serde_json/tests/lexical/float.rs b/third_party/rust/serde_json/tests/lexical/float.rs
new file mode 100644
index 0000000000..c87e7e1ed9
--- /dev/null
+++ b/third_party/rust/serde_json/tests/lexical/float.rs
@@ -0,0 +1,581 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+use crate::lexical::float::ExtendedFloat;
+use crate::lexical::rounding::round_nearest_tie_even;
+use std::{f32, f64};
+
+// NORMALIZE
+
+fn check_normalize(mant: u64, exp: i32, shift: u32, r_mant: u64, r_exp: i32) {
+ let mut x = ExtendedFloat { mant, exp };
+ assert_eq!(x.normalize(), shift);
+ assert_eq!(
+ x,
+ ExtendedFloat {
+ mant: r_mant,
+ exp: r_exp
+ }
+ );
+}
+
+#[test]
+fn normalize_test() {
+ // F32
+ // 0
+ check_normalize(0, 0, 0, 0, 0);
+
+ // min value
+ check_normalize(1, -149, 63, 9223372036854775808, -212);
+
+ // 1.0e-40
+ check_normalize(71362, -149, 47, 10043308644012916736, -196);
+
+ // 1.0e-20
+ check_normalize(12379400, -90, 40, 13611294244890214400, -130);
+
+ // 1.0
+ check_normalize(8388608, -23, 40, 9223372036854775808, -63);
+
+ // 1e20
+ check_normalize(11368684, 43, 40, 12500000250510966784, 3);
+
+ // max value
+ check_normalize(16777213, 104, 40, 18446740775174668288, 64);
+
+ // F64
+
+ // min value
+ check_normalize(1, -1074, 63, 9223372036854775808, -1137);
+
+ // 1.0e-250
+ check_normalize(6448907850777164, -883, 11, 13207363278391631872, -894);
+
+ // 1.0e-150
+ check_normalize(7371020360979573, -551, 11, 15095849699286165504, -562);
+
+ // 1.0e-45
+ check_normalize(6427752177035961, -202, 11, 13164036458569648128, -213);
+
+ // 1.0e-40
+ check_normalize(4903985730770844, -185, 11, 10043362776618688512, -196);
+
+ // 1.0e-20
+ check_normalize(6646139978924579, -119, 11, 13611294676837537792, -130);
+
+ // 1.0
+ check_normalize(4503599627370496, -52, 11, 9223372036854775808, -63);
+
+ // 1e20
+ check_normalize(6103515625000000, 14, 11, 12500000000000000000, 3);
+
+ // 1e40
+ check_normalize(8271806125530277, 80, 11, 16940658945086007296, 69);
+
+ // 1e150
+ check_normalize(5503284107318959, 446, 11, 11270725851789228032, 435);
+
+ // 1e250
+ check_normalize(6290184345309700, 778, 11, 12882297539194265600, 767);
+
+ // max value
+ check_normalize(9007199254740991, 971, 11, 18446744073709549568, 960);
+}
+
+// ROUND
+
+fn check_round_to_f32(mant: u64, exp: i32, r_mant: u64, r_exp: i32) {
+ let mut x = ExtendedFloat { mant, exp };
+ x.round_to_native::<f32, _>(round_nearest_tie_even);
+ assert_eq!(
+ x,
+ ExtendedFloat {
+ mant: r_mant,
+ exp: r_exp
+ }
+ );
+}
+
+#[test]
+fn round_to_f32_test() {
+ // This is lossy, so some of these values are **slightly** rounded.
+
+ // underflow
+ check_round_to_f32(9223372036854775808, -213, 0, -149);
+
+ // min value
+ check_round_to_f32(9223372036854775808, -212, 1, -149);
+
+ // 1.0e-40
+ check_round_to_f32(10043308644012916736, -196, 71362, -149);
+
+ // 1.0e-20
+ check_round_to_f32(13611294244890214400, -130, 12379400, -90);
+
+ // 1.0
+ check_round_to_f32(9223372036854775808, -63, 8388608, -23);
+
+ // 1e20
+ check_round_to_f32(12500000250510966784, 3, 11368684, 43);
+
+ // max value
+ check_round_to_f32(18446740775174668288, 64, 16777213, 104);
+
+ // overflow
+ check_round_to_f32(18446740775174668288, 65, 16777213, 105);
+}
+
+fn check_round_to_f64(mant: u64, exp: i32, r_mant: u64, r_exp: i32) {
+ let mut x = ExtendedFloat { mant, exp };
+ x.round_to_native::<f64, _>(round_nearest_tie_even);
+ assert_eq!(
+ x,
+ ExtendedFloat {
+ mant: r_mant,
+ exp: r_exp
+ }
+ );
+}
+
+#[test]
+fn round_to_f64_test() {
+ // This is lossy, so some of these values are **slightly** rounded.
+
+ // underflow
+ check_round_to_f64(9223372036854775808, -1138, 0, -1074);
+
+ // min value
+ check_round_to_f64(9223372036854775808, -1137, 1, -1074);
+
+ // 1.0e-250
+ check_round_to_f64(15095849699286165504, -562, 7371020360979573, -551);
+
+ // 1.0e-150
+ check_round_to_f64(15095849699286165504, -562, 7371020360979573, -551);
+
+ // 1.0e-45
+ check_round_to_f64(13164036458569648128, -213, 6427752177035961, -202);
+
+ // 1.0e-40
+ check_round_to_f64(10043362776618688512, -196, 4903985730770844, -185);
+
+ // 1.0e-20
+ check_round_to_f64(13611294676837537792, -130, 6646139978924579, -119);
+
+ // 1.0
+ check_round_to_f64(9223372036854775808, -63, 4503599627370496, -52);
+
+ // 1e20
+ check_round_to_f64(12500000000000000000, 3, 6103515625000000, 14);
+
+ // 1e40
+ check_round_to_f64(16940658945086007296, 69, 8271806125530277, 80);
+
+ // 1e150
+ check_round_to_f64(11270725851789228032, 435, 5503284107318959, 446);
+
+ // 1e250
+ check_round_to_f64(12882297539194265600, 767, 6290184345309700, 778);
+
+ // max value
+ check_round_to_f64(18446744073709549568, 960, 9007199254740991, 971);
+
+ // Bug fixes
+ // 1.2345e-308
+ check_round_to_f64(10234494226754558294, -1086, 2498655817078750, -1074);
+}
+
+fn assert_normalized_eq(mut x: ExtendedFloat, mut y: ExtendedFloat) {
+ x.normalize();
+ y.normalize();
+ assert_eq!(x, y);
+}
+
+#[test]
+fn from_float() {
+ let values: [f32; 26] = [
+ 1e-40, 2e-40, 1e-35, 2e-35, 1e-30, 2e-30, 1e-25, 2e-25, 1e-20, 2e-20, 1e-15, 2e-15, 1e-10,
+ 2e-10, 1e-5, 2e-5, 1.0, 2.0, 1e5, 2e5, 1e10, 2e10, 1e15, 2e15, 1e20, 2e20,
+ ];
+ for value in &values {
+ assert_normalized_eq(
+ ExtendedFloat::from_float(*value),
+ ExtendedFloat::from_float(*value as f64),
+ );
+ }
+}
+
+// TO
+
+// Sample of interesting numbers to check during standard test builds.
+const INTEGERS: [u64; 32] = [
+ 0, // 0x0
+ 1, // 0x1
+ 7, // 0x7
+ 15, // 0xF
+ 112, // 0x70
+ 119, // 0x77
+ 127, // 0x7F
+ 240, // 0xF0
+ 247, // 0xF7
+ 255, // 0xFF
+ 2032, // 0x7F0
+ 2039, // 0x7F7
+ 2047, // 0x7FF
+ 4080, // 0xFF0
+ 4087, // 0xFF7
+ 4095, // 0xFFF
+ 65520, // 0xFFF0
+ 65527, // 0xFFF7
+ 65535, // 0xFFFF
+ 1048560, // 0xFFFF0
+ 1048567, // 0xFFFF7
+ 1048575, // 0xFFFFF
+ 16777200, // 0xFFFFF0
+ 16777207, // 0xFFFFF7
+ 16777215, // 0xFFFFFF
+ 268435440, // 0xFFFFFF0
+ 268435447, // 0xFFFFFF7
+ 268435455, // 0xFFFFFFF
+ 4294967280, // 0xFFFFFFF0
+ 4294967287, // 0xFFFFFFF7
+ 4294967295, // 0xFFFFFFFF
+ 18446744073709551615, // 0xFFFFFFFFFFFFFFFF
+];
+
+#[test]
+fn to_f32_test() {
+ // underflow
+ let x = ExtendedFloat {
+ mant: 9223372036854775808,
+ exp: -213,
+ };
+ assert_eq!(x.into_float::<f32>(), 0.0);
+
+ // min value
+ let x = ExtendedFloat {
+ mant: 9223372036854775808,
+ exp: -212,
+ };
+ assert_eq!(x.into_float::<f32>(), 1e-45);
+
+ // 1.0e-40
+ let x = ExtendedFloat {
+ mant: 10043308644012916736,
+ exp: -196,
+ };
+ assert_eq!(x.into_float::<f32>(), 1e-40);
+
+ // 1.0e-20
+ let x = ExtendedFloat {
+ mant: 13611294244890214400,
+ exp: -130,
+ };
+ assert_eq!(x.into_float::<f32>(), 1e-20);
+
+ // 1.0
+ let x = ExtendedFloat {
+ mant: 9223372036854775808,
+ exp: -63,
+ };
+ assert_eq!(x.into_float::<f32>(), 1.0);
+
+ // 1e20
+ let x = ExtendedFloat {
+ mant: 12500000250510966784,
+ exp: 3,
+ };
+ assert_eq!(x.into_float::<f32>(), 1e20);
+
+ // max value
+ let x = ExtendedFloat {
+ mant: 18446740775174668288,
+ exp: 64,
+ };
+ assert_eq!(x.into_float::<f32>(), 3.402823e38);
+
+ // almost max, high exp
+ let x = ExtendedFloat {
+ mant: 1048575,
+ exp: 108,
+ };
+ assert_eq!(x.into_float::<f32>(), 3.4028204e38);
+
+ // max value + 1
+ let x = ExtendedFloat {
+ mant: 16777216,
+ exp: 104,
+ };
+ assert_eq!(x.into_float::<f32>(), f32::INFINITY);
+
+ // max value + 1
+ let x = ExtendedFloat {
+ mant: 1048576,
+ exp: 108,
+ };
+ assert_eq!(x.into_float::<f32>(), f32::INFINITY);
+
+ // 1e40
+ let x = ExtendedFloat {
+ mant: 16940658945086007296,
+ exp: 69,
+ };
+ assert_eq!(x.into_float::<f32>(), f32::INFINITY);
+
+ // Integers.
+ for int in &INTEGERS {
+ let fp = ExtendedFloat { mant: *int, exp: 0 };
+ assert_eq!(fp.into_float::<f32>(), *int as f32, "{:?} as f32", *int);
+ }
+}
+
+#[test]
+fn to_f64_test() {
+ // underflow
+ let x = ExtendedFloat {
+ mant: 9223372036854775808,
+ exp: -1138,
+ };
+ assert_eq!(x.into_float::<f64>(), 0.0);
+
+ // min value
+ let x = ExtendedFloat {
+ mant: 9223372036854775808,
+ exp: -1137,
+ };
+ assert_eq!(x.into_float::<f64>(), 5e-324);
+
+ // 1.0e-250
+ let x = ExtendedFloat {
+ mant: 13207363278391631872,
+ exp: -894,
+ };
+ assert_eq!(x.into_float::<f64>(), 1e-250);
+
+ // 1.0e-150
+ let x = ExtendedFloat {
+ mant: 15095849699286165504,
+ exp: -562,
+ };
+ assert_eq!(x.into_float::<f64>(), 1e-150);
+
+ // 1.0e-45
+ let x = ExtendedFloat {
+ mant: 13164036458569648128,
+ exp: -213,
+ };
+ assert_eq!(x.into_float::<f64>(), 1e-45);
+
+ // 1.0e-40
+ let x = ExtendedFloat {
+ mant: 10043362776618688512,
+ exp: -196,
+ };
+ assert_eq!(x.into_float::<f64>(), 1e-40);
+
+ // 1.0e-20
+ let x = ExtendedFloat {
+ mant: 13611294676837537792,
+ exp: -130,
+ };
+ assert_eq!(x.into_float::<f64>(), 1e-20);
+
+ // 1.0
+ let x = ExtendedFloat {
+ mant: 9223372036854775808,
+ exp: -63,
+ };
+ assert_eq!(x.into_float::<f64>(), 1.0);
+
+ // 1e20
+ let x = ExtendedFloat {
+ mant: 12500000000000000000,
+ exp: 3,
+ };
+ assert_eq!(x.into_float::<f64>(), 1e20);
+
+ // 1e40
+ let x = ExtendedFloat {
+ mant: 16940658945086007296,
+ exp: 69,
+ };
+ assert_eq!(x.into_float::<f64>(), 1e40);
+
+ // 1e150
+ let x = ExtendedFloat {
+ mant: 11270725851789228032,
+ exp: 435,
+ };
+ assert_eq!(x.into_float::<f64>(), 1e150);
+
+ // 1e250
+ let x = ExtendedFloat {
+ mant: 12882297539194265600,
+ exp: 767,
+ };
+ assert_eq!(x.into_float::<f64>(), 1e250);
+
+ // max value
+ let x = ExtendedFloat {
+ mant: 9007199254740991,
+ exp: 971,
+ };
+ assert_eq!(x.into_float::<f64>(), 1.7976931348623157e308);
+
+ // max value
+ let x = ExtendedFloat {
+ mant: 18446744073709549568,
+ exp: 960,
+ };
+ assert_eq!(x.into_float::<f64>(), 1.7976931348623157e308);
+
+ // overflow
+ let x = ExtendedFloat {
+ mant: 9007199254740992,
+ exp: 971,
+ };
+ assert_eq!(x.into_float::<f64>(), f64::INFINITY);
+
+ // overflow
+ let x = ExtendedFloat {
+ mant: 18446744073709549568,
+ exp: 961,
+ };
+ assert_eq!(x.into_float::<f64>(), f64::INFINITY);
+
+ // Underflow
+ // Adapted from failures in strtod.
+ let x = ExtendedFloat {
+ exp: -1139,
+ mant: 18446744073709550712,
+ };
+ assert_eq!(x.into_float::<f64>(), 0.0);
+
+ let x = ExtendedFloat {
+ exp: -1139,
+ mant: 18446744073709551460,
+ };
+ assert_eq!(x.into_float::<f64>(), 0.0);
+
+ let x = ExtendedFloat {
+ exp: -1138,
+ mant: 9223372036854776103,
+ };
+ assert_eq!(x.into_float::<f64>(), 5e-324);
+
+ // Integers.
+ for int in &INTEGERS {
+ let fp = ExtendedFloat { mant: *int, exp: 0 };
+ assert_eq!(fp.into_float::<f64>(), *int as f64, "{:?} as f64", *int);
+ }
+}
+
+// OPERATIONS
+
+fn check_mul(a: ExtendedFloat, b: ExtendedFloat, c: ExtendedFloat) {
+ let r = a.mul(&b);
+ assert_eq!(r, c);
+}
+
+#[test]
+fn mul_test() {
+ // Normalized (64-bit mantissa)
+ let a = ExtendedFloat {
+ mant: 13164036458569648128,
+ exp: -213,
+ };
+ let b = ExtendedFloat {
+ mant: 9223372036854775808,
+ exp: -62,
+ };
+ let c = ExtendedFloat {
+ mant: 6582018229284824064,
+ exp: -211,
+ };
+ check_mul(a, b, c);
+
+ // Check with integers
+ // 64-bit mantissa
+ let mut a = ExtendedFloat { mant: 10, exp: 0 };
+ let mut b = ExtendedFloat { mant: 10, exp: 0 };
+ a.normalize();
+ b.normalize();
+ assert_eq!(a.mul(&b).into_float::<f64>(), 100.0);
+
+ // Check both values need high bits set.
+ let a = ExtendedFloat {
+ mant: 1 << 32,
+ exp: -31,
+ };
+ let b = ExtendedFloat {
+ mant: 1 << 32,
+ exp: -31,
+ };
+ assert_eq!(a.mul(&b).into_float::<f64>(), 4.0);
+
+ // Check both values need high bits set.
+ let a = ExtendedFloat {
+ mant: 10 << 31,
+ exp: -31,
+ };
+ let b = ExtendedFloat {
+ mant: 10 << 31,
+ exp: -31,
+ };
+ assert_eq!(a.mul(&b).into_float::<f64>(), 100.0);
+}
+
+fn check_imul(mut a: ExtendedFloat, b: ExtendedFloat, c: ExtendedFloat) {
+ a.imul(&b);
+ assert_eq!(a, c);
+}
+
+#[test]
+fn imul_test() {
+ // Normalized (64-bit mantissa)
+ let a = ExtendedFloat {
+ mant: 13164036458569648128,
+ exp: -213,
+ };
+ let b = ExtendedFloat {
+ mant: 9223372036854775808,
+ exp: -62,
+ };
+ let c = ExtendedFloat {
+ mant: 6582018229284824064,
+ exp: -211,
+ };
+ check_imul(a, b, c);
+
+ // Check with integers
+ // 64-bit mantissa
+ let mut a = ExtendedFloat { mant: 10, exp: 0 };
+ let mut b = ExtendedFloat { mant: 10, exp: 0 };
+ a.normalize();
+ b.normalize();
+ a.imul(&b);
+ assert_eq!(a.into_float::<f64>(), 100.0);
+
+ // Check both values need high bits set.
+ let mut a = ExtendedFloat {
+ mant: 1 << 32,
+ exp: -31,
+ };
+ let b = ExtendedFloat {
+ mant: 1 << 32,
+ exp: -31,
+ };
+ a.imul(&b);
+ assert_eq!(a.into_float::<f64>(), 4.0);
+
+ // Check both values need high bits set.
+ let mut a = ExtendedFloat {
+ mant: 10 << 31,
+ exp: -31,
+ };
+ let b = ExtendedFloat {
+ mant: 10 << 31,
+ exp: -31,
+ };
+ a.imul(&b);
+ assert_eq!(a.into_float::<f64>(), 100.0);
+}
diff --git a/third_party/rust/serde_json/tests/lexical/math.rs b/third_party/rust/serde_json/tests/lexical/math.rs
new file mode 100644
index 0000000000..79d3ef3ee5
--- /dev/null
+++ b/third_party/rust/serde_json/tests/lexical/math.rs
@@ -0,0 +1,211 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+use crate::lexical::math::{Limb, Math};
+use std::cmp;
+
+#[derive(Clone, Default)]
+struct Bigint {
+ data: Vec<Limb>,
+}
+
+impl Math for Bigint {
+ fn data(&self) -> &Vec<Limb> {
+ &self.data
+ }
+
+ fn data_mut(&mut self) -> &mut Vec<Limb> {
+ &mut self.data
+ }
+}
+
+#[cfg(limb_width_32)]
+pub(crate) fn from_u32(x: &[u32]) -> Vec<Limb> {
+ x.iter().cloned().collect()
+}
+
+#[cfg(limb_width_64)]
+pub(crate) fn from_u32(x: &[u32]) -> Vec<Limb> {
+ let mut v = Vec::<Limb>::default();
+ for xi in x.chunks(2) {
+ match xi.len() {
+ 1 => v.push(xi[0] as u64),
+ 2 => v.push(((xi[1] as u64) << 32) | (xi[0] as u64)),
+ _ => unreachable!(),
+ }
+ }
+
+ v
+}
+
+#[test]
+fn compare_test() {
+ // Simple
+ let x = Bigint {
+ data: from_u32(&[1]),
+ };
+ let y = Bigint {
+ data: from_u32(&[2]),
+ };
+ assert_eq!(x.compare(&y), cmp::Ordering::Less);
+ assert_eq!(x.compare(&x), cmp::Ordering::Equal);
+ assert_eq!(y.compare(&x), cmp::Ordering::Greater);
+
+ // Check asymmetric
+ let x = Bigint {
+ data: from_u32(&[5, 1]),
+ };
+ let y = Bigint {
+ data: from_u32(&[2]),
+ };
+ assert_eq!(x.compare(&y), cmp::Ordering::Greater);
+ assert_eq!(x.compare(&x), cmp::Ordering::Equal);
+ assert_eq!(y.compare(&x), cmp::Ordering::Less);
+
+ // Check when we use reverse ordering properly.
+ let x = Bigint {
+ data: from_u32(&[5, 1, 9]),
+ };
+ let y = Bigint {
+ data: from_u32(&[6, 2, 8]),
+ };
+ assert_eq!(x.compare(&y), cmp::Ordering::Greater);
+ assert_eq!(x.compare(&x), cmp::Ordering::Equal);
+ assert_eq!(y.compare(&x), cmp::Ordering::Less);
+
+ // Complex scenario, check it properly uses reverse ordering.
+ let x = Bigint {
+ data: from_u32(&[0, 1, 9]),
+ };
+ let y = Bigint {
+ data: from_u32(&[4294967295, 0, 9]),
+ };
+ assert_eq!(x.compare(&y), cmp::Ordering::Greater);
+ assert_eq!(x.compare(&x), cmp::Ordering::Equal);
+ assert_eq!(y.compare(&x), cmp::Ordering::Less);
+}
+
+#[test]
+fn hi64_test() {
+ assert_eq!(Bigint::from_u64(0xA).hi64(), (0xA000000000000000, false));
+ assert_eq!(Bigint::from_u64(0xAB).hi64(), (0xAB00000000000000, false));
+ assert_eq!(
+ Bigint::from_u64(0xAB00000000).hi64(),
+ (0xAB00000000000000, false)
+ );
+ assert_eq!(
+ Bigint::from_u64(0xA23456789A).hi64(),
+ (0xA23456789A000000, false)
+ );
+}
+
+#[test]
+fn bit_length_test() {
+ let x = Bigint {
+ data: from_u32(&[0, 0, 0, 1]),
+ };
+ assert_eq!(x.bit_length(), 97);
+
+ let x = Bigint {
+ data: from_u32(&[0, 0, 0, 3]),
+ };
+ assert_eq!(x.bit_length(), 98);
+
+ let x = Bigint {
+ data: from_u32(&[1 << 31]),
+ };
+ assert_eq!(x.bit_length(), 32);
+}
+
+#[test]
+fn iadd_small_test() {
+ // Overflow check (single)
+ // This should set all the internal data values to 0, the top
+ // value to (1<<31), and the bottom value to (4>>1).
+ // This is because the max_value + 1 leads to all 0s, we set the
+ // topmost bit to 1.
+ let mut x = Bigint {
+ data: from_u32(&[4294967295]),
+ };
+ x.iadd_small(5);
+ assert_eq!(x.data, from_u32(&[4, 1]));
+
+ // No overflow, single value
+ let mut x = Bigint {
+ data: from_u32(&[5]),
+ };
+ x.iadd_small(7);
+ assert_eq!(x.data, from_u32(&[12]));
+
+ // Single carry, internal overflow
+ let mut x = Bigint::from_u64(0x80000000FFFFFFFF);
+ x.iadd_small(7);
+ assert_eq!(x.data, from_u32(&[6, 0x80000001]));
+
+ // Double carry, overflow
+ let mut x = Bigint::from_u64(0xFFFFFFFFFFFFFFFF);
+ x.iadd_small(7);
+ assert_eq!(x.data, from_u32(&[6, 0, 1]));
+}
+
+#[test]
+fn imul_small_test() {
+ // No overflow check, 1-int.
+ let mut x = Bigint {
+ data: from_u32(&[5]),
+ };
+ x.imul_small(7);
+ assert_eq!(x.data, from_u32(&[35]));
+
+ // No overflow check, 2-ints.
+ let mut x = Bigint::from_u64(0x4000000040000);
+ x.imul_small(5);
+ assert_eq!(x.data, from_u32(&[0x00140000, 0x140000]));
+
+ // Overflow, 1 carry.
+ let mut x = Bigint {
+ data: from_u32(&[0x33333334]),
+ };
+ x.imul_small(5);
+ assert_eq!(x.data, from_u32(&[4, 1]));
+
+ // Overflow, 1 carry, internal.
+ let mut x = Bigint::from_u64(0x133333334);
+ x.imul_small(5);
+ assert_eq!(x.data, from_u32(&[4, 6]));
+
+ // Overflow, 2 carries.
+ let mut x = Bigint::from_u64(0x3333333333333334);
+ x.imul_small(5);
+ assert_eq!(x.data, from_u32(&[4, 0, 1]));
+}
+
+#[test]
+fn shl_test() {
+ // Pattern generated via `''.join(["1" +"0"*i for i in range(20)])`
+ let mut big = Bigint {
+ data: from_u32(&[0xD2210408]),
+ };
+ big.ishl(5);
+ assert_eq!(big.data, from_u32(&[0x44208100, 0x1A]));
+ big.ishl(32);
+ assert_eq!(big.data, from_u32(&[0, 0x44208100, 0x1A]));
+ big.ishl(27);
+ assert_eq!(big.data, from_u32(&[0, 0, 0xD2210408]));
+
+ // 96-bits of previous pattern
+ let mut big = Bigint {
+ data: from_u32(&[0x20020010, 0x8040100, 0xD2210408]),
+ };
+ big.ishl(5);
+ assert_eq!(big.data, from_u32(&[0x400200, 0x802004, 0x44208101, 0x1A]));
+ big.ishl(32);
+ assert_eq!(
+ big.data,
+ from_u32(&[0, 0x400200, 0x802004, 0x44208101, 0x1A])
+ );
+ big.ishl(27);
+ assert_eq!(
+ big.data,
+ from_u32(&[0, 0, 0x20020010, 0x8040100, 0xD2210408])
+ );
+}
diff --git a/third_party/rust/serde_json/tests/lexical/num.rs b/third_party/rust/serde_json/tests/lexical/num.rs
new file mode 100644
index 0000000000..1a94be0130
--- /dev/null
+++ b/third_party/rust/serde_json/tests/lexical/num.rs
@@ -0,0 +1,76 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+use crate::lexical::num::{AsPrimitive, Float, Integer, Number};
+
+fn check_as_primitive<T: AsPrimitive>(t: T) {
+ let _: u32 = t.as_u32();
+ let _: u64 = t.as_u64();
+ let _: u128 = t.as_u128();
+ let _: usize = t.as_usize();
+ let _: f32 = t.as_f32();
+ let _: f64 = t.as_f64();
+}
+
+#[test]
+fn as_primitive_test() {
+ check_as_primitive(1u32);
+ check_as_primitive(1u64);
+ check_as_primitive(1u128);
+ check_as_primitive(1usize);
+ check_as_primitive(1f32);
+ check_as_primitive(1f64);
+}
+
+fn check_number<T: Number>(x: T, y: T) {
+ // Copy, partialeq, partialord
+ let _ = x;
+ assert!(x < y);
+ assert!(x != y);
+
+ // Operations
+ let _ = y + x;
+
+ // Conversions already tested.
+}
+
+#[test]
+fn number_test() {
+ check_number(1u32, 5);
+ check_number(1u64, 5);
+ check_number(1u128, 5);
+ check_number(1usize, 5);
+ check_number(1f32, 5.0);
+ check_number(1f64, 5.0);
+}
+
+fn check_integer<T: Integer>(x: T) {
+ // Bitwise operations
+ let _ = x & T::ZERO;
+}
+
+#[test]
+fn integer_test() {
+ check_integer(65u32);
+ check_integer(65u64);
+ check_integer(65u128);
+ check_integer(65usize);
+}
+
+fn check_float<T: Float>(x: T) {
+ // Check functions
+ let _ = x.pow10(5);
+ let _ = x.to_bits();
+ assert!(T::from_bits(x.to_bits()) == x);
+
+ // Check properties
+ let _ = x.to_bits() & T::SIGN_MASK;
+ let _ = x.to_bits() & T::EXPONENT_MASK;
+ let _ = x.to_bits() & T::HIDDEN_BIT_MASK;
+ let _ = x.to_bits() & T::MANTISSA_MASK;
+}
+
+#[test]
+fn float_test() {
+ check_float(123f32);
+ check_float(123f64);
+}
diff --git a/third_party/rust/serde_json/tests/lexical/parse.rs b/third_party/rust/serde_json/tests/lexical/parse.rs
new file mode 100644
index 0000000000..80ca25e772
--- /dev/null
+++ b/third_party/rust/serde_json/tests/lexical/parse.rs
@@ -0,0 +1,204 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+use crate::lexical::num::Float;
+use crate::lexical::parse::{parse_concise_float, parse_truncated_float};
+use core::f64;
+use core::fmt::Debug;
+
+fn check_concise_float<F>(mantissa: u64, exponent: i32, expected: F)
+where
+ F: Float + Debug,
+{
+ assert_eq!(parse_concise_float::<F>(mantissa, exponent), expected);
+}
+
+fn check_truncated_float<F>(integer: &str, fraction: &str, exponent: i32, expected: F)
+where
+ F: Float + Debug,
+{
+ let integer = integer.as_bytes();
+ let fraction = fraction.as_bytes();
+ assert_eq!(
+ parse_truncated_float::<F>(integer, fraction, exponent),
+ expected,
+ );
+}
+
+#[test]
+fn parse_f32_test() {
+ check_concise_float(0, 0, 0.0_f32);
+ check_concise_float(12345, -4, 1.2345_f32);
+ check_concise_float(12345, -3, 12.345_f32);
+ check_concise_float(123456789, -4, 12345.6789_f32);
+ check_concise_float(12345, 6, 1.2345e10_f32);
+ check_concise_float(12345, -42, 1.2345e-38_f32);
+
+ // Check expected rounding, using borderline cases.
+ // Round-down, halfway
+ check_concise_float(16777216, 0, 16777216.0_f32);
+ check_concise_float(16777217, 0, 16777216.0_f32);
+ check_concise_float(16777218, 0, 16777218.0_f32);
+ check_concise_float(33554432, 0, 33554432.0_f32);
+ check_concise_float(33554434, 0, 33554432.0_f32);
+ check_concise_float(33554436, 0, 33554436.0_f32);
+ check_concise_float(17179869184, 0, 17179869184.0_f32);
+ check_concise_float(17179870208, 0, 17179869184.0_f32);
+ check_concise_float(17179871232, 0, 17179871232.0_f32);
+
+ // Round-up, halfway
+ check_concise_float(16777218, 0, 16777218.0_f32);
+ check_concise_float(16777219, 0, 16777220.0_f32);
+ check_concise_float(16777220, 0, 16777220.0_f32);
+
+ check_concise_float(33554436, 0, 33554436.0_f32);
+ check_concise_float(33554438, 0, 33554440.0_f32);
+ check_concise_float(33554440, 0, 33554440.0_f32);
+
+ check_concise_float(17179871232, 0, 17179871232.0_f32);
+ check_concise_float(17179872256, 0, 17179873280.0_f32);
+ check_concise_float(17179873280, 0, 17179873280.0_f32);
+
+ // Round-up, above halfway
+ check_concise_float(33554435, 0, 33554436.0_f32);
+ check_concise_float(17179870209, 0, 17179871232.0_f32);
+
+ // Check exactly halfway, round-up at halfway
+ check_truncated_float("1", "00000017881393432617187499", 0, 1.0000001_f32);
+ check_truncated_float("1", "000000178813934326171875", 0, 1.0000002_f32);
+ check_truncated_float("1", "00000017881393432617187501", 0, 1.0000002_f32);
+}
+
+#[test]
+fn parse_f64_test() {
+ check_concise_float(0, 0, 0.0_f64);
+ check_concise_float(12345, -4, 1.2345_f64);
+ check_concise_float(12345, -3, 12.345_f64);
+ check_concise_float(123456789, -4, 12345.6789_f64);
+ check_concise_float(12345, 6, 1.2345e10_f64);
+ check_concise_float(12345, -312, 1.2345e-308_f64);
+
+ // Check expected rounding, using borderline cases.
+ // Round-down, halfway
+ check_concise_float(9007199254740992, 0, 9007199254740992.0_f64);
+ check_concise_float(9007199254740993, 0, 9007199254740992.0_f64);
+ check_concise_float(9007199254740994, 0, 9007199254740994.0_f64);
+
+ check_concise_float(18014398509481984, 0, 18014398509481984.0_f64);
+ check_concise_float(18014398509481986, 0, 18014398509481984.0_f64);
+ check_concise_float(18014398509481988, 0, 18014398509481988.0_f64);
+
+ check_concise_float(9223372036854775808, 0, 9223372036854775808.0_f64);
+ check_concise_float(9223372036854776832, 0, 9223372036854775808.0_f64);
+ check_concise_float(9223372036854777856, 0, 9223372036854777856.0_f64);
+
+ check_truncated_float(
+ "11417981541647679048466287755595961091061972992",
+ "",
+ 0,
+ 11417981541647679048466287755595961091061972992.0_f64,
+ );
+ check_truncated_float(
+ "11417981541647680316116887983825362587765178368",
+ "",
+ 0,
+ 11417981541647679048466287755595961091061972992.0_f64,
+ );
+ check_truncated_float(
+ "11417981541647681583767488212054764084468383744",
+ "",
+ 0,
+ 11417981541647681583767488212054764084468383744.0_f64,
+ );
+
+ // Round-up, halfway
+ check_concise_float(9007199254740994, 0, 9007199254740994.0_f64);
+ check_concise_float(9007199254740995, 0, 9007199254740996.0_f64);
+ check_concise_float(9007199254740996, 0, 9007199254740996.0_f64);
+
+ check_concise_float(18014398509481988, 0, 18014398509481988.0_f64);
+ check_concise_float(18014398509481990, 0, 18014398509481992.0_f64);
+ check_concise_float(18014398509481992, 0, 18014398509481992.0_f64);
+
+ check_concise_float(9223372036854777856, 0, 9223372036854777856.0_f64);
+ check_concise_float(9223372036854778880, 0, 9223372036854779904.0_f64);
+ check_concise_float(9223372036854779904, 0, 9223372036854779904.0_f64);
+
+ check_truncated_float(
+ "11417981541647681583767488212054764084468383744",
+ "",
+ 0,
+ 11417981541647681583767488212054764084468383744.0_f64,
+ );
+ check_truncated_float(
+ "11417981541647682851418088440284165581171589120",
+ "",
+ 0,
+ 11417981541647684119068688668513567077874794496.0_f64,
+ );
+ check_truncated_float(
+ "11417981541647684119068688668513567077874794496",
+ "",
+ 0,
+ 11417981541647684119068688668513567077874794496.0_f64,
+ );
+
+ // Round-up, above halfway
+ check_concise_float(9223372036854776833, 0, 9223372036854777856.0_f64);
+ check_truncated_float(
+ "11417981541647680316116887983825362587765178369",
+ "",
+ 0,
+ 11417981541647681583767488212054764084468383744.0_f64,
+ );
+
+ // Rounding error
+ // Adapted from failures in strtod.
+ check_concise_float(22250738585072014, -324, 2.2250738585072014e-308_f64);
+ check_truncated_float("2", "2250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350879141491589130396211068700864386945946455276572074078206217433799881410632673292535522868813721490129811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050510806099407302629371289589500035837999672072543043602840788957717961509455167482434710307026091446215722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704275671864433837704860378616227717385456230658746790140867233276367187499", -308, 2.225073858507201e-308_f64);
+ check_truncated_float("2", "22507385850720113605740979670913197593481954635164564802342610972482222202107694551652952390813508791414915891303962110687008643869459464552765720740782062174337998814106326732925355228688137214901298112245145188984905722230728525513315575501591439747639798341180199932396254828901710708185069063066665599493827577257201576306269066333264756530000924588831643303777979186961204949739037782970490505108060994073026293712895895000358379996720725430436028407889577179615094551674824347103070260914462157228988025818254518032570701886087211312807951223342628836862232150377566662250398253433597456888442390026549819838548794829220689472168983109969836584681402285424333066033985088644580400103493397042756718644338377048603786162277173854562306587467901408672332763671875", -308, 2.2250738585072014e-308_f64);
+ check_truncated_float("2", "2250738585072011360574097967091319759348195463516456480234261097248222220210769455165295239081350879141491589130396211068700864386945946455276572074078206217433799881410632673292535522868813721490129811224514518898490572223072852551331557550159143974763979834118019993239625482890171070818506906306666559949382757725720157630626906633326475653000092458883164330377797918696120494973903778297049050510806099407302629371289589500035837999672072543043602840788957717961509455167482434710307026091446215722898802581825451803257070188608721131280795122334262883686223215037756666225039825343359745688844239002654981983854879482922068947216898310996983658468140228542433306603398508864458040010349339704275671864433837704860378616227717385456230658746790140867233276367187501", -308, 2.2250738585072014e-308_f64);
+ check_truncated_float("179769313486231580793728971405303415079934132710037826936173778980444968292764750946649017977587207096330286416692887910946555547851940402630657488671505820681908902000708383676273854845817711531764475730270069855571366959622842914819860834936475292719074168444365510704342711559699508093042880177904174497791", "9999999999999999999999999999999999999999999999999999999999999999999999", 0, 1.7976931348623157e+308_f64);
+ check_truncated_float("7", "4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984374999", -324, 5.0e-324_f64);
+ check_truncated_float("7", "4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375", -324, 1.0e-323_f64);
+ check_truncated_float("7", "4109846876186981626485318930233205854758970392148714663837852375101326090531312779794975454245398856969484704316857659638998506553390969459816219401617281718945106978546710679176872575177347315553307795408549809608457500958111373034747658096871009590975442271004757307809711118935784838675653998783503015228055934046593739791790738723868299395818481660169122019456499931289798411362062484498678713572180352209017023903285791732520220528974020802906854021606612375549983402671300035812486479041385743401875520901590172592547146296175134159774938718574737870961645638908718119841271673056017045493004705269590165763776884908267986972573366521765567941072508764337560846003984904972149117463085539556354188641513168478436313080237596295773983001708984375001", -324, 1.0e-323_f64);
+ check_truncated_float("", "0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000024703282292062327208828439643411068618252990130716238221279284125033775363510437593264991818081799618989828234772285886546332835517796989819938739800539093906315035659515570226392290858392449105184435931802849936536152500319370457678249219365623669863658480757001585769269903706311928279558551332927834338409351978015531246597263579574622766465272827220056374006485499977096599470454020828166226237857393450736339007967761930577506740176324673600968951340535537458516661134223766678604162159680461914467291840300530057530849048765391711386591646239524912623653881879636239373280423891018672348497668235089863388587925628302755995657524455507255189313690836254779186948667994968324049705821028513185451396213837722826145437693412532098591327667236328125", 0, 0.0_f64);
+
+ // Rounding error
+ // Adapted from:
+ // https://www.exploringbinary.com/how-glibc-strtod-works/
+ check_truncated_float("", "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375", 0, 2.2250738585072011e-308_f64);
+
+ // Rounding error
+ // Adapted from test-parse-random failures.
+ check_concise_float(1009, -31, 1.009e-28_f64);
+ check_concise_float(18294, 304, f64::INFINITY);
+
+ // Rounding error
+ // Adapted from a @dangrabcad's issue #20.
+ check_concise_float(7689539722041643, 149, 7.689539722041643e164_f64);
+ check_truncated_float("768953972204164300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "", 0, 7.689539722041643e164_f64);
+ check_truncated_float("768953972204164300000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 7.689539722041643e164_f64);
+
+ // Check other cases similar to @dangrabcad's issue #20.
+ check_truncated_float("9223372036854776833", "0", 0, 9223372036854777856.0_f64);
+ check_truncated_float(
+ "11417981541647680316116887983825362587765178369",
+ "0",
+ 0,
+ 11417981541647681583767488212054764084468383744.0_f64,
+ );
+ check_concise_float(90071992547409950, -1, 9007199254740996.0_f64);
+ check_concise_float(180143985094819900, -1, 18014398509481992.0_f64);
+ check_truncated_float("9223372036854778880", "0", 0, 9223372036854779904.0_f64);
+ check_truncated_float(
+ "11417981541647682851418088440284165581171589120",
+ "0",
+ 0,
+ 11417981541647684119068688668513567077874794496.0_f64,
+ );
+
+ // Check other cases ostensibly identified via proptest.
+ check_truncated_float("71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 71610528364411830000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0_f64);
+ check_truncated_float("126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 126769393745745060000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0_f64);
+ check_truncated_float("38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000", "0", 0, 38652960461239320000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0_f64);
+}
diff --git a/third_party/rust/serde_json/tests/lexical/rounding.rs b/third_party/rust/serde_json/tests/lexical/rounding.rs
new file mode 100644
index 0000000000..7ea17716c3
--- /dev/null
+++ b/third_party/rust/serde_json/tests/lexical/rounding.rs
@@ -0,0 +1,316 @@
+// Adapted from https://github.com/Alexhuszagh/rust-lexical.
+
+use crate::lexical::float::ExtendedFloat;
+use crate::lexical::num::Float;
+use crate::lexical::rounding::*;
+
+// MASKS
+
+#[test]
+fn lower_n_mask_test() {
+ assert_eq!(lower_n_mask(0u64), 0b0);
+ assert_eq!(lower_n_mask(1u64), 0b1);
+ assert_eq!(lower_n_mask(2u64), 0b11);
+ assert_eq!(lower_n_mask(10u64), 0b1111111111);
+ assert_eq!(lower_n_mask(32u64), 0b11111111111111111111111111111111);
+}
+
+#[test]
+fn lower_n_halfway_test() {
+ assert_eq!(lower_n_halfway(0u64), 0b0);
+ assert_eq!(lower_n_halfway(1u64), 0b1);
+ assert_eq!(lower_n_halfway(2u64), 0b10);
+ assert_eq!(lower_n_halfway(10u64), 0b1000000000);
+ assert_eq!(lower_n_halfway(32u64), 0b10000000000000000000000000000000);
+}
+
+#[test]
+fn nth_bit_test() {
+ assert_eq!(nth_bit(0u64), 0b1);
+ assert_eq!(nth_bit(1u64), 0b10);
+ assert_eq!(nth_bit(2u64), 0b100);
+ assert_eq!(nth_bit(10u64), 0b10000000000);
+ assert_eq!(nth_bit(31u64), 0b10000000000000000000000000000000);
+}
+
+#[test]
+fn internal_n_mask_test() {
+ assert_eq!(internal_n_mask(1u64, 0u64), 0b0);
+ assert_eq!(internal_n_mask(1u64, 1u64), 0b1);
+ assert_eq!(internal_n_mask(2u64, 1u64), 0b10);
+ assert_eq!(internal_n_mask(4u64, 2u64), 0b1100);
+ assert_eq!(internal_n_mask(10u64, 2u64), 0b1100000000);
+ assert_eq!(internal_n_mask(10u64, 4u64), 0b1111000000);
+ assert_eq!(
+ internal_n_mask(32u64, 4u64),
+ 0b11110000000000000000000000000000
+ );
+}
+
+// NEAREST ROUNDING
+
+#[test]
+fn round_nearest_test() {
+ // Check exactly halfway (b'1100000')
+ let mut fp = ExtendedFloat { mant: 0x60, exp: 0 };
+ let (above, halfway) = round_nearest(&mut fp, 6);
+ assert!(!above);
+ assert!(halfway);
+ assert_eq!(fp.mant, 1);
+
+ // Check above halfway (b'1100001')
+ let mut fp = ExtendedFloat { mant: 0x61, exp: 0 };
+ let (above, halfway) = round_nearest(&mut fp, 6);
+ assert!(above);
+ assert!(!halfway);
+ assert_eq!(fp.mant, 1);
+
+ // Check below halfway (b'1011111')
+ let mut fp = ExtendedFloat { mant: 0x5F, exp: 0 };
+ let (above, halfway) = round_nearest(&mut fp, 6);
+ assert!(!above);
+ assert!(!halfway);
+ assert_eq!(fp.mant, 1);
+}
+
+// DIRECTED ROUNDING
+
+#[test]
+fn round_downward_test() {
+ // b0000000
+ let mut fp = ExtendedFloat { mant: 0x00, exp: 0 };
+ round_downward(&mut fp, 6);
+ assert_eq!(fp.mant, 0);
+
+ // b1000000
+ let mut fp = ExtendedFloat { mant: 0x40, exp: 0 };
+ round_downward(&mut fp, 6);
+ assert_eq!(fp.mant, 1);
+
+ // b1100000
+ let mut fp = ExtendedFloat { mant: 0x60, exp: 0 };
+ round_downward(&mut fp, 6);
+ assert_eq!(fp.mant, 1);
+
+ // b1110000
+ let mut fp = ExtendedFloat { mant: 0x70, exp: 0 };
+ round_downward(&mut fp, 6);
+ assert_eq!(fp.mant, 1);
+}
+
+#[test]
+fn round_nearest_tie_even_test() {
+ // Check round-up, halfway
+ let mut fp = ExtendedFloat { mant: 0x60, exp: 0 };
+ round_nearest_tie_even(&mut fp, 6);
+ assert_eq!(fp.mant, 2);
+
+ // Check round-down, halfway
+ let mut fp = ExtendedFloat { mant: 0x20, exp: 0 };
+ round_nearest_tie_even(&mut fp, 6);
+ assert_eq!(fp.mant, 0);
+
+ // Check round-up, above halfway
+ let mut fp = ExtendedFloat { mant: 0x61, exp: 0 };
+ round_nearest_tie_even(&mut fp, 6);
+ assert_eq!(fp.mant, 2);
+
+ let mut fp = ExtendedFloat { mant: 0x21, exp: 0 };
+ round_nearest_tie_even(&mut fp, 6);
+ assert_eq!(fp.mant, 1);
+
+ // Check round-down, below halfway
+ let mut fp = ExtendedFloat { mant: 0x5F, exp: 0 };
+ round_nearest_tie_even(&mut fp, 6);
+ assert_eq!(fp.mant, 1);
+
+ let mut fp = ExtendedFloat { mant: 0x1F, exp: 0 };
+ round_nearest_tie_even(&mut fp, 6);
+ assert_eq!(fp.mant, 0);
+}
+
+// HIGH-LEVEL
+
+#[test]
+fn round_to_float_test() {
+ // Denormal
+ let mut fp = ExtendedFloat {
+ mant: 1 << 63,
+ exp: f64::DENORMAL_EXPONENT - 15,
+ };
+ round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, 1 << 48);
+ assert_eq!(fp.exp, f64::DENORMAL_EXPONENT);
+
+ // Halfway, round-down (b'1000000000000000000000000000000000000000000000000000010000000000')
+ let mut fp = ExtendedFloat {
+ mant: 0x8000000000000400,
+ exp: -63,
+ };
+ round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, 1 << 52);
+ assert_eq!(fp.exp, -52);
+
+ // Halfway, round-up (b'1000000000000000000000000000000000000000000000000000110000000000')
+ let mut fp = ExtendedFloat {
+ mant: 0x8000000000000C00,
+ exp: -63,
+ };
+ round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, (1 << 52) + 2);
+ assert_eq!(fp.exp, -52);
+
+ // Above halfway
+ let mut fp = ExtendedFloat {
+ mant: 0x8000000000000401,
+ exp: -63,
+ };
+ round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, (1 << 52) + 1);
+ assert_eq!(fp.exp, -52);
+
+ let mut fp = ExtendedFloat {
+ mant: 0x8000000000000C01,
+ exp: -63,
+ };
+ round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, (1 << 52) + 2);
+ assert_eq!(fp.exp, -52);
+
+ // Below halfway
+ let mut fp = ExtendedFloat {
+ mant: 0x80000000000003FF,
+ exp: -63,
+ };
+ round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, 1 << 52);
+ assert_eq!(fp.exp, -52);
+
+ let mut fp = ExtendedFloat {
+ mant: 0x8000000000000BFF,
+ exp: -63,
+ };
+ round_to_float::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, (1 << 52) + 1);
+ assert_eq!(fp.exp, -52);
+}
+
+#[test]
+fn avoid_overflow_test() {
+ // Avoid overflow, fails by 1
+ let mut fp = ExtendedFloat {
+ mant: 0xFFFFFFFFFFFF,
+ exp: f64::MAX_EXPONENT + 5,
+ };
+ avoid_overflow::<f64>(&mut fp);
+ assert_eq!(fp.mant, 0xFFFFFFFFFFFF);
+ assert_eq!(fp.exp, f64::MAX_EXPONENT + 5);
+
+ // Avoid overflow, succeeds
+ let mut fp = ExtendedFloat {
+ mant: 0xFFFFFFFFFFFF,
+ exp: f64::MAX_EXPONENT + 4,
+ };
+ avoid_overflow::<f64>(&mut fp);
+ assert_eq!(fp.mant, 0x1FFFFFFFFFFFE0);
+ assert_eq!(fp.exp, f64::MAX_EXPONENT - 1);
+}
+
+#[test]
+fn round_to_native_test() {
+ // Overflow
+ let mut fp = ExtendedFloat {
+ mant: 0xFFFFFFFFFFFF,
+ exp: f64::MAX_EXPONENT + 4,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, 0x1FFFFFFFFFFFE0);
+ assert_eq!(fp.exp, f64::MAX_EXPONENT - 1);
+
+ // Need denormal
+ let mut fp = ExtendedFloat {
+ mant: 1,
+ exp: f64::DENORMAL_EXPONENT + 48,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, 1 << 48);
+ assert_eq!(fp.exp, f64::DENORMAL_EXPONENT);
+
+ // Halfway, round-down (b'10000000000000000000000000000000000000000000000000000100000')
+ let mut fp = ExtendedFloat {
+ mant: 0x400000000000020,
+ exp: -58,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, 1 << 52);
+ assert_eq!(fp.exp, -52);
+
+ // Halfway, round-up (b'10000000000000000000000000000000000000000000000000001100000')
+ let mut fp = ExtendedFloat {
+ mant: 0x400000000000060,
+ exp: -58,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, (1 << 52) + 2);
+ assert_eq!(fp.exp, -52);
+
+ // Above halfway
+ let mut fp = ExtendedFloat {
+ mant: 0x400000000000021,
+ exp: -58,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, (1 << 52) + 1);
+ assert_eq!(fp.exp, -52);
+
+ let mut fp = ExtendedFloat {
+ mant: 0x400000000000061,
+ exp: -58,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, (1 << 52) + 2);
+ assert_eq!(fp.exp, -52);
+
+ // Below halfway
+ let mut fp = ExtendedFloat {
+ mant: 0x40000000000001F,
+ exp: -58,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, 1 << 52);
+ assert_eq!(fp.exp, -52);
+
+ let mut fp = ExtendedFloat {
+ mant: 0x40000000000005F,
+ exp: -58,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, (1 << 52) + 1);
+ assert_eq!(fp.exp, -52);
+
+ // Underflow
+ // Adapted from failures in strtod.
+ let mut fp = ExtendedFloat {
+ exp: -1139,
+ mant: 18446744073709550712,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, 0);
+ assert_eq!(fp.exp, 0);
+
+ let mut fp = ExtendedFloat {
+ exp: -1139,
+ mant: 18446744073709551460,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, 0);
+ assert_eq!(fp.exp, 0);
+
+ let mut fp = ExtendedFloat {
+ exp: -1138,
+ mant: 9223372036854776103,
+ };
+ round_to_native::<f64, _>(&mut fp, round_nearest_tie_even);
+ assert_eq!(fp.mant, 1);
+ assert_eq!(fp.exp, -1074);
+}
diff --git a/third_party/rust/serde_json/tests/macros/mod.rs b/third_party/rust/serde_json/tests/macros/mod.rs
new file mode 100644
index 0000000000..aaf820f074
--- /dev/null
+++ b/third_party/rust/serde_json/tests/macros/mod.rs
@@ -0,0 +1,61 @@
+#![allow(unused_macro_rules)]
+
+macro_rules! json_str {
+ ([]) => {
+ "[]"
+ };
+ ([ $e0:tt $(, $e:tt)* $(,)? ]) => {
+ concat!("[",
+ json_str!($e0),
+ $(",", json_str!($e),)*
+ "]")
+ };
+ ({}) => {
+ "{}"
+ };
+ ({ $k0:tt : $v0:tt $(, $k:tt : $v:tt)* $(,)? }) => {
+ concat!("{",
+ stringify!($k0), ":", json_str!($v0),
+ $(",", stringify!($k), ":", json_str!($v),)*
+ "}")
+ };
+ (($other:tt)) => {
+ $other
+ };
+ ($other:tt) => {
+ stringify!($other)
+ };
+}
+
+macro_rules! pretty_str {
+ ($json:tt) => {
+ pretty_str_impl!("", $json)
+ };
+}
+
+macro_rules! pretty_str_impl {
+ ($indent:expr, []) => {
+ "[]"
+ };
+ ($indent:expr, [ $e0:tt $(, $e:tt)* $(,)? ]) => {
+ concat!("[\n ",
+ $indent, pretty_str_impl!(concat!(" ", $indent), $e0),
+ $(",\n ", $indent, pretty_str_impl!(concat!(" ", $indent), $e),)*
+ "\n", $indent, "]")
+ };
+ ($indent:expr, {}) => {
+ "{}"
+ };
+ ($indent:expr, { $k0:tt : $v0:tt $(, $k:tt : $v:tt)* $(,)? }) => {
+ concat!("{\n ",
+ $indent, stringify!($k0), ": ", pretty_str_impl!(concat!(" ", $indent), $v0),
+ $(",\n ", $indent, stringify!($k), ": ", pretty_str_impl!(concat!(" ", $indent), $v),)*
+ "\n", $indent, "}")
+ };
+ ($indent:expr, ($other:tt)) => {
+ $other
+ };
+ ($indent:expr, $other:tt) => {
+ stringify!($other)
+ };
+}
diff --git a/third_party/rust/serde_json/tests/map.rs b/third_party/rust/serde_json/tests/map.rs
new file mode 100644
index 0000000000..ae01969561
--- /dev/null
+++ b/third_party/rust/serde_json/tests/map.rs
@@ -0,0 +1,47 @@
+use serde_json::{from_str, Map, Value};
+
+#[test]
+fn test_preserve_order() {
+ // Sorted order
+ #[cfg(not(feature = "preserve_order"))]
+ const EXPECTED: &[&str] = &["a", "b", "c"];
+
+ // Insertion order
+ #[cfg(feature = "preserve_order")]
+ const EXPECTED: &[&str] = &["b", "a", "c"];
+
+ let v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap();
+ let keys: Vec<_> = v.as_object().unwrap().keys().collect();
+ assert_eq!(keys, EXPECTED);
+}
+
+#[test]
+fn test_append() {
+ // Sorted order
+ #[cfg(not(feature = "preserve_order"))]
+ const EXPECTED: &[&str] = &["a", "b", "c"];
+
+ // Insertion order
+ #[cfg(feature = "preserve_order")]
+ const EXPECTED: &[&str] = &["b", "a", "c"];
+
+ let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap();
+ let val = v.as_object_mut().unwrap();
+ let mut m = Map::new();
+ m.append(val);
+ let keys: Vec<_> = m.keys().collect();
+
+ assert_eq!(keys, EXPECTED);
+ assert!(val.is_empty());
+}
+
+#[cfg(not(no_btreemap_retain))]
+#[test]
+fn test_retain() {
+ let mut v: Value = from_str(r#"{"b":null,"a":null,"c":null}"#).unwrap();
+ let val = v.as_object_mut().unwrap();
+ val.retain(|k, _| k.as_str() != "b");
+
+ let keys: Vec<_> = val.keys().collect();
+ assert_eq!(keys, &["a", "c"]);
+}
diff --git a/third_party/rust/serde_json/tests/regression.rs b/third_party/rust/serde_json/tests/regression.rs
new file mode 100644
index 0000000000..fb2b25c89b
--- /dev/null
+++ b/third_party/rust/serde_json/tests/regression.rs
@@ -0,0 +1,3 @@
+mod regression {
+ automod::dir!("tests/regression");
+}
diff --git a/third_party/rust/serde_json/tests/regression/issue520.rs b/third_party/rust/serde_json/tests/regression/issue520.rs
new file mode 100644
index 0000000000..9ed367731b
--- /dev/null
+++ b/third_party/rust/serde_json/tests/regression/issue520.rs
@@ -0,0 +1,20 @@
+#![allow(clippy::float_cmp)]
+
+use serde_derive::{Serialize, Deserialize};
+
+#[derive(Serialize, Deserialize, Debug)]
+#[serde(tag = "type", content = "data")]
+enum E {
+ Float(f32),
+}
+
+#[test]
+fn test() {
+ let e = E::Float(159.1);
+ let v = serde_json::to_value(e).unwrap();
+ let e = serde_json::from_value::<E>(v).unwrap();
+
+ match e {
+ E::Float(f) => assert_eq!(f, 159.1),
+ }
+}
diff --git a/third_party/rust/serde_json/tests/regression/issue795.rs b/third_party/rust/serde_json/tests/regression/issue795.rs
new file mode 100644
index 0000000000..bb82852c54
--- /dev/null
+++ b/third_party/rust/serde_json/tests/regression/issue795.rs
@@ -0,0 +1,59 @@
+#![allow(clippy::assertions_on_result_states)]
+
+use serde::de::{
+ Deserialize, Deserializer, EnumAccess, IgnoredAny, MapAccess, VariantAccess, Visitor,
+};
+use serde_json::json;
+use std::fmt;
+
+#[derive(Debug)]
+pub enum Enum {
+ Variant { x: u8 },
+}
+
+impl<'de> Deserialize<'de> for Enum {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct EnumVisitor;
+
+ impl<'de> Visitor<'de> for EnumVisitor {
+ type Value = Enum;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("enum Enum")
+ }
+
+ fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
+ where
+ A: EnumAccess<'de>,
+ {
+ let (IgnoredAny, variant) = data.variant()?;
+ variant.struct_variant(&["x"], self)
+ }
+
+ fn visit_map<A>(self, mut data: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let mut x = 0;
+ if let Some((IgnoredAny, value)) = data.next_entry()? {
+ x = value;
+ }
+ Ok(Enum::Variant { x })
+ }
+ }
+
+ deserializer.deserialize_enum("Enum", &["Variant"], EnumVisitor)
+ }
+}
+
+#[test]
+fn test() {
+ let s = r#" {"Variant":{"x":0,"y":0}} "#;
+ assert!(serde_json::from_str::<Enum>(s).is_err());
+
+ let j = json!({"Variant":{"x":0,"y":0}});
+ assert!(serde_json::from_value::<Enum>(j).is_err());
+}
diff --git a/third_party/rust/serde_json/tests/regression/issue845.rs b/third_party/rust/serde_json/tests/regression/issue845.rs
new file mode 100644
index 0000000000..56037ae669
--- /dev/null
+++ b/third_party/rust/serde_json/tests/regression/issue845.rs
@@ -0,0 +1,74 @@
+#![allow(clippy::trait_duplication_in_bounds)] // https://github.com/rust-lang/rust-clippy/issues/8757
+
+use serde::{Deserialize, Deserializer};
+use std::convert::TryFrom;
+use std::fmt::{self, Display};
+use std::marker::PhantomData;
+use std::str::FromStr;
+
+pub struct NumberVisitor<T> {
+ marker: PhantomData<T>,
+}
+
+impl<'de, T> serde::de::Visitor<'de> for NumberVisitor<T>
+where
+ T: TryFrom<u64> + TryFrom<i64> + FromStr,
+ <T as TryFrom<u64>>::Error: Display,
+ <T as TryFrom<i64>>::Error: Display,
+ <T as FromStr>::Err: Display,
+{
+ type Value = T;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("an integer or string")
+ }
+
+ fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
+ where
+ E: serde::de::Error,
+ {
+ T::try_from(v).map_err(serde::de::Error::custom)
+ }
+
+ fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
+ where
+ E: serde::de::Error,
+ {
+ T::try_from(v).map_err(serde::de::Error::custom)
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: serde::de::Error,
+ {
+ v.parse().map_err(serde::de::Error::custom)
+ }
+}
+
+fn deserialize_integer_or_string<'de, D, T>(deserializer: D) -> Result<T, D::Error>
+where
+ D: Deserializer<'de>,
+ T: TryFrom<u64> + TryFrom<i64> + FromStr,
+ <T as TryFrom<u64>>::Error: Display,
+ <T as TryFrom<i64>>::Error: Display,
+ <T as FromStr>::Err: Display,
+{
+ deserializer.deserialize_any(NumberVisitor {
+ marker: PhantomData,
+ })
+}
+
+#[derive(Deserialize, Debug)]
+pub struct Struct {
+ #[serde(deserialize_with = "deserialize_integer_or_string")]
+ pub i: i64,
+}
+
+#[test]
+fn test() {
+ let j = r#" {"i":100} "#;
+ println!("{:?}", serde_json::from_str::<Struct>(j).unwrap());
+
+ let j = r#" {"i":"100"} "#;
+ println!("{:?}", serde_json::from_str::<Struct>(j).unwrap());
+}
diff --git a/third_party/rust/serde_json/tests/regression/issue953.rs b/third_party/rust/serde_json/tests/regression/issue953.rs
new file mode 100644
index 0000000000..771aa5287c
--- /dev/null
+++ b/third_party/rust/serde_json/tests/regression/issue953.rs
@@ -0,0 +1,9 @@
+use serde_json::Value;
+
+#[test]
+fn test() {
+ let x1 = serde_json::from_str::<Value>("18446744073709551615.");
+ assert!(x1.is_err());
+ let x2 = serde_json::from_str::<Value>("18446744073709551616.");
+ assert!(x2.is_err());
+}
diff --git a/third_party/rust/serde_json/tests/stream.rs b/third_party/rust/serde_json/tests/stream.rs
new file mode 100644
index 0000000000..ec6b9e3d02
--- /dev/null
+++ b/third_party/rust/serde_json/tests/stream.rs
@@ -0,0 +1,183 @@
+#![cfg(not(feature = "preserve_order"))]
+#![allow(clippy::assertions_on_result_states)]
+
+use serde_json::{json, Deserializer, Value};
+
+// Rustfmt issue https://github.com/rust-lang-nursery/rustfmt/issues/2740
+#[rustfmt::skip]
+macro_rules! test_stream {
+ ($data:expr, $ty:ty, |$stream:ident| $test:block) => {
+ {
+ let de = Deserializer::from_str($data);
+ let mut $stream = de.into_iter::<$ty>();
+ assert_eq!($stream.byte_offset(), 0);
+ $test
+ }
+ {
+ let de = Deserializer::from_slice($data.as_bytes());
+ let mut $stream = de.into_iter::<$ty>();
+ assert_eq!($stream.byte_offset(), 0);
+ $test
+ }
+ {
+ let mut bytes = $data.as_bytes();
+ let de = Deserializer::from_reader(&mut bytes);
+ let mut $stream = de.into_iter::<$ty>();
+ assert_eq!($stream.byte_offset(), 0);
+ $test
+ }
+ };
+}
+
+#[test]
+fn test_json_stream_newlines() {
+ let data = "{\"x\":39} {\"x\":40}{\"x\":41}\n{\"x\":42}";
+
+ test_stream!(data, Value, |stream| {
+ assert_eq!(stream.next().unwrap().unwrap()["x"], 39);
+ assert_eq!(stream.byte_offset(), 8);
+
+ assert_eq!(stream.next().unwrap().unwrap()["x"], 40);
+ assert_eq!(stream.byte_offset(), 17);
+
+ assert_eq!(stream.next().unwrap().unwrap()["x"], 41);
+ assert_eq!(stream.byte_offset(), 25);
+
+ assert_eq!(stream.next().unwrap().unwrap()["x"], 42);
+ assert_eq!(stream.byte_offset(), 34);
+
+ assert!(stream.next().is_none());
+ assert_eq!(stream.byte_offset(), 34);
+ });
+}
+
+#[test]
+fn test_json_stream_trailing_whitespaces() {
+ let data = "{\"x\":42} \t\n";
+
+ test_stream!(data, Value, |stream| {
+ assert_eq!(stream.next().unwrap().unwrap()["x"], 42);
+ assert_eq!(stream.byte_offset(), 8);
+
+ assert!(stream.next().is_none());
+ assert_eq!(stream.byte_offset(), 11);
+ });
+}
+
+#[test]
+fn test_json_stream_truncated() {
+ let data = "{\"x\":40}\n{\"x\":";
+
+ test_stream!(data, Value, |stream| {
+ assert_eq!(stream.next().unwrap().unwrap()["x"], 40);
+ assert_eq!(stream.byte_offset(), 8);
+
+ assert!(stream.next().unwrap().unwrap_err().is_eof());
+ assert_eq!(stream.byte_offset(), 9);
+ });
+}
+
+#[test]
+fn test_json_stream_truncated_decimal() {
+ let data = "{\"x\":4.";
+
+ test_stream!(data, Value, |stream| {
+ assert!(stream.next().unwrap().unwrap_err().is_eof());
+ assert_eq!(stream.byte_offset(), 0);
+ });
+}
+
+#[test]
+fn test_json_stream_truncated_negative() {
+ let data = "{\"x\":-";
+
+ test_stream!(data, Value, |stream| {
+ assert!(stream.next().unwrap().unwrap_err().is_eof());
+ assert_eq!(stream.byte_offset(), 0);
+ });
+}
+
+#[test]
+fn test_json_stream_truncated_exponent() {
+ let data = "{\"x\":4e";
+
+ test_stream!(data, Value, |stream| {
+ assert!(stream.next().unwrap().unwrap_err().is_eof());
+ assert_eq!(stream.byte_offset(), 0);
+ });
+}
+
+#[test]
+fn test_json_stream_empty() {
+ let data = "";
+
+ test_stream!(data, Value, |stream| {
+ assert!(stream.next().is_none());
+ assert_eq!(stream.byte_offset(), 0);
+ });
+}
+
+#[test]
+fn test_json_stream_primitive() {
+ let data = "{} true{}1[]\nfalse\"hey\"2 ";
+
+ test_stream!(data, Value, |stream| {
+ assert_eq!(stream.next().unwrap().unwrap(), json!({}));
+ assert_eq!(stream.byte_offset(), 2);
+
+ assert_eq!(stream.next().unwrap().unwrap(), true);
+ assert_eq!(stream.byte_offset(), 7);
+
+ assert_eq!(stream.next().unwrap().unwrap(), json!({}));
+ assert_eq!(stream.byte_offset(), 9);
+
+ assert_eq!(stream.next().unwrap().unwrap(), 1);
+ assert_eq!(stream.byte_offset(), 10);
+
+ assert_eq!(stream.next().unwrap().unwrap(), json!([]));
+ assert_eq!(stream.byte_offset(), 12);
+
+ assert_eq!(stream.next().unwrap().unwrap(), false);
+ assert_eq!(stream.byte_offset(), 18);
+
+ assert_eq!(stream.next().unwrap().unwrap(), "hey");
+ assert_eq!(stream.byte_offset(), 23);
+
+ assert_eq!(stream.next().unwrap().unwrap(), 2);
+ assert_eq!(stream.byte_offset(), 24);
+
+ assert!(stream.next().is_none());
+ assert_eq!(stream.byte_offset(), 25);
+ });
+}
+
+#[test]
+fn test_json_stream_invalid_literal() {
+ let data = "truefalse";
+
+ test_stream!(data, Value, |stream| {
+ let second = stream.next().unwrap().unwrap_err();
+ assert_eq!(second.to_string(), "trailing characters at line 1 column 5");
+ });
+}
+
+#[test]
+fn test_json_stream_invalid_number() {
+ let data = "1true";
+
+ test_stream!(data, Value, |stream| {
+ let second = stream.next().unwrap().unwrap_err();
+ assert_eq!(second.to_string(), "trailing characters at line 1 column 2");
+ });
+}
+
+#[test]
+fn test_error() {
+ let data = "true wrong false";
+
+ test_stream!(data, Value, |stream| {
+ assert_eq!(stream.next().unwrap().unwrap(), true);
+ assert!(stream.next().unwrap().is_err());
+ assert!(stream.next().is_none());
+ });
+}
diff --git a/third_party/rust/serde_json/tests/test.rs b/third_party/rust/serde_json/tests/test.rs
new file mode 100644
index 0000000000..f62a545e7f
--- /dev/null
+++ b/third_party/rust/serde_json/tests/test.rs
@@ -0,0 +1,2408 @@
+#![cfg(not(feature = "preserve_order"))]
+#![allow(
+ clippy::assertions_on_result_states,
+ clippy::cast_precision_loss,
+ clippy::derive_partial_eq_without_eq,
+ clippy::excessive_precision,
+ clippy::float_cmp,
+ clippy::items_after_statements,
+ clippy::shadow_unrelated,
+ clippy::too_many_lines,
+ clippy::unreadable_literal,
+ clippy::unseparated_literal_suffix,
+ clippy::vec_init_then_push,
+ clippy::zero_sized_map_values
+)]
+#![cfg_attr(feature = "trace-macros", feature(trace_macros))]
+#[cfg(feature = "trace-macros")]
+trace_macros!(true);
+
+#[macro_use]
+mod macros;
+
+#[cfg(feature = "raw_value")]
+use ref_cast::RefCast;
+use serde::de::{self, IgnoredAny, IntoDeserializer};
+use serde::ser::{self, SerializeMap, SerializeSeq, Serializer};
+use serde::{Deserialize, Serialize};
+use serde_bytes::{ByteBuf, Bytes};
+#[cfg(feature = "raw_value")]
+use serde_json::value::RawValue;
+use serde_json::{
+ from_reader, from_slice, from_str, from_value, json, to_string, to_string_pretty, to_value,
+ to_vec, Deserializer, Number, Value,
+};
+use std::collections::hash_map::DefaultHasher;
+use std::collections::BTreeMap;
+#[cfg(feature = "raw_value")]
+use std::collections::HashMap;
+use std::fmt::{self, Debug};
+use std::hash::{Hash, Hasher};
+use std::io;
+use std::iter;
+use std::marker::PhantomData;
+use std::mem;
+use std::str::FromStr;
+use std::string::ToString;
+use std::{f32, f64};
+use std::{i16, i32, i64, i8};
+use std::{u16, u32, u64, u8};
+
+macro_rules! treemap {
+ () => {
+ BTreeMap::new()
+ };
+ ($($k:expr => $v:expr),+) => {
+ {
+ let mut m = BTreeMap::new();
+ $(
+ m.insert($k, $v);
+ )+
+ m
+ }
+ };
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+#[serde(deny_unknown_fields)]
+enum Animal {
+ Dog,
+ Frog(String, Vec<isize>),
+ Cat { age: usize, name: String },
+ AntHive(Vec<String>),
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+struct Inner {
+ a: (),
+ b: usize,
+ c: Vec<String>,
+}
+
+#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+struct Outer {
+ inner: Vec<Inner>,
+}
+
+fn test_encode_ok<T>(errors: &[(T, &str)])
+where
+ T: PartialEq + Debug + ser::Serialize,
+{
+ for &(ref value, out) in errors {
+ let out = out.to_string();
+
+ let s = to_string(value).unwrap();
+ assert_eq!(s, out);
+
+ let v = to_value(value).unwrap();
+ let s = to_string(&v).unwrap();
+ assert_eq!(s, out);
+ }
+}
+
+fn test_pretty_encode_ok<T>(errors: &[(T, &str)])
+where
+ T: PartialEq + Debug + ser::Serialize,
+{
+ for &(ref value, out) in errors {
+ let out = out.to_string();
+
+ let s = to_string_pretty(value).unwrap();
+ assert_eq!(s, out);
+
+ let v = to_value(value).unwrap();
+ let s = to_string_pretty(&v).unwrap();
+ assert_eq!(s, out);
+ }
+}
+
+#[test]
+fn test_write_null() {
+ let tests = &[((), "null")];
+ test_encode_ok(tests);
+ test_pretty_encode_ok(tests);
+}
+
+#[test]
+fn test_write_u64() {
+ let tests = &[(3u64, "3"), (u64::MAX, &u64::MAX.to_string())];
+ test_encode_ok(tests);
+ test_pretty_encode_ok(tests);
+}
+
+#[test]
+fn test_write_i64() {
+ let tests = &[
+ (3i64, "3"),
+ (-2i64, "-2"),
+ (-1234i64, "-1234"),
+ (i64::MIN, &i64::MIN.to_string()),
+ ];
+ test_encode_ok(tests);
+ test_pretty_encode_ok(tests);
+}
+
+#[test]
+fn test_write_f64() {
+ let tests = &[
+ (3.0, "3.0"),
+ (3.1, "3.1"),
+ (-1.5, "-1.5"),
+ (0.5, "0.5"),
+ (f64::MIN, "-1.7976931348623157e308"),
+ (f64::MAX, "1.7976931348623157e308"),
+ (f64::EPSILON, "2.220446049250313e-16"),
+ ];
+ test_encode_ok(tests);
+ test_pretty_encode_ok(tests);
+}
+
+#[test]
+fn test_encode_nonfinite_float_yields_null() {
+ let v = to_value(::std::f64::NAN).unwrap();
+ assert!(v.is_null());
+
+ let v = to_value(::std::f64::INFINITY).unwrap();
+ assert!(v.is_null());
+
+ let v = to_value(::std::f32::NAN).unwrap();
+ assert!(v.is_null());
+
+ let v = to_value(::std::f32::INFINITY).unwrap();
+ assert!(v.is_null());
+}
+
+#[test]
+fn test_write_str() {
+ let tests = &[("", "\"\""), ("foo", "\"foo\"")];
+ test_encode_ok(tests);
+ test_pretty_encode_ok(tests);
+}
+
+#[test]
+fn test_write_bool() {
+ let tests = &[(true, "true"), (false, "false")];
+ test_encode_ok(tests);
+ test_pretty_encode_ok(tests);
+}
+
+#[test]
+fn test_write_char() {
+ let tests = &[
+ ('n', "\"n\""),
+ ('"', "\"\\\"\""),
+ ('\\', "\"\\\\\""),
+ ('/', "\"/\""),
+ ('\x08', "\"\\b\""),
+ ('\x0C', "\"\\f\""),
+ ('\n', "\"\\n\""),
+ ('\r', "\"\\r\""),
+ ('\t', "\"\\t\""),
+ ('\x0B', "\"\\u000b\""),
+ ('\u{3A3}', "\"\u{3A3}\""),
+ ];
+ test_encode_ok(tests);
+ test_pretty_encode_ok(tests);
+}
+
+#[test]
+fn test_write_list() {
+ test_encode_ok(&[
+ (vec![], "[]"),
+ (vec![true], "[true]"),
+ (vec![true, false], "[true,false]"),
+ ]);
+
+ test_encode_ok(&[
+ (vec![vec![], vec![], vec![]], "[[],[],[]]"),
+ (vec![vec![1, 2, 3], vec![], vec![]], "[[1,2,3],[],[]]"),
+ (vec![vec![], vec![1, 2, 3], vec![]], "[[],[1,2,3],[]]"),
+ (vec![vec![], vec![], vec![1, 2, 3]], "[[],[],[1,2,3]]"),
+ ]);
+
+ test_pretty_encode_ok(&[
+ (vec![vec![], vec![], vec![]], pretty_str!([[], [], []])),
+ (
+ vec![vec![1, 2, 3], vec![], vec![]],
+ pretty_str!([[1, 2, 3], [], []]),
+ ),
+ (
+ vec![vec![], vec![1, 2, 3], vec![]],
+ pretty_str!([[], [1, 2, 3], []]),
+ ),
+ (
+ vec![vec![], vec![], vec![1, 2, 3]],
+ pretty_str!([[], [], [1, 2, 3]]),
+ ),
+ ]);
+
+ test_pretty_encode_ok(&[
+ (vec![], "[]"),
+ (vec![true], pretty_str!([true])),
+ (vec![true, false], pretty_str!([true, false])),
+ ]);
+
+ let long_test_list = json!([false, null, ["foo\nbar", 3.5]]);
+
+ test_encode_ok(&[(
+ long_test_list.clone(),
+ json_str!([false, null, ["foo\nbar", 3.5]]),
+ )]);
+
+ test_pretty_encode_ok(&[(
+ long_test_list,
+ pretty_str!([false, null, ["foo\nbar", 3.5]]),
+ )]);
+}
+
+#[test]
+fn test_write_object() {
+ test_encode_ok(&[
+ (treemap!(), "{}"),
+ (treemap!("a".to_string() => true), "{\"a\":true}"),
+ (
+ treemap!(
+ "a".to_string() => true,
+ "b".to_string() => false
+ ),
+ "{\"a\":true,\"b\":false}",
+ ),
+ ]);
+
+ test_encode_ok(&[
+ (
+ treemap![
+ "a".to_string() => treemap![],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![]
+ ],
+ "{\"a\":{},\"b\":{},\"c\":{}}",
+ ),
+ (
+ treemap![
+ "a".to_string() => treemap![
+ "a".to_string() => treemap!["a" => vec![1,2,3]],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![]
+ ],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![]
+ ],
+ "{\"a\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"b\":{},\"c\":{}}",
+ ),
+ (
+ treemap![
+ "a".to_string() => treemap![],
+ "b".to_string() => treemap![
+ "a".to_string() => treemap!["a" => vec![1,2,3]],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![]
+ ],
+ "c".to_string() => treemap![]
+ ],
+ "{\"a\":{},\"b\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"c\":{}}",
+ ),
+ (
+ treemap![
+ "a".to_string() => treemap![],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![
+ "a".to_string() => treemap!["a" => vec![1,2,3]],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![]
+ ]
+ ],
+ "{\"a\":{},\"b\":{},\"c\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}}}",
+ ),
+ ]);
+
+ test_encode_ok(&[(treemap!['c' => ()], "{\"c\":null}")]);
+
+ test_pretty_encode_ok(&[
+ (
+ treemap![
+ "a".to_string() => treemap![],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![]
+ ],
+ pretty_str!({
+ "a": {},
+ "b": {},
+ "c": {}
+ }),
+ ),
+ (
+ treemap![
+ "a".to_string() => treemap![
+ "a".to_string() => treemap!["a" => vec![1,2,3]],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![]
+ ],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![]
+ ],
+ pretty_str!({
+ "a": {
+ "a": {
+ "a": [
+ 1,
+ 2,
+ 3
+ ]
+ },
+ "b": {},
+ "c": {}
+ },
+ "b": {},
+ "c": {}
+ }),
+ ),
+ (
+ treemap![
+ "a".to_string() => treemap![],
+ "b".to_string() => treemap![
+ "a".to_string() => treemap!["a" => vec![1,2,3]],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![]
+ ],
+ "c".to_string() => treemap![]
+ ],
+ pretty_str!({
+ "a": {},
+ "b": {
+ "a": {
+ "a": [
+ 1,
+ 2,
+ 3
+ ]
+ },
+ "b": {},
+ "c": {}
+ },
+ "c": {}
+ }),
+ ),
+ (
+ treemap![
+ "a".to_string() => treemap![],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![
+ "a".to_string() => treemap!["a" => vec![1,2,3]],
+ "b".to_string() => treemap![],
+ "c".to_string() => treemap![]
+ ]
+ ],
+ pretty_str!({
+ "a": {},
+ "b": {},
+ "c": {
+ "a": {
+ "a": [
+ 1,
+ 2,
+ 3
+ ]
+ },
+ "b": {},
+ "c": {}
+ }
+ }),
+ ),
+ ]);
+
+ test_pretty_encode_ok(&[
+ (treemap!(), "{}"),
+ (
+ treemap!("a".to_string() => true),
+ pretty_str!({
+ "a": true
+ }),
+ ),
+ (
+ treemap!(
+ "a".to_string() => true,
+ "b".to_string() => false
+ ),
+ pretty_str!( {
+ "a": true,
+ "b": false
+ }),
+ ),
+ ]);
+
+ let complex_obj = json!({
+ "b": [
+ {"c": "\x0c\x1f\r"},
+ {"d": ""}
+ ]
+ });
+
+ test_encode_ok(&[(
+ complex_obj.clone(),
+ json_str!({
+ "b": [
+ {
+ "c": (r#""\f\u001f\r""#)
+ },
+ {
+ "d": ""
+ }
+ ]
+ }),
+ )]);
+
+ test_pretty_encode_ok(&[(
+ complex_obj,
+ pretty_str!({
+ "b": [
+ {
+ "c": (r#""\f\u001f\r""#)
+ },
+ {
+ "d": ""
+ }
+ ]
+ }),
+ )]);
+}
+
+#[test]
+fn test_write_tuple() {
+ test_encode_ok(&[((5,), "[5]")]);
+
+ test_pretty_encode_ok(&[((5,), pretty_str!([5]))]);
+
+ test_encode_ok(&[((5, (6, "abc")), "[5,[6,\"abc\"]]")]);
+
+ test_pretty_encode_ok(&[((5, (6, "abc")), pretty_str!([5, [6, "abc"]]))]);
+}
+
+#[test]
+fn test_write_enum() {
+ test_encode_ok(&[
+ (Animal::Dog, "\"Dog\""),
+ (
+ Animal::Frog("Henry".to_string(), vec![]),
+ "{\"Frog\":[\"Henry\",[]]}",
+ ),
+ (
+ Animal::Frog("Henry".to_string(), vec![349]),
+ "{\"Frog\":[\"Henry\",[349]]}",
+ ),
+ (
+ Animal::Frog("Henry".to_string(), vec![349, 102]),
+ "{\"Frog\":[\"Henry\",[349,102]]}",
+ ),
+ (
+ Animal::Cat {
+ age: 5,
+ name: "Kate".to_string(),
+ },
+ "{\"Cat\":{\"age\":5,\"name\":\"Kate\"}}",
+ ),
+ (
+ Animal::AntHive(vec!["Bob".to_string(), "Stuart".to_string()]),
+ "{\"AntHive\":[\"Bob\",\"Stuart\"]}",
+ ),
+ ]);
+
+ test_pretty_encode_ok(&[
+ (Animal::Dog, "\"Dog\""),
+ (
+ Animal::Frog("Henry".to_string(), vec![]),
+ pretty_str!({
+ "Frog": [
+ "Henry",
+ []
+ ]
+ }),
+ ),
+ (
+ Animal::Frog("Henry".to_string(), vec![349]),
+ pretty_str!({
+ "Frog": [
+ "Henry",
+ [
+ 349
+ ]
+ ]
+ }),
+ ),
+ (
+ Animal::Frog("Henry".to_string(), vec![349, 102]),
+ pretty_str!({
+ "Frog": [
+ "Henry",
+ [
+ 349,
+ 102
+ ]
+ ]
+ }),
+ ),
+ ]);
+}
+
+#[test]
+fn test_write_option() {
+ test_encode_ok(&[(None, "null"), (Some("jodhpurs"), "\"jodhpurs\"")]);
+
+ test_encode_ok(&[
+ (None, "null"),
+ (Some(vec!["foo", "bar"]), "[\"foo\",\"bar\"]"),
+ ]);
+
+ test_pretty_encode_ok(&[(None, "null"), (Some("jodhpurs"), "\"jodhpurs\"")]);
+
+ test_pretty_encode_ok(&[
+ (None, "null"),
+ (Some(vec!["foo", "bar"]), pretty_str!(["foo", "bar"])),
+ ]);
+}
+
+#[test]
+fn test_write_newtype_struct() {
+ #[derive(Serialize, PartialEq, Debug)]
+ struct Newtype(BTreeMap<String, i32>);
+
+ let inner = Newtype(treemap!(String::from("inner") => 123));
+ let outer = treemap!(String::from("outer") => to_value(&inner).unwrap());
+
+ test_encode_ok(&[(inner, r#"{"inner":123}"#)]);
+
+ test_encode_ok(&[(outer, r#"{"outer":{"inner":123}}"#)]);
+}
+
+#[test]
+fn test_deserialize_number_to_untagged_enum() {
+ #[derive(Eq, PartialEq, Deserialize, Debug)]
+ #[serde(untagged)]
+ enum E {
+ N(i64),
+ }
+
+ assert_eq!(E::N(0), E::deserialize(Number::from(0)).unwrap());
+}
+
+fn test_parse_ok<T>(tests: Vec<(&str, T)>)
+where
+ T: Clone + Debug + PartialEq + ser::Serialize + de::DeserializeOwned,
+{
+ for (s, value) in tests {
+ let v: T = from_str(s).unwrap();
+ assert_eq!(v, value.clone());
+
+ let v: T = from_slice(s.as_bytes()).unwrap();
+ assert_eq!(v, value.clone());
+
+ // Make sure we can deserialize into a `Value`.
+ let json_value: Value = from_str(s).unwrap();
+ assert_eq!(json_value, to_value(&value).unwrap());
+
+ // Make sure we can deserialize from a `&Value`.
+ let v = T::deserialize(&json_value).unwrap();
+ assert_eq!(v, value);
+
+ // Make sure we can deserialize from a `Value`.
+ let v: T = from_value(json_value.clone()).unwrap();
+ assert_eq!(v, value);
+
+ // Make sure we can round trip back to `Value`.
+ let json_value2: Value = from_value(json_value.clone()).unwrap();
+ assert_eq!(json_value2, json_value);
+
+ // Make sure we can fully ignore.
+ let twoline = s.to_owned() + "\n3735928559";
+ let mut de = Deserializer::from_str(&twoline);
+ IgnoredAny::deserialize(&mut de).unwrap();
+ assert_eq!(0xDEAD_BEEF, u64::deserialize(&mut de).unwrap());
+
+ // Make sure every prefix is an EOF error, except that a prefix of a
+ // number may be a valid number.
+ if !json_value.is_number() {
+ for (i, _) in s.trim_end().char_indices() {
+ assert!(from_str::<Value>(&s[..i]).unwrap_err().is_eof());
+ assert!(from_str::<IgnoredAny>(&s[..i]).unwrap_err().is_eof());
+ }
+ }
+ }
+}
+
+// For testing representations that the deserializer accepts but the serializer
+// never generates. These do not survive a round-trip through Value.
+fn test_parse_unusual_ok<T>(tests: Vec<(&str, T)>)
+where
+ T: Clone + Debug + PartialEq + ser::Serialize + de::DeserializeOwned,
+{
+ for (s, value) in tests {
+ let v: T = from_str(s).unwrap();
+ assert_eq!(v, value.clone());
+
+ let v: T = from_slice(s.as_bytes()).unwrap();
+ assert_eq!(v, value.clone());
+ }
+}
+
+macro_rules! test_parse_err {
+ ($name:ident::<$($ty:ty),*>($arg:expr) => $expected:expr) => {
+ let actual = $name::<$($ty),*>($arg).unwrap_err().to_string();
+ assert_eq!(actual, $expected, "unexpected {} error", stringify!($name));
+ };
+}
+
+fn test_parse_err<T>(errors: &[(&str, &'static str)])
+where
+ T: Debug + PartialEq + de::DeserializeOwned,
+{
+ for &(s, err) in errors {
+ test_parse_err!(from_str::<T>(s) => err);
+ test_parse_err!(from_slice::<T>(s.as_bytes()) => err);
+ }
+}
+
+fn test_parse_slice_err<T>(errors: &[(&[u8], &'static str)])
+where
+ T: Debug + PartialEq + de::DeserializeOwned,
+{
+ for &(s, err) in errors {
+ test_parse_err!(from_slice::<T>(s) => err);
+ }
+}
+
+fn test_fromstr_parse_err<T>(errors: &[(&str, &'static str)])
+where
+ T: Debug + PartialEq + FromStr,
+ <T as FromStr>::Err: ToString,
+{
+ for &(s, err) in errors {
+ let actual = s.parse::<T>().unwrap_err().to_string();
+ assert_eq!(actual, err, "unexpected parsing error");
+ }
+}
+
+#[test]
+fn test_parse_null() {
+ test_parse_err::<()>(&[
+ ("n", "EOF while parsing a value at line 1 column 1"),
+ ("nul", "EOF while parsing a value at line 1 column 3"),
+ ("nulla", "trailing characters at line 1 column 5"),
+ ]);
+
+ test_parse_ok(vec![("null", ())]);
+}
+
+#[test]
+fn test_parse_bool() {
+ test_parse_err::<bool>(&[
+ ("t", "EOF while parsing a value at line 1 column 1"),
+ ("truz", "expected ident at line 1 column 4"),
+ ("f", "EOF while parsing a value at line 1 column 1"),
+ ("faz", "expected ident at line 1 column 3"),
+ ("truea", "trailing characters at line 1 column 5"),
+ ("falsea", "trailing characters at line 1 column 6"),
+ ]);
+
+ test_parse_ok(vec![
+ ("true", true),
+ (" true ", true),
+ ("false", false),
+ (" false ", false),
+ ]);
+}
+
+#[test]
+fn test_parse_char() {
+ test_parse_err::<char>(&[
+ (
+ "\"ab\"",
+ "invalid value: string \"ab\", expected a character at line 1 column 4",
+ ),
+ (
+ "10",
+ "invalid type: integer `10`, expected a character at line 1 column 2",
+ ),
+ ]);
+
+ test_parse_ok(vec![
+ ("\"n\"", 'n'),
+ ("\"\\\"\"", '"'),
+ ("\"\\\\\"", '\\'),
+ ("\"/\"", '/'),
+ ("\"\\b\"", '\x08'),
+ ("\"\\f\"", '\x0C'),
+ ("\"\\n\"", '\n'),
+ ("\"\\r\"", '\r'),
+ ("\"\\t\"", '\t'),
+ ("\"\\u000b\"", '\x0B'),
+ ("\"\\u000B\"", '\x0B'),
+ ("\"\u{3A3}\"", '\u{3A3}'),
+ ]);
+}
+
+#[test]
+fn test_parse_number_errors() {
+ test_parse_err::<f64>(&[
+ ("+", "expected value at line 1 column 1"),
+ (".", "expected value at line 1 column 1"),
+ ("-", "EOF while parsing a value at line 1 column 1"),
+ ("00", "invalid number at line 1 column 2"),
+ ("0x80", "trailing characters at line 1 column 2"),
+ ("\\0", "expected value at line 1 column 1"),
+ (".0", "expected value at line 1 column 1"),
+ ("0.", "EOF while parsing a value at line 1 column 2"),
+ ("1.", "EOF while parsing a value at line 1 column 2"),
+ ("1.a", "invalid number at line 1 column 3"),
+ ("1.e1", "invalid number at line 1 column 3"),
+ ("1e", "EOF while parsing a value at line 1 column 2"),
+ ("1e+", "EOF while parsing a value at line 1 column 3"),
+ ("1a", "trailing characters at line 1 column 2"),
+ (
+ "100e777777777777777777777777777",
+ "number out of range at line 1 column 14",
+ ),
+ (
+ "-100e777777777777777777777777777",
+ "number out of range at line 1 column 15",
+ ),
+ (
+ "1000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000", // 1e309
+ "number out of range at line 1 column 310",
+ ),
+ (
+ "1000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ .0e9", // 1e309
+ "number out of range at line 1 column 305",
+ ),
+ (
+ "1000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ e9", // 1e309
+ "number out of range at line 1 column 303",
+ ),
+ ]);
+}
+
+#[test]
+fn test_parse_i64() {
+ test_parse_ok(vec![
+ ("-2", -2),
+ ("-1234", -1234),
+ (" -1234 ", -1234),
+ (&i64::MIN.to_string(), i64::MIN),
+ (&i64::MAX.to_string(), i64::MAX),
+ ]);
+}
+
+#[test]
+fn test_parse_u64() {
+ test_parse_ok(vec![
+ ("0", 0u64),
+ ("3", 3u64),
+ ("1234", 1234),
+ (&u64::MAX.to_string(), u64::MAX),
+ ]);
+}
+
+#[test]
+fn test_parse_negative_zero() {
+ for negative_zero in &[
+ "-0",
+ "-0.0",
+ "-0e2",
+ "-0.0e2",
+ "-1e-400",
+ "-1e-4000000000000000000000000000000000000000000000000",
+ ] {
+ assert!(
+ from_str::<f32>(negative_zero).unwrap().is_sign_negative(),
+ "should have been negative: {:?}",
+ negative_zero,
+ );
+ assert!(
+ from_str::<f64>(negative_zero).unwrap().is_sign_negative(),
+ "should have been negative: {:?}",
+ negative_zero,
+ );
+ }
+}
+
+#[test]
+fn test_parse_f64() {
+ test_parse_ok(vec![
+ ("0.0", 0.0f64),
+ ("3.0", 3.0f64),
+ ("3.1", 3.1),
+ ("-1.2", -1.2),
+ ("0.4", 0.4),
+ // Edge case from:
+ // https://github.com/serde-rs/json/issues/536#issuecomment-583714900
+ ("2.638344616030823e-256", 2.638344616030823e-256),
+ ]);
+
+ #[cfg(not(feature = "arbitrary_precision"))]
+ test_parse_ok(vec![
+ // With arbitrary-precision enabled, this parses as Number{"3.00"}
+ // but the float is Number{"3.0"}
+ ("3.00", 3.0f64),
+ ("0.4e5", 0.4e5),
+ ("0.4e+5", 0.4e5),
+ ("0.4e15", 0.4e15),
+ ("0.4e+15", 0.4e15),
+ ("0.4e-01", 0.4e-1),
+ (" 0.4e-01 ", 0.4e-1),
+ ("0.4e-001", 0.4e-1),
+ ("0.4e-0", 0.4e0),
+ ("0.00e00", 0.0),
+ ("0.00e+00", 0.0),
+ ("0.00e-00", 0.0),
+ ("3.5E-2147483647", 0.0),
+ ("0.0100000000000000000001", 0.01),
+ (
+ &format!("{}", (i64::MIN as f64) - 1.0),
+ (i64::MIN as f64) - 1.0,
+ ),
+ (
+ &format!("{}", (u64::MAX as f64) + 1.0),
+ (u64::MAX as f64) + 1.0,
+ ),
+ (&format!("{}", f64::EPSILON), f64::EPSILON),
+ (
+ "0.0000000000000000000000000000000000000000000000000123e50",
+ 1.23,
+ ),
+ ("100e-777777777777777777777777777", 0.0),
+ (
+ "1010101010101010101010101010101010101010",
+ 10101010101010101010e20,
+ ),
+ (
+ "0.1010101010101010101010101010101010101010",
+ 0.1010101010101010101,
+ ),
+ ("0e1000000000000000000000000000000000000000000000", 0.0),
+ (
+ "1000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 00000000",
+ 1e308,
+ ),
+ (
+ "1000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ .0e8",
+ 1e308,
+ ),
+ (
+ "1000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ e8",
+ 1e308,
+ ),
+ (
+ "1000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000000000000000000000000000000000000000000000\
+ 000000000000000000e-10",
+ 1e308,
+ ),
+ ]);
+}
+
+#[test]
+fn test_value_as_f64() {
+ let v = serde_json::from_str::<Value>("1e1000");
+
+ #[cfg(not(feature = "arbitrary_precision"))]
+ assert!(v.is_err());
+
+ #[cfg(feature = "arbitrary_precision")]
+ assert_eq!(v.unwrap().as_f64(), None);
+}
+
+// Test roundtrip with some values that were not perfectly roundtripped by the
+// old f64 deserializer.
+#[cfg(feature = "float_roundtrip")]
+#[test]
+fn test_roundtrip_f64() {
+ for &float in &[
+ // Samples from quickcheck-ing roundtrip with `input: f64`. Comments
+ // indicate the value returned by the old deserializer.
+ 51.24817837550540_4, // 51.2481783755054_1
+ -93.3113703768803_3, // -93.3113703768803_2
+ -36.5739948427534_36, // -36.5739948427534_4
+ 52.31400820410624_4, // 52.31400820410624_
+ 97.4536532003468_5, // 97.4536532003468_4
+ // Samples from `rng.next_u64` + `f64::from_bits` + `is_finite` filter.
+ 2.0030397744267762e-253,
+ 7.101215824554616e260,
+ 1.769268377902049e74,
+ -1.6727517818542075e58,
+ 3.9287532173373315e299,
+ ] {
+ let json = serde_json::to_string(&float).unwrap();
+ let output: f64 = serde_json::from_str(&json).unwrap();
+ assert_eq!(float, output);
+ }
+}
+
+#[test]
+fn test_roundtrip_f32() {
+ // This number has 1 ULP error if parsed via f64 and converted to f32.
+ // https://github.com/serde-rs/json/pull/671#issuecomment-628534468
+ let float = 7.038531e-26;
+ let json = serde_json::to_string(&float).unwrap();
+ let output: f32 = serde_json::from_str(&json).unwrap();
+ assert_eq!(float, output);
+}
+
+#[test]
+fn test_serialize_char() {
+ let value = json!(
+ ({
+ let mut map = BTreeMap::new();
+ map.insert('c', ());
+ map
+ })
+ );
+ assert_eq!(&Value::Null, value.get("c").unwrap());
+}
+
+#[cfg(feature = "arbitrary_precision")]
+#[test]
+fn test_malicious_number() {
+ #[derive(Serialize)]
+ #[serde(rename = "$serde_json::private::Number")]
+ struct S {
+ #[serde(rename = "$serde_json::private::Number")]
+ f: &'static str,
+ }
+
+ let actual = serde_json::to_value(&S { f: "not a number" })
+ .unwrap_err()
+ .to_string();
+ assert_eq!(actual, "invalid number at line 1 column 1");
+}
+
+#[test]
+fn test_parse_number() {
+ test_parse_ok(vec![
+ ("0.0", Number::from_f64(0.0f64).unwrap()),
+ ("3.0", Number::from_f64(3.0f64).unwrap()),
+ ("3.1", Number::from_f64(3.1).unwrap()),
+ ("-1.2", Number::from_f64(-1.2).unwrap()),
+ ("0.4", Number::from_f64(0.4).unwrap()),
+ ]);
+
+ test_fromstr_parse_err::<Number>(&[
+ (" 1.0", "invalid number at line 1 column 1"),
+ ("1.0 ", "invalid number at line 1 column 4"),
+ ("\t1.0", "invalid number at line 1 column 1"),
+ ("1.0\t", "invalid number at line 1 column 4"),
+ ]);
+
+ #[cfg(feature = "arbitrary_precision")]
+ test_parse_ok(vec![
+ ("1e999", Number::from_string_unchecked("1e999".to_owned())),
+ ("1e+999", Number::from_string_unchecked("1e+999".to_owned())),
+ ("-1e999", Number::from_string_unchecked("-1e999".to_owned())),
+ ("1e-999", Number::from_string_unchecked("1e-999".to_owned())),
+ ("1E999", Number::from_string_unchecked("1E999".to_owned())),
+ ("1E+999", Number::from_string_unchecked("1E+999".to_owned())),
+ ("-1E999", Number::from_string_unchecked("-1E999".to_owned())),
+ ("1E-999", Number::from_string_unchecked("1E-999".to_owned())),
+ ("1E+000", Number::from_string_unchecked("1E+000".to_owned())),
+ (
+ "2.3e999",
+ Number::from_string_unchecked("2.3e999".to_owned()),
+ ),
+ (
+ "-2.3e999",
+ Number::from_string_unchecked("-2.3e999".to_owned()),
+ ),
+ ]);
+}
+
+#[test]
+fn test_parse_string() {
+ test_parse_err::<String>(&[
+ ("\"", "EOF while parsing a string at line 1 column 1"),
+ ("\"lol", "EOF while parsing a string at line 1 column 4"),
+ ("\"lol\"a", "trailing characters at line 1 column 6"),
+ (
+ "\"\\uD83C\\uFFFF\"",
+ "lone leading surrogate in hex escape at line 1 column 13",
+ ),
+ (
+ "\"\n\"",
+ "control character (\\u0000-\\u001F) found while parsing a string at line 2 column 0",
+ ),
+ (
+ "\"\x1F\"",
+ "control character (\\u0000-\\u001F) found while parsing a string at line 1 column 2",
+ ),
+ ]);
+
+ test_parse_slice_err::<String>(&[
+ (
+ &[b'"', 159, 146, 150, b'"'],
+ "invalid unicode code point at line 1 column 5",
+ ),
+ (
+ &[b'"', b'\\', b'n', 159, 146, 150, b'"'],
+ "invalid unicode code point at line 1 column 7",
+ ),
+ (
+ &[b'"', b'\\', b'u', 48, 48, 51],
+ "EOF while parsing a string at line 1 column 6",
+ ),
+ (
+ &[b'"', b'\\', b'u', 250, 48, 51, 48, b'"'],
+ "invalid escape at line 1 column 4",
+ ),
+ (
+ &[b'"', b'\\', b'u', 48, 250, 51, 48, b'"'],
+ "invalid escape at line 1 column 5",
+ ),
+ (
+ &[b'"', b'\\', b'u', 48, 48, 250, 48, b'"'],
+ "invalid escape at line 1 column 6",
+ ),
+ (
+ &[b'"', b'\\', b'u', 48, 48, 51, 250, b'"'],
+ "invalid escape at line 1 column 7",
+ ),
+ (
+ &[b'"', b'\n', b'"'],
+ "control character (\\u0000-\\u001F) found while parsing a string at line 2 column 0",
+ ),
+ (
+ &[b'"', b'\x1F', b'"'],
+ "control character (\\u0000-\\u001F) found while parsing a string at line 1 column 2",
+ ),
+ ]);
+
+ test_parse_ok(vec![
+ ("\"\"", String::new()),
+ ("\"foo\"", "foo".to_string()),
+ (" \"foo\" ", "foo".to_string()),
+ ("\"\\\"\"", "\"".to_string()),
+ ("\"\\b\"", "\x08".to_string()),
+ ("\"\\n\"", "\n".to_string()),
+ ("\"\\r\"", "\r".to_string()),
+ ("\"\\t\"", "\t".to_string()),
+ ("\"\\u12ab\"", "\u{12ab}".to_string()),
+ ("\"\\uAB12\"", "\u{AB12}".to_string()),
+ ("\"\\uD83C\\uDF95\"", "\u{1F395}".to_string()),
+ ]);
+}
+
+#[test]
+fn test_parse_list() {
+ test_parse_err::<Vec<f64>>(&[
+ ("[", "EOF while parsing a list at line 1 column 1"),
+ ("[ ", "EOF while parsing a list at line 1 column 2"),
+ ("[1", "EOF while parsing a list at line 1 column 2"),
+ ("[1,", "EOF while parsing a value at line 1 column 3"),
+ ("[1,]", "trailing comma at line 1 column 4"),
+ ("[1 2]", "expected `,` or `]` at line 1 column 4"),
+ ("[]a", "trailing characters at line 1 column 3"),
+ ]);
+
+ test_parse_ok(vec![
+ ("[]", vec![]),
+ ("[ ]", vec![]),
+ ("[null]", vec![()]),
+ (" [ null ] ", vec![()]),
+ ]);
+
+ test_parse_ok(vec![("[true]", vec![true])]);
+
+ test_parse_ok(vec![("[3,1]", vec![3u64, 1]), (" [ 3 , 1 ] ", vec![3, 1])]);
+
+ test_parse_ok(vec![("[[3], [1, 2]]", vec![vec![3u64], vec![1, 2]])]);
+
+ test_parse_ok(vec![("[1]", (1u64,))]);
+
+ test_parse_ok(vec![("[1, 2]", (1u64, 2u64))]);
+
+ test_parse_ok(vec![("[1, 2, 3]", (1u64, 2u64, 3u64))]);
+
+ test_parse_ok(vec![("[1, [2, 3]]", (1u64, (2u64, 3u64)))]);
+}
+
+#[test]
+fn test_parse_object() {
+ test_parse_err::<BTreeMap<String, u32>>(&[
+ ("{", "EOF while parsing an object at line 1 column 1"),
+ ("{ ", "EOF while parsing an object at line 1 column 2"),
+ ("{1", "key must be a string at line 1 column 2"),
+ ("{ \"a\"", "EOF while parsing an object at line 1 column 5"),
+ ("{\"a\"", "EOF while parsing an object at line 1 column 4"),
+ ("{\"a\" ", "EOF while parsing an object at line 1 column 5"),
+ ("{\"a\" 1", "expected `:` at line 1 column 6"),
+ ("{\"a\":", "EOF while parsing a value at line 1 column 5"),
+ ("{\"a\":1", "EOF while parsing an object at line 1 column 6"),
+ ("{\"a\":1 1", "expected `,` or `}` at line 1 column 8"),
+ ("{\"a\":1,", "EOF while parsing a value at line 1 column 7"),
+ ("{}a", "trailing characters at line 1 column 3"),
+ ]);
+
+ test_parse_ok(vec![
+ ("{}", treemap!()),
+ ("{ }", treemap!()),
+ ("{\"a\":3}", treemap!("a".to_string() => 3u64)),
+ ("{ \"a\" : 3 }", treemap!("a".to_string() => 3)),
+ (
+ "{\"a\":3,\"b\":4}",
+ treemap!("a".to_string() => 3, "b".to_string() => 4),
+ ),
+ (
+ " { \"a\" : 3 , \"b\" : 4 } ",
+ treemap!("a".to_string() => 3, "b".to_string() => 4),
+ ),
+ ]);
+
+ test_parse_ok(vec![(
+ "{\"a\": {\"b\": 3, \"c\": 4}}",
+ treemap!(
+ "a".to_string() => treemap!(
+ "b".to_string() => 3u64,
+ "c".to_string() => 4
+ )
+ ),
+ )]);
+
+ test_parse_ok(vec![("{\"c\":null}", treemap!('c' => ()))]);
+}
+
+#[test]
+fn test_parse_struct() {
+ test_parse_err::<Outer>(&[
+ (
+ "5",
+ "invalid type: integer `5`, expected struct Outer at line 1 column 1",
+ ),
+ (
+ "\"hello\"",
+ "invalid type: string \"hello\", expected struct Outer at line 1 column 7",
+ ),
+ (
+ "{\"inner\": true}",
+ "invalid type: boolean `true`, expected a sequence at line 1 column 14",
+ ),
+ ("{}", "missing field `inner` at line 1 column 2"),
+ (
+ r#"{"inner": [{"b": 42, "c": []}]}"#,
+ "missing field `a` at line 1 column 29",
+ ),
+ ]);
+
+ test_parse_ok(vec![
+ (
+ "{
+ \"inner\": []
+ }",
+ Outer { inner: vec![] },
+ ),
+ (
+ "{
+ \"inner\": [
+ { \"a\": null, \"b\": 2, \"c\": [\"abc\", \"xyz\"] }
+ ]
+ }",
+ Outer {
+ inner: vec![Inner {
+ a: (),
+ b: 2,
+ c: vec!["abc".to_string(), "xyz".to_string()],
+ }],
+ },
+ ),
+ ]);
+
+ let v: Outer = from_str(
+ "[
+ [
+ [ null, 2, [\"abc\", \"xyz\"] ]
+ ]
+ ]",
+ )
+ .unwrap();
+
+ assert_eq!(
+ v,
+ Outer {
+ inner: vec![Inner {
+ a: (),
+ b: 2,
+ c: vec!["abc".to_string(), "xyz".to_string()],
+ }],
+ }
+ );
+
+ let j = json!([null, 2, []]);
+ Inner::deserialize(&j).unwrap();
+ Inner::deserialize(j).unwrap();
+}
+
+#[test]
+fn test_parse_option() {
+ test_parse_ok(vec![
+ ("null", None::<String>),
+ ("\"jodhpurs\"", Some("jodhpurs".to_string())),
+ ]);
+
+ #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+ struct Foo {
+ x: Option<isize>,
+ }
+
+ let value: Foo = from_str("{}").unwrap();
+ assert_eq!(value, Foo { x: None });
+
+ test_parse_ok(vec![
+ ("{\"x\": null}", Foo { x: None }),
+ ("{\"x\": 5}", Foo { x: Some(5) }),
+ ]);
+}
+
+#[test]
+fn test_parse_enum_errors() {
+ test_parse_err::<Animal>(
+ &[
+ ("{}", "expected value at line 1 column 2"),
+ ("[]", "expected value at line 1 column 1"),
+ ("\"unknown\"",
+ "unknown variant `unknown`, expected one of `Dog`, `Frog`, `Cat`, `AntHive` at line 1 column 9"),
+ ("{\"unknown\":null}",
+ "unknown variant `unknown`, expected one of `Dog`, `Frog`, `Cat`, `AntHive` at line 1 column 10"),
+ ("{\"Dog\":", "EOF while parsing a value at line 1 column 7"),
+ ("{\"Dog\":}", "expected value at line 1 column 8"),
+ ("{\"Dog\":{}}", "invalid type: map, expected unit at line 1 column 7"),
+ ("\"Frog\"", "invalid type: unit variant, expected tuple variant"),
+ ("\"Frog\" 0 ", "invalid type: unit variant, expected tuple variant"),
+ ("{\"Frog\":{}}",
+ "invalid type: map, expected tuple variant Animal::Frog at line 1 column 8"),
+ ("{\"Cat\":[]}", "invalid length 0, expected struct variant Animal::Cat with 2 elements at line 1 column 9"),
+ ("{\"Cat\":[0]}", "invalid length 1, expected struct variant Animal::Cat with 2 elements at line 1 column 10"),
+ ("{\"Cat\":[0, \"\", 2]}", "trailing characters at line 1 column 16"),
+ ("{\"Cat\":{\"age\": 5, \"name\": \"Kate\", \"foo\":\"bar\"}",
+ "unknown field `foo`, expected `age` or `name` at line 1 column 39"),
+
+ // JSON does not allow trailing commas in data structures
+ ("{\"Cat\":[0, \"Kate\",]}", "trailing comma at line 1 column 19"),
+ ("{\"Cat\":{\"age\": 2, \"name\": \"Kate\",}}",
+ "trailing comma at line 1 column 34"),
+ ],
+ );
+}
+
+#[test]
+fn test_parse_enum() {
+ test_parse_ok(vec![
+ ("\"Dog\"", Animal::Dog),
+ (" \"Dog\" ", Animal::Dog),
+ (
+ "{\"Frog\":[\"Henry\",[]]}",
+ Animal::Frog("Henry".to_string(), vec![]),
+ ),
+ (
+ " { \"Frog\": [ \"Henry\" , [ 349, 102 ] ] } ",
+ Animal::Frog("Henry".to_string(), vec![349, 102]),
+ ),
+ (
+ "{\"Cat\": {\"age\": 5, \"name\": \"Kate\"}}",
+ Animal::Cat {
+ age: 5,
+ name: "Kate".to_string(),
+ },
+ ),
+ (
+ " { \"Cat\" : { \"age\" : 5 , \"name\" : \"Kate\" } } ",
+ Animal::Cat {
+ age: 5,
+ name: "Kate".to_string(),
+ },
+ ),
+ (
+ " { \"AntHive\" : [\"Bob\", \"Stuart\"] } ",
+ Animal::AntHive(vec!["Bob".to_string(), "Stuart".to_string()]),
+ ),
+ ]);
+
+ test_parse_unusual_ok(vec![
+ ("{\"Dog\":null}", Animal::Dog),
+ (" { \"Dog\" : null } ", Animal::Dog),
+ ]);
+
+ test_parse_ok(vec![(
+ concat!(
+ "{",
+ " \"a\": \"Dog\",",
+ " \"b\": {\"Frog\":[\"Henry\", []]}",
+ "}"
+ ),
+ treemap!(
+ "a".to_string() => Animal::Dog,
+ "b".to_string() => Animal::Frog("Henry".to_string(), vec![])
+ ),
+ )]);
+}
+
+#[test]
+fn test_parse_trailing_whitespace() {
+ test_parse_ok(vec![
+ ("[1, 2] ", vec![1u64, 2]),
+ ("[1, 2]\n", vec![1, 2]),
+ ("[1, 2]\t", vec![1, 2]),
+ ("[1, 2]\t \n", vec![1, 2]),
+ ]);
+}
+
+#[test]
+fn test_multiline_errors() {
+ test_parse_err::<BTreeMap<String, String>>(&[(
+ "{\n \"foo\":\n \"bar\"",
+ "EOF while parsing an object at line 3 column 6",
+ )]);
+}
+
+#[test]
+fn test_missing_option_field() {
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct Foo {
+ x: Option<u32>,
+ }
+
+ let value: Foo = from_str("{}").unwrap();
+ assert_eq!(value, Foo { x: None });
+
+ let value: Foo = from_str("{\"x\": 5}").unwrap();
+ assert_eq!(value, Foo { x: Some(5) });
+
+ let value: Foo = from_value(json!({})).unwrap();
+ assert_eq!(value, Foo { x: None });
+
+ let value: Foo = from_value(json!({"x": 5})).unwrap();
+ assert_eq!(value, Foo { x: Some(5) });
+}
+
+#[test]
+fn test_missing_nonoption_field() {
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct Foo {
+ x: u32,
+ }
+
+ test_parse_err::<Foo>(&[("{}", "missing field `x` at line 1 column 2")]);
+}
+
+#[test]
+fn test_missing_renamed_field() {
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct Foo {
+ #[serde(rename = "y")]
+ x: Option<u32>,
+ }
+
+ let value: Foo = from_str("{}").unwrap();
+ assert_eq!(value, Foo { x: None });
+
+ let value: Foo = from_str("{\"y\": 5}").unwrap();
+ assert_eq!(value, Foo { x: Some(5) });
+
+ let value: Foo = from_value(json!({})).unwrap();
+ assert_eq!(value, Foo { x: None });
+
+ let value: Foo = from_value(json!({"y": 5})).unwrap();
+ assert_eq!(value, Foo { x: Some(5) });
+}
+
+#[test]
+fn test_serialize_seq_with_no_len() {
+ #[derive(Clone, Debug, PartialEq)]
+ struct MyVec<T>(Vec<T>);
+
+ impl<T> ser::Serialize for MyVec<T>
+ where
+ T: ser::Serialize,
+ {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ let mut seq = serializer.serialize_seq(None)?;
+ for elem in &self.0 {
+ seq.serialize_element(elem)?;
+ }
+ seq.end()
+ }
+ }
+
+ struct Visitor<T> {
+ marker: PhantomData<MyVec<T>>,
+ }
+
+ impl<'de, T> de::Visitor<'de> for Visitor<T>
+ where
+ T: de::Deserialize<'de>,
+ {
+ type Value = MyVec<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("array")
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<MyVec<T>, E>
+ where
+ E: de::Error,
+ {
+ Ok(MyVec(Vec::new()))
+ }
+
+ #[inline]
+ fn visit_seq<V>(self, mut visitor: V) -> Result<MyVec<T>, V::Error>
+ where
+ V: de::SeqAccess<'de>,
+ {
+ let mut values = Vec::new();
+
+ while let Some(value) = visitor.next_element()? {
+ values.push(value);
+ }
+
+ Ok(MyVec(values))
+ }
+ }
+
+ impl<'de, T> de::Deserialize<'de> for MyVec<T>
+ where
+ T: de::Deserialize<'de>,
+ {
+ fn deserialize<D>(deserializer: D) -> Result<MyVec<T>, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ deserializer.deserialize_map(Visitor {
+ marker: PhantomData,
+ })
+ }
+ }
+
+ let mut vec = Vec::new();
+ vec.push(MyVec(Vec::new()));
+ vec.push(MyVec(Vec::new()));
+ let vec: MyVec<MyVec<u32>> = MyVec(vec);
+
+ test_encode_ok(&[(vec.clone(), "[[],[]]")]);
+
+ let s = to_string_pretty(&vec).unwrap();
+ let expected = pretty_str!([[], []]);
+ assert_eq!(s, expected);
+}
+
+#[test]
+fn test_serialize_map_with_no_len() {
+ #[derive(Clone, Debug, PartialEq)]
+ struct MyMap<K, V>(BTreeMap<K, V>);
+
+ impl<K, V> ser::Serialize for MyMap<K, V>
+ where
+ K: ser::Serialize + Ord,
+ V: ser::Serialize,
+ {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: ser::Serializer,
+ {
+ let mut map = serializer.serialize_map(None)?;
+ for (k, v) in &self.0 {
+ map.serialize_entry(k, v)?;
+ }
+ map.end()
+ }
+ }
+
+ struct Visitor<K, V> {
+ marker: PhantomData<MyMap<K, V>>,
+ }
+
+ impl<'de, K, V> de::Visitor<'de> for Visitor<K, V>
+ where
+ K: de::Deserialize<'de> + Eq + Ord,
+ V: de::Deserialize<'de>,
+ {
+ type Value = MyMap<K, V>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("map")
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<MyMap<K, V>, E>
+ where
+ E: de::Error,
+ {
+ Ok(MyMap(BTreeMap::new()))
+ }
+
+ #[inline]
+ fn visit_map<Visitor>(self, mut visitor: Visitor) -> Result<MyMap<K, V>, Visitor::Error>
+ where
+ Visitor: de::MapAccess<'de>,
+ {
+ let mut values = BTreeMap::new();
+
+ while let Some((key, value)) = visitor.next_entry()? {
+ values.insert(key, value);
+ }
+
+ Ok(MyMap(values))
+ }
+ }
+
+ impl<'de, K, V> de::Deserialize<'de> for MyMap<K, V>
+ where
+ K: de::Deserialize<'de> + Eq + Ord,
+ V: de::Deserialize<'de>,
+ {
+ fn deserialize<D>(deserializer: D) -> Result<MyMap<K, V>, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ deserializer.deserialize_map(Visitor {
+ marker: PhantomData,
+ })
+ }
+ }
+
+ let mut map = BTreeMap::new();
+ map.insert("a", MyMap(BTreeMap::new()));
+ map.insert("b", MyMap(BTreeMap::new()));
+ let map: MyMap<_, MyMap<u32, u32>> = MyMap(map);
+
+ test_encode_ok(&[(map.clone(), "{\"a\":{},\"b\":{}}")]);
+
+ let s = to_string_pretty(&map).unwrap();
+ let expected = pretty_str!({
+ "a": {},
+ "b": {}
+ });
+ assert_eq!(s, expected);
+}
+
+#[cfg(not(miri))]
+#[test]
+fn test_deserialize_from_stream() {
+ use serde_json::to_writer;
+ use std::net::{TcpListener, TcpStream};
+ use std::thread;
+
+ #[derive(Debug, PartialEq, Serialize, Deserialize)]
+ struct Message {
+ message: String,
+ }
+
+ let l = TcpListener::bind("localhost:20000").unwrap();
+
+ thread::spawn(|| {
+ let l = l;
+ for stream in l.incoming() {
+ let mut stream = stream.unwrap();
+ let read_stream = stream.try_clone().unwrap();
+
+ let mut de = Deserializer::from_reader(read_stream);
+ let request = Message::deserialize(&mut de).unwrap();
+ let response = Message {
+ message: request.message,
+ };
+ to_writer(&mut stream, &response).unwrap();
+ }
+ });
+
+ let mut stream = TcpStream::connect("localhost:20000").unwrap();
+ let request = Message {
+ message: "hi there".to_string(),
+ };
+ to_writer(&mut stream, &request).unwrap();
+
+ let mut de = Deserializer::from_reader(stream);
+ let response = Message::deserialize(&mut de).unwrap();
+
+ assert_eq!(request, response);
+}
+
+#[test]
+fn test_serialize_rejects_bool_keys() {
+ let map = treemap!(
+ true => 2,
+ false => 4
+ );
+
+ let err = to_vec(&map).unwrap_err();
+ assert_eq!(err.to_string(), "key must be a string");
+}
+
+#[test]
+fn test_serialize_rejects_adt_keys() {
+ let map = treemap!(
+ Some("a") => 2,
+ Some("b") => 4,
+ None => 6
+ );
+
+ let err = to_vec(&map).unwrap_err();
+ assert_eq!(err.to_string(), "key must be a string");
+}
+
+#[test]
+fn test_bytes_ser() {
+ let buf = vec![];
+ let bytes = Bytes::new(&buf);
+ assert_eq!(to_string(&bytes).unwrap(), "[]".to_string());
+
+ let buf = vec![1, 2, 3];
+ let bytes = Bytes::new(&buf);
+ assert_eq!(to_string(&bytes).unwrap(), "[1,2,3]".to_string());
+}
+
+#[test]
+fn test_byte_buf_ser() {
+ let bytes = ByteBuf::new();
+ assert_eq!(to_string(&bytes).unwrap(), "[]".to_string());
+
+ let bytes = ByteBuf::from(vec![1, 2, 3]);
+ assert_eq!(to_string(&bytes).unwrap(), "[1,2,3]".to_string());
+}
+
+#[test]
+fn test_byte_buf_de() {
+ let bytes = ByteBuf::new();
+ let v: ByteBuf = from_str("[]").unwrap();
+ assert_eq!(v, bytes);
+
+ let bytes = ByteBuf::from(vec![1, 2, 3]);
+ let v: ByteBuf = from_str("[1, 2, 3]").unwrap();
+ assert_eq!(v, bytes);
+}
+
+#[test]
+fn test_byte_buf_de_lone_surrogate() {
+ let bytes = ByteBuf::from(vec![237, 160, 188]);
+ let v: ByteBuf = from_str(r#""\ud83c""#).unwrap();
+ assert_eq!(v, bytes);
+
+ let bytes = ByteBuf::from(vec![237, 160, 188, 10]);
+ let v: ByteBuf = from_str(r#""\ud83c\n""#).unwrap();
+ assert_eq!(v, bytes);
+
+ let bytes = ByteBuf::from(vec![237, 160, 188, 32]);
+ let v: ByteBuf = from_str(r#""\ud83c ""#).unwrap();
+ assert_eq!(v, bytes);
+
+ let bytes = ByteBuf::from(vec![237, 176, 129]);
+ let v: ByteBuf = from_str(r#""\udc01""#).unwrap();
+ assert_eq!(v, bytes);
+
+ let res = from_str::<ByteBuf>(r#""\ud83c\!""#);
+ assert!(res.is_err());
+
+ let res = from_str::<ByteBuf>(r#""\ud83c\u""#);
+ assert!(res.is_err());
+
+ let res = from_str::<ByteBuf>(r#""\ud83c\ud83c""#);
+ assert!(res.is_err());
+}
+
+#[cfg(feature = "raw_value")]
+#[test]
+fn test_raw_de_lone_surrogate() {
+ use serde_json::value::RawValue;
+
+ assert!(from_str::<Box<RawValue>>(r#""\ud83c""#).is_ok());
+ assert!(from_str::<Box<RawValue>>(r#""\ud83c\n""#).is_ok());
+ assert!(from_str::<Box<RawValue>>(r#""\ud83c ""#).is_ok());
+ assert!(from_str::<Box<RawValue>>(r#""\udc01 ""#).is_ok());
+ assert!(from_str::<Box<RawValue>>(r#""\udc01\!""#).is_err());
+ assert!(from_str::<Box<RawValue>>(r#""\udc01\u""#).is_err());
+ assert!(from_str::<Box<RawValue>>(r#""\ud83c\ud83c""#).is_ok());
+}
+
+#[test]
+fn test_byte_buf_de_multiple() {
+ let s: Vec<ByteBuf> = from_str(r#"["ab\nc", "cd\ne"]"#).unwrap();
+ let a = ByteBuf::from(b"ab\nc".to_vec());
+ let b = ByteBuf::from(b"cd\ne".to_vec());
+ assert_eq!(vec![a, b], s);
+}
+
+#[test]
+fn test_json_pointer() {
+ // Test case taken from https://tools.ietf.org/html/rfc6901#page-5
+ let data: Value = from_str(
+ r#"{
+ "foo": ["bar", "baz"],
+ "": 0,
+ "a/b": 1,
+ "c%d": 2,
+ "e^f": 3,
+ "g|h": 4,
+ "i\\j": 5,
+ "k\"l": 6,
+ " ": 7,
+ "m~n": 8
+ }"#,
+ )
+ .unwrap();
+ assert_eq!(data.pointer("").unwrap(), &data);
+ assert_eq!(data.pointer("/foo").unwrap(), &json!(["bar", "baz"]));
+ assert_eq!(data.pointer("/foo/0").unwrap(), &json!("bar"));
+ assert_eq!(data.pointer("/").unwrap(), &json!(0));
+ assert_eq!(data.pointer("/a~1b").unwrap(), &json!(1));
+ assert_eq!(data.pointer("/c%d").unwrap(), &json!(2));
+ assert_eq!(data.pointer("/e^f").unwrap(), &json!(3));
+ assert_eq!(data.pointer("/g|h").unwrap(), &json!(4));
+ assert_eq!(data.pointer("/i\\j").unwrap(), &json!(5));
+ assert_eq!(data.pointer("/k\"l").unwrap(), &json!(6));
+ assert_eq!(data.pointer("/ ").unwrap(), &json!(7));
+ assert_eq!(data.pointer("/m~0n").unwrap(), &json!(8));
+ // Invalid pointers
+ assert!(data.pointer("/unknown").is_none());
+ assert!(data.pointer("/e^f/ertz").is_none());
+ assert!(data.pointer("/foo/00").is_none());
+ assert!(data.pointer("/foo/01").is_none());
+}
+
+#[test]
+fn test_json_pointer_mut() {
+ // Test case taken from https://tools.ietf.org/html/rfc6901#page-5
+ let mut data: Value = from_str(
+ r#"{
+ "foo": ["bar", "baz"],
+ "": 0,
+ "a/b": 1,
+ "c%d": 2,
+ "e^f": 3,
+ "g|h": 4,
+ "i\\j": 5,
+ "k\"l": 6,
+ " ": 7,
+ "m~n": 8
+ }"#,
+ )
+ .unwrap();
+
+ // Basic pointer checks
+ assert_eq!(data.pointer_mut("/foo").unwrap(), &json!(["bar", "baz"]));
+ assert_eq!(data.pointer_mut("/foo/0").unwrap(), &json!("bar"));
+ assert_eq!(data.pointer_mut("/").unwrap(), 0);
+ assert_eq!(data.pointer_mut("/a~1b").unwrap(), 1);
+ assert_eq!(data.pointer_mut("/c%d").unwrap(), 2);
+ assert_eq!(data.pointer_mut("/e^f").unwrap(), 3);
+ assert_eq!(data.pointer_mut("/g|h").unwrap(), 4);
+ assert_eq!(data.pointer_mut("/i\\j").unwrap(), 5);
+ assert_eq!(data.pointer_mut("/k\"l").unwrap(), 6);
+ assert_eq!(data.pointer_mut("/ ").unwrap(), 7);
+ assert_eq!(data.pointer_mut("/m~0n").unwrap(), 8);
+
+ // Invalid pointers
+ assert!(data.pointer_mut("/unknown").is_none());
+ assert!(data.pointer_mut("/e^f/ertz").is_none());
+ assert!(data.pointer_mut("/foo/00").is_none());
+ assert!(data.pointer_mut("/foo/01").is_none());
+
+ // Mutable pointer checks
+ *data.pointer_mut("/").unwrap() = 100.into();
+ assert_eq!(data.pointer("/").unwrap(), 100);
+ *data.pointer_mut("/foo/0").unwrap() = json!("buzz");
+ assert_eq!(data.pointer("/foo/0").unwrap(), &json!("buzz"));
+
+ // Example of ownership stealing
+ assert_eq!(
+ data.pointer_mut("/a~1b")
+ .map(|m| mem::replace(m, json!(null)))
+ .unwrap(),
+ 1
+ );
+ assert_eq!(data.pointer("/a~1b").unwrap(), &json!(null));
+
+ // Need to compare against a clone so we don't anger the borrow checker
+ // by taking out two references to a mutable value
+ let mut d2 = data.clone();
+ assert_eq!(data.pointer_mut("").unwrap(), &mut d2);
+}
+
+#[test]
+fn test_stack_overflow() {
+ let brackets: String = iter::repeat('[')
+ .take(127)
+ .chain(iter::repeat(']').take(127))
+ .collect();
+ let _: Value = from_str(&brackets).unwrap();
+
+ let brackets = "[".repeat(129);
+ test_parse_err::<Value>(&[(&brackets, "recursion limit exceeded at line 1 column 128")]);
+}
+
+#[test]
+#[cfg(feature = "unbounded_depth")]
+fn test_disable_recursion_limit() {
+ let brackets: String = iter::repeat('[')
+ .take(140)
+ .chain(iter::repeat(']').take(140))
+ .collect();
+
+ let mut deserializer = Deserializer::from_str(&brackets);
+ deserializer.disable_recursion_limit();
+ Value::deserialize(&mut deserializer).unwrap();
+}
+
+#[test]
+fn test_integer_key() {
+ // map with integer keys
+ let map = treemap!(
+ 1 => 2,
+ -1 => 6
+ );
+ let j = r#"{"-1":6,"1":2}"#;
+ test_encode_ok(&[(&map, j)]);
+ test_parse_ok(vec![(j, map)]);
+
+ let j = r#"{"x":null}"#;
+ test_parse_err::<BTreeMap<i32, ()>>(&[(
+ j,
+ "invalid type: string \"x\", expected i32 at line 1 column 4",
+ )]);
+}
+
+#[test]
+fn test_integer128_key() {
+ let map = treemap! {
+ 100000000000000000000000000000000000000u128 => ()
+ };
+ let j = r#"{"100000000000000000000000000000000000000":null}"#;
+ assert_eq!(to_string(&map).unwrap(), j);
+ assert_eq!(from_str::<BTreeMap<u128, ()>>(j).unwrap(), map);
+}
+
+#[test]
+fn test_deny_float_key() {
+ #[derive(Eq, PartialEq, Ord, PartialOrd)]
+ struct Float;
+ impl Serialize for Float {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_f32(1.0)
+ }
+ }
+
+ // map with float key
+ let map = treemap!(Float => "x");
+ assert!(serde_json::to_value(map).is_err());
+}
+
+#[test]
+fn test_borrowed_key() {
+ let map: BTreeMap<&str, ()> = from_str("{\"borrowed\":null}").unwrap();
+ let expected = treemap! { "borrowed" => () };
+ assert_eq!(map, expected);
+
+ #[derive(Deserialize, Debug, Ord, PartialOrd, Eq, PartialEq)]
+ struct NewtypeStr<'a>(&'a str);
+
+ let map: BTreeMap<NewtypeStr, ()> = from_str("{\"borrowed\":null}").unwrap();
+ let expected = treemap! { NewtypeStr("borrowed") => () };
+ assert_eq!(map, expected);
+}
+
+#[test]
+fn test_effectively_string_keys() {
+ #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Serialize, Deserialize)]
+ enum Enum {
+ One,
+ Two,
+ }
+ let map = treemap! {
+ Enum::One => 1,
+ Enum::Two => 2
+ };
+ let expected = r#"{"One":1,"Two":2}"#;
+ test_encode_ok(&[(&map, expected)]);
+ test_parse_ok(vec![(expected, map)]);
+
+ #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Clone, Serialize, Deserialize)]
+ struct Wrapper(String);
+ let map = treemap! {
+ Wrapper("zero".to_owned()) => 0,
+ Wrapper("one".to_owned()) => 1
+ };
+ let expected = r#"{"one":1,"zero":0}"#;
+ test_encode_ok(&[(&map, expected)]);
+ test_parse_ok(vec![(expected, map)]);
+}
+
+#[test]
+fn test_json_macro() {
+ // This is tricky because the <...> is not a single TT and the comma inside
+ // looks like an array element separator.
+ let _ = json!([
+ <Result<(), ()> as Clone>::clone(&Ok(())),
+ <Result<(), ()> as Clone>::clone(&Err(()))
+ ]);
+
+ // Same thing but in the map values.
+ let _ = json!({
+ "ok": <Result<(), ()> as Clone>::clone(&Ok(())),
+ "err": <Result<(), ()> as Clone>::clone(&Err(()))
+ });
+
+ // It works in map keys but only if they are parenthesized.
+ let _ = json!({
+ (<Result<&str, ()> as Clone>::clone(&Ok("")).unwrap()): "ok",
+ (<Result<(), &str> as Clone>::clone(&Err("")).unwrap_err()): "err"
+ });
+
+ #[deny(unused_results)]
+ let _ = json!({ "architecture": [true, null] });
+}
+
+#[test]
+fn issue_220() {
+ #[derive(Debug, PartialEq, Eq, Deserialize)]
+ enum E {
+ V(u8),
+ }
+
+ assert!(from_str::<E>(r#" "V"0 "#).is_err());
+
+ assert_eq!(from_str::<E>(r#"{"V": 0}"#).unwrap(), E::V(0));
+}
+
+macro_rules! number_partialeq_ok {
+ ($($n:expr)*) => {
+ $(
+ let value = to_value($n).unwrap();
+ let s = $n.to_string();
+ assert_eq!(value, $n);
+ assert_eq!($n, value);
+ assert_ne!(value, s);
+ )*
+ }
+}
+
+#[test]
+fn test_partialeq_number() {
+ number_partialeq_ok!(0 1 100
+ i8::MIN i8::MAX i16::MIN i16::MAX i32::MIN i32::MAX i64::MIN i64::MAX
+ u8::MIN u8::MAX u16::MIN u16::MAX u32::MIN u32::MAX u64::MIN u64::MAX
+ f32::MIN f32::MAX f32::MIN_EXP f32::MAX_EXP f32::MIN_POSITIVE
+ f64::MIN f64::MAX f64::MIN_EXP f64::MAX_EXP f64::MIN_POSITIVE
+ f32::consts::E f32::consts::PI f32::consts::LN_2 f32::consts::LOG2_E
+ f64::consts::E f64::consts::PI f64::consts::LN_2 f64::consts::LOG2_E
+ );
+}
+
+#[test]
+#[cfg(integer128)]
+#[cfg(feature = "arbitrary_precision")]
+fn test_partialeq_integer128() {
+ number_partialeq_ok!(i128::MIN i128::MAX u128::MIN u128::MAX)
+}
+
+#[test]
+fn test_partialeq_string() {
+ let v = to_value("42").unwrap();
+ assert_eq!(v, "42");
+ assert_eq!("42", v);
+ assert_ne!(v, 42);
+ assert_eq!(v, String::from("42"));
+ assert_eq!(String::from("42"), v);
+}
+
+#[test]
+fn test_partialeq_bool() {
+ let v = to_value(true).unwrap();
+ assert_eq!(v, true);
+ assert_eq!(true, v);
+ assert_ne!(v, false);
+ assert_ne!(v, "true");
+ assert_ne!(v, 1);
+ assert_ne!(v, 0);
+}
+
+struct FailReader(io::ErrorKind);
+
+impl io::Read for FailReader {
+ fn read(&mut self, _: &mut [u8]) -> io::Result<usize> {
+ Err(io::Error::new(self.0, "oh no!"))
+ }
+}
+
+#[test]
+fn test_category() {
+ assert!(from_str::<String>("123").unwrap_err().is_data());
+
+ assert!(from_str::<String>("]").unwrap_err().is_syntax());
+
+ assert!(from_str::<String>("").unwrap_err().is_eof());
+ assert!(from_str::<String>("\"").unwrap_err().is_eof());
+ assert!(from_str::<String>("\"\\").unwrap_err().is_eof());
+ assert!(from_str::<String>("\"\\u").unwrap_err().is_eof());
+ assert!(from_str::<String>("\"\\u0").unwrap_err().is_eof());
+ assert!(from_str::<String>("\"\\u00").unwrap_err().is_eof());
+ assert!(from_str::<String>("\"\\u000").unwrap_err().is_eof());
+
+ assert!(from_str::<Vec<usize>>("[").unwrap_err().is_eof());
+ assert!(from_str::<Vec<usize>>("[0").unwrap_err().is_eof());
+ assert!(from_str::<Vec<usize>>("[0,").unwrap_err().is_eof());
+
+ assert!(from_str::<BTreeMap<String, usize>>("{")
+ .unwrap_err()
+ .is_eof());
+ assert!(from_str::<BTreeMap<String, usize>>("{\"k\"")
+ .unwrap_err()
+ .is_eof());
+ assert!(from_str::<BTreeMap<String, usize>>("{\"k\":")
+ .unwrap_err()
+ .is_eof());
+ assert!(from_str::<BTreeMap<String, usize>>("{\"k\":0")
+ .unwrap_err()
+ .is_eof());
+ assert!(from_str::<BTreeMap<String, usize>>("{\"k\":0,")
+ .unwrap_err()
+ .is_eof());
+
+ let fail = FailReader(io::ErrorKind::NotConnected);
+ assert!(from_reader::<_, String>(fail).unwrap_err().is_io());
+}
+
+#[test]
+// Clippy false positive: https://github.com/Manishearth/rust-clippy/issues/292
+#[allow(clippy::needless_lifetimes)]
+fn test_into_io_error() {
+ fn io_error<'de, T: Deserialize<'de> + Debug>(j: &'static str) -> io::Error {
+ from_str::<T>(j).unwrap_err().into()
+ }
+
+ assert_eq!(
+ io_error::<String>("\"\\u").kind(),
+ io::ErrorKind::UnexpectedEof
+ );
+ assert_eq!(io_error::<String>("0").kind(), io::ErrorKind::InvalidData);
+ assert_eq!(io_error::<String>("]").kind(), io::ErrorKind::InvalidData);
+
+ let fail = FailReader(io::ErrorKind::NotConnected);
+ let io_err: io::Error = from_reader::<_, u8>(fail).unwrap_err().into();
+ assert_eq!(io_err.kind(), io::ErrorKind::NotConnected);
+}
+
+#[test]
+fn test_borrow() {
+ let s: &str = from_str("\"borrowed\"").unwrap();
+ assert_eq!("borrowed", s);
+
+ let s: &str = from_slice(b"\"borrowed\"").unwrap();
+ assert_eq!("borrowed", s);
+}
+
+#[test]
+fn null_invalid_type() {
+ let err = serde_json::from_str::<String>("null").unwrap_err();
+ assert_eq!(
+ format!("{}", err),
+ String::from("invalid type: null, expected a string at line 1 column 4")
+ );
+}
+
+#[test]
+fn test_integer128() {
+ let signed = &[i128::min_value(), -1, 0, 1, i128::max_value()];
+ let unsigned = &[0, 1, u128::max_value()];
+
+ for integer128 in signed {
+ let expected = integer128.to_string();
+ assert_eq!(to_string(integer128).unwrap(), expected);
+ assert_eq!(from_str::<i128>(&expected).unwrap(), *integer128);
+ }
+
+ for integer128 in unsigned {
+ let expected = integer128.to_string();
+ assert_eq!(to_string(integer128).unwrap(), expected);
+ assert_eq!(from_str::<u128>(&expected).unwrap(), *integer128);
+ }
+
+ test_parse_err::<i128>(&[
+ (
+ "-170141183460469231731687303715884105729",
+ "number out of range at line 1 column 40",
+ ),
+ (
+ "170141183460469231731687303715884105728",
+ "number out of range at line 1 column 39",
+ ),
+ ]);
+
+ test_parse_err::<u128>(&[
+ ("-1", "number out of range at line 1 column 1"),
+ (
+ "340282366920938463463374607431768211456",
+ "number out of range at line 1 column 39",
+ ),
+ ]);
+}
+
+#[test]
+fn test_integer128_to_value() {
+ let signed = &[i128::from(i64::min_value()), i128::from(u64::max_value())];
+ let unsigned = &[0, u128::from(u64::max_value())];
+
+ for integer128 in signed {
+ let expected = integer128.to_string();
+ assert_eq!(to_value(integer128).unwrap().to_string(), expected);
+ }
+
+ for integer128 in unsigned {
+ let expected = integer128.to_string();
+ assert_eq!(to_value(integer128).unwrap().to_string(), expected);
+ }
+
+ if !cfg!(feature = "arbitrary_precision") {
+ let err = to_value(u128::from(u64::max_value()) + 1).unwrap_err();
+ assert_eq!(err.to_string(), "number out of range");
+ }
+}
+
+#[cfg(feature = "raw_value")]
+#[test]
+fn test_borrowed_raw_value() {
+ #[derive(Serialize, Deserialize)]
+ struct Wrapper<'a> {
+ a: i8,
+ #[serde(borrow)]
+ b: &'a RawValue,
+ c: i8,
+ }
+
+ let wrapper_from_str: Wrapper =
+ serde_json::from_str(r#"{"a": 1, "b": {"foo": 2}, "c": 3}"#).unwrap();
+ assert_eq!(r#"{"foo": 2}"#, wrapper_from_str.b.get());
+
+ let wrapper_to_string = serde_json::to_string(&wrapper_from_str).unwrap();
+ assert_eq!(r#"{"a":1,"b":{"foo": 2},"c":3}"#, wrapper_to_string);
+
+ let wrapper_to_value = serde_json::to_value(&wrapper_from_str).unwrap();
+ assert_eq!(json!({"a": 1, "b": {"foo": 2}, "c": 3}), wrapper_to_value);
+
+ let array_from_str: Vec<&RawValue> =
+ serde_json::from_str(r#"["a", 42, {"foo": "bar"}, null]"#).unwrap();
+ assert_eq!(r#""a""#, array_from_str[0].get());
+ assert_eq!(r#"42"#, array_from_str[1].get());
+ assert_eq!(r#"{"foo": "bar"}"#, array_from_str[2].get());
+ assert_eq!(r#"null"#, array_from_str[3].get());
+
+ let array_to_string = serde_json::to_string(&array_from_str).unwrap();
+ assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string);
+}
+
+#[cfg(feature = "raw_value")]
+#[test]
+fn test_raw_value_in_map_key() {
+ #[derive(RefCast)]
+ #[repr(transparent)]
+ struct RawMapKey(RawValue);
+
+ impl<'de> Deserialize<'de> for &'de RawMapKey {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ let raw_value = <&RawValue>::deserialize(deserializer)?;
+ Ok(RawMapKey::ref_cast(raw_value))
+ }
+ }
+
+ impl PartialEq for RawMapKey {
+ fn eq(&self, other: &Self) -> bool {
+ self.0.get() == other.0.get()
+ }
+ }
+
+ impl Eq for RawMapKey {}
+
+ impl Hash for RawMapKey {
+ fn hash<H: Hasher>(&self, hasher: &mut H) {
+ self.0.get().hash(hasher);
+ }
+ }
+
+ let map_from_str: HashMap<&RawMapKey, &RawValue> =
+ serde_json::from_str(r#" {"\\k":"\\v"} "#).unwrap();
+ let (map_k, map_v) = map_from_str.into_iter().next().unwrap();
+ assert_eq!("\"\\\\k\"", map_k.0.get());
+ assert_eq!("\"\\\\v\"", map_v.get());
+}
+
+#[cfg(feature = "raw_value")]
+#[test]
+fn test_boxed_raw_value() {
+ #[derive(Serialize, Deserialize)]
+ struct Wrapper {
+ a: i8,
+ b: Box<RawValue>,
+ c: i8,
+ }
+
+ let wrapper_from_str: Wrapper =
+ serde_json::from_str(r#"{"a": 1, "b": {"foo": 2}, "c": 3}"#).unwrap();
+ assert_eq!(r#"{"foo": 2}"#, wrapper_from_str.b.get());
+
+ let wrapper_from_reader: Wrapper =
+ serde_json::from_reader(br#"{"a": 1, "b": {"foo": 2}, "c": 3}"#.as_ref()).unwrap();
+ assert_eq!(r#"{"foo": 2}"#, wrapper_from_reader.b.get());
+
+ let wrapper_from_value: Wrapper =
+ serde_json::from_value(json!({"a": 1, "b": {"foo": 2}, "c": 3})).unwrap();
+ assert_eq!(r#"{"foo":2}"#, wrapper_from_value.b.get());
+
+ let wrapper_to_string = serde_json::to_string(&wrapper_from_str).unwrap();
+ assert_eq!(r#"{"a":1,"b":{"foo": 2},"c":3}"#, wrapper_to_string);
+
+ let wrapper_to_value = serde_json::to_value(&wrapper_from_str).unwrap();
+ assert_eq!(json!({"a": 1, "b": {"foo": 2}, "c": 3}), wrapper_to_value);
+
+ let array_from_str: Vec<Box<RawValue>> =
+ serde_json::from_str(r#"["a", 42, {"foo": "bar"}, null]"#).unwrap();
+ assert_eq!(r#""a""#, array_from_str[0].get());
+ assert_eq!(r#"42"#, array_from_str[1].get());
+ assert_eq!(r#"{"foo": "bar"}"#, array_from_str[2].get());
+ assert_eq!(r#"null"#, array_from_str[3].get());
+
+ let array_from_reader: Vec<Box<RawValue>> =
+ serde_json::from_reader(br#"["a", 42, {"foo": "bar"}, null]"#.as_ref()).unwrap();
+ assert_eq!(r#""a""#, array_from_reader[0].get());
+ assert_eq!(r#"42"#, array_from_reader[1].get());
+ assert_eq!(r#"{"foo": "bar"}"#, array_from_reader[2].get());
+ assert_eq!(r#"null"#, array_from_reader[3].get());
+
+ let array_to_string = serde_json::to_string(&array_from_str).unwrap();
+ assert_eq!(r#"["a",42,{"foo": "bar"},null]"#, array_to_string);
+}
+
+#[cfg(feature = "raw_value")]
+#[test]
+fn test_raw_invalid_utf8() {
+ let j = &[b'"', b'\xCE', b'\xF8', b'"'];
+ let value_err = serde_json::from_slice::<Value>(j).unwrap_err();
+ let raw_value_err = serde_json::from_slice::<Box<RawValue>>(j).unwrap_err();
+
+ assert_eq!(
+ value_err.to_string(),
+ "invalid unicode code point at line 1 column 4",
+ );
+ assert_eq!(
+ raw_value_err.to_string(),
+ "invalid unicode code point at line 1 column 4",
+ );
+}
+
+#[cfg(feature = "raw_value")]
+#[test]
+fn test_serialize_unsized_value_to_raw_value() {
+ assert_eq!(
+ serde_json::value::to_raw_value("foobar").unwrap().get(),
+ r#""foobar""#,
+ );
+}
+
+#[test]
+fn test_borrow_in_map_key() {
+ #[derive(Deserialize, Debug)]
+ struct Outer {
+ #[allow(dead_code)]
+ map: BTreeMap<MyMapKey, ()>,
+ }
+
+ #[derive(Ord, PartialOrd, Eq, PartialEq, Debug)]
+ struct MyMapKey(usize);
+
+ impl<'de> Deserialize<'de> for MyMapKey {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: de::Deserializer<'de>,
+ {
+ let s = <&str>::deserialize(deserializer)?;
+ let n = s.parse().map_err(de::Error::custom)?;
+ Ok(MyMapKey(n))
+ }
+ }
+
+ let value = json!({ "map": { "1": null } });
+ Outer::deserialize(&value).unwrap();
+}
+
+#[test]
+fn test_value_into_deserializer() {
+ #[derive(Deserialize)]
+ struct Outer {
+ inner: Inner,
+ }
+
+ #[derive(Deserialize)]
+ struct Inner {
+ string: String,
+ }
+
+ let mut map = BTreeMap::new();
+ map.insert("inner", json!({ "string": "Hello World" }));
+
+ let outer = Outer::deserialize(map.into_deserializer()).unwrap();
+ assert_eq!(outer.inner.string, "Hello World");
+}
+
+#[test]
+fn hash_positive_and_negative_zero() {
+ fn hash(obj: impl Hash) -> u64 {
+ let mut hasher = DefaultHasher::new();
+ obj.hash(&mut hasher);
+ hasher.finish()
+ }
+
+ let k1 = serde_json::from_str::<Number>("0.0").unwrap();
+ let k2 = serde_json::from_str::<Number>("-0.0").unwrap();
+ if cfg!(feature = "arbitrary_precision") {
+ assert_ne!(k1, k2);
+ assert_ne!(hash(k1), hash(k2));
+ } else {
+ assert_eq!(k1, k2);
+ assert_eq!(hash(k1), hash(k2));
+ }
+}
diff --git a/third_party/rust/serde_json/tests/ui/missing_colon.rs b/third_party/rust/serde_json/tests/ui/missing_colon.rs
new file mode 100644
index 0000000000..d93b7b907d
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/missing_colon.rs
@@ -0,0 +1,5 @@
+use serde_json::json;
+
+fn main() {
+ json!({ "a" });
+}
diff --git a/third_party/rust/serde_json/tests/ui/missing_colon.stderr b/third_party/rust/serde_json/tests/ui/missing_colon.stderr
new file mode 100644
index 0000000000..1515211adf
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/missing_colon.stderr
@@ -0,0 +1,12 @@
+error: unexpected end of macro invocation
+ --> tests/ui/missing_colon.rs:4:5
+ |
+4 | json!({ "a" });
+ | ^^^^^^^^^^^^^^ missing tokens in macro arguments
+ |
+note: while trying to match `@`
+ --> src/macros.rs
+ |
+ | (@array [$($elems:expr,)*]) => {
+ | ^
+ = note: this error originates in the macro `json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/serde_json/tests/ui/missing_comma.rs b/third_party/rust/serde_json/tests/ui/missing_comma.rs
new file mode 100644
index 0000000000..8818c3e60c
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/missing_comma.rs
@@ -0,0 +1,5 @@
+use serde_json::json;
+
+fn main() {
+ json!({ "1": "" "2": "" });
+}
diff --git a/third_party/rust/serde_json/tests/ui/missing_comma.stderr b/third_party/rust/serde_json/tests/ui/missing_comma.stderr
new file mode 100644
index 0000000000..bafa0f8915
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/missing_comma.stderr
@@ -0,0 +1,13 @@
+error: no rules expected the token `"2"`
+ --> tests/ui/missing_comma.rs:4:21
+ |
+4 | json!({ "1": "" "2": "" });
+ | -^^^ no rules expected this token in macro call
+ | |
+ | help: missing comma here
+ |
+note: while trying to match `,`
+ --> src/macros.rs
+ |
+ | ($e:expr , $($tt:tt)*) => {};
+ | ^
diff --git a/third_party/rust/serde_json/tests/ui/missing_value.rs b/third_party/rust/serde_json/tests/ui/missing_value.rs
new file mode 100644
index 0000000000..0ba14e22c2
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/missing_value.rs
@@ -0,0 +1,5 @@
+use serde_json::json;
+
+fn main() {
+ json!({ "a" : });
+}
diff --git a/third_party/rust/serde_json/tests/ui/missing_value.stderr b/third_party/rust/serde_json/tests/ui/missing_value.stderr
new file mode 100644
index 0000000000..9c9de99ca9
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/missing_value.stderr
@@ -0,0 +1,12 @@
+error: unexpected end of macro invocation
+ --> tests/ui/missing_value.rs:4:5
+ |
+4 | json!({ "a" : });
+ | ^^^^^^^^^^^^^^^^ missing tokens in macro arguments
+ |
+note: while trying to match `@`
+ --> src/macros.rs
+ |
+ | (@array [$($elems:expr,)*]) => {
+ | ^
+ = note: this error originates in the macro `json_internal` which comes from the expansion of the macro `json` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/serde_json/tests/ui/not_found.rs b/third_party/rust/serde_json/tests/ui/not_found.rs
new file mode 100644
index 0000000000..2df6870dc3
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/not_found.rs
@@ -0,0 +1,5 @@
+use serde_json::json;
+
+fn main() {
+ json!({ "a" : x });
+}
diff --git a/third_party/rust/serde_json/tests/ui/not_found.stderr b/third_party/rust/serde_json/tests/ui/not_found.stderr
new file mode 100644
index 0000000000..6fec180409
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/not_found.stderr
@@ -0,0 +1,5 @@
+error[E0425]: cannot find value `x` in this scope
+ --> tests/ui/not_found.rs:4:19
+ |
+4 | json!({ "a" : x });
+ | ^ not found in this scope
diff --git a/third_party/rust/serde_json/tests/ui/parse_expr.rs b/third_party/rust/serde_json/tests/ui/parse_expr.rs
new file mode 100644
index 0000000000..e7f1805b1e
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/parse_expr.rs
@@ -0,0 +1,5 @@
+use serde_json::json;
+
+fn main() {
+ json!({ "a" : ~ });
+}
diff --git a/third_party/rust/serde_json/tests/ui/parse_expr.stderr b/third_party/rust/serde_json/tests/ui/parse_expr.stderr
new file mode 100644
index 0000000000..cd3e1c94d1
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/parse_expr.stderr
@@ -0,0 +1,11 @@
+error: no rules expected the token `~`
+ --> tests/ui/parse_expr.rs:4:19
+ |
+4 | json!({ "a" : ~ });
+ | ^ no rules expected this token in macro call
+ |
+note: while trying to match meta-variable `$e:expr`
+ --> src/macros.rs
+ |
+ | ($e:expr , $($tt:tt)*) => {};
+ | ^^^^^^^
diff --git a/third_party/rust/serde_json/tests/ui/parse_key.rs b/third_party/rust/serde_json/tests/ui/parse_key.rs
new file mode 100644
index 0000000000..858bd71692
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/parse_key.rs
@@ -0,0 +1,5 @@
+use serde_json::json;
+
+fn main() {
+ json!({ "".s : true });
+}
diff --git a/third_party/rust/serde_json/tests/ui/parse_key.stderr b/third_party/rust/serde_json/tests/ui/parse_key.stderr
new file mode 100644
index 0000000000..f10c21800e
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/parse_key.stderr
@@ -0,0 +1,5 @@
+error[E0609]: no field `s` on type `&'static str`
+ --> tests/ui/parse_key.rs:4:16
+ |
+4 | json!({ "".s : true });
+ | ^
diff --git a/third_party/rust/serde_json/tests/ui/unexpected_after_array_element.rs b/third_party/rust/serde_json/tests/ui/unexpected_after_array_element.rs
new file mode 100644
index 0000000000..226c58cf17
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/unexpected_after_array_element.rs
@@ -0,0 +1,5 @@
+use serde_json::json;
+
+fn main() {
+ json!([ true => ]);
+}
diff --git a/third_party/rust/serde_json/tests/ui/unexpected_after_array_element.stderr b/third_party/rust/serde_json/tests/ui/unexpected_after_array_element.stderr
new file mode 100644
index 0000000000..ef449f764d
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/unexpected_after_array_element.stderr
@@ -0,0 +1,7 @@
+error: no rules expected the token `=>`
+ --> tests/ui/unexpected_after_array_element.rs:4:18
+ |
+4 | json!([ true => ]);
+ | ^^ no rules expected this token in macro call
+ |
+ = note: while trying to match end of macro
diff --git a/third_party/rust/serde_json/tests/ui/unexpected_after_map_entry.rs b/third_party/rust/serde_json/tests/ui/unexpected_after_map_entry.rs
new file mode 100644
index 0000000000..0dfb731559
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/unexpected_after_map_entry.rs
@@ -0,0 +1,5 @@
+use serde_json::json;
+
+fn main() {
+ json!({ "k": true => });
+}
diff --git a/third_party/rust/serde_json/tests/ui/unexpected_after_map_entry.stderr b/third_party/rust/serde_json/tests/ui/unexpected_after_map_entry.stderr
new file mode 100644
index 0000000000..c62d90ba0d
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/unexpected_after_map_entry.stderr
@@ -0,0 +1,7 @@
+error: no rules expected the token `=>`
+ --> tests/ui/unexpected_after_map_entry.rs:4:23
+ |
+4 | json!({ "k": true => });
+ | ^^ no rules expected this token in macro call
+ |
+ = note: while trying to match end of macro
diff --git a/third_party/rust/serde_json/tests/ui/unexpected_colon.rs b/third_party/rust/serde_json/tests/ui/unexpected_colon.rs
new file mode 100644
index 0000000000..e767ea6f7d
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/unexpected_colon.rs
@@ -0,0 +1,5 @@
+use serde_json::json;
+
+fn main() {
+ json!({ : true });
+}
diff --git a/third_party/rust/serde_json/tests/ui/unexpected_colon.stderr b/third_party/rust/serde_json/tests/ui/unexpected_colon.stderr
new file mode 100644
index 0000000000..7e47726bc6
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/unexpected_colon.stderr
@@ -0,0 +1,7 @@
+error: no rules expected the token `:`
+ --> tests/ui/unexpected_colon.rs:4:13
+ |
+4 | json!({ : true });
+ | ^ no rules expected this token in macro call
+ |
+ = note: while trying to match end of macro
diff --git a/third_party/rust/serde_json/tests/ui/unexpected_comma.rs b/third_party/rust/serde_json/tests/ui/unexpected_comma.rs
new file mode 100644
index 0000000000..338874ed8f
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/unexpected_comma.rs
@@ -0,0 +1,5 @@
+use serde_json::json;
+
+fn main() {
+ json!({ "a" , "b": true });
+}
diff --git a/third_party/rust/serde_json/tests/ui/unexpected_comma.stderr b/third_party/rust/serde_json/tests/ui/unexpected_comma.stderr
new file mode 100644
index 0000000000..552f399a50
--- /dev/null
+++ b/third_party/rust/serde_json/tests/ui/unexpected_comma.stderr
@@ -0,0 +1,7 @@
+error: no rules expected the token `,`
+ --> tests/ui/unexpected_comma.rs:4:17
+ |
+4 | json!({ "a" , "b": true });
+ | ^ no rules expected this token in macro call
+ |
+ = note: while trying to match end of macro
diff --git a/third_party/rust/serde_repr/.cargo-checksum.json b/third_party/rust/serde_repr/.cargo-checksum.json
new file mode 100644
index 0000000000..ac7ba6ea52
--- /dev/null
+++ b/third_party/rust/serde_repr/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"eeae9b55dbaecf1fbe4505c7a202da3143336766d2f6bc6880776d3a724884f5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"eeaecee94e896222307c54e647a2ca546e3f7a778f5a37f9a33300c9a3260324","src/lib.rs":"7acb4fb05f93dd98a0f2c83de6da38ed68e882c7b7ea244aa607c1c5113f8509","src/parse.rs":"687cf1436d12c0c26b1c6d06f80e56b4ec0d63a38d71e1f175b981c0fdc10c68","tests/compiletest.rs":"022a8e400ef813d7ea1875b944549cee5125f6a995dc33e93b48cba3e1b57bd1","tests/test.rs":"a4ddb956ee9eafc0b50694075497a2712a347f1a682f9038e2dd654c6605af44","tests/ui/empty_enum.rs":"fe1166f2f92ee213d26a23e57572a99c65c163d446fd8d67e1520bab34f4b859","tests/ui/empty_enum.stderr":"2c8907fc146bb4dcdb926b72de4f823dae4c1c0d8de8a636c512539408f26cc7","tests/ui/missing_repr.rs":"b7ba9341111582cad52e761b82f14778c60352014c4265566e4d4d01ccdcb306","tests/ui/missing_repr.stderr":"dfcb65527963fb8962e1442e10d3c71e141f238b1732483e1739b528ae0eca43","tests/ui/multiple_others.rs":"569658516619719f21e5071873a37125d5390edb77558e4381401f03efda0c83","tests/ui/multiple_others.stderr":"a300f94d2a2049d6718866d17b5673201edc275164b9e8eba25a9ffcd71fd30f","tests/ui/non_unit_variant.rs":"0d8295ae08d882fc3ef4164857240038c5b0674ff0811da9b6ea7343e8bb955c","tests/ui/non_unit_variant.stderr":"18f2900e501b8c64b980445758ca1cb59594dc8d24a1a76abb08a48d8beb3f35","tests/ui/not_enum.rs":"ada7637821c924a6b99175363c820375991be60223f96ca553d304fde2721386","tests/ui/not_enum.stderr":"814525f9a1495225511a02ad4149c9371ea622230b8002564fe83cf52300c728"},"package":"9a5ec9fa74a20ebbe5d9ac23dac1fc96ba0ecfe9f50f2843b52e537b10fbcb4e"} \ No newline at end of file
diff --git a/third_party/rust/serde_repr/Cargo.toml b/third_party/rust/serde_repr/Cargo.toml
new file mode 100644
index 0000000000..d1a4916e0a
--- /dev/null
+++ b/third_party/rust/serde_repr/Cargo.toml
@@ -0,0 +1,59 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+rust-version = "1.31"
+name = "serde_repr"
+version = "0.1.10"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+description = "Derive Serialize and Deserialize that delegates to the underlying repr of a C-like enum."
+documentation = "https://docs.rs/serde_repr"
+readme = "README.md"
+keywords = [
+ "serde",
+ "serialization",
+ "integer",
+]
+categories = [
+ "encoding",
+ "no-std",
+]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/serde-repr"
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[lib]
+proc-macro = true
+
+[dependencies.proc-macro2]
+version = "1.0"
+
+[dependencies.quote]
+version = "1.0"
+
+[dependencies.syn]
+version = "1.0"
+
+[dev-dependencies.rustversion]
+version = "1.0"
+
+[dev-dependencies.serde]
+version = "1.0"
+
+[dev-dependencies.serde_json]
+version = "1.0"
+
+[dev-dependencies.trybuild]
+version = "1.0.49"
+features = ["diff"]
diff --git a/third_party/rust/serde_repr/LICENSE-APACHE b/third_party/rust/serde_repr/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/serde_repr/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/third_party/rust/serde_repr/LICENSE-MIT b/third_party/rust/serde_repr/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/third_party/rust/serde_repr/LICENSE-MIT
@@ -0,0 +1,23 @@
+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.
diff --git a/third_party/rust/serde_repr/README.md b/third_party/rust/serde_repr/README.md
new file mode 100644
index 0000000000..a932449e51
--- /dev/null
+++ b/third_party/rust/serde_repr/README.md
@@ -0,0 +1,57 @@
+Serde repr derive
+=================
+
+[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/serde--repr-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/serde-repr)
+[<img alt="crates.io" src="https://img.shields.io/crates/v/serde_repr.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/serde_repr)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-serde__repr-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/serde_repr)
+[<img alt="build status" src="https://img.shields.io/github/actions/workflow/status/dtolnay/serde-repr/ci.yml?branch=master&style=for-the-badge" height="20">](https://github.com/dtolnay/serde-repr/actions?query=branch%3Amaster)
+
+This crate provides a derive macro to derive Serde's `Serialize` and
+`Deserialize` traits in a way that delegates to the underlying repr of a C-like
+enum.
+
+```toml
+[dependencies]
+serde = "1.0"
+serde_repr = "0.1"
+```
+
+```rust
+use serde_repr::{Serialize_repr, Deserialize_repr};
+
+#[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
+#[repr(u8)]
+enum SmallPrime {
+ Two = 2,
+ Three = 3,
+ Five = 5,
+ Seven = 7,
+}
+
+fn main() -> serde_json::Result<()> {
+ let j = serde_json::to_string(&SmallPrime::Seven)?;
+ assert_eq!(j, "7");
+
+ let p: SmallPrime = serde_json::from_str("2")?;
+ assert_eq!(p, SmallPrime::Two);
+
+ Ok(())
+}
+```
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
+be dual licensed as above, without any additional terms or conditions.
+</sub>
diff --git a/third_party/rust/serde_repr/src/lib.rs b/third_party/rust/serde_repr/src/lib.rs
new file mode 100644
index 0000000000..2ad67df065
--- /dev/null
+++ b/third_party/rust/serde_repr/src/lib.rs
@@ -0,0 +1,140 @@
+//! [![github]](https://github.com/dtolnay/serde-repr)&ensp;[![crates-io]](https://crates.io/crates/serde_repr)&ensp;[![docs-rs]](https://docs.rs/serde_repr)
+//!
+//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
+//!
+//! <br>
+//!
+//! Derive `Serialize` and `Deserialize` that delegates to the underlying repr
+//! of a C-like enum.
+//!
+//! # Examples
+//!
+//! ```
+//! use serde_repr::{Serialize_repr, Deserialize_repr};
+//!
+//! #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
+//! #[repr(u8)]
+//! enum SmallPrime {
+//! Two = 2,
+//! Three = 3,
+//! Five = 5,
+//! Seven = 7,
+//! }
+//!
+//! fn main() -> serde_json::Result<()> {
+//! let j = serde_json::to_string(&SmallPrime::Seven)?;
+//! assert_eq!(j, "7");
+//!
+//! let p: SmallPrime = serde_json::from_str("2")?;
+//! assert_eq!(p, SmallPrime::Two);
+//!
+//! Ok(())
+//! }
+//! ```
+
+#![allow(clippy::single_match_else)]
+
+extern crate proc_macro;
+
+mod parse;
+
+use proc_macro::TokenStream;
+use quote::quote;
+use syn::parse_macro_input;
+
+use crate::parse::Input;
+
+#[proc_macro_derive(Serialize_repr)]
+pub fn derive_serialize(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as Input);
+ let ident = input.ident;
+ let repr = input.repr;
+
+ let match_variants = input.variants.iter().map(|variant| {
+ let variant = &variant.ident;
+ quote! {
+ #ident::#variant => #ident::#variant as #repr,
+ }
+ });
+
+ TokenStream::from(quote! {
+ impl serde::Serialize for #ident {
+ #[allow(clippy::use_self)]
+ fn serialize<S>(&self, serializer: S) -> core::result::Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer
+ {
+ let value: #repr = match *self {
+ #(#match_variants)*
+ };
+ serde::Serialize::serialize(&value, serializer)
+ }
+ }
+ })
+}
+
+#[proc_macro_derive(Deserialize_repr, attributes(serde))]
+pub fn derive_deserialize(input: TokenStream) -> TokenStream {
+ let input = parse_macro_input!(input as Input);
+ let ident = input.ident;
+ let repr = input.repr;
+ let variants = input.variants.iter().map(|variant| &variant.ident);
+
+ let declare_discriminants = input.variants.iter().map(|variant| {
+ let variant = &variant.ident;
+ quote! {
+ const #variant: #repr = #ident::#variant as #repr;
+ }
+ });
+
+ let match_discriminants = input.variants.iter().map(|variant| {
+ let variant = &variant.ident;
+ quote! {
+ discriminant::#variant => core::result::Result::Ok(#ident::#variant),
+ }
+ });
+
+ let error_format = match input.variants.len() {
+ 1 => "invalid value: {}, expected {}".to_owned(),
+ 2 => "invalid value: {}, expected {} or {}".to_owned(),
+ n => "invalid value: {}, expected one of: {}".to_owned() + &", {}".repeat(n - 1),
+ };
+
+ let other_arm = match input.default_variant {
+ Some(variant) => {
+ let variant = &variant.ident;
+ quote! {
+ core::result::Result::Ok(#ident::#variant)
+ }
+ }
+ None => quote! {
+ core::result::Result::Err(serde::de::Error::custom(
+ format_args!(#error_format, other #(, discriminant::#variants)*)
+ ))
+ },
+ };
+
+ TokenStream::from(quote! {
+ impl<'de> serde::Deserialize<'de> for #ident {
+ #[allow(clippy::use_self)]
+ fn deserialize<D>(deserializer: D) -> core::result::Result<Self, D::Error>
+ where
+ D: serde::Deserializer<'de>,
+ {
+ struct discriminant;
+
+ #[allow(non_upper_case_globals)]
+ impl discriminant {
+ #(#declare_discriminants)*
+ }
+
+ match <#repr as serde::Deserialize>::deserialize(deserializer)? {
+ #(#match_discriminants)*
+ other => #other_arm,
+ }
+ }
+ }
+ })
+}
diff --git a/third_party/rust/serde_repr/src/parse.rs b/third_party/rust/serde_repr/src/parse.rs
new file mode 100644
index 0000000000..2c0ad1e7dc
--- /dev/null
+++ b/third_party/rust/serde_repr/src/parse.rs
@@ -0,0 +1,114 @@
+use proc_macro2::Span;
+use syn::parse::{Error, Parse, ParseStream, Parser, Result};
+use syn::{parenthesized, Data, DeriveInput, Fields, Ident, Meta, NestedMeta};
+
+pub struct Input {
+ pub ident: Ident,
+ pub repr: Ident,
+ pub variants: Vec<Variant>,
+ pub default_variant: Option<Variant>,
+}
+
+#[derive(Clone)]
+pub struct Variant {
+ pub ident: Ident,
+ pub attrs: VariantAttrs,
+}
+
+#[derive(Clone)]
+pub struct VariantAttrs {
+ pub is_default: bool,
+}
+
+fn parse_meta(attrs: &mut VariantAttrs, meta: &Meta) {
+ if let Meta::List(value) = meta {
+ for meta in &value.nested {
+ if let NestedMeta::Meta(Meta::Path(path)) = meta {
+ if path.is_ident("other") {
+ attrs.is_default = true;
+ }
+ }
+ }
+ }
+}
+
+fn parse_attrs(variant: &syn::Variant) -> Result<VariantAttrs> {
+ let mut attrs = VariantAttrs { is_default: false };
+ for attr in &variant.attrs {
+ if attr.path.is_ident("serde") {
+ parse_meta(&mut attrs, &attr.parse_meta()?);
+ }
+ }
+ Ok(attrs)
+}
+
+impl Parse for Input {
+ fn parse(input: ParseStream) -> Result<Self> {
+ let call_site = Span::call_site();
+ let derive_input = DeriveInput::parse(input)?;
+
+ let data = match derive_input.data {
+ Data::Enum(data) => data,
+ _ => {
+ return Err(Error::new(call_site, "input must be an enum"));
+ }
+ };
+
+ let variants = data
+ .variants
+ .into_iter()
+ .map(|variant| match variant.fields {
+ Fields::Unit => {
+ let attrs = parse_attrs(&variant)?;
+ Ok(Variant {
+ ident: variant.ident,
+ attrs,
+ })
+ }
+ Fields::Named(_) | Fields::Unnamed(_) => {
+ Err(Error::new(variant.ident.span(), "must be a unit variant"))
+ }
+ })
+ .collect::<Result<Vec<Variant>>>()?;
+
+ if variants.is_empty() {
+ return Err(Error::new(call_site, "there must be at least one variant"));
+ }
+
+ let generics = derive_input.generics;
+ if !generics.params.is_empty() || generics.where_clause.is_some() {
+ return Err(Error::new(call_site, "generic enum is not supported"));
+ }
+
+ let mut repr = None;
+ for attr in derive_input.attrs {
+ if attr.path.is_ident("repr") {
+ fn repr_arg(input: ParseStream) -> Result<Ident> {
+ let content;
+ parenthesized!(content in input);
+ content.parse()
+ }
+ let ty = repr_arg.parse2(attr.tokens)?;
+ repr = Some(ty);
+ break;
+ }
+ }
+ let repr = repr.ok_or_else(|| Error::new(call_site, "missing #[repr(...)] attribute"))?;
+
+ let mut default_variants = variants.iter().filter(|x| x.attrs.is_default);
+ let default_variant = default_variants.next().cloned();
+ if default_variants.next().is_some() {
+ return Err(Error::new(
+ call_site,
+ "only one variant can be #[serde(other)]",
+ ));
+ }
+
+ Ok(Input {
+ ident: derive_input.ident,
+ repr,
+ variants,
+ default_variant,
+ })
+ }
+}
diff --git a/third_party/rust/serde_repr/tests/compiletest.rs b/third_party/rust/serde_repr/tests/compiletest.rs
new file mode 100644
index 0000000000..7974a6249e
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/compiletest.rs
@@ -0,0 +1,7 @@
+#[rustversion::attr(not(nightly), ignore)]
+#[cfg_attr(miri, ignore)]
+#[test]
+fn ui() {
+ let t = trybuild::TestCases::new();
+ t.compile_fail("tests/ui/*.rs");
+}
diff --git a/third_party/rust/serde_repr/tests/test.rs b/third_party/rust/serde_repr/tests/test.rs
new file mode 100644
index 0000000000..d442448dd5
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/test.rs
@@ -0,0 +1,81 @@
+#![allow(
+ clippy::derive_partial_eq_without_eq,
+ // Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422
+ clippy::nonstandard_macro_braces,
+ clippy::wildcard_imports,
+)]
+
+use serde_repr::{Deserialize_repr, Serialize_repr};
+
+mod small_prime {
+ use super::*;
+
+ #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
+ #[repr(u8)]
+ enum SmallPrime {
+ Two = 2,
+ Three = 3,
+ Five = 5,
+ Seven = 7,
+ }
+
+ #[test]
+ fn test_serialize() {
+ let j = serde_json::to_string(&SmallPrime::Seven).unwrap();
+ assert_eq!(j, "7");
+ }
+
+ #[test]
+ fn test_deserialize() {
+ let p: SmallPrime = serde_json::from_str("2").unwrap();
+ assert_eq!(p, SmallPrime::Two);
+ }
+}
+
+mod other {
+ use super::*;
+
+ #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
+ #[repr(u8)]
+ enum TestOther {
+ A,
+ B,
+ #[serde(other, rename = "useless")]
+ Other,
+ }
+
+ #[test]
+ fn test_deserialize() {
+ let p: TestOther = serde_json::from_str("0").unwrap();
+ assert_eq!(p, TestOther::A);
+ let p: TestOther = serde_json::from_str("1").unwrap();
+ assert_eq!(p, TestOther::B);
+ let p: TestOther = serde_json::from_str("5").unwrap();
+ assert_eq!(p, TestOther::Other);
+ }
+}
+
+mod implicit_discriminant {
+ use super::*;
+
+ #[derive(Serialize_repr, Deserialize_repr, PartialEq, Debug)]
+ #[repr(u8)]
+ enum ImplicitDiscriminant {
+ Zero,
+ One,
+ Two,
+ Three,
+ }
+
+ #[test]
+ fn test_serialize() {
+ let j = serde_json::to_string(&ImplicitDiscriminant::Three).unwrap();
+ assert_eq!(j, "3");
+ }
+
+ #[test]
+ fn test_deserialize() {
+ let p: ImplicitDiscriminant = serde_json::from_str("2").unwrap();
+ assert_eq!(p, ImplicitDiscriminant::Two);
+ }
+}
diff --git a/third_party/rust/serde_repr/tests/ui/empty_enum.rs b/third_party/rust/serde_repr/tests/ui/empty_enum.rs
new file mode 100644
index 0000000000..f1fb6f9d56
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/ui/empty_enum.rs
@@ -0,0 +1,6 @@
+use serde_repr::Serialize_repr;
+
+#[derive(Serialize_repr)]
+enum SmallPrime {}
+
+fn main() {}
diff --git a/third_party/rust/serde_repr/tests/ui/empty_enum.stderr b/third_party/rust/serde_repr/tests/ui/empty_enum.stderr
new file mode 100644
index 0000000000..d7c4de19b3
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/ui/empty_enum.stderr
@@ -0,0 +1,7 @@
+error: there must be at least one variant
+ --> tests/ui/empty_enum.rs:3:10
+ |
+3 | #[derive(Serialize_repr)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: this error originates in the derive macro `Serialize_repr` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/serde_repr/tests/ui/missing_repr.rs b/third_party/rust/serde_repr/tests/ui/missing_repr.rs
new file mode 100644
index 0000000000..00836356b9
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/ui/missing_repr.rs
@@ -0,0 +1,11 @@
+use serde_repr::Serialize_repr;
+
+#[derive(Serialize_repr)]
+enum SmallPrime {
+ Two = 2,
+ Three = 3,
+ Five = 5,
+ Seven = 7,
+}
+
+fn main() {}
diff --git a/third_party/rust/serde_repr/tests/ui/missing_repr.stderr b/third_party/rust/serde_repr/tests/ui/missing_repr.stderr
new file mode 100644
index 0000000000..e011be6f1c
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/ui/missing_repr.stderr
@@ -0,0 +1,7 @@
+error: missing #[repr(...)] attribute
+ --> tests/ui/missing_repr.rs:3:10
+ |
+3 | #[derive(Serialize_repr)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: this error originates in the derive macro `Serialize_repr` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/serde_repr/tests/ui/multiple_others.rs b/third_party/rust/serde_repr/tests/ui/multiple_others.rs
new file mode 100644
index 0000000000..fdb552b109
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/ui/multiple_others.rs
@@ -0,0 +1,12 @@
+use serde_repr::Deserialize_repr;
+
+#[derive(Deserialize_repr)]
+#[repr(u8)]
+enum MultipleOthers {
+ #[serde(other)]
+ A,
+ #[serde(other)]
+ B,
+}
+
+fn main() {}
diff --git a/third_party/rust/serde_repr/tests/ui/multiple_others.stderr b/third_party/rust/serde_repr/tests/ui/multiple_others.stderr
new file mode 100644
index 0000000000..599d5e1724
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/ui/multiple_others.stderr
@@ -0,0 +1,7 @@
+error: only one variant can be #[serde(other)]
+ --> tests/ui/multiple_others.rs:3:10
+ |
+3 | #[derive(Deserialize_repr)]
+ | ^^^^^^^^^^^^^^^^
+ |
+ = note: this error originates in the derive macro `Deserialize_repr` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/serde_repr/tests/ui/non_unit_variant.rs b/third_party/rust/serde_repr/tests/ui/non_unit_variant.rs
new file mode 100644
index 0000000000..9cdc80d0af
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/ui/non_unit_variant.rs
@@ -0,0 +1,12 @@
+use serde_repr::Serialize_repr;
+
+#[derive(Serialize_repr)]
+#[repr(u8)]
+enum SmallPrime {
+ Two(u8),
+ Three(u8),
+ Five(u8),
+ Seven(u8),
+}
+
+fn main() {}
diff --git a/third_party/rust/serde_repr/tests/ui/non_unit_variant.stderr b/third_party/rust/serde_repr/tests/ui/non_unit_variant.stderr
new file mode 100644
index 0000000000..8eaf0c1d9b
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/ui/non_unit_variant.stderr
@@ -0,0 +1,5 @@
+error: must be a unit variant
+ --> tests/ui/non_unit_variant.rs:6:5
+ |
+6 | Two(u8),
+ | ^^^
diff --git a/third_party/rust/serde_repr/tests/ui/not_enum.rs b/third_party/rust/serde_repr/tests/ui/not_enum.rs
new file mode 100644
index 0000000000..92a1d746dc
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/ui/not_enum.rs
@@ -0,0 +1,11 @@
+use serde_repr::Serialize_repr;
+
+#[derive(Serialize_repr)]
+struct SmallPrime {
+ two: u8,
+ three: u8,
+ five: u8,
+ seven: u8,
+}
+
+fn main() {}
diff --git a/third_party/rust/serde_repr/tests/ui/not_enum.stderr b/third_party/rust/serde_repr/tests/ui/not_enum.stderr
new file mode 100644
index 0000000000..26ad4c313f
--- /dev/null
+++ b/third_party/rust/serde_repr/tests/ui/not_enum.stderr
@@ -0,0 +1,7 @@
+error: input must be an enum
+ --> tests/ui/not_enum.rs:3:10
+ |
+3 | #[derive(Serialize_repr)]
+ | ^^^^^^^^^^^^^^
+ |
+ = note: this error originates in the derive macro `Serialize_repr` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/third_party/rust/serde_urlencoded/.cargo-checksum.json b/third_party/rust/serde_urlencoded/.cargo-checksum.json
new file mode 100644
index 0000000000..126414d161
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"776416273e0e2004aaf8869df552bd0ff39858184730540604dad69e4dd17873","LICENSE-APACHE":"62c7a1e35f56406896d7aa7ca52d0cc0d272ac022b5d2796e7d6905db8a3636a","LICENSE-MIT":"b9eb266294324f672cbe945fe8f2e32f85024f0d61a1a7d14382cdde0ac44769","README.md":"0adc2e76e529922436075eddeaaf8decf04f1a642f0e6d9c513b634e72c00699","rustfmt.toml":"5dab9ecd7e76bc1f49cc5a6985196912b9ac8086dfb70833b6251721ba5bf74c","src/de.rs":"3e7ed20d227e2dab88c201f9fda80ebc39b8219fe66ceaf6bef478ca5c9bd891","src/lib.rs":"83718fe61b847408cd08da3515ce4f4ec45998615605b6e878461313986d8571","src/ser/key.rs":"4651a34088cf08b948b27e885efe5c1f6876dbd70f502892bbb7710ce76c878f","src/ser/mod.rs":"2a2eeaf30790e24fbee6bb2ba140dc29343ef797bf3668587892f2c6d2644648","src/ser/pair.rs":"be19e319092dba66aac06bae47f77d2ef39c4c308bbd67c13d031ab88c0e68e7","src/ser/part.rs":"8da25ff5a5159a05dd4b221a757aac514975243b4860aa5eee4ad4500a46d48b","src/ser/value.rs":"5eacb91e054476b982c5fa1b0b38179e844ca79842170d47665aca9e4515552a","tests/test_deserialize.rs":"4525a4d05fd86b2535d50857adab101a02bb5c61a6cb9c138513c8687eca32a7","tests/test_serialize.rs":"2f57ffda172d84573c5d9abe2d700b756fa844639ff0f1bf295441429ddd662b"},"package":"d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd"} \ No newline at end of file
diff --git a/third_party/rust/serde_urlencoded/Cargo.toml b/third_party/rust/serde_urlencoded/Cargo.toml
new file mode 100644
index 0000000000..dfe8cc1ff2
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/Cargo.toml
@@ -0,0 +1,41 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+name = "serde_urlencoded"
+version = "0.7.1"
+authors = ["Anthony Ramine <n.oxyde@gmail.com>"]
+exclude = ["/.travis.yml", "/bors.toml"]
+description = "`x-www-form-urlencoded` meets Serde"
+documentation = "https://docs.rs/serde_urlencoded/0.7.1/serde_urlencoded/"
+keywords = ["serde", "serialization", "urlencoded"]
+categories = ["encoding", "web-programming"]
+license = "MIT/Apache-2.0"
+repository = "https://github.com/nox/serde_urlencoded"
+
+[lib]
+test = false
+[dependencies.form_urlencoded]
+version = "1"
+
+[dependencies.itoa]
+version = "1"
+
+[dependencies.ryu]
+version = "1"
+
+[dependencies.serde]
+version = "1.0.69"
+[dev-dependencies.serde_derive]
+version = "1"
+[badges.travis-ci]
+repository = "nox/serde_urlencoded"
diff --git a/third_party/rust/serde_urlencoded/LICENSE-APACHE b/third_party/rust/serde_urlencoded/LICENSE-APACHE
new file mode 100644
index 0000000000..1b5ec8b78e
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/LICENSE-APACHE
@@ -0,0 +1,176 @@
+ 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
diff --git a/third_party/rust/serde_urlencoded/LICENSE-MIT b/third_party/rust/serde_urlencoded/LICENSE-MIT
new file mode 100644
index 0000000000..39f6303ad3
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2016 Anthony Ramine
+
+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.
diff --git a/third_party/rust/serde_urlencoded/README.md b/third_party/rust/serde_urlencoded/README.md
new file mode 100644
index 0000000000..92cacb65b8
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/README.md
@@ -0,0 +1,53 @@
+`x-www-form-urlencoded` meets Serde
+===================================
+
+This crate is a Rust library for serialising to and deserialising from
+the [`application/x-www-form-urlencoded`][urlencoded] format. It is built
+upon [Serde], a high performance generic serialization framework and [rust-url],
+a URL parser for Rust.
+
+[rust-url]: https://github.com/servo/rust-url
+[Serde]: https://github.com/serde-rs/serde
+[urlencoded]: https://url.spec.whatwg.org/#application/x-www-form-urlencoded
+
+Installation
+============
+
+This crate works with Cargo and can be found on
+[crates.io] with a `Cargo.toml` like:
+
+```toml
+[dependencies]
+serde_urlencoded = "0.7"
+```
+
+The documentation is available on [docs.rs].
+
+[crates.io]: https://crates.io/crates/serde_urlencoded
+[docs.rs]: https://docs.rs/serde_urlencoded/0.7.1/serde_urlencoded/
+
+## Getting help
+
+Serde developers live in the #serde channel on
+[`irc.mozilla.org`](https://wiki.mozilla.org/IRC) and most rust-url developers
+live in the #servo one. The #rust channel is also a good resource with generally
+faster response time but less specific knowledge about Serde, rust-url or this
+crate. If IRC is not your thing, we are happy to respond to [GitHub
+issues](https://github.com/nox/serde_urlencoded/issues/new) as well.
+
+## License
+
+serde_urlencoded 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_urlencoded by you, as defined in the Apache-2.0 license,
+shall be dual licensed as above, without any additional terms or conditions.
diff --git a/third_party/rust/serde_urlencoded/rustfmt.toml b/third_party/rust/serde_urlencoded/rustfmt.toml
new file mode 100644
index 0000000000..f80ce4e9c8
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/rustfmt.toml
@@ -0,0 +1,5 @@
+match_block_trailing_comma = false
+max_width = 80
+newline_style = "Unix"
+reorder_imports = true
+use_try_shorthand = true
diff --git a/third_party/rust/serde_urlencoded/src/de.rs b/third_party/rust/serde_urlencoded/src/de.rs
new file mode 100644
index 0000000000..d906eaae2a
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/src/de.rs
@@ -0,0 +1,321 @@
+//! Deserialization support for the `application/x-www-form-urlencoded` format.
+
+use form_urlencoded::parse;
+use form_urlencoded::Parse as UrlEncodedParse;
+use serde::de::value::MapDeserializer;
+use serde::de::Error as de_Error;
+use serde::de::{self, IntoDeserializer};
+use serde::forward_to_deserialize_any;
+use std::borrow::Cow;
+use std::io::Read;
+
+#[doc(inline)]
+pub use serde::de::value::Error;
+
+/// Deserializes a `application/x-www-form-urlencoded` value from a `&[u8]`.
+///
+/// ```
+/// let meal = vec![
+/// ("bread".to_owned(), "baguette".to_owned()),
+/// ("cheese".to_owned(), "comté".to_owned()),
+/// ("meat".to_owned(), "ham".to_owned()),
+/// ("fat".to_owned(), "butter".to_owned()),
+/// ];
+///
+/// assert_eq!(
+/// serde_urlencoded::from_bytes::<Vec<(String, String)>>(
+/// b"bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter"),
+/// Ok(meal));
+/// ```
+pub fn from_bytes<'de, T>(input: &'de [u8]) -> Result<T, Error>
+where
+ T: de::Deserialize<'de>,
+{
+ T::deserialize(Deserializer::new(parse(input)))
+}
+
+/// Deserializes a `application/x-www-form-urlencoded` value from a `&str`.
+///
+/// ```
+/// let meal = vec![
+/// ("bread".to_owned(), "baguette".to_owned()),
+/// ("cheese".to_owned(), "comté".to_owned()),
+/// ("meat".to_owned(), "ham".to_owned()),
+/// ("fat".to_owned(), "butter".to_owned()),
+/// ];
+///
+/// assert_eq!(
+/// serde_urlencoded::from_str::<Vec<(String, String)>>(
+/// "bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter"),
+/// Ok(meal));
+/// ```
+pub fn from_str<'de, T>(input: &'de str) -> Result<T, Error>
+where
+ T: de::Deserialize<'de>,
+{
+ from_bytes(input.as_bytes())
+}
+
+/// Convenience function that reads all bytes from `reader` and deserializes
+/// them with `from_bytes`.
+pub fn from_reader<T, R>(mut reader: R) -> Result<T, Error>
+where
+ T: de::DeserializeOwned,
+ R: Read,
+{
+ let mut buf = vec![];
+ reader.read_to_end(&mut buf).map_err(|e| {
+ de::Error::custom(format_args!("could not read input: {}", e))
+ })?;
+ from_bytes(&buf)
+}
+
+/// A deserializer for the `application/x-www-form-urlencoded` format.
+///
+/// * Supported top-level outputs are structs, maps and sequences of pairs,
+/// with or without a given length.
+///
+/// * Main `deserialize` methods defers to `deserialize_map`.
+///
+/// * Everything else but `deserialize_seq` and `deserialize_seq_fixed_size`
+/// defers to `deserialize`.
+pub struct Deserializer<'de> {
+ inner: MapDeserializer<'de, PartIterator<'de>, Error>,
+}
+
+impl<'de> Deserializer<'de> {
+ /// Returns a new `Deserializer`.
+ pub fn new(parser: UrlEncodedParse<'de>) -> Self {
+ Deserializer {
+ inner: MapDeserializer::new(PartIterator(parser)),
+ }
+ }
+}
+
+impl<'de> de::Deserializer<'de> for Deserializer<'de> {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.deserialize_map(visitor)
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_map(self.inner)
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_seq(self.inner)
+ }
+
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ self.inner.end()?;
+ visitor.visit_unit()
+ }
+
+ forward_to_deserialize_any! {
+ bool
+ u8
+ u16
+ u32
+ u64
+ i8
+ i16
+ i32
+ i64
+ f32
+ f64
+ char
+ str
+ string
+ option
+ bytes
+ byte_buf
+ unit_struct
+ newtype_struct
+ tuple_struct
+ struct
+ identifier
+ tuple
+ enum
+ ignored_any
+ }
+}
+
+struct PartIterator<'de>(UrlEncodedParse<'de>);
+
+impl<'de> Iterator for PartIterator<'de> {
+ type Item = (Part<'de>, Part<'de>);
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.0.next().map(|(k, v)| (Part(k), Part(v)))
+ }
+}
+
+struct Part<'de>(Cow<'de, str>);
+
+impl<'de> IntoDeserializer<'de> for Part<'de> {
+ type Deserializer = Self;
+
+ fn into_deserializer(self) -> Self::Deserializer {
+ self
+ }
+}
+
+macro_rules! forward_parsed_value {
+ ($($ty:ident => $method:ident,)*) => {
+ $(
+ fn $method<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where V: de::Visitor<'de>
+ {
+ match self.0.parse::<$ty>() {
+ Ok(val) => val.into_deserializer().$method(visitor),
+ Err(e) => Err(de::Error::custom(e))
+ }
+ }
+ )*
+ }
+}
+
+impl<'de> de::Deserializer<'de> for Part<'de> {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ match self.0 {
+ Cow::Borrowed(value) => visitor.visit_borrowed_str(value),
+ Cow::Owned(value) => visitor.visit_string(value),
+ }
+ }
+
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_some(self)
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ _name: &'static str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_enum(ValueEnumAccess(self.0))
+ }
+
+ fn deserialize_newtype_struct<V>(
+ self,
+ _name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ visitor.visit_newtype_struct(self)
+ }
+
+ forward_to_deserialize_any! {
+ char
+ str
+ string
+ unit
+ bytes
+ byte_buf
+ unit_struct
+ tuple_struct
+ struct
+ identifier
+ tuple
+ ignored_any
+ seq
+ map
+ }
+
+ forward_parsed_value! {
+ bool => deserialize_bool,
+ u8 => deserialize_u8,
+ u16 => deserialize_u16,
+ u32 => deserialize_u32,
+ u64 => deserialize_u64,
+ i8 => deserialize_i8,
+ i16 => deserialize_i16,
+ i32 => deserialize_i32,
+ i64 => deserialize_i64,
+ f32 => deserialize_f32,
+ f64 => deserialize_f64,
+ }
+}
+
+struct ValueEnumAccess<'de>(Cow<'de, str>);
+
+impl<'de> de::EnumAccess<'de> for ValueEnumAccess<'de> {
+ type Error = Error;
+ type Variant = UnitOnlyVariantAccess;
+
+ fn variant_seed<V>(
+ self,
+ seed: V,
+ ) -> Result<(V::Value, Self::Variant), Self::Error>
+ where
+ V: de::DeserializeSeed<'de>,
+ {
+ let variant = seed.deserialize(self.0.into_deserializer())?;
+ Ok((variant, UnitOnlyVariantAccess))
+ }
+}
+
+struct UnitOnlyVariantAccess;
+
+impl<'de> de::VariantAccess<'de> for UnitOnlyVariantAccess {
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<(), Self::Error> {
+ Ok(())
+ }
+
+ fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value, Self::Error>
+ where
+ T: de::DeserializeSeed<'de>,
+ {
+ Err(Error::custom("expected unit variant"))
+ }
+
+ fn tuple_variant<V>(
+ self,
+ _len: usize,
+ _visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(Error::custom("expected unit variant"))
+ }
+
+ fn struct_variant<V>(
+ self,
+ _fields: &'static [&'static str],
+ _visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: de::Visitor<'de>,
+ {
+ Err(Error::custom("expected unit variant"))
+ }
+}
diff --git a/third_party/rust/serde_urlencoded/src/lib.rs b/third_party/rust/serde_urlencoded/src/lib.rs
new file mode 100644
index 0000000000..b7ccc783f5
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/src/lib.rs
@@ -0,0 +1,12 @@
+//! `x-www-form-urlencoded` meets Serde
+
+#![warn(unused_extern_crates)]
+#![forbid(unsafe_code)]
+
+pub mod de;
+pub mod ser;
+
+#[doc(inline)]
+pub use crate::de::{from_bytes, from_reader, from_str, Deserializer};
+#[doc(inline)]
+pub use crate::ser::{to_string, Serializer};
diff --git a/third_party/rust/serde_urlencoded/src/ser/key.rs b/third_party/rust/serde_urlencoded/src/ser/key.rs
new file mode 100644
index 0000000000..8128a64ebb
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/src/ser/key.rs
@@ -0,0 +1,77 @@
+use crate::ser::part::Sink;
+use crate::ser::Error;
+use serde::Serialize;
+use std::borrow::Cow;
+use std::ops::Deref;
+
+pub enum Key<'key> {
+ Static(&'static str),
+ Dynamic(Cow<'key, str>),
+}
+
+impl<'key> Deref for Key<'key> {
+ type Target = str;
+
+ fn deref(&self) -> &str {
+ match *self {
+ Key::Static(key) => key,
+ Key::Dynamic(ref key) => key,
+ }
+ }
+}
+
+impl<'key> From<Key<'key>> for Cow<'static, str> {
+ fn from(key: Key<'key>) -> Self {
+ match key {
+ Key::Static(key) => key.into(),
+ Key::Dynamic(key) => key.into_owned().into(),
+ }
+ }
+}
+
+pub struct KeySink<End> {
+ end: End,
+}
+
+impl<End, Ok> KeySink<End>
+where
+ End: for<'key> FnOnce(Key<'key>) -> Result<Ok, Error>,
+{
+ pub fn new(end: End) -> Self {
+ KeySink { end }
+ }
+}
+
+impl<End, Ok> Sink for KeySink<End>
+where
+ End: for<'key> FnOnce(Key<'key>) -> Result<Ok, Error>,
+{
+ type Ok = Ok;
+
+ fn serialize_static_str(self, value: &'static str) -> Result<Ok, Error> {
+ (self.end)(Key::Static(value))
+ }
+
+ fn serialize_str(self, value: &str) -> Result<Ok, Error> {
+ (self.end)(Key::Dynamic(value.into()))
+ }
+
+ fn serialize_string(self, value: String) -> Result<Ok, Error> {
+ (self.end)(Key::Dynamic(value.into()))
+ }
+
+ fn serialize_none(self) -> Result<Ok, Error> {
+ Err(self.unsupported())
+ }
+
+ fn serialize_some<T: ?Sized + Serialize>(
+ self,
+ _value: &T,
+ ) -> Result<Ok, Error> {
+ Err(self.unsupported())
+ }
+
+ fn unsupported(self) -> Error {
+ Error::Custom("unsupported key".into())
+ }
+}
diff --git a/third_party/rust/serde_urlencoded/src/ser/mod.rs b/third_party/rust/serde_urlencoded/src/ser/mod.rs
new file mode 100644
index 0000000000..d75b9022b2
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/src/ser/mod.rs
@@ -0,0 +1,555 @@
+//! Serialization support for the `application/x-www-form-urlencoded` format.
+
+mod key;
+mod pair;
+mod part;
+mod value;
+
+use form_urlencoded::Serializer as UrlEncodedSerializer;
+use form_urlencoded::Target as UrlEncodedTarget;
+use serde::ser;
+use std::borrow::Cow;
+use std::error;
+use std::fmt;
+use std::str;
+
+/// Serializes a value into a `application/x-www-form-urlencoded` `String` buffer.
+///
+/// ```
+/// let meal = &[
+/// ("bread", "baguette"),
+/// ("cheese", "comté"),
+/// ("meat", "ham"),
+/// ("fat", "butter"),
+/// ];
+///
+/// assert_eq!(
+/// serde_urlencoded::to_string(meal),
+/// Ok("bread=baguette&cheese=comt%C3%A9&meat=ham&fat=butter".to_owned()));
+/// ```
+pub fn to_string<T: ser::Serialize>(input: T) -> Result<String, Error> {
+ let mut urlencoder = UrlEncodedSerializer::new("".to_owned());
+ input.serialize(Serializer::new(&mut urlencoder))?;
+ Ok(urlencoder.finish())
+}
+
+/// A serializer for the `application/x-www-form-urlencoded` format.
+///
+/// * Supported top-level inputs are structs, maps and sequences of pairs,
+/// with or without a given length.
+///
+/// * Supported keys and values are integers, bytes (if convertible to strings),
+/// unit structs and unit variants.
+///
+/// * Newtype structs defer to their inner values.
+pub struct Serializer<'input, 'output, Target: UrlEncodedTarget> {
+ urlencoder: &'output mut UrlEncodedSerializer<'input, Target>,
+}
+
+impl<'input, 'output, Target: 'output + UrlEncodedTarget>
+ Serializer<'input, 'output, Target>
+{
+ /// Returns a new `Serializer`.
+ pub fn new(
+ urlencoder: &'output mut UrlEncodedSerializer<'input, Target>,
+ ) -> Self {
+ Serializer { urlencoder }
+ }
+}
+
+/// Errors returned during serializing to `application/x-www-form-urlencoded`.
+#[derive(Clone, Debug, PartialEq, Eq)]
+pub enum Error {
+ Custom(Cow<'static, str>),
+ Utf8(str::Utf8Error),
+}
+
+impl fmt::Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ match *self {
+ Error::Custom(ref msg) => msg.fmt(f),
+ Error::Utf8(ref err) => write!(f, "invalid UTF-8: {}", err),
+ }
+ }
+}
+
+impl error::Error for Error {
+ fn description(&self) -> &str {
+ match *self {
+ Error::Custom(ref msg) => msg,
+ Error::Utf8(ref err) => error::Error::description(err),
+ }
+ }
+
+ /// The lower-level cause of this error, in the case of a `Utf8` error.
+ fn cause(&self) -> Option<&dyn error::Error> {
+ match *self {
+ Error::Custom(_) => None,
+ Error::Utf8(ref err) => Some(err),
+ }
+ }
+
+ /// The lower-level source of this error, in the case of a `Utf8` error.
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+ match *self {
+ Error::Custom(_) => None,
+ Error::Utf8(ref err) => Some(err),
+ }
+ }
+}
+
+impl ser::Error for Error {
+ fn custom<T: fmt::Display>(msg: T) -> Self {
+ Error::Custom(format!("{}", msg).into())
+ }
+}
+
+/// Sequence serializer.
+pub struct SeqSerializer<'input, 'output, Target: UrlEncodedTarget> {
+ urlencoder: &'output mut UrlEncodedSerializer<'input, Target>,
+}
+
+/// Tuple serializer.
+///
+/// Mostly used for arrays.
+pub struct TupleSerializer<'input, 'output, Target: UrlEncodedTarget> {
+ urlencoder: &'output mut UrlEncodedSerializer<'input, Target>,
+}
+
+/// Tuple struct serializer.
+///
+/// Never instantiated, tuple structs are not supported.
+pub struct TupleStructSerializer<'input, 'output, T: UrlEncodedTarget> {
+ inner: ser::Impossible<&'output mut UrlEncodedSerializer<'input, T>, Error>,
+}
+
+/// Tuple variant serializer.
+///
+/// Never instantiated, tuple variants are not supported.
+pub struct TupleVariantSerializer<'input, 'output, T: UrlEncodedTarget> {
+ inner: ser::Impossible<&'output mut UrlEncodedSerializer<'input, T>, Error>,
+}
+
+/// Map serializer.
+pub struct MapSerializer<'input, 'output, Target: UrlEncodedTarget> {
+ urlencoder: &'output mut UrlEncodedSerializer<'input, Target>,
+ key: Option<Cow<'static, str>>,
+}
+
+/// Struct serializer.
+pub struct StructSerializer<'input, 'output, Target: UrlEncodedTarget> {
+ urlencoder: &'output mut UrlEncodedSerializer<'input, Target>,
+}
+
+/// Struct variant serializer.
+///
+/// Never instantiated, struct variants are not supported.
+pub struct StructVariantSerializer<'input, 'output, T: UrlEncodedTarget> {
+ inner: ser::Impossible<&'output mut UrlEncodedSerializer<'input, T>, Error>,
+}
+
+impl<'input, 'output, Target> ser::Serializer
+ for Serializer<'input, 'output, Target>
+where
+ Target: 'output + UrlEncodedTarget,
+{
+ type Ok = &'output mut UrlEncodedSerializer<'input, Target>;
+ type Error = Error;
+ type SerializeSeq = SeqSerializer<'input, 'output, Target>;
+ type SerializeTuple = TupleSerializer<'input, 'output, Target>;
+ type SerializeTupleStruct = TupleStructSerializer<'input, 'output, Target>;
+ type SerializeTupleVariant =
+ TupleVariantSerializer<'input, 'output, Target>;
+ type SerializeMap = MapSerializer<'input, 'output, Target>;
+ type SerializeStruct = StructSerializer<'input, 'output, Target>;
+ type SerializeStructVariant =
+ StructVariantSerializer<'input, 'output, Target>;
+
+ /// Returns an error.
+ fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_char(self, _v: char) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_str(self, _value: &str) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_bytes(self, _value: &[u8]) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns `Ok`.
+ fn serialize_unit(self) -> Result<Self::Ok, Error> {
+ Ok(self.urlencoder)
+ }
+
+ /// Returns `Ok`.
+ fn serialize_unit_struct(
+ self,
+ _name: &'static str,
+ ) -> Result<Self::Ok, Error> {
+ Ok(self.urlencoder)
+ }
+
+ /// Returns an error.
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ ) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Serializes the inner value, ignoring the newtype name.
+ fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(
+ self,
+ _name: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Error> {
+ value.serialize(self)
+ }
+
+ /// Returns an error.
+ fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<Self::Ok, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns `Ok`.
+ fn serialize_none(self) -> Result<Self::Ok, Error> {
+ Ok(self.urlencoder)
+ }
+
+ /// Serializes the given value.
+ fn serialize_some<T: ?Sized + ser::Serialize>(
+ self,
+ value: &T,
+ ) -> Result<Self::Ok, Error> {
+ value.serialize(self)
+ }
+
+ /// Serialize a sequence, given length (if any) is ignored.
+ fn serialize_seq(
+ self,
+ _len: Option<usize>,
+ ) -> Result<Self::SerializeSeq, Error> {
+ Ok(SeqSerializer {
+ urlencoder: self.urlencoder,
+ })
+ }
+
+ /// Returns an error.
+ fn serialize_tuple(
+ self,
+ _len: usize,
+ ) -> Result<Self::SerializeTuple, Error> {
+ Ok(TupleSerializer {
+ urlencoder: self.urlencoder,
+ })
+ }
+
+ /// Returns an error.
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Returns an error.
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Error> {
+ Err(Error::top_level())
+ }
+
+ /// Serializes a map, given length is ignored.
+ fn serialize_map(
+ self,
+ _len: Option<usize>,
+ ) -> Result<Self::SerializeMap, Error> {
+ Ok(MapSerializer {
+ urlencoder: self.urlencoder,
+ key: None,
+ })
+ }
+
+ /// Serializes a struct, given length is ignored.
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStruct, Error> {
+ Ok(StructSerializer {
+ urlencoder: self.urlencoder,
+ })
+ }
+
+ /// Returns an error.
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant, Error> {
+ Err(Error::top_level())
+ }
+}
+
+impl<'input, 'output, Target> ser::SerializeSeq
+ for SeqSerializer<'input, 'output, Target>
+where
+ Target: 'output + UrlEncodedTarget,
+{
+ type Ok = &'output mut UrlEncodedSerializer<'input, Target>;
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized + ser::Serialize>(
+ &mut self,
+ value: &T,
+ ) -> Result<(), Error> {
+ value.serialize(pair::PairSerializer::new(self.urlencoder))
+ }
+
+ fn end(self) -> Result<Self::Ok, Error> {
+ Ok(self.urlencoder)
+ }
+}
+
+impl<'input, 'output, Target> ser::SerializeTuple
+ for TupleSerializer<'input, 'output, Target>
+where
+ Target: 'output + UrlEncodedTarget,
+{
+ type Ok = &'output mut UrlEncodedSerializer<'input, Target>;
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized + ser::Serialize>(
+ &mut self,
+ value: &T,
+ ) -> Result<(), Error> {
+ value.serialize(pair::PairSerializer::new(self.urlencoder))
+ }
+
+ fn end(self) -> Result<Self::Ok, Error> {
+ Ok(self.urlencoder)
+ }
+}
+
+impl<'input, 'output, Target> ser::SerializeTupleStruct
+ for TupleStructSerializer<'input, 'output, Target>
+where
+ Target: 'output + UrlEncodedTarget,
+{
+ type Ok = &'output mut UrlEncodedSerializer<'input, Target>;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized + ser::Serialize>(
+ &mut self,
+ value: &T,
+ ) -> Result<(), Error> {
+ self.inner.serialize_field(value)
+ }
+
+ fn end(self) -> Result<Self::Ok, Error> {
+ self.inner.end()
+ }
+}
+
+impl<'input, 'output, Target> ser::SerializeTupleVariant
+ for TupleVariantSerializer<'input, 'output, Target>
+where
+ Target: 'output + UrlEncodedTarget,
+{
+ type Ok = &'output mut UrlEncodedSerializer<'input, Target>;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized + ser::Serialize>(
+ &mut self,
+ value: &T,
+ ) -> Result<(), Error> {
+ self.inner.serialize_field(value)
+ }
+
+ fn end(self) -> Result<Self::Ok, Error> {
+ self.inner.end()
+ }
+}
+
+impl<'input, 'output, Target> ser::SerializeMap
+ for MapSerializer<'input, 'output, Target>
+where
+ Target: 'output + UrlEncodedTarget,
+{
+ type Ok = &'output mut UrlEncodedSerializer<'input, Target>;
+ type Error = Error;
+
+ fn serialize_entry<
+ K: ?Sized + ser::Serialize,
+ V: ?Sized + ser::Serialize,
+ >(
+ &mut self,
+ key: &K,
+ value: &V,
+ ) -> Result<(), Error> {
+ let key_sink = key::KeySink::new(|key| {
+ let value_sink = value::ValueSink::new(self.urlencoder, &key);
+ value.serialize(part::PartSerializer::new(value_sink))?;
+ self.key = None;
+ Ok(())
+ });
+ let entry_serializer = part::PartSerializer::new(key_sink);
+ key.serialize(entry_serializer)
+ }
+
+ fn serialize_key<T: ?Sized + ser::Serialize>(
+ &mut self,
+ key: &T,
+ ) -> Result<(), Error> {
+ let key_sink = key::KeySink::new(|key| Ok(key.into()));
+ let key_serializer = part::PartSerializer::new(key_sink);
+ self.key = Some(key.serialize(key_serializer)?);
+ Ok(())
+ }
+
+ fn serialize_value<T: ?Sized + ser::Serialize>(
+ &mut self,
+ value: &T,
+ ) -> Result<(), Error> {
+ {
+ let key = self.key.as_ref().ok_or_else(Error::no_key)?;
+ let value_sink = value::ValueSink::new(self.urlencoder, &key);
+ value.serialize(part::PartSerializer::new(value_sink))?;
+ }
+ self.key = None;
+ Ok(())
+ }
+
+ fn end(self) -> Result<Self::Ok, Error> {
+ Ok(self.urlencoder)
+ }
+}
+
+impl<'input, 'output, Target> ser::SerializeStruct
+ for StructSerializer<'input, 'output, Target>
+where
+ Target: 'output + UrlEncodedTarget,
+{
+ type Ok = &'output mut UrlEncodedSerializer<'input, Target>;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized + ser::Serialize>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), Error> {
+ let value_sink = value::ValueSink::new(self.urlencoder, key);
+ value.serialize(part::PartSerializer::new(value_sink))
+ }
+
+ fn end(self) -> Result<Self::Ok, Error> {
+ Ok(self.urlencoder)
+ }
+}
+
+impl<'input, 'output, Target> ser::SerializeStructVariant
+ for StructVariantSerializer<'input, 'output, Target>
+where
+ Target: 'output + UrlEncodedTarget,
+{
+ type Ok = &'output mut UrlEncodedSerializer<'input, Target>;
+ type Error = Error;
+
+ fn serialize_field<T: ?Sized + ser::Serialize>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), Error> {
+ self.inner.serialize_field(key, value)
+ }
+
+ fn end(self) -> Result<Self::Ok, Error> {
+ self.inner.end()
+ }
+}
+
+impl Error {
+ fn top_level() -> Self {
+ let msg = "top-level serializer supports only maps and structs";
+ Error::Custom(msg.into())
+ }
+
+ fn no_key() -> Self {
+ let msg = "tried to serialize a value before serializing key";
+ Error::Custom(msg.into())
+ }
+}
diff --git a/third_party/rust/serde_urlencoded/src/ser/pair.rs b/third_party/rust/serde_urlencoded/src/ser/pair.rs
new file mode 100644
index 0000000000..429ce4b2bd
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/src/ser/pair.rs
@@ -0,0 +1,271 @@
+use crate::ser::key::KeySink;
+use crate::ser::part::PartSerializer;
+use crate::ser::value::ValueSink;
+use crate::ser::Error;
+use form_urlencoded::Serializer as UrlEncodedSerializer;
+use form_urlencoded::Target as UrlEncodedTarget;
+use serde::ser;
+use std::borrow::Cow;
+use std::mem;
+
+pub struct PairSerializer<'input, 'target, Target: UrlEncodedTarget> {
+ urlencoder: &'target mut UrlEncodedSerializer<'input, Target>,
+ state: PairState,
+}
+
+impl<'input, 'target, Target> PairSerializer<'input, 'target, Target>
+where
+ Target: 'target + UrlEncodedTarget,
+{
+ pub fn new(
+ urlencoder: &'target mut UrlEncodedSerializer<'input, Target>,
+ ) -> Self {
+ PairSerializer {
+ urlencoder,
+ state: PairState::WaitingForKey,
+ }
+ }
+}
+
+impl<'input, 'target, Target> ser::Serializer
+ for PairSerializer<'input, 'target, Target>
+where
+ Target: 'target + UrlEncodedTarget,
+{
+ type Ok = ();
+ type Error = Error;
+ type SerializeSeq = ser::Impossible<(), Error>;
+ type SerializeTuple = Self;
+ type SerializeTupleStruct = ser::Impossible<(), Error>;
+ type SerializeTupleVariant = ser::Impossible<(), Error>;
+ type SerializeMap = ser::Impossible<(), Error>;
+ type SerializeStruct = ser::Impossible<(), Error>;
+ type SerializeStructVariant = ser::Impossible<(), Error>;
+
+ fn serialize_bool(self, _v: bool) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_i8(self, _v: i8) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_i16(self, _v: i16) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_i32(self, _v: i32) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_i64(self, _v: i64) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_u8(self, _v: u8) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_u16(self, _v: u16) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_u32(self, _v: u32) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_u64(self, _v: u64) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_f32(self, _v: f32) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_f64(self, _v: f64) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_char(self, _v: char) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_str(self, _value: &str) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_bytes(self, _value: &[u8]) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_unit(self) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ ) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(
+ self,
+ _name: &'static str,
+ value: &T,
+ ) -> Result<(), Error> {
+ value.serialize(self)
+ }
+
+ fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<(), Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_none(self) -> Result<(), Error> {
+ Ok(())
+ }
+
+ fn serialize_some<T: ?Sized + ser::Serialize>(
+ self,
+ value: &T,
+ ) -> Result<(), Error> {
+ value.serialize(self)
+ }
+
+ fn serialize_seq(
+ self,
+ _len: Option<usize>,
+ ) -> Result<Self::SerializeSeq, Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self, Error> {
+ if len == 2 {
+ Ok(self)
+ } else {
+ Err(Error::unsupported_pair())
+ }
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_map(
+ self,
+ _len: Option<usize>,
+ ) -> Result<Self::SerializeMap, Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStruct, Error> {
+ Err(Error::unsupported_pair())
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant, Error> {
+ Err(Error::unsupported_pair())
+ }
+}
+
+impl<'input, 'target, Target> ser::SerializeTuple
+ for PairSerializer<'input, 'target, Target>
+where
+ Target: 'target + UrlEncodedTarget,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_element<T: ?Sized + ser::Serialize>(
+ &mut self,
+ value: &T,
+ ) -> Result<(), Error> {
+ match mem::replace(&mut self.state, PairState::Done) {
+ PairState::WaitingForKey => {
+ let key_sink = KeySink::new(|key| Ok(key.into()));
+ let key_serializer = PartSerializer::new(key_sink);
+ self.state = PairState::WaitingForValue {
+ key: value.serialize(key_serializer)?,
+ };
+ Ok(())
+ }
+ PairState::WaitingForValue { key } => {
+ let result = {
+ let value_sink = ValueSink::new(self.urlencoder, &key);
+ let value_serializer = PartSerializer::new(value_sink);
+ value.serialize(value_serializer)
+ };
+ if result.is_ok() {
+ self.state = PairState::Done;
+ } else {
+ self.state = PairState::WaitingForValue { key };
+ }
+ result
+ }
+ PairState::Done => Err(Error::done()),
+ }
+ }
+
+ fn end(self) -> Result<(), Error> {
+ if let PairState::Done = self.state {
+ Ok(())
+ } else {
+ Err(Error::not_done())
+ }
+ }
+}
+
+enum PairState {
+ WaitingForKey,
+ WaitingForValue { key: Cow<'static, str> },
+ Done,
+}
+
+impl Error {
+ fn done() -> Self {
+ Error::Custom("this pair has already been serialized".into())
+ }
+
+ fn not_done() -> Self {
+ Error::Custom("this pair has not yet been serialized".into())
+ }
+
+ fn unsupported_pair() -> Self {
+ Error::Custom("unsupported pair".into())
+ }
+}
diff --git a/third_party/rust/serde_urlencoded/src/ser/part.rs b/third_party/rust/serde_urlencoded/src/ser/part.rs
new file mode 100644
index 0000000000..1deffa54b5
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/src/ser/part.rs
@@ -0,0 +1,236 @@
+use crate::ser::Error;
+use serde::ser;
+use std::str;
+
+pub struct PartSerializer<S> {
+ sink: S,
+}
+
+impl<S: Sink> PartSerializer<S> {
+ pub fn new(sink: S) -> Self {
+ PartSerializer { sink }
+ }
+}
+
+pub trait Sink: Sized {
+ type Ok;
+
+ fn serialize_static_str(
+ self,
+ value: &'static str,
+ ) -> Result<Self::Ok, Error>;
+
+ fn serialize_str(self, value: &str) -> Result<Self::Ok, Error>;
+ fn serialize_string(self, value: String) -> Result<Self::Ok, Error>;
+ fn serialize_none(self) -> Result<Self::Ok, Error>;
+
+ fn serialize_some<T: ?Sized + ser::Serialize>(
+ self,
+ value: &T,
+ ) -> Result<Self::Ok, Error>;
+
+ fn unsupported(self) -> Error;
+}
+
+impl<S: Sink> ser::Serializer for PartSerializer<S> {
+ type Ok = S::Ok;
+ type Error = Error;
+ type SerializeSeq = ser::Impossible<S::Ok, Error>;
+ type SerializeTuple = ser::Impossible<S::Ok, Error>;
+ type SerializeTupleStruct = ser::Impossible<S::Ok, Error>;
+ type SerializeTupleVariant = ser::Impossible<S::Ok, Error>;
+ type SerializeMap = ser::Impossible<S::Ok, Error>;
+ type SerializeStruct = ser::Impossible<S::Ok, Error>;
+ type SerializeStructVariant = ser::Impossible<S::Ok, Error>;
+
+ fn serialize_bool(self, v: bool) -> Result<S::Ok, Error> {
+ self.sink
+ .serialize_static_str(if v { "true" } else { "false" })
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<S::Ok, Error> {
+ self.serialize_integer(v)
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<S::Ok, Error> {
+ self.serialize_integer(v)
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<S::Ok, Error> {
+ self.serialize_integer(v)
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<S::Ok, Error> {
+ self.serialize_integer(v)
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<S::Ok, Error> {
+ self.serialize_integer(v)
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<S::Ok, Error> {
+ self.serialize_integer(v)
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<S::Ok, Error> {
+ self.serialize_integer(v)
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<S::Ok, Error> {
+ self.serialize_integer(v)
+ }
+
+ fn serialize_u128(self, v: u128) -> Result<S::Ok, Error> {
+ self.serialize_integer(v)
+ }
+
+ fn serialize_i128(self, v: i128) -> Result<S::Ok, Error> {
+ self.serialize_integer(v)
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<S::Ok, Error> {
+ self.serialize_floating(v)
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<S::Ok, Error> {
+ self.serialize_floating(v)
+ }
+
+ fn serialize_char(self, v: char) -> Result<S::Ok, Error> {
+ self.sink.serialize_string(v.to_string())
+ }
+
+ fn serialize_str(self, value: &str) -> Result<S::Ok, Error> {
+ self.sink.serialize_str(value)
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<S::Ok, Error> {
+ match str::from_utf8(value) {
+ Ok(value) => self.sink.serialize_str(value),
+ Err(err) => Err(Error::Utf8(err)),
+ }
+ }
+
+ fn serialize_unit(self) -> Result<S::Ok, Error> {
+ Err(self.sink.unsupported())
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<S::Ok, Error> {
+ self.sink.serialize_static_str(name)
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<S::Ok, Error> {
+ self.sink.serialize_static_str(variant)
+ }
+
+ fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(
+ self,
+ _name: &'static str,
+ value: &T,
+ ) -> Result<S::Ok, Error> {
+ value.serialize(self)
+ }
+
+ fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<S::Ok, Error> {
+ Err(self.sink.unsupported())
+ }
+
+ fn serialize_none(self) -> Result<S::Ok, Error> {
+ self.sink.serialize_none()
+ }
+
+ fn serialize_some<T: ?Sized + ser::Serialize>(
+ self,
+ value: &T,
+ ) -> Result<S::Ok, Error> {
+ self.sink.serialize_some(value)
+ }
+
+ fn serialize_seq(
+ self,
+ _len: Option<usize>,
+ ) -> Result<Self::SerializeSeq, Error> {
+ Err(self.sink.unsupported())
+ }
+
+ fn serialize_tuple(
+ self,
+ _len: usize,
+ ) -> Result<Self::SerializeTuple, Error> {
+ Err(self.sink.unsupported())
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTuple, Error> {
+ Err(self.sink.unsupported())
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Error> {
+ Err(self.sink.unsupported())
+ }
+
+ fn serialize_map(
+ self,
+ _len: Option<usize>,
+ ) -> Result<Self::SerializeMap, Error> {
+ Err(self.sink.unsupported())
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStruct, Error> {
+ Err(self.sink.unsupported())
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant, Error> {
+ Err(self.sink.unsupported())
+ }
+}
+
+impl<S: Sink> PartSerializer<S> {
+ fn serialize_integer<I>(self, value: I) -> Result<S::Ok, Error>
+ where
+ I: itoa::Integer,
+ {
+ let mut buf = itoa::Buffer::new();
+ let part = buf.format(value);
+ ser::Serializer::serialize_str(self, part)
+ }
+
+ fn serialize_floating<F>(self, value: F) -> Result<S::Ok, Error>
+ where
+ F: ryu::Float,
+ {
+ let mut buf = ryu::Buffer::new();
+ let part = buf.format(value);
+ ser::Serializer::serialize_str(self, part)
+ }
+}
diff --git a/third_party/rust/serde_urlencoded/src/ser/value.rs b/third_party/rust/serde_urlencoded/src/ser/value.rs
new file mode 100644
index 0000000000..e8823ce703
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/src/ser/value.rs
@@ -0,0 +1,62 @@
+use crate::ser::part::{PartSerializer, Sink};
+use crate::ser::Error;
+use form_urlencoded::Serializer as UrlEncodedSerializer;
+use form_urlencoded::Target as UrlEncodedTarget;
+use serde::ser::Serialize;
+use std::str;
+
+pub struct ValueSink<'input, 'key, 'target, Target>
+where
+ Target: UrlEncodedTarget,
+{
+ urlencoder: &'target mut UrlEncodedSerializer<'input, Target>,
+ key: &'key str,
+}
+
+impl<'input, 'key, 'target, Target> ValueSink<'input, 'key, 'target, Target>
+where
+ Target: 'target + UrlEncodedTarget,
+{
+ pub fn new(
+ urlencoder: &'target mut UrlEncodedSerializer<'input, Target>,
+ key: &'key str,
+ ) -> Self {
+ ValueSink { urlencoder, key }
+ }
+}
+
+impl<'input, 'key, 'target, Target> Sink
+ for ValueSink<'input, 'key, 'target, Target>
+where
+ Target: 'target + UrlEncodedTarget,
+{
+ type Ok = ();
+
+ fn serialize_str(self, value: &str) -> Result<(), Error> {
+ self.urlencoder.append_pair(self.key, value);
+ Ok(())
+ }
+
+ fn serialize_static_str(self, value: &'static str) -> Result<(), Error> {
+ self.serialize_str(value)
+ }
+
+ fn serialize_string(self, value: String) -> Result<(), Error> {
+ self.serialize_str(&value)
+ }
+
+ fn serialize_none(self) -> Result<Self::Ok, Error> {
+ Ok(())
+ }
+
+ fn serialize_some<T: ?Sized + Serialize>(
+ self,
+ value: &T,
+ ) -> Result<Self::Ok, Error> {
+ value.serialize(PartSerializer::new(self))
+ }
+
+ fn unsupported(self) -> Error {
+ Error::Custom("unsupported value".into())
+ }
+}
diff --git a/third_party/rust/serde_urlencoded/tests/test_deserialize.rs b/third_party/rust/serde_urlencoded/tests/test_deserialize.rs
new file mode 100644
index 0000000000..00700d3060
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/tests/test_deserialize.rs
@@ -0,0 +1,88 @@
+use serde_derive::Deserialize;
+
+#[derive(Deserialize, Debug, PartialEq)]
+struct NewType<T>(T);
+
+#[test]
+fn deserialize_newtype_i32() {
+ let result = vec![("field".to_owned(), NewType(11))];
+
+ assert_eq!(serde_urlencoded::from_str("field=11"), Ok(result));
+}
+
+#[test]
+fn deserialize_bytes() {
+ let result = vec![("first".to_owned(), 23), ("last".to_owned(), 42)];
+
+ assert_eq!(
+ serde_urlencoded::from_bytes(b"first=23&last=42"),
+ Ok(result)
+ );
+}
+
+#[test]
+fn deserialize_str() {
+ let result = vec![("first".to_owned(), 23), ("last".to_owned(), 42)];
+
+ assert_eq!(serde_urlencoded::from_str("first=23&last=42"), Ok(result));
+}
+
+#[test]
+fn deserialize_borrowed_str() {
+ let result = vec![("first", 23), ("last", 42)];
+
+ assert_eq!(serde_urlencoded::from_str("first=23&last=42"), Ok(result));
+}
+
+#[test]
+fn deserialize_reader() {
+ let result = vec![("first".to_owned(), 23), ("last".to_owned(), 42)];
+
+ assert_eq!(
+ serde_urlencoded::from_reader(b"first=23&last=42" as &[_]),
+ Ok(result)
+ );
+}
+
+#[test]
+fn deserialize_option() {
+ let result = vec![
+ ("first".to_owned(), Some(23)),
+ ("last".to_owned(), Some(42)),
+ ];
+ assert_eq!(serde_urlencoded::from_str("first=23&last=42"), Ok(result));
+}
+
+#[test]
+fn deserialize_unit() {
+ assert_eq!(serde_urlencoded::from_str(""), Ok(()));
+ assert_eq!(serde_urlencoded::from_str("&"), Ok(()));
+ assert_eq!(serde_urlencoded::from_str("&&"), Ok(()));
+ assert!(serde_urlencoded::from_str::<()>("first=23").is_err());
+}
+
+#[derive(Deserialize, Debug, PartialEq, Eq)]
+enum X {
+ A,
+ B,
+ C,
+}
+
+#[test]
+fn deserialize_unit_enum() {
+ let result = vec![
+ ("one".to_owned(), X::A),
+ ("two".to_owned(), X::B),
+ ("three".to_owned(), X::C),
+ ];
+
+ assert_eq!(
+ serde_urlencoded::from_str("one=A&two=B&three=C"),
+ Ok(result)
+ );
+}
+
+#[test]
+fn deserialize_unit_type() {
+ assert_eq!(serde_urlencoded::from_str(""), Ok(()));
+}
diff --git a/third_party/rust/serde_urlencoded/tests/test_serialize.rs b/third_party/rust/serde_urlencoded/tests/test_serialize.rs
new file mode 100644
index 0000000000..abb4907a46
--- /dev/null
+++ b/third_party/rust/serde_urlencoded/tests/test_serialize.rs
@@ -0,0 +1,104 @@
+use serde_derive::Serialize;
+
+#[derive(Serialize)]
+struct NewType<T>(T);
+
+#[test]
+fn serialize_newtype_i32() {
+ let params = &[("field", Some(NewType(11)))];
+ assert_eq!(
+ serde_urlencoded::to_string(params),
+ Ok("field=11".to_owned())
+ );
+}
+
+#[test]
+fn serialize_newtype_u128() {
+ let params = &[("field", Some(NewType(u128::MAX)))];
+ assert_eq!(
+ serde_urlencoded::to_string(params),
+ Ok(format!("field={}", u128::MAX))
+ );
+}
+
+#[test]
+fn serialize_newtype_i128() {
+ let params = &[("field", Some(NewType(i128::MIN)))];
+ assert_eq!(
+ serde_urlencoded::to_string(params),
+ Ok(format!("field={}", i128::MIN))
+ );
+}
+
+#[test]
+fn serialize_option_map_int() {
+ let params = &[("first", Some(23)), ("middle", None), ("last", Some(42))];
+
+ assert_eq!(
+ serde_urlencoded::to_string(params),
+ Ok("first=23&last=42".to_owned())
+ );
+}
+
+#[test]
+fn serialize_option_map_string() {
+ let params = &[
+ ("first", Some("hello")),
+ ("middle", None),
+ ("last", Some("world")),
+ ];
+
+ assert_eq!(
+ serde_urlencoded::to_string(params),
+ Ok("first=hello&last=world".to_owned())
+ );
+}
+
+#[test]
+fn serialize_option_map_bool() {
+ let params = &[("one", Some(true)), ("two", Some(false))];
+
+ assert_eq!(
+ serde_urlencoded::to_string(params),
+ Ok("one=true&two=false".to_owned())
+ );
+}
+
+#[test]
+fn serialize_map_bool() {
+ let params = &[("one", true), ("two", false)];
+
+ assert_eq!(
+ serde_urlencoded::to_string(params),
+ Ok("one=true&two=false".to_owned())
+ );
+}
+
+#[derive(Serialize)]
+enum X {
+ A,
+ B,
+ C,
+}
+
+#[test]
+fn serialize_unit_enum() {
+ let params = &[("one", X::A), ("two", X::B), ("three", X::C)];
+ assert_eq!(
+ serde_urlencoded::to_string(params),
+ Ok("one=A&two=B&three=C".to_owned())
+ );
+}
+
+#[derive(Serialize)]
+struct Unit;
+
+#[test]
+fn serialize_unit_struct() {
+ assert_eq!(serde_urlencoded::to_string(Unit), Ok("".to_owned()));
+}
+
+#[test]
+fn serialize_unit_type() {
+ assert_eq!(serde_urlencoded::to_string(()), Ok("".to_owned()));
+}
diff --git a/third_party/rust/serde_with/.cargo-checksum.json b/third_party/rust/serde_with/.cargo-checksum.json
new file mode 100644
index 0000000000..ac5b75ca75
--- /dev/null
+++ b/third_party/rust/serde_with/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"d3291ed2505ed562246982c982393be13428c33320fb4fe978c4a16553e32b86","Cargo.toml":"0c01c0832dc504b98d4df90e2c3b460ae4099d53272c3b262725a71c7a5d8569","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"b85503ad4bc4d7d932583e404bb04f376c3630364719462a7fcd6daf6c1193d1","src/base64.rs":"1d8b125a7bab23fe974aa429b938344a0263156448aa0a3e70486fbf7e84cae3","src/chrono.rs":"a7d3d9afd13befd72418f845ca371018b321a5da844d09be2ed808b3040b36a4","src/content/mod.rs":"f8900091c0cffacc6946a98a98d7c9fb16ff13a6d0335777bd60d0f9832a3988","src/content/ser.rs":"631702fbd1671e1ebc44b3515b0da7094fc8dbafa5390b5a8e34f0d635274d68","src/de/const_arrays.rs":"161debd41e388bcbdadb035d48a05e23ed0aa950749d7d690120240a8a78bf6f","src/de/impls.rs":"86f8c377d1dff802eaa42761c2b9da88c2880cbb50a82f0b18d0e73fa3c1076d","src/de/legacy_arrays.rs":"7271d976b16ec102f1e3ffb0852eb60d34000133b3612d96782ae94f57a0273b","src/de/mod.rs":"4b8c1a248f84ba479be542bca023064c9d96d183084cb769d0d01227139dc5c3","src/duplicate_key_impls/error_on_duplicate.rs":"df63ea30c1d2965cc83c4d8e24b6b9e4ec93648835f586dce1a7a3c94cc1e098","src/duplicate_key_impls/first_value_wins.rs":"f1f84931df16f4ed5f4e5570ea2bdeb8af20957e2c3a160cb0137f3a9aad1bbb","src/duplicate_key_impls/last_value_wins.rs":"0ebf6ff1a80ba5a9d507f97b6482fa7721f66c81acb6982564bb293a241efd87","src/duplicate_key_impls/mod.rs":"0c6867f48ca5b9aea3260d8aadab23e30c0f98fc7a685c3a91ffac8c9cbaf817","src/enum_map.rs":"00b7e52f4cedb52c5aecf3aeb8fe65752a4cacee6108c64165c1a526afbf6606","src/flatten_maybe.rs":"32ab7f2e9c87357eda8834d1ca98e5cd7f3a257b2d80e5b16551fb26ae1f9eb6","src/formats.rs":"b56e83c35a385b4e54b91e5a6ca6dbea0121c08026d3269da632e1db730bc0d7","src/guide.md":"9e2af8ca56d3d9d76eaa1651f4397e0da1f9d8743a8d3412134c16823242dca8","src/guide/feature_flags.md":"f5a22a34371905027891e191141aad604252bea414fc9834727392c6d32679eb","src/guide/serde_as.md":"0323ecbeb8bd75e34dc1c0977f801c3a35dd420880faf57331a3f8df18e83d7e","src/guide/serde_as_transformations.md":"26aa40b1452aeb27851b9fa575db26515d63afe32efd6ac5542474b9575d4853","src/hex.rs":"9fc4bae4a435fab2cfc1bb39b5dcda1d335f69448d8e6f373e352ab5c4d0568a","src/json.rs":"db9604f55569b3290a519353aa746ba9f5080dd364671697f54e6faeaa4d8c40","src/lib.rs":"bd12fcd39baf7488163bbb4c6dfcec68ec22bfd946d317ace71b9d6e50611e58","src/rust.rs":"7b2847f91f4780c84a9e098031aea2cd1b544d35040147c9e42074e6723f981c","src/ser/const_arrays.rs":"48d6231a6396cfda634d69ae9672321fda7626049d8705e9006438e0dce8c789","src/ser/impls.rs":"5b532c310e5f3b6c987711b43a6645bf7ca5a524a2304464cc2c109cbf8ca276","src/ser/legacy_arrays.rs":"54ee16c90b18cb76657d51dbb7fd85a90c04798bdfd27593d63e5c3f8cfb9b14","src/ser/mod.rs":"864718e6256104278cbcaec4caa6db3822f3747b830f53815eafec613b3e6f4a","src/serde_conv.rs":"000bc7ed387afc6824819f1da4dca6dcaf98f466aa0130897a795ae36e1a2730","src/time_0_3.rs":"24f1edc87f6da0014a990656b80bdb2b1d4833ecf5d7de768ffb2eb3db85a9ed","src/utils.rs":"d0f770493294c3951516929becf4681eeaaec8340673c2a46b8f5503d778bd45","src/utils/duration.rs":"696fe02d2a6f988d1d428821d40404ecd00b8faad4f2ad45c1a930cb98b53c76","src/with_prefix.rs":"2877a7861715b4a809048e99c48523fc7901c8a8e936c1b145d067bfc2109b87","tests/base64.rs":"e944a600ab728108e974d5e7697c4adc0c0e2907f0b0390f2e14342abe431e41","tests/chrono.rs":"90810d1c47b9e1c0ac7d032fe28599aeee182bfa1ad350a690908900ab5e20a2","tests/derives/deserialize_fromstr.rs":"b23b236247b619eecc25053f64e527f44fd066d602027f4b1518b333110362e9","tests/derives/lib.rs":"abb2046d6798889dcef2cf40157f3182851ae87436d0f981adecd76051d74b5a","tests/derives/serialize_display.rs":"9ae9ad6c632202639e6e7ddeeaa6c5613593a9c2cc5275e175eb866ba727fb31","tests/hex.rs":"3d3198efed7d328962695e359eb5fc688531fb9c2befa270401109d04167d0ff","tests/indexmap.rs":"855a7cf19622f53c201ba3e459ecc3c0edff325d07de50ac0a61c16767166e17","tests/json.rs":"97a093eff339aba9a14eb4ee406ff9d22cf88b5be55b87f48c3a7772a3ccfd51","tests/rust.rs":"b904fb96b3a1e8d3e8fd4923f7b467bbf2eae550875d6878ddde87da12a06f0a","tests/serde_as/collections.rs":"e09c62f6ad84aa2493bfc20817edbe6216b35614e2b92f510536252a11041e7c","tests/serde_as/default_on.rs":"c2e7aad6f4c309305dc925b7c95e3cb2c10bf462fb5577448606416913400a56","tests/serde_as/enum_map.rs":"48589f746440cf05f902674e591c0636f54f03db569d8b4baecb8e24d0a3993c","tests/serde_as/frominto.rs":"c7feb6d10a85c54a46ca619f7b7751c2d4a2ac2a936dfec64b8050267152cd96","tests/serde_as/lib.rs":"8aded29ac5fa60811bf050905237c7231fb1fcaeeabdd9470c01ddeb1bd4ebb5","tests/serde_as/map_tuple_list.rs":"655de06a6df00075c68f4084c9b2524bd4503a5ca8b2102cfa43d48df53ccc53","tests/serde_as/pickfirst.rs":"6f0d32f57e1fc31b73952f5ba523794de8667633530418bcc5d821d28556e54c","tests/serde_as/serde_as_macro.rs":"b0799238f56fe3f0d1a697a9bf4474cda8c5498e7ed5323848e6becaf141a98c","tests/serde_as/serde_conv.rs":"1d3546d46390e631fe380e8cf56a8ed45020958b82eb6396d33062e133237173","tests/serde_as/time.rs":"69cdd8db5432a0eafa2da08ca633872c160ce23302ae03dc2f397191b9de9477","tests/time_0_3.rs":"969e4ddb58b164cdb3d22e0b7e030b526e009e145064e7c871437d6bb3a13c40","tests/utils.rs":"f540ced55ae803fa98404812078ecc2c6aca10e9052f39a1b812bbde9dff5df5","tests/version_numbers.rs":"f274da4dad87fbeba4b30e3485c7a6d3f2dcf5b778a7acaf3caea9393d10c8b0","tests/with_prefix.rs":"cff484c442a3504342f793da451ce9c9d3aa4180781aebc965971bae34783ecc"},"package":"678b5a069e50bf00ecd22d0cd8ddf7c236f68581b03db652061ed5eb13a312ff"} \ No newline at end of file
diff --git a/third_party/rust/serde_with/CHANGELOG.md b/third_party/rust/serde_with/CHANGELOG.md
new file mode 100644
index 0000000000..ca42d74bf1
--- /dev/null
+++ b/third_party/rust/serde_with/CHANGELOG.md
@@ -0,0 +1,682 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+## [1.14.0] - 2022-05-29
+
+### Added
+
+* Add support for `time` crate v0.3 #450
+
+ `time::Duration` can now be serialized with the `DurationSeconds` and related converters.
+
+ ```rust
+ // Rust
+ #[serde_as(as = "serde_with::DurationSeconds<u64>")]
+ value: Duration,
+
+ // JSON
+ "value": 86400,
+ ```
+
+ `time::OffsetDateTime` and `time::PrimitiveDateTime` can now be serialized with the `TimestampSeconds` and related converters.
+
+ ```rust
+ // Rust
+ #[serde_as(as = "serde_with::TimestampMicroSecondsWithFrac<String>")]
+ value: time::PrimitiveDateTime,
+
+ // JSON
+ "value": "1000000",
+ ```
+
+ `time::OffsetDateTime` can be serialized in string format in different well-known formats.
+ Two formats are supported, `time::format_description::well_known::Rfc2822` and `time::format_description::well_known::Rfc3339`.
+
+ ```rust
+ // Rust
+ #[serde_as(as = "time::format_description::well_known::Rfc2822")]
+ rfc_2822: OffsetDateTime,
+ #[serde_as(as = "Vec<time::format_description::well_known::Rfc3339>")]
+ rfc_3339: Vec<OffsetDateTime>,
+
+ // JSON
+ "rfc_2822": "Fri, 21 Nov 1997 09:55:06 -0600",
+ "rfc_3339": ["1997-11-21T09:55:06-06:00"],
+ ```
+
+* Deserialize `bool` from integers #456 462
+
+ Deserialize an integer and convert it into a `bool`.
+ `BoolFromInt<Strict>` (default) deserializes 0 to `false` and `1` to `true`, other numbers are errors.
+ `BoolFromInt<Flexible>` deserializes any non-zero as `true`.
+ Serialization only emits 0/1.
+
+ ```rust
+ // Rust
+ #[serde_as(as = "BoolFromInt")] // BoolFromInt<Strict>
+ b: bool,
+
+ // JSON
+ "b": 1,
+ ```
+
+### Changed
+
+* Bump MSRV to 1.53, since the new dependency `time` requires that version.
+
+### Fixed
+
+* Make the documentation clearer by stating that the `#[serde_as]` and `#[skip_serializing_none]` attributes must always be places before `#[derive]`.
+
+## [1.13.0] - 2022-04-23
+
+### Added
+
+* Added support for `indexmap::IndexMap` and `indexmap::IndexSet` types. #431, #436
+
+ Both types are now compatible with these functions: `maps_duplicate_key_is_error`, `maps_first_key_wins`, `sets_duplicate_value_is_error`, `sets_last_value_wins`.
+ `serde_as` integration is provided by implementing both `SerializeAs` and `DeserializeAs` for both types.
+ `IndexMap`s can also be serialized as a list of types via the `serde_as(as = "Vec<(_, _)>")` annotation.
+
+ All implementations are gated behind the `indexmap` feature.
+
+ Thanks to @jgrund for providing parts of the implementation.
+
+## [1.12.1] - 2022-04-07
+
+### Fixed
+
+* Depend on a newer `serde_with_macros` version to pull in some fixes.
+ * Account for generics when deriving implementations with `SerializeDisplay` and `DeserializeFromStr` #413
+ * Provide better error messages when parsing types fails #423
+
+
+## [1.12.0] - 2022-02-07
+
+### Added
+
+* Deserialize a `Vec` and skip all elements failing to deserialize #383
+
+ `VecSkipError` acts like a `Vec`, but elements which fail to deserialize, like the `"Yellow"` are ignored.
+
+ ```rust
+ #[derive(serde::Deserialize)]
+ enum Color {
+ Red,
+ Green,
+ Blue,
+ }
+ // JSON
+ "colors": ["Blue", "Yellow", "Green"],
+ // Rust
+ #[serde_as(as = "VecSkipError<_>")]
+ colors: Vec<Color>,
+ // => vec![Blue, Green]
+ ```
+
+ Thanks to @hdhoang for creating the PR.
+
+* Transform between maps and `Vec<Enum>` #375
+
+ The new `EnumMap` type converts `Vec` of enums into a single map.
+ The key is the enum variant name, and the value is the variant value.
+
+ ```rust
+ // Rust
+ VecEnumValues(vec![
+ EnumValue::Int(123),
+ EnumValue::String("Foo".to_string()),
+ EnumValue::Unit,
+ EnumValue::Tuple(1, "Bar".to_string()),
+ EnumValue::Struct {
+ a: 666,
+ b: "Baz".to_string(),
+ },
+ ]
+
+ // JSON
+ {
+ "Int": 123,
+ "String": "Foo",
+ "Unit": null,
+ "Tuple": [
+ 1,
+ "Bar",
+ ],
+ "Struct": {
+ "a": 666,
+ "b": "Baz",
+ }
+ }
+ ```
+
+### Changed
+
+* The `Timestamp*Seconds` and `Timestamp*SecondsWithFrac` types can now be used with `chrono::NaiveDateTime`. #389
+
+## [1.11.0] - 2021-10-18
+
+### Added
+
+* Serialize bytes as base64 encoded strings.
+ The character set and padding behavior can be configured.
+
+ ```rust
+ // Rust
+ #[serde_as(as = "serde_with::base64::Base64")]
+ value: Vec<u8>,
+ #[serde_as(as = "Base64<Bcrypt, Unpadded>")]
+ bcrypt_unpadded: Vec<u8>,
+
+ // JSON
+ "value": "SGVsbG8gV29ybGQ=",
+ "bcrypt_unpadded": "QETqZE6eT07wZEO",
+ ```
+
+* The minimal supported Rust version (MSRV) is now specified in the `Cargo.toml` via the `rust-version` field. The field is supported in Rust 1.56 and has no effect on versions before.
+
+ More details: https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-rust-version-field
+
+### Fixed
+
+* Fixed RUSTSEC-2020-0071 in the `time` v0.1 dependency, but changing the feature flags of the `chrono` dependency. This should not change anything. Crates requiring the `oldtime` feature of `chrono` can enable it separately.
+* Allow `HashSet`s with custom hashers to be deserialized when used in combination with `serde_as`. #408
+
+## [1.10.0] - 2021-09-04
+
+### Added
+
+* Add `BorrowCow` which instructs serde to borrow data during deserialization of `Cow<'_, str>`, `Cow<'_, [u8]>`, or `Cow<'_, [u8; N]>`. (#347)
+ The implementation is for [serde#2072](https://github.com/serde-rs/serde/pull/2072#pullrequestreview-735511713) and [serde#2016](https://github.com/serde-rs/serde/issues/2016), about `#[serde(borrow)]` not working for `Option<Cow<'a, str>>`.
+
+ ```rust
+ #[serde_as]
+ #[derive(Deserialize, Serialize)]
+ struct Data<'a> {
+ #[serde_as(as = "Option<[BorrowCow; 1]>")]
+ nested: Option<[Cow<'a, str>; 1]>,
+ }
+ ```
+
+ The `#[serde(borrow)]` annotation is automatically added by the `#[serde_as]` attribute.
+
+### Changed
+
+* Bump MSRV to 1.46, since the dev-dependency `bitflags` requires that version now.
+* `flattened_maybe!` no longer requires the `serde_with` crate to be available with a specific name.
+ This allows renaming the crate or using `flattened_maybe!` through a re-export without any complications.
+
+## [1.9.4] - 2021-06-18
+
+### Fixed
+
+* `with_prefix!` now supports an optional visibility modifier. (#327, #328)
+ If not specified `pub(self)` is assumed.
+
+ ```rust
+ with_prefix!(prefix_active "active_"); // => mod {...}
+ with_prefix!(pub prefix_active "active_"); // => pub mod {...}
+ with_prefix!(pub(crate) prefix_active "active_"); // => pub(crate) mod {...}
+ with_prefix!(pub(in other_mod) prefix_active "active_"); // => pub(in other_mod) mod {...}
+ ```
+
+ Thanks to @elpiel for raising and fixing the issue.
+
+## [1.9.3] - 2021-06-14
+
+### Added
+
+* The `Bytes` type now supports borrowed and Cow arrays of fixed size (requires Rust 1.51+)
+
+ ```rust
+ #[serde_as(as = "Bytes")]
+ #[serde(borrow)]
+ borrowed_array: &'a [u8; 15],
+ #[serde_as(as = "Bytes")]
+ #[serde(borrow)]
+ cow_array: Cow<'a, [u8; 15]>,
+ ```
+
+ Note: For borrowed arrays the used Deserializer needs to support Serde's 0-copy deserialization.
+
+## [1.9.2] - 2021-06-07
+
+### Fixed
+
+* Suppress clippy warnings, which can occur while using `serde_conv` (#320)
+ Thanks to @mkroening for reporting and fixing the issue.
+
+## [1.9.1] - 2021-05-15
+
+### Changed
+
+* `NoneAsEmptyString`: Deserialize using `FromStr` instead of using `for<'a> From<&'a str>` (#316)
+ This will *not* change any behavior when applied to a field of type `Option<String>` as used in the documentation.
+ Thanks to @mkroening for finding and fixing the issue.
+
+## [1.9.0] - 2021-05-09
+
+### Added
+
+* Added `FromInto` and `TryFromInto` adapters, which enable serialization by converting into a proxy type.
+
+ ```rust
+ // Rust
+ #[serde_as(as = "FromInto<(u8, u8, u8)>")]
+ value: Rgb,
+
+ impl From<(u8, u8, u8)> for Rgb { ... }
+ impl From<Rgb> for (u8, u8, u8) { ... }
+
+ // JSON
+ "value": [128, 64, 32],
+ ```
+
+* New `serde_conv!` macro to create conversion types with reduced boilerplate.
+ The generated types can be used with `#[serde_as]` or serde's with-attribute.
+
+ ```rust
+ serde_with::serde_conv!(
+ RgbAsArray,
+ Rgb,
+ |rgb: &Rgb| [rgb.red, rgb.green, rgb.blue],
+ |value: [u8; 3]| -> Result<_, std::convert::Infallible> {
+ Ok(Rgb {
+ red: value[0],
+ green: value[1],
+ blue: value[2],
+ })
+ }
+ );
+ ```
+
+## [1.8.1] - 2021-04-19
+
+### Added
+
+* The `hex::Hex` type also works for u8-arrays on Rust 1.48.
+ Thanks to @TheAlgorythm for raising and fixing the issue.
+
+## [1.8.0] - 2021-03-30
+
+### Added
+
+* Added `PickFirst` adapter for `serde_as`. [#291]
+ It allows deserializing from multiple different forms.
+ Deserializing a number from either a number or string can be implemented like:
+
+ ```rust
+ #[serde_as(as = "PickFirst<(_, DisplayFromStr)>")]
+ value: u32,
+ ```
+
+* Implement `SerializeAs`/`DeserializeAs` for more wrapper types. [#288], [#293]
+ This now supports:
+ * `Arc`, `sync::Weak`
+ * `Rc`, `rc::Weak`
+ * `Cell`, `RefCell`
+ * `Mutex`, `RwLock`
+ * `Result`
+
+[#288]: https://github.com/jonasbb/serde_with/issues/288
+[#291]: https://github.com/jonasbb/serde_with/issues/291
+[#293]: https://github.com/jonasbb/serde_with/issues/293
+
+### Changed
+
+* Add a new `serde_with::rust::map_as_tuple_list` module as a replacement for `serde_with::rust::btreemap_as_tuple_list` and `serde_with::rust::hashmap_as_tuple_list`.
+ The new module uses `IntoIterator` and `FromIterator` as trait bound making it usable in more situations.
+ The old names continue to exist but are marked as deprecated.
+
+### Deprecated
+
+* Deprecated the module names `serde_with::rust::btreemap_as_tuple_list` and `serde_with::rust::hashmap_as_tuple_list`.
+ You can use `serde_with::rust::map_as_tuple_list` as a replacement.
+
+### Fixed
+
+* Implement `Timestamp*Seconds` and `Duration*Seconds` also for chrono types.
+ This closes [#194]. This was incompletely implemented in [#199].
+
+[#194]: https://github.com/jonasbb/serde_with/issues/194
+[#199]: https://github.com/jonasbb/serde_with/issues/199
+
+## [1.7.0] - 2021-03-24
+
+### Added
+
+* Add support for arrays of arbitrary size. ([#272])
+ This feature requires Rust 1.51+.
+
+ ```rust
+ // Rust
+ #[serde_as(as = "[[_; 64]; 33]")]
+ value: [[u8; 64]; 33],
+
+ // JSON
+ "value": [[0,0,0,0,0,...], [0,0,0,...], ...],
+ ```
+
+ Mapping of arrays was available before, but limited to arrays of length 32.
+ All conversion methods are available for the array elements.
+
+ This is similar to the existing [`serde-big-array`] crate with three important improvements:
+
+ 1. Support for the `serde_as` annotation.
+ 2. Supports non-copy elements (see [serde-big-array#6][serde-big-array-copy]).
+ 3. Supports arbitrary nestings of arrays (see [serde-big-array#7][serde-big-array-nested]).
+
+[#272]: https://github.com/jonasbb/serde_with/pull/272
+[`serde-big-array`]: https://crates.io/crates/serde-big-array
+[serde-big-array-copy]: https://github.com/est31/serde-big-array/issues/6
+[serde-big-array-nested]: https://github.com/est31/serde-big-array/issues/7
+
+* Arrays with tuple elements can now be deserialized from a map. ([#272])
+ This feature requires Rust 1.51+.
+
+ ```rust
+ // Rust
+ #[serde_as(as = "BTreeMap<_, _>")]
+ value: [(String, u16); 3],
+
+ // JSON
+ "value": {
+ "a": 1,
+ "b": 2,
+ "c": 3
+ },
+ ```
+
+* The `Bytes` type is heavily inspired by `serde_bytes` and ports it to the `serde_as` system. ([#277])
+
+ ```rust
+ #[serde_as(as = "Bytes")]
+ value: Vec<u8>,
+ ```
+
+ Compared to `serde_bytes` these improvements are available
+
+ 1. Integration with the `serde_as` annotation (see [serde-bytes#14][serde-bytes-complex]).
+ 2. Implementation for arrays of arbitrary size (Rust 1.51+) (see [serde-bytes#26][serde-bytes-arrays]).
+
+[#277]: https://github.com/jonasbb/serde_with/pull/277
+[serde-bytes-complex]: https://github.com/serde-rs/bytes/issues/14
+[serde-bytes-arrays]: https://github.com/serde-rs/bytes/issues/26
+
+* The `OneOrMany` type allows deserializing a `Vec` from either a single element or a sequence. ([#281])
+
+ ```rust
+ #[serde_as(as = "OneOrMany<_>")]
+ cities: Vec<String>,
+ ```
+
+ This allows deserializing from either `cities: "Berlin"` or `cities: ["Berlin", "Paris"]`.
+ The serialization can be configured to always emit a list with `PreferMany` or emit a single element with `PreferOne`.
+
+[#281]: https://github.com/jonasbb/serde_with/pull/281
+
+## [1.6.4] - 2021-02-16
+
+### Fixed
+
+* Fix compiling when having a struct field without the `serde_as` annotation by updating `serde_with_macros`.
+ This broke in 1.4.0 of `serde_with_macros`. [#267](https://github.com/jonasbb/serde_with/issues/267)
+
+## [1.6.3] - 2021-02-15
+
+### Changed
+
+* Bump macro crate dependency (`serde_with_macros`) to 1.4.0 to pull in those improvements.
+
+## [1.6.2] - 2021-01-30
+
+### Added
+
+* New function `serde_with::rust::deserialize_ignore_any`.
+ This function allows deserializing any data and returns the default value of the type.
+ This can be used in conjunction with `#[serde(other)]` to allow deserialization of unknown data carrying enum variants.
+
+ Thanks to @lovasoa for suggesting and implementing it.
+
+## [1.6.1] - 2021-01-24
+
+### Added
+
+* Add new types similar to `DurationSeconds` and `TimestampSeconds` but for base units of milliseconds, microseconds, and nanoseconds.
+ The `*WithFrac` variants also exist.
+* Add `SerializeAs` implementation for references.
+
+### Changed
+
+* Release `Sized` trait bound from `As`, `Same`, `SerializeAs`, and `SerializeAsWrap`.
+ Only the serialize part is relaxed.
+
+## [1.6.0] - 2020-11-22
+
+### Added
+
+* Add `DefaultOnNull` as the equivalent for `rust::default_on_null` but for the `serde_as` system.
+* Support specifying a path to the `serde_with` crate for the `serde_as` and derive macros.
+ This is useful when using crate renaming in Cargo.toml or while re-exporting the macros.
+
+ Many thanks to @tobz1000 for raising the issue and contributing fixes.
+
+### Changed
+
+* Bump minimum supported rust version to 1.40.0
+
+## [1.5.1] - 2020-10-07
+
+### Fixed
+
+* Depend on serde with the `derive` feature enabled.
+ The `derive` feature is required to deserialize untagged enums which are used in the `DefaultOnError` helpers.
+ This fixes compilation of `serde_with` in scenarios where no other crate enables the `derive` feature.
+
+## [1.5.0] - 2020-10-01
+
+### Added
+
+* The largest addition to this release is the addition of the `serde_as` de/serialization scheme.
+ It's goal is it to be a more flexible replacement to serde's with-annotation, by being more composable than before.
+ No longer is it a problem to add a custom de/serialization adapter is the type is within an `Option` or a `Vec`.
+
+ Thanks to `@markazmierczak` for the design of the trait without whom this wouldn't be possible.
+
+ More details about this new scheme can be found in the also new [user guide](https://docs.rs/serde_with/1.5.0/serde_with/guide/index.html)
+* This release also features a detailed user guide.
+ The guide focusses more on how to use this crate by providing examples.
+ For example, it includes a section about the available feature flags of this crate and how you can migrate to the shiny new `serde_as` scheme.
+* The crate now features de/serialization adaptors for the std and chrono's `Duration` types. #56 #104
+* Add a `hex` module, which allows formatting bytes (i.e. `Vec<u8>`) as a hexadecimal string.
+ The formatting supports different arguments how the formatting is happening.
+* Add two derive macros, `SerializeDisplay` and `DeserializeFromStr`, which implement the `Serialize`/`Deserialize` traits based on `Display` and `FromStr`.
+ This is in addition to the already existing methods like `DisplayFromStr`, which act locally, whereas the derive macros provide the traits expected by the rest of the ecosystem.
+
+ This is part of `serde_with_macros` v1.2.0.
+* Added some `serialize` functions to modules which previously had none.
+ This makes it easier to use the conversion when also deriving `Serialize`.
+ The functions simply pass through to the underlying `Serialize` implementation.
+ This affects `sets_duplicate_value_is_error`, `maps_duplicate_key_is_error`, `maps_first_key_wins`, `default_on_error`, and `default_on_null`.
+* Added `sets_last_value_wins` as a replacement for `sets_first_value_wins` which is deprecated now.
+ The default behavior of serde is to prefer the first value of a set so the opposite is taking the last value.
+* Added `#[serde_as]` compatible conversion methods for serializing durations and timestamps as numbers.
+ The four types `DurationSeconds`, `DurationSecondsWithFrac`, `TimestampSeconds`, `TimestampSecondsWithFrac` provide the serialization conversion with optional subsecond precision.
+ There is support for `std::time::Duration`, `chrono::Duration`, `std::time::SystemTime` and `chrono::DateTime`.
+ Timestamps are serialized as a duration since the UNIX epoch.
+ The serialization can be customized.
+ It supports multiple formats, such as `i64`, `f64`, or `String`, and the deserialization can be tweaked if it should be strict or lenient when accepting formats.
+
+### Changed
+
+* Convert the code to use 2018 edition.
+* @peterjoel improved the performance of `with_prefix!`. #101
+
+### Fixed
+
+* The `with_prefix!` macro, to add a string prefixes during serialization, now also works with unit variant enum types. #115 #116
+* The `serde_as` macro now supports serde attributes and no longer panic on unrecognized values in the attribute.
+ This is part of `serde_with_macros` v1.2.0.
+
+### Deprecated
+
+* Deprecate `sets_first_value_wins`.
+ The default behavior of serde is to take the first value, so this module is not necessary.
+
+## [1.5.0-alpha.2] - 2020-08-16
+
+### Added
+
+* Add a `hex` module, which allows formatting bytes (i.e. `Vec<u8>`) as a hexadecimal string.
+ The formatting supports different arguments how the formatting is happening.
+* Add two derive macros, `SerializeDisplay` and `DeserializeFromStr`, which implement the `Serialize`/`Deserialize` traits based on `Display` and `FromStr`.
+ This is in addition to the already existing methods like `DisplayFromStr`, which act locally, whereas the derive macros provide the traits expected by the rest of the ecosystem.
+
+ This is part of `serde_with_macros` v1.2.0-alpha.3.
+
+### Fixed
+
+* The `serde_as` macro now supports serde attributes and no longer panic on unrecognized values in the attribute.
+ This is part of `serde_with_macros` v1.2.0-alpha.2.
+
+## [1.5.0-alpha.1] - 2020-06-27
+
+### Added
+
+* The largest addition to this release is the addition of the `serde_as` de/serialization scheme.
+ It's goal is it to be a more flexible replacement to serde's with-annotation, by being more composable than before.
+ No longer is it a problem to add a custom de/serialization adapter is the type is within an `Option` or a `Vec`.
+
+ Thanks to `@markazmierczak` for the design of the trait without whom this wouldn't be possible.
+
+ More details about this new scheme can be found in the also new [user guide](https://docs.rs/serde_with/1.5.0-alpha.1/serde_with/guide/index.html)
+* This release also features a detailed user guide.
+ The guide focusses more on how to use this crate by providing examples.
+ For example, it includes a section about the available feature flags of this crate and how you can migrate to the shiny new `serde_as` scheme.
+* The crate now features de/serialization adaptors for the std and chrono's `Duration` types. #56 #104
+
+### Changed
+
+* Convert the code to use 2018 edition.
+* @peterjoel improved the performance of `with_prefix!`. #101
+
+### Fixed
+
+* The `with_prefix!` macro, to add a string prefixes during serialization, now also works with unit variant enum types. #115 #116
+
+## [1.4.0] - 2020-01-16
+
+### Added
+
+* Add a helper to deserialize a `Vec<u8>` from `String` (#35)
+* Add `default_on_error` helper, which turns errors into `Default`s of the type
+* Add `default_on_null` helper, which turns `null` values into `Default`s of the type
+
+### Changed
+
+* Bump minimal Rust version to 1.36.0
+ * Supports Rust Edition 2018
+ * version-sync depends on smallvec which requires 1.36
+* Improved CI pipeline by running `cargo audit` and `tarpaulin` in all configurations now.
+
+## [1.3.1] - 2019-04-09
+
+### Fixed
+
+* Use `serde_with_macros` with proper dependencies specified.
+
+## [1.3.0] - 2019-04-02
+
+### Added
+
+* Add `skip_serializing_none` attribute, which adds `#[serde(skip_serializing_if = "Option::is_none")]` for each Option in a struct.
+ This is helpful for APIs which have many optional fields.
+ The effect of can be negated by adding `serialize_always` on those fields, which should always be serialized.
+ Existing `skip_serializing_if` will never be modified and those fields keep their behavior.
+
+## [1.2.0] - 2019-03-04
+
+### Added
+
+* Add macro helper to support deserializing values with nested or flattened syntax #38
+* Serialize tuple list as map helper
+
+### Changed
+
+* Bumped minimal Rust version to 1.30.0
+
+## [1.1.0] - 2019-02-18
+
+### Added
+
+* Serialize HashMap/BTreeMap as list of tuples
+
+## [1.0.0] - 2019-01-17
+
+### Added
+
+* No changes in this release.
+* Bumped version number to indicate the stability of the library.
+
+## [0.2.5] - 2018-11-29
+
+### Added
+
+* Helper which deserializes an empty string as `None` and otherwise uses `FromStr` and `AsRef<str>`.
+
+## [0.2.4] - 2018-11-24
+
+### Added
+
+* De/Serialize sequences by using `Display` and `FromStr` implementations on each element. Contributed by @katyo
+
+## [0.2.3] - 2018-11-08
+
+### Added
+
+* Add missing docs and enable deny missing_docs
+* Add badges to Cargo.toml and crates.io
+
+### Changed
+
+* Improve Travis configuration
+* Various clippy improvements
+
+## [0.2.2] - 2018-08-05
+
+### Added
+
+* `unwrap_or_skip` allows to transparently serialize the inner part of a `Some(T)`
+* Add deserialization helper for sets and maps, inspired by [comment](https://github.com/serde-rs/serde/issues/553#issuecomment-299711855)
+ * Create an error if duplicate values for a set are detected
+ * Create an error if duplicate keys for a map are detected
+ * Implement a first-value wins strategy for sets/maps. This is different to serde's default
+ which implements a last value wins strategy.
+
+## [0.2.1] - 2018-06-05
+
+### Added
+
+* Double Option pattern to differentiate between missing, unset, or existing value
+* `with_prefix!` macro, which puts a prefix on every struct field
+
+## [0.2.0] - 2018-05-31
+
+### Added
+
+* Add chrono support: Deserialize timestamps from int, float, and string
+* Serialization of embedded JSON strings
+* De/Serialization using `Display` and `FromStr` implementations
+* String-based collections using `Display` and `FromStr`, allows deserializing "#foo,#bar"
+
+## [0.1.0] - 2017-08-17
+
+### Added
+
+* Reserve name on crates.io
diff --git a/third_party/rust/serde_with/Cargo.toml b/third_party/rust/serde_with/Cargo.toml
new file mode 100644
index 0000000000..eeca00edef
--- /dev/null
+++ b/third_party/rust/serde_with/Cargo.toml
@@ -0,0 +1,214 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+rust-version = "1.53"
+name = "serde_with"
+version = "1.14.0"
+authors = [
+ "Jonas Bushart",
+ "Marcin Kaźmierczak",
+]
+include = [
+ "src/**/*",
+ "tests/**/*",
+ "LICENSE-*",
+ "README.md",
+ "CHANGELOG.md",
+]
+description = "Custom de/serialization functions for Rust's serde"
+documentation = "https://docs.rs/serde_with/"
+readme = "README.md"
+keywords = [
+ "serde",
+ "utilities",
+ "serialization",
+ "deserialization",
+]
+categories = ["encoding"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/jonasbb/serde_with"
+resolver = "2"
+
+[package.metadata.docs.rs]
+all-features = true
+rustdoc-args = [
+ "--cfg=docsrs",
+ "-Zunstable-options",
+ "--generate-link-to-definition",
+]
+
+[[test]]
+name = "base64"
+path = "tests/base64.rs"
+required-features = [
+ "base64",
+ "macros",
+]
+
+[[test]]
+name = "chrono"
+path = "tests/chrono.rs"
+required-features = [
+ "chrono",
+ "macros",
+]
+
+[[test]]
+name = "hex"
+path = "tests/hex.rs"
+required-features = [
+ "hex",
+ "macros",
+]
+
+[[test]]
+name = "indexmap"
+path = "tests/indexmap.rs"
+required-features = [
+ "indexmap",
+ "macros",
+]
+
+[[test]]
+name = "json"
+path = "tests/json.rs"
+required-features = [
+ "json",
+ "macros",
+]
+
+[[test]]
+name = "serde_as"
+path = "tests/serde_as/lib.rs"
+required-features = ["macros"]
+
+[[test]]
+name = "time_0_3"
+path = "tests/time_0_3.rs"
+required-features = [
+ "macros",
+ "time_0_3",
+]
+
+[[test]]
+name = "derives"
+path = "tests/derives/lib.rs"
+required-features = ["macros"]
+
+[dependencies.base64_crate]
+version = "0.13.0"
+optional = true
+package = "base64"
+
+[dependencies.chrono_crate]
+version = "0.4.1"
+features = [
+ "clock",
+ "serde",
+ "std",
+]
+optional = true
+default-features = false
+package = "chrono"
+
+[dependencies.doc-comment]
+version = "0.3.3"
+optional = true
+
+[dependencies.hex]
+version = "0.4.2"
+optional = true
+
+[dependencies.indexmap_crate]
+version = "1.8"
+features = ["serde-1"]
+optional = true
+package = "indexmap"
+
+[dependencies.serde]
+version = "1.0.122"
+features = ["derive"]
+
+[dependencies.serde_json]
+version = "1.0.1"
+optional = true
+
+[dependencies.serde_with_macros]
+version = "1.5.2"
+optional = true
+
+[dependencies.time_0_3]
+version = "~0.3"
+features = ["serde-well-known"]
+optional = true
+package = "time"
+
+[dev-dependencies.expect-test]
+version = "1.0.0"
+
+[dev-dependencies.fnv]
+version = "1.0.6"
+
+[dev-dependencies.glob]
+version = "0.3.0"
+
+[dev-dependencies.mime]
+version = "0.3.16"
+
+[dev-dependencies.pretty_assertions]
+version = "1.0.0"
+
+[dev-dependencies.regex]
+version = "1.3.9"
+features = ["std"]
+default-features = false
+
+[dev-dependencies.rmp-serde]
+version = "1.1.0"
+
+[dev-dependencies.ron]
+version = "0.7"
+
+[dev-dependencies.rustversion]
+version = "1.0.0"
+
+[dev-dependencies.serde-xml-rs]
+version = "0.5.0"
+
+[dev-dependencies.serde_json]
+version = "1.0.25"
+features = ["preserve_order"]
+
+[dev-dependencies.serde_test]
+version = "1.0.124"
+
+[dev-dependencies.serde_yaml]
+version = "0.8.21"
+
+[dev-dependencies.version-sync]
+version = "0.9.1"
+
+[features]
+base64 = ["base64_crate"]
+chrono = ["chrono_crate"]
+default = ["macros"]
+guide = [
+ "doc-comment",
+ "macros",
+]
+indexmap = ["indexmap_crate"]
+json = ["serde_json"]
+macros = ["serde_with_macros"]
+
+[badges.maintenance]
+status = "actively-developed"
diff --git a/third_party/rust/serde_with/LICENSE-APACHE b/third_party/rust/serde_with/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/serde_with/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/third_party/rust/serde_with/LICENSE-MIT b/third_party/rust/serde_with/LICENSE-MIT
new file mode 100644
index 0000000000..9203baa055
--- /dev/null
+++ b/third_party/rust/serde_with/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2015
+
+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.
diff --git a/third_party/rust/serde_with/README.md b/third_party/rust/serde_with/README.md
new file mode 100644
index 0000000000..a765d3578d
--- /dev/null
+++ b/third_party/rust/serde_with/README.md
@@ -0,0 +1,188 @@
+# Custom de/serialization functions for Rust's [serde](https://serde.rs)
+
+[![crates.io badge](https://img.shields.io/crates/v/serde_with.svg)](https://crates.io/crates/serde_with/)
+[![Build Status](https://github.com/jonasbb/serde_with/workflows/Rust%20CI/badge.svg)](https://github.com/jonasbb/serde_with)
+[![codecov](https://codecov.io/gh/jonasbb/serde_with/branch/master/graph/badge.svg)](https://codecov.io/gh/jonasbb/serde_with)
+[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4322/badge)](https://bestpractices.coreinfrastructure.org/projects/4322)
+[![Binder](https://img.shields.io/badge/Try%20on%20-binder-579ACA.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAABZCAMAAABi1XidAAAB8lBMVEX///9XmsrmZYH1olJXmsr1olJXmsrmZYH1olJXmsr1olJXmsrmZYH1olL1olJXmsr1olJXmsrmZYH1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olJXmsrmZYH1olL1olL0nFf1olJXmsrmZYH1olJXmsq8dZb1olJXmsrmZYH1olJXmspXmspXmsr1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olLeaIVXmsrmZYH1olL1olL1olJXmsrmZYH1olLna31Xmsr1olJXmsr1olJXmsrmZYH1olLqoVr1olJXmsr1olJXmsrmZYH1olL1olKkfaPobXvviGabgadXmsqThKuofKHmZ4Dobnr1olJXmsr1olJXmspXmsr1olJXmsrfZ4TuhWn1olL1olJXmsqBi7X1olJXmspZmslbmMhbmsdemsVfl8ZgmsNim8Jpk8F0m7R4m7F5nLB6jbh7jbiDirOEibOGnKaMhq+PnaCVg6qWg6qegKaff6WhnpKofKGtnomxeZy3noG6dZi+n3vCcpPDcpPGn3bLb4/Mb47UbIrVa4rYoGjdaIbeaIXhoWHmZYHobXvpcHjqdHXreHLroVrsfG/uhGnuh2bwj2Hxk17yl1vzmljzm1j0nlX1olL3AJXWAAAAbXRSTlMAEBAQHx8gICAuLjAwMDw9PUBAQEpQUFBXV1hgYGBkcHBwcXl8gICAgoiIkJCQlJicnJ2goKCmqK+wsLC4usDAwMjP0NDQ1NbW3Nzg4ODi5+3v8PDw8/T09PX29vb39/f5+fr7+/z8/Pz9/v7+zczCxgAABC5JREFUeAHN1ul3k0UUBvCb1CTVpmpaitAGSLSpSuKCLWpbTKNJFGlcSMAFF63iUmRccNG6gLbuxkXU66JAUef/9LSpmXnyLr3T5AO/rzl5zj137p136BISy44fKJXuGN/d19PUfYeO67Znqtf2KH33Id1psXoFdW30sPZ1sMvs2D060AHqws4FHeJojLZqnw53cmfvg+XR8mC0OEjuxrXEkX5ydeVJLVIlV0e10PXk5k7dYeHu7Cj1j+49uKg7uLU61tGLw1lq27ugQYlclHC4bgv7VQ+TAyj5Zc/UjsPvs1sd5cWryWObtvWT2EPa4rtnWW3JkpjggEpbOsPr7F7EyNewtpBIslA7p43HCsnwooXTEc3UmPmCNn5lrqTJxy6nRmcavGZVt/3Da2pD5NHvsOHJCrdc1G2r3DITpU7yic7w/7Rxnjc0kt5GC4djiv2Sz3Fb2iEZg41/ddsFDoyuYrIkmFehz0HR2thPgQqMyQYb2OtB0WxsZ3BeG3+wpRb1vzl2UYBog8FfGhttFKjtAclnZYrRo9ryG9uG/FZQU4AEg8ZE9LjGMzTmqKXPLnlWVnIlQQTvxJf8ip7VgjZjyVPrjw1te5otM7RmP7xm+sK2Gv9I8Gi++BRbEkR9EBw8zRUcKxwp73xkaLiqQb+kGduJTNHG72zcW9LoJgqQxpP3/Tj//c3yB0tqzaml05/+orHLksVO+95kX7/7qgJvnjlrfr2Ggsyx0eoy9uPzN5SPd86aXggOsEKW2Prz7du3VID3/tzs/sSRs2w7ovVHKtjrX2pd7ZMlTxAYfBAL9jiDwfLkq55Tm7ifhMlTGPyCAs7RFRhn47JnlcB9RM5T97ASuZXIcVNuUDIndpDbdsfrqsOppeXl5Y+XVKdjFCTh+zGaVuj0d9zy05PPK3QzBamxdwtTCrzyg/2Rvf2EstUjordGwa/kx9mSJLr8mLLtCW8HHGJc2R5hS219IiF6PnTusOqcMl57gm0Z8kanKMAQg0qSyuZfn7zItsbGyO9QlnxY0eCuD1XL2ys/MsrQhltE7Ug0uFOzufJFE2PxBo/YAx8XPPdDwWN0MrDRYIZF0mSMKCNHgaIVFoBbNoLJ7tEQDKxGF0kcLQimojCZopv0OkNOyWCCg9XMVAi7ARJzQdM2QUh0gmBozjc3Skg6dSBRqDGYSUOu66Zg+I2fNZs/M3/f/Grl/XnyF1Gw3VKCez0PN5IUfFLqvgUN4C0qNqYs5YhPL+aVZYDE4IpUk57oSFnJm4FyCqqOE0jhY2SMyLFoo56zyo6becOS5UVDdj7Vih0zp+tcMhwRpBeLyqtIjlJKAIZSbI8SGSF3k0pA3mR5tHuwPFoa7N7reoq2bqCsAk1HqCu5uvI1n6JuRXI+S1Mco54YmYTwcn6Aeic+kssXi8XpXC4V3t7/ADuTNKaQJdScAAAAAElFTkSuQmCC)](https://mybinder.org/v2/gist/jonasbb/18b9aece4c17f617b1c2b3946d29eeb0/HEAD?filepath=serde-with-demo.ipynb)
+
+---
+
+This crate provides custom de/serialization helpers to use in combination with [serde's with-annotation][with-annotation] and with the improved [`serde_as`][as-annotation]-annotation.
+Some common use cases are:
+
+* De/Serializing a type using the `Display` and `FromStr` traits, e.g., for `u8`, `url::Url`, or `mime::Mime`.
+ Check [`DisplayFromStr`][] or [`serde_with::rust::display_fromstr`][display_fromstr] for details.
+* Support for arrays larger than 32 elements or using const generics.
+ With `serde_as` large arrays are supported, even if they are nested in other types.
+ `[bool; 64]`, `Option<[u8; M]>`, and `Box<[[u8; 64]; N]>` are all supported, as [this examples shows](#large-and-const-generic-arrays).
+* Skip serializing all empty `Option` types with [`#[skip_serializing_none]`][skip_serializing_none].
+* Apply a prefix to each field name of a struct, without changing the de/serialize implementations of the struct using [`with_prefix!`][].
+* Deserialize a comma separated list like `#hash,#tags,#are,#great` into a `Vec<String>`.
+ Check the documentation for [`serde_with::rust::StringWithSeparator::<CommaSeparator>`][StringWithSeparator].
+
+### Getting Help
+
+**Check out the [user guide][user guide] to find out more tips and tricks about this crate.**
+
+For further help using this crate you can [open a new discussion](https://github.com/jonasbb/serde_with/discussions/new) or ask on [users.rust-lang.org](https://users.rust-lang.org/).
+For bugs, please open a [new issue](https://github.com/jonasbb/serde_with/issues/new) on GitHub.
+
+## Use `serde_with` in your Project
+
+Add this to your `Cargo.toml`:
+
+```toml
+[dependencies.serde_with]
+version = "1.14.0"
+features = [ "..." ]
+```
+
+The crate contains different features for integration with other common crates.
+Check the [feature flags][] section for information about all available features.
+
+## Examples
+
+Annotate your struct or enum to enable the custom de/serializer.
+The `#[serde_as]` attribute must be place *before* the `#[derive]`.
+
+### `DisplayFromStr`
+
+```rust
+#[serde_as]
+#[derive(Deserialize, Serialize)]
+struct Foo {
+ // Serialize with Display, deserialize with FromStr
+ #[serde_as(as = "DisplayFromStr")]
+ bar: u8,
+}
+
+// This will serialize
+Foo {bar: 12}
+
+// into this JSON
+{"bar": "12"}
+```
+
+### Large and const-generic arrays
+
+serde does not support arrays with more than 32 elements or using const-generics.
+The `serde_as` attribute allows to circumvent this restriction, even for nested types and nested arrays.
+
+```rust
+#[serde_as]
+#[derive(Deserialize, Serialize)]
+struct Arrays<const N: usize, const M: usize> {
+ #[serde_as(as = "[_; N]")]
+ constgeneric: [bool; N],
+
+ #[serde_as(as = "Box<[[_; 64]; N]>")]
+ nested: Box<[[u8; 64]; N]>,
+
+ #[serde_as(as = "Option<[_; M]>")]
+ optional: Option<[u8; M]>,
+}
+
+// This allows us to serialize a struct like this
+let arrays: Arrays<100, 128> = Arrays {
+ constgeneric: [true; 100],
+ nested: Box::new([[111; 64]; 100]),
+ optional: Some([222; 128])
+};
+assert!(serde_json::to_string(&arrays).is_ok());
+```
+
+### `skip_serializing_none`
+
+This situation often occurs with JSON, but other formats also support optional fields.
+If many fields are optional, putting the annotations on the structs can become tedious.
+The `#[skip_serializing_none]` attribute must be place *before* the `#[derive]`.
+
+```rust
+#[skip_serializing_none]
+#[derive(Deserialize, Serialize)]
+struct Foo {
+ a: Option<usize>,
+ b: Option<usize>,
+ c: Option<usize>,
+ d: Option<usize>,
+ e: Option<usize>,
+ f: Option<usize>,
+ g: Option<usize>,
+}
+
+// This will serialize
+Foo {a: None, b: None, c: None, d: Some(4), e: None, f: None, g: Some(7)}
+
+// into this JSON
+{"d": 4, "g": 7}
+```
+
+### Advanced `serde_as` usage
+
+This example is mainly supposed to highlight the flexibility of the `serde_as`-annotation compared to [serde's with-annotation][with-annotation].
+More details about `serde_as` can be found in the [user guide][].
+
+```rust
+#[serde_as]
+#[derive(Deserialize, Serialize)]
+struct Foo {
+ // Serialize them into a list of number as seconds
+ #[serde_as(as = "Vec<DurationSeconds>")]
+ durations: Vec<Duration>,
+ // We can treat a Vec like a map with duplicates.
+ // JSON only allows string keys, so convert i32 to strings
+ // The bytes will be hex encoded
+ #[serde_as(as = "BTreeMap<DisplayFromStr, Hex>")]
+ bytes: Vec<(i32, Vec<u8>)>,
+}
+
+// This will serialize
+Foo {
+ durations: vec![Duration::new(5, 0), Duration::new(3600, 0), Duration::new(0, 0)],
+ bytes: vec![
+ (1, vec![0, 1, 2]),
+ (-100, vec![100, 200, 255]),
+ (1, vec![0, 111, 222]),
+ ],
+}
+
+// into this JSON
+{
+ "durations": [5, 3600, 0],
+ "bytes": {
+ "1": "000102",
+ "-100": "64c8ff",
+ "1": "006fde"
+ }
+}
+```
+
+[`DisplayFromStr`]: https://docs.rs/serde_with/1.14.0/serde_with/struct.DisplayFromStr.html
+[`with_prefix!`]: https://docs.rs/serde_with/1.14.0/serde_with/macro.with_prefix.html
+[display_fromstr]: https://docs.rs/serde_with/1.14.0/serde_with/rust/display_fromstr/index.html
+[feature flags]: https://docs.rs/serde_with/1.14.0/serde_with/guide/feature_flags/index.html
+[skip_serializing_none]: https://docs.rs/serde_with/1.14.0/serde_with/attr.skip_serializing_none.html
+[StringWithSeparator]: https://docs.rs/serde_with/1.14.0/serde_with/rust/struct.StringWithSeparator.html
+[user guide]: https://docs.rs/serde_with/1.14.0/serde_with/guide/index.html
+[with-annotation]: https://serde.rs/field-attrs.html#with
+[as-annotation]: https://docs.rs/serde_with/1.14.0/serde_with/guide/serde_as/index.html
+
+## License
+
+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
+
+For detailed contribution instructions please read [`CONTRIBUTING.md`].
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall
+be dual licensed as above, without any additional terms or conditions.
+
+[`CONTRIBUTING.md`]: https://github.com/jonasbb/serde_with/blob/master/CONTRIBUTING.md
diff --git a/third_party/rust/serde_with/src/base64.rs b/third_party/rust/serde_with/src/base64.rs
new file mode 100644
index 0000000000..e1c6490f44
--- /dev/null
+++ b/third_party/rust/serde_with/src/base64.rs
@@ -0,0 +1,205 @@
+//! De/Serialization of base64 encoded bytes
+//!
+//! This modules is only available when using the `base64` feature of the crate.
+//!
+//! Please check the documentation on the [`Base64`] type for details.
+
+use crate::{formats, DeserializeAs, SerializeAs};
+use alloc::{format, string::String, vec::Vec};
+use core::{
+ convert::{TryFrom, TryInto},
+ default::Default,
+ marker::PhantomData,
+};
+use serde::{de::Error, Deserialize, Deserializer, Serialize, Serializer};
+
+/// Serialize bytes with base64
+///
+/// The type serializes a sequence of bytes as a base64 string.
+/// It works on any type implementing `AsRef<[u8]>` for serialization and `TryFrom<Vec<u8>>` for deserialization.
+///
+/// The type allows customizing the character set and the padding behavior.
+/// The `CHARSET` is a type implementing [`CharacterSet`].
+/// `PADDING` specifies if serializing should emit padding.
+/// Deserialization always supports padded and unpadded formats.
+/// [`formats::Padded`] emits padding and [`formats::Unpadded`] leaves it off.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::serde_as;
+/// use serde_with::base64::{Base64, Bcrypt, BinHex, Standard};
+/// use serde_with::formats::{Padded, Unpadded};
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq, Eq)]
+/// #[derive(Serialize, Deserialize)]
+/// struct B64 {
+/// // The default is the same as Standard character set with padding
+/// #[serde_as(as = "Base64")]
+/// default: Vec<u8>,
+/// // Only change the character set, implies padding
+/// #[serde_as(as = "Base64<BinHex>")]
+/// charset_binhex: Vec<u8>,
+///
+/// #[serde_as(as = "Base64<Standard, Padded>")]
+/// explicit_padding: Vec<u8>,
+/// #[serde_as(as = "Base64<Bcrypt, Unpadded>")]
+/// no_padding: Vec<u8>,
+/// }
+///
+/// let b64 = B64 {
+/// default: b"Hello World".to_vec(),
+/// charset_binhex: b"Hello World".to_vec(),
+/// explicit_padding: b"Hello World".to_vec(),
+/// no_padding: b"Hello World".to_vec(),
+/// };
+/// let json = serde_json::json!({
+/// "default": "SGVsbG8gV29ybGQ=",
+/// "charset_binhex": "5'8VD'mI8epaD'3=",
+/// "explicit_padding": "SGVsbG8gV29ybGQ=",
+/// "no_padding": "QETqZE6eT07wZEO",
+/// });
+///
+/// // Test serialization and deserialization
+/// assert_eq!(json, serde_json::to_value(&b64).unwrap());
+/// assert_eq!(b64, serde_json::from_value(json).unwrap());
+/// # }
+/// ```
+
+// The padding might be better as `const PADDING: bool = true`
+// https://blog.rust-lang.org/inside-rust/2021/09/06/Splitting-const-generics.html#featureconst_generics_default/
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Base64<CHARSET: CharacterSet = Standard, PADDING: formats::Format = formats::Padded>(
+ PhantomData<(CHARSET, PADDING)>,
+);
+
+impl<T, CHARSET> SerializeAs<T> for Base64<CHARSET, formats::Padded>
+where
+ T: AsRef<[u8]>,
+ CHARSET: CharacterSet,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ base64_crate::encode_config(source, base64_crate::Config::new(CHARSET::charset(), true))
+ .serialize(serializer)
+ }
+}
+
+impl<T, CHARSET> SerializeAs<T> for Base64<CHARSET, formats::Unpadded>
+where
+ T: AsRef<[u8]>,
+ CHARSET: CharacterSet,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ base64_crate::encode_config(source, base64_crate::Config::new(CHARSET::charset(), false))
+ .serialize(serializer)
+ }
+}
+
+impl<'de, T, CHARSET, FORMAT> DeserializeAs<'de, T> for Base64<CHARSET, FORMAT>
+where
+ T: TryFrom<Vec<u8>>,
+ CHARSET: CharacterSet,
+ FORMAT: formats::Format,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ String::deserialize(deserializer)
+ .and_then(|s| {
+ base64_crate::decode_config(
+ &*s,
+ base64_crate::Config::new(CHARSET::charset(), false),
+ )
+ .map_err(Error::custom)
+ })
+ .and_then(|vec: Vec<u8>| {
+ let length = vec.len();
+ vec.try_into().map_err(|_e: T::Error| {
+ Error::custom(format!(
+ "Can't convert a Byte Vector of length {} to the output type.",
+ length
+ ))
+ })
+ })
+ }
+}
+
+/// A base64 character set from [this list](base64_crate::CharacterSet).
+pub trait CharacterSet {
+ /// Return a specific character set.
+ ///
+ /// Return one enum variant of the [`base64::CharacterSet`](base64_crate::CharacterSet) enum.
+ fn charset() -> base64_crate::CharacterSet;
+}
+
+/// The standard character set (uses `+` and `/`).
+///
+/// See [RFC 3548](https://tools.ietf.org/html/rfc3548#section-3).
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Standard;
+impl CharacterSet for Standard {
+ fn charset() -> base64_crate::CharacterSet {
+ base64_crate::CharacterSet::Standard
+ }
+}
+
+/// The URL safe character set (uses `-` and `_`).
+///
+/// See [RFC 3548](https://tools.ietf.org/html/rfc3548#section-3).
+#[derive(Copy, Clone, Debug, Default)]
+pub struct UrlSafe;
+impl CharacterSet for UrlSafe {
+ fn charset() -> base64_crate::CharacterSet {
+ base64_crate::CharacterSet::UrlSafe
+ }
+}
+
+/// The `crypt(3)` character set (uses `./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`).
+///
+/// Not standardized, but folk wisdom on the net asserts that this alphabet is what crypt uses.
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Crypt;
+impl CharacterSet for Crypt {
+ fn charset() -> base64_crate::CharacterSet {
+ base64_crate::CharacterSet::Crypt
+ }
+}
+
+/// The bcrypt character set (uses `./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789`).
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Bcrypt;
+impl CharacterSet for Bcrypt {
+ fn charset() -> base64_crate::CharacterSet {
+ base64_crate::CharacterSet::Bcrypt
+ }
+}
+
+/// The character set used in IMAP-modified UTF-7 (uses `+` and `,`).
+///
+/// See [RFC 3501](https://tools.ietf.org/html/rfc3501#section-5.1.3).
+#[derive(Copy, Clone, Debug, Default)]
+pub struct ImapMutf7;
+impl CharacterSet for ImapMutf7 {
+ fn charset() -> base64_crate::CharacterSet {
+ base64_crate::CharacterSet::ImapMutf7
+ }
+}
+
+/// The character set used in BinHex 4.0 files.
+///
+/// See [BinHex 4.0 Definition](http://files.stairways.com/other/binhex-40-specs-info.txt).
+#[derive(Copy, Clone, Debug, Default)]
+pub struct BinHex;
+impl CharacterSet for BinHex {
+ fn charset() -> base64_crate::CharacterSet {
+ base64_crate::CharacterSet::BinHex
+ }
+}
diff --git a/third_party/rust/serde_with/src/chrono.rs b/third_party/rust/serde_with/src/chrono.rs
new file mode 100644
index 0000000000..d39725464f
--- /dev/null
+++ b/third_party/rust/serde_with/src/chrono.rs
@@ -0,0 +1,516 @@
+//! De/Serialization of [chrono][] types
+//!
+//! This modules is only available if using the `chrono` feature of the crate.
+//!
+//! [chrono]: https://docs.rs/chrono/
+
+use crate::{
+ de::DeserializeAs,
+ formats::{Flexible, Format, Strict, Strictness},
+ ser::SerializeAs,
+ utils::duration::{DurationSigned, Sign},
+ DurationMicroSeconds, DurationMicroSecondsWithFrac, DurationMilliSeconds,
+ DurationMilliSecondsWithFrac, DurationNanoSeconds, DurationNanoSecondsWithFrac,
+ DurationSeconds, DurationSecondsWithFrac, TimestampMicroSeconds, TimestampMicroSecondsWithFrac,
+ TimestampMilliSeconds, TimestampMilliSecondsWithFrac, TimestampNanoSeconds,
+ TimestampNanoSecondsWithFrac, TimestampSeconds, TimestampSecondsWithFrac,
+};
+use alloc::{format, string::String, vec::Vec};
+use chrono_crate::{DateTime, Duration, Local, NaiveDateTime, TimeZone, Utc};
+use core::fmt;
+use serde::{de, Deserialize, Deserializer, Serialize, Serializer};
+
+/// Create a [`DateTime`] for the Unix Epoch using the [`Utc`] timezone
+fn unix_epoch_utc() -> DateTime<Utc> {
+ DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc)
+}
+
+/// Create a [`DateTime`] for the Unix Epoch using the [`Local`] timezone
+fn unix_epoch_local() -> DateTime<Local> {
+ DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc).with_timezone(&Local)
+}
+
+/// Create a [`NaiveDateTime`] for the Unix Epoch
+fn unix_epoch_naive() -> NaiveDateTime {
+ NaiveDateTime::from_timestamp(0, 0)
+}
+
+/// Deserialize a Unix timestamp with optional subsecond precision into a `DateTime<Utc>`.
+///
+/// The `DateTime<Utc>` can be serialized from an integer, a float, or a string representing a number.
+///
+/// # Examples
+///
+/// ```
+/// # use chrono_crate::{DateTime, Utc};
+/// # use serde::Deserialize;
+/// #
+/// #[derive(Debug, Deserialize)]
+/// struct S {
+/// #[serde(with = "serde_with::chrono::datetime_utc_ts_seconds_from_any")]
+/// date: DateTime<Utc>,
+/// }
+///
+/// // Deserializes integers
+/// assert!(serde_json::from_str::<S>(r#"{ "date": 1478563200 }"#).is_ok());
+/// // floats
+/// assert!(serde_json::from_str::<S>(r#"{ "date": 1478563200.123 }"#).is_ok());
+/// // and strings with numbers, for high-precision values
+/// assert!(serde_json::from_str::<S>(r#"{ "date": "1478563200.123" }"#).is_ok());
+/// ```
+pub mod datetime_utc_ts_seconds_from_any {
+ use super::*;
+ use chrono_crate::{DateTime, NaiveDateTime, Utc};
+ use serde::de::{Deserializer, Error, Unexpected, Visitor};
+
+ /// Deserialize a Unix timestamp with optional subsecond precision into a `DateTime<Utc>`.
+ pub fn deserialize<'de, D>(deserializer: D) -> Result<DateTime<Utc>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct Helper;
+ impl<'de> Visitor<'de> for Helper {
+ type Value = DateTime<Utc>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter
+ .write_str("an integer, float, or string with optional subsecond precision.")
+ }
+
+ fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let ndt = NaiveDateTime::from_timestamp_opt(value, 0);
+ if let Some(ndt) = ndt {
+ Ok(DateTime::<Utc>::from_utc(ndt, Utc))
+ } else {
+ Err(Error::custom(format!(
+ "a timestamp which can be represented in a DateTime but received '{}'",
+ value
+ )))
+ }
+ }
+
+ fn visit_u64<E>(self, value: u64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let ndt = NaiveDateTime::from_timestamp_opt(value as i64, 0);
+ if let Some(ndt) = ndt {
+ Ok(DateTime::<Utc>::from_utc(ndt, Utc))
+ } else {
+ Err(Error::custom(format!(
+ "a timestamp which can be represented in a DateTime but received '{}'",
+ value
+ )))
+ }
+ }
+
+ fn visit_f64<E>(self, value: f64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let seconds = value.trunc() as i64;
+ let nsecs = (value.fract() * 1_000_000_000_f64).abs() as u32;
+ let ndt = NaiveDateTime::from_timestamp_opt(seconds, nsecs);
+ if let Some(ndt) = ndt {
+ Ok(DateTime::<Utc>::from_utc(ndt, Utc))
+ } else {
+ Err(Error::custom(format!(
+ "a timestamp which can be represented in a DateTime but received '{}'",
+ value
+ )))
+ }
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let parts: Vec<_> = value.split('.').collect();
+
+ match *parts.as_slice() {
+ [seconds] => {
+ if let Ok(seconds) = seconds.parse() {
+ let ndt = NaiveDateTime::from_timestamp_opt(seconds, 0);
+ if let Some(ndt) = ndt {
+ Ok(DateTime::<Utc>::from_utc(ndt, Utc))
+ } else {
+ Err(Error::custom(format!(
+ "a timestamp which can be represented in a DateTime but received '{}'",
+ value
+ )))
+ }
+ } else {
+ Err(Error::invalid_value(Unexpected::Str(value), &self))
+ }
+ }
+ [seconds, subseconds] => {
+ if let Ok(seconds) = seconds.parse() {
+ let subseclen = subseconds.chars().count() as u32;
+ if subseclen > 9 {
+ return Err(Error::custom(format!(
+ "DateTimes only support nanosecond precision but '{}' has more than 9 digits.",
+ value
+ )));
+ }
+
+ if let Ok(mut subseconds) = subseconds.parse() {
+ // convert subseconds to nanoseconds (10^-9), require 9 places for nanoseconds
+ subseconds *= 10u32.pow(9 - subseclen);
+ let ndt = NaiveDateTime::from_timestamp_opt(seconds, subseconds);
+ if let Some(ndt) = ndt {
+ Ok(DateTime::<Utc>::from_utc(ndt, Utc))
+ } else {
+ Err(Error::custom(format!(
+ "a timestamp which can be represented in a DateTime but received '{}'",
+ value
+ )))
+ }
+ } else {
+ Err(Error::invalid_value(Unexpected::Str(value), &self))
+ }
+ } else {
+ Err(Error::invalid_value(Unexpected::Str(value), &self))
+ }
+ }
+
+ _ => Err(Error::invalid_value(Unexpected::Str(value), &self)),
+ }
+ }
+ }
+
+ deserializer.deserialize_any(Helper)
+ }
+}
+
+impl SerializeAs<NaiveDateTime> for DateTime<Utc> {
+ fn serialize_as<S>(source: &NaiveDateTime, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let datetime = DateTime::<Utc>::from_utc(*source, Utc);
+ datetime.serialize(serializer)
+ }
+}
+
+impl<'de> DeserializeAs<'de, NaiveDateTime> for DateTime<Utc> {
+ fn deserialize_as<D>(deserializer: D) -> Result<NaiveDateTime, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ DateTime::<Utc>::deserialize(deserializer).map(|datetime| datetime.naive_utc())
+ }
+}
+
+/// Convert a [`chrono::Duration`] into a [`DurationSigned`]
+fn duration_into_duration_signed(dur: &Duration) -> DurationSigned {
+ match dur.to_std() {
+ Ok(dur) => DurationSigned::with_duration(Sign::Positive, dur),
+ Err(_) => {
+ if let Ok(dur) = (-*dur).to_std() {
+ DurationSigned::with_duration(Sign::Negative, dur)
+ } else {
+ panic!("A chrono Duration should be convertible to a DurationSigned")
+ }
+ }
+ }
+}
+
+/// Convert a [`DurationSigned`] into a [`chrono::Duration`]
+fn duration_from_duration_signed<'de, D>(dur: DurationSigned) -> Result<Duration, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ let mut chrono_dur = match Duration::from_std(dur.duration) {
+ Ok(dur) => dur,
+ Err(msg) => {
+ return Err(de::Error::custom(format!(
+ "Duration is outside of the representable range: {}",
+ msg
+ )))
+ }
+ };
+ if dur.sign.is_negative() {
+ chrono_dur = -chrono_dur;
+ }
+ Ok(chrono_dur)
+}
+
+macro_rules! use_duration_signed_ser {
+ (
+ $main_trait:ident $internal_trait:ident =>
+ {
+ $ty:ty; $converter:ident =>
+ $({
+ $format:ty, $strictness:ty =>
+ $($tbound:ident: $bound:ident $(,)?)*
+ })*
+ }
+ ) => {
+ $(
+ impl<$($tbound ,)*> SerializeAs<$ty> for $main_trait<$format, $strictness>
+ where
+ $($tbound: $bound,)*
+ {
+ fn serialize_as<S>(source: &$ty, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let dur: DurationSigned = $converter(source);
+ $internal_trait::<$format, $strictness>::serialize_as(
+ &dur,
+ serializer,
+ )
+ }
+ }
+ )*
+ };
+ (
+ $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt
+ ) => {
+ $( use_duration_signed_ser!($main_trait $internal_trait => $rest); )+
+ };
+}
+
+fn datetime_to_duration<TZ>(source: &DateTime<TZ>) -> DurationSigned
+where
+ TZ: TimeZone,
+{
+ duration_into_duration_signed(&source.clone().signed_duration_since(unix_epoch_utc()))
+}
+
+fn naive_datetime_to_duration(source: &NaiveDateTime) -> DurationSigned {
+ duration_into_duration_signed(&source.signed_duration_since(unix_epoch_naive()))
+}
+
+use_duration_signed_ser!(
+ DurationSeconds DurationSeconds,
+ DurationMilliSeconds DurationMilliSeconds,
+ DurationMicroSeconds DurationMicroSeconds,
+ DurationNanoSeconds DurationNanoSeconds,
+ => {
+ Duration; duration_into_duration_signed =>
+ {i64, STRICTNESS => STRICTNESS: Strictness}
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+use_duration_signed_ser!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ DateTime<TZ>; datetime_to_duration =>
+ {i64, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
+ {f64, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
+ {String, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
+ }
+);
+use_duration_signed_ser!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ NaiveDateTime; naive_datetime_to_duration =>
+ {i64, STRICTNESS => STRICTNESS: Strictness}
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+
+// Duration/Timestamp WITH FRACTIONS
+use_duration_signed_ser!(
+ DurationSecondsWithFrac DurationSecondsWithFrac,
+ DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ Duration; duration_into_duration_signed =>
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+use_duration_signed_ser!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ DateTime<TZ>; datetime_to_duration =>
+ {f64, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
+ {String, STRICTNESS => TZ: TimeZone, STRICTNESS: Strictness}
+ }
+);
+use_duration_signed_ser!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ NaiveDateTime; naive_datetime_to_duration =>
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+
+macro_rules! use_duration_signed_de {
+ (
+ $main_trait:ident $internal_trait:ident =>
+ {
+ $ty:ty; $converter:ident =>
+ $({
+ $format:ty, $strictness:ty =>
+ $($tbound:ident: $bound:ident)*
+ })*
+ }
+ ) =>{
+ $(
+ impl<'de, $($tbound,)*> DeserializeAs<'de, $ty> for $main_trait<$format, $strictness>
+ where
+ $($tbound: $bound,)*
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<$ty, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let dur: DurationSigned = $internal_trait::<$format, $strictness>::deserialize_as(deserializer)?;
+ $converter::<D>(dur)
+ }
+ }
+ )*
+ };
+ (
+ $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt
+ ) => {
+ $( use_duration_signed_de!($main_trait $internal_trait => $rest); )+
+ };
+}
+
+fn duration_to_datetime_utc<'de, D>(dur: DurationSigned) -> Result<DateTime<Utc>, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ Ok(unix_epoch_utc() + duration_from_duration_signed::<D>(dur)?)
+}
+
+fn duration_to_datetime_local<'de, D>(dur: DurationSigned) -> Result<DateTime<Local>, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ Ok(unix_epoch_local() + duration_from_duration_signed::<D>(dur)?)
+}
+
+fn duration_to_naive_datetime<'de, D>(dur: DurationSigned) -> Result<NaiveDateTime, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ Ok(unix_epoch_naive() + duration_from_duration_signed::<D>(dur)?)
+}
+
+// No subsecond precision
+use_duration_signed_de!(
+ DurationSeconds DurationSeconds,
+ DurationMilliSeconds DurationMilliSeconds,
+ DurationMicroSeconds DurationMicroSeconds,
+ DurationNanoSeconds DurationNanoSeconds,
+ => {
+ Duration; duration_from_duration_signed =>
+ {i64, Strict =>}
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_duration_signed_de!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ DateTime<Utc>; duration_to_datetime_utc =>
+ {i64, Strict =>}
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_duration_signed_de!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ DateTime<Local>; duration_to_datetime_local =>
+ {i64, Strict =>}
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_duration_signed_de!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ NaiveDateTime; duration_to_naive_datetime =>
+ {i64, Strict =>}
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+
+// Duration/Timestamp WITH FRACTIONS
+use_duration_signed_de!(
+ DurationSecondsWithFrac DurationSecondsWithFrac,
+ DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ Duration; duration_from_duration_signed =>
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_duration_signed_de!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ DateTime<Utc>; duration_to_datetime_utc =>
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_duration_signed_de!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ DateTime<Local>; duration_to_datetime_local =>
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_duration_signed_de!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ NaiveDateTime; duration_to_naive_datetime =>
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
diff --git a/third_party/rust/serde_with/src/content/mod.rs b/third_party/rust/serde_with/src/content/mod.rs
new file mode 100644
index 0000000000..711af475c8
--- /dev/null
+++ b/third_party/rust/serde_with/src/content/mod.rs
@@ -0,0 +1,5 @@
+//! Import of the unstable private `Content` type from `serde`.
+//!
+//! <https://github.com/serde-rs/serde/blob/55a7cedd737278a9d75a2efd038c6f38b8c38bd6/serde/src/private/ser.rs#L338-L997>
+
+pub(crate) mod ser;
diff --git a/third_party/rust/serde_with/src/content/ser.rs b/third_party/rust/serde_with/src/content/ser.rs
new file mode 100644
index 0000000000..be02595af9
--- /dev/null
+++ b/third_party/rust/serde_with/src/content/ser.rs
@@ -0,0 +1,623 @@
+//! Buffer for serializing data.
+//!
+//! This is a copy and improvement of the `serde` private type:
+//! <https://github.com/serde-rs/serde/blob/55a7cedd737278a9d75a2efd038c6f38b8c38bd6/serde/src/private/ser.rs#L338-L997>
+//! The code is very stable in the `serde` crate, so no maintainability problem is expected.
+//!
+//! Since the type is private we copy the type here.
+//! `serde` is licensed as MIT+Apache2, the same as this crate.
+//!
+//! This version carries improvements compared to `serde`'s version.
+//! The types support 128-bit integers, which is supported for all targets in Rust 1.40+.
+//! The [`ContentSerializer`] can also be configured to human readable or compact representation.
+
+use alloc::{borrow::ToOwned, boxed::Box, string::String, vec::Vec};
+use core::marker::PhantomData;
+use serde::ser::{self, Serialize, Serializer};
+
+#[derive(Debug)]
+pub(crate) enum Content {
+ Bool(bool),
+
+ U8(u8),
+ U16(u16),
+ U32(u32),
+ U64(u64),
+ U128(u128),
+
+ I8(i8),
+ I16(i16),
+ I32(i32),
+ I64(i64),
+ I128(i128),
+
+ F32(f32),
+ F64(f64),
+
+ Char(char),
+ String(String),
+ Bytes(Vec<u8>),
+
+ None,
+ Some(Box<Content>),
+
+ Unit,
+ UnitStruct(&'static str),
+ UnitVariant(&'static str, u32, &'static str),
+ NewtypeStruct(&'static str, Box<Content>),
+ NewtypeVariant(&'static str, u32, &'static str, Box<Content>),
+
+ Seq(Vec<Content>),
+ Tuple(Vec<Content>),
+ TupleStruct(&'static str, Vec<Content>),
+ TupleVariant(&'static str, u32, &'static str, Vec<Content>),
+ Map(Vec<(Content, Content)>),
+ Struct(&'static str, Vec<(&'static str, Content)>),
+ StructVariant(
+ &'static str,
+ u32,
+ &'static str,
+ Vec<(&'static str, Content)>,
+ ),
+}
+
+impl Serialize for Content {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match *self {
+ Content::Bool(b) => serializer.serialize_bool(b),
+ Content::U8(u) => serializer.serialize_u8(u),
+ Content::U16(u) => serializer.serialize_u16(u),
+ Content::U32(u) => serializer.serialize_u32(u),
+ Content::U64(u) => serializer.serialize_u64(u),
+ Content::U128(u) => serializer.serialize_u128(u),
+ Content::I8(i) => serializer.serialize_i8(i),
+ Content::I16(i) => serializer.serialize_i16(i),
+ Content::I32(i) => serializer.serialize_i32(i),
+ Content::I64(i) => serializer.serialize_i64(i),
+ Content::I128(i) => serializer.serialize_i128(i),
+ Content::F32(f) => serializer.serialize_f32(f),
+ Content::F64(f) => serializer.serialize_f64(f),
+ Content::Char(c) => serializer.serialize_char(c),
+ Content::String(ref s) => serializer.serialize_str(s),
+ Content::Bytes(ref b) => serializer.serialize_bytes(b),
+ Content::None => serializer.serialize_none(),
+ Content::Some(ref c) => serializer.serialize_some(&**c),
+ Content::Unit => serializer.serialize_unit(),
+ Content::UnitStruct(n) => serializer.serialize_unit_struct(n),
+ Content::UnitVariant(n, i, v) => serializer.serialize_unit_variant(n, i, v),
+ Content::NewtypeStruct(n, ref c) => serializer.serialize_newtype_struct(n, &**c),
+ Content::NewtypeVariant(n, i, v, ref c) => {
+ serializer.serialize_newtype_variant(n, i, v, &**c)
+ }
+ Content::Seq(ref elements) => elements.serialize(serializer),
+ Content::Tuple(ref elements) => {
+ use serde::ser::SerializeTuple;
+ let mut tuple = serializer.serialize_tuple(elements.len())?;
+ for e in elements {
+ tuple.serialize_element(e)?;
+ }
+ tuple.end()
+ }
+ Content::TupleStruct(n, ref fields) => {
+ use serde::ser::SerializeTupleStruct;
+ let mut ts = serializer.serialize_tuple_struct(n, fields.len())?;
+ for f in fields {
+ ts.serialize_field(f)?;
+ }
+ ts.end()
+ }
+ Content::TupleVariant(n, i, v, ref fields) => {
+ use serde::ser::SerializeTupleVariant;
+ let mut tv = serializer.serialize_tuple_variant(n, i, v, fields.len())?;
+ for f in fields {
+ tv.serialize_field(f)?;
+ }
+ tv.end()
+ }
+ Content::Map(ref entries) => {
+ use serde::ser::SerializeMap;
+ let mut map = serializer.serialize_map(Some(entries.len()))?;
+ for &(ref k, ref v) in entries {
+ map.serialize_entry(k, v)?;
+ }
+ map.end()
+ }
+ Content::Struct(n, ref fields) => {
+ use serde::ser::SerializeStruct;
+ let mut s = serializer.serialize_struct(n, fields.len())?;
+ for &(k, ref v) in fields {
+ s.serialize_field(k, v)?;
+ }
+ s.end()
+ }
+ Content::StructVariant(n, i, v, ref fields) => {
+ use serde::ser::SerializeStructVariant;
+ let mut sv = serializer.serialize_struct_variant(n, i, v, fields.len())?;
+ for &(k, ref v) in fields {
+ sv.serialize_field(k, v)?;
+ }
+ sv.end()
+ }
+ }
+ }
+}
+
+pub(crate) struct ContentSerializer<E> {
+ is_human_readable: bool,
+ error: PhantomData<E>,
+}
+
+impl<E> ContentSerializer<E> {
+ pub(crate) fn new(is_human_readable: bool) -> Self {
+ ContentSerializer {
+ is_human_readable,
+ error: PhantomData,
+ }
+ }
+}
+
+impl<E> Default for ContentSerializer<E> {
+ fn default() -> Self {
+ Self::new(true)
+ }
+}
+
+impl<E> Serializer for ContentSerializer<E>
+where
+ E: ser::Error,
+{
+ type Ok = Content;
+ type Error = E;
+
+ type SerializeSeq = SerializeSeq<E>;
+ type SerializeTuple = SerializeTuple<E>;
+ type SerializeTupleStruct = SerializeTupleStruct<E>;
+ type SerializeTupleVariant = SerializeTupleVariant<E>;
+ type SerializeMap = SerializeMap<E>;
+ type SerializeStruct = SerializeStruct<E>;
+ type SerializeStructVariant = SerializeStructVariant<E>;
+
+ fn is_human_readable(&self) -> bool {
+ self.is_human_readable
+ }
+
+ fn serialize_bool(self, v: bool) -> Result<Content, E> {
+ Ok(Content::Bool(v))
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<Content, E> {
+ Ok(Content::I8(v))
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<Content, E> {
+ Ok(Content::I16(v))
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<Content, E> {
+ Ok(Content::I32(v))
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<Content, E> {
+ Ok(Content::I64(v))
+ }
+
+ fn serialize_i128(self, v: i128) -> Result<Content, E> {
+ Ok(Content::I128(v))
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<Content, E> {
+ Ok(Content::U8(v))
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<Content, E> {
+ Ok(Content::U16(v))
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<Content, E> {
+ Ok(Content::U32(v))
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<Content, E> {
+ Ok(Content::U64(v))
+ }
+
+ fn serialize_u128(self, v: u128) -> Result<Content, E> {
+ Ok(Content::U128(v))
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<Content, E> {
+ Ok(Content::F32(v))
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<Content, E> {
+ Ok(Content::F64(v))
+ }
+
+ fn serialize_char(self, v: char) -> Result<Content, E> {
+ Ok(Content::Char(v))
+ }
+
+ fn serialize_str(self, value: &str) -> Result<Content, E> {
+ Ok(Content::String(value.to_owned()))
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<Content, E> {
+ Ok(Content::Bytes(value.to_owned()))
+ }
+
+ fn serialize_none(self) -> Result<Content, E> {
+ Ok(Content::None)
+ }
+
+ fn serialize_some<T: ?Sized>(self, value: &T) -> Result<Content, E>
+ where
+ T: Serialize,
+ {
+ Ok(Content::Some(Box::new(value.serialize(self)?)))
+ }
+
+ fn serialize_unit(self) -> Result<Content, E> {
+ Ok(Content::Unit)
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<Content, E> {
+ Ok(Content::UnitStruct(name))
+ }
+
+ fn serialize_unit_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Content, E> {
+ Ok(Content::UnitVariant(name, variant_index, variant))
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ name: &'static str,
+ value: &T,
+ ) -> Result<Content, E>
+ where
+ T: Serialize,
+ {
+ Ok(Content::NewtypeStruct(
+ name,
+ Box::new(value.serialize(self)?),
+ ))
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Content, E>
+ where
+ T: Serialize,
+ {
+ Ok(Content::NewtypeVariant(
+ name,
+ variant_index,
+ variant,
+ Box::new(value.serialize(self)?),
+ ))
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, E> {
+ Ok(SerializeSeq {
+ is_human_readable: self.is_human_readable,
+ elements: Vec::with_capacity(len.unwrap_or(0)),
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, E> {
+ Ok(SerializeTuple {
+ is_human_readable: self.is_human_readable,
+ elements: Vec::with_capacity(len),
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct, E> {
+ Ok(SerializeTupleStruct {
+ is_human_readable: self.is_human_readable,
+ name,
+ fields: Vec::with_capacity(len),
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant, E> {
+ Ok(SerializeTupleVariant {
+ is_human_readable: self.is_human_readable,
+ name,
+ variant_index,
+ variant,
+ fields: Vec::with_capacity(len),
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, E> {
+ Ok(SerializeMap {
+ is_human_readable: self.is_human_readable,
+ entries: Vec::with_capacity(len.unwrap_or(0)),
+ key: None,
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct, E> {
+ Ok(SerializeStruct {
+ is_human_readable: self.is_human_readable,
+ name,
+ fields: Vec::with_capacity(len),
+ error: PhantomData,
+ })
+ }
+
+ fn serialize_struct_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant, E> {
+ Ok(SerializeStructVariant {
+ is_human_readable: self.is_human_readable,
+ name,
+ variant_index,
+ variant,
+ fields: Vec::with_capacity(len),
+ error: PhantomData,
+ })
+ }
+}
+
+pub(crate) struct SerializeSeq<E> {
+ is_human_readable: bool,
+ elements: Vec<Content>,
+ error: PhantomData<E>,
+}
+
+impl<E> ser::SerializeSeq for SerializeSeq<E>
+where
+ E: ser::Error,
+{
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = value.serialize(ContentSerializer::<E>::new(self.is_human_readable))?;
+ self.elements.push(value);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::Seq(self.elements))
+ }
+}
+
+pub(crate) struct SerializeTuple<E> {
+ is_human_readable: bool,
+ elements: Vec<Content>,
+ error: PhantomData<E>,
+}
+
+impl<E> ser::SerializeTuple for SerializeTuple<E>
+where
+ E: ser::Error,
+{
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = value.serialize(ContentSerializer::<E>::new(self.is_human_readable))?;
+ self.elements.push(value);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::Tuple(self.elements))
+ }
+}
+
+pub(crate) struct SerializeTupleStruct<E> {
+ is_human_readable: bool,
+ name: &'static str,
+ fields: Vec<Content>,
+ error: PhantomData<E>,
+}
+
+impl<E> ser::SerializeTupleStruct for SerializeTupleStruct<E>
+where
+ E: ser::Error,
+{
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = value.serialize(ContentSerializer::<E>::new(self.is_human_readable))?;
+ self.fields.push(value);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::TupleStruct(self.name, self.fields))
+ }
+}
+
+pub(crate) struct SerializeTupleVariant<E> {
+ is_human_readable: bool,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ fields: Vec<Content>,
+ error: PhantomData<E>,
+}
+
+impl<E> ser::SerializeTupleVariant for SerializeTupleVariant<E>
+where
+ E: ser::Error,
+{
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = value.serialize(ContentSerializer::<E>::new(self.is_human_readable))?;
+ self.fields.push(value);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::TupleVariant(
+ self.name,
+ self.variant_index,
+ self.variant,
+ self.fields,
+ ))
+ }
+}
+
+pub(crate) struct SerializeMap<E> {
+ is_human_readable: bool,
+ entries: Vec<(Content, Content)>,
+ key: Option<Content>,
+ error: PhantomData<E>,
+}
+
+impl<E> ser::SerializeMap for SerializeMap<E>
+where
+ E: ser::Error,
+{
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let key = key.serialize(ContentSerializer::<E>::new(self.is_human_readable))?;
+ self.key = Some(key);
+ Ok(())
+ }
+
+ fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let key = self
+ .key
+ .take()
+ .expect("serialize_value called before serialize_key");
+ let value = value.serialize(ContentSerializer::<E>::new(self.is_human_readable))?;
+ self.entries.push((key, value));
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::Map(self.entries))
+ }
+
+ fn serialize_entry<K: ?Sized, V: ?Sized>(&mut self, key: &K, value: &V) -> Result<(), E>
+ where
+ K: Serialize,
+ V: Serialize,
+ {
+ let key = key.serialize(ContentSerializer::<E>::new(self.is_human_readable))?;
+ let value = value.serialize(ContentSerializer::<E>::new(self.is_human_readable))?;
+ self.entries.push((key, value));
+ Ok(())
+ }
+}
+
+pub(crate) struct SerializeStruct<E> {
+ is_human_readable: bool,
+ name: &'static str,
+ fields: Vec<(&'static str, Content)>,
+ error: PhantomData<E>,
+}
+
+impl<E> ser::SerializeStruct for SerializeStruct<E>
+where
+ E: ser::Error,
+{
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = value.serialize(ContentSerializer::<E>::new(self.is_human_readable))?;
+ self.fields.push((key, value));
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::Struct(self.name, self.fields))
+ }
+}
+
+pub(crate) struct SerializeStructVariant<E> {
+ is_human_readable: bool,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ fields: Vec<(&'static str, Content)>,
+ error: PhantomData<E>,
+}
+
+impl<E> ser::SerializeStructVariant for SerializeStructVariant<E>
+where
+ E: ser::Error,
+{
+ type Ok = Content;
+ type Error = E;
+
+ fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), E>
+ where
+ T: Serialize,
+ {
+ let value = value.serialize(ContentSerializer::<E>::new(self.is_human_readable))?;
+ self.fields.push((key, value));
+ Ok(())
+ }
+
+ fn end(self) -> Result<Content, E> {
+ Ok(Content::StructVariant(
+ self.name,
+ self.variant_index,
+ self.variant,
+ self.fields,
+ ))
+ }
+}
diff --git a/third_party/rust/serde_with/src/de/const_arrays.rs b/third_party/rust/serde_with/src/de/const_arrays.rs
new file mode 100644
index 0000000000..63f6d662d6
--- /dev/null
+++ b/third_party/rust/serde_with/src/de/const_arrays.rs
@@ -0,0 +1,338 @@
+use super::*;
+use crate::utils::{MapIter, SeqIter};
+use alloc::{borrow::Cow, boxed::Box, collections::BTreeMap, string::String, vec::Vec};
+use core::{convert::TryInto, fmt, mem::MaybeUninit};
+use serde::de::*;
+use std::collections::HashMap;
+
+// TODO this should probably be moved into the utils module when const generics are available for MSRV
+
+/// # Safety
+/// The code follow exactly the pattern of initializing an array element-by-element from the standard library.
+/// <https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#initializing-an-array-element-by-element>
+fn array_from_iterator<I, T, E, const N: usize>(
+ mut iter: I,
+ expected: &dyn Expected,
+) -> Result<[T; N], E>
+where
+ I: Iterator<Item = Result<T, E>>,
+ E: Error,
+{
+ fn drop_array_elems<T, const N: usize>(num: usize, mut arr: [MaybeUninit<T>; N]) {
+ arr[..num].iter_mut().for_each(|elem| {
+ // TODO This would be better with assume_init_drop nightly function
+ // https://github.com/rust-lang/rust/issues/63567
+ unsafe { core::ptr::drop_in_place(elem.as_mut_ptr()) };
+ });
+ }
+
+ // Create an uninitialized array of `MaybeUninit`. The `assume_init` is
+ // safe because the type we are claiming to have initialized here is a
+ // bunch of `MaybeUninit`s, which do not require initialization.
+ //
+ // TODO could be simplified with nightly maybe_uninit_uninit_array feature
+ // https://doc.rust-lang.org/nightly/std/mem/union.MaybeUninit.html#method.uninit_array
+ let mut arr: [MaybeUninit<T>; N] = unsafe { MaybeUninit::uninit().assume_init() };
+
+ // Dropping a `MaybeUninit` does nothing. Thus using raw pointer
+ // assignment instead of `ptr::write` does not cause the old
+ // uninitialized value to be dropped. Also if there is a panic during
+ // this loop, we have a memory leak, but there is no memory safety
+ // issue.
+ for (idx, elem) in arr[..].iter_mut().enumerate() {
+ *elem = match iter.next() {
+ Some(Ok(value)) => MaybeUninit::new(value),
+ Some(Err(err)) => {
+ drop_array_elems(idx, arr);
+ return Err(err);
+ }
+ None => {
+ drop_array_elems(idx, arr);
+ return Err(Error::invalid_length(idx, expected));
+ }
+ };
+ }
+
+ // Everything is initialized. Transmute the array to the
+ // initialized type.
+ // A normal transmute is not possible because of:
+ // https://github.com/rust-lang/rust/issues/61956
+ Ok(unsafe { core::mem::transmute_copy::<_, [T; N]>(&arr) })
+}
+
+impl<'de, T, As, const N: usize> DeserializeAs<'de, [T; N]> for [As; N]
+where
+ As: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<[T; N], D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct ArrayVisitor<T, const M: usize>(PhantomData<T>);
+
+ impl<'de, T, As, const M: usize> Visitor<'de> for ArrayVisitor<DeserializeAsWrap<T, As>, M>
+ where
+ As: DeserializeAs<'de, T>,
+ {
+ type Value = [T; M];
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_fmt(format_args!("an array of size {}", M))
+ }
+
+ fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ array_from_iterator(
+ SeqIter::new(seq).map(|res: Result<DeserializeAsWrap<T, As>, A::Error>| {
+ res.map(|t| t.into_inner())
+ }),
+ &self,
+ )
+ }
+ }
+
+ deserializer.deserialize_tuple(N, ArrayVisitor::<DeserializeAsWrap<T, As>, N>(PhantomData))
+ }
+}
+
+macro_rules! tuple_seq_as_map_impl_intern {
+ ($tyorig:ty, $ty:ident <KAs, VAs>) => {
+ #[allow(clippy::implicit_hasher)]
+ impl<'de, K, KAs, V, VAs, const N: usize> DeserializeAs<'de, $tyorig> for $ty<KAs, VAs>
+ where
+ KAs: DeserializeAs<'de, K>,
+ VAs: DeserializeAs<'de, V>,
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<$tyorig, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct MapVisitor<K, KAs, V, VAs, const M: usize> {
+ marker: PhantomData<(K, KAs, V, VAs)>,
+ }
+
+ impl<'de, K, KAs, V, VAs, const M: usize> Visitor<'de> for MapVisitor<K, KAs, V, VAs, M>
+ where
+ KAs: DeserializeAs<'de, K>,
+ VAs: DeserializeAs<'de, V>,
+ {
+ type Value = [(K, V); M];
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_fmt(format_args!("a map of length {}", M))
+ }
+
+ fn visit_map<A>(self, access: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ array_from_iterator(MapIter::new(access).map(
+ |res: Result<(DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>), A::Error>| {
+ res.map(|(k, v)| (k.into_inner(), v.into_inner()))
+ }
+ ), &self)
+ }
+ }
+
+ let visitor = MapVisitor::<K, KAs, V, VAs, N> {
+ marker: PhantomData,
+ };
+ deserializer.deserialize_map(visitor)
+ }
+ }
+ }
+}
+tuple_seq_as_map_impl_intern!([(K, V); N], BTreeMap<KAs, VAs>);
+tuple_seq_as_map_impl_intern!([(K, V); N], HashMap<KAs, VAs>);
+
+impl<'de, const N: usize> DeserializeAs<'de, [u8; N]> for Bytes {
+ fn deserialize_as<D>(deserializer: D) -> Result<[u8; N], D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct ArrayVisitor<const M: usize>;
+
+ impl<'de, const M: usize> Visitor<'de> for ArrayVisitor<M> {
+ type Value = [u8; M];
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_fmt(format_args!("an byte array of size {}", M))
+ }
+
+ fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ array_from_iterator(SeqIter::new(seq), &self)
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ v.try_into()
+ .map_err(|_| Error::invalid_length(v.len(), &self))
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ v.as_bytes()
+ .try_into()
+ .map_err(|_| Error::invalid_length(v.len(), &self))
+ }
+ }
+
+ deserializer.deserialize_bytes(ArrayVisitor::<N>)
+ }
+}
+
+impl<'de, const N: usize> DeserializeAs<'de, &'de [u8; N]> for Bytes {
+ fn deserialize_as<D>(deserializer: D) -> Result<&'de [u8; N], D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct ArrayVisitor<const M: usize>;
+
+ impl<'de, const M: usize> Visitor<'de> for ArrayVisitor<M> {
+ type Value = &'de [u8; M];
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_fmt(format_args!("a borrowed byte array of size {}", M))
+ }
+
+ fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ v.try_into()
+ .map_err(|_| Error::invalid_length(v.len(), &self))
+ }
+
+ fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ v.as_bytes()
+ .try_into()
+ .map_err(|_| Error::invalid_length(v.len(), &self))
+ }
+ }
+
+ deserializer.deserialize_bytes(ArrayVisitor::<N>)
+ }
+}
+
+impl<'de, const N: usize> DeserializeAs<'de, Cow<'de, [u8; N]>> for Bytes {
+ fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, [u8; N]>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct CowVisitor<const M: usize>;
+
+ impl<'de, const M: usize> Visitor<'de> for CowVisitor<M> {
+ type Value = Cow<'de, [u8; M]>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a byte array")
+ }
+
+ fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Borrowed(
+ v.try_into()
+ .map_err(|_| Error::invalid_length(v.len(), &self))?,
+ ))
+ }
+
+ fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Borrowed(
+ v.as_bytes()
+ .try_into()
+ .map_err(|_| Error::invalid_length(v.len(), &self))?,
+ ))
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(
+ v.to_vec()
+ .try_into()
+ .map_err(|_| Error::invalid_length(v.len(), &self))?,
+ ))
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(
+ v.as_bytes()
+ .to_vec()
+ .try_into()
+ .map_err(|_| Error::invalid_length(v.len(), &self))?,
+ ))
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let len = v.len();
+ Ok(Cow::Owned(
+ v.try_into()
+ .map_err(|_| Error::invalid_length(len, &self))?,
+ ))
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ let len = v.len();
+ Ok(Cow::Owned(
+ v.into_bytes()
+ .try_into()
+ .map_err(|_| Error::invalid_length(len, &self))?,
+ ))
+ }
+
+ fn visit_seq<V>(self, seq: V) -> Result<Self::Value, V::Error>
+ where
+ V: SeqAccess<'de>,
+ {
+ Ok(Cow::Owned(array_from_iterator(SeqIter::new(seq), &self)?))
+ }
+ }
+
+ deserializer.deserialize_bytes(CowVisitor)
+ }
+}
+
+impl<'de, const N: usize> DeserializeAs<'de, Box<[u8; N]>> for Bytes {
+ fn deserialize_as<D>(deserializer: D) -> Result<Box<[u8; N]>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Bytes::deserialize_as(deserializer).map(Box::new)
+ }
+}
+
+impl<'de, const N: usize> DeserializeAs<'de, Cow<'de, [u8; N]>> for BorrowCow {
+ fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, [u8; N]>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Bytes::deserialize_as(deserializer)
+ }
+}
diff --git a/third_party/rust/serde_with/src/de/impls.rs b/third_party/rust/serde_with/src/de/impls.rs
new file mode 100644
index 0000000000..fc960c3d07
--- /dev/null
+++ b/third_party/rust/serde_with/src/de/impls.rs
@@ -0,0 +1,1508 @@
+use super::*;
+use crate::{
+ formats::{Flexible, Format, Strict},
+ rust::StringWithSeparator,
+ utils,
+ utils::duration::DurationSigned,
+};
+use alloc::{
+ borrow::{Cow, ToOwned},
+ boxed::Box,
+ collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque},
+ rc::{Rc, Weak as RcWeak},
+ string::String,
+ sync::{Arc, Weak as ArcWeak},
+ vec::Vec,
+};
+use core::{
+ cell::{Cell, RefCell},
+ convert::TryInto,
+ fmt::{self, Display},
+ hash::{BuildHasher, Hash},
+ iter::FromIterator,
+ str::FromStr,
+ time::Duration,
+};
+#[cfg(feature = "indexmap")]
+use indexmap_crate::{IndexMap, IndexSet};
+use serde::de::*;
+use std::{
+ collections::{HashMap, HashSet},
+ sync::{Mutex, RwLock},
+ time::SystemTime,
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// region: Simple Wrapper types (e.g., Box, Option)
+
+impl<'de, T, U> DeserializeAs<'de, Box<T>> for Box<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Box<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(Box::new(
+ DeserializeAsWrap::<T, U>::deserialize(deserializer)?.into_inner(),
+ ))
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, Option<T>> for Option<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Option<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct OptionVisitor<T, U>(PhantomData<(T, U)>);
+
+ impl<'de, T, U> Visitor<'de> for OptionVisitor<T, U>
+ where
+ U: DeserializeAs<'de, T>,
+ {
+ type Value = Option<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("option")
+ }
+
+ #[inline]
+ 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_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ U::deserialize_as(deserializer).map(Some)
+ }
+ }
+
+ deserializer.deserialize_option(OptionVisitor::<T, U>(PhantomData))
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, Rc<T>> for Rc<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Rc<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(Rc::new(
+ DeserializeAsWrap::<T, U>::deserialize(deserializer)?.into_inner(),
+ ))
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, RcWeak<T>> for RcWeak<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<RcWeak<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ DeserializeAsWrap::<Option<Rc<T>>, Option<Rc<U>>>::deserialize(deserializer)?;
+ Ok(RcWeak::new())
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, Arc<T>> for Arc<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Arc<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(Arc::new(
+ DeserializeAsWrap::<T, U>::deserialize(deserializer)?.into_inner(),
+ ))
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, ArcWeak<T>> for ArcWeak<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<ArcWeak<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ DeserializeAsWrap::<Option<Arc<T>>, Option<Arc<U>>>::deserialize(deserializer)?;
+ Ok(ArcWeak::new())
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, Cell<T>> for Cell<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Cell<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(Cell::new(
+ DeserializeAsWrap::<T, U>::deserialize(deserializer)?.into_inner(),
+ ))
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, RefCell<T>> for RefCell<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<RefCell<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(RefCell::new(
+ DeserializeAsWrap::<T, U>::deserialize(deserializer)?.into_inner(),
+ ))
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, Mutex<T>> for Mutex<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Mutex<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(Mutex::new(
+ DeserializeAsWrap::<T, U>::deserialize(deserializer)?.into_inner(),
+ ))
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, RwLock<T>> for RwLock<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<RwLock<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(RwLock::new(
+ DeserializeAsWrap::<T, U>::deserialize(deserializer)?.into_inner(),
+ ))
+ }
+}
+
+impl<'de, T, TAs, E, EAs> DeserializeAs<'de, Result<T, E>> for Result<TAs, EAs>
+where
+ TAs: DeserializeAs<'de, T>,
+ EAs: DeserializeAs<'de, E>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Result<T, E>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(
+ match Result::<DeserializeAsWrap<T, TAs>, DeserializeAsWrap<E, EAs>>::deserialize(
+ deserializer,
+ )? {
+ Ok(value) => Ok(value.into_inner()),
+ Err(err) => Err(err.into_inner()),
+ },
+ )
+ }
+}
+
+// endregion
+///////////////////////////////////////////////////////////////////////////////
+// region: Collection Types (e.g., Maps, Sets, Vec)
+
+macro_rules! seq_impl {
+ (
+ $ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)* )* >,
+ $access:ident,
+ $with_capacity:expr,
+ $append:ident
+ ) => {
+ // Fix for clippy regression in macros on stable
+ // The bug no longer exists on nightly
+ // https://github.com/rust-lang/rust-clippy/issues/7768
+ #[allow(clippy::semicolon_if_nothing_returned)]
+ impl<'de, T, U $(, $typaram)*> DeserializeAs<'de, $ty<T $(, $typaram)*>> for $ty<U $(, $typaram)*>
+ where
+ U: DeserializeAs<'de, T>,
+ $(T: $tbound1 $(+ $tbound2)*,)*
+ $($typaram: $bound1 $(+ $bound2)*),*
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<$ty<T $(, $typaram)*>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct SeqVisitor<T, U $(, $typaram)*> {
+ marker: PhantomData<(T, U $(, $typaram)*)>,
+ }
+
+ impl<'de, T, U $(, $typaram)*> Visitor<'de> for SeqVisitor<T, U $(, $typaram)*>
+ where
+ U: DeserializeAs<'de, T>,
+ $(T: $tbound1 $(+ $tbound2)*,)*
+ $($typaram: $bound1 $(+ $bound2)*),*
+ {
+ type Value = $ty<T $(, $typaram)*>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ fn visit_seq<A>(self, mut $access: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut values = $with_capacity;
+
+ while let Some(value) = $access
+ .next_element()?
+ .map(|v: DeserializeAsWrap<T, U>| v.into_inner())
+ {
+ values.$append(value);
+ }
+
+ Ok(values.into())
+ }
+ }
+
+ let visitor = SeqVisitor::<T, U $(, $typaram)*> {
+ marker: PhantomData,
+ };
+ deserializer.deserialize_seq(visitor)
+ }
+ }
+ };
+}
+
+type BoxedSlice<T> = Box<[T]>;
+seq_impl!(
+ BinaryHeap<T: Ord>,
+ seq,
+ BinaryHeap::with_capacity(utils::size_hint_cautious(seq.size_hint())),
+ push
+);
+seq_impl!(
+ BoxedSlice<T>,
+ seq,
+ Vec::with_capacity(utils::size_hint_cautious(seq.size_hint())),
+ push
+);
+seq_impl!(BTreeSet<T: Ord>, seq, BTreeSet::new(), insert);
+seq_impl!(
+ HashSet<T: Eq + Hash, S: BuildHasher + Default>,
+ seq,
+ HashSet::with_capacity_and_hasher(utils::size_hint_cautious(seq.size_hint()), S::default()),
+ insert
+);
+seq_impl!(LinkedList<T>, seq, LinkedList::new(), push_back);
+seq_impl!(
+ Vec<T>,
+ seq,
+ Vec::with_capacity(utils::size_hint_cautious(seq.size_hint())),
+ push
+);
+seq_impl!(
+ VecDeque<T>,
+ seq,
+ VecDeque::with_capacity(utils::size_hint_cautious(seq.size_hint())),
+ push_back
+);
+#[cfg(feature = "indexmap")]
+seq_impl!(
+ IndexSet<T: Eq + Hash, S: BuildHasher + Default>,
+ seq,
+ IndexSet::with_capacity_and_hasher(utils::size_hint_cautious(seq.size_hint()), S::default()),
+ insert
+);
+
+macro_rules! map_impl {
+ (
+ $ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
+ // We need an external name, such that we can use it in the `with_capacity` expression
+ $access:ident,
+ $with_capacity:expr
+ ) => {
+ // Fix for clippy regression in macros on stable
+ // The bug no longer exists on nightly
+ // https://github.com/rust-lang/rust-clippy/issues/7768
+ #[allow(clippy::semicolon_if_nothing_returned)]
+ impl<'de, K, V, KU, VU $(, $typaram)*> DeserializeAs<'de, $ty<K, V $(, $typaram)*>> for $ty<KU, VU $(, $typaram)*>
+ where
+ KU: DeserializeAs<'de, K>,
+ VU: DeserializeAs<'de, V>,
+ $(K: $kbound1 $(+ $kbound2)*,)*
+ $($typaram: $bound1 $(+ $bound2)*),*
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<$ty<K, V $(, $typaram)*>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct MapVisitor<K, V, KU, VU $(, $typaram)*> {
+ marker: PhantomData<$ty<K, V $(, $typaram)*>>,
+ marker2: PhantomData<$ty<KU, VU $(, $typaram)*>>,
+ }
+
+ impl<'de, K, V, KU, VU $(, $typaram)*> Visitor<'de> for MapVisitor<K, V, KU, VU $(, $typaram)*>
+ where
+ KU: DeserializeAs<'de, K>,
+ VU: DeserializeAs<'de, V>,
+ $(K: $kbound1 $(+ $kbound2)*,)*
+ $($typaram: $bound1 $(+ $bound2)*),*
+ {
+ type Value = $ty<K, V $(, $typaram)*>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a map")
+ }
+
+ #[inline]
+ fn visit_map<A>(self, mut $access: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let mut values = $with_capacity;
+
+ while let Some((key, value)) = ($access.next_entry())?.map(|(k, v): (DeserializeAsWrap::<K, KU>, DeserializeAsWrap::<V, VU>)| (k.into_inner(), v.into_inner())) {
+ values.insert(key, value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = MapVisitor::<K, V, KU, VU $(, $typaram)*> { marker: PhantomData, marker2: PhantomData };
+ deserializer.deserialize_map(visitor)
+ }
+ }
+ }
+}
+
+map_impl!(
+ BTreeMap<K: Ord, V>,
+ map,
+ BTreeMap::new());
+map_impl!(
+ HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
+ map,
+ HashMap::with_capacity_and_hasher(utils::size_hint_cautious(map.size_hint()), S::default()));
+#[cfg(feature = "indexmap")]
+map_impl!(
+ IndexMap<K: Eq + Hash, V, S: BuildHasher + Default>,
+ map,
+ IndexMap::with_capacity_and_hasher(utils::size_hint_cautious(map.size_hint()), S::default()));
+
+macro_rules! tuple_impl {
+ ($len:literal $($n:tt $t:ident $tas:ident)+) => {
+ impl<'de, $($t, $tas,)+> DeserializeAs<'de, ($($t,)+)> for ($($tas,)+)
+ where
+ $($tas: DeserializeAs<'de, $t>,)+
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<($($t,)+), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct TupleVisitor<$($t,)+>(PhantomData<($($t,)+)>);
+
+ impl<'de, $($t, $tas,)+> Visitor<'de>
+ for TupleVisitor<$(DeserializeAsWrap<$t, $tas>,)+>
+ where
+ $($tas: DeserializeAs<'de, $t>,)+
+ {
+ type Value = ($($t,)+);
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str(concat!("a tuple of size ", $len))
+ }
+
+ #[allow(non_snake_case)]
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ $(
+ let $t: DeserializeAsWrap<$t, $tas> = match seq.next_element()? {
+ Some(value) => value,
+ None => return Err(Error::invalid_length($n, &self)),
+ };
+ )+
+
+ Ok(($($t.into_inner(),)+))
+ }
+ }
+
+ deserializer.deserialize_tuple(
+ $len,
+ TupleVisitor::<$(DeserializeAsWrap<$t, $tas>,)+>(PhantomData),
+ )
+ }
+ }
+ };
+}
+
+tuple_impl!(1 0 T0 As0);
+tuple_impl!(2 0 T0 As0 1 T1 As1);
+tuple_impl!(3 0 T0 As0 1 T1 As1 2 T2 As2);
+tuple_impl!(4 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3);
+tuple_impl!(5 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4);
+tuple_impl!(6 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5);
+tuple_impl!(7 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6);
+tuple_impl!(8 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7);
+tuple_impl!(9 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8);
+tuple_impl!(10 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9);
+tuple_impl!(11 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10);
+tuple_impl!(12 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11);
+tuple_impl!(13 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12);
+tuple_impl!(14 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12 13 T13 As13);
+tuple_impl!(15 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12 13 T13 As13 14 T14 As14);
+tuple_impl!(16 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12 13 T13 As13 14 T14 As14 15 T15 As15);
+
+macro_rules! map_as_tuple_seq {
+ ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V>) => {
+ impl<'de, K, KAs, V, VAs> DeserializeAs<'de, $ty<K, V>> for Vec<(KAs, VAs)>
+ where
+ KAs: DeserializeAs<'de, K>,
+ VAs: DeserializeAs<'de, V>,
+ $(K: $kbound1 $(+ $kbound2)*,)*
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<$ty<K, V>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct SeqVisitor<K, KAs, V, VAs> {
+ marker: PhantomData<(K, KAs, V, VAs)>,
+ }
+
+ impl<'de, K, KAs, V, VAs> Visitor<'de> for SeqVisitor<K, KAs, V, VAs>
+ where
+ KAs: DeserializeAs<'de, K>,
+ VAs: DeserializeAs<'de, V>,
+ $(K: $kbound1 $(+ $kbound2)*,)*
+ {
+ type Value = $ty<K, V>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ #[inline]
+ fn visit_seq<A>(self, access: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let iter = utils::SeqIter::new(access);
+ iter.map(|res| {
+ res.map(
+ |(k, v): (DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>)| {
+ (k.into_inner(), v.into_inner())
+ },
+ )
+ })
+ .collect()
+ }
+ }
+
+ let visitor = SeqVisitor::<K, KAs, V, VAs> {
+ marker: PhantomData,
+ };
+ deserializer.deserialize_seq(visitor)
+ }
+ }
+ };
+}
+map_as_tuple_seq!(BTreeMap<K: Ord, V>);
+map_as_tuple_seq!(HashMap<K: Eq + Hash, V>);
+#[cfg(feature = "indexmap")]
+map_as_tuple_seq!(IndexMap<K: Eq + Hash, V>);
+
+// endregion
+///////////////////////////////////////////////////////////////////////////////
+// region: Conversion types which cause different serialization behavior
+
+impl<'de, T: Deserialize<'de>> DeserializeAs<'de, T> for Same {
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ T::deserialize(deserializer)
+ }
+}
+
+impl<'de, T> DeserializeAs<'de, T> for DisplayFromStr
+where
+ T: FromStr,
+ T::Err: Display,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ crate::rust::display_fromstr::deserialize(deserializer)
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, Vec<T>> for VecSkipError<U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Vec<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ #[derive(serde::Deserialize)]
+ #[serde(
+ untagged,
+ bound(deserialize = "DeserializeAsWrap<T, TAs>: Deserialize<'de>")
+ )]
+ enum GoodOrError<'a, T, TAs>
+ where
+ TAs: DeserializeAs<'a, T>,
+ {
+ Good(DeserializeAsWrap<T, TAs>),
+ // This consumes one "item" when `T` errors while deserializing.
+ // This is necessary to make this work, when instead of having a direct value
+ // like integer or string, the deserializer sees a list or map.
+ Error(IgnoredAny),
+ #[serde(skip)]
+ _JustAMarkerForTheLifetime(PhantomData<&'a u32>),
+ }
+
+ struct SeqVisitor<T, U> {
+ marker: PhantomData<T>,
+ marker2: PhantomData<U>,
+ }
+
+ impl<'de, T, U> Visitor<'de> for SeqVisitor<T, U>
+ where
+ U: DeserializeAs<'de, T>,
+ {
+ type Value = Vec<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut values = Vec::with_capacity(seq.size_hint().unwrap_or_default());
+
+ while let Some(value) = seq.next_element()? {
+ if let GoodOrError::<T, U>::Good(value) = value {
+ values.push(value.into_inner());
+ }
+ }
+ Ok(values)
+ }
+ }
+
+ let visitor = SeqVisitor::<T, U> {
+ marker: PhantomData,
+ marker2: PhantomData,
+ };
+ deserializer.deserialize_seq(visitor)
+ }
+}
+
+impl<'de, Str> DeserializeAs<'de, Option<Str>> for NoneAsEmptyString
+where
+ Str: FromStr,
+ Str::Err: Display,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Option<Str>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ crate::rust::string_empty_as_none::deserialize(deserializer)
+ }
+}
+
+macro_rules! tuple_seq_as_map_impl_intern {
+ ($tyorig:ident < (K $(: $($kbound:ident $(+)?)+)?, V $(: $($vbound:ident $(+)?)+)?)>, $ty:ident <KAs, VAs>) => {
+ #[allow(clippy::implicit_hasher)]
+ impl<'de, K, KAs, V, VAs> DeserializeAs<'de, $tyorig < (K, V) >> for $ty<KAs, VAs>
+ where
+ KAs: DeserializeAs<'de, K>,
+ VAs: DeserializeAs<'de, V>,
+ K: $($($kbound +)*)*,
+ V: $($($vbound +)*)*,
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<$tyorig < (K, V) >, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct MapVisitor<K, KAs, V, VAs> {
+ marker: PhantomData<(K, KAs, V, VAs)>,
+ }
+
+ impl<'de, K, KAs, V, VAs> Visitor<'de> for MapVisitor<K, KAs, V, VAs>
+ where
+ KAs: DeserializeAs<'de, K>,
+ VAs: DeserializeAs<'de, V>,
+ K: $($($kbound +)*)*,
+ V: $($($vbound +)*)*,
+ {
+ type Value = $tyorig < (K, V) >;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a map")
+ }
+
+ #[inline]
+ fn visit_map<A>(self, access: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let iter = utils::MapIter::new(access);
+ iter.map(|res| {
+ res.map(
+ |(k, v): (DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>)| {
+ (k.into_inner(), v.into_inner())
+ },
+ )
+ })
+ .collect()
+ }
+ }
+
+ let visitor = MapVisitor::<K, KAs, V, VAs> {
+ marker: PhantomData,
+ };
+ deserializer.deserialize_map(visitor)
+ }
+ }
+ }
+}
+macro_rules! tuple_seq_as_map_impl {
+ ($($tyorig:ident < (K $(: $($kbound:ident $(+)?)+)?, V $(: $($vbound:ident $(+)?)+)?)> $(,)?)+) => {$(
+ tuple_seq_as_map_impl_intern!($tyorig < (K $(: $($kbound +)+)?, V $(: $($vbound +)+)?) >, BTreeMap<KAs, VAs>);
+ tuple_seq_as_map_impl_intern!($tyorig < (K $(: $($kbound +)+)?, V $(: $($vbound +)+)?) >, HashMap<KAs, VAs>);
+ )+}
+}
+
+tuple_seq_as_map_impl! {
+ BinaryHeap<(K: Ord, V: Ord)>,
+ BTreeSet<(K: Ord, V: Ord)>,
+ LinkedList<(K, V)>,
+ Vec<(K, V)>,
+ VecDeque<(K, V)>,
+}
+tuple_seq_as_map_impl!(HashSet<(K: Eq + Hash, V: Eq + Hash)>);
+#[cfg(feature = "indexmap")]
+tuple_seq_as_map_impl!(IndexSet<(K: Eq + Hash, V: Eq + Hash)>);
+
+macro_rules! tuple_seq_as_map_option_impl {
+ ($($ty:ident $(,)?)+) => {$(
+ #[allow(clippy::implicit_hasher)]
+ impl<'de, K, KAs, V, VAs> DeserializeAs<'de, Option<(K, V)>> for $ty<KAs, VAs>
+ where
+ KAs: DeserializeAs<'de, K>,
+ VAs: DeserializeAs<'de, V>,
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<Option<(K, V)>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct MapVisitor<K, KAs, V, VAs> {
+ marker: PhantomData<(K, KAs, V, VAs)>,
+ }
+
+ impl<'de, K, KAs, V, VAs> Visitor<'de> for MapVisitor<K, KAs, V, VAs>
+ where
+ KAs: DeserializeAs<'de, K>,
+ VAs: DeserializeAs<'de, V>,
+ {
+ type Value = Option<(K, V)>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a map of size 1")
+ }
+
+ #[inline]
+ fn visit_map<A>(self, access: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let iter = utils::MapIter::new(access);
+ iter.map(|res| {
+ res.map(
+ |(k, v): (DeserializeAsWrap<K, KAs>, DeserializeAsWrap<V, VAs>)| {
+ (k.into_inner(), v.into_inner())
+ },
+ )
+ })
+ .next()
+ .transpose()
+ }
+ }
+
+ let visitor = MapVisitor::<K, KAs, V, VAs> {
+ marker: PhantomData,
+ };
+ deserializer.deserialize_map(visitor)
+ }
+ }
+ )+}
+}
+tuple_seq_as_map_option_impl!(BTreeMap);
+tuple_seq_as_map_option_impl!(HashMap);
+
+impl<'de, T, TAs> DeserializeAs<'de, T> for DefaultOnError<TAs>
+where
+ TAs: DeserializeAs<'de, T>,
+ T: Default,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ #[derive(serde::Deserialize)]
+ #[serde(
+ untagged,
+ bound(deserialize = "DeserializeAsWrap<T, TAs>: Deserialize<'de>")
+ )]
+ enum GoodOrError<'a, T, TAs>
+ where
+ TAs: DeserializeAs<'a, T>,
+ {
+ Good(DeserializeAsWrap<T, TAs>),
+ // This consumes one "item" when `T` errors while deserializing.
+ // This is necessary to make this work, when instead of having a direct value
+ // like integer or string, the deserializer sees a list or map.
+ Error(IgnoredAny),
+ #[serde(skip)]
+ _JustAMarkerForTheLifetime(PhantomData<&'a u32>),
+ }
+
+ Ok(match Deserialize::deserialize(deserializer) {
+ Ok(GoodOrError::<T, TAs>::Good(res)) => res.into_inner(),
+ _ => Default::default(),
+ })
+ }
+}
+
+impl<'de> DeserializeAs<'de, Vec<u8>> for BytesOrString {
+ fn deserialize_as<D>(deserializer: D) -> Result<Vec<u8>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ crate::rust::bytes_or_string::deserialize(deserializer)
+ }
+}
+
+impl<'de, SEPARATOR, I, T> DeserializeAs<'de, I> for StringWithSeparator<SEPARATOR, T>
+where
+ SEPARATOR: Separator,
+ I: FromIterator<T>,
+ T: FromStr,
+ T::Err: Display,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<I, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let s = String::deserialize(deserializer)?;
+ if s.is_empty() {
+ Ok(None.into_iter().collect())
+ } else {
+ s.split(SEPARATOR::separator())
+ .map(FromStr::from_str)
+ .collect::<Result<_, _>>()
+ .map_err(Error::custom)
+ }
+ }
+}
+
+macro_rules! use_signed_duration {
+ (
+ $main_trait:ident $internal_trait:ident =>
+ {
+ $ty:ty; $converter:ident =>
+ $({
+ $format:ty, $strictness:ty =>
+ $($tbound:ident: $bound:ident $(,)?)*
+ })*
+ }
+ ) => {
+ $(
+ impl<'de, $($tbound,)*> DeserializeAs<'de, $ty> for $main_trait<$format, $strictness>
+ where
+ $($tbound: $bound,)*
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<$ty, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let dur: DurationSigned = $internal_trait::<$format, $strictness>::deserialize_as(deserializer)?;
+ dur.$converter::<D>()
+ }
+ }
+ )*
+ };
+ (
+ $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt
+ ) => {
+ $( use_signed_duration!($main_trait $internal_trait => $rest); )+
+ };
+}
+
+use_signed_duration!(
+ DurationSeconds DurationSeconds,
+ DurationMilliSeconds DurationMilliSeconds,
+ DurationMicroSeconds DurationMicroSeconds,
+ DurationNanoSeconds DurationNanoSeconds,
+ => {
+ Duration; to_std_duration =>
+ {u64, Strict =>}
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_signed_duration!(
+ DurationSecondsWithFrac DurationSecondsWithFrac,
+ DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ Duration; to_std_duration =>
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+
+use_signed_duration!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ SystemTime; to_system_time =>
+ {i64, Strict =>}
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_signed_duration!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ SystemTime; to_system_time =>
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+
+impl<'de, T, U> DeserializeAs<'de, T> for DefaultOnNull<U>
+where
+ U: DeserializeAs<'de, T>,
+ T: Default,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(Option::<U>::deserialize_as(deserializer)?.unwrap_or_default())
+ }
+}
+
+impl<'de> DeserializeAs<'de, &'de [u8]> for Bytes {
+ fn deserialize_as<D>(deserializer: D) -> Result<&'de [u8], D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ <&'de [u8]>::deserialize(deserializer)
+ }
+}
+
+// serde_bytes implementation for ByteBuf
+// https://github.com/serde-rs/bytes/blob/cbae606b9dc225fc094b031cc84eac9493da2058/src/bytebuf.rs#L196
+//
+// Implements:
+// * visit_seq
+// * visit_bytes
+// * visit_byte_buf
+// * visit_str
+// * visit_string
+impl<'de> DeserializeAs<'de, Vec<u8>> for Bytes {
+ fn deserialize_as<D>(deserializer: D) -> Result<Vec<u8>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct VecVisitor;
+
+ impl<'de> Visitor<'de> for VecVisitor {
+ type Value = Vec<u8>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a byte array")
+ }
+
+ fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ utils::SeqIter::new(seq).collect::<Result<_, _>>()
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v.to_vec())
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v)
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v.as_bytes().to_vec())
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v.into_bytes())
+ }
+ }
+
+ deserializer.deserialize_byte_buf(VecVisitor)
+ }
+}
+
+impl<'de> DeserializeAs<'de, Box<[u8]>> for Bytes {
+ fn deserialize_as<D>(deserializer: D) -> Result<Box<[u8]>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ <Bytes as DeserializeAs<'de, Vec<u8>>>::deserialize_as(deserializer)
+ .map(|vec| vec.into_boxed_slice())
+ }
+}
+
+// serde_bytes implementation for Cow<'a, [u8]>
+// https://github.com/serde-rs/bytes/blob/cbae606b9dc225fc094b031cc84eac9493da2058/src/de.rs#L77
+//
+// Implements:
+// * visit_borrowed_bytes
+// * visit_borrowed_str
+// * visit_bytes
+// * visit_str
+// * visit_byte_buf
+// * visit_string
+// * visit_seq
+impl<'de> DeserializeAs<'de, Cow<'de, [u8]>> for Bytes {
+ fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, [u8]>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct CowVisitor;
+
+ impl<'de> Visitor<'de> for CowVisitor {
+ type Value = Cow<'de, [u8]>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a byte array")
+ }
+
+ fn visit_borrowed_bytes<E>(self, v: &'de [u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Borrowed(v))
+ }
+
+ fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Borrowed(v.as_bytes()))
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.to_vec()))
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.as_bytes().to_vec()))
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v))
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.into_bytes()))
+ }
+
+ fn visit_seq<V>(self, seq: V) -> Result<Self::Value, V::Error>
+ where
+ V: SeqAccess<'de>,
+ {
+ Ok(Cow::Owned(
+ utils::SeqIter::new(seq).collect::<Result<_, _>>()?,
+ ))
+ }
+ }
+
+ deserializer.deserialize_bytes(CowVisitor)
+ }
+}
+
+impl<'de, T, U, FORMAT> DeserializeAs<'de, Vec<T>> for OneOrMany<U, FORMAT>
+where
+ U: DeserializeAs<'de, T>,
+ FORMAT: Format,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Vec<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ #[derive(serde::Deserialize)]
+ #[serde(
+ untagged,
+ bound(deserialize = r#"DeserializeAsWrap<T, U>: Deserialize<'de>,
+ DeserializeAsWrap<Vec<T>, Vec<U>>: Deserialize<'de>"#),
+ expecting = "a list or single element"
+ )]
+ enum Helper<'a, T, U>
+ where
+ U: DeserializeAs<'a, T>,
+ {
+ One(DeserializeAsWrap<T, U>),
+ Many(DeserializeAsWrap<Vec<T>, Vec<U>>),
+ #[serde(skip)]
+ _JustAMarkerForTheLifetime(PhantomData<&'a u32>),
+ }
+
+ let h: Helper<'de, T, U> = Deserialize::deserialize(deserializer)?;
+ match h {
+ Helper::One(one) => Ok(alloc::vec![one.into_inner()]),
+ Helper::Many(many) => Ok(many.into_inner()),
+ Helper::_JustAMarkerForTheLifetime(_) => unreachable!(),
+ }
+ }
+}
+
+impl<'de, T, TAs1> DeserializeAs<'de, T> for PickFirst<(TAs1,)>
+where
+ TAs1: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(DeserializeAsWrap::<T, TAs1>::deserialize(deserializer)?.into_inner())
+ }
+}
+
+impl<'de, T, TAs1, TAs2> DeserializeAs<'de, T> for PickFirst<(TAs1, TAs2)>
+where
+ TAs1: DeserializeAs<'de, T>,
+ TAs2: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ #[derive(serde::Deserialize)]
+ #[serde(
+ untagged,
+ bound(deserialize = r#"
+ DeserializeAsWrap<T, TAs1>: Deserialize<'de>,
+ DeserializeAsWrap<T, TAs2>: Deserialize<'de>,
+ "#),
+ expecting = "PickFirst could not deserialize data"
+ )]
+ enum Helper<'a, T, TAs1, TAs2>
+ where
+ TAs1: DeserializeAs<'a, T>,
+ TAs2: DeserializeAs<'a, T>,
+ {
+ First(DeserializeAsWrap<T, TAs1>),
+ Second(DeserializeAsWrap<T, TAs2>),
+ #[serde(skip)]
+ _JustAMarkerForTheLifetime(PhantomData<&'a u32>),
+ }
+
+ let h: Helper<'de, T, TAs1, TAs2> = Deserialize::deserialize(deserializer)?;
+ match h {
+ Helper::First(first) => Ok(first.into_inner()),
+ Helper::Second(second) => Ok(second.into_inner()),
+ Helper::_JustAMarkerForTheLifetime(_) => unreachable!(),
+ }
+ }
+}
+
+impl<'de, T, TAs1, TAs2, TAs3> DeserializeAs<'de, T> for PickFirst<(TAs1, TAs2, TAs3)>
+where
+ TAs1: DeserializeAs<'de, T>,
+ TAs2: DeserializeAs<'de, T>,
+ TAs3: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ #[derive(serde::Deserialize)]
+ #[serde(
+ untagged,
+ bound(deserialize = r#"
+ DeserializeAsWrap<T, TAs1>: Deserialize<'de>,
+ DeserializeAsWrap<T, TAs2>: Deserialize<'de>,
+ DeserializeAsWrap<T, TAs3>: Deserialize<'de>,
+ "#),
+ expecting = "PickFirst could not deserialize data"
+ )]
+ enum Helper<'a, T, TAs1, TAs2, TAs3>
+ where
+ TAs1: DeserializeAs<'a, T>,
+ TAs2: DeserializeAs<'a, T>,
+ TAs3: DeserializeAs<'a, T>,
+ {
+ First(DeserializeAsWrap<T, TAs1>),
+ Second(DeserializeAsWrap<T, TAs2>),
+ Third(DeserializeAsWrap<T, TAs3>),
+ #[serde(skip)]
+ _JustAMarkerForTheLifetime(PhantomData<&'a u32>),
+ }
+
+ let h: Helper<'de, T, TAs1, TAs2, TAs3> = Deserialize::deserialize(deserializer)?;
+ match h {
+ Helper::First(first) => Ok(first.into_inner()),
+ Helper::Second(second) => Ok(second.into_inner()),
+ Helper::Third(third) => Ok(third.into_inner()),
+ Helper::_JustAMarkerForTheLifetime(_) => unreachable!(),
+ }
+ }
+}
+
+impl<'de, T, TAs1, TAs2, TAs3, TAs4> DeserializeAs<'de, T> for PickFirst<(TAs1, TAs2, TAs3, TAs4)>
+where
+ TAs1: DeserializeAs<'de, T>,
+ TAs2: DeserializeAs<'de, T>,
+ TAs3: DeserializeAs<'de, T>,
+ TAs4: DeserializeAs<'de, T>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ #[derive(serde::Deserialize)]
+ #[serde(
+ untagged,
+ bound(deserialize = r#"
+ DeserializeAsWrap<T, TAs1>: Deserialize<'de>,
+ DeserializeAsWrap<T, TAs2>: Deserialize<'de>,
+ DeserializeAsWrap<T, TAs3>: Deserialize<'de>,
+ DeserializeAsWrap<T, TAs4>: Deserialize<'de>,
+ "#),
+ expecting = "PickFirst could not deserialize data"
+ )]
+ enum Helper<'a, T, TAs1, TAs2, TAs3, TAs4>
+ where
+ TAs1: DeserializeAs<'a, T>,
+ TAs2: DeserializeAs<'a, T>,
+ TAs3: DeserializeAs<'a, T>,
+ TAs4: DeserializeAs<'a, T>,
+ {
+ First(DeserializeAsWrap<T, TAs1>),
+ Second(DeserializeAsWrap<T, TAs2>),
+ Third(DeserializeAsWrap<T, TAs3>),
+ Forth(DeserializeAsWrap<T, TAs4>),
+ #[serde(skip)]
+ _JustAMarkerForTheLifetime(PhantomData<&'a u32>),
+ }
+
+ let h: Helper<'de, T, TAs1, TAs2, TAs3, TAs4> = Deserialize::deserialize(deserializer)?;
+ match h {
+ Helper::First(first) => Ok(first.into_inner()),
+ Helper::Second(second) => Ok(second.into_inner()),
+ Helper::Third(third) => Ok(third.into_inner()),
+ Helper::Forth(forth) => Ok(forth.into_inner()),
+ Helper::_JustAMarkerForTheLifetime(_) => unreachable!(),
+ }
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, T> for FromInto<U>
+where
+ U: Into<T>,
+ U: Deserialize<'de>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Ok(U::deserialize(deserializer)?.into())
+ }
+}
+
+impl<'de, T, U> DeserializeAs<'de, T> for TryFromInto<U>
+where
+ U: TryInto<T>,
+ <U as TryInto<T>>::Error: Display,
+ U: Deserialize<'de>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ U::deserialize(deserializer)?
+ .try_into()
+ .map_err(Error::custom)
+ }
+}
+
+impl<'de> DeserializeAs<'de, Cow<'de, str>> for BorrowCow {
+ fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, str>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct CowVisitor;
+
+ impl<'de> Visitor<'de> for CowVisitor {
+ type Value = Cow<'de, str>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("an optionally borrowed string")
+ }
+
+ fn visit_borrowed_str<E>(self, v: &'de str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Borrowed(v))
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v.to_owned()))
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(Cow::Owned(v))
+ }
+ }
+
+ deserializer.deserialize_str(CowVisitor)
+ }
+}
+
+impl<'de> DeserializeAs<'de, Cow<'de, [u8]>> for BorrowCow {
+ fn deserialize_as<D>(deserializer: D) -> Result<Cow<'de, [u8]>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Bytes::deserialize_as(deserializer)
+ }
+}
+
+impl<'de> DeserializeAs<'de, bool> for BoolFromInt<Strict> {
+ fn deserialize_as<D>(deserializer: D) -> Result<bool, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct U8Visitor;
+ impl<'de> Visitor<'de> for U8Visitor {
+ type Value = bool;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("an integer 0 or 1")
+ }
+
+ fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match v {
+ 0 => Ok(false),
+ 1 => Ok(true),
+ unexp => Err(Error::invalid_value(
+ Unexpected::Unsigned(unexp as u64),
+ &"0 or 1",
+ )),
+ }
+ }
+
+ fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match v {
+ 0 => Ok(false),
+ 1 => Ok(true),
+ unexp => Err(Error::invalid_value(
+ Unexpected::Signed(unexp as i64),
+ &"0 or 1",
+ )),
+ }
+ }
+
+ fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match v {
+ 0 => Ok(false),
+ 1 => Ok(true),
+ unexp => Err(Error::invalid_value(Unexpected::Unsigned(unexp), &"0 or 1")),
+ }
+ }
+
+ fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match v {
+ 0 => Ok(false),
+ 1 => Ok(true),
+ unexp => Err(Error::invalid_value(Unexpected::Signed(unexp), &"0 or 1")),
+ }
+ }
+
+ fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match v {
+ 0 => Ok(false),
+ 1 => Ok(true),
+ unexp => Err(Error::invalid_value(
+ Unexpected::Unsigned(unexp as u64),
+ &"0 or 1",
+ )),
+ }
+ }
+
+ fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match v {
+ 0 => Ok(false),
+ 1 => Ok(true),
+ unexp => Err(Error::invalid_value(
+ Unexpected::Unsigned(unexp as u64),
+ &"0 or 1",
+ )),
+ }
+ }
+ }
+
+ deserializer.deserialize_u8(U8Visitor)
+ }
+}
+
+impl<'de> DeserializeAs<'de, bool> for BoolFromInt<Flexible> {
+ fn deserialize_as<D>(deserializer: D) -> Result<bool, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct U8Visitor;
+ impl<'de> Visitor<'de> for U8Visitor {
+ type Value = bool;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("an integer")
+ }
+
+ fn visit_u8<E>(self, v: u8) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v != 0)
+ }
+
+ fn visit_i8<E>(self, v: i8) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v != 0)
+ }
+
+ fn visit_u64<E>(self, v: u64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v != 0)
+ }
+
+ fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v != 0)
+ }
+
+ fn visit_u128<E>(self, v: u128) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v != 0)
+ }
+
+ fn visit_i128<E>(self, v: i128) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(v != 0)
+ }
+ }
+
+ deserializer.deserialize_u8(U8Visitor)
+ }
+}
+
+// endregion
diff --git a/third_party/rust/serde_with/src/de/legacy_arrays.rs b/third_party/rust/serde_with/src/de/legacy_arrays.rs
new file mode 100644
index 0000000000..550e444a2f
--- /dev/null
+++ b/third_party/rust/serde_with/src/de/legacy_arrays.rs
@@ -0,0 +1,85 @@
+use super::*;
+use core::fmt;
+use serde::de::*;
+
+macro_rules! array_impl {
+ ($len:literal $($idx:tt)*) => {
+ impl<'de, T, As> DeserializeAs<'de, [T; $len]> for [As; $len]
+ where
+ As: DeserializeAs<'de, T>,
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<[T; $len], D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct ArrayVisitor<T>(PhantomData<T>);
+
+ impl<'de, T, As> Visitor<'de>
+ for ArrayVisitor<DeserializeAsWrap<T, As>>
+ where
+ As: DeserializeAs<'de, T>,
+ {
+ type Value = [T; $len];
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str(concat!("an array of size ", $len))
+ }
+
+ #[allow(non_snake_case)]
+ // Because of 0-size arrays
+ #[allow(unused_variables, unused_mut)]
+ fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ Ok([$(
+ match seq.next_element::<DeserializeAsWrap<T, As>>()? {
+ Some(value) => value.into_inner(),
+ None => return Err(Error::invalid_length($idx, &self)),
+ },
+ )*])
+ }
+ }
+
+ deserializer.deserialize_tuple(
+ $len,
+ ArrayVisitor::<DeserializeAsWrap<T, As>>(PhantomData),
+ )
+ }
+ }
+ };
+}
+
+array_impl!(0);
+array_impl!(1 0);
+array_impl!(2 0 1);
+array_impl!(3 0 1 2);
+array_impl!(4 0 1 2 3);
+array_impl!(5 0 1 2 3 4);
+array_impl!(6 0 1 2 3 4 5);
+array_impl!(7 0 1 2 3 4 5 6);
+array_impl!(8 0 1 2 3 4 5 6 7);
+array_impl!(9 0 1 2 3 4 5 6 7 8);
+array_impl!(10 0 1 2 3 4 5 6 7 8 9);
+array_impl!(11 0 1 2 3 4 5 6 7 8 9 10);
+array_impl!(12 0 1 2 3 4 5 6 7 8 9 10 11);
+array_impl!(13 0 1 2 3 4 5 6 7 8 9 10 11 12);
+array_impl!(14 0 1 2 3 4 5 6 7 8 9 10 11 12 13);
+array_impl!(15 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14);
+array_impl!(16 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15);
+array_impl!(17 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16);
+array_impl!(18 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17);
+array_impl!(19 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18);
+array_impl!(20 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19);
+array_impl!(21 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20);
+array_impl!(22 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21);
+array_impl!(23 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22);
+array_impl!(24 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23);
+array_impl!(25 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24);
+array_impl!(26 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25);
+array_impl!(27 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26);
+array_impl!(28 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27);
+array_impl!(29 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28);
+array_impl!(30 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29);
+array_impl!(31 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30);
+array_impl!(32 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31);
diff --git a/third_party/rust/serde_with/src/de/mod.rs b/third_party/rust/serde_with/src/de/mod.rs
new file mode 100644
index 0000000000..518b4f2606
--- /dev/null
+++ b/third_party/rust/serde_with/src/de/mod.rs
@@ -0,0 +1,143 @@
+//! Module for [`DeserializeAs`][] implementations
+//!
+//! The module contains the [`DeserializeAs`][] trait and helper code.
+//! Additionally, it contains implementations of [`DeserializeAs`][] for types defined in the Rust Standard Library or this crate.
+//!
+//! You can find more details on how to implement this trait for your types in the documentation of the [`DeserializeAs`][] trait and details about the usage in the [user guide][].
+//!
+//! [user guide]: crate::guide
+
+mod const_arrays;
+mod impls;
+
+use super::*;
+
+/// A **data structure** that can be deserialized from any data format supported by Serde, analogue to [`Deserialize`].
+///
+/// The trait is analogue to the [`serde::Deserialize`][`Deserialize`] trait, with the same meaning of input and output arguments.
+/// It can and should the implemented using the same code structure as the [`Deserialize`] trait.
+/// As such, the same advice for [implementing `Deserialize`][impl-deserialize] applies here.
+///
+/// # Differences to [`Deserialize`]
+///
+/// The trait is only required for container-like types or types implementing specific conversion functions.
+/// Container-like types are [`Vec`], [`BTreeMap`], but also [`Option`] and [`Box`].
+/// Conversion types deserialize into a different Rust type.
+/// For example, [`DisplayFromStr`] uses the [`FromStr`] trait after deserializing a string and [`DurationSeconds`] creates a [`Duration`] from either String or integer values.
+///
+/// This code shows how to implement [`Deserialize`] for [`Box`]:
+///
+/// ```rust,ignore
+/// impl<'de, T: Deserialize<'de>> Deserialize<'de> for Box<T> {
+/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+/// where
+/// D: Deserializer<'de>,
+/// {
+/// Ok(Box::new(Deserialize::deserialize(deserializer)?))
+/// }
+/// }
+/// ```
+///
+/// and this code shows how to do the same using [`DeserializeAs`][]:
+///
+/// ```rust,ignore
+/// impl<'de, T, U> DeserializeAs<'de, Box<T>> for Box<U>
+/// where
+/// U: DeserializeAs<'de, T>,
+/// {
+/// fn deserialize_as<D>(deserializer: D) -> Result<Box<T>, D::Error>
+/// where
+/// D: Deserializer<'de>,
+/// {
+/// Ok(Box::new(
+/// DeserializeAsWrap::<T, U>::deserialize(deserializer)?.into_inner(),
+/// ))
+/// }
+/// }
+/// ```
+///
+/// It uses two type parameters, `T` and `U` instead of only one and performs the deserialization step using the `DeserializeAsWrap` type.
+/// The `T` type is the on the Rust side after deserialization, whereas the `U` type determines how the value will be deserialized.
+/// These two changes are usually enough to make a container type implement [`DeserializeAs`][].
+///
+///
+/// [`DeserializeAsWrap`] is a piece of glue code which turns [`DeserializeAs`] into a serde compatible datatype, by converting all calls to `deserialize` into `deserialize_as`.
+/// This allows us to implement [`DeserializeAs`] such that it can be applied recursively throughout the whole data structure.
+/// This is mostly important for container types, such as `Vec` or `BTreeMap`.
+/// In a `BTreeMap` this allows us to specify two different serialization behaviors, one for key and one for value, using the [`DeserializeAs`] trait.
+///
+/// ## Implementing a converter Type
+///
+/// This shows a simplified implementation for [`DisplayFromStr`].
+///
+/// ```rust
+/// # #[cfg(all(feature = "macros"))] {
+/// # use serde::Deserialize;
+/// # use serde::de::Error;
+/// # use serde_with::DeserializeAs;
+/// # use std::str::FromStr;
+/// # use std::fmt::Display;
+/// struct DisplayFromStr;
+///
+/// impl<'de, T> DeserializeAs<'de, T> for DisplayFromStr
+/// where
+/// T: FromStr,
+/// T::Err: Display,
+/// {
+/// fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+/// where
+/// D: serde::Deserializer<'de>,
+/// {
+/// let s = String::deserialize(deserializer).map_err(Error::custom)?;
+/// s.parse().map_err(Error::custom)
+/// }
+/// }
+/// #
+/// # #[serde_with::serde_as]
+/// # #[derive(serde::Deserialize)]
+/// # struct S (#[serde_as(as = "DisplayFromStr")] bool);
+/// #
+/// # assert_eq!(false, serde_json::from_str::<S>(r#""false""#).unwrap().0);
+/// # }
+/// ```
+/// [`Box`]: std::boxed::Box
+/// [`BTreeMap`]: std::collections::BTreeMap
+/// [`Duration`]: std::time::Duration
+/// [`FromStr`]: std::str::FromStr
+/// [`Vec`]: std::vec::Vec
+/// [impl-deserialize]: https://serde.rs/impl-deserialize.html
+pub trait DeserializeAs<'de, T>: Sized {
+ /// Deserialize this value from the given Serde deserializer.
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>;
+}
+
+/// Helper type to implement [`DeserializeAs`] for container-like types.
+#[derive(Debug)]
+pub struct DeserializeAsWrap<T, U> {
+ value: T,
+ marker: PhantomData<U>,
+}
+
+impl<T, U> DeserializeAsWrap<T, U> {
+ /// Return the inner value of type `T`.
+ pub fn into_inner(self) -> T {
+ self.value
+ }
+}
+
+impl<'de, T, U> Deserialize<'de> for DeserializeAsWrap<T, U>
+where
+ U: DeserializeAs<'de, T>,
+{
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ U::deserialize_as(deserializer).map(|value| Self {
+ value,
+ marker: PhantomData,
+ })
+ }
+}
diff --git a/third_party/rust/serde_with/src/duplicate_key_impls/error_on_duplicate.rs b/third_party/rust/serde_with/src/duplicate_key_impls/error_on_duplicate.rs
new file mode 100644
index 0000000000..9370f5fd51
--- /dev/null
+++ b/third_party/rust/serde_with/src/duplicate_key_impls/error_on_duplicate.rs
@@ -0,0 +1,127 @@
+use alloc::collections::{BTreeMap, BTreeSet};
+use core::hash::{BuildHasher, Hash};
+#[cfg(feature = "indexmap")]
+use indexmap_crate::{IndexMap, IndexSet};
+use std::collections::{HashMap, HashSet};
+
+pub trait PreventDuplicateInsertsSet<T> {
+ fn new(size_hint: Option<usize>) -> Self;
+
+ /// Return true if the insert was successful and the value did not exist in the set
+ fn insert(&mut self, value: T) -> bool;
+}
+
+pub trait PreventDuplicateInsertsMap<K, V> {
+ fn new(size_hint: Option<usize>) -> Self;
+
+ /// Return true if the insert was successful and the key did not exist in the map
+ fn insert(&mut self, key: K, value: V) -> bool;
+}
+
+impl<T, S> PreventDuplicateInsertsSet<T> for HashSet<T, S>
+where
+ T: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ #[inline]
+ fn new(size_hint: Option<usize>) -> Self {
+ match size_hint {
+ Some(size) => Self::with_capacity_and_hasher(size, S::default()),
+ None => Self::with_hasher(S::default()),
+ }
+ }
+
+ #[inline]
+ fn insert(&mut self, value: T) -> bool {
+ self.insert(value)
+ }
+}
+
+#[cfg(feature = "indexmap")]
+impl<T, S> PreventDuplicateInsertsSet<T> for IndexSet<T, S>
+where
+ T: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ #[inline]
+ fn new(size_hint: Option<usize>) -> Self {
+ match size_hint {
+ Some(size) => Self::with_capacity_and_hasher(size, S::default()),
+ None => Self::with_hasher(S::default()),
+ }
+ }
+
+ #[inline]
+ fn insert(&mut self, value: T) -> bool {
+ self.insert(value)
+ }
+}
+
+impl<T> PreventDuplicateInsertsSet<T> for BTreeSet<T>
+where
+ T: Ord,
+{
+ #[inline]
+ fn new(_size_hint: Option<usize>) -> Self {
+ Self::new()
+ }
+
+ #[inline]
+ fn insert(&mut self, value: T) -> bool {
+ self.insert(value)
+ }
+}
+
+impl<K, V, S> PreventDuplicateInsertsMap<K, V> for HashMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ #[inline]
+ fn new(size_hint: Option<usize>) -> Self {
+ match size_hint {
+ Some(size) => Self::with_capacity_and_hasher(size, S::default()),
+ None => Self::with_hasher(S::default()),
+ }
+ }
+
+ #[inline]
+ fn insert(&mut self, key: K, value: V) -> bool {
+ self.insert(key, value).is_none()
+ }
+}
+
+#[cfg(feature = "indexmap")]
+impl<K, V, S> PreventDuplicateInsertsMap<K, V> for IndexMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ #[inline]
+ fn new(size_hint: Option<usize>) -> Self {
+ match size_hint {
+ Some(size) => Self::with_capacity_and_hasher(size, S::default()),
+ None => Self::with_hasher(S::default()),
+ }
+ }
+
+ #[inline]
+ fn insert(&mut self, key: K, value: V) -> bool {
+ self.insert(key, value).is_none()
+ }
+}
+
+impl<K, V> PreventDuplicateInsertsMap<K, V> for BTreeMap<K, V>
+where
+ K: Ord,
+{
+ #[inline]
+ fn new(_size_hint: Option<usize>) -> Self {
+ Self::new()
+ }
+
+ #[inline]
+ fn insert(&mut self, key: K, value: V) -> bool {
+ self.insert(key, value).is_none()
+ }
+}
diff --git a/third_party/rust/serde_with/src/duplicate_key_impls/first_value_wins.rs b/third_party/rust/serde_with/src/duplicate_key_impls/first_value_wins.rs
new file mode 100644
index 0000000000..faf922b8c2
--- /dev/null
+++ b/third_party/rust/serde_with/src/duplicate_key_impls/first_value_wins.rs
@@ -0,0 +1,136 @@
+use alloc::collections::{BTreeMap, BTreeSet};
+use core::hash::{BuildHasher, Hash};
+#[cfg(feature = "indexmap")]
+use indexmap_crate::IndexMap;
+use std::collections::{HashMap, HashSet};
+
+#[deprecated = "This is serde's default behavior."]
+pub trait DuplicateInsertsFirstWinsSet<T> {
+ fn new(size_hint: Option<usize>) -> Self;
+
+ /// Insert the value into the set, if there is not already an existing value
+ fn insert(&mut self, value: T);
+}
+
+pub trait DuplicateInsertsFirstWinsMap<K, V> {
+ fn new(size_hint: Option<usize>) -> Self;
+
+ /// Insert the value into the map, if there is not already an existing value
+ fn insert(&mut self, key: K, value: V);
+}
+
+#[allow(deprecated)]
+impl<T, S> DuplicateInsertsFirstWinsSet<T> for HashSet<T, S>
+where
+ T: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ #[inline]
+ fn new(size_hint: Option<usize>) -> Self {
+ match size_hint {
+ Some(size) => Self::with_capacity_and_hasher(size, S::default()),
+ None => Self::with_hasher(S::default()),
+ }
+ }
+
+ #[inline]
+ fn insert(&mut self, value: T) {
+ // Hashset already fulfils the contract and always keeps the first value
+ self.insert(value);
+ }
+}
+
+#[allow(deprecated)]
+impl<T> DuplicateInsertsFirstWinsSet<T> for BTreeSet<T>
+where
+ T: Ord,
+{
+ #[inline]
+ fn new(_size_hint: Option<usize>) -> Self {
+ Self::new()
+ }
+
+ #[inline]
+ fn insert(&mut self, value: T) {
+ // BTreeSet already fulfils the contract and always keeps the first value
+ self.insert(value);
+ }
+}
+
+impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for HashMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ #[inline]
+ fn new(size_hint: Option<usize>) -> Self {
+ match size_hint {
+ Some(size) => Self::with_capacity_and_hasher(size, S::default()),
+ None => Self::with_hasher(S::default()),
+ }
+ }
+
+ #[inline]
+ fn insert(&mut self, key: K, value: V) {
+ use std::collections::hash_map::Entry;
+
+ match self.entry(key) {
+ // we want to keep the first value, so do nothing
+ Entry::Occupied(_) => {}
+ Entry::Vacant(vacant) => {
+ vacant.insert(value);
+ }
+ }
+ }
+}
+
+#[cfg(feature = "indexmap")]
+impl<K, V, S> DuplicateInsertsFirstWinsMap<K, V> for IndexMap<K, V, S>
+where
+ K: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ #[inline]
+ fn new(size_hint: Option<usize>) -> Self {
+ match size_hint {
+ Some(size) => Self::with_capacity_and_hasher(size, S::default()),
+ None => Self::with_hasher(S::default()),
+ }
+ }
+
+ #[inline]
+ fn insert(&mut self, key: K, value: V) {
+ use indexmap_crate::map::Entry;
+
+ match self.entry(key) {
+ // we want to keep the first value, so do nothing
+ Entry::Occupied(_) => {}
+ Entry::Vacant(vacant) => {
+ vacant.insert(value);
+ }
+ }
+ }
+}
+
+impl<K, V> DuplicateInsertsFirstWinsMap<K, V> for BTreeMap<K, V>
+where
+ K: Ord,
+{
+ #[inline]
+ fn new(_size_hint: Option<usize>) -> Self {
+ Self::new()
+ }
+
+ #[inline]
+ fn insert(&mut self, key: K, value: V) {
+ use alloc::collections::btree_map::Entry;
+
+ match self.entry(key) {
+ // we want to keep the first value, so do nothing
+ Entry::Occupied(_) => {}
+ Entry::Vacant(vacant) => {
+ vacant.insert(value);
+ }
+ }
+ }
+}
diff --git a/third_party/rust/serde_with/src/duplicate_key_impls/last_value_wins.rs b/third_party/rust/serde_with/src/duplicate_key_impls/last_value_wins.rs
new file mode 100644
index 0000000000..3eeeaac079
--- /dev/null
+++ b/third_party/rust/serde_with/src/duplicate_key_impls/last_value_wins.rs
@@ -0,0 +1,69 @@
+use alloc::collections::BTreeSet;
+use core::hash::{BuildHasher, Hash};
+#[cfg(feature = "indexmap")]
+use indexmap_crate::IndexSet;
+use std::collections::HashSet;
+
+pub trait DuplicateInsertsLastWinsSet<T> {
+ fn new(size_hint: Option<usize>) -> Self;
+
+ /// Insert or replace the existing value
+ fn replace(&mut self, value: T);
+}
+
+impl<T, S> DuplicateInsertsLastWinsSet<T> for HashSet<T, S>
+where
+ T: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ #[inline]
+ fn new(size_hint: Option<usize>) -> Self {
+ match size_hint {
+ Some(size) => Self::with_capacity_and_hasher(size, S::default()),
+ None => Self::with_hasher(S::default()),
+ }
+ }
+
+ #[inline]
+ fn replace(&mut self, value: T) {
+ // Hashset already fulfils the contract
+ self.replace(value);
+ }
+}
+
+#[cfg(feature = "indexmap")]
+impl<T, S> DuplicateInsertsLastWinsSet<T> for IndexSet<T, S>
+where
+ T: Eq + Hash,
+ S: BuildHasher + Default,
+{
+ #[inline]
+ fn new(size_hint: Option<usize>) -> Self {
+ match size_hint {
+ Some(size) => Self::with_capacity_and_hasher(size, S::default()),
+ None => Self::with_hasher(S::default()),
+ }
+ }
+
+ #[inline]
+ fn replace(&mut self, value: T) {
+ // Hashset already fulfils the contract
+ self.replace(value);
+ }
+}
+
+impl<T> DuplicateInsertsLastWinsSet<T> for BTreeSet<T>
+where
+ T: Ord,
+{
+ #[inline]
+ fn new(_size_hint: Option<usize>) -> Self {
+ Self::new()
+ }
+
+ #[inline]
+ fn replace(&mut self, value: T) {
+ // BTreeSet already fulfils the contract
+ self.replace(value);
+ }
+}
diff --git a/third_party/rust/serde_with/src/duplicate_key_impls/mod.rs b/third_party/rust/serde_with/src/duplicate_key_impls/mod.rs
new file mode 100644
index 0000000000..6080812232
--- /dev/null
+++ b/third_party/rust/serde_with/src/duplicate_key_impls/mod.rs
@@ -0,0 +1,10 @@
+mod error_on_duplicate;
+mod first_value_wins;
+mod last_value_wins;
+
+#[allow(deprecated)]
+pub use self::{
+ error_on_duplicate::{PreventDuplicateInsertsMap, PreventDuplicateInsertsSet},
+ first_value_wins::{DuplicateInsertsFirstWinsMap, DuplicateInsertsFirstWinsSet},
+ last_value_wins::DuplicateInsertsLastWinsSet,
+};
diff --git a/third_party/rust/serde_with/src/enum_map.rs b/third_party/rust/serde_with/src/enum_map.rs
new file mode 100644
index 0000000000..ef65f8985f
--- /dev/null
+++ b/third_party/rust/serde_with/src/enum_map.rs
@@ -0,0 +1,888 @@
+use crate::{
+ content::ser::{Content, ContentSerializer},
+ DeserializeAs, SerializeAs,
+};
+use alloc::{string::ToString, vec::Vec};
+use core::{fmt, marker::PhantomData};
+use serde::{
+ de::{DeserializeSeed, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor},
+ ser,
+ ser::{Impossible, SerializeMap, SerializeSeq, SerializeStructVariant, SerializeTupleVariant},
+ Deserialize, Deserializer, Serialize, Serializer,
+};
+
+/// Represent a list of enum values as a map.
+///
+/// This **only works** if the enum uses the default *externally tagged* representation.
+/// Other enum representations are not supported.
+///
+/// serde data formats often represent *externally tagged* enums as maps with a single key.
+/// The key is the enum variant name, and the value is the variant value.
+/// Sometimes a map with multiple keys should be treated like a list of enum values.
+///
+/// # Examples
+///
+/// ## JSON Map with multiple keys
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// use serde_with::EnumMap;
+///
+/// # #[derive(Debug, Clone, PartialEq, Eq)]
+/// #[derive(Serialize, Deserialize)]
+/// enum EnumValue {
+/// Int(i32),
+/// String(String),
+/// Unit,
+/// Tuple(i32, String, bool),
+/// Struct {
+/// a: i32,
+/// b: String,
+/// c: bool,
+/// },
+/// }
+///
+/// #[serde_with::serde_as]
+/// # #[derive(Debug, Clone, PartialEq, Eq)]
+/// #[derive(Serialize, Deserialize)]
+/// struct VecEnumValues (
+/// #[serde_as(as = "EnumMap")]
+/// Vec<EnumValue>,
+/// );
+///
+/// // ---
+///
+/// // This will serialize this list of values
+/// let values = VecEnumValues(vec![
+/// EnumValue::Int(123),
+/// EnumValue::String("FooBar".to_string()),
+/// EnumValue::Int(456),
+/// EnumValue::String("XXX".to_string()),
+/// EnumValue::Unit,
+/// EnumValue::Tuple(1, "Middle".to_string(), false),
+/// EnumValue::Struct {
+/// a: 666,
+/// b: "BBB".to_string(),
+/// c: true,
+/// },
+/// ]);
+///
+/// // into this JSON map
+/// // Duplicate keys are emitted for identical enum variants.
+/// let expected =
+/// r#"{
+/// "Int": 123,
+/// "String": "FooBar",
+/// "Int": 456,
+/// "String": "XXX",
+/// "Unit": null,
+/// "Tuple": [
+/// 1,
+/// "Middle",
+/// false
+/// ],
+/// "Struct": {
+/// "a": 666,
+/// "b": "BBB",
+/// "c": true
+/// }
+/// }"#;
+///
+/// // Both serialization and deserialization work flawlessly.
+/// let serialized = serde_json::to_string_pretty(&values).unwrap();
+/// assert_eq!(expected, serialized);
+/// let deserialized: VecEnumValues = serde_json::from_str(&serialized).unwrap();
+/// assert_eq!(values, deserialized);
+/// # }
+/// ```
+///
+/// ## XML structure with varying keys
+///
+/// With `serde_xml_rs` tuple and struct variants are not supported since they fail to roundtrip.
+/// The enum may have such variants as long as they are not serialized or deserialized.
+///
+/// ```
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// use serde_with::EnumMap;
+///
+/// # #[derive(Debug, Clone, PartialEq, Eq)]
+/// #[derive(Serialize, Deserialize)]
+/// enum EnumValue {
+/// Int(i32),
+/// String(String),
+/// Unit,
+/// }
+///
+/// #[serde_with::serde_as]
+/// # #[derive(Debug, Clone, PartialEq, Eq)]
+/// #[derive(Serialize, Deserialize)]
+/// struct VecEnumValues {
+/// #[serde_as(as = "EnumMap")]
+/// vec: Vec<EnumValue>,
+/// }
+///
+/// // ---
+///
+/// // This will serialize this list of values
+/// let values = VecEnumValues {
+/// vec: vec![
+/// EnumValue::Int(123),
+/// EnumValue::String("FooBar".to_string()),
+/// EnumValue::Int(456),
+/// EnumValue::String("XXX".to_string()),
+/// EnumValue::Unit,
+/// ],
+/// };
+///
+/// // into this XML document
+/// // Duplicate keys are emitted for identical enum variants.
+/// let expected = r#"
+/// <VecEnumValues>
+/// <vec>
+/// <Int>123</Int>
+/// <String>FooBar</String>
+/// <Int>456</Int>
+/// <String>XXX</String>
+/// <Unit></Unit>
+/// </vec>
+/// </VecEnumValues>"#
+/// // Remove whitespace
+/// .replace(' ', "")
+/// .replace('\n', "");
+///
+/// // Both serialization and deserialization work flawlessly.
+/// let serialized = serde_xml_rs::to_string(&values).unwrap();
+/// assert_eq!(expected, serialized);
+/// let deserialized: VecEnumValues = serde_xml_rs::from_str(&serialized).unwrap();
+/// assert_eq!(values, deserialized);
+/// # }
+/// ```
+#[derive(Debug, Copy, Clone)]
+pub struct EnumMap;
+
+impl<T> SerializeAs<Vec<T>> for EnumMap
+where
+ T: Serialize,
+{
+ fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ source.serialize(SeqAsMapSerializer(serializer))
+ }
+}
+
+impl<'de, T> DeserializeAs<'de, Vec<T>> for EnumMap
+where
+ T: Deserialize<'de>,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<Vec<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct EnumMapVisitor<T>(PhantomData<T>);
+
+ impl<'de, T> Visitor<'de> for EnumMapVisitor<T>
+ where
+ T: Deserialize<'de>,
+ {
+ type Value = Vec<T>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(formatter, "a map or enum values")
+ }
+
+ fn visit_map<A: MapAccess<'de>>(self, map: A) -> Result<Self::Value, A::Error> {
+ Vec::deserialize(SeqDeserializer(map))
+ }
+ }
+
+ deserializer.deserialize_map(EnumMapVisitor(PhantomData))
+ }
+}
+
+static END_OF_MAP_IDENTIFIER: &str = "__PRIVATE_END_OF_MAP_MARKER__";
+
+// Serialization code below here
+
+/// Convert a sequence to a map during serialization.
+///
+/// Only `serialize_seq` is implemented and forwarded to `serialize_map` on the inner `Serializer`.
+/// The elements are serialized with [`SerializeSeqElement`].
+struct SeqAsMapSerializer<S>(S);
+
+impl<S> Serializer for SeqAsMapSerializer<S>
+where
+ S: Serializer,
+{
+ type Ok = S::Ok;
+ type Error = S::Error;
+
+ type SerializeSeq = SerializeSeqElement<S::SerializeMap>;
+ type SerializeTuple = Impossible<S::Ok, S::Error>;
+ type SerializeTupleStruct = Impossible<S::Ok, S::Error>;
+ type SerializeTupleVariant = Impossible<S::Ok, S::Error>;
+ type SerializeMap = Impossible<S::Ok, S::Error>;
+ type SerializeStruct = Impossible<S::Ok, S::Error>;
+ type SerializeStructVariant = Impossible<S::Ok, S::Error>;
+
+ fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i128(self, _v: i128) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u128(self, _v: u128) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ ) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ let is_human_readable = self.0.is_human_readable();
+ self.0
+ .serialize_map(len)
+ .map(|delegate| SerializeSeqElement {
+ delegate,
+ is_human_readable,
+ })
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStruct, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+}
+
+/// Serialize a single element but turn the sequence into a map logic.
+///
+/// It uses [`SerializeEnumAsMapElement`] for the map element serialization.
+///
+/// The [`Serializer`] implementation handles all the `serialize_*_variant` functions and defers to [`SerializeVariant`] for the more complicated tuple and struct variants.
+struct SerializeSeqElement<M> {
+ delegate: M,
+ is_human_readable: bool,
+}
+
+impl<M> SerializeSeq for SerializeSeqElement<M>
+where
+ M: SerializeMap,
+{
+ type Ok = M::Ok;
+ type Error = M::Error;
+
+ fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize,
+ {
+ value.serialize(EnumAsMapElementSerializer {
+ delegate: &mut self.delegate,
+ is_human_readable: self.is_human_readable,
+ })?;
+ Ok(())
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ self.delegate.end()
+ }
+}
+
+struct EnumAsMapElementSerializer<'a, M> {
+ delegate: &'a mut M,
+ is_human_readable: bool,
+}
+
+impl<'a, M> Serializer for EnumAsMapElementSerializer<'a, M>
+where
+ M: SerializeMap,
+{
+ type Ok = ();
+ type Error = M::Error;
+
+ type SerializeSeq = Impossible<Self::Ok, Self::Error>;
+ type SerializeTuple = Impossible<Self::Ok, Self::Error>;
+ type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
+ type SerializeTupleVariant = SerializeVariant<'a, M>;
+ type SerializeMap = Impossible<Self::Ok, Self::Error>;
+ type SerializeStruct = Impossible<Self::Ok, Self::Error>;
+ type SerializeStructVariant = SerializeVariant<'a, M>;
+
+ fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_i128(self, _v: i128) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_u128(self, _v: u128) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_str(self, _v: &str) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_some<T: ?Sized>(self, _value: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Self::Ok, Self::Error> {
+ self.delegate.serialize_entry(variant, &())?;
+ Ok(())
+ }
+
+ fn serialize_newtype_struct<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_newtype_variant<T: ?Sized>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: Serialize,
+ {
+ self.delegate.serialize_entry(variant, value)?;
+ Ok(())
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+ Ok(SerializeVariant {
+ delegate: self.delegate,
+ is_human_readable: self.is_human_readable,
+ variant,
+ content: Content::TupleStruct(name, Vec::with_capacity(len)),
+ })
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStruct, Self::Error> {
+ Err(ser::Error::custom("wrong type for EnumMap"))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant, Self::Error> {
+ Ok(SerializeVariant {
+ delegate: self.delegate,
+ is_human_readable: self.is_human_readable,
+ variant,
+ content: Content::Struct(name, Vec::with_capacity(len)),
+ })
+ }
+}
+
+/// Serialize a struct or tuple variant enum as a map element
+///
+/// [`SerializeStructVariant`] serializes a struct variant, and [`SerializeTupleVariant`] a tuple variant.
+struct SerializeVariant<'a, M> {
+ delegate: &'a mut M,
+ is_human_readable: bool,
+ variant: &'static str,
+ content: Content,
+}
+
+impl<'a, M> SerializeStructVariant for SerializeVariant<'a, M>
+where
+ M: SerializeMap,
+{
+ type Ok = ();
+
+ type Error = M::Error;
+
+ fn serialize_field<T: ?Sized>(
+ &mut self,
+ key: &'static str,
+ value: &T,
+ ) -> Result<(), Self::Error>
+ where
+ T: Serialize,
+ {
+ // Serialize to a Content type first
+ let value: Content = value.serialize(ContentSerializer::new(self.is_human_readable))?;
+ if let Content::Struct(_name, fields) = &mut self.content {
+ fields.push((key, value));
+ }
+ Ok(())
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ self.delegate.serialize_entry(&self.variant, &self.content)
+ }
+}
+
+impl<'a, M> SerializeTupleVariant for SerializeVariant<'a, M>
+where
+ M: SerializeMap,
+{
+ type Ok = ();
+
+ type Error = M::Error;
+
+ fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: Serialize,
+ {
+ // Serialize to a Content type first
+ let value: Content = value.serialize(ContentSerializer::new(self.is_human_readable))?;
+ if let Content::TupleStruct(_name, fields) = &mut self.content {
+ fields.push(value);
+ }
+ Ok(())
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ self.delegate.serialize_entry(&self.variant, &self.content)
+ }
+}
+
+// Below is deserialization code
+
+/// Deserialize the sequence of enum instances.
+///
+/// The main [`Deserializer`] implementation handles the outer sequence (e.g., `Vec`), while the [`SeqAccess`] implementation is responsible for the inner elements.
+struct SeqDeserializer<M>(M);
+
+impl<'de, M> Deserializer<'de> for SeqDeserializer<M>
+where
+ M: MapAccess<'de>,
+{
+ type Error = M::Error;
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_seq(self)
+ }
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ serde::forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+impl<'de, M> SeqAccess<'de> for SeqDeserializer<M>
+where
+ M: MapAccess<'de>,
+{
+ type Error = M::Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match seed.deserialize(EnumDeserializer(&mut self.0)) {
+ Ok(value) => Ok(Some(value)),
+ Err(err) => {
+ // Unfortunately we loose the optional aspect of MapAccess, so we need to special case an error value to mark the end of the map.
+ if err.to_string().contains(END_OF_MAP_IDENTIFIER) {
+ Ok(None)
+ } else {
+ Err(err)
+ }
+ }
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ self.0.size_hint()
+ }
+}
+
+/// Deserialize an enum from a map element
+///
+/// The [`Deserializer`] implementation is the starting point, which first calls the [`EnumAccess`] methods.
+/// The [`EnumAccess`] is used to deserialize the enum variant type of the enum.
+/// The [`VariantAccess`] is used to deserialize the value part of the enum.
+struct EnumDeserializer<M>(M);
+
+impl<'de, M> Deserializer<'de> for EnumDeserializer<M>
+where
+ M: MapAccess<'de>,
+{
+ type Error = M::Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_enum("", &[], visitor)
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ _name: &'static str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_enum(self)
+ }
+
+ serde::forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct identifier ignored_any
+ }
+}
+
+impl<'de, M> EnumAccess<'de> for EnumDeserializer<M>
+where
+ M: MapAccess<'de>,
+{
+ type Error = M::Error;
+ type Variant = Self;
+
+ fn variant_seed<T>(mut self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.0.next_key_seed(seed)? {
+ Some(key) => Ok((key, self)),
+
+ // Unfortunately we loose the optional aspect of MapAccess, so we need to special case an error value to mark the end of the map.
+ None => Err(Error::custom(END_OF_MAP_IDENTIFIER)),
+ }
+ }
+}
+
+impl<'de, M> VariantAccess<'de> for EnumDeserializer<M>
+where
+ M: MapAccess<'de>,
+{
+ type Error = M::Error;
+
+ fn unit_variant(mut self) -> Result<(), Self::Error> {
+ self.0.next_value()
+ }
+
+ fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Self::Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ self.0.next_value_seed(seed)
+ }
+
+ fn tuple_variant<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.0.next_value_seed(SeedTupleVariant { len, visitor })
+ }
+
+ fn struct_variant<V>(
+ mut self,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.0.next_value_seed(SeedStructVariant { visitor })
+ }
+}
+
+struct SeedTupleVariant<V> {
+ len: usize,
+ visitor: V,
+}
+
+impl<'de, V> DeserializeSeed<'de> for SeedTupleVariant<V>
+where
+ V: Visitor<'de>,
+{
+ type Value = V::Value;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_tuple(self.len, self.visitor)
+ }
+}
+
+struct SeedStructVariant<V> {
+ visitor: V,
+}
+
+impl<'de, V> DeserializeSeed<'de> for SeedStructVariant<V>
+where
+ V: Visitor<'de>,
+{
+ type Value = V::Value;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_map(self.visitor)
+ }
+}
diff --git a/third_party/rust/serde_with/src/flatten_maybe.rs b/third_party/rust/serde_with/src/flatten_maybe.rs
new file mode 100644
index 0000000000..e012812d5a
--- /dev/null
+++ b/third_party/rust/serde_with/src/flatten_maybe.rs
@@ -0,0 +1,86 @@
+/// Support deserializing from flattened and non-flattened representation
+///
+/// When working with different serialization formats, sometimes it is more idiomatic to flatten
+/// fields, while other formats prefer nesting. Using `#[serde(flatten)]` only the flattened form
+/// is supported.
+///
+/// This helper creates a function, which support deserializing from either the flattened or the
+/// nested form. It gives an error, when both forms are provided. The `flatten` attribute is
+/// required on the field such that the helper works. The serialization format will always be
+/// flattened.
+///
+/// # Examples
+///
+/// ```rust
+/// # use serde::Deserialize;
+/// #
+/// // Setup the types
+/// #[derive(Deserialize, Debug)]
+/// struct S {
+/// #[serde(flatten, deserialize_with = "deserialize_t")]
+/// t: T,
+/// }
+///
+/// #[derive(Deserialize, Debug)]
+/// struct T {
+/// i: i32,
+/// }
+///
+/// // The macro creates custom deserialization code.
+/// // You need to specify a function name and the field name of the flattened field.
+/// serde_with::flattened_maybe!(deserialize_t, "t");
+///
+/// # fn main() {
+/// // Supports both flattened
+/// let j = r#" {"i":1} "#;
+/// assert!(serde_json::from_str::<S>(j).is_ok());
+///
+/// // and non-flattened versions.
+/// let j = r#" {"t":{"i":1}} "#;
+/// assert!(serde_json::from_str::<S>(j).is_ok());
+///
+/// // Ensure that the value is given
+/// let j = r#" {} "#;
+/// assert!(serde_json::from_str::<S>(j).is_err());
+///
+/// // and only occurs once, not multiple times.
+/// let j = r#" {"i":1,"t":{"i":1}} "#;
+/// assert!(serde_json::from_str::<S>(j).is_err());
+/// # }
+/// ```
+#[macro_export]
+macro_rules! flattened_maybe {
+ ($fn:ident, $field:literal) => {
+ fn $fn<'de, T, D>(deserializer: D) -> ::std::result::Result<T, D::Error>
+ where
+ T: $crate::serde::Deserialize<'de>,
+ D: $crate::serde::Deserializer<'de>,
+ {
+ use ::std::{
+ option::Option::{self, None, Some},
+ result::Result::{self, Err, Ok},
+ };
+ use $crate::serde;
+
+ #[derive($crate::serde::Deserialize)]
+ #[serde(crate = "serde")]
+ pub struct Both<T> {
+ #[serde(flatten)]
+ flat: Option<T>,
+ #[serde(rename = $field)]
+ not_flat: Option<T>,
+ }
+
+ let both: Both<T> = $crate::serde::Deserialize::deserialize(deserializer)?;
+ match (both.flat, both.not_flat) {
+ (Some(t), None) | (None, Some(t)) => Ok(t),
+ (None, None) => Err($crate::serde::de::Error::missing_field($field)),
+ (Some(_), Some(_)) => Err($crate::serde::de::Error::custom(concat!(
+ "`",
+ $field,
+ "` is both flattened and not"
+ ))),
+ }
+ }
+ };
+}
diff --git a/third_party/rust/serde_with/src/formats.rs b/third_party/rust/serde_with/src/formats.rs
new file mode 100644
index 0000000000..2d7aaa6965
--- /dev/null
+++ b/third_party/rust/serde_with/src/formats.rs
@@ -0,0 +1,96 @@
+//! Specify the format and how lenient the deserialization is
+
+use alloc::string::String;
+
+/// Specify how to serialize/deserialize a type
+///
+/// The format specifier allows to configure how a value is serialized/deserialized.
+/// For example, you can serialize a timestamp as an integer using the UNIX epoch, as a string containing an integer, or as a string using ISO 8601.
+/// This [`Format`] traits allows more flexibility in configuring the format without the need to create a new type for each case.
+pub trait Format {}
+
+macro_rules! impl_format {
+ ($(#[$attr:meta] $t:ty)*) => {
+ $(
+ #[$attr]
+ impl Format for $t {}
+ )*
+ };
+}
+macro_rules! create_format {
+ ($(#[$attr:meta] $t:ident)*) => {
+ $(
+ #[$attr]
+ #[derive(Copy, Clone, Debug, Default)]
+ pub struct $t;
+ impl_format!(#[$attr] $t);
+ )*
+ };
+}
+impl_format!(
+ /// Serialize into an i8
+ i8
+ /// Serialize into a u8
+ u8
+ /// Serialize into an i16
+ i16
+ /// Serialize into a u16
+ u16
+ /// Serialize into an i32
+ i32
+ /// Serialize into a u32
+ u32
+ /// Serialize into an i64
+ i64
+ /// Serialize into a u64
+ u64
+
+ /// Serialize into a f32
+ f32
+ /// Serialize into a f64
+ f64
+
+ /// Serialize into a bool
+ bool
+
+ /// Serialize into a String
+ String
+);
+serde::serde_if_integer128!(impl_format!(
+ /// Serialize into an i128
+ i128
+ /// Serialize into a u128
+ u128
+););
+
+create_format!(
+ /// Use uppercase characters
+ Uppercase
+ /// Use lowercase characters
+ Lowercase
+
+ /// Use in combination with [`OneOrMany`](crate::OneOrMany). Emit single element for lists of size 1.
+ PreferOne
+ /// Use in combination with [`OneOrMany`](crate::OneOrMany). Always emit the list form.
+ PreferMany
+
+ /// Emit padding during serialization.
+ Padded
+ /// Do not emit padding during serialization.
+ Unpadded
+);
+
+/// Specify how lenient the deserialization process should be
+///
+/// Formats which make use of this trait should specify how it affects the deserialization behavior.
+pub trait Strictness {}
+
+/// Use strict deserialization behavior, see [`Strictness`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Strict;
+impl Strictness for Strict {}
+
+/// Use a flexible deserialization behavior, see [`Strictness`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Flexible;
+impl Strictness for Flexible {}
diff --git a/third_party/rust/serde_with/src/guide.md b/third_party/rust/serde_with/src/guide.md
new file mode 100644
index 0000000000..9eb80dd915
--- /dev/null
+++ b/third_party/rust/serde_with/src/guide.md
@@ -0,0 +1,144 @@
+# `serde_with` User Guide
+
+This crate provides helper functions to extend and change how [`serde`] serializes different data types.
+For example, you can serialize [a map as a sequence of tuples][crate::guide::serde_as#maps-to-vec-of-tuples], serialize [using the `Display` and `FromStr` traits][`DisplayFromStr`], or serialize [an empty `String` like `None`][NoneAsEmptyString].
+`serde_with` covers types from the Rust Standard Library and some common crates like [`chrono`][serde_with_chrono].
+
+[**A list of all supported transformations is available on this page.**](crate::guide::serde_as_transformations)
+
+The crate offers four types of functionality.
+
+## 1. A more flexible and composable replacement for the with annotation, called `serde_as` *(v1.5.0+)*
+
+This is an alternative to [serde's with-annotation][with-annotation], which adds flexibility and composability to the scheme.
+The main downside is that it work with fewer types than [with-annotations][with-annotation].
+However, all types from the Rust Standard Library should be supported in all combinations and any missing entry is a bug.
+
+The `serde_as` scheme is based on two new traits: [`SerializeAs`] and [`DeserializeAs`].
+[Check out the detailed page about `serde_as` and the available features.](crate::guide::serde_as)
+
+### Example
+
+```rust
+# use serde::{Deserialize, Serialize};
+# use serde_with::{serde_as, DisplayFromStr};
+# use std::collections::HashMap;
+# use std::net::Ipv4Addr;
+#
+#[serde_as]
+# #[derive(Debug, PartialEq, Eq)]
+#[derive(Deserialize, Serialize)]
+struct Data {
+ // Type does not implement Serialize or Deserialize
+ #[serde_as(as = "DisplayFromStr")]
+ address: Ipv4Addr,
+ // Treat the Vec like a map with duplicates
+ // Convert u32 into a String and keep the String the same type
+ #[serde_as(as = "HashMap<DisplayFromStr, _>")]
+ vec_as_map: Vec<(u32, String)>,
+}
+
+let data = Data {
+ address: Ipv4Addr::new(192, 168, 0, 1),
+ vec_as_map: vec![
+ (123, "Hello".into()),
+ (456, "World".into()),
+ (123, "Hello".into()),
+ ],
+};
+
+let json = r#"{
+ "address": "192.168.0.1",
+ "vec_as_map": {
+ "123": "Hello",
+ "456": "World",
+ "123": "Hello"
+ }
+}"#;
+
+// Test Serialization
+assert_eq!(json, serde_json::to_string_pretty(&data).unwrap());
+// Test Deserialization
+assert_eq!(data, serde_json::from_str(json).unwrap());
+```
+
+## 2. Integration with serde's with-annotation
+
+[serde's with-annotation][with-annotation] allows specifying a different serialization or deserialization function for a field.
+It is useful to adapt the serialization of existing types to the requirements of a protocol.
+Most modules in this crate can be used together with the with-annotation.
+
+The annotation approach has one big drawback, in that it is very inflexible.
+It allows specifying arbitrary serialization code, but the code has to perform the correct transformations.
+It is not possible to combine multiple of those functions.
+One common use case for this is the serialization of collections like `Vec`.
+If you have a field of type `T`, you can apply the with-annotation, but if you have a field of type `Vec<T>`, there is no way to re-use the same functions for the with-annotation.
+This inflexibility is fixed in the `serde_as` scheme presented above.
+
+The example shows a similar setup as in the `serde_as` example above, but using the with-annotation.
+
+### Example
+
+```rust
+# use serde::{Deserialize, Serialize};
+# use std::net::Ipv4Addr;
+#
+# #[derive(Debug, PartialEq, Eq)]
+#[derive(Deserialize, Serialize)]
+struct Data {
+ // Type does not implement Serialize or Deserialize
+ #[serde(with = "serde_with::rust::display_fromstr")]
+ address: Ipv4Addr,
+ // Treat the Vec like a map with duplicates
+ #[serde(with = "serde_with::rust::tuple_list_as_map")]
+ vec_as_map: Vec<(String, u32)>,
+}
+
+let data = Data {
+ address: Ipv4Addr::new(192, 168, 0, 1),
+ vec_as_map: vec![
+ ("Hello".into(), 123),
+ ("World".into(), 456),
+ ("Hello".into(), 123),
+ ],
+};
+
+let json = r#"{
+ "address": "192.168.0.1",
+ "vec_as_map": {
+ "Hello": 123,
+ "World": 456,
+ "Hello": 123
+ }
+}"#;
+
+// Test Serialization
+assert_eq!(json, serde_json::to_string_pretty(&data).unwrap());
+// Test Deserialization
+assert_eq!(data, serde_json::from_str(json).unwrap());
+```
+
+## 3. proc-macros to make it easier to use both above parts
+
+The proc-macros are an optional addition and improve the user experience for common tasks.
+We have already seen how the `serde_as` attribute is used to define the serialization instructions.
+
+The proc-macro attributes are defined in the [`serde_with_macros`] crate and re-exported from the root of this crate.
+The proc-macros are optional, but enabled by default.
+For further details, please refer to the documentation of each proc-macro.
+
+## 4. Derive macros to implement `Deserialize` and `Serialize`
+
+The derive macros work similar to the serde provided ones, but they do implement other de/serialization schemes.
+For example, the derives [`DeserializeFromStr`] and [`SerializeDisplay`] require that the type also implement [`FromStr`] and [`Display`] and de/serializes from/to a string instead of the usual way of iterating over all fields.
+
+## Migrating from the with-annotations to `serde_as`
+
+Each old style module explains how it can be converted to `serde_as`.
+Not all modules have such a description since not all are migrated and some are hard to implement in the `serde_as` system.
+
+[`Display`]: std::fmt::Display
+[`FromStr`]: std::str::FromStr
+[`serde_with_macros`]: serde_with_macros
+[serde_with_chrono]: crate::chrono
+[with-annotation]: https://serde.rs/field-attrs.html#with
diff --git a/third_party/rust/serde_with/src/guide/feature_flags.md b/third_party/rust/serde_with/src/guide/feature_flags.md
new file mode 100644
index 0000000000..9e80177ad2
--- /dev/null
+++ b/third_party/rust/serde_with/src/guide/feature_flags.md
@@ -0,0 +1,62 @@
+# Available Feature Flags
+
+This crate has the following features which can be enabled.
+Each entry will explain the feature in more detail.
+
+1. [`base64`](#base64)
+2. [`chrono`](#chrono)
+3. [`guide`](#guide)
+4. [`hex`](#hex)
+5. [`indexmap`](#indexmap)
+6. [`json`](#json)
+7. [`macros`](#macros)
+8. [`time_0_3`](#time_0_3)
+
+## `base64`
+
+The `base64` feature enables serializing data in base64 format.
+
+This pulls in `base64` as a dependency.
+
+## `chrono`
+
+The `chrono` feature enables integration of `chrono` specific conversions.
+This includes support for the timestamp and duration types.
+
+This pulls in `chrono` as a dependency.
+
+## `guide`
+
+The `guide` feature enables inclusion of this user guide.
+The feature only changes the rustdoc output and enables no other effects.
+
+## `hex`
+
+The `hex` feature enables serializing data in hex format.
+
+This pulls in `hex` as a dependency.
+
+## `indexmap`
+
+The `indexmap` feature enables implementations of `indexmap` specific checks.
+This includes support for checking duplicate keys
+
+## `json`
+
+The `json` features enables JSON conversions from the `json` module.
+
+This pulls in `serde_json` as a dependency.
+
+## `macros`
+
+The `macros` features enables all helper macros and derives.
+It is enabled by default, since the macros provide a usability benefit, especially for `serde_as`.
+
+This pulls in `serde_with_macros` as a dependency.
+
+## `time_0_3`
+
+The `time_0_3` enables integration of `time` v0.3 specific conversions.
+This includes support for the timestamp and duration types.
+
+This pulls in `time` v0.3 as a dependency.
diff --git a/third_party/rust/serde_with/src/guide/serde_as.md b/third_party/rust/serde_with/src/guide/serde_as.md
new file mode 100644
index 0000000000..76275f0047
--- /dev/null
+++ b/third_party/rust/serde_with/src/guide/serde_as.md
@@ -0,0 +1,332 @@
+# `serde_as` Annotation
+
+This is an alternative to serde's with-annotation.
+It is more flexible and composable, but work with fewer types.
+
+The scheme is based on two new traits, [`SerializeAs`] and [`DeserializeAs`], which need to be implemented by all types which want to be compatible with `serde_as`.
+The proc-macro attribute [`#[serde_as]`][crate::serde_as] exists as a usability boost for users.
+The basic design of `serde_as` was developed by [@markazmierczak](https://github.com/markazmierczak).
+
+This page contains some general advice on the usage of `serde_as` and on implementing the necessary traits.
+[**A list of all supported transformations enabled by `serde_as` is available on this page.**](crate::guide::serde_as_transformations)
+
+1. [Switching from serde's with to `serde_as`](#switching-from-serdes-with-to-serde_as)
+ 1. [Deserializing Optional Fields](#deserializing-optional-fields)
+ 2. [Gating `serde_as` on Features](#gating-serde_as-on-features)
+2. [Implementing `SerializeAs` / `DeserializeAs`](#implementing-serializeas--deserializeas)
+ 1. [Using `#[serde_as]` on types without `SerializeAs` and `Serialize` implementations](#using-serde_as-on-types-without-serializeas-and-serialize-implementations)
+ 2. [Using `#[serde_as]` with serde's remote derives](#using-serde_as-with-serdes-remote-derives)
+3. [Re-exporting `serde_as`](#re-exporting-serde_as)
+
+## Switching from serde's with to `serde_as`
+
+For the user, the main difference is that instead of
+
+```rust,ignore
+#[serde(with = "...")]
+```
+
+you now have to write
+
+```rust,ignore
+#[serde_as(as = "...")]
+```
+
+and place the `#[serde_as]` attribute *before* the `#[derive]` attribute.
+You still need the `#[derive(Serialize, Deserialize)]` on the struct/enum.
+
+All together, this looks like:
+
+```rust
+use serde::{Deserialize, Serialize};
+use serde_with::{serde_as, DisplayFromStr};
+
+#[serde_as]
+#[derive(Serialize, Deserialize)]
+struct A {
+ #[serde_as(as = "DisplayFromStr")]
+ mime: mime::Mime,
+}
+```
+
+The main advantage is that you can compose `serde_as` stuff, which is impossible with the with-annotation.
+For example, the `mime` field from above could be nested in one or more data structures:
+
+```rust
+# use std::collections::BTreeMap;
+# use serde::{Deserialize, Serialize};
+# use serde_with::{serde_as, DisplayFromStr};
+#
+#[serde_as]
+#[derive(Serialize, Deserialize)]
+struct A {
+ #[serde_as(as = "Option<BTreeMap<_, Vec<DisplayFromStr>>>")]
+ mime: Option<BTreeMap<String, Vec<mime::Mime>>>,
+}
+```
+
+### Deserializing Optional Fields
+
+During deserialization, serde treats fields of `Option<T>` as optional and does not require them to be present.
+This breaks when adding either the `serde_as` annotation or serde's `with` annotation.
+The default behavior can be restored by adding serde's `default` attribute.
+
+```rust
+# use serde::{Deserialize, Serialize};
+# use serde_with::{serde_as, DisplayFromStr};
+#
+#[serde_as]
+#[derive(Serialize, Deserialize)]
+struct A {
+ #[serde_as(as = "Option<DisplayFromStr>")]
+ // Allows deserialization without providing a value for `val`
+ #[serde(default)]
+ val: Option<u32>,
+}
+```
+
+In the future, this behavior might change and `default` would be applied on `Option<T>` fields.
+You can add your feedback at [serde_with#185].
+
+### Gating `serde_as` on Features
+
+Gating `serde_as` behind optional features is currently not supported.
+More details can be found in the corresponding issue [serde_with#355].
+
+```rust,ignore
+#[cfg_attr(feature="serde" ,serde_as)]
+#[cfg_attr(feature="serde", derive(Serialize, Deserialize))]
+struct StructC {
+ #[cfg_attr(feature="serde" ,serde_as(as = "Vec<(_, _)>"))]
+ map: HashMap<(i32,i32), i32>,
+}
+```
+
+The `serde_as` proc-macro attribute will not recognize the `serde_as` attribute on the field and will not perform the necessary translation steps.
+The problem can be avoided by forcing Rust to evaluate all cfg-expressions before running `serde_as`.
+This is possible with the `#[cfg_eval]` attribute, which is considered for stabilization ([rust#82679], [rust#87221]).
+
+As a workaround, it is possible to remove the `serde_as` proc-macro attribute and perform the transformation manually.
+The transformation steps are listed in the [`serde_as`] documentations.
+For the example above, this means to replace the field attribute with:
+
+```rust,ignore
+use serde_with::{As, Same};
+
+#[cfg_attr(feature="serde", serde(with = "As::<Vec<(Same, Same)>>"))]
+map: HashMap<(i32,i32), i32>,
+```
+
+[rust#82679]: https://github.com/rust-lang/rust/issues/82679
+[rust#87221]: https://github.com/rust-lang/rust/pull/87221
+[serde_with#355]: https://github.com/jonasbb/serde_with/issues/355
+
+## Implementing `SerializeAs` / `DeserializeAs`
+
+You can support [`SerializeAs`] / [`DeserializeAs`] on your own types too.
+Most "leaf" types do not need to implement these traits, since they are supported implicitly.
+"Leaf" type refers to types which directly serialize like plain data types.
+[`SerializeAs`] / [`DeserializeAs`] is very important for collection types, like `Vec` or `BTreeMap`, since they need special handling for the key/value de/serialization such that the conversions can be done on the key/values.
+You also find them implemented on the conversion types, such as the [`DisplayFromStr`] type.
+These make up the bulk of this crate and allow you to perform all the nice conversions to [hex strings], the [bytes to string converter], or [duration to UNIX epoch].
+
+In many cases, conversion is only required from one serializable type to another one, without requiring the full power of the `Serialize` or `Deserialize` traits.
+In these cases, the [`serde_conv!`] macro conveniently allows defining conversion types without the boilerplate.
+The documentation of [`serde_conv!`] contains more details how to use it.
+
+The trait documentations for [`SerializeAs`] and [`DeserializeAs`] describe in details how to implement them for container types like `Box` or `Vec` and other types.
+
+### Using `#[serde_as]` on types without `SerializeAs` and `Serialize` implementations
+
+The `SerializeAs` and `DeserializeAs` traits can easily be used together with types from other crates without running into orphan rule problems.
+This is a distinct advantage of the `serde_as` system.
+For this example we assume we have a type `RemoteType` from a dependency which does not implement `Serialize` nor `SerializeAs`.
+We assume we have a module containing a `serialize` and a `deserialize` function, which can be used in the `#[serde(with = "MODULE")]` annotation.
+You find an example in the [official serde documentation](https://serde.rs/custom-date-format.html).
+
+Our goal is to serialize this `Data` struct.
+Right now, we do not have anything we can use to replace `???` with, since `_` only works if `RemoteType` would implement `Serialize`, which it does not.
+
+```rust
+# #[cfg(FALSE)] {
+#[serde_as]
+#[derive(serde::Serialize)]
+struct Data {
+ #[serde_as(as = "Vec<???>")]
+ vec: Vec<RemoteType>,
+}
+# }
+```
+
+We need to create a new type for which we can implement `SerializeAs`, to replace the `???`.
+The `SerializeAs` implementation is **always** written for a local type.
+This allows it to seamlessly work with types from dependencies without running into orphan rule problems.
+
+```rust
+# #[cfg(FALSE)] {
+struct LocalType;
+
+impl SerializeAs<RemoteType> for LocalType {
+ fn serialize_as<S>(value: &RemoteType, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ MODULE::serialize(value, serializer)
+ }
+}
+
+impl<'de> DeserializeAs<'de, RemoteType> for LocalType {
+ fn deserialize_as<D>(deserializer: D) -> Result<RemoteType, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ MODULE::deserialize(deserializer)
+ }
+}
+# }
+```
+
+This is how the final implementation looks like.
+We assumed we have a module `MODULE` with a `serialize` function already, which we use here to provide the implementation.
+As can be seen, this is mostly boilerplate, since the most part is encapsulated in `$module::serialize`.
+The final `Data` struct will now look like:
+
+```rust
+# #[cfg(FALSE)] {
+#[serde_as]
+#[derive(serde::Serialize)]
+struct Data {
+ #[serde_as(as = "Vec<LocalType>")]
+ vec: Vec<RemoteType>,
+}
+# }
+```
+
+### Using `#[serde_as]` with serde's remote derives
+
+A special case of the above section is using it on remote derives.
+This is a special functionality of serde, where it derives the de/serialization code for a type from another crate if all fields are `pub`.
+You can find all the details in the [official serde documentation](https://serde.rs/remote-derive.html).
+
+```rust
+# #[cfg(FALSE)] {
+// Pretend that this is somebody else's crate, not a module.
+mod other_crate {
+ // Neither Serde nor the other crate provides Serialize and Deserialize
+ // impls for this struct.
+ pub struct Duration {
+ pub secs: i64,
+ pub nanos: i32,
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
+use other_crate::Duration;
+
+// Serde calls this the definition of the remote type. It is just a copy of the
+// remote data structure. The `remote` attribute gives the path to the actual
+// type we intend to derive code for.
+#[derive(serde::Serialize, serde::Deserialize)]
+#[serde(remote = "Duration")]
+struct DurationDef {
+ secs: i64,
+ nanos: i32,
+}
+# }
+```
+
+Our goal is now to use `Duration` within `serde_as`.
+We use the existing `DurationDef` type and its `serialize` and `deserialize` functions.
+We can write this implementation.
+The implementation for `DeserializeAs` works analogue.
+
+```rust
+# #[cfg(FALSE)] {
+impl SerializeAs<Duration> for DurationDef {
+ fn serialize_as<S>(value: &Duration, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ DurationDef::serialize(value, serializer)
+ }
+}
+# }
+```
+
+This now allows us to use `Duration` for serialization.
+
+```rust
+# #[cfg(FALSE)] {
+use other_crate::Duration;
+
+#[serde_as]
+#[derive(serde::Serialize)]
+struct Data {
+ #[serde_as(as = "Vec<DurationDef>")]
+ vec: Vec<Duration>,
+}
+# }
+```
+
+## Re-exporting `serde_as`
+
+If `serde_as` is being used in a context where the `serde_with` crate is not available from the root
+path, but is re-exported at some other path, the `crate = "..."` attribute argument should be used
+to specify its path. This may be the case if `serde_as` is being used in a procedural macro -
+otherwise, users of that macro would need to add `serde_with` to their own Cargo manifest.
+
+The `crate` argument will generally be used in conjunction with [`serde`'s own `crate` argument].
+
+For example, a type definition may be defined in a procedural macro:
+
+```rust,ignore
+// some_other_lib_derive/src/lib.rs
+
+use proc_macro::TokenStream;
+use quote::quote;
+
+#[proc_macro]
+pub fn define_some_type(_item: TokenStream) -> TokenStream {
+ let def = quote! {
+ #[serde(crate = "::some_other_lib::serde")]
+ #[::some_other_lib::serde_with::serde_as(crate = "::some_other_lib::serde_with")]
+ #[derive(::some_other_lib::serde::Deserialize)]
+ struct Data {
+ #[serde_as(as = "_")]
+ a: u32,
+ }
+ };
+
+ TokenStream::from(def)
+}
+```
+
+This can be re-exported through a library which also re-exports `serde` and `serde_with`:
+
+```rust,ignore
+// some_other_lib/src/lib.rs
+
+pub use serde;
+pub use serde_with;
+pub use some_other_lib_derive::define_some_type;
+```
+
+The procedural macro can be used by other crates without any additional imports:
+
+```rust,ignore
+// consuming_crate/src/main.rs
+
+some_other_lib::define_some_type!();
+```
+
+[`DeserializeAs`]: crate::DeserializeAs
+[`DisplayFromStr`]: crate::DisplayFromStr
+[`serde_as`]: crate::serde_as
+[`serde_conv!`]: crate::serde_conv!
+[`serde`'s own `crate` argument]: https://serde.rs/container-attrs.html#crate
+[`SerializeAs`]: crate::SerializeAs
+[bytes to string converter]: crate::BytesOrString
+[duration to UNIX epoch]: crate::DurationSeconds
+[hex strings]: crate::hex::Hex
+[serde_with#185]: https://github.com/jonasbb/serde_with/issues/185
diff --git a/third_party/rust/serde_with/src/guide/serde_as_transformations.md b/third_party/rust/serde_with/src/guide/serde_as_transformations.md
new file mode 100644
index 0000000000..9be67e154b
--- /dev/null
+++ b/third_party/rust/serde_with/src/guide/serde_as_transformations.md
@@ -0,0 +1,518 @@
+# De/Serialize Transformations Available
+
+This page lists the transformations implemented in this crate and supported by `serde_as`.
+
+1. [Base64 encode bytes](#base64-encode-bytes)
+2. [Big Array support](#big-array-support)
+3. [`bool` from integer](#bool-from-integer)
+4. [Borrow from the input for `Cow` type](#borrow-from-the-input-for-cow-type)
+5. [`Bytes` with more efficiency](#bytes-with-more-efficiency)
+6. [Convert to an intermediate type using `Into`](#convert-to-an-intermediate-type-using-into)
+7. [Convert to an intermediate type using `TryInto`](#convert-to-an-intermediate-type-using-tryinto)
+8. [`Default` from `null`](#default-from-null)
+9. [De/Serialize into `Vec`, ignoring errors](#deserialize-into-vec-ignoring-errors)
+10. [De/Serialize with `FromStr` and `Display`](#deserialize-with-fromstr-and-display)
+11. [`Duration` as seconds](#duration-as-seconds)
+12. [Hex encode bytes](#hex-encode-bytes)
+13. [Ignore deserialization errors](#ignore-deserialization-errors)
+14. [`Maps` to `Vec` of enums](#maps-to-vec-of-enums)
+15. [`Maps` to `Vec` of tuples](#maps-to-vec-of-tuples)
+16. [`NaiveDateTime` like UTC timestamp](#naivedatetime-like-utc-timestamp)
+17. [`None` as empty `String`](#none-as-empty-string)
+18. [One or many elements into `Vec`](#one-or-many-elements-into-vec)
+19. [Pick first successful deserialization](#pick-first-successful-deserialization)
+20. [Timestamps as seconds since UNIX epoch](#timestamps-as-seconds-since-unix-epoch)
+21. [Value into JSON String](#value-into-json-string)
+22. [`Vec` of tuples to `Maps`](#vec-of-tuples-to-maps)
+23. [Well-known time formats for `OffsetDateTime`](#well-known-time-formats-for-offsetdatetime)
+
+## Base64 encode bytes
+
+[`Base64`]
+
+Requires the `base64` feature.
+The character set and padding behavior can be configured.
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::base64::Base64")]
+value: Vec<u8>,
+#[serde_as(as = "Base64<Bcrypt, Unpadded>")]
+bcrypt_unpadded: Vec<u8>,
+
+// JSON
+"value": "SGVsbG8gV29ybGQ=",
+"bcrypt_unpadded": "QETqZE6eT07wZEO",
+```
+
+## Big Array support
+
+Support for arrays of arbitrary size.
+
+```ignore
+// Rust
+#[serde_as(as = "[[_; 64]; 33]")]
+value: [[u8; 64]; 33],
+
+// JSON
+"value": [[0,0,0,0,0,...], [0,0,0,...], ...],
+```
+
+## `bool` from integer
+
+Deserialize an integer and convert it into a `bool`.
+[`BoolFromInt<Strict>`] (default) deserializes 0 to `false` and `1` to `true`, other numbers are errors.
+[`BoolFromInt<Flexible>`] deserializes any non-zero as `true`.
+Serialization only emits 0/1.
+
+```ignore
+// Rust
+#[serde_as(as = "BoolFromInt")] // BoolFromInt<Strict>
+b: bool,
+
+// JSON
+"b": 1,
+```
+
+## Borrow from the input for `Cow` type
+
+The types `Cow<'_, str>`, `Cow<'_, [u8]>`, or `Cow<'_, [u8; N]>` can borrow from the input, avoiding extra copies.
+
+```ignore
+// Rust
+#[serde_as(as = "BorrowCow")]
+value: Cow<'a, str>,
+
+// JSON
+"value": "foobar",
+```
+
+## `Bytes` with more efficiency
+
+[`Bytes`]
+
+More efficient serialization for byte slices and similar.
+
+```ignore
+// Rust
+#[serde_as(as = "Bytes")]
+value: Vec<u8>,
+
+// JSON
+"value": [0, 1, 2, 3, ...],
+```
+
+## Convert to an intermediate type using `Into`
+
+[`FromInto`]
+
+```ignore
+// Rust
+#[serde_as(as = "FromInto<(u8, u8, u8)>")]
+value: Rgb,
+
+impl From<(u8, u8, u8)> for Rgb { ... }
+impl From<Rgb> for (u8, u8, u8) { ... }
+
+// JSON
+"value": [128, 64, 32],
+```
+
+## Convert to an intermediate type using `TryInto`
+
+[`TryFromInto`]
+
+```ignore
+// Rust
+#[serde_as(as = "TryFromInto<i8>")]
+value: u8,
+
+// JSON
+"value": 127,
+```
+
+## `Default` from `null`
+
+[`DefaultOnNull`]
+
+```ignore
+// Rust
+#[serde_as(as = "DefaultOnNull")]
+value: u32,
+#[serde_as(as = "DefaultOnNull<DisplayFromStr>")]
+value2: u32,
+
+// JSON
+"value": 123,
+"value2": "999",
+
+// Deserializes null into the Default value, i.e.,
+null => 0
+```
+
+## De/Serialize into `Vec`, ignoring errors
+
+[`VecSkipError`]
+
+For formats with heterogenous-typed sequences, we can collect only the deserializable elements.
+This is also useful for unknown enum variants.
+
+```ignore
+#[derive(serde::Deserialize)]
+enum Color {
+ Red,
+ Green,
+ Blue,
+}
+
+// JSON
+"colors": ["Blue", "Yellow", "Green"],
+
+// Rust
+#[serde_as(as = "VecSkipError<_>")]
+colors: Vec<Color>,
+
+// => vec![Blue, Green]
+```
+
+## De/Serialize with `FromStr` and `Display`
+
+Useful if a type implements `FromStr` / `Display` but not `Deserialize` / `Serialize`.
+
+[`DisplayFromStr`]
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::DisplayFromStr")]
+value: u128,
+#[serde_as(as = "serde_with::DisplayFromStr")]
+mime: mime::Mime,
+
+// JSON
+"value": "340282366920938463463374607431768211455",
+"mime": "text/*",
+```
+
+## `Duration` as seconds
+
+[`DurationSeconds`]
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::DurationSeconds<u64>")]
+value: Duration,
+
+// JSON
+"value": 86400,
+```
+
+[`DurationSecondsWithFrac`] supports subsecond precision:
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::DurationSecondsWithFrac<f64>")]
+value: Duration,
+
+// JSON
+"value": 1.234,
+```
+
+Different serialization formats are possible:
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::DurationSecondsWithFrac<String>")]
+value: Duration,
+
+// JSON
+"value": "1.234",
+```
+
+The same conversions are also implemented for [`chrono::Duration`] with the `chrono` feature.
+
+The same conversions are also implemented for [`time::Duration`] with the `time_0_3` feature.
+
+## Hex encode bytes
+
+[`Hex`]
+
+Requires the `hex` feature.
+The hex string can use upper- and lowercase characters.
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::hex::Hex")]
+lowercase: Vec<u8>,
+#[serde_as(as = "serde_with::hex::Hex<serde_with::formats::Uppercase>")]
+uppercase: Vec<u8>,
+
+// JSON
+"lowercase": "deadbeef",
+"uppercase": "DEADBEEF",
+```
+
+## Ignore deserialization errors
+
+Check the documentation for [`DefaultOnError`].
+
+## `Maps` to `Vec` of enums
+
+[`EnumMap`]
+
+Combine multiple enum values into a single map.
+The key is the enum variant name, and the value is the variant value.
+This only works with [*externally tagged*] enums, the default enum representation.
+Other forms cannot be supported.
+
+```ignore
+enum EnumValue {
+ Int(i32),
+ String(String),
+ Unit,
+ Tuple(i32, String),
+ Struct {
+ a: i32,
+ b: String,
+ },
+}
+
+// Rust
+struct VecEnumValues (
+ #[serde_as(as = "EnumMap")]
+ Vec<EnumValue>,
+);
+
+VecEnumValues(vec![
+ EnumValue::Int(123),
+ EnumValue::String("Foo".to_string()),
+ EnumValue::Unit,
+ EnumValue::Tuple(1, "Bar".to_string()),
+ EnumValue::Struct {
+ a: 666,
+ b: "Baz".to_string(),
+ },
+])
+
+// JSON
+{
+ "Int": 123,
+ "String": "Foo",
+ "Unit": null,
+ "Tuple": [
+ 1,
+ "Bar",
+ ],
+ "Struct": {
+ "a": 666,
+ "b": "Baz",
+ }
+}
+```
+
+[*externally tagged*]: https://serde.rs/enum-representations.html#externally-tagged
+
+## `Maps` to `Vec` of tuples
+
+```ignore
+// Rust
+#[serde_as(as = "Vec<(_, _)>")]
+value: HashMap<String, u32>, // also works with BTreeMap
+
+// JSON
+"value": [
+ ["hello", 1],
+ ["world", 2]
+],
+```
+
+The [inverse operation](#vec-of-tuples-to-maps) is also available.
+
+## `NaiveDateTime` like UTC timestamp
+
+Requires the `chrono` feature.
+
+```ignore
+// Rust
+#[serde_as(as = "chrono::DateTime<chrono::Utc>")]
+value: chrono::NaiveDateTime,
+
+// JSON
+"value": "1994-11-05T08:15:30Z",
+ ^ Pretend DateTime is UTC
+```
+
+## `None` as empty `String`
+
+[`NoneAsEmptyString`]
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::NoneAsEmptyString")]
+value: Option<String>,
+
+// JSON
+"value": "", // converts to None
+
+"value": "Hello World!", // converts to Some
+```
+
+## One or many elements into `Vec`
+
+[`OneOrMany`]
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::OneOrMany<_>")]
+value: Vec<String>,
+
+// JSON
+"value": "", // Deserializes single elements
+
+"value": ["Hello", "World!"], // or lists of many
+```
+
+## Pick first successful deserialization
+
+[`PickFirst`]
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::PickFirst<(_, serde_with::DisplayFromStr)>")]
+value: u32,
+
+// JSON
+// serialize into
+"value": 666,
+// deserialize from either
+"value": 666,
+"value": "666",
+```
+
+## Timestamps as seconds since UNIX epoch
+
+[`TimestampSeconds`]
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::TimestampSeconds<i64>")]
+value: SystemTime,
+
+// JSON
+"value": 86400,
+```
+
+[`TimestampSecondsWithFrac`] supports subsecond precision:
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::TimestampSecondsWithFrac<f64>")]
+value: SystemTime,
+
+// JSON
+"value": 1.234,
+```
+
+Different serialization formats are possible:
+
+```ignore
+// Rust
+#[serde_as(as = "serde_with::TimestampSecondsWithFrac<String>")]
+value: SystemTime,
+
+// JSON
+"value": "1.234",
+```
+
+The same conversions are also implemented for [`chrono::DateTime<Utc>`], [`chrono::DateTime<Local>`], and [`chrono::NaiveDateTime`] with the `chrono` feature.
+
+The conversions are availble for [`time::OffsetDateTime`] and [`time::PrimitiveDateTime`] with the `time_0_3` feature enabled.
+
+## Value into JSON String
+
+Some JSON APIs are weird and return a JSON encoded string in a JSON response
+
+[`JsonString`]
+
+Requires the `json` feature.
+
+```ignore
+// Rust
+#[derive(Deserialize, Serialize)]
+struct OtherStruct {
+ value: usize,
+}
+
+#[serde_as(as = "serde_with::json::JsonString")]
+value: OtherStruct,
+
+// JSON
+"value": "{\"value\":5}",
+```
+
+## `Vec` of tuples to `Maps`
+
+```ignore
+// Rust
+#[serde_as(as = "HashMap<_, _>")] // also works with BTreeMap
+value: Vec<(String, u32)>,
+
+// JSON
+"value": {
+ "hello": 1,
+ "world": 2
+},
+```
+
+This operation is also available for other sequence types.
+This includes `BinaryHeap<(K, V)>`, `BTreeSet<(K, V)>`, `HashSet<(K, V)>`, `LinkedList<(K, V)>`, `VecDeque<(K, V)>`, `Option<(K, V)>` and `[(K, V); N]` for all sizes of N.
+
+The [inverse operation](#maps-to-vec-of-tuples) is also available.
+
+## Well-known time formats for `OffsetDateTime`
+
+[`time::OffsetDateTime`] can be serialized in string format in different well-known formats.
+Two formats are supported, [`time::format_description::well_known::Rfc2822`] and [`time::format_description::well_known::Rfc3339`].
+
+```ignore
+// Rust
+#[serde_as(as = "time::format_description::well_known::Rfc2822")]
+rfc_2822: OffsetDateTime,
+#[serde_as(as = "time::format_description::well_known::Rfc3339")]
+rfc_3339: OffsetDateTime,
+
+// JSON
+"rfc_2822": "Fri, 21 Nov 1997 09:55:06 -0600",
+"rfc_3339": "1997-11-21T09:55:06-06:00",
+```
+
+These conversions are availble with the `time_0_3` feature flag.
+
+[`Base64`]: crate::base64::Base64
+[`BoolFromInt<Flexible>`]: crate::BoolFromInt
+[`BoolFromInt<Strict>`]: crate::BoolFromInt
+[`Bytes`]: crate::Bytes
+[`chrono::DateTime<Local>`]: chrono_crate::DateTime
+[`chrono::DateTime<Utc>`]: chrono_crate::DateTime
+[`chrono::Duration`]: https://docs.rs/chrono/latest/chrono/struct.Duration.html
+[`chrono::NaiveDateTime`]: chrono_crate::NaiveDateTime
+[`DefaultOnError`]: crate::DefaultOnError
+[`DefaultOnNull`]: crate::DefaultOnNull
+[`DisplayFromStr`]: crate::DisplayFromStr
+[`DurationSeconds`]: crate::DurationSeconds
+[`DurationSecondsWithFrac`]: crate::DurationSecondsWithFrac
+[`EnumMap`]: crate::EnumMap
+[`FromInto`]: crate::FromInto
+[`Hex`]: crate::hex::Hex
+[`JsonString`]: crate::json::JsonString
+[`NoneAsEmptyString`]: crate::NoneAsEmptyString
+[`OneOrMany`]: crate::OneOrMany
+[`PickFirst`]: crate::PickFirst
+[`time::Duration`]: time_0_3::Duration
+[`time::format_description::well_known::Rfc2822`]: time_0_3::format_description::well_known::Rfc2822
+[`time::format_description::well_known::Rfc3339`]: time_0_3::format_description::well_known::Rfc3339
+[`time::OffsetDateTime`]: time_0_3::OffsetDateTime
+[`time::PrimitiveDateTime`]: time_0_3::PrimitiveDateTime
+[`TimestampSeconds`]: crate::TimestampSeconds
+[`TimestampSecondsWithFrac`]: crate::TimestampSecondsWithFrac
+[`TryFromInto`]: crate::TryFromInto
+[`VecSkipError`]: crate::VecSkipError
diff --git a/third_party/rust/serde_with/src/hex.rs b/third_party/rust/serde_with/src/hex.rs
new file mode 100644
index 0000000000..1937e35394
--- /dev/null
+++ b/third_party/rust/serde_with/src/hex.rs
@@ -0,0 +1,155 @@
+//! De/Serialization of hexadecimal encoded bytes
+//!
+//! This modules is only available when using the `hex` feature of the crate.
+//!
+//! Please check the documentation on the [`Hex`] type for details.
+
+use crate::{
+ de::DeserializeAs,
+ formats::{Format, Lowercase, Uppercase},
+ ser::SerializeAs,
+};
+use alloc::{borrow::Cow, format, vec::Vec};
+use core::{
+ convert::{TryFrom, TryInto},
+ marker::PhantomData,
+};
+use serde::{de::Error, Deserialize, Deserializer, Serializer};
+
+/// Serialize bytes as a hex string
+///
+/// The type serializes a sequence of bytes as a hexadecimal string.
+/// It works on any type implementing `AsRef<[u8]>` for serialization and `TryFrom<Vec<u8>>` for deserialization.
+///
+/// The format type parameter specifies if the hex string should use lower- or uppercase characters.
+/// Valid options are the types [`Lowercase`] and [`Uppercase`].
+/// Deserialization always supports lower- and uppercase characters, even mixed in one string.
+///
+/// # Example
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::serde_as;
+/// #
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq, Eq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct BytesLowercase(
+/// // Equivalent to serde_with::hex::Hex<serde_with::formats::Lowercase>
+/// #[serde_as(as = "serde_with::hex::Hex")]
+/// Vec<u8>
+/// );
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq, Eq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct BytesUppercase(
+/// #[serde_as(as = "serde_with::hex::Hex<serde_with::formats::Uppercase>")]
+/// Vec<u8>
+/// );
+///
+/// let b = b"Hello World!";
+///
+/// // Hex with lowercase letters
+/// assert_eq!(
+/// json!("48656c6c6f20576f726c6421"),
+/// serde_json::to_value(BytesLowercase(b.to_vec())).unwrap()
+/// );
+/// // Hex with uppercase letters
+/// assert_eq!(
+/// json!("48656C6C6F20576F726C6421"),
+/// serde_json::to_value(BytesUppercase(b.to_vec())).unwrap()
+/// );
+///
+/// // Serialization always work from lower- and uppercase characters, even mixed case.
+/// assert_eq!(
+/// BytesLowercase(vec![0x00, 0xaa, 0xbc, 0x99, 0xff]),
+/// serde_json::from_value(json!("00aAbc99FF")).unwrap()
+/// );
+/// assert_eq!(
+/// BytesUppercase(vec![0x00, 0xaa, 0xbc, 0x99, 0xff]),
+/// serde_json::from_value(json!("00aAbc99FF")).unwrap()
+/// );
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq, Eq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct ByteArray(
+/// // Equivalent to serde_with::hex::Hex<serde_with::formats::Lowercase>
+/// #[serde_as(as = "serde_with::hex::Hex")]
+/// [u8; 12]
+/// );
+///
+/// let b = b"Hello World!";
+///
+/// assert_eq!(
+/// json!("48656c6c6f20576f726c6421"),
+/// serde_json::to_value(ByteArray(b.clone())).unwrap()
+/// );
+///
+/// // Serialization always work from lower- and uppercase characters, even mixed case.
+/// assert_eq!(
+/// ByteArray([0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0xaa, 0xbc, 0x99, 0xff]),
+/// serde_json::from_value(json!("0011223344556677aAbc99FF")).unwrap()
+/// );
+///
+/// // Remember that the conversion may fail. (The following errors are specific to fixed-size arrays)
+/// let error_result: Result<ByteArray, _> = serde_json::from_value(json!("42")); // Too short
+/// error_result.unwrap_err();
+///
+/// let error_result: Result<ByteArray, _> =
+/// serde_json::from_value(json!("000000000000000000000000000000")); // Too long
+/// error_result.unwrap_err();
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Hex<FORMAT: Format = Lowercase>(PhantomData<FORMAT>);
+
+impl<T> SerializeAs<T> for Hex<Lowercase>
+where
+ T: AsRef<[u8]>,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_str(&hex::encode(source))
+ }
+}
+
+impl<T> SerializeAs<T> for Hex<Uppercase>
+where
+ T: AsRef<[u8]>,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_str(&hex::encode_upper(source))
+ }
+}
+
+impl<'de, T, FORMAT> DeserializeAs<'de, T> for Hex<FORMAT>
+where
+ T: TryFrom<Vec<u8>>,
+ FORMAT: Format,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ <Cow<'de, str> as Deserialize<'de>>::deserialize(deserializer)
+ .and_then(|s| hex::decode(&*s).map_err(Error::custom))
+ .and_then(|vec: Vec<u8>| {
+ let length = vec.len();
+ vec.try_into().map_err(|_e: T::Error| {
+ Error::custom(format!(
+ "Can't convert a Byte Vector of length {} to the output type.",
+ length
+ ))
+ })
+ })
+ }
+}
diff --git a/third_party/rust/serde_with/src/json.rs b/third_party/rust/serde_with/src/json.rs
new file mode 100644
index 0000000000..699d31c8d2
--- /dev/null
+++ b/third_party/rust/serde_with/src/json.rs
@@ -0,0 +1,150 @@
+//! De/Serialization of JSON
+//!
+//! This modules is only available when using the `json` feature of the crate.
+
+use crate::{de::DeserializeAs, ser::SerializeAs};
+use serde::{de::DeserializeOwned, Deserializer, Serialize, Serializer};
+
+/// Serialize value as string containing JSON
+///
+/// The same functionality is also available as [`serde_with::json::JsonString`][crate::json::JsonString] compatible with the `serde_as`-annotation.
+///
+/// # Examples
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// #
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde(with = "serde_with::json::nested")]
+/// other_struct: B,
+/// }
+/// #[derive(Deserialize, Serialize)]
+/// struct B {
+/// value: usize,
+/// }
+///
+/// let v: A = serde_json::from_str(r#"{"other_struct":"{\"value\":5}"}"#).unwrap();
+/// assert_eq!(5, v.other_struct.value);
+///
+/// let x = A {
+/// other_struct: B { value: 10 },
+/// };
+/// assert_eq!(
+/// r#"{"other_struct":"{\"value\":10}"}"#,
+/// serde_json::to_string(&x).unwrap()
+/// );
+/// ```
+pub mod nested {
+ use core::{fmt, marker::PhantomData};
+ use serde::{
+ de::{DeserializeOwned, Deserializer, Error, Visitor},
+ ser::{self, Serialize, Serializer},
+ };
+
+ /// Deserialize value from a string which is valid JSON
+ pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ T: DeserializeOwned,
+ {
+ #[derive(Default)]
+ struct Helper<S: DeserializeOwned>(PhantomData<S>);
+
+ impl<'de, S> Visitor<'de> for Helper<S>
+ where
+ S: DeserializeOwned,
+ {
+ type Value = S;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(formatter, "valid json object")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<S, E>
+ where
+ E: Error,
+ {
+ serde_json::from_str(value).map_err(Error::custom)
+ }
+ }
+
+ deserializer.deserialize_str(Helper(PhantomData))
+ }
+
+ /// Serialize value as string containing JSON
+ ///
+ /// # Errors
+ ///
+ /// Serialization can fail if `T`'s implementation of `Serialize` decides to
+ /// fail, or if `T` contains a map with non-string keys.
+ pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: Serialize,
+ S: Serializer,
+ {
+ let s = serde_json::to_string(value).map_err(ser::Error::custom)?;
+ serializer.serialize_str(&*s)
+ }
+}
+
+/// Serialize value as string containing JSON
+///
+/// The same functionality is also available as [`serde_with::json::nested`][crate::json::nested] compatible with serde's with-annotation.
+///
+/// # Examples
+///
+/// ```
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::{serde_as, json::JsonString};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde_as(as = "JsonString")]
+/// other_struct: B,
+/// }
+/// #[derive(Deserialize, Serialize)]
+/// struct B {
+/// value: usize,
+/// }
+///
+/// let v: A = serde_json::from_str(r#"{"other_struct":"{\"value\":5}"}"#).unwrap();
+/// assert_eq!(5, v.other_struct.value);
+///
+/// let x = A {
+/// other_struct: B { value: 10 },
+/// };
+/// assert_eq!(
+/// r#"{"other_struct":"{\"value\":10}"}"#,
+/// serde_json::to_string(&x).unwrap()
+/// );
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct JsonString;
+
+impl<T> SerializeAs<T> for JsonString
+where
+ T: Serialize,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ crate::json::nested::serialize(source, serializer)
+ }
+}
+
+impl<'de, T> DeserializeAs<'de, T> for JsonString
+where
+ T: DeserializeOwned,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ crate::json::nested::deserialize(deserializer)
+ }
+}
diff --git a/third_party/rust/serde_with/src/lib.rs b/third_party/rust/serde_with/src/lib.rs
new file mode 100644
index 0000000000..6285a6f695
--- /dev/null
+++ b/third_party/rust/serde_with/src/lib.rs
@@ -0,0 +1,2034 @@
+#![warn(
+ clippy::semicolon_if_nothing_returned,
+ missing_copy_implementations,
+ // missing_crate_level_docs, not available in MSRV
+ missing_debug_implementations,
+ missing_docs,
+ rust_2018_idioms,
+ trivial_casts,
+ trivial_numeric_casts,
+ unused_extern_crates,
+ unused_import_braces,
+ unused_qualifications,
+ variant_size_differences
+)]
+#![doc(test(attr(forbid(unsafe_code))))]
+#![doc(test(attr(deny(
+ missing_copy_implementations,
+ missing_debug_implementations,
+ trivial_casts,
+ trivial_numeric_casts,
+ unused_extern_crates,
+ unused_import_braces,
+ unused_qualifications,
+))))]
+#![doc(test(attr(warn(rust_2018_idioms))))]
+// Not needed for 2018 edition and conflicts with `rust_2018_idioms`
+#![doc(test(no_crate_inject))]
+#![doc(html_root_url = "https://docs.rs/serde_with/1.14.0")]
+#![cfg_attr(docsrs, feature(doc_cfg))]
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8560
+ clippy::only_used_in_recursion,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+#![no_std]
+
+//! [![crates.io badge](https://img.shields.io/crates/v/serde_with.svg)](https://crates.io/crates/serde_with/)
+//! [![Build Status](https://github.com/jonasbb/serde_with/workflows/Rust%20CI/badge.svg)](https://github.com/jonasbb/serde_with)
+//! [![codecov](https://codecov.io/gh/jonasbb/serde_with/branch/master/graph/badge.svg)](https://codecov.io/gh/jonasbb/serde_with)
+//! [![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4322/badge)](https://bestpractices.coreinfrastructure.org/projects/4322)
+//! [![Binder](https://img.shields.io/badge/Try%20on%20-binder-579ACA.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAABZCAMAAABi1XidAAAB8lBMVEX///9XmsrmZYH1olJXmsr1olJXmsrmZYH1olJXmsr1olJXmsrmZYH1olL1olJXmsr1olJXmsrmZYH1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olJXmsrmZYH1olL1olL0nFf1olJXmsrmZYH1olJXmsq8dZb1olJXmsrmZYH1olJXmspXmspXmsr1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olLeaIVXmsrmZYH1olL1olL1olJXmsrmZYH1olLna31Xmsr1olJXmsr1olJXmsrmZYH1olLqoVr1olJXmsr1olJXmsrmZYH1olL1olKkfaPobXvviGabgadXmsqThKuofKHmZ4Dobnr1olJXmsr1olJXmspXmsr1olJXmsrfZ4TuhWn1olL1olJXmsqBi7X1olJXmspZmslbmMhbmsdemsVfl8ZgmsNim8Jpk8F0m7R4m7F5nLB6jbh7jbiDirOEibOGnKaMhq+PnaCVg6qWg6qegKaff6WhnpKofKGtnomxeZy3noG6dZi+n3vCcpPDcpPGn3bLb4/Mb47UbIrVa4rYoGjdaIbeaIXhoWHmZYHobXvpcHjqdHXreHLroVrsfG/uhGnuh2bwj2Hxk17yl1vzmljzm1j0nlX1olL3AJXWAAAAbXRSTlMAEBAQHx8gICAuLjAwMDw9PUBAQEpQUFBXV1hgYGBkcHBwcXl8gICAgoiIkJCQlJicnJ2goKCmqK+wsLC4usDAwMjP0NDQ1NbW3Nzg4ODi5+3v8PDw8/T09PX29vb39/f5+fr7+/z8/Pz9/v7+zczCxgAABC5JREFUeAHN1ul3k0UUBvCb1CTVpmpaitAGSLSpSuKCLWpbTKNJFGlcSMAFF63iUmRccNG6gLbuxkXU66JAUef/9LSpmXnyLr3T5AO/rzl5zj137p136BISy44fKJXuGN/d19PUfYeO67Znqtf2KH33Id1psXoFdW30sPZ1sMvs2D060AHqws4FHeJojLZqnw53cmfvg+XR8mC0OEjuxrXEkX5ydeVJLVIlV0e10PXk5k7dYeHu7Cj1j+49uKg7uLU61tGLw1lq27ugQYlclHC4bgv7VQ+TAyj5Zc/UjsPvs1sd5cWryWObtvWT2EPa4rtnWW3JkpjggEpbOsPr7F7EyNewtpBIslA7p43HCsnwooXTEc3UmPmCNn5lrqTJxy6nRmcavGZVt/3Da2pD5NHvsOHJCrdc1G2r3DITpU7yic7w/7Rxnjc0kt5GC4djiv2Sz3Fb2iEZg41/ddsFDoyuYrIkmFehz0HR2thPgQqMyQYb2OtB0WxsZ3BeG3+wpRb1vzl2UYBog8FfGhttFKjtAclnZYrRo9ryG9uG/FZQU4AEg8ZE9LjGMzTmqKXPLnlWVnIlQQTvxJf8ip7VgjZjyVPrjw1te5otM7RmP7xm+sK2Gv9I8Gi++BRbEkR9EBw8zRUcKxwp73xkaLiqQb+kGduJTNHG72zcW9LoJgqQxpP3/Tj//c3yB0tqzaml05/+orHLksVO+95kX7/7qgJvnjlrfr2Ggsyx0eoy9uPzN5SPd86aXggOsEKW2Prz7du3VID3/tzs/sSRs2w7ovVHKtjrX2pd7ZMlTxAYfBAL9jiDwfLkq55Tm7ifhMlTGPyCAs7RFRhn47JnlcB9RM5T97ASuZXIcVNuUDIndpDbdsfrqsOppeXl5Y+XVKdjFCTh+zGaVuj0d9zy05PPK3QzBamxdwtTCrzyg/2Rvf2EstUjordGwa/kx9mSJLr8mLLtCW8HHGJc2R5hS219IiF6PnTusOqcMl57gm0Z8kanKMAQg0qSyuZfn7zItsbGyO9QlnxY0eCuD1XL2ys/MsrQhltE7Ug0uFOzufJFE2PxBo/YAx8XPPdDwWN0MrDRYIZF0mSMKCNHgaIVFoBbNoLJ7tEQDKxGF0kcLQimojCZopv0OkNOyWCCg9XMVAi7ARJzQdM2QUh0gmBozjc3Skg6dSBRqDGYSUOu66Zg+I2fNZs/M3/f/Grl/XnyF1Gw3VKCez0PN5IUfFLqvgUN4C0qNqYs5YhPL+aVZYDE4IpUk57oSFnJm4FyCqqOE0jhY2SMyLFoo56zyo6becOS5UVDdj7Vih0zp+tcMhwRpBeLyqtIjlJKAIZSbI8SGSF3k0pA3mR5tHuwPFoa7N7reoq2bqCsAk1HqCu5uvI1n6JuRXI+S1Mco54YmYTwcn6Aeic+kssXi8XpXC4V3t7/ADuTNKaQJdScAAAAAElFTkSuQmCC)](https://mybinder.org/v2/gist/jonasbb/18b9aece4c17f617b1c2b3946d29eeb0/HEAD?filepath=serde-with-demo.ipynb)
+//!
+//! ---
+//!
+//! This crate provides custom de/serialization helpers to use in combination with [serde's with-annotation][with-annotation] and with the improved [`serde_as`][as-annotation]-annotation.
+//! Some common use cases are:
+//!
+//! * De/Serializing a type using the `Display` and `FromStr` traits, e.g., for `u8`, `url::Url`, or `mime::Mime`.
+//! Check [`DisplayFromStr`][] or [`serde_with::rust::display_fromstr`][display_fromstr] for details.
+//! * Support for arrays larger than 32 elements or using const generics.
+//! With `serde_as` large arrays are supported, even if they are nested in other types.
+//! `[bool; 64]`, `Option<[u8; M]>`, and `Box<[[u8; 64]; N]>` are all supported, as [this examples shows](#large-and-const-generic-arrays).
+//! * Skip serializing all empty `Option` types with [`#[skip_serializing_none]`][skip_serializing_none].
+//! * Apply a prefix to each field name of a struct, without changing the de/serialize implementations of the struct using [`with_prefix!`][].
+//! * Deserialize a comma separated list like `#hash,#tags,#are,#great` into a `Vec<String>`.
+//! Check the documentation for [`serde_with::rust::StringWithSeparator::<CommaSeparator>`][StringWithSeparator].
+//!
+//! ## Getting Help
+//!
+//! **Check out the [user guide][user guide] to find out more tips and tricks about this crate.**
+//!
+//! For further help using this crate you can [open a new discussion](https://github.com/jonasbb/serde_with/discussions/new) or ask on [users.rust-lang.org](https://users.rust-lang.org/).
+//! For bugs, please open a [new issue](https://github.com/jonasbb/serde_with/issues/new) on GitHub.
+//!
+//! # Use `serde_with` in your Project
+//!
+//! Add this to your `Cargo.toml`:
+//!
+//! ```toml
+//! [dependencies.serde_with]
+//! version = "1.14.0"
+//! features = [ "..." ]
+//! ```
+//!
+//! The crate contains different features for integration with other common crates.
+//! Check the [feature flags][] section for information about all available features.
+//!
+//! # Examples
+//!
+//! Annotate your struct or enum to enable the custom de/serializer.
+//! The `#[serde_as]` attribute must be place *before* the `#[derive]`.
+//!
+//! ## `DisplayFromStr`
+//!
+//! ```rust
+//! # #[cfg(feature = "macros")]
+//! # use serde::{Deserialize, Serialize};
+//! # #[cfg(feature = "macros")]
+//! # use serde_with::{serde_as, DisplayFromStr};
+//! # #[cfg(feature = "macros")]
+//! #[serde_as]
+//! # #[derive(Debug, Eq, PartialEq)]
+//! #[derive(Deserialize, Serialize)]
+//! struct Foo {
+//! // Serialize with Display, deserialize with FromStr
+//! #[serde_as(as = "DisplayFromStr")]
+//! bar: u8,
+//! }
+//!
+//! # #[cfg(all(feature = "macros", feature = "json"))] {
+//! // This will serialize
+//! # let foo =
+//! Foo {bar: 12}
+//! # ;
+//!
+//! // into this JSON
+//! # let json = r#"
+//! {"bar": "12"}
+//! # "#;
+//! # assert_eq!(json.replace(" ", "").replace("\n", ""), serde_json::to_string(&foo).unwrap());
+//! # assert_eq!(foo, serde_json::from_str(&json).unwrap());
+//! # }
+//! ```
+//!
+//! ## Large and const-generic arrays
+//!
+//! serde does not support arrays with more than 32 elements or using const-generics.
+//! The `serde_as` attribute allows circumventing this restriction, even for nested types and nested arrays.
+//!
+//! ```rust
+//! # #[cfg(FALSE)] {
+//! # #[cfg(feature = "macros")]
+//! # use serde::{Deserialize, Serialize};
+//! # #[cfg(feature = "macros")]
+//! # use serde_with::serde_as;
+//! # #[cfg(feature = "macros")]
+//! #[serde_as]
+//! # #[derive(Debug, Eq, PartialEq)]
+//! #[derive(Deserialize, Serialize)]
+//! struct Arrays<const N: usize, const M: usize> {
+//! #[serde_as(as = "[_; N]")]
+//! constgeneric: [bool; N],
+//!
+//! #[serde_as(as = "Box<[[_; 64]; N]>")]
+//! nested: Box<[[u8; 64]; N]>,
+//!
+//! #[serde_as(as = "Option<[_; M]>")]
+//! optional: Option<[u8; M]>,
+//! }
+//!
+//! # #[cfg(all(feature = "macros", feature = "json"))] {
+//! // This allows us to serialize a struct like this
+//! let arrays: Arrays<100, 128> = Arrays {
+//! constgeneric: [true; 100],
+//! nested: Box::new([[111; 64]; 100]),
+//! optional: Some([222; 128])
+//! };
+//! assert!(serde_json::to_string(&arrays).is_ok());
+//! # }
+//! # }
+//! ```
+//!
+//! ## `skip_serializing_none`
+//!
+//! This situation often occurs with JSON, but other formats also support optional fields.
+//! If many fields are optional, putting the annotations on the structs can become tedious.
+//! The `#[skip_serializing_none]` attribute must be place *before* the `#[derive]`.
+//!
+//! ```rust
+//! # #[cfg(feature = "macros")]
+//! # use serde::{Deserialize, Serialize};
+//! # #[cfg(feature = "macros")]
+//! # use serde_with::skip_serializing_none;
+//! # #[cfg(feature = "macros")]
+//! #[skip_serializing_none]
+//! # #[derive(Debug, Eq, PartialEq)]
+//! #[derive(Deserialize, Serialize)]
+//! struct Foo {
+//! a: Option<usize>,
+//! b: Option<usize>,
+//! c: Option<usize>,
+//! d: Option<usize>,
+//! e: Option<usize>,
+//! f: Option<usize>,
+//! g: Option<usize>,
+//! }
+//!
+//! # #[cfg(all(feature = "macros", feature = "json"))] {
+//! // This will serialize
+//! # let foo =
+//! Foo {a: None, b: None, c: None, d: Some(4), e: None, f: None, g: Some(7)}
+//! # ;
+//!
+//! // into this JSON
+//! # let json = r#"
+//! {"d": 4, "g": 7}
+//! # "#;
+//! # assert_eq!(json.replace(" ", "").replace("\n", ""), serde_json::to_string(&foo).unwrap());
+//! # assert_eq!(foo, serde_json::from_str(&json).unwrap());
+//! # }
+//! ```
+//!
+//! ## Advanced `serde_as` usage
+//!
+//! This example is mainly supposed to highlight the flexibility of the `serde_as`-annotation compared to [serde's with-annotation][with-annotation].
+//! More details about `serde_as` can be found in the [user guide][].
+//!
+//! ```rust
+//! # #[cfg(all(feature = "macros", feature = "hex"))]
+//! # use {
+//! # serde::{Deserialize, Serialize},
+//! # serde_with::{serde_as, DisplayFromStr, DurationSeconds, hex::Hex},
+//! # std::time::Duration,
+//! # std::collections::BTreeMap,
+//! # };
+//! # #[cfg(all(feature = "macros", feature = "hex"))]
+//! #[serde_as]
+//! # #[derive(Debug, Eq, PartialEq)]
+//! #[derive(Deserialize, Serialize)]
+//! struct Foo {
+//! // Serialize them into a list of number as seconds
+//! #[serde_as(as = "Vec<DurationSeconds>")]
+//! durations: Vec<Duration>,
+//! // We can treat a Vec like a map with duplicates.
+//! // JSON only allows string keys, so convert i32 to strings
+//! // The bytes will be hex encoded
+//! #[serde_as(as = "BTreeMap<DisplayFromStr, Hex>")]
+//! bytes: Vec<(i32, Vec<u8>)>,
+//! }
+//!
+//! # #[cfg(all(feature = "macros", feature = "json", feature = "hex"))] {
+//! // This will serialize
+//! # let foo =
+//! Foo {
+//! durations: vec![Duration::new(5, 0), Duration::new(3600, 0), Duration::new(0, 0)],
+//! bytes: vec![
+//! (1, vec![0, 1, 2]),
+//! (-100, vec![100, 200, 255]),
+//! (1, vec![0, 111, 222]),
+//! ],
+//! }
+//! # ;
+//!
+//! // into this JSON
+//! # let json = r#"
+//! {
+//! "durations": [5, 3600, 0],
+//! "bytes": {
+//! "1": "000102",
+//! "-100": "64c8ff",
+//! "1": "006fde"
+//! }
+//! }
+//! # "#;
+//! # assert_eq!(json.replace(" ", "").replace("\n", ""), serde_json::to_string(&foo).unwrap());
+//! # assert_eq!(foo, serde_json::from_str(&json).unwrap());
+//! # }
+//! ```
+//!
+//! [`DisplayFromStr`]: https://docs.rs/serde_with/1.14.0/serde_with/struct.DisplayFromStr.html
+//! [`with_prefix!`]: https://docs.rs/serde_with/1.14.0/serde_with/macro.with_prefix.html
+//! [display_fromstr]: https://docs.rs/serde_with/1.14.0/serde_with/rust/display_fromstr/index.html
+//! [feature flags]: https://docs.rs/serde_with/1.14.0/serde_with/guide/feature_flags/index.html
+//! [skip_serializing_none]: https://docs.rs/serde_with/1.14.0/serde_with/attr.skip_serializing_none.html
+//! [StringWithSeparator]: https://docs.rs/serde_with/1.14.0/serde_with/rust/struct.StringWithSeparator.html
+//! [user guide]: https://docs.rs/serde_with/1.14.0/serde_with/guide/index.html
+//! [with-annotation]: https://serde.rs/field-attrs.html#with
+//! [as-annotation]: https://docs.rs/serde_with/1.14.0/serde_with/guide/serde_as/index.html
+
+extern crate alloc;
+#[doc(hidden)]
+pub extern crate serde;
+extern crate std;
+
+#[cfg(feature = "base64")]
+#[cfg_attr(docsrs, doc(cfg(feature = "base64")))]
+pub mod base64;
+#[cfg(feature = "chrono")]
+#[cfg_attr(docsrs, doc(cfg(feature = "chrono")))]
+pub mod chrono;
+mod content;
+pub mod de;
+mod duplicate_key_impls;
+mod enum_map;
+mod flatten_maybe;
+pub mod formats;
+#[cfg(feature = "hex")]
+#[cfg_attr(docsrs, doc(cfg(feature = "hex")))]
+pub mod hex;
+#[cfg(feature = "json")]
+#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
+pub mod json;
+pub mod rust;
+pub mod ser;
+mod serde_conv;
+#[cfg(feature = "time_0_3")]
+#[cfg_attr(docsrs, doc(cfg(feature = "time_0_3")))]
+pub mod time_0_3;
+mod utils;
+#[doc(hidden)]
+pub mod with_prefix;
+
+// Taken from shepmaster/snafu
+// Originally licensed as MIT+Apache 2
+// https://github.com/shepmaster/snafu/blob/fd37d79d4531ed1d3eebffad0d658928eb860cfe/src/lib.rs#L121-L165
+#[cfg(feature = "guide")]
+#[allow(unused_macro_rules)]
+macro_rules! generate_guide {
+ (pub mod $name:ident; $($rest:tt)*) => {
+ generate_guide!(@gen ".", pub mod $name { } $($rest)*);
+ };
+ (pub mod $name:ident { $($children:tt)* } $($rest:tt)*) => {
+ generate_guide!(@gen ".", pub mod $name { $($children)* } $($rest)*);
+ };
+ (@gen $prefix:expr, ) => {};
+ (@gen $prefix:expr, pub mod $name:ident; $($rest:tt)*) => {
+ generate_guide!(@gen $prefix, pub mod $name { } $($rest)*);
+ };
+ (@gen $prefix:expr, @code pub mod $name:ident; $($rest:tt)*) => {
+ pub mod $name;
+ generate_guide!(@gen $prefix, $($rest)*);
+ };
+ (@gen $prefix:expr, pub mod $name:ident { $($children:tt)* } $($rest:tt)*) => {
+ doc_comment::doc_comment! {
+ include_str!(concat!($prefix, "/", stringify!($name), ".md")),
+ pub mod $name {
+ generate_guide!(@gen concat!($prefix, "/", stringify!($name)), $($children)*);
+ }
+ }
+ generate_guide!(@gen $prefix, $($rest)*);
+ };
+}
+
+#[cfg(feature = "guide")]
+generate_guide! {
+ pub mod guide {
+ pub mod feature_flags;
+ pub mod serde_as;
+ pub mod serde_as_transformations;
+ }
+}
+
+#[doc(inline)]
+pub use crate::{
+ de::DeserializeAs, enum_map::EnumMap, rust::StringWithSeparator, ser::SerializeAs,
+};
+use core::marker::PhantomData;
+use serde::{Deserialize, Deserializer, Serialize, Serializer};
+// Re-Export all proc_macros, as these should be seen as part of the serde_with crate
+#[cfg(feature = "macros")]
+#[cfg_attr(docsrs, doc(cfg(feature = "macros")))]
+#[doc(inline)]
+pub use serde_with_macros::*;
+
+/// Separator for string-based collection de/serialization
+pub trait Separator {
+ /// Return the string delimiting two elements in the string-based collection
+ fn separator() -> &'static str;
+}
+
+/// Predefined separator using a single space
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
+pub struct SpaceSeparator;
+
+impl Separator for SpaceSeparator {
+ #[inline]
+ fn separator() -> &'static str {
+ " "
+ }
+}
+
+/// Predefined separator using a single comma
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
+pub struct CommaSeparator;
+
+impl Separator for CommaSeparator {
+ #[inline]
+ fn separator() -> &'static str {
+ ","
+ }
+}
+
+/// Adapter to convert from `serde_as` to the serde traits.
+///
+/// The `As` type adapter allows using types which implement [`DeserializeAs`] or [`SerializeAs`] in place of serde's with-annotation.
+/// The with-annotation allows running custom code when de/serializing, however it is quite inflexible.
+/// The traits [`DeserializeAs`]/[`SerializeAs`] are more flexible, as they allow composition and nesting of types to create more complex de/serialization behavior.
+/// However, they are not directly compatible with serde, as they are not provided by serde.
+/// The `As` type adapter makes them compatible, by forwarding the function calls to `serialize`/`deserialize` to the corresponding functions `serialize_as` and `deserialize_as`.
+///
+/// It is not required to use this type directly.
+/// Instead, it is highly encouraged to use the [`#[serde_as]`][serde_as] attribute since it includes further usability improvements.
+/// If the use of the use of the proc-macro is not acceptable, then `As` can be used directly with serde.
+///
+/// ```rust
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::{As, DisplayFromStr};
+/// #
+/// #[derive(Deserialize, Serialize)]
+/// # struct S {
+/// // Serialize numbers as sequence of strings, using Display and FromStr
+/// #[serde(with = "As::<Vec<DisplayFromStr>>")]
+/// field: Vec<u8>,
+/// # }
+/// ```
+/// If the normal `Deserialize`/`Serialize` traits should be used, the placeholder type [`Same`] can be used.
+/// It implements [`DeserializeAs`][]/[`SerializeAs`][], when the underlying type implements `Deserialize`/`Serialize`.
+///
+/// ```rust
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::{As, DisplayFromStr, Same};
+/// # use std::collections::BTreeMap;
+/// #
+/// #[derive(Deserialize, Serialize)]
+/// # struct S {
+/// // Serialize map, turn keys into strings but keep type of value
+/// #[serde(with = "As::<BTreeMap<DisplayFromStr, Same>>")]
+/// field: BTreeMap<u8, i32>,
+/// # }
+/// ```
+///
+/// [serde_as]: https://docs.rs/serde_with/1.14.0/serde_with/attr.serde_as.html
+#[derive(Copy, Clone, Debug, Default)]
+pub struct As<T: ?Sized>(PhantomData<T>);
+
+impl<T: ?Sized> As<T> {
+ /// Serialize type `T` using [`SerializeAs`][]
+ ///
+ /// The function signature is compatible with [serde's with-annotation][with-annotation].
+ ///
+ /// [with-annotation]: https://serde.rs/field-attrs.html#with
+ pub fn serialize<S, I>(value: &I, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ T: SerializeAs<I>,
+ I: ?Sized,
+ {
+ T::serialize_as(value, serializer)
+ }
+
+ /// Deserialize type `T` using [`DeserializeAs`][]
+ ///
+ /// The function signature is compatible with [serde's with-annotation][with-annotation].
+ ///
+ /// [with-annotation]: https://serde.rs/field-attrs.html#with
+ pub fn deserialize<'de, D, I>(deserializer: D) -> Result<I, D::Error>
+ where
+ T: DeserializeAs<'de, I>,
+ D: Deserializer<'de>,
+ {
+ T::deserialize_as(deserializer)
+ }
+}
+
+/// Adapter to convert from `serde_as` to the serde traits.
+///
+/// This is the counter-type to [`As`][].
+/// It can be used whenever a type implementing [`DeserializeAs`][]/[`SerializeAs`][] is required but the normal `Deserialize`/`Serialize` traits should be used.
+/// Check [`As`] for an example.
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Same;
+
+/// De/Serialize using [`Display`] and [`FromStr`] implementation
+///
+/// This allows deserializing a string as a number.
+/// It can be very useful for serialization formats like JSON, which do not support integer
+/// numbers and have to resort to strings to represent them.
+///
+/// Another use case is types with [`Display`] and [`FromStr`] implementations, but without serde
+/// support, which can be found in some crates.
+///
+/// If you control the type you want to de/serialize, you can instead use the two derive macros, [`SerializeDisplay`] and [`DeserializeFromStr`].
+/// They properly implement the traits [`Serialize`] and [`Deserialize`] such that user of the type no longer have to use the `serde_as` system.
+///
+/// The same functionality is also available as [`serde_with::rust::display_fromstr`][crate::rust::display_fromstr] compatible with serde's with-annotation.
+///
+/// # Examples
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, DisplayFromStr};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde_as(as = "DisplayFromStr")]
+/// mime: mime::Mime,
+/// #[serde_as(as = "DisplayFromStr")]
+/// number: u32,
+/// }
+///
+/// let v: A = serde_json::from_value(json!({
+/// "mime": "text/plain",
+/// "number": "159",
+/// })).unwrap();
+/// assert_eq!(mime::TEXT_PLAIN, v.mime);
+/// assert_eq!(159, v.number);
+///
+/// let x = A {
+/// mime: mime::STAR_STAR,
+/// number: 777,
+/// };
+/// assert_eq!(json!({ "mime": "*/*", "number": "777" }), serde_json::to_value(&x).unwrap());
+/// # }
+/// ```
+///
+/// [`Display`]: std::fmt::Display
+/// [`FromStr`]: std::str::FromStr
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DisplayFromStr;
+
+/// De/Serialize a [`Option<String>`] type while transforming the empty string to [`None`]
+///
+/// Convert an [`Option<T>`] from/to string using [`FromStr`] and [`AsRef<str>`] implementations.
+/// An empty string is deserialized as [`None`] and a [`None`] vice versa.
+///
+/// The same functionality is also available as [`serde_with::rust::string_empty_as_none`][crate::rust::string_empty_as_none] compatible with serde's with-annotation.
+///
+/// # Examples
+///
+/// ```
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, NoneAsEmptyString};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde_as(as = "NoneAsEmptyString")]
+/// tags: Option<String>,
+/// }
+///
+/// let v: A = serde_json::from_value(json!({ "tags": "" })).unwrap();
+/// assert_eq!(None, v.tags);
+///
+/// let v: A = serde_json::from_value(json!({ "tags": "Hi" })).unwrap();
+/// assert_eq!(Some("Hi".to_string()), v.tags);
+///
+/// let x = A {
+/// tags: Some("This is text".to_string()),
+/// };
+/// assert_eq!(json!({ "tags": "This is text" }), serde_json::to_value(&x).unwrap());
+///
+/// let x = A {
+/// tags: None,
+/// };
+/// assert_eq!(json!({ "tags": "" }), serde_json::to_value(&x).unwrap());
+/// # }
+/// ```
+///
+/// [`FromStr`]: std::str::FromStr
+#[derive(Copy, Clone, Debug, Default)]
+pub struct NoneAsEmptyString;
+
+/// Deserialize value and return [`Default`] on error
+///
+/// The main use case is ignoring error while deserializing.
+/// Instead of erroring, it simply deserializes the [`Default`] variant of the type.
+/// It is not possible to find the error location, i.e., which field had a deserialization error, with this method.
+/// During serialization this wrapper does nothing.
+/// The serialization behavior of the underlying type is preserved.
+/// The type must implement [`Default`] for this conversion to work.
+///
+/// The same functionality is also available as [`serde_with::rust::default_on_error`][crate::rust::default_on_error] compatible with serde's with-annotation.
+///
+/// # Examples
+///
+/// ```
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_with::{serde_as, DefaultOnError};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize, Debug)]
+/// struct A {
+/// #[serde_as(deserialize_as = "DefaultOnError")]
+/// value: u32,
+/// }
+///
+/// let a: A = serde_json::from_str(r#"{"value": 123}"#).unwrap();
+/// assert_eq!(123, a.value);
+///
+/// // null is of invalid type
+/// let a: A = serde_json::from_str(r#"{"value": null}"#).unwrap();
+/// assert_eq!(0, a.value);
+///
+/// // String is of invalid type
+/// let a: A = serde_json::from_str(r#"{"value": "123"}"#).unwrap();
+/// assert_eq!(0, a.value);
+///
+/// // Map is of invalid type
+/// let a: A = dbg!(serde_json::from_str(r#"{"value": {}}"#)).unwrap();
+/// assert_eq!(0, a.value);
+///
+/// // Missing entries still cause errors
+/// assert!(serde_json::from_str::<A>(r#"{ }"#).is_err());
+/// # }
+/// ```
+///
+/// Deserializing missing values can be supported by adding the `default` field attribute:
+///
+/// ```
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_with::{serde_as, DefaultOnError};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize)]
+/// struct B {
+/// #[serde_as(deserialize_as = "DefaultOnError")]
+/// #[serde(default)]
+/// value: u32,
+/// }
+///
+/// let b: B = serde_json::from_str(r#"{ }"#).unwrap();
+/// assert_eq!(0, b.value);
+/// # }
+/// ```
+///
+/// `DefaultOnError` can be combined with other conversion methods.
+/// In this example, we deserialize a `Vec`, each element is deserialized from a string.
+/// If the string does not parse as a number, then we get the default value of 0.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, DefaultOnError, DisplayFromStr};
+/// #
+/// #[serde_as]
+/// #[derive(Serialize, Deserialize)]
+/// struct C {
+/// #[serde_as(as = "Vec<DefaultOnError<DisplayFromStr>>")]
+/// value: Vec<u32>,
+/// };
+///
+/// let c: C = serde_json::from_value(json!({
+/// "value": ["1", "2", "a3", "", {}, "6"]
+/// })).unwrap();
+/// assert_eq!(vec![1, 2, 0, 0, 0, 6], c.value);
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DefaultOnError<T = Same>(PhantomData<T>);
+
+/// Deserialize [`Default`] from `null` values
+///
+/// Instead of erroring on `null` values, it simply deserializes the [`Default`] variant of the type.
+/// During serialization this wrapper does nothing.
+/// The serialization behavior of the underlying type is preserved.
+/// The type must implement [`Default`] for this conversion to work.
+///
+/// The same functionality is also available as [`serde_with::rust::default_on_null`][crate::rust::default_on_null] compatible with serde's with-annotation.
+///
+/// # Examples
+///
+/// ```
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_with::{serde_as, DefaultOnNull};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize, Debug)]
+/// struct A {
+/// #[serde_as(deserialize_as = "DefaultOnNull")]
+/// value: u32,
+/// }
+///
+/// let a: A = serde_json::from_str(r#"{"value": 123}"#).unwrap();
+/// assert_eq!(123, a.value);
+///
+/// // null values are deserialized into the default, here 0
+/// let a: A = serde_json::from_str(r#"{"value": null}"#).unwrap();
+/// assert_eq!(0, a.value);
+/// # }
+/// ```
+///
+/// `DefaultOnNull` can be combined with other conversion methods.
+/// In this example, we deserialize a `Vec`, each element is deserialized from a string.
+/// If we encounter null, then we get the default value of 0.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, DefaultOnNull, DisplayFromStr};
+/// #
+/// #[serde_as]
+/// #[derive(Serialize, Deserialize)]
+/// struct C {
+/// #[serde_as(as = "Vec<DefaultOnNull<DisplayFromStr>>")]
+/// value: Vec<u32>,
+/// };
+///
+/// let c: C = serde_json::from_value(json!({
+/// "value": ["1", "2", null, null, "5"]
+/// })).unwrap();
+/// assert_eq!(vec![1, 2, 0, 0, 5], c.value);
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DefaultOnNull<T = Same>(PhantomData<T>);
+
+/// Deserialize from bytes or string
+///
+/// Any Rust [`String`] can be converted into bytes, i.e., `Vec<u8>`.
+/// Accepting both as formats while deserializing can be helpful while interacting with language
+/// which have a looser definition of string than Rust.
+///
+/// # Example
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, BytesOrString};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde_as(as = "BytesOrString")]
+/// bytes_or_string: Vec<u8>,
+/// }
+///
+/// // Here we deserialize from a byte array ...
+/// let j = json!({
+/// "bytes_or_string": [
+/// 0,
+/// 1,
+/// 2,
+/// 3
+/// ]
+/// });
+///
+/// let a: A = serde_json::from_value(j.clone()).unwrap();
+/// assert_eq!(vec![0, 1, 2, 3], a.bytes_or_string);
+///
+/// // and serialization works too.
+/// assert_eq!(j, serde_json::to_value(&a).unwrap());
+///
+/// // But we also support deserializing from a String
+/// let j = json!({
+/// "bytes_or_string": "✨Works!"
+/// });
+///
+/// let a: A = serde_json::from_value(j).unwrap();
+/// assert_eq!("✨Works!".as_bytes(), &*a.bytes_or_string);
+/// # }
+/// ```
+/// [`String`]: std::string::String
+#[derive(Copy, Clone, Debug, Default)]
+pub struct BytesOrString;
+
+/// De/Serialize Durations as number of seconds.
+///
+/// De/serialize durations as number of seconds with subsecond precision.
+/// Subsecond precision is *only* supported for [`DurationSecondsWithFrac`], but not for [`DurationSeconds`].
+/// You can configure the serialization format between integers, floats, and stringified numbers with the `FORMAT` specifier and configure the deserialization with the `STRICTNESS` specifier.
+///
+/// The `STRICTNESS` specifier can either be [`formats::Strict`] or [`formats::Flexible`] and defaults to [`formats::Strict`].
+/// [`formats::Strict`] means that deserialization only supports the type given in `FORMAT`, e.g., if `FORMAT` is `u64` deserialization from a `f64` will error.
+/// [`formats::Flexible`] means that deserialization will perform a best effort to extract the correct duration and allows deserialization from any type.
+/// For example, deserializing `DurationSeconds<f64, Flexible>` will discard any subsecond precision during deserialization from `f64` and will parse a `String` as an integer number.
+///
+/// This type also supports [`chrono::Duration`] with the `chrono`-[feature flag].
+/// This type also supports [`time::Duration`][::time_0_3::Duration] with the `time_0_3`-[feature flag].
+///
+/// | Duration Type | Converter | Available `FORMAT`s |
+/// | --------------------- | ------------------------- | ---------------------- |
+/// | `std::time::Duration` | `DurationSeconds` | `u64`, `f64`, `String` |
+/// | `std::time::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
+/// | `chrono::Duration` | `DurationSeconds` | `i64`, `f64`, `String` |
+/// | `chrono::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
+/// | `time::Duration` | `DurationSeconds` | `i64`, `f64`, `String` |
+/// | `time::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
+///
+/// # Examples
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, DurationSeconds};
+/// use std::time::Duration;
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Durations {
+/// #[serde_as(as = "DurationSeconds<u64>")]
+/// d_u64: Duration,
+/// #[serde_as(as = "DurationSeconds<f64>")]
+/// d_f64: Duration,
+/// #[serde_as(as = "DurationSeconds<String>")]
+/// d_string: Duration,
+/// };
+///
+/// // Serialization
+/// // See how the values get rounded, since subsecond precision is not allowed.
+///
+/// let d = Durations {
+/// d_u64: Duration::new(12345, 0), // Create from seconds and nanoseconds
+/// d_f64: Duration::new(12345, 500_000_000),
+/// d_string: Duration::new(12345, 999_999_999),
+/// };
+/// // Observe the different data types
+/// let expected = json!({
+/// "d_u64": 12345,
+/// "d_f64": 12346.0,
+/// "d_string": "12346",
+/// });
+/// assert_eq!(expected, serde_json::to_value(&d).unwrap());
+///
+/// // Deserialization works too
+/// // Subsecond precision in numbers will be rounded away
+///
+/// let json = json!({
+/// "d_u64": 12345,
+/// "d_f64": 12345.5,
+/// "d_string": "12346",
+/// });
+/// let expected = Durations {
+/// d_u64: Duration::new(12345, 0), // Create from seconds and nanoseconds
+/// d_f64: Duration::new(12346, 0),
+/// d_string: Duration::new(12346, 0),
+/// };
+/// assert_eq!(expected, serde_json::from_value(json).unwrap());
+/// # }
+/// ```
+///
+/// [`chrono::Duration`] is also supported when using the `chrono` feature.
+/// It is a signed duration, thus can be de/serialized as an `i64` instead of a `u64`.
+///
+/// ```rust
+/// # #[cfg(all(feature = "macros", feature = "chrono"))] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, DurationSeconds};
+/// # use chrono_crate::Duration;
+/// # /* Ugliness to make the docs look nicer since I want to hide the rename of the chrono crate
+/// use chrono::Duration;
+/// # */
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Durations {
+/// #[serde_as(as = "DurationSeconds<i64>")]
+/// d_i64: Duration,
+/// #[serde_as(as = "DurationSeconds<f64>")]
+/// d_f64: Duration,
+/// #[serde_as(as = "DurationSeconds<String>")]
+/// d_string: Duration,
+/// };
+///
+/// // Serialization
+/// // See how the values get rounded, since subsecond precision is not allowed.
+///
+/// let d = Durations {
+/// d_i64: Duration::seconds(-12345),
+/// d_f64: Duration::seconds(-12345) + Duration::milliseconds(500),
+/// d_string: Duration::seconds(12345) + Duration::nanoseconds(999_999_999),
+/// };
+/// // Observe the different data types
+/// let expected = json!({
+/// "d_i64": -12345,
+/// "d_f64": -12345.0,
+/// "d_string": "12346",
+/// });
+/// assert_eq!(expected, serde_json::to_value(&d).unwrap());
+///
+/// // Deserialization works too
+/// // Subsecond precision in numbers will be rounded away
+///
+/// let json = json!({
+/// "d_i64": -12345,
+/// "d_f64": -12345.5,
+/// "d_string": "12346",
+/// });
+/// let expected = Durations {
+/// d_i64: Duration::seconds(-12345),
+/// d_f64: Duration::seconds(-12346),
+/// d_string: Duration::seconds(12346),
+/// };
+/// assert_eq!(expected, serde_json::from_value(json).unwrap());
+/// # }
+/// ```
+///
+/// [`chrono::Duration`]: chrono_crate::Duration
+/// [feature flag]: https://docs.rs/serde_with/1.14.0/serde_with/guide/feature_flags/index.html
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DurationSeconds<
+ FORMAT: formats::Format = u64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// De/Serialize Durations as number of seconds.
+///
+/// De/serialize durations as number of seconds with subsecond precision.
+/// Subsecond precision is *only* supported for [`DurationSecondsWithFrac`], but not for [`DurationSeconds`].
+/// You can configure the serialization format between integers, floats, and stringified numbers with the `FORMAT` specifier and configure the deserialization with the `STRICTNESS` specifier.
+///
+/// The `STRICTNESS` specifier can either be [`formats::Strict`] or [`formats::Flexible`] and defaults to [`formats::Strict`].
+/// [`formats::Strict`] means that deserialization only supports the type given in `FORMAT`, e.g., if `FORMAT` is `u64` deserialization from a `f64` will error.
+/// [`formats::Flexible`] means that deserialization will perform a best effort to extract the correct duration and allows deserialization from any type.
+/// For example, deserializing `DurationSeconds<f64, Flexible>` will discard any subsecond precision during deserialization from `f64` and will parse a `String` as an integer number.
+///
+/// This type also supports [`chrono::Duration`] with the `chrono`-[feature flag].
+/// This type also supports [`time::Duration`][::time_0_3::Duration] with the `time_0_3`-[feature flag].
+///
+/// | Duration Type | Converter | Available `FORMAT`s |
+/// | --------------------- | ------------------------- | ---------------------- |
+/// | `std::time::Duration` | `DurationSeconds` | `u64`, `f64`, `String` |
+/// | `std::time::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
+/// | `chrono::Duration` | `DurationSeconds` | `i64`, `f64`, `String` |
+/// | `chrono::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
+/// | `time::Duration` | `DurationSeconds` | `i64`, `f64`, `String` |
+/// | `time::Duration` | `DurationSecondsWithFrac` | `f64`, `String` |
+///
+/// # Examples
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, DurationSecondsWithFrac};
+/// use std::time::Duration;
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Durations {
+/// #[serde_as(as = "DurationSecondsWithFrac<f64>")]
+/// d_f64: Duration,
+/// #[serde_as(as = "DurationSecondsWithFrac<String>")]
+/// d_string: Duration,
+/// };
+///
+/// // Serialization
+/// // See how the values get rounded, since subsecond precision is not allowed.
+///
+/// let d = Durations {
+/// d_f64: Duration::new(12345, 500_000_000), // Create from seconds and nanoseconds
+/// d_string: Duration::new(12345, 999_999_000),
+/// };
+/// // Observe the different data types
+/// let expected = json!({
+/// "d_f64": 12345.5,
+/// "d_string": "12345.999999",
+/// });
+/// assert_eq!(expected, serde_json::to_value(&d).unwrap());
+///
+/// // Deserialization works too
+/// // Subsecond precision in numbers will be rounded away
+///
+/// let json = json!({
+/// "d_f64": 12345.5,
+/// "d_string": "12345.987654",
+/// });
+/// let expected = Durations {
+/// d_f64: Duration::new(12345, 500_000_000), // Create from seconds and nanoseconds
+/// d_string: Duration::new(12345, 987_654_000),
+/// };
+/// assert_eq!(expected, serde_json::from_value(json).unwrap());
+/// # }
+/// ```
+///
+/// [`chrono::Duration`] is also supported when using the `chrono` feature.
+/// It is a signed duration, thus can be de/serialized as an `i64` instead of a `u64`.
+///
+/// ```rust
+/// # #[cfg(all(feature = "macros", feature = "chrono"))] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, DurationSecondsWithFrac};
+/// # use chrono_crate::Duration;
+/// # /* Ugliness to make the docs look nicer since I want to hide the rename of the chrono crate
+/// use chrono::Duration;
+/// # */
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Durations {
+/// #[serde_as(as = "DurationSecondsWithFrac<f64>")]
+/// d_f64: Duration,
+/// #[serde_as(as = "DurationSecondsWithFrac<String>")]
+/// d_string: Duration,
+/// };
+///
+/// // Serialization
+///
+/// let d = Durations {
+/// d_f64: Duration::seconds(-12345) + Duration::milliseconds(500),
+/// d_string: Duration::seconds(12345) + Duration::nanoseconds(999_999_000),
+/// };
+/// // Observe the different data types
+/// let expected = json!({
+/// "d_f64": -12344.5,
+/// "d_string": "12345.999999",
+/// });
+/// assert_eq!(expected, serde_json::to_value(&d).unwrap());
+///
+/// // Deserialization works too
+///
+/// let json = json!({
+/// "d_f64": -12344.5,
+/// "d_string": "12345.987",
+/// });
+/// let expected = Durations {
+/// d_f64: Duration::seconds(-12345) + Duration::milliseconds(500),
+/// d_string: Duration::seconds(12345) + Duration::milliseconds(987),
+/// };
+/// assert_eq!(expected, serde_json::from_value(json).unwrap());
+/// # }
+/// ```
+///
+/// [`chrono::Duration`]: chrono_crate::Duration
+/// [feature flag]: https://docs.rs/serde_with/1.14.0/serde_with/guide/feature_flags/index.html
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DurationSecondsWithFrac<
+ FORMAT: formats::Format = f64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`DurationSeconds`] with milli-seconds as base unit.
+///
+/// This type is equivalent to [`DurationSeconds`] except that each unit represents 1 milli-second instead of 1 second for [`DurationSeconds`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DurationMilliSeconds<
+ FORMAT: formats::Format = u64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`DurationSecondsWithFrac`] with milli-seconds as base unit.
+///
+/// This type is equivalent to [`DurationSecondsWithFrac`] except that each unit represents 1 milli-second instead of 1 second for [`DurationSecondsWithFrac`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DurationMilliSecondsWithFrac<
+ FORMAT: formats::Format = f64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`DurationSeconds`] with micro-seconds as base unit.
+///
+/// This type is equivalent to [`DurationSeconds`] except that each unit represents 1 micro-second instead of 1 second for [`DurationSeconds`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DurationMicroSeconds<
+ FORMAT: formats::Format = u64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`DurationSecondsWithFrac`] with micro-seconds as base unit.
+///
+/// This type is equivalent to [`DurationSecondsWithFrac`] except that each unit represents 1 micro-second instead of 1 second for [`DurationSecondsWithFrac`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DurationMicroSecondsWithFrac<
+ FORMAT: formats::Format = f64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`DurationSeconds`] with nano-seconds as base unit.
+///
+/// This type is equivalent to [`DurationSeconds`] except that each unit represents 1 nano-second instead of 1 second for [`DurationSeconds`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DurationNanoSeconds<
+ FORMAT: formats::Format = u64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`DurationSecondsWithFrac`] with nano-seconds as base unit.
+///
+/// This type is equivalent to [`DurationSecondsWithFrac`] except that each unit represents 1 nano-second instead of 1 second for [`DurationSecondsWithFrac`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct DurationNanoSecondsWithFrac<
+ FORMAT: formats::Format = f64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// De/Serialize timestamps as seconds since the UNIX epoch
+///
+/// De/serialize timestamps as seconds since the UNIX epoch.
+/// Subsecond precision is *only* supported for [`TimestampSecondsWithFrac`], but not for [`TimestampSeconds`].
+/// You can configure the serialization format between integers, floats, and stringified numbers with the `FORMAT` specifier and configure the deserialization with the `STRICTNESS` specifier.
+///
+/// The `STRICTNESS` specifier can either be [`formats::Strict`] or [`formats::Flexible`] and defaults to [`formats::Strict`].
+/// [`formats::Strict`] means that deserialization only supports the type given in `FORMAT`, e.g., if `FORMAT` is `i64` deserialization from a `f64` will error.
+/// [`formats::Flexible`] means that deserialization will perform a best effort to extract the correct timestamp and allows deserialization from any type.
+/// For example, deserializing `TimestampSeconds<f64, Flexible>` will discard any subsecond precision during deserialization from `f64` and will parse a `String` as an integer number.
+///
+/// This type also supports [`chrono::DateTime`][DateTime] with the `chrono`-[feature flag].
+/// This type also supports [`time::OffsetDateTime`][::time_0_3::OffsetDateTime] and [`time::PrimitiveDateTime`][::time_0_3::PrimitiveDateTime] with the `time_0_3`-[feature flag].
+///
+/// | Timestamp Type | Converter | Available `FORMAT`s |
+/// | ------------------------- | -------------------------- | ---------------------- |
+/// | `std::time::SystemTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `std::time::SystemTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
+/// | `chrono::DateTime<Utc>` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `chrono::DateTime<Utc>` | `TimestampSecondsWithFrac` | `f64`, `String` |
+/// | `chrono::DateTime<Local>` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `chrono::DateTime<Local>` | `TimestampSecondsWithFrac` | `f64`, `String` |
+/// | `time::OffsetDateTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `time::OffsetDateTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
+/// | `time::PrimitiveDateTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `time::PrimitiveDateTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
+///
+/// # Examples
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, TimestampSeconds};
+/// use std::time::{Duration, SystemTime};
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Timestamps {
+/// #[serde_as(as = "TimestampSeconds<i64>")]
+/// st_i64: SystemTime,
+/// #[serde_as(as = "TimestampSeconds<f64>")]
+/// st_f64: SystemTime,
+/// #[serde_as(as = "TimestampSeconds<String>")]
+/// st_string: SystemTime,
+/// };
+///
+/// // Serialization
+/// // See how the values get rounded, since subsecond precision is not allowed.
+///
+/// let ts = Timestamps {
+/// st_i64: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 0)).unwrap(),
+/// st_f64: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 500_000_000)).unwrap(),
+/// st_string: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 999_999_999)).unwrap(),
+/// };
+/// // Observe the different data types
+/// let expected = json!({
+/// "st_i64": 12345,
+/// "st_f64": 12346.0,
+/// "st_string": "12346",
+/// });
+/// assert_eq!(expected, serde_json::to_value(&ts).unwrap());
+///
+/// // Deserialization works too
+/// // Subsecond precision in numbers will be rounded away
+///
+/// let json = json!({
+/// "st_i64": 12345,
+/// "st_f64": 12345.5,
+/// "st_string": "12346",
+/// });
+/// let expected = Timestamps {
+/// st_i64: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 0)).unwrap(),
+/// st_f64: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12346, 0)).unwrap(),
+/// st_string: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12346, 0)).unwrap(),
+/// };
+/// assert_eq!(expected, serde_json::from_value(json).unwrap());
+/// # }
+/// ```
+///
+/// [`chrono::DateTime<Utc>`][DateTime] and [`chrono::DateTime<Local>`][DateTime] are also supported when using the `chrono` feature.
+/// Like [`SystemTime`], it is a signed timestamp, thus can be de/serialized as an `i64`.
+///
+/// ```rust
+/// # #[cfg(all(feature = "macros", feature = "chrono"))] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, TimestampSeconds};
+/// # use chrono_crate::{DateTime, Local, TimeZone, Utc};
+/// # /* Ugliness to make the docs look nicer since I want to hide the rename of the chrono crate
+/// use chrono::{DateTime, Local, TimeZone, Utc};
+/// # */
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Timestamps {
+/// #[serde_as(as = "TimestampSeconds<i64>")]
+/// dt_i64: DateTime<Utc>,
+/// #[serde_as(as = "TimestampSeconds<f64>")]
+/// dt_f64: DateTime<Local>,
+/// #[serde_as(as = "TimestampSeconds<String>")]
+/// dt_string: DateTime<Utc>,
+/// };
+///
+/// // Serialization
+/// // See how the values get rounded, since subsecond precision is not allowed.
+///
+/// let ts = Timestamps {
+/// dt_i64: Utc.timestamp(-12345, 0),
+/// dt_f64: Local.timestamp(-12345, 500_000_000),
+/// dt_string: Utc.timestamp(12345, 999_999_999),
+/// };
+/// // Observe the different data types
+/// let expected = json!({
+/// "dt_i64": -12345,
+/// "dt_f64": -12345.0,
+/// "dt_string": "12346",
+/// });
+/// assert_eq!(expected, serde_json::to_value(&ts).unwrap());
+///
+/// // Deserialization works too
+/// // Subsecond precision in numbers will be rounded away
+///
+/// let json = json!({
+/// "dt_i64": -12345,
+/// "dt_f64": -12345.5,
+/// "dt_string": "12346",
+/// });
+/// let expected = Timestamps {
+/// dt_i64: Utc.timestamp(-12345, 0),
+/// dt_f64: Local.timestamp(-12346, 0),
+/// dt_string: Utc.timestamp(12346, 0),
+/// };
+/// assert_eq!(expected, serde_json::from_value(json).unwrap());
+/// # }
+/// ```
+///
+/// [`SystemTime`]: std::time::SystemTime
+/// [DateTime]: chrono_crate::DateTime
+/// [feature flag]: https://docs.rs/serde_with/1.14.0/serde_with/guide/feature_flags/index.html
+#[derive(Copy, Clone, Debug, Default)]
+pub struct TimestampSeconds<
+ FORMAT: formats::Format = i64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// De/Serialize timestamps as seconds since the UNIX epoch
+///
+/// De/serialize timestamps as seconds since the UNIX epoch.
+/// Subsecond precision is *only* supported for [`TimestampSecondsWithFrac`], but not for [`TimestampSeconds`].
+/// You can configure the serialization format between integers, floats, and stringified numbers with the `FORMAT` specifier and configure the deserialization with the `STRICTNESS` specifier.
+///
+/// The `STRICTNESS` specifier can either be [`formats::Strict`] or [`formats::Flexible`] and defaults to [`formats::Strict`].
+/// [`formats::Strict`] means that deserialization only supports the type given in `FORMAT`, e.g., if `FORMAT` is `i64` deserialization from a `f64` will error.
+/// [`formats::Flexible`] means that deserialization will perform a best effort to extract the correct timestamp and allows deserialization from any type.
+/// For example, deserializing `TimestampSeconds<f64, Flexible>` will discard any subsecond precision during deserialization from `f64` and will parse a `String` as an integer number.
+///
+/// This type also supports [`chrono::DateTime`][DateTime] and [`chrono::NaiveDateTime`][NaiveDateTime] with the `chrono`-[feature flag].
+/// This type also supports [`time::OffsetDateTime`][::time_0_3::OffsetDateTime] and [`time::PrimitiveDateTime`][::time_0_3::PrimitiveDateTime] with the `time_0_3`-[feature flag].
+///
+/// | Timestamp Type | Converter | Available `FORMAT`s |
+/// | ------------------------- | -------------------------- | ---------------------- |
+/// | `std::time::SystemTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `std::time::SystemTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
+/// | `chrono::DateTime<Utc>` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `chrono::DateTime<Utc>` | `TimestampSecondsWithFrac` | `f64`, `String` |
+/// | `chrono::DateTime<Local>` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `chrono::DateTime<Local>` | `TimestampSecondsWithFrac` | `f64`, `String` |
+/// | `chrono::NaiveDateTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `chrono::NaiveDateTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
+/// | `time::OffsetDateTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `time::OffsetDateTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
+/// | `time::PrimitiveDateTime` | `TimestampSeconds` | `i64`, `f64`, `String` |
+/// | `time::PrimitiveDateTime` | `TimestampSecondsWithFrac` | `f64`, `String` |
+///
+/// # Examples
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, TimestampSecondsWithFrac};
+/// use std::time::{Duration, SystemTime};
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Timestamps {
+/// #[serde_as(as = "TimestampSecondsWithFrac<f64>")]
+/// st_f64: SystemTime,
+/// #[serde_as(as = "TimestampSecondsWithFrac<String>")]
+/// st_string: SystemTime,
+/// };
+///
+/// // Serialization
+/// // See how the values get rounded, since subsecond precision is not allowed.
+///
+/// let ts = Timestamps {
+/// st_f64: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 500_000_000)).unwrap(),
+/// st_string: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 999_999_000)).unwrap(),
+/// };
+/// // Observe the different data types
+/// let expected = json!({
+/// "st_f64": 12345.5,
+/// "st_string": "12345.999999",
+/// });
+/// assert_eq!(expected, serde_json::to_value(&ts).unwrap());
+///
+/// // Deserialization works too
+/// // Subsecond precision in numbers will be rounded away
+///
+/// let json = json!({
+/// "st_f64": 12345.5,
+/// "st_string": "12345.987654",
+/// });
+/// let expected = Timestamps {
+/// st_f64: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 500_000_000)).unwrap(),
+/// st_string: SystemTime::UNIX_EPOCH.checked_add(Duration::new(12345, 987_654_000)).unwrap(),
+/// };
+/// assert_eq!(expected, serde_json::from_value(json).unwrap());
+/// # }
+/// ```
+///
+/// [`chrono::DateTime<Utc>`][DateTime] and [`chrono::DateTime<Local>`][DateTime] are also supported when using the `chrono` feature.
+/// Like [`SystemTime`], it is a signed timestamp, thus can be de/serialized as an `i64`.
+///
+/// ```rust
+/// # #[cfg(all(feature = "macros", feature = "chrono"))] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, TimestampSecondsWithFrac};
+/// # use chrono_crate::{DateTime, Local, TimeZone, Utc};
+/// # /* Ugliness to make the docs look nicer since I want to hide the rename of the chrono crate
+/// use chrono::{DateTime, Local, TimeZone, Utc};
+/// # */
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Timestamps {
+/// #[serde_as(as = "TimestampSecondsWithFrac<f64>")]
+/// dt_f64: DateTime<Utc>,
+/// #[serde_as(as = "TimestampSecondsWithFrac<String>")]
+/// dt_string: DateTime<Local>,
+/// };
+///
+/// // Serialization
+///
+/// let ts = Timestamps {
+/// dt_f64: Utc.timestamp(-12345, 500_000_000),
+/// dt_string: Local.timestamp(12345, 999_999_000),
+/// };
+/// // Observe the different data types
+/// let expected = json!({
+/// "dt_f64": -12344.5,
+/// "dt_string": "12345.999999",
+/// });
+/// assert_eq!(expected, serde_json::to_value(&ts).unwrap());
+///
+/// // Deserialization works too
+///
+/// let json = json!({
+/// "dt_f64": -12344.5,
+/// "dt_string": "12345.987",
+/// });
+/// let expected = Timestamps {
+/// dt_f64: Utc.timestamp(-12345, 500_000_000),
+/// dt_string: Local.timestamp(12345, 987_000_000),
+/// };
+/// assert_eq!(expected, serde_json::from_value(json).unwrap());
+/// # }
+/// ```
+///
+/// [`SystemTime`]: std::time::SystemTime
+/// [DateTime]: chrono_crate::DateTime
+/// [NaiveDateTime]: chrono_crate::NaiveDateTime
+/// [feature flag]: https://docs.rs/serde_with/1.14.0/serde_with/guide/feature_flags/index.html
+#[derive(Copy, Clone, Debug, Default)]
+pub struct TimestampSecondsWithFrac<
+ FORMAT: formats::Format = f64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`TimestampSeconds`] with milli-seconds as base unit.
+///
+/// This type is equivalent to [`TimestampSeconds`] except that each unit represents 1 milli-second instead of 1 second for [`TimestampSeconds`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct TimestampMilliSeconds<
+ FORMAT: formats::Format = i64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`TimestampSecondsWithFrac`] with milli-seconds as base unit.
+///
+/// This type is equivalent to [`TimestampSecondsWithFrac`] except that each unit represents 1 milli-second instead of 1 second for [`TimestampSecondsWithFrac`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct TimestampMilliSecondsWithFrac<
+ FORMAT: formats::Format = f64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`TimestampSeconds`] with micro-seconds as base unit.
+///
+/// This type is equivalent to [`TimestampSeconds`] except that each unit represents 1 micro-second instead of 1 second for [`TimestampSeconds`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct TimestampMicroSeconds<
+ FORMAT: formats::Format = i64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`TimestampSecondsWithFrac`] with micro-seconds as base unit.
+///
+/// This type is equivalent to [`TimestampSecondsWithFrac`] except that each unit represents 1 micro-second instead of 1 second for [`TimestampSecondsWithFrac`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct TimestampMicroSecondsWithFrac<
+ FORMAT: formats::Format = f64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`TimestampSeconds`] with nano-seconds as base unit.
+///
+/// This type is equivalent to [`TimestampSeconds`] except that each unit represents 1 nano-second instead of 1 second for [`TimestampSeconds`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct TimestampNanoSeconds<
+ FORMAT: formats::Format = i64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Equivalent to [`TimestampSecondsWithFrac`] with nano-seconds as base unit.
+///
+/// This type is equivalent to [`TimestampSecondsWithFrac`] except that each unit represents 1 nano-second instead of 1 second for [`TimestampSecondsWithFrac`].
+#[derive(Copy, Clone, Debug, Default)]
+pub struct TimestampNanoSecondsWithFrac<
+ FORMAT: formats::Format = f64,
+ STRICTNESS: formats::Strictness = formats::Strict,
+>(PhantomData<(FORMAT, STRICTNESS)>);
+
+/// Optimized handling of owned and borrowed byte representations.
+///
+/// Serialization of byte sequences like `&[u8]` or `Vec<u8>` is quite inefficient since each value will be serialized individually.
+/// This converter type optimizes the serialization and deserialization.
+///
+/// This is a port of the [`serde_bytes`] crate making it compatible with the `serde_as`-annotation, which allows it to be used in more cases than provided by [`serde_bytes`].
+///
+/// The type provides de/serialization for these types:
+///
+/// * `[u8; N]`, not possible using `serde_bytes`
+/// * `&[u8; N]`, not possible using `serde_bytes`
+/// * `&[u8]`
+/// * `Box<[u8; N]>`, not possible using `serde_bytes`
+/// * `Box<[u8]>`
+/// * `Vec<u8>`
+/// * `Cow<'_, [u8]>`
+/// * `Cow<'_, [u8; N]>`, not possible using `serde_bytes`
+///
+/// [`serde_bytes`]: https://crates.io/crates/serde_bytes
+///
+/// # Examples
+///
+/// ```
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::{serde_as, Bytes};
+/// # use std::borrow::Cow;
+/// #
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Test<'a> {
+/// # #[cfg(FALSE)]
+/// #[serde_as(as = "Bytes")]
+/// array: [u8; 15],
+/// #[serde_as(as = "Bytes")]
+/// boxed: Box<[u8]>,
+/// #[serde_as(as = "Bytes")]
+/// #[serde(borrow)]
+/// cow: Cow<'a, [u8]>,
+/// # #[cfg(FALSE)]
+/// #[serde_as(as = "Bytes")]
+/// #[serde(borrow)]
+/// cow_array: Cow<'a, [u8; 15]>,
+/// #[serde_as(as = "Bytes")]
+/// vec: Vec<u8>,
+/// }
+///
+/// let value = Test {
+/// # #[cfg(FALSE)]
+/// array: b"0123456789ABCDE".clone(),
+/// boxed: b"...".to_vec().into_boxed_slice(),
+/// cow: Cow::Borrowed(b"FooBar"),
+/// # #[cfg(FALSE)]
+/// cow_array: Cow::Borrowed(&[42u8; 15]),
+/// vec: vec![0x41, 0x61, 0x21],
+/// };
+/// let expected = r#"(
+/// array: "MDEyMzQ1Njc4OUFCQ0RF",
+/// boxed: "Li4u",
+/// cow: "Rm9vQmFy",
+/// cow_array: "KioqKioqKioqKioqKioq",
+/// vec: "QWEh",
+/// )"#;
+/// # drop(expected);
+/// # // Create a fake expected value that doesn't use const generics
+/// # let expected = r#"(
+/// # boxed: "Li4u",
+/// # cow: "Rm9vQmFy",
+/// # vec: "QWEh",
+/// # )"#;
+///
+/// # let pretty_config = ron::ser::PrettyConfig::new()
+/// # .new_line("\n".into());
+/// assert_eq!(expected, ron::ser::to_string_pretty(&value, pretty_config).unwrap());
+/// assert_eq!(value, ron::from_str(&expected).unwrap());
+/// # }
+/// ```
+///
+/// Fully borrowed types can also be used but you'll need a Deserializer that
+/// supports Serde's 0-copy deserialization:
+///
+/// ```
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::{serde_as, Bytes};
+/// # use std::borrow::Cow;
+/// #
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct TestBorrows<'a> {
+/// # #[cfg(FALSE)]
+/// #[serde_as(as = "Bytes")]
+/// #[serde(borrow)]
+/// array_buf: &'a [u8; 15],
+/// #[serde_as(as = "Bytes")]
+/// #[serde(borrow)]
+/// buf: &'a [u8],
+/// }
+///
+/// let value = TestBorrows {
+/// # #[cfg(FALSE)]
+/// array_buf: &[10u8; 15],
+/// buf: &[20u8, 21u8, 22u8],
+/// };
+/// let expected = r#"(
+/// array_buf: "CgoKCgoKCgoKCgoKCgoK",
+/// buf: "FBUW",
+/// )"#;
+/// # drop(expected);
+/// # // Create a fake expected value that doesn't use const generics
+/// # let expected = r#"(
+/// # buf: "FBUW",
+/// # )"#;
+///
+/// # let pretty_config = ron::ser::PrettyConfig::new()
+/// # .new_line("\n".into());
+/// assert_eq!(expected, ron::ser::to_string_pretty(&value, pretty_config).unwrap());
+/// // RON doesn't support borrowed deserialization of byte arrays
+/// # }
+/// ```
+///
+/// ## Alternative to [`BytesOrString`]
+///
+/// The [`Bytes`] can replace [`BytesOrString`].
+/// [`Bytes`] is implemented for more types, which makes it better.
+/// The serialization behavior of [`Bytes`] differs from [`BytesOrString`], therefore only `deserialize_as` should be used.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, Bytes};
+/// #
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, serde::Serialize)]
+/// struct Test {
+/// #[serde_as(deserialize_as = "Bytes")]
+/// from_bytes: Vec<u8>,
+/// #[serde_as(deserialize_as = "Bytes")]
+/// from_str: Vec<u8>,
+/// }
+///
+/// // Different serialized values ...
+/// let j = json!({
+/// "from_bytes": [70,111,111,45,66,97,114],
+/// "from_str": "Foo-Bar",
+/// });
+///
+/// // can be deserialized ...
+/// let test = Test {
+/// from_bytes: b"Foo-Bar".to_vec(),
+/// from_str: b"Foo-Bar".to_vec(),
+/// };
+/// assert_eq!(test, serde_json::from_value(j).unwrap());
+///
+/// // and serialization will always be a byte sequence
+/// # assert_eq!(json!(
+/// {
+/// "from_bytes": [70,111,111,45,66,97,114],
+/// "from_str": [70,111,111,45,66,97,114],
+/// }
+/// # ), serde_json::to_value(&test).unwrap());
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct Bytes;
+
+/// Deserialize one or many elements
+///
+/// Sometimes it is desirable to have a shortcut in writing 1-element lists in a config file.
+/// Usually, this is done by either writing a list or the list element itself.
+/// This distinction is not semantically important on the Rust side, thus both forms should deserialize into the same `Vec`.
+///
+/// The `OneOrMany` adapter achieves exactly this use case.
+/// The serialization behavior can be tweaked to either always serialize as a list using `PreferMany` or to serialize as the inner element if possible using `PreferOne`.
+/// By default, `PreferOne` is assumed, which can also be omitted like `OneOrMany<_>`.
+///
+/// # Examples
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, OneOrMany};
+/// # use serde_with::formats::{PreferOne, PreferMany};
+/// #
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, serde::Serialize)]
+/// struct Data {
+/// #[serde_as(deserialize_as = "OneOrMany<_, PreferOne>")]
+/// countries: Vec<String>,
+/// #[serde_as(deserialize_as = "OneOrMany<_, PreferMany>")]
+/// cities: Vec<String>,
+/// }
+///
+/// // The adapter allows deserializing a `Vec` from either
+/// // a single element
+/// let j = json!({
+/// "countries": "Spain",
+/// "cities": "Berlin",
+/// });
+/// assert!(serde_json::from_value::<Data>(j).is_ok());
+///
+/// // or from a list.
+/// let j = json!({
+/// "countries": ["Germany", "France"],
+/// "cities": ["Amsterdam"],
+/// });
+/// assert!(serde_json::from_value::<Data>(j).is_ok());
+///
+/// // For serialization you can choose how a single element should be encoded.
+/// // Either directly, with `PreferOne` (default), or as a list with `PreferMany`.
+/// let data = Data {
+/// countries: vec!["Spain".to_string()],
+/// cities: vec!["Berlin".to_string()],
+/// };
+/// let j = json!({
+/// "countries": "Spain",
+/// "cities": ["Berlin"],
+/// });
+/// assert_eq!(data, serde_json::from_value(j).unwrap());
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct OneOrMany<T, FORMAT: formats::Format = formats::PreferOne>(PhantomData<(T, FORMAT)>);
+
+/// Try multiple deserialization options until one succeeds.
+///
+/// This adapter allows you to specify a list of deserialization options.
+/// They are tried in order and the first one working is applied.
+/// Serialization always picks the first option.
+///
+/// `PickFirst` has one type parameter which must be instantiated with a tuple of two, three, or four elements.
+/// For example, `PickFirst<(_, DisplayFromStr)>` on a field of type `u32` allows deserializing from a number or from a string via the `FromStr` trait.
+/// The value will be serialized as a number, since that is what the first type `_` indicates.
+///
+/// # Examples
+///
+/// Deserialize a number from either a number or a string.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, DisplayFromStr, PickFirst};
+/// #
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Data {
+/// #[serde_as(as = "PickFirst<(_, DisplayFromStr)>")]
+/// as_number: u32,
+/// #[serde_as(as = "PickFirst<(DisplayFromStr, _)>")]
+/// as_string: u32,
+/// }
+/// let data = Data {
+/// as_number: 123,
+/// as_string: 456
+/// };
+///
+/// // Both fields can be deserialized from numbers:
+/// let j = json!({
+/// "as_number": 123,
+/// "as_string": 456,
+/// });
+/// assert_eq!(data, serde_json::from_value(j).unwrap());
+///
+/// // or from a string:
+/// let j = json!({
+/// "as_number": "123",
+/// "as_string": "456",
+/// });
+/// assert_eq!(data, serde_json::from_value(j).unwrap());
+///
+/// // For serialization the first type in the tuple determines the behavior.
+/// // The `as_number` field will use the normal `Serialize` behavior and produce a number,
+/// // while `as_string` used `Display` to produce a string.
+/// let expected = json!({
+/// "as_number": 123,
+/// "as_string": "456",
+/// });
+/// assert_eq!(expected, serde_json::to_value(&data).unwrap());
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct PickFirst<T>(PhantomData<T>);
+
+/// Serialize value by converting to/from a proxy type with serde support.
+///
+/// This adapter serializes a type `O` by converting it into a second type `T` and serializing `T`.
+/// Deserializing works analogue, by deserializing a `T` and then converting into `O`.
+///
+/// ```rust
+/// # #[cfg(FALSE)] {
+/// struct S {
+/// #[serde_as(as = "FromInto<T>")]
+/// value: O,
+/// }
+/// # }
+/// ```
+///
+/// For serialization `O` needs to be `O: Into<T> + Clone`.
+/// For deserialization the opposite `T: Into<O>` is required.
+/// The `Clone` bound is required since `serialize` operates on a reference but `Into` implementations on references are uncommon.
+///
+/// **Note**: [`TryFromInto`] is the more generalized version of this adapter which uses the [`TryInto`](std::convert::TryInto) trait instead.
+///
+/// # Example
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, FromInto};
+/// #
+/// #[derive(Clone, Debug, PartialEq)]
+/// struct Rgb {
+/// red: u8,
+/// green: u8,
+/// blue: u8,
+/// }
+///
+/// # /*
+/// impl From<(u8, u8, u8)> for Rgb { ... }
+/// impl From<Rgb> for (u8, u8, u8) { ... }
+/// # */
+/// #
+/// # impl From<(u8, u8, u8)> for Rgb {
+/// # fn from(v: (u8, u8, u8)) -> Self {
+/// # Rgb {
+/// # red: v.0,
+/// # green: v.1,
+/// # blue: v.2,
+/// # }
+/// # }
+/// # }
+/// #
+/// # impl From<Rgb> for (u8, u8, u8) {
+/// # fn from(v: Rgb) -> Self {
+/// # (v.red, v.green, v.blue)
+/// # }
+/// # }
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Color {
+/// #[serde_as(as = "FromInto<(u8, u8, u8)>")]
+/// rgb: Rgb,
+/// }
+/// let color = Color {
+/// rgb: Rgb {
+/// red: 128,
+/// green: 64,
+/// blue: 32,
+/// },
+/// };
+///
+/// // Define our expected JSON form
+/// let j = json!({
+/// "rgb": [128, 64, 32],
+/// });
+/// // Ensure serialization and deserialization produce the expected results
+/// assert_eq!(j, serde_json::to_value(&color).unwrap());
+/// assert_eq!(color, serde_json::from_value(j).unwrap());
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct FromInto<T>(PhantomData<T>);
+
+/// Serialize value by converting to/from a proxy type with serde support.
+///
+/// This adapter serializes a type `O` by converting it into a second type `T` and serializing `T`.
+/// Deserializing works analogue, by deserializing a `T` and then converting into `O`.
+///
+/// ```rust
+/// # #[cfg(FALSE)] {
+/// struct S {
+/// #[serde_as(as = "TryFromInto<T>")]
+/// value: O,
+/// }
+/// # }
+/// ```
+///
+/// For serialization `O` needs to be `O: TryInto<T> + Clone`.
+/// For deserialization the opposite `T: TryInto<O>` is required.
+/// The `Clone` bound is required since `serialize` operates on a reference but `TryInto` implementations on references are uncommon.
+/// In both cases the `TryInto::Error` type must implement [`Display`](std::fmt::Display).
+///
+/// **Note**: [`FromInto`] is the more specialized version of this adapter which uses the infallible [`Into`] trait instead.
+/// [`TryFromInto`] is strictly more general and can also be used where [`FromInto`] is applicable.
+/// The example shows a use case, when only the deserialization behavior is fallible, but not serializing.
+///
+/// # Example
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, TryFromInto};
+/// # use std::convert::TryFrom;
+/// #
+/// #[derive(Clone, Debug, PartialEq)]
+/// enum Boollike {
+/// True,
+/// False,
+/// }
+///
+/// # /*
+/// impl From<Boollike> for u8 { ... }
+/// # */
+/// #
+/// impl TryFrom<u8> for Boollike {
+/// type Error = String;
+/// fn try_from(v: u8) -> Result<Self, Self::Error> {
+/// match v {
+/// 0 => Ok(Boollike::False),
+/// 1 => Ok(Boollike::True),
+/// _ => Err(format!("Boolikes can only be constructed from 0 or 1 but found {}", v))
+/// }
+/// }
+/// }
+/// #
+/// # impl From<Boollike> for u8 {
+/// # fn from(v: Boollike) -> Self {
+/// # match v {
+/// # Boollike::True => 1,
+/// # Boollike::False => 0,
+/// # }
+/// # }
+/// # }
+///
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Data {
+/// #[serde_as(as = "TryFromInto<u8>")]
+/// b: Boollike,
+/// }
+/// let data = Data {
+/// b: Boollike::True,
+/// };
+///
+/// // Define our expected JSON form
+/// let j = json!({
+/// "b": 1,
+/// });
+/// // Ensure serialization and deserialization produce the expected results
+/// assert_eq!(j, serde_json::to_value(&data).unwrap());
+/// assert_eq!(data, serde_json::from_value(j).unwrap());
+///
+/// // Numbers besides 0 or 1 should be an error
+/// let j = json!({
+/// "b": 2,
+/// });
+/// assert_eq!("Boolikes can only be constructed from 0 or 1 but found 2", serde_json::from_value::<Data>(j).unwrap_err().to_string());
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct TryFromInto<T>(PhantomData<T>);
+
+/// Borrow `Cow` data during deserialization when possible.
+///
+/// The types `Cow<'a, [u8]>`, `Cow<'a, [u8; N]>`, and `Cow<'a, str>` can borrow from the input data during deserialization.
+/// serde supports this, by annotating the fields with `#[serde(borrow)]`. but does not support borrowing on nested types.
+/// This gap is filled by this `BorrowCow` adapter.
+///
+/// Using this adapter with `Cow<'a, [u8]>`/Cow<'a, [u8; N]>` will serialize the value as a sequence of `u8` values.
+/// This *might* not allow to borrow the data during deserialization.
+/// For a different format, which is also more efficient, use the [`Bytes`] adapter, which is also implemented for `Cow`.
+///
+/// When combined with the [`serde_as`] attribute, the `#[serde(borrow)]` annotation will be added automatically.
+/// If the annotation is wrong or too broad, for example because of multiple lifetime parameters, a manual annotation is required.
+///
+/// # Examples
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::{serde_as, BorrowCow};
+/// # use std::borrow::Cow;
+/// #
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Data<'a, 'b, 'c> {
+/// #[serde_as(as = "BorrowCow")]
+/// str: Cow<'a, str>,
+/// #[serde_as(as = "BorrowCow")]
+/// slice: Cow<'b, [u8]>,
+///
+/// #[serde_as(as = "Option<[BorrowCow; 1]>")]
+/// nested: Option<[Cow<'c, str>; 1]>,
+/// }
+/// let data = Data {
+/// str: "foobar".into(),
+/// slice: b"foobar"[..].into(),
+/// nested: Some(["HelloWorld".into()]),
+/// };
+///
+/// // Define our expected JSON form
+/// let j = r#"{
+/// "str": "foobar",
+/// "slice": [
+/// 102,
+/// 111,
+/// 111,
+/// 98,
+/// 97,
+/// 114
+/// ],
+/// "nested": [
+/// "HelloWorld"
+/// ]
+/// }"#;
+/// // Ensure serialization and deserialization produce the expected results
+/// assert_eq!(j, serde_json::to_string_pretty(&data).unwrap());
+/// assert_eq!(data, serde_json::from_str(j).unwrap());
+///
+/// // Cow borrows from the input data
+/// let deserialized: Data<'_, '_, '_> = serde_json::from_str(j).unwrap();
+/// assert!(matches!(deserialized.str, Cow::Borrowed(_)));
+/// assert!(matches!(deserialized.nested, Some([Cow::Borrowed(_)])));
+/// // JSON does not allow borrowing bytes, so `slice` does not borrow
+/// assert!(matches!(deserialized.slice, Cow::Owned(_)));
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct BorrowCow;
+
+/// Deserialize a sequence into `Vec<T>`, skipping elements which fail to deserialize.
+///
+/// The serialization behavior is identical to `Vec<T>`. This is an alternative to `Vec<T>`
+/// which is resilient against unexpected data.
+///
+/// # Examples
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::{serde_as, VecSkipError};
+/// #
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// # #[non_exhaustive]
+/// enum Color {
+/// Red,
+/// Green,
+/// Blue,
+/// }
+/// # use Color::*;
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Palette(#[serde_as(as = "VecSkipError<_>")] Vec<Color>);
+///
+/// let data = Palette(vec![Blue, Green,]);
+/// let source_json = r#"["Blue", "Yellow", "Green"]"#;
+/// let data_json = r#"["Blue","Green"]"#;
+/// // Ensure serialization and deserialization produce the expected results
+/// assert_eq!(data_json, serde_json::to_string(&data).unwrap());
+/// assert_eq!(data, serde_json::from_str(source_json).unwrap());
+/// # }
+/// ```
+
+#[derive(Copy, Clone, Debug, Default)]
+pub struct VecSkipError<T>(PhantomData<T>);
+
+/// Deserialize a boolean from a number
+///
+/// Deserialize a number (of `u8`) and turn it into a boolean.
+/// The adapter supports a [`Strict`](crate::formats::Strict) and [`Flexible`](crate::formats::Flexible) format.
+/// In `Strict` mode, the number must be `0` or `1`.
+/// All other values produce an error.
+/// In `Flexible` mode, the number any non-zero value is converted to `true`.
+///
+/// During serialization only `0` or `1` are ever emitted.
+///
+/// # Examples
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::{serde_as, BoolFromInt};
+/// #
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Data(#[serde_as(as = "BoolFromInt")] bool);
+///
+/// let data = Data(true);
+/// let j = json!(1);
+/// // Ensure serialization and deserialization produce the expected results
+/// assert_eq!(j, serde_json::to_value(&data).unwrap());
+/// assert_eq!(data, serde_json::from_value(j).unwrap());
+///
+/// // false maps to 0
+/// let data = Data(false);
+/// let j = json!(0);
+/// assert_eq!(j, serde_json::to_value(&data).unwrap());
+/// assert_eq!(data, serde_json::from_value(j).unwrap());
+//
+/// #[serde_as]
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Flexible(#[serde_as(as = "BoolFromInt<serde_with::formats::Flexible>")] bool);
+///
+/// // Flexible turns any non-zero number into true
+/// let data = Flexible(true);
+/// let j = json!(100);
+/// assert_eq!(data, serde_json::from_value(j).unwrap());
+/// # }
+/// ```
+#[derive(Copy, Clone, Debug, Default)]
+pub struct BoolFromInt<S: formats::Strictness = formats::Strict>(PhantomData<S>);
diff --git a/third_party/rust/serde_with/src/rust.rs b/third_party/rust/serde_with/src/rust.rs
new file mode 100644
index 0000000000..cb64f0da9f
--- /dev/null
+++ b/third_party/rust/serde_with/src/rust.rs
@@ -0,0 +1,1943 @@
+//! De/Serialization for Rust's builtin and std types
+
+use crate::{utils, Separator};
+#[cfg(doc)]
+use alloc::collections::BTreeMap;
+use alloc::{
+ string::{String, ToString},
+ vec::Vec,
+};
+use core::{
+ cmp::Eq,
+ fmt::{self, Display},
+ hash::Hash,
+ iter::FromIterator,
+ marker::PhantomData,
+ str::FromStr,
+};
+use serde::{
+ de::{Deserialize, DeserializeOwned, Deserializer, Error, MapAccess, SeqAccess, Visitor},
+ ser::{Serialize, Serializer},
+};
+#[cfg(doc)]
+use std::collections::HashMap;
+
+/// De/Serialize using [`Display`] and [`FromStr`] implementation
+///
+/// This allows deserializing a string as a number.
+/// It can be very useful for serialization formats like JSON, which do not support integer
+/// numbers and have to resort to strings to represent them.
+///
+/// If you control the type you want to de/serialize, you can instead use the two derive macros, [`SerializeDisplay`] and [`DeserializeFromStr`].
+/// They properly implement the traits [`Serialize`] and [`Deserialize`] such that user of the type no longer have to use the with-attribute.
+///
+/// ## Converting to `serde_as`
+///
+/// The same functionality can be more clearly expressed via [`DisplayFromStr`] and using the [`serde_as`] macro.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_with::{serde_as, DisplayFromStr};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize)]
+/// struct A {
+/// #[serde_as(as = "DisplayFromStr")]
+/// value: mime::Mime,
+/// }
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// ```rust
+/// # use serde::{Deserialize, Serialize};
+/// #
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde(with = "serde_with::rust::display_fromstr")]
+/// mime: mime::Mime,
+/// #[serde(with = "serde_with::rust::display_fromstr")]
+/// number: u32,
+/// }
+///
+/// let v: A = serde_json::from_str(r#"{
+/// "mime": "text/plain",
+/// "number": "159"
+/// }"#).unwrap();
+/// assert_eq!(mime::TEXT_PLAIN, v.mime);
+/// assert_eq!(159, v.number);
+///
+/// let x = A {
+/// mime: mime::STAR_STAR,
+/// number: 777,
+/// };
+/// assert_eq!(
+/// r#"{"mime":"*/*","number":"777"}"#,
+/// serde_json::to_string(&x).unwrap()
+/// );
+/// ```
+///
+/// [`DeserializeFromStr`]: serde_with_macros::DeserializeFromStr
+/// [`DisplayFromStr`]: crate::DisplayFromStr
+/// [`serde_as`]: crate::guide::serde_as
+/// [`SerializeDisplay`]: serde_with_macros::SerializeDisplay
+pub mod display_fromstr {
+ use super::*;
+
+ /// Deserialize T using [`FromStr`]
+ pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ T: FromStr,
+ T::Err: Display,
+ {
+ struct Helper<S>(PhantomData<S>);
+
+ impl<'de, S> Visitor<'de> for Helper<S>
+ where
+ S: FromStr,
+ <S as FromStr>::Err: Display,
+ {
+ type Value = S;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(formatter, "a string")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ value.parse::<Self::Value>().map_err(Error::custom)
+ }
+ }
+
+ deserializer.deserialize_str(Helper(PhantomData))
+ }
+
+ /// Serialize T using [Display]
+ pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: Display,
+ S: Serializer,
+ {
+ serializer.collect_str(&value)
+ }
+}
+
+/// De/Serialize sequences using [`FromIterator`] and [`IntoIterator`] implementation for it and [`Display`] and [`FromStr`] implementation for each element
+///
+/// This allows to serialize and deserialize collections with elements which can be represented as strings.
+///
+/// ## Converting to `serde_as`
+///
+/// The same functionality can be more clearly expressed via [`DisplayFromStr`] and using the [`serde_as`] macro.
+/// Instead of
+///
+/// ```rust,ignore
+/// #[serde(with = "serde_with::rust::seq_display_fromstr")]
+/// addresses: BTreeSet<Ipv4Addr>,
+/// ```
+/// you can write:
+/// ```rust,ignore
+/// #[serde_as(as = "BTreeSet<DisplayFromStr>")]
+/// addresses: BTreeSet<Ipv4Addr>,
+/// ```
+///
+/// This works for any container type, so also for `Vec`:
+/// ```rust,ignore
+/// #[serde_as(as = "Vec<DisplayFromStr>")]
+/// bs: Vec<bool>,
+/// ```
+///
+/// # Examples
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// #
+/// use std::collections::BTreeSet;
+/// use std::net::Ipv4Addr;
+///
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde(with = "serde_with::rust::seq_display_fromstr")]
+/// addresses: BTreeSet<Ipv4Addr>,
+/// #[serde(with = "serde_with::rust::seq_display_fromstr")]
+/// bs: Vec<bool>,
+/// }
+///
+/// let v: A = serde_json::from_str(r#"{
+/// "addresses": ["192.168.2.1", "192.168.2.2", "192.168.1.1", "192.168.2.2"],
+/// "bs": ["true", "false"]
+/// }"#).unwrap();
+/// assert_eq!(v.addresses.len(), 3);
+/// assert!(v.addresses.contains(&Ipv4Addr::new(192, 168, 2, 1)));
+/// assert!(v.addresses.contains(&Ipv4Addr::new(192, 168, 2, 2)));
+/// assert!(!v.addresses.contains(&Ipv4Addr::new(192, 168, 1, 2)));
+/// assert_eq!(v.bs.len(), 2);
+/// assert!(v.bs[0]);
+/// assert!(!v.bs[1]);
+///
+/// let x = A {
+/// addresses: vec![
+/// Ipv4Addr::new(127, 53, 0, 1),
+/// Ipv4Addr::new(127, 53, 1, 1),
+/// Ipv4Addr::new(127, 53, 0, 2)
+/// ].into_iter().collect(),
+/// bs: vec![false, true],
+/// };
+/// assert_eq!(
+/// r#"{"addresses":["127.53.0.1","127.53.0.2","127.53.1.1"],"bs":["false","true"]}"#,
+/// serde_json::to_string(&x).unwrap()
+/// );
+/// ```
+///
+/// [`DisplayFromStr`]: crate::DisplayFromStr
+/// [`serde_as`]: crate::guide::serde_as
+pub mod seq_display_fromstr {
+ use super::*;
+
+ /// Deserialize collection T using [FromIterator] and [FromStr] for each element
+ pub fn deserialize<'de, D, T, I>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ T: FromIterator<I> + Sized,
+ I: FromStr,
+ I::Err: Display,
+ {
+ struct Helper<S>(PhantomData<S>);
+
+ impl<'de, S> Visitor<'de> for Helper<S>
+ where
+ S: FromStr,
+ <S as FromStr>::Err: Display,
+ {
+ type Value = Vec<S>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(formatter, "a sequence")
+ }
+
+ fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ utils::SeqIter::new(seq)
+ .map(|res| {
+ res.and_then(|value: &str| value.parse::<S>().map_err(Error::custom))
+ })
+ .collect()
+ }
+ }
+
+ deserializer
+ .deserialize_seq(Helper(PhantomData))
+ .map(T::from_iter)
+ }
+
+ /// Serialize collection T using [IntoIterator] and [Display] for each element
+ pub fn serialize<S, T, I>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ for<'a> &'a T: IntoIterator<Item = &'a I>,
+ I: Display,
+ {
+ struct SerializeString<'a, I>(&'a I);
+
+ impl<'a, I> Serialize for SerializeString<'a, I>
+ where
+ I: Display,
+ {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_str(self.0)
+ }
+ }
+
+ serializer.collect_seq(value.into_iter().map(SerializeString))
+ }
+}
+
+/// De/Serialize a delimited collection using [`Display`] and [`FromStr`] implementation
+///
+/// You can define an arbitrary separator, by specifying a type which implements [`Separator`].
+/// Some common ones, like space and comma are already predefined and you can find them [here][Separator].
+///
+/// An empty string deserializes as an empty collection.
+///
+/// ## Converting to `serde_as`
+///
+/// The same functionality can also be expressed using the [`serde_as`] macro.
+/// The usage is slightly different.
+/// `StringWithSeparator` takes a second type, which needs to implement [`Display`]+[`FromStr`] and constitutes the inner type of the collection.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_with::{serde_as, SpaceSeparator, StringWithSeparator};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize)]
+/// struct A {
+/// #[serde_as(as = "StringWithSeparator::<SpaceSeparator, String>")]
+/// tags: Vec<String>,
+/// }
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// #
+/// use serde_with::{CommaSeparator, SpaceSeparator};
+/// use std::collections::BTreeSet;
+///
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde(with = "serde_with::rust::StringWithSeparator::<SpaceSeparator>")]
+/// tags: Vec<String>,
+/// #[serde(with = "serde_with::rust::StringWithSeparator::<CommaSeparator>")]
+/// more_tags: BTreeSet<String>,
+/// }
+///
+/// let v: A = serde_json::from_str(r##"{
+/// "tags": "#hello #world",
+/// "more_tags": "foo,bar,bar"
+/// }"##).unwrap();
+/// assert_eq!(vec!["#hello", "#world"], v.tags);
+/// assert_eq!(2, v.more_tags.len());
+///
+/// let x = A {
+/// tags: vec!["1".to_string(), "2".to_string(), "3".to_string()],
+/// more_tags: BTreeSet::new(),
+/// };
+/// assert_eq!(
+/// r#"{"tags":"1 2 3","more_tags":""}"#,
+/// serde_json::to_string(&x).unwrap()
+/// );
+/// ```
+///
+/// [`serde_as`]: crate::guide::serde_as
+#[derive(Copy, Clone, Eq, PartialEq, Ord, PartialOrd, Hash, Debug, Default)]
+pub struct StringWithSeparator<Sep, T = ()>(PhantomData<(Sep, T)>);
+
+impl<Sep> StringWithSeparator<Sep>
+where
+ Sep: Separator,
+{
+ /// Serialize collection into a string with separator symbol
+ pub fn serialize<S, T, V>(values: T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ T: IntoIterator<Item = V>,
+ V: Display,
+ {
+ let mut s = String::new();
+ for v in values {
+ s.push_str(&*v.to_string());
+ s.push_str(Sep::separator());
+ }
+ serializer.serialize_str(if !s.is_empty() {
+ // remove trailing separator if present
+ &s[..s.len() - Sep::separator().len()]
+ } else {
+ &s[..]
+ })
+ }
+
+ /// Deserialize a collection from a string with separator symbol
+ pub fn deserialize<'de, D, T, V>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ T: FromIterator<V>,
+ V: FromStr,
+ V::Err: Display,
+ {
+ let s = String::deserialize(deserializer)?;
+ if s.is_empty() {
+ Ok(None.into_iter().collect())
+ } else {
+ s.split(Sep::separator())
+ .map(FromStr::from_str)
+ .collect::<Result<_, _>>()
+ .map_err(Error::custom)
+ }
+ }
+}
+
+/// Makes a distinction between a missing, unset, or existing value
+///
+/// Some serialization formats make a distinction between missing fields, fields with a `null`
+/// value, and existing values. One such format is JSON. By default it is not easily possible to
+/// differentiate between a missing value and a field which is `null`, as they deserialize to the
+/// same value. This helper changes it, by using an `Option<Option<T>>` to deserialize into.
+///
+/// * `None`: Represents a missing value.
+/// * `Some(None)`: Represents a `null` value.
+/// * `Some(Some(value))`: Represents an existing value.
+///
+/// # Examples
+///
+/// ```rust
+/// # use serde::{Deserialize, Serialize};
+/// #
+/// # #[derive(Debug, PartialEq, Eq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Doc {
+/// #[serde(
+/// default, // <- important for deserialization
+/// skip_serializing_if = "Option::is_none", // <- important for serialization
+/// with = "::serde_with::rust::double_option",
+/// )]
+/// a: Option<Option<u8>>,
+/// }
+/// // Missing Value
+/// let s = r#"{}"#;
+/// assert_eq!(Doc { a: None }, serde_json::from_str(s).unwrap());
+/// assert_eq!(s, serde_json::to_string(&Doc { a: None }).unwrap());
+///
+/// // Unset Value
+/// let s = r#"{"a":null}"#;
+/// assert_eq!(Doc { a: Some(None) }, serde_json::from_str(s).unwrap());
+/// assert_eq!(s, serde_json::to_string(&Doc { a: Some(None) }).unwrap());
+///
+/// // Existing Value
+/// let s = r#"{"a":5}"#;
+/// assert_eq!(Doc { a: Some(Some(5)) }, serde_json::from_str(s).unwrap());
+/// assert_eq!(s, serde_json::to_string(&Doc { a: Some(Some(5)) }).unwrap());
+/// ```
+#[allow(clippy::option_option)]
+pub mod double_option {
+ use super::*;
+
+ /// Deserialize potentially non-existing optional value
+ pub fn deserialize<'de, T, D>(deserializer: D) -> Result<Option<Option<T>>, D::Error>
+ where
+ T: Deserialize<'de>,
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer).map(Some)
+ }
+
+ /// Serialize optional value
+ pub fn serialize<S, T>(values: &Option<Option<T>>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ T: Serialize,
+ {
+ match values {
+ None => serializer.serialize_unit(),
+ Some(None) => serializer.serialize_none(),
+ Some(Some(v)) => serializer.serialize_some(&v),
+ }
+ }
+}
+
+/// Serialize inner value if [`Some`]`(T)`. If [`None`], serialize the unit struct `()`.
+///
+/// When used in conjunction with `skip_serializing_if = "Option::is_none"` and
+/// `default`, you can build an optional value by skipping if it is [`None`], or serializing its
+/// inner value if [`Some`]`(T)`.
+///
+/// Not all serialization formats easily support optional values.
+/// While JSON uses the [`Option`] type to represent optional values and only serializes the inner
+/// part of the [`Some`]`()`, other serialization formats, such as [RON][], choose to serialize the
+/// [`Some`] around a value.
+/// This helper helps building a truly optional value for such serializers.
+///
+/// [RON]: https://github.com/ron-rs/ron
+///
+/// # Example
+///
+/// ```rust
+/// # use serde::{Deserialize, Serialize};
+/// #
+/// # #[derive(Debug, Eq, PartialEq)]
+/// #[derive(Deserialize, Serialize)]
+/// struct Doc {
+/// mandatory: usize,
+/// #[serde(
+/// default, // <- important for deserialization
+/// skip_serializing_if = "Option::is_none", // <- important for serialization
+/// with = "::serde_with::rust::unwrap_or_skip",
+/// )]
+/// optional: Option<usize>,
+/// }
+///
+/// // Transparently add/remove Some() wrapper
+/// # let pretty_config = ron::ser::PrettyConfig::new()
+/// # .new_line("\n".into());
+/// let s = r#"(
+/// mandatory: 1,
+/// optional: 2,
+/// )"#;
+/// let v = Doc {
+/// mandatory: 1,
+/// optional: Some(2),
+/// };
+/// assert_eq!(v, ron::de::from_str(s).unwrap());
+/// assert_eq!(s, ron::ser::to_string_pretty(&v, pretty_config).unwrap());
+///
+/// // Missing values are deserialized as `None`
+/// // while `None` values are skipped during serialization.
+/// # let pretty_config = ron::ser::PrettyConfig::new()
+/// # .new_line("\n".into());
+/// let s = r#"(
+/// mandatory: 1,
+/// )"#;
+/// let v = Doc {
+/// mandatory: 1,
+/// optional: None,
+/// };
+/// assert_eq!(v, ron::de::from_str(s).unwrap());
+/// assert_eq!(s, ron::ser::to_string_pretty(&v, pretty_config).unwrap());
+/// ```
+pub mod unwrap_or_skip {
+ use super::*;
+
+ /// Deserialize value wrapped in Some(T)
+ pub fn deserialize<'de, D, T>(deserializer: D) -> Result<Option<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ T: DeserializeOwned,
+ {
+ T::deserialize(deserializer).map(Some)
+ }
+
+ /// Serialize value if Some(T), unit struct if None
+ pub fn serialize<T, S>(option: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: Serialize,
+ S: Serializer,
+ {
+ if let Some(value) = option {
+ value.serialize(serializer)
+ } else {
+ ().serialize(serializer)
+ }
+ }
+}
+
+/// Ensure no duplicate values exist in a set.
+///
+/// By default serde has a last-value-wins implementation, if duplicate values for a set exist.
+/// Sometimes it is desirable to know when such an event happens, as the first value is overwritten
+/// and it can indicate an error in the serialized data.
+///
+/// This helper returns an error if two identical values exist in a set.
+///
+/// The implementation supports both the [`HashSet`] and the [`BTreeSet`] from the standard library.
+///
+/// [`HashSet`]: std::collections::HashSet
+/// [`BTreeSet`]: std::collections::HashSet
+///
+/// # Example
+///
+/// ```rust
+/// # use std::{collections::HashSet, iter::FromIterator};
+/// # use serde::Deserialize;
+/// #
+/// # #[derive(Debug, Eq, PartialEq)]
+/// #[derive(Deserialize)]
+/// struct Doc {
+/// #[serde(with = "::serde_with::rust::sets_duplicate_value_is_error")]
+/// set: HashSet<usize>,
+/// }
+///
+/// // Sets are serialized normally,
+/// let s = r#"{"set": [1, 2, 3, 4]}"#;
+/// let v = Doc {
+/// set: HashSet::from_iter(vec![1, 2, 3, 4]),
+/// };
+/// assert_eq!(v, serde_json::from_str(s).unwrap());
+///
+/// // but create an error if duplicate values, like the `1`, exist.
+/// let s = r#"{"set": [1, 2, 3, 4, 1]}"#;
+/// let res: Result<Doc, _> = serde_json::from_str(s);
+/// assert!(res.is_err());
+/// ```
+pub mod sets_duplicate_value_is_error {
+ use super::*;
+ use crate::duplicate_key_impls::PreventDuplicateInsertsSet;
+
+ /// Deserialize a set and return an error on duplicate values
+ pub fn deserialize<'de, D, T, V>(deserializer: D) -> Result<T, D::Error>
+ where
+ T: PreventDuplicateInsertsSet<V>,
+ V: Deserialize<'de>,
+ D: Deserializer<'de>,
+ {
+ struct SeqVisitor<T, V> {
+ marker: PhantomData<T>,
+ set_item_type: PhantomData<V>,
+ }
+
+ impl<'de, T, V> Visitor<'de> for SeqVisitor<T, V>
+ where
+ T: PreventDuplicateInsertsSet<V>,
+ V: Deserialize<'de>,
+ {
+ type Value = T;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ #[inline]
+ fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut values = Self::Value::new(access.size_hint());
+
+ while let Some(value) = access.next_element()? {
+ if !values.insert(value) {
+ return Err(Error::custom("invalid entry: found duplicate value"));
+ };
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = SeqVisitor {
+ marker: PhantomData,
+ set_item_type: PhantomData,
+ };
+ deserializer.deserialize_seq(visitor)
+ }
+
+ /// Serialize the set with the default serializer
+ pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: Serialize,
+ S: Serializer,
+ {
+ value.serialize(serializer)
+ }
+}
+
+/// Ensure no duplicate keys exist in a map.
+///
+/// By default serde has a last-value-wins implementation, if duplicate keys for a map exist.
+/// Sometimes it is desirable to know when such an event happens, as the first value is overwritten
+/// and it can indicate an error in the serialized data.
+///
+/// This helper returns an error if two identical keys exist in a map.
+///
+/// The implementation supports both the [`HashMap`] and the [`BTreeMap`] from the standard library.
+///
+/// [`HashMap`]: std::collections::HashMap
+/// [`BTreeMap`]: std::collections::HashMap
+///
+/// # Example
+///
+/// ```rust
+/// # use serde::Deserialize;
+/// # use std::collections::HashMap;
+/// #
+/// # #[derive(Debug, Eq, PartialEq)]
+/// #[derive(Deserialize)]
+/// struct Doc {
+/// #[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")]
+/// map: HashMap<usize, usize>,
+/// }
+///
+/// // Maps are serialized normally,
+/// let s = r#"{"map": {"1": 1, "2": 2, "3": 3}}"#;
+/// let mut v = Doc {
+/// map: HashMap::new(),
+/// };
+/// v.map.insert(1, 1);
+/// v.map.insert(2, 2);
+/// v.map.insert(3, 3);
+/// assert_eq!(v, serde_json::from_str(s).unwrap());
+///
+/// // but create an error if duplicate keys, like the `1`, exist.
+/// let s = r#"{"map": {"1": 1, "2": 2, "1": 3}}"#;
+/// let res: Result<Doc, _> = serde_json::from_str(s);
+/// assert!(res.is_err());
+/// ```
+pub mod maps_duplicate_key_is_error {
+ use super::*;
+ use crate::duplicate_key_impls::PreventDuplicateInsertsMap;
+
+ /// Deserialize a map and return an error on duplicate keys
+ pub fn deserialize<'de, D, T, K, V>(deserializer: D) -> Result<T, D::Error>
+ where
+ T: PreventDuplicateInsertsMap<K, V>,
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+ D: Deserializer<'de>,
+ {
+ struct MapVisitor<T, K, V> {
+ marker: PhantomData<T>,
+ map_key_type: PhantomData<K>,
+ map_value_type: PhantomData<V>,
+ }
+
+ impl<'de, T, K, V> Visitor<'de> for MapVisitor<T, K, V>
+ where
+ T: PreventDuplicateInsertsMap<K, V>,
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+ {
+ type Value = T;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a map")
+ }
+
+ #[inline]
+ fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let mut values = Self::Value::new(access.size_hint());
+
+ while let Some((key, value)) = access.next_entry()? {
+ if !values.insert(key, value) {
+ return Err(Error::custom("invalid entry: found duplicate key"));
+ };
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = MapVisitor {
+ marker: PhantomData,
+ map_key_type: PhantomData,
+ map_value_type: PhantomData,
+ };
+ deserializer.deserialize_map(visitor)
+ }
+
+ /// Serialize the map with the default serializer
+ pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: Serialize,
+ S: Serializer,
+ {
+ value.serialize(serializer)
+ }
+}
+
+/// *DEPRECATED* Ensure that the first value is taken, if duplicate values exist
+///
+/// This module implements the default behavior in serde.
+#[deprecated = "This module does nothing. Remove the attribute. Serde's default behavior is to use the first value when deserializing a set."]
+#[allow(deprecated)]
+pub mod sets_first_value_wins {
+ use super::*;
+ use crate::duplicate_key_impls::DuplicateInsertsFirstWinsSet;
+
+ /// Deserialize a set and keep the first of equal values
+ #[deprecated = "This function does nothing. Remove the attribute. Serde's default behavior is to use the first value when deserializing a set."]
+ pub fn deserialize<'de, D, T, V>(deserializer: D) -> Result<T, D::Error>
+ where
+ T: DuplicateInsertsFirstWinsSet<V>,
+ V: Deserialize<'de>,
+ D: Deserializer<'de>,
+ {
+ struct SeqVisitor<T, V> {
+ marker: PhantomData<T>,
+ set_item_type: PhantomData<V>,
+ }
+
+ impl<'de, T, V> Visitor<'de> for SeqVisitor<T, V>
+ where
+ T: DuplicateInsertsFirstWinsSet<V>,
+ V: Deserialize<'de>,
+ {
+ type Value = T;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ #[inline]
+ fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut values = Self::Value::new(access.size_hint());
+
+ while let Some(value) = access.next_element()? {
+ values.insert(value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = SeqVisitor {
+ marker: PhantomData,
+ set_item_type: PhantomData,
+ };
+ deserializer.deserialize_seq(visitor)
+ }
+
+ /// Serialize the set with the default serializer
+ #[deprecated = "This function does nothing. Remove the attribute. Serde's default behavior is to use the first value when deserializing a set."]
+ pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: Serialize,
+ S: Serializer,
+ {
+ value.serialize(serializer)
+ }
+}
+
+/// Ensure that the last value is taken, if duplicate values exist
+///
+/// By default serde has a first-value-wins implementation, if duplicate keys for a set exist.
+/// Sometimes the opposite strategy is desired. This helper implements a first-value-wins strategy.
+///
+/// The implementation supports both the [`HashSet`] and the [`BTreeSet`] from the standard library.
+///
+/// [`HashSet`]: std::collections::HashSet
+/// [`BTreeSet`]: std::collections::HashSet
+pub mod sets_last_value_wins {
+ use super::*;
+ use crate::duplicate_key_impls::DuplicateInsertsLastWinsSet;
+
+ /// Deserialize a set and keep the last of equal values
+ pub fn deserialize<'de, D, T, V>(deserializer: D) -> Result<T, D::Error>
+ where
+ T: DuplicateInsertsLastWinsSet<V>,
+ V: Deserialize<'de>,
+ D: Deserializer<'de>,
+ {
+ struct SeqVisitor<T, V> {
+ marker: PhantomData<T>,
+ set_item_type: PhantomData<V>,
+ }
+
+ impl<'de, T, V> Visitor<'de> for SeqVisitor<T, V>
+ where
+ T: DuplicateInsertsLastWinsSet<V>,
+ V: Deserialize<'de>,
+ {
+ type Value = T;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ #[inline]
+ fn visit_seq<A>(self, mut access: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut values = Self::Value::new(access.size_hint());
+
+ while let Some(value) = access.next_element()? {
+ values.replace(value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = SeqVisitor {
+ marker: PhantomData,
+ set_item_type: PhantomData,
+ };
+ deserializer.deserialize_seq(visitor)
+ }
+
+ /// Serialize the set with the default serializer
+ pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: Serialize,
+ S: Serializer,
+ {
+ value.serialize(serializer)
+ }
+}
+
+/// Ensure that the first key is taken, if duplicate keys exist
+///
+/// By default serde has a last-key-wins implementation, if duplicate keys for a map exist.
+/// Sometimes the opposite strategy is desired. This helper implements a first-key-wins strategy.
+///
+/// The implementation supports both the [`HashMap`] and the [`BTreeMap`] from the standard library.
+///
+/// [`HashMap`]: std::collections::HashMap
+/// [`BTreeMap`]: std::collections::HashMap
+///
+/// # Example
+///
+/// ```rust
+/// # use serde::Deserialize;
+/// # use std::collections::HashMap;
+/// #
+/// # #[derive(Debug, Eq, PartialEq)]
+/// #[derive(Deserialize)]
+/// struct Doc {
+/// #[serde(with = "::serde_with::rust::maps_first_key_wins")]
+/// map: HashMap<usize, usize>,
+/// }
+///
+/// // Maps are serialized normally,
+/// let s = r#"{"map": {"1": 1, "2": 2, "3": 3}}"#;
+/// let mut v = Doc {
+/// map: HashMap::new(),
+/// };
+/// v.map.insert(1, 1);
+/// v.map.insert(2, 2);
+/// v.map.insert(3, 3);
+/// assert_eq!(v, serde_json::from_str(s).unwrap());
+///
+/// // but create an error if duplicate keys, like the `1`, exist.
+/// let s = r#"{"map": {"1": 1, "2": 2, "1": 3}}"#;
+/// let mut v = Doc {
+/// map: HashMap::new(),
+/// };
+/// v.map.insert(1, 1);
+/// v.map.insert(2, 2);
+/// assert_eq!(v, serde_json::from_str(s).unwrap());
+/// ```
+pub mod maps_first_key_wins {
+ use super::*;
+ use crate::duplicate_key_impls::DuplicateInsertsFirstWinsMap;
+
+ /// Deserialize a map and return an error on duplicate keys
+ pub fn deserialize<'de, D, T, K, V>(deserializer: D) -> Result<T, D::Error>
+ where
+ T: DuplicateInsertsFirstWinsMap<K, V>,
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+ D: Deserializer<'de>,
+ {
+ struct MapVisitor<T, K, V> {
+ marker: PhantomData<T>,
+ map_key_type: PhantomData<K>,
+ map_value_type: PhantomData<V>,
+ }
+
+ impl<'de, T, K, V> Visitor<'de> for MapVisitor<T, K, V>
+ where
+ T: DuplicateInsertsFirstWinsMap<K, V>,
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+ {
+ type Value = T;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a map")
+ }
+
+ #[inline]
+ fn visit_map<A>(self, mut access: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let mut values = Self::Value::new(access.size_hint());
+
+ while let Some((key, value)) = access.next_entry()? {
+ values.insert(key, value);
+ }
+
+ Ok(values)
+ }
+ }
+
+ let visitor = MapVisitor {
+ marker: PhantomData,
+ map_key_type: PhantomData,
+ map_value_type: PhantomData,
+ };
+ deserializer.deserialize_map(visitor)
+ }
+
+ /// Serialize the map with the default serializer
+ pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: Serialize,
+ S: Serializer,
+ {
+ value.serialize(serializer)
+ }
+}
+
+/// De/Serialize a [`Option<String>`] type while transforming the empty string to [`None`]
+///
+/// Convert an [`Option<T>`] from/to string using [`FromStr`] and [`AsRef<str>`] implementations.
+/// An empty string is deserialized as [`None`] and a [`None`] vice versa.
+///
+/// ## Converting to `serde_as`
+///
+/// The same functionality can be more clearly expressed via [`NoneAsEmptyString`] and using the [`serde_as`] macro.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_with::{serde_as, NoneAsEmptyString};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize)]
+/// struct A {
+/// #[serde_as(as = "NoneAsEmptyString")]
+/// value: Option<String>,
+/// }
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use serde_with::rust::string_empty_as_none;
+/// #
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde(with = "string_empty_as_none")]
+/// tags: Option<String>,
+/// }
+///
+/// let v: A = serde_json::from_value(json!({ "tags": "" })).unwrap();
+/// assert_eq!(None, v.tags);
+///
+/// let v: A = serde_json::from_value(json!({ "tags": "Hi" })).unwrap();
+/// assert_eq!(Some("Hi".to_string()), v.tags);
+///
+/// let x = A {
+/// tags: Some("This is text".to_string()),
+/// };
+/// assert_eq!(json!({ "tags": "This is text" }), serde_json::to_value(&x).unwrap());
+///
+/// let x = A {
+/// tags: None,
+/// };
+/// assert_eq!(json!({ "tags": "" }), serde_json::to_value(&x).unwrap());
+/// ```
+///
+/// [`NoneAsEmptyString`]: crate::NoneAsEmptyString
+/// [`serde_as`]: crate::guide::serde_as
+pub mod string_empty_as_none {
+ use super::*;
+
+ /// Deserialize an `Option<T>` from a string using `FromStr`
+ pub fn deserialize<'de, D, S>(deserializer: D) -> Result<Option<S>, D::Error>
+ where
+ D: Deserializer<'de>,
+ S: FromStr,
+ S::Err: Display,
+ {
+ struct OptionStringEmptyNone<S>(PhantomData<S>);
+ impl<'de, S> Visitor<'de> for OptionStringEmptyNone<S>
+ where
+ S: FromStr,
+ S::Err: Display,
+ {
+ type Value = Option<S>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("any string")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ "" => Ok(None),
+ v => S::from_str(v).map(Some).map_err(Error::custom),
+ }
+ }
+
+ fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match &*value {
+ "" => Ok(None),
+ v => S::from_str(v).map(Some).map_err(Error::custom),
+ }
+ }
+
+ // handles the `null` case
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ Ok(None)
+ }
+ }
+
+ deserializer.deserialize_any(OptionStringEmptyNone(PhantomData))
+ }
+
+ /// Serialize a string from `Option<T>` using `AsRef<str>` or using the empty string if `None`.
+ pub fn serialize<T, S>(option: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: AsRef<str>,
+ S: Serializer,
+ {
+ if let Some(value) = option {
+ value.as_ref().serialize(serializer)
+ } else {
+ "".serialize(serializer)
+ }
+ }
+}
+
+/// De/Serialize a Map into a list of tuples
+///
+/// Some formats, like JSON, have limitations on the type of keys for maps.
+/// In case of JSON, keys are restricted to strings.
+/// Rust features more powerful keys, for example tuple, which can not be serialized to JSON.
+///
+/// This helper serializes the Map into a list of tuples, which does not have the same type restrictions.
+/// The module can be applied on any type implementing `IntoIterator<Item = (&'a K, &'a V)>` and `FromIterator<(K, V)>`, with `K` and `V` being the key and value types.
+/// From the standard library both [`HashMap`] and [`BTreeMap`] fullfil the condition and can be used here.
+///
+/// ## Converting to `serde_as`
+///
+/// If the map is of type [`HashMap`] or [`BTreeMap`] the same functionality can be expressed more clearly using the [`serde_as`] macro.
+/// The `_` is a placeholder which works for any type which implements [`Serialize`]/[`Deserialize`], such as the tuple and `u32` type.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::serde_as;
+/// # use std::collections::{BTreeMap, HashMap};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde_as(as = "Vec<(_, _)>")]
+/// hashmap: HashMap<(String, u32), u32>,
+/// #[serde_as(as = "Vec<(_, _)>")]
+/// btreemap: BTreeMap<(String, u32), u32>,
+/// }
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use std::collections::BTreeMap;
+/// #
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde(with = "serde_with::rust::map_as_tuple_list")]
+/// s: BTreeMap<(String, u32), u32>,
+/// }
+///
+/// let v: A = serde_json::from_value(json!({
+/// "s": [
+/// [["Hello", 123], 0],
+/// [["World", 456], 1]
+/// ]
+/// })).unwrap();
+///
+/// assert_eq!(2, v.s.len());
+/// assert_eq!(1, v.s[&("World".to_string(), 456)]);
+/// ```
+///
+/// The helper is generic over the hasher type of the [`HashMap`] and works with different variants, such as `FnvHashMap`.
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// #
+/// use fnv::FnvHashMap;
+///
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde(with = "serde_with::rust::map_as_tuple_list")]
+/// s: FnvHashMap<u32, bool>,
+/// }
+///
+/// let v: A = serde_json::from_value(json!({
+/// "s": [
+/// [0, false],
+/// [1, true]
+/// ]
+/// })).unwrap();
+///
+/// assert_eq!(2, v.s.len());
+/// assert_eq!(true, v.s[&1]);
+/// ```
+///
+/// [`serde_as`]: crate::guide::serde_as
+pub mod map_as_tuple_list {
+ // Trait bounds based on this answer: https://stackoverflow.com/a/66600486/15470286
+ use super::*;
+
+ /// Serialize the map as a list of tuples
+ pub fn serialize<'a, T, K, V, S>(map: T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ T: IntoIterator<Item = (&'a K, &'a V)>,
+ T::IntoIter: ExactSizeIterator,
+ K: Serialize + 'a,
+ V: Serialize + 'a,
+ {
+ serializer.collect_seq(map)
+ }
+
+ /// Deserialize a map from a list of tuples
+ pub fn deserialize<'de, T, K, V, D>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ T: FromIterator<(K, V)>,
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+ {
+ struct SeqVisitor<T, K, V>(PhantomData<(T, K, V)>);
+
+ impl<'de, T, K, V> Visitor<'de> for SeqVisitor<T, K, V>
+ where
+ T: FromIterator<(K, V)>,
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+ {
+ type Value = T;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a list of key-value pairs")
+ }
+
+ fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ utils::SeqIter::new(seq).collect()
+ }
+ }
+
+ deserializer.deserialize_seq(SeqVisitor(PhantomData))
+ }
+}
+
+/// DEPRECATED De/Serialize a [`HashMap`] into a list of tuples
+///
+/// Use the [`map_as_tuple_list`] module which is more general than this.
+/// It should work with everything convertible to and from an `Iterator` including [`BTreeMap`] and [`HashMap`].
+///
+/// ---
+///
+/// Some formats, like JSON, have limitations on the type of keys for maps.
+/// In case of JSON, keys are restricted to strings.
+/// Rust features more powerful keys, for example tuple, which can not be serialized to JSON.
+///
+/// This helper serializes the [`HashMap`] into a list of tuples, which does not have the same type restrictions.
+///
+/// If you need to de/serialize a [`BTreeMap`] then use [`btreemap_as_tuple_list`].
+///
+/// ## Converting to `serde_as`
+///
+/// The same functionality can be more clearly expressed using the [`serde_as`] macro.
+/// The `_` is a placeholder which works for any type which implements [`Serialize`]/[`Deserialize`], such as the tuple and `u32` type.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::serde_as;
+/// # use std::collections::HashMap;
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde_as(as = "Vec<(_, _)>")]
+/// s: HashMap<(String, u32), u32>,
+/// }
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use std::collections::HashMap;
+/// #
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde(with = "serde_with::rust::hashmap_as_tuple_list")]
+/// s: HashMap<(String, u32), u32>,
+/// }
+///
+/// let v: A = serde_json::from_value(json!({
+/// "s": [
+/// [["Hello", 123], 0],
+/// [["World", 456], 1]
+/// ]
+/// })).unwrap();
+///
+/// assert_eq!(2, v.s.len());
+/// assert_eq!(1, v.s[&("World".to_string(), 456)]);
+/// ```
+///
+/// The helper is generic over the hasher type of the [`HashMap`] and works with different variants, such as `FnvHashMap`.
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// #
+/// use fnv::FnvHashMap;
+///
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde(with = "serde_with::rust::hashmap_as_tuple_list")]
+/// s: FnvHashMap<u32, bool>,
+/// }
+///
+/// let v: A = serde_json::from_value(json!({
+/// "s": [
+/// [0, false],
+/// [1, true]
+/// ]
+/// })).unwrap();
+///
+/// assert_eq!(2, v.s.len());
+/// assert_eq!(true, v.s[&1]);
+/// ```
+///
+/// [`serde_as`]: crate::guide::serde_as
+#[deprecated(
+ since = "1.8.0",
+ note = "Use the more general map_as_tuple_list module."
+)]
+pub mod hashmap_as_tuple_list {
+ #[doc(inline)]
+ #[deprecated(
+ since = "1.8.0",
+ note = "Use the more general map_as_tuple_list::deserialize function."
+ )]
+ pub use super::map_as_tuple_list::deserialize;
+ #[doc(inline)]
+ #[deprecated(
+ since = "1.8.0",
+ note = "Use the more general map_as_tuple_list::serialize function."
+ )]
+ pub use super::map_as_tuple_list::serialize;
+}
+
+/// DEPRECATED De/Serialize a [`BTreeMap`] into a list of tuples
+///
+/// Use the [`map_as_tuple_list`] module which is more general than this.
+/// It should work with everything convertible to and from an `Iterator` including [`BTreeMap`] and [`HashMap`].
+///
+/// ---
+///
+/// Some formats, like JSON, have limitations on the type of keys for maps.
+/// In case of JSON, keys are restricted to strings.
+/// Rust features more powerful keys, for example tuple, which can not be serialized to JSON.
+///
+/// This helper serializes the [`BTreeMap`] into a list of tuples, which does not have the same type restrictions.
+///
+/// If you need to de/serialize a [`HashMap`] then use [`hashmap_as_tuple_list`].
+///
+/// ## Converting to `serde_as`
+///
+/// The same functionality can be more clearly expressed using the [`serde_as`] macro.
+/// The `_` is a placeholder which works for any type which implements [`Serialize`]/[`Deserialize`], such as the tuple and `u32` type.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::serde_as;
+/// # use std::collections::BTreeMap;
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde_as(as = "Vec<(_, _)>")]
+/// s: BTreeMap<(String, u32), u32>,
+/// }
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_json::json;
+/// # use std::collections::BTreeMap;
+/// #
+/// #[derive(Deserialize, Serialize)]
+/// struct A {
+/// #[serde(with = "serde_with::rust::btreemap_as_tuple_list")]
+/// s: BTreeMap<(String, u32), u32>,
+/// }
+///
+/// let v: A = serde_json::from_value(json!({
+/// "s": [
+/// [["Hello", 123], 0],
+/// [["World", 456], 1]
+/// ]
+/// })).unwrap();
+///
+/// assert_eq!(2, v.s.len());
+/// assert_eq!(1, v.s[&("World".to_string(), 456)]);
+/// ```
+///
+/// [`serde_as`]: crate::guide::serde_as
+#[deprecated(
+ since = "1.8.0",
+ note = "Use the more general map_as_tuple_list module."
+)]
+pub mod btreemap_as_tuple_list {
+ #[doc(inline)]
+ #[deprecated(
+ since = "1.8.0",
+ note = "Use the more general map_as_tuple_list::deserialize function."
+ )]
+ pub use super::map_as_tuple_list::deserialize;
+ #[doc(inline)]
+ #[deprecated(
+ since = "1.8.0",
+ note = "Use the more general map_as_tuple_list::serialize function."
+ )]
+ pub use super::map_as_tuple_list::serialize;
+}
+
+/// This serializes a list of tuples into a map and back
+///
+/// Normally, you want to use a [`HashMap`] or a [`BTreeMap`] when deserializing a map.
+/// However, sometimes this is not possible due to type contains, e.g., if the type implements neither [`Hash`] nor [`Ord`].
+/// Another use case is deserializing a map with duplicate keys.
+///
+/// The implementation is generic using the [`FromIterator`] and [`IntoIterator`] traits.
+/// Therefore, all of [`Vec`], [`VecDeque`](std::collections::VecDeque), and [`LinkedList`](std::collections::LinkedList) and anything which implements those are supported.
+///
+/// ## Converting to `serde_as`
+///
+/// The same functionality can be more clearly expressed using the [`serde_as`] macro.
+/// The `_` is a placeholder which works for any type which implements [`Serialize`]/[`Deserialize`], such as the tuple and `u32` type.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Deserialize, Serialize};
+/// # use serde_with::serde_as;
+/// # use std::collections::BTreeMap;
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize, Serialize)]
+/// struct S {
+/// #[serde_as(as = "BTreeMap<_, _>")] // HashMap will also work
+/// s: Vec<(i32, String)>,
+/// }
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// `Wrapper` does not implement [`Hash`] nor [`Ord`], thus prohibiting the use [`HashMap`] or [`BTreeMap`].
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// #
+/// #[derive(Debug, Deserialize, Serialize, Default)]
+/// struct S {
+/// #[serde(with = "serde_with::rust::tuple_list_as_map")]
+/// s: Vec<(Wrapper<i32>, Wrapper<String>)>,
+/// }
+///
+/// #[derive(Clone, Debug, Serialize, Deserialize)]
+/// #[serde(transparent)]
+/// struct Wrapper<T>(T);
+///
+/// let from = r#"{
+/// "s": {
+/// "1": "Hi",
+/// "2": "Cake",
+/// "99": "Lie"
+/// }
+/// }"#;
+/// let mut expected = S::default();
+/// expected.s.push((Wrapper(1), Wrapper("Hi".into())));
+/// expected.s.push((Wrapper(2), Wrapper("Cake".into())));
+/// expected.s.push((Wrapper(99), Wrapper("Lie".into())));
+///
+/// let res: S = serde_json::from_str(from).unwrap();
+/// for ((exp_k, exp_v), (res_k, res_v)) in expected.s.iter().zip(&res.s) {
+/// assert_eq!(exp_k.0, res_k.0);
+/// assert_eq!(exp_v.0, res_v.0);
+/// }
+/// assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap());
+/// ```
+///
+/// In this example, the serialized format contains duplicate keys, which is not supported with [`HashMap`] or [`BTreeMap`].
+///
+/// ```
+/// # use serde::{Deserialize, Serialize};
+/// #
+/// #[derive(Debug, Deserialize, Serialize, PartialEq, Default)]
+/// struct S {
+/// #[serde(with = "serde_with::rust::tuple_list_as_map")]
+/// s: Vec<(i32, String)>,
+/// }
+///
+/// let from = r#"{
+/// "s": {
+/// "1": "Hi",
+/// "1": "Cake",
+/// "1": "Lie"
+/// }
+/// }"#;
+/// let mut expected = S::default();
+/// expected.s.push((1, "Hi".into()));
+/// expected.s.push((1, "Cake".into()));
+/// expected.s.push((1, "Lie".into()));
+///
+/// let res: S = serde_json::from_str(from).unwrap();
+/// assert_eq!(3, res.s.len());
+/// assert_eq!(expected, res);
+/// assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap());
+/// ```
+///
+/// [`serde_as`]: crate::guide::serde_as
+pub mod tuple_list_as_map {
+ use super::*;
+
+ /// Serialize any iteration of tuples into a map.
+ pub fn serialize<'a, I, K, V, S>(iter: I, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ I: IntoIterator<Item = &'a (K, V)>,
+ I::IntoIter: ExactSizeIterator,
+ K: Serialize + 'a,
+ V: Serialize + 'a,
+ S: Serializer,
+ {
+ // Convert &(K, V) to (&K, &V) for collect_map.
+ let iter = iter.into_iter().map(|(k, v)| (k, v));
+ serializer.collect_map(iter)
+ }
+
+ /// Deserialize a map into an iterator of tuples.
+ pub fn deserialize<'de, I, K, V, D>(deserializer: D) -> Result<I, D::Error>
+ where
+ I: FromIterator<(K, V)>,
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_map(MapVisitor(PhantomData))
+ }
+
+ #[allow(clippy::type_complexity)]
+ struct MapVisitor<I, K, V>(PhantomData<fn() -> (I, K, V)>);
+
+ impl<'de, I, K, V> Visitor<'de> for MapVisitor<I, K, V>
+ where
+ I: FromIterator<(K, V)>,
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+ {
+ type Value = I;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a map")
+ }
+
+ fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ utils::MapIter::new(map).collect()
+ }
+ }
+}
+
+/// Deserialize from bytes or string
+///
+/// Any Rust [`String`] can be converted into bytes, i.e., `Vec<u8>`.
+/// Accepting both as formats while deserializing can be helpful while interacting with language
+/// which have a looser definition of string than Rust.
+///
+/// ## Converting to `serde_as`
+///
+/// The same functionality can be more clearly expressed via [`BytesOrString`] and using the [`serde_as`] macro.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_with::{serde_as, BytesOrString};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize)]
+/// struct A {
+/// #[serde_as(as = "BytesOrString")]
+/// bos: Vec<u8>,
+/// }
+/// # }
+/// ```
+///
+/// # Example
+/// ```rust
+/// # use serde::{Deserialize, Serialize};
+/// #
+/// #[derive(Debug, Deserialize, Serialize, PartialEq, Default)]
+/// struct S {
+/// #[serde(deserialize_with = "serde_with::rust::bytes_or_string::deserialize")]
+/// bos: Vec<u8>,
+/// }
+///
+/// // Here we deserialize from a byte array ...
+/// let from = r#"{
+/// "bos": [
+/// 0,
+/// 1,
+/// 2,
+/// 3
+/// ]
+/// }"#;
+/// let expected = S {
+/// bos: vec![0, 1, 2, 3],
+/// };
+///
+/// let res: S = serde_json::from_str(from).unwrap();
+/// assert_eq!(expected, res);
+///
+/// // and serialization works too.
+/// assert_eq!(from, serde_json::to_string_pretty(&expected).unwrap());
+///
+/// // But we also support deserializing from a String
+/// let from = r#"{
+/// "bos": "✨Works!"
+/// }"#;
+/// let expected = S {
+/// bos: "✨Works!".as_bytes().to_vec(),
+/// };
+///
+/// let res: S = serde_json::from_str(from).unwrap();
+/// assert_eq!(expected, res);
+/// ```
+///
+/// [`BytesOrString`]: crate::BytesOrString
+/// [`serde_as`]: crate::guide::serde_as
+pub mod bytes_or_string {
+ use super::*;
+
+ /// Deserialize a [`Vec<u8>`] from either bytes or string
+ pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_any(BytesOrStringVisitor)
+ }
+
+ struct BytesOrStringVisitor;
+
+ impl<'de> Visitor<'de> for BytesOrStringVisitor {
+ type Value = Vec<u8>;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a list of bytes or a string")
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E> {
+ Ok(v.to_vec())
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E> {
+ Ok(v)
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<Self::Value, E> {
+ Ok(v.as_bytes().to_vec())
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<Self::Value, E> {
+ Ok(v.into_bytes())
+ }
+
+ fn visit_seq<A>(self, seq: A) -> Result<Self::Value, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ utils::SeqIter::new(seq).collect()
+ }
+ }
+}
+
+/// Deserialize value and return [`Default`] on error
+///
+/// The main use case is ignoring error while deserializing.
+/// Instead of erroring, it simply deserializes the [`Default`] variant of the type.
+/// It is not possible to find the error location, i.e., which field had a deserialization error, with this method.
+///
+/// ## Converting to `serde_as`
+///
+/// The same functionality can be more clearly expressed via [`DefaultOnError`] and using the [`serde_as`] macro.
+/// It can be combined with other converts as shown.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_with::{serde_as, DefaultOnError, DisplayFromStr};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize)]
+/// struct A {
+/// #[serde_as(as = "DefaultOnError")]
+/// value: u32,
+/// #[serde_as(as = "DefaultOnError<DisplayFromStr>")]
+/// value2: u32,
+/// }
+/// # }
+/// ```
+///
+/// [`DefaultOnError`]: crate::DefaultOnError
+/// [`serde_as`]: crate::guide::serde_as
+///
+/// # Examples
+///
+/// ```
+/// # use serde::Deserialize;
+/// #
+/// #[derive(Deserialize)]
+/// struct A {
+/// #[serde(deserialize_with = "serde_with::rust::default_on_error::deserialize")]
+/// value: u32,
+/// }
+///
+/// let a: A = serde_json::from_str(r#"{"value": 123}"#).unwrap();
+/// assert_eq!(123, a.value);
+///
+/// // null is of invalid type
+/// let a: A = serde_json::from_str(r#"{"value": null}"#).unwrap();
+/// assert_eq!(0, a.value);
+///
+/// // String is of invalid type
+/// let a: A = serde_json::from_str(r#"{"value": "123"}"#).unwrap();
+/// assert_eq!(0, a.value);
+///
+/// // Map is of invalid type
+/// let a: A = serde_json::from_str(r#"{"value": {}}"#).unwrap();
+/// assert_eq!(0, a.value);
+///
+/// // Missing entries still cause errors
+/// assert!(serde_json::from_str::<A>(r#"{ }"#).is_err());
+/// ```
+///
+/// Deserializing missing values can be supported by adding the `default` field attribute:
+///
+/// ```
+/// # use serde::Deserialize;
+/// #
+/// #[derive(Deserialize)]
+/// struct B {
+/// #[serde(default, deserialize_with = "serde_with::rust::default_on_error::deserialize")]
+/// value: u32,
+/// }
+///
+/// let b: B = serde_json::from_str(r#"{ }"#).unwrap();
+/// assert_eq!(0, b.value);
+/// ```
+pub mod default_on_error {
+ use super::*;
+
+ /// Deserialize T and return the [`Default`] value on error
+ pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ T: Deserialize<'de> + Default,
+ {
+ #[derive(Debug, serde::Deserialize)]
+ #[serde(untagged)]
+ enum GoodOrError<T> {
+ Good(T),
+ // This consumes one "item" when `T` errors while deserializing.
+ // This is necessary to make this work, when instead of having a direct value
+ // like integer or string, the deserializer sees a list or map.
+ Error(serde::de::IgnoredAny),
+ }
+
+ Ok(match Deserialize::deserialize(deserializer) {
+ Ok(GoodOrError::Good(res)) => res,
+ _ => Default::default(),
+ })
+ }
+
+ /// Serialize value with the default serializer
+ pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: Serialize,
+ S: Serializer,
+ {
+ value.serialize(serializer)
+ }
+}
+
+/// Deserialize default value if encountering `null`.
+///
+/// One use case are JSON APIs in which the `null` value represents some default state.
+/// This adapter allows to turn the `null` directly into the [`Default`] value of the type.
+///
+/// ## Converting to `serde_as`
+///
+/// The same functionality can be more clearly expressed via [`DefaultOnNull`] and using the [`serde_as`] macro.
+/// It can be combined with other convertes as shown.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::Deserialize;
+/// # use serde_with::{serde_as, DefaultOnNull, DisplayFromStr};
+/// #
+/// #[serde_as]
+/// #[derive(Deserialize)]
+/// struct A {
+/// #[serde_as(as = "DefaultOnNull")]
+/// value: u32,
+/// #[serde_as(as = "DefaultOnNull<DisplayFromStr>")]
+/// value2: u32,
+/// }
+/// # }
+/// ```
+///
+/// [`DefaultOnNull`]: crate::DefaultOnNull
+/// [`serde_as`]: crate::guide::serde_as
+///
+/// # Examples
+///
+/// ```
+/// # use serde::Deserialize;
+/// #
+/// #[derive(Deserialize)]
+/// struct A {
+/// #[serde(deserialize_with = "serde_with::rust::default_on_null::deserialize")]
+/// value: u32,
+/// }
+///
+/// let a: A = serde_json::from_str(r#"{"value": 123}"#).unwrap();
+/// assert_eq!(123, a.value);
+///
+/// let a: A = serde_json::from_str(r#"{"value": null}"#).unwrap();
+/// assert_eq!(0, a.value);
+///
+/// // String is invalid type
+/// assert!(serde_json::from_str::<A>(r#"{"value": "123"}"#).is_err());
+/// ```
+pub mod default_on_null {
+ use super::*;
+
+ /// Deserialize T and return the [`Default`] value if original value is `null`
+ pub fn deserialize<'de, D, T>(deserializer: D) -> Result<T, D::Error>
+ where
+ D: Deserializer<'de>,
+ T: Deserialize<'de> + Default,
+ {
+ Ok(Option::deserialize(deserializer)?.unwrap_or_default())
+ }
+
+ /// Serialize value with the default serializer
+ pub fn serialize<T, S>(value: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ T: Serialize,
+ S: Serializer,
+ {
+ value.serialize(serializer)
+ }
+}
+
+/// Deserialize any value, ignore it, and return the default value for the type being deserialized.
+///
+/// This function can be used in two different ways:
+///
+/// 1. It is useful for instance to create an enum with a catch-all variant that will accept any incoming data.
+/// 2. [`untagged`] enum representations do not allow the `other` annotation as the fallback enum variant.
+/// With this function you can emulate an `other` variant, which can deserialize any data carrying enum.
+///
+/// **Note:** Using this function will prevent deserializing data-less enum variants.
+/// If this is a problem depends on the data format.
+/// For example, deserializing `"Bar"` as an enum in JSON would fail, since it carries no data.
+///
+/// # Examples
+///
+/// ## Deserializing a heterogeneous collection of XML nodes
+///
+/// When [`serde-xml-rs`] deserializes an XML tag to an enum, it always maps the tag
+/// name to the enum variant name, and the tag attributes and children to the enum contents.
+/// This means that in order for an enum variant to accept any XML tag, it both has to use
+/// `#[serde(other)]` to accept any tag name, and `#[serde(deserialize_with = "deserialize_ignore_any")]`
+/// to accept any attributes and children.
+///
+/// ```rust
+/// # use serde::Deserialize;
+/// use serde_with::rust::deserialize_ignore_any;
+///
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize)]
+/// #[serde(rename_all = "lowercase")]
+/// enum Item {
+/// Foo(String),
+/// Bar(String),
+/// #[serde(other, deserialize_with = "deserialize_ignore_any")]
+/// Other,
+/// }
+///
+/// // Deserialize this XML
+/// # let items: Vec<Item> = serde_xml_rs::from_str(
+/// r"
+/// <foo>a</foo>
+/// <bar>b</bar>
+/// <foo>c</foo>
+/// <unknown>d</unknown>
+/// "
+/// # ).unwrap();
+///
+/// // into these Items
+/// # let expected =
+/// vec![
+/// Item::Foo(String::from("a")),
+/// Item::Bar(String::from("b")),
+/// Item::Foo(String::from("c")),
+/// Item::Other,
+/// ]
+/// # ;
+/// # assert_eq!(expected, items);
+/// ```
+///
+/// ## Simulating an `other` enum variant in an `untagged` enum
+///
+/// ```rust
+/// # use serde::Deserialize;
+/// # use serde_json::json;
+/// use serde_with::rust::deserialize_ignore_any;
+///
+/// # #[derive(Debug, PartialEq)]
+/// #[derive(Deserialize)]
+/// #[serde(untagged)]
+/// enum Item {
+/// Foo{x: u8},
+/// #[serde(deserialize_with = "deserialize_ignore_any")]
+/// Other,
+/// }
+///
+/// // Deserialize this JSON
+/// # let items: Vec<Item> = serde_json::from_value(
+/// json!([
+/// {"y": 1},
+/// {"x": 1},
+/// ])
+/// # ).unwrap();
+///
+/// // into these Items
+/// # let expected =
+/// vec![Item::Other, Item::Foo{x: 1}]
+/// # ;
+/// # assert_eq!(expected, items);
+/// ```
+///
+/// [`serde-xml-rs`]: https://docs.rs/serde-xml-rs
+/// [`untagged`]: https://serde.rs/enum-representations.html#untagged
+pub fn deserialize_ignore_any<'de, D: Deserializer<'de>, T: Default>(
+ deserializer: D,
+) -> Result<T, D::Error> {
+ serde::de::IgnoredAny::deserialize(deserializer).map(|_| T::default())
+}
diff --git a/third_party/rust/serde_with/src/ser/const_arrays.rs b/third_party/rust/serde_with/src/ser/const_arrays.rs
new file mode 100644
index 0000000000..b864f2b7e5
--- /dev/null
+++ b/third_party/rust/serde_with/src/ser/const_arrays.rs
@@ -0,0 +1,90 @@
+use super::*;
+use alloc::{borrow::Cow, boxed::Box, collections::BTreeMap};
+use std::collections::HashMap;
+
+impl<T, As, const N: usize> SerializeAs<[T; N]> for [As; N]
+where
+ As: SerializeAs<T>,
+{
+ fn serialize_as<S>(array: &[T; N], serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use serde::ser::SerializeTuple;
+ let mut arr = serializer.serialize_tuple(N)?;
+ for elem in array {
+ arr.serialize_element(&SerializeAsWrap::<T, As>::new(elem))?;
+ }
+ arr.end()
+ }
+}
+
+macro_rules! tuple_seq_as_map_impl_intern {
+ ($tyorig:ty, $ty:ident <K, V>) => {
+ #[allow(clippy::implicit_hasher)]
+ impl<K, KAs, V, VAs, const N: usize> SerializeAs<$tyorig> for $ty<KAs, VAs>
+ where
+ KAs: SerializeAs<K>,
+ VAs: SerializeAs<V>,
+ {
+ fn serialize_as<S>(source: &$tyorig, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_map(source.iter().map(|(k, v)| {
+ (
+ SerializeAsWrap::<K, KAs>::new(k),
+ SerializeAsWrap::<V, VAs>::new(v),
+ )
+ }))
+ }
+ }
+ };
+}
+tuple_seq_as_map_impl_intern!([(K, V); N], BTreeMap<K, V>);
+tuple_seq_as_map_impl_intern!([(K, V); N], HashMap<K, V>);
+
+impl<const N: usize> SerializeAs<[u8; N]> for Bytes {
+ fn serialize_as<S>(bytes: &[u8; N], serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(bytes)
+ }
+}
+
+impl<const N: usize> SerializeAs<&[u8; N]> for Bytes {
+ fn serialize_as<S>(bytes: &&[u8; N], serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(*bytes)
+ }
+}
+
+impl<const N: usize> SerializeAs<Box<[u8; N]>> for Bytes {
+ fn serialize_as<S>(bytes: &Box<[u8; N]>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(&**bytes)
+ }
+}
+
+impl<'a, const N: usize> SerializeAs<Cow<'a, [u8; N]>> for Bytes {
+ fn serialize_as<S>(bytes: &Cow<'a, [u8; N]>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(bytes.as_ref())
+ }
+}
+
+impl<'a, const N: usize> SerializeAs<Cow<'a, [u8; N]>> for BorrowCow {
+ fn serialize_as<S>(value: &Cow<'a, [u8; N]>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq(value.iter())
+ }
+}
diff --git a/third_party/rust/serde_with/src/ser/impls.rs b/third_party/rust/serde_with/src/ser/impls.rs
new file mode 100644
index 0000000000..16a8fb913c
--- /dev/null
+++ b/third_party/rust/serde_with/src/ser/impls.rs
@@ -0,0 +1,739 @@
+use super::*;
+use crate::{
+ formats::Strictness, rust::StringWithSeparator, utils::duration::DurationSigned, Separator,
+};
+use alloc::{
+ borrow::Cow,
+ boxed::Box,
+ collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque},
+ rc::{Rc, Weak as RcWeak},
+ string::{String, ToString},
+ sync::{Arc, Weak as ArcWeak},
+ vec::Vec,
+};
+use core::{
+ cell::{Cell, RefCell},
+ convert::TryInto,
+ fmt::Display,
+ time::Duration,
+};
+#[cfg(feature = "indexmap")]
+use indexmap_crate::{IndexMap, IndexSet};
+use serde::ser::Error;
+use std::{
+ collections::{HashMap, HashSet},
+ sync::{Mutex, RwLock},
+ time::SystemTime,
+};
+
+///////////////////////////////////////////////////////////////////////////////
+// region: Simple Wrapper types (e.g., Box, Option)
+
+impl<'a, T, U> SerializeAs<&'a T> for &'a U
+where
+ U: SerializeAs<T>,
+ T: ?Sized,
+ U: ?Sized,
+{
+ fn serialize_as<S>(source: &&'a T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<T, U>::new(source).serialize(serializer)
+ }
+}
+
+impl<'a, T, U> SerializeAs<&'a mut T> for &'a mut U
+where
+ U: SerializeAs<T>,
+ T: ?Sized,
+ U: ?Sized,
+{
+ fn serialize_as<S>(source: &&'a mut T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<T, U>::new(source).serialize(serializer)
+ }
+}
+
+impl<T, U> SerializeAs<Box<T>> for Box<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &Box<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<T, U>::new(source).serialize(serializer)
+ }
+}
+
+impl<T, U> SerializeAs<Option<T>> for Option<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &Option<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match *source {
+ Some(ref value) => serializer.serialize_some(&SerializeAsWrap::<T, U>::new(value)),
+ None => serializer.serialize_none(),
+ }
+ }
+}
+
+impl<T, U> SerializeAs<Rc<T>> for Rc<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &Rc<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<T, U>::new(source).serialize(serializer)
+ }
+}
+
+impl<T, U> SerializeAs<RcWeak<T>> for RcWeak<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &RcWeak<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<Option<Rc<T>>, Option<Rc<U>>>::new(&source.upgrade())
+ .serialize(serializer)
+ }
+}
+
+impl<T, U> SerializeAs<Arc<T>> for Arc<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &Arc<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<T, U>::new(source).serialize(serializer)
+ }
+}
+
+impl<T, U> SerializeAs<ArcWeak<T>> for ArcWeak<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &ArcWeak<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<Option<Arc<T>>, Option<Arc<U>>>::new(&source.upgrade())
+ .serialize(serializer)
+ }
+}
+
+impl<T, U> SerializeAs<Cell<T>> for Cell<U>
+where
+ U: SerializeAs<T>,
+ T: Copy,
+{
+ fn serialize_as<S>(source: &Cell<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<T, U>::new(&source.get()).serialize(serializer)
+ }
+}
+
+impl<T, U> SerializeAs<RefCell<T>> for RefCell<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &RefCell<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match source.try_borrow() {
+ Ok(source) => SerializeAsWrap::<T, U>::new(&*source).serialize(serializer),
+ Err(_) => Err(S::Error::custom("already mutably borrowed")),
+ }
+ }
+}
+
+impl<T, U> SerializeAs<Mutex<T>> for Mutex<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &Mutex<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match source.lock() {
+ Ok(source) => SerializeAsWrap::<T, U>::new(&*source).serialize(serializer),
+ Err(_) => Err(S::Error::custom("lock poison error while serializing")),
+ }
+ }
+}
+
+impl<T, U> SerializeAs<RwLock<T>> for RwLock<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &RwLock<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match source.read() {
+ Ok(source) => SerializeAsWrap::<T, U>::new(&*source).serialize(serializer),
+ Err(_) => Err(S::Error::custom("lock poison error while serializing")),
+ }
+ }
+}
+
+impl<T, TAs, E, EAs> SerializeAs<Result<T, E>> for Result<TAs, EAs>
+where
+ TAs: SerializeAs<T>,
+ EAs: SerializeAs<E>,
+{
+ fn serialize_as<S>(source: &Result<T, E>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ source
+ .as_ref()
+ .map(SerializeAsWrap::<T, TAs>::new)
+ .map_err(SerializeAsWrap::<E, EAs>::new)
+ .serialize(serializer)
+ }
+}
+
+// endregion
+///////////////////////////////////////////////////////////////////////////////
+// region: Collection Types (e.g., Maps, Sets, Vec)
+
+macro_rules! seq_impl {
+ ($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident )* >) => {
+ impl<T, U $(, $typaram)*> SerializeAs<$ty<T $(, $typaram)*>> for $ty<U $(, $typaram)*>
+ where
+ U: SerializeAs<T>,
+ $(T: ?Sized + $tbound1 $(+ $tbound2)*,)*
+ $($typaram: ?Sized + $bound,)*
+ {
+ fn serialize_as<S>(source: &$ty<T $(, $typaram)*>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq(source.iter().map(|item| SerializeAsWrap::<T, U>::new(item)))
+ }
+ }
+ }
+}
+
+type BoxedSlice<T> = Box<[T]>;
+type Slice<T> = [T];
+seq_impl!(BinaryHeap<T>);
+seq_impl!(BoxedSlice<T>);
+seq_impl!(BTreeSet<T>);
+seq_impl!(HashSet<T, H: Sized>);
+seq_impl!(LinkedList<T>);
+seq_impl!(Slice<T>);
+seq_impl!(Vec<T>);
+seq_impl!(VecDeque<T>);
+#[cfg(feature = "indexmap")]
+seq_impl!(IndexSet<T, H: Sized>);
+
+macro_rules! map_impl {
+ ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => {
+ impl<K, KU, V, VU $(, $typaram)*> SerializeAs<$ty<K, V $(, $typaram)*>> for $ty<KU, VU $(, $typaram)*>
+ where
+ KU: SerializeAs<K>,
+ VU: SerializeAs<V>,
+ $(K: ?Sized + $kbound1 $(+ $kbound2)*,)*
+ $($typaram: ?Sized + $bound,)*
+ {
+ fn serialize_as<S>(source: &$ty<K, V $(, $typaram)*>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_map(source.iter().map(|(k, v)| (SerializeAsWrap::<K, KU>::new(k), SerializeAsWrap::<V, VU>::new(v))))
+ }
+ }
+ }
+}
+
+map_impl!(BTreeMap<K, V>);
+map_impl!(HashMap<K, V, H: Sized>);
+#[cfg(feature = "indexmap")]
+map_impl!(IndexMap<K, V, H: Sized>);
+
+macro_rules! tuple_impl {
+ ($len:literal $($n:tt $t:ident $tas:ident)+) => {
+ impl<$($t, $tas,)+> SerializeAs<($($t,)+)> for ($($tas,)+)
+ where
+ $($tas: SerializeAs<$t>,)+
+ {
+ fn serialize_as<S>(tuple: &($($t,)+), serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use serde::ser::SerializeTuple;
+ let mut tup = serializer.serialize_tuple($len)?;
+ $(
+ tup.serialize_element(&SerializeAsWrap::<$t, $tas>::new(&tuple.$n))?;
+ )+
+ tup.end()
+ }
+ }
+ };
+}
+
+tuple_impl!(1 0 T0 As0);
+tuple_impl!(2 0 T0 As0 1 T1 As1);
+tuple_impl!(3 0 T0 As0 1 T1 As1 2 T2 As2);
+tuple_impl!(4 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3);
+tuple_impl!(5 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4);
+tuple_impl!(6 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5);
+tuple_impl!(7 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6);
+tuple_impl!(8 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7);
+tuple_impl!(9 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8);
+tuple_impl!(10 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9);
+tuple_impl!(11 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10);
+tuple_impl!(12 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11);
+tuple_impl!(13 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12);
+tuple_impl!(14 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12 13 T13 As13);
+tuple_impl!(15 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12 13 T13 As13 14 T14 As14);
+tuple_impl!(16 0 T0 As0 1 T1 As1 2 T2 As2 3 T3 As3 4 T4 As4 5 T5 As5 6 T6 As6 7 T7 As7 8 T8 As8 9 T9 As9 10 T10 As10 11 T11 As11 12 T12 As12 13 T13 As13 14 T14 As14 15 T15 As15);
+
+macro_rules! map_as_tuple_seq {
+ ($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V >) => {
+ impl<K, KAs, V, VAs> SerializeAs<$ty<K, V>> for Vec<(KAs, VAs)>
+ where
+ KAs: SerializeAs<K>,
+ VAs: SerializeAs<V>,
+ {
+ fn serialize_as<S>(source: &$ty<K, V>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq(source.iter().map(|(k, v)| {
+ (
+ SerializeAsWrap::<K, KAs>::new(k),
+ SerializeAsWrap::<V, VAs>::new(v),
+ )
+ }))
+ }
+ }
+ };
+}
+map_as_tuple_seq!(BTreeMap<K, V>);
+// TODO HashMap with a custom hasher support would be better, but results in "unconstrained type parameter"
+map_as_tuple_seq!(HashMap<K, V>);
+#[cfg(feature = "indexmap")]
+map_as_tuple_seq!(IndexMap<K, V>);
+
+// endregion
+///////////////////////////////////////////////////////////////////////////////
+// region: Conversion types which cause different serialization behavior
+
+impl<T> SerializeAs<T> for Same
+where
+ T: Serialize + ?Sized,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ source.serialize(serializer)
+ }
+}
+
+impl<T> SerializeAs<T> for DisplayFromStr
+where
+ T: Display,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ crate::rust::display_fromstr::serialize(source, serializer)
+ }
+}
+
+impl<T, U> SerializeAs<Vec<T>> for VecSkipError<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ Vec::<U>::serialize_as(source, serializer)
+ }
+}
+
+impl<AsRefStr> SerializeAs<Option<AsRefStr>> for NoneAsEmptyString
+where
+ AsRefStr: AsRef<str>,
+{
+ fn serialize_as<S>(source: &Option<AsRefStr>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ crate::rust::string_empty_as_none::serialize(source, serializer)
+ }
+}
+
+macro_rules! tuple_seq_as_map_impl_intern {
+ ($tyorig:ty, $ty:ident <K, V>) => {
+ #[allow(clippy::implicit_hasher)]
+ impl<K, KAs, V, VAs> SerializeAs<$tyorig> for $ty<KAs, VAs>
+ where
+ KAs: SerializeAs<K>,
+ VAs: SerializeAs<V>,
+ {
+ fn serialize_as<S>(source: &$tyorig, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_map(source.iter().map(|(k, v)| {
+ (
+ SerializeAsWrap::<K, KAs>::new(k),
+ SerializeAsWrap::<V, VAs>::new(v),
+ )
+ }))
+ }
+ }
+ };
+}
+macro_rules! tuple_seq_as_map_impl {
+ ($($ty:ty $(,)?)+) => {$(
+ tuple_seq_as_map_impl_intern!($ty, BTreeMap<K, V>);
+ tuple_seq_as_map_impl_intern!($ty, HashMap<K, V>);
+ )+}
+}
+
+tuple_seq_as_map_impl! {
+ BinaryHeap<(K, V)>,
+ BTreeSet<(K, V)>,
+ LinkedList<(K, V)>,
+ Option<(K, V)>,
+ Vec<(K, V)>,
+ VecDeque<(K, V)>,
+}
+tuple_seq_as_map_impl!(HashSet<(K, V)>);
+#[cfg(feature = "indexmap")]
+tuple_seq_as_map_impl!(IndexSet<(K, V)>);
+
+impl<T, TAs> SerializeAs<T> for DefaultOnError<TAs>
+where
+ TAs: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ TAs::serialize_as(source, serializer)
+ }
+}
+
+impl SerializeAs<Vec<u8>> for BytesOrString {
+ fn serialize_as<S>(source: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ source.serialize(serializer)
+ }
+}
+
+impl<SEPARATOR, I, T> SerializeAs<I> for StringWithSeparator<SEPARATOR, T>
+where
+ SEPARATOR: Separator,
+ for<'a> &'a I: IntoIterator<Item = &'a T>,
+ T: ToString,
+{
+ fn serialize_as<S>(source: &I, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut s = String::new();
+ for v in source {
+ s.push_str(&*v.to_string());
+ s.push_str(SEPARATOR::separator());
+ }
+ serializer.serialize_str(if !s.is_empty() {
+ // remove trailing separator if present
+ &s[..s.len() - SEPARATOR::separator().len()]
+ } else {
+ &s[..]
+ })
+ }
+}
+
+macro_rules! use_signed_duration {
+ (
+ $main_trait:ident $internal_trait:ident =>
+ {
+ $ty:ty =>
+ $({
+ $format:ty, $strictness:ty =>
+ $($tbound:ident: $bound:ident $(,)?)*
+ })*
+ }
+ ) => {
+ $(
+ impl<$($tbound,)*> SerializeAs<$ty> for $main_trait<$format, $strictness>
+ where
+ $($tbound: $bound,)*
+ {
+ fn serialize_as<S>(source: &$ty, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ $internal_trait::<$format, $strictness>::serialize_as(
+ &DurationSigned::from(source),
+ serializer,
+ )
+ }
+ }
+ )*
+ };
+ (
+ $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt
+ ) => {
+ $( use_signed_duration!($main_trait $internal_trait => $rest); )+
+ };
+}
+
+use_signed_duration!(
+ DurationSeconds DurationSeconds,
+ DurationMilliSeconds DurationMilliSeconds,
+ DurationMicroSeconds DurationMicroSeconds,
+ DurationNanoSeconds DurationNanoSeconds,
+ => {
+ Duration =>
+ {u64, STRICTNESS => STRICTNESS: Strictness}
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+use_signed_duration!(
+ DurationSecondsWithFrac DurationSecondsWithFrac,
+ DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ Duration =>
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+
+use_signed_duration!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ SystemTime =>
+ {i64, STRICTNESS => STRICTNESS: Strictness}
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+use_signed_duration!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ SystemTime =>
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+
+impl<T, U> SerializeAs<T> for DefaultOnNull<U>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_some(&SerializeAsWrap::<T, U>::new(source))
+ }
+}
+
+impl SerializeAs<&[u8]> for Bytes {
+ fn serialize_as<S>(bytes: &&[u8], serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(bytes)
+ }
+}
+
+impl SerializeAs<Vec<u8>> for Bytes {
+ fn serialize_as<S>(bytes: &Vec<u8>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(bytes)
+ }
+}
+
+impl SerializeAs<Box<[u8]>> for Bytes {
+ fn serialize_as<S>(bytes: &Box<[u8]>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(bytes)
+ }
+}
+
+impl<'a> SerializeAs<Cow<'a, [u8]>> for Bytes {
+ fn serialize_as<S>(bytes: &Cow<'a, [u8]>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_bytes(bytes)
+ }
+}
+
+impl<T, U> SerializeAs<Vec<T>> for OneOrMany<U, formats::PreferOne>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match source.len() {
+ 1 => SerializeAsWrap::<T, U>::new(source.iter().next().expect("Cannot be empty"))
+ .serialize(serializer),
+ _ => SerializeAsWrap::<Vec<T>, Vec<U>>::new(source).serialize(serializer),
+ }
+ }
+}
+
+impl<T, U> SerializeAs<Vec<T>> for OneOrMany<U, formats::PreferMany>
+where
+ U: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &Vec<T>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<Vec<T>, Vec<U>>::new(source).serialize(serializer)
+ }
+}
+
+impl<T, TAs1> SerializeAs<T> for PickFirst<(TAs1,)>
+where
+ TAs1: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
+ }
+}
+
+impl<T, TAs1, TAs2> SerializeAs<T> for PickFirst<(TAs1, TAs2)>
+where
+ TAs1: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
+ }
+}
+
+impl<T, TAs1, TAs2, TAs3> SerializeAs<T> for PickFirst<(TAs1, TAs2, TAs3)>
+where
+ TAs1: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
+ }
+}
+
+impl<T, TAs1, TAs2, TAs3, TAs4> SerializeAs<T> for PickFirst<(TAs1, TAs2, TAs3, TAs4)>
+where
+ TAs1: SerializeAs<T>,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ SerializeAsWrap::<T, TAs1>::new(source).serialize(serializer)
+ }
+}
+
+impl<T, U> SerializeAs<T> for FromInto<U>
+where
+ T: Into<U> + Clone,
+ U: Serialize,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ source.clone().into().serialize(serializer)
+ }
+}
+
+impl<T, U> SerializeAs<T> for TryFromInto<U>
+where
+ T: TryInto<U> + Clone,
+ <T as TryInto<U>>::Error: Display,
+ U: Serialize,
+{
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ source
+ .clone()
+ .try_into()
+ .map_err(S::Error::custom)?
+ .serialize(serializer)
+ }
+}
+
+impl<'a> SerializeAs<Cow<'a, str>> for BorrowCow {
+ fn serialize_as<S>(source: &Cow<'a, str>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_str(source)
+ }
+}
+
+impl<'a> SerializeAs<Cow<'a, [u8]>> for BorrowCow {
+ fn serialize_as<S>(value: &Cow<'a, [u8]>, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.collect_seq(value.iter())
+ }
+}
+
+impl<STRICTNESS: Strictness> SerializeAs<bool> for BoolFromInt<STRICTNESS> {
+ fn serialize_as<S>(source: &bool, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ serializer.serialize_u8(*source as u8)
+ }
+}
+
+// endregion
diff --git a/third_party/rust/serde_with/src/ser/legacy_arrays.rs b/third_party/rust/serde_with/src/ser/legacy_arrays.rs
new file mode 100644
index 0000000000..2c228ee640
--- /dev/null
+++ b/third_party/rust/serde_with/src/ser/legacy_arrays.rs
@@ -0,0 +1,34 @@
+use super::*;
+use alloc::collections::BTreeMap;
+use std::collections::HashMap;
+
+macro_rules! array_impl {
+ ($($len:literal)+) => {$(
+ impl<T, As> SerializeAs<[T; $len]> for [As; $len]
+ where
+ As: SerializeAs<T>,
+ {
+ fn serialize_as<S>(array: &[T; $len], serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use serde::ser::SerializeTuple;
+ let mut arr = serializer.serialize_tuple($len)?;
+ for elem in array {
+ arr.serialize_element(&SerializeAsWrap::<T, As>::new(elem))?;
+ }
+ arr.end()
+ }
+ }
+ )+};
+}
+
+array_impl!(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32);
+
+tuple_seq_as_map_impl! {
+ [(K, V); 0], [(K, V); 1], [(K, V); 2], [(K, V); 3], [(K, V); 4], [(K, V); 5], [(K, V); 6],
+ [(K, V); 7], [(K, V); 8], [(K, V); 9], [(K, V); 10], [(K, V); 11], [(K, V); 12], [(K, V); 13],
+ [(K, V); 14], [(K, V); 15], [(K, V); 16], [(K, V); 17], [(K, V); 18], [(K, V); 19], [(K, V); 20],
+ [(K, V); 21], [(K, V); 22], [(K, V); 23], [(K, V); 24], [(K, V); 25], [(K, V); 26], [(K, V); 27],
+ [(K, V); 28], [(K, V); 29], [(K, V); 30], [(K, V); 31], [(K, V); 32],
+}
diff --git a/third_party/rust/serde_with/src/ser/mod.rs b/third_party/rust/serde_with/src/ser/mod.rs
new file mode 100644
index 0000000000..dda0891e89
--- /dev/null
+++ b/third_party/rust/serde_with/src/ser/mod.rs
@@ -0,0 +1,158 @@
+//! Module for [`SerializeAs`][] implementations
+//!
+//! The module contains the [`SerializeAs`][] trait and helper code.
+//! Additionally, it contains implementations of [`SerializeAs`][] for types defined in the Rust Standard Library or this crate.
+//!
+//! You can find more details on how to implement this trait for your types in the documentation of the [`SerializeAs`][] trait and details about the usage in the [user guide][].
+//!
+//! [user guide]: crate::guide
+
+mod const_arrays;
+#[macro_use]
+mod impls;
+
+use super::*;
+
+/// A **data structure** that can be serialized into any data format supported by Serde, analogue to [`Serialize`].
+///
+/// The trait is analogue to the [`serde::Serialize`][`Serialize`] trait, with the same meaning of input and output arguments.
+/// It can and should the implemented using the same code structure as the [`Serialize`] trait.
+/// As such, the same advice for [implementing `Serialize`][impl-serialize] applies here.
+///
+/// # Differences to [`Serialize`]
+///
+/// The trait is only required for container-like types or types implementing specific conversion functions.
+/// Container-like types are [`Vec`], [`BTreeMap`], but also [`Option`] and [`Box`].
+/// Conversion types serialize into a different serde data type.
+/// For example, [`DisplayFromStr`] uses the [`Display`] trait to serialize a String and [`DurationSeconds`] converts a [`Duration`] into either String or integer values.
+///
+/// This code shows how to implement [`Serialize`] for [`Box`]:
+///
+/// ```rust,ignore
+/// impl<T> Serialize for Box<T>
+/// where
+/// T: Serialize,
+/// {
+/// #[inline]
+/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+/// where
+/// S: Serializer,
+/// {
+/// (**self).serialize(serializer)
+/// }
+/// }
+/// ```
+///
+/// and this code shows how to do the same using [`SerializeAs`][]:
+///
+/// ```rust,ignore
+/// impl<T, U> SerializeAs<Box<T>> for Box<U>
+/// where
+/// U: SerializeAs<T>,
+/// {
+/// fn serialize_as<S>(source: &Box<T>, serializer: S) -> Result<S::Ok, S::Error>
+/// where
+/// S: Serializer,
+/// {
+/// SerializeAsWrap::<T, U>::new(source).serialize(serializer)
+/// }
+/// }
+/// ```
+///
+/// It uses two type parameters, `T` and `U` instead of only one and performs the serialization step using the `SerializeAsWrap` type.
+/// The `T` type is the on the Rust side before serialization, whereas the `U` type determines how the value will be serialized.
+/// These two changes are usually enough to make a container type implement [`SerializeAs`][].
+///
+/// [`SerializeAsWrap`] is a piece of glue code which turns [`SerializeAs`] into a serde compatible datatype, by converting all calls to `serialize` into `serialize_as`.
+/// This allows us to implement [`SerializeAs`] such that it can be applied recursively throughout the whole data structure.
+/// This is mostly important for container types, such as `Vec` or `BTreeMap`.
+/// In a `BTreeMap` this allows us to specify two different serialization behaviors, one for key and one for value, using the [`SerializeAs`] trait.
+///
+/// ## Implementing a converter Type
+///
+/// This shows a simplified implementation for [`DisplayFromStr`].
+///
+/// ```rust
+/// # #[cfg(all(feature = "macros"))] {
+/// # use serde_with::SerializeAs;
+/// # use std::fmt::Display;
+/// struct DisplayFromStr;
+///
+/// impl<T> SerializeAs<T> for DisplayFromStr
+/// where
+/// T: Display,
+/// {
+/// fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+/// where
+/// S: serde::Serializer,
+/// {
+/// serializer.collect_str(&source)
+/// }
+/// }
+/// #
+/// # #[serde_with::serde_as]
+/// # #[derive(serde::Serialize)]
+/// # struct S (#[serde_as(as = "DisplayFromStr")] bool);
+/// #
+/// # assert_eq!(r#""false""#, serde_json::to_string(&S(false)).unwrap());
+/// # }
+/// ```
+///
+/// [`Box`]: std::boxed::Box
+/// [`BTreeMap`]: std::collections::BTreeMap
+/// [`Display`]: std::fmt::Display
+/// [`Duration`]: std::time::Duration
+/// [`Vec`]: std::vec::Vec
+/// [impl-serialize]: https://serde.rs/impl-serialize.html
+pub trait SerializeAs<T: ?Sized> {
+ /// Serialize this value into the given Serde serializer.
+ fn serialize_as<S>(source: &T, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer;
+}
+
+/// Helper type to implement [`SerializeAs`] for container-like types.
+#[derive(Debug)]
+pub struct SerializeAsWrap<'a, T: ?Sized, U: ?Sized> {
+ value: &'a T,
+ marker: PhantomData<U>,
+}
+
+impl<'a, T, U> SerializeAsWrap<'a, T, U>
+where
+ T: ?Sized,
+ U: ?Sized,
+{
+ /// Create new instance with provided value.
+ pub fn new(value: &'a T) -> Self {
+ Self {
+ value,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'a, T, U> Serialize for SerializeAsWrap<'a, T, U>
+where
+ T: ?Sized,
+ U: ?Sized,
+ U: SerializeAs<T>,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ U::serialize_as(self.value, serializer)
+ }
+}
+
+impl<'a, T, U> From<&'a T> for SerializeAsWrap<'a, T, U>
+where
+ T: ?Sized,
+ U: ?Sized,
+ U: SerializeAs<T>,
+{
+ fn from(value: &'a T) -> Self {
+ Self::new(value)
+ }
+}
diff --git a/third_party/rust/serde_with/src/serde_conv.rs b/third_party/rust/serde_with/src/serde_conv.rs
new file mode 100644
index 0000000000..c5659ebfda
--- /dev/null
+++ b/third_party/rust/serde_with/src/serde_conv.rs
@@ -0,0 +1,147 @@
+/// Create new conversion adapters from functions
+///
+/// The macro lets you create a new converter, which is usable for serde's with-attribute and `#[serde_as]`.
+/// Its main use case is to write simple converters for types, which are not serializable.
+/// Another use-case is to change the serialization behavior if the implemented `Serialize`/`Deserialize` trait is insufficient.
+///
+/// The macro takes four arguments:
+///
+/// 1. The name of the converter type.
+/// The type can be prefixed with a visibility modifies like `pub` or `pub(crate)`.
+/// By default, the type is not marked as public (`pub(self)`).
+/// 2. The type `T` we want to extend with custom behavior.
+/// 3. A function or macro taking a `&T` and returning a serializable type.
+/// 4. A function or macro taking a deserializable type and returning a `Result<T, E>`.
+/// The error type `E` must implement `Display`.
+///
+/// # Example
+///
+/// In this example, we write custom serialization behavior for a `Rgb` type.
+/// We want to serialize it as a `[u8; 3]`.
+///
+/// ```rust
+/// # #[cfg(feature = "macros")] {
+/// # use serde::{Serialize, Deserialize};
+///
+/// #[derive(Clone, Copy, Debug, PartialEq)]
+/// struct Rgb {
+/// red: u8,
+/// green: u8,
+/// blue: u8,
+/// }
+///
+/// serde_with::serde_conv!(
+/// RgbAsArray,
+/// Rgb,
+/// |rgb: &Rgb| [rgb.red, rgb.green, rgb.blue],
+/// |value: [u8; 3]| -> Result<_, std::convert::Infallible> {
+/// Ok(Rgb {
+/// red: value[0],
+/// green: value[1],
+/// blue: value[2],
+/// })
+/// }
+/// );
+///
+/// //////////////////////////////////////////////////
+///
+/// // We define some colors to be used later
+///
+/// let green = Rgb {red: 0, green: 255, blue: 0};
+/// let orange = Rgb {red: 255, green: 128, blue: 0};
+/// let pink = Rgb {red: 255, green: 0, blue: 255};
+///
+/// //////////////////////////////////////////////////
+///
+/// // We can now use the `RgbAsArray` adapter with `serde_as`.
+///
+/// #[serde_with::serde_as]
+/// #[derive(Debug, PartialEq, Serialize, Deserialize)]
+/// struct Colors {
+/// #[serde_as(as = "RgbAsArray")]
+/// one_rgb: Rgb,
+/// #[serde_as(as = "Vec<RgbAsArray>")]
+/// rgbs_in_vec: Vec<Rgb>,
+/// }
+///
+/// let data = Colors {
+/// one_rgb: orange,
+/// rgbs_in_vec: vec![green, pink],
+/// };
+/// let json = serde_json::json!({
+/// "one_rgb": [255, 128, 0],
+/// "rgbs_in_vec": [
+/// [0, 255, 0],
+/// [255, 0, 255]
+/// ]
+/// });
+///
+/// assert_eq!(json, serde_json::to_value(&data).unwrap());
+/// assert_eq!(data, serde_json::from_value(json).unwrap());
+///
+/// //////////////////////////////////////////////////
+///
+/// // The types generated by `serde_conv` is also compatible with serde's with attribute
+///
+/// #[derive(Debug, PartialEq, Serialize, Deserialize)]
+/// struct ColorsWith {
+/// #[serde(with = "RgbAsArray")]
+/// rgb_with: Rgb,
+/// }
+///
+/// let data = ColorsWith {
+/// rgb_with: pink,
+/// };
+/// let json = serde_json::json!({
+/// "rgb_with": [255, 0, 255]
+/// });
+///
+/// assert_eq!(json, serde_json::to_value(&data).unwrap());
+/// assert_eq!(data, serde_json::from_value(json).unwrap());
+/// # }
+/// ```
+#[macro_export]
+macro_rules! serde_conv {
+ ($m:ident, $t:ty, $ser:expr, $de:expr) => {$crate::serde_conv!(pub(self) $m, $t, $ser, $de);};
+ ($vis:vis $m:ident, $t:ty, $ser:expr, $de:expr) => {
+ #[allow(non_camel_case_types)]
+ $vis struct $m;
+
+ #[allow(clippy::ptr_arg)]
+ impl $m {
+ $vis fn serialize<S>(x: &$t, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
+ where
+ S: $crate::serde::Serializer,
+ {
+ let y = $ser(x);
+ $crate::serde::Serialize::serialize(&y, serializer)
+ }
+
+ $vis fn deserialize<'de, D>(deserializer: D) -> ::std::result::Result<$t, D::Error>
+ where
+ D: $crate::serde::Deserializer<'de>,
+ {
+ let y = $crate::serde::Deserialize::deserialize(deserializer)?;
+ $de(y).map_err($crate::serde::de::Error::custom)
+ }
+ }
+
+ impl $crate::SerializeAs<$t> for $m {
+ fn serialize_as<S>(x: &$t, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
+ where
+ S: $crate::serde::Serializer,
+ {
+ Self::serialize(x, serializer)
+ }
+ }
+
+ impl<'de> $crate::DeserializeAs<'de, $t> for $m {
+ fn deserialize_as<D>(deserializer: D) -> ::std::result::Result<$t, D::Error>
+ where
+ D: $crate::serde::Deserializer<'de>,
+ {
+ Self::deserialize(deserializer)
+ }
+ }
+ };
+}
diff --git a/third_party/rust/serde_with/src/time_0_3.rs b/third_party/rust/serde_with/src/time_0_3.rs
new file mode 100644
index 0000000000..76dca006d2
--- /dev/null
+++ b/third_party/rust/serde_with/src/time_0_3.rs
@@ -0,0 +1,382 @@
+//! De/Serialization of [time v0.3][time] types
+//!
+//! This modules is only available if using the `time_0_3` feature of the crate.
+//!
+//! [time]: https://docs.rs/time/0.3/
+
+use crate::{
+ de::DeserializeAs,
+ formats::{Flexible, Format, Strict, Strictness},
+ ser::SerializeAs,
+ utils::duration::{DurationSigned, Sign},
+ DurationMicroSeconds, DurationMicroSecondsWithFrac, DurationMilliSeconds,
+ DurationMilliSecondsWithFrac, DurationNanoSeconds, DurationNanoSecondsWithFrac,
+ DurationSeconds, DurationSecondsWithFrac, TimestampMicroSeconds, TimestampMicroSecondsWithFrac,
+ TimestampMilliSeconds, TimestampMilliSecondsWithFrac, TimestampNanoSeconds,
+ TimestampNanoSecondsWithFrac, TimestampSeconds, TimestampSecondsWithFrac,
+};
+use alloc::{format, string::String};
+use serde::{de, ser::Error as _, Deserializer, Serialize, Serializer};
+use std::{convert::TryInto, fmt, time::Duration as StdDuration};
+use time_0_3::{
+ format_description::well_known::{Rfc2822, Rfc3339},
+ Duration, OffsetDateTime, PrimitiveDateTime,
+};
+
+/// Create a [`PrimitiveDateTime`] for the Unix Epoch
+fn unix_epoch_primitive() -> PrimitiveDateTime {
+ PrimitiveDateTime::new(
+ time_0_3::Date::from_ordinal_date(1970, 1).unwrap(),
+ time_0_3::Time::from_hms_nano(0, 0, 0, 0).unwrap(),
+ )
+}
+
+/// Convert a [`time::Duration`][time_0_3::Duration] into a [`DurationSigned`]
+fn duration_into_duration_signed(dur: &Duration) -> DurationSigned {
+ let std_dur = StdDuration::new(
+ dur.whole_seconds().unsigned_abs(),
+ dur.subsec_nanoseconds().unsigned_abs(),
+ );
+
+ DurationSigned::with_duration(
+ // A duration of 0 is not positive, so check for negative value.
+ if dur.is_negative() {
+ Sign::Negative
+ } else {
+ Sign::Positive
+ },
+ std_dur,
+ )
+}
+
+/// Convert a [`DurationSigned`] into a [`time_0_3::Duration`]
+fn duration_from_duration_signed<'de, D>(sdur: DurationSigned) -> Result<Duration, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ let mut dur: Duration = match sdur.duration.try_into() {
+ Ok(dur) => dur,
+ Err(msg) => {
+ return Err(de::Error::custom(format!(
+ "Duration is outside of the representable range: {}",
+ msg
+ )))
+ }
+ };
+ if sdur.sign.is_negative() {
+ dur = -dur;
+ }
+ Ok(dur)
+}
+
+macro_rules! use_duration_signed_ser {
+ (
+ $main_trait:ident $internal_trait:ident =>
+ {
+ $ty:ty; $converter:ident =>
+ $({
+ $format:ty, $strictness:ty =>
+ $($tbound:ident: $bound:ident $(,)?)*
+ })*
+ }
+ ) => {
+ $(
+ impl<$($tbound ,)*> SerializeAs<$ty> for $main_trait<$format, $strictness>
+ where
+ $($tbound: $bound,)*
+ {
+ fn serialize_as<S>(source: &$ty, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let dur: DurationSigned = $converter(source);
+ $internal_trait::<$format, $strictness>::serialize_as(
+ &dur,
+ serializer,
+ )
+ }
+ }
+ )*
+ };
+ (
+ $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt
+ ) => {
+ $( use_duration_signed_ser!($main_trait $internal_trait => $rest); )+
+ };
+}
+
+fn offset_datetime_to_duration(source: &OffsetDateTime) -> DurationSigned {
+ duration_into_duration_signed(&(*source - OffsetDateTime::UNIX_EPOCH))
+}
+
+fn primitive_datetime_to_duration(source: &PrimitiveDateTime) -> DurationSigned {
+ duration_into_duration_signed(&(*source - unix_epoch_primitive()))
+}
+
+use_duration_signed_ser!(
+ DurationSeconds DurationSeconds,
+ DurationMilliSeconds DurationMilliSeconds,
+ DurationMicroSeconds DurationMicroSeconds,
+ DurationNanoSeconds DurationNanoSeconds,
+ => {
+ Duration; duration_into_duration_signed =>
+ {i64, STRICTNESS => STRICTNESS: Strictness}
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+use_duration_signed_ser!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ OffsetDateTime; offset_datetime_to_duration =>
+ {i64, STRICTNESS => STRICTNESS: Strictness}
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+use_duration_signed_ser!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ PrimitiveDateTime; primitive_datetime_to_duration =>
+ {i64, STRICTNESS => STRICTNESS: Strictness}
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+
+// Duration/Timestamp WITH FRACTIONS
+use_duration_signed_ser!(
+ DurationSecondsWithFrac DurationSecondsWithFrac,
+ DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ Duration; duration_into_duration_signed =>
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+use_duration_signed_ser!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ OffsetDateTime; offset_datetime_to_duration =>
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+use_duration_signed_ser!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ PrimitiveDateTime; primitive_datetime_to_duration =>
+ {f64, STRICTNESS => STRICTNESS: Strictness}
+ {String, STRICTNESS => STRICTNESS: Strictness}
+ }
+);
+
+macro_rules! use_duration_signed_de {
+ (
+ $main_trait:ident $internal_trait:ident =>
+ {
+ $ty:ty; $converter:ident =>
+ $({
+ $format:ty, $strictness:ty =>
+ $($tbound:ident: $bound:ident)*
+ })*
+ }
+ ) =>{
+ $(
+ impl<'de, $($tbound,)*> DeserializeAs<'de, $ty> for $main_trait<$format, $strictness>
+ where
+ $($tbound: $bound,)*
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<$ty, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let dur: DurationSigned = $internal_trait::<$format, $strictness>::deserialize_as(deserializer)?;
+ $converter::<D>(dur)
+ }
+ }
+ )*
+ };
+ (
+ $( $main_trait:ident $internal_trait:ident, )+ => $rest:tt
+ ) => {
+ $( use_duration_signed_de!($main_trait $internal_trait => $rest); )+
+ };
+}
+
+fn duration_to_offset_datetime<'de, D>(dur: DurationSigned) -> Result<OffsetDateTime, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ Ok(OffsetDateTime::UNIX_EPOCH + duration_from_duration_signed::<D>(dur)?)
+}
+
+fn duration_to_primitive_datetime<'de, D>(
+ dur: DurationSigned,
+) -> Result<PrimitiveDateTime, D::Error>
+where
+ D: Deserializer<'de>,
+{
+ Ok(unix_epoch_primitive() + duration_from_duration_signed::<D>(dur)?)
+}
+
+// No subsecond precision
+use_duration_signed_de!(
+ DurationSeconds DurationSeconds,
+ DurationMilliSeconds DurationMilliSeconds,
+ DurationMicroSeconds DurationMicroSeconds,
+ DurationNanoSeconds DurationNanoSeconds,
+ => {
+ Duration; duration_from_duration_signed =>
+ {i64, Strict =>}
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_duration_signed_de!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ OffsetDateTime; duration_to_offset_datetime =>
+ {i64, Strict =>}
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_duration_signed_de!(
+ TimestampSeconds DurationSeconds,
+ TimestampMilliSeconds DurationMilliSeconds,
+ TimestampMicroSeconds DurationMicroSeconds,
+ TimestampNanoSeconds DurationNanoSeconds,
+ => {
+ PrimitiveDateTime; duration_to_primitive_datetime =>
+ {i64, Strict =>}
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+
+// Duration/Timestamp WITH FRACTIONS
+use_duration_signed_de!(
+ DurationSecondsWithFrac DurationSecondsWithFrac,
+ DurationMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ DurationMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ DurationNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ Duration; duration_from_duration_signed =>
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_duration_signed_de!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ OffsetDateTime; duration_to_offset_datetime =>
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+use_duration_signed_de!(
+ TimestampSecondsWithFrac DurationSecondsWithFrac,
+ TimestampMilliSecondsWithFrac DurationMilliSecondsWithFrac,
+ TimestampMicroSecondsWithFrac DurationMicroSecondsWithFrac,
+ TimestampNanoSecondsWithFrac DurationNanoSecondsWithFrac,
+ => {
+ PrimitiveDateTime; duration_to_primitive_datetime =>
+ {f64, Strict =>}
+ {String, Strict =>}
+ {FORMAT, Flexible => FORMAT: Format}
+ }
+);
+
+impl SerializeAs<OffsetDateTime> for Rfc2822 {
+ fn serialize_as<S>(datetime: &OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ datetime
+ .format(&Rfc2822)
+ .map_err(S::Error::custom)?
+ .serialize(serializer)
+ }
+}
+
+impl<'de> DeserializeAs<'de, OffsetDateTime> for Rfc2822 {
+ fn deserialize_as<D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct Visitor;
+ impl<'de> de::Visitor<'de> for Visitor {
+ type Value = OffsetDateTime;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a RFC2822-formatted `OffsetDateTime`")
+ }
+
+ fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
+ Self::Value::parse(value, &Rfc2822).map_err(E::custom)
+ }
+ }
+
+ deserializer.deserialize_str(Visitor)
+ }
+}
+
+impl SerializeAs<OffsetDateTime> for Rfc3339 {
+ fn serialize_as<S>(datetime: &OffsetDateTime, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ datetime
+ .format(&Rfc3339)
+ .map_err(S::Error::custom)?
+ .serialize(serializer)
+ }
+}
+
+impl<'de> DeserializeAs<'de, OffsetDateTime> for Rfc3339 {
+ fn deserialize_as<D>(deserializer: D) -> Result<OffsetDateTime, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct Visitor;
+ impl<'de> de::Visitor<'de> for Visitor {
+ type Value = OffsetDateTime;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("a RFC3339-formatted `OffsetDateTime`")
+ }
+
+ fn visit_str<E: de::Error>(self, value: &str) -> Result<Self::Value, E> {
+ Self::Value::parse(value, &Rfc3339).map_err(E::custom)
+ }
+ }
+
+ deserializer.deserialize_str(Visitor)
+ }
+}
diff --git a/third_party/rust/serde_with/src/utils.rs b/third_party/rust/serde_with/src/utils.rs
new file mode 100644
index 0000000000..ccf99128e4
--- /dev/null
+++ b/third_party/rust/serde_with/src/utils.rs
@@ -0,0 +1,120 @@
+pub(crate) mod duration;
+
+use alloc::string::String;
+use core::marker::PhantomData;
+use serde::de::{Deserialize, MapAccess, SeqAccess};
+
+/// Re-Implementation of `serde::private::de::size_hint::cautious`
+#[inline]
+pub(crate) fn size_hint_cautious(hint: Option<usize>) -> usize {
+ core::cmp::min(hint.unwrap_or(0), 4096)
+}
+
+pub(crate) const NANOS_PER_SEC: u32 = 1_000_000_000;
+// pub(crate) const NANOS_PER_MILLI: u32 = 1_000_000;
+// pub(crate) const NANOS_PER_MICRO: u32 = 1_000;
+// pub(crate) const MILLIS_PER_SEC: u64 = 1_000;
+// pub(crate) const MICROS_PER_SEC: u64 = 1_000_000;
+
+pub(crate) struct MapIter<'de, A, K, V> {
+ pub(crate) access: A,
+ marker: PhantomData<(&'de (), K, V)>,
+}
+
+impl<'de, A, K, V> MapIter<'de, A, K, V> {
+ pub(crate) fn new(access: A) -> Self
+ where
+ A: MapAccess<'de>,
+ {
+ Self {
+ access,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'de, A, K, V> Iterator for MapIter<'de, A, K, V>
+where
+ A: MapAccess<'de>,
+ K: Deserialize<'de>,
+ V: Deserialize<'de>,
+{
+ type Item = Result<(K, V), A::Error>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.access.next_entry().transpose()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ match self.access.size_hint() {
+ Some(size) => (size, Some(size)),
+ None => (0, None),
+ }
+ }
+}
+
+pub(crate) struct SeqIter<'de, A, T> {
+ access: A,
+ marker: PhantomData<(&'de (), T)>,
+}
+
+impl<'de, A, T> SeqIter<'de, A, T> {
+ pub(crate) fn new(access: A) -> Self
+ where
+ A: SeqAccess<'de>,
+ {
+ Self {
+ access,
+ marker: PhantomData,
+ }
+ }
+}
+
+impl<'de, A, T> Iterator for SeqIter<'de, A, T>
+where
+ A: SeqAccess<'de>,
+ T: Deserialize<'de>,
+{
+ type Item = Result<T, A::Error>;
+
+ fn next(&mut self) -> Option<Self::Item> {
+ self.access.next_element().transpose()
+ }
+
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ match self.access.size_hint() {
+ Some(size) => (size, Some(size)),
+ None => (0, None),
+ }
+ }
+}
+
+pub(crate) fn duration_as_secs_f64(dur: &core::time::Duration) -> f64 {
+ (dur.as_secs() as f64) + (dur.subsec_nanos() as f64) / (NANOS_PER_SEC as f64)
+}
+
+pub(crate) fn duration_signed_from_secs_f64(
+ secs: f64,
+) -> Result<self::duration::DurationSigned, String> {
+ const MAX_NANOS_F64: f64 = ((u64::max_value() as u128 + 1) * (NANOS_PER_SEC as u128)) as f64;
+ // TODO why are the seconds converted to nanoseconds first?
+ // Does it make sense to just truncate the value?
+ let mut nanos = secs * (NANOS_PER_SEC as f64);
+ if !nanos.is_finite() {
+ return Err("got non-finite value when converting float to duration".into());
+ }
+ if nanos >= MAX_NANOS_F64 {
+ return Err("overflow when converting float to duration".into());
+ }
+ let mut sign = self::duration::Sign::Positive;
+ if nanos < 0.0 {
+ nanos = -nanos;
+ sign = self::duration::Sign::Negative;
+ }
+ let nanos = nanos as u128;
+ Ok(self::duration::DurationSigned::new(
+ sign,
+ (nanos / (NANOS_PER_SEC as u128)) as u64,
+ (nanos % (NANOS_PER_SEC as u128)) as u32,
+ ))
+}
diff --git a/third_party/rust/serde_with/src/utils/duration.rs b/third_party/rust/serde_with/src/utils/duration.rs
new file mode 100644
index 0000000000..2d5a27e87d
--- /dev/null
+++ b/third_party/rust/serde_with/src/utils/duration.rs
@@ -0,0 +1,559 @@
+//! Internal Helper types
+
+use crate::{
+ formats::{Flexible, Format, Strict, Strictness},
+ utils, DeserializeAs, DurationMicroSeconds, DurationMicroSecondsWithFrac, DurationMilliSeconds,
+ DurationMilliSecondsWithFrac, DurationNanoSeconds, DurationNanoSecondsWithFrac,
+ DurationSeconds, DurationSecondsWithFrac, SerializeAs,
+};
+use alloc::{
+ format,
+ string::{String, ToString},
+ vec::Vec,
+};
+use core::{fmt, ops::Neg, time::Duration};
+use serde::{
+ de::{self, Unexpected, Visitor},
+ ser, Deserialize, Deserializer, Serialize, Serializer,
+};
+use std::time::SystemTime;
+
+#[derive(Copy, Clone, Debug, Eq, PartialEq)]
+pub(crate) enum Sign {
+ Positive,
+ Negative,
+}
+
+impl Sign {
+ #[allow(dead_code)]
+ pub(crate) fn is_positive(&self) -> bool {
+ *self == Sign::Positive
+ }
+
+ #[allow(dead_code)]
+ pub(crate) fn is_negative(&self) -> bool {
+ *self == Sign::Negative
+ }
+
+ pub(crate) fn apply<T>(&self, value: T) -> T
+ where
+ T: Neg<Output = T>,
+ {
+ match *self {
+ Sign::Positive => value,
+ Sign::Negative => value.neg(),
+ }
+ }
+}
+
+#[derive(Copy, Clone, Debug)]
+pub(crate) struct DurationSigned {
+ pub(crate) sign: Sign,
+ pub(crate) duration: Duration,
+}
+
+impl DurationSigned {
+ pub(crate) fn new(sign: Sign, secs: u64, nanosecs: u32) -> Self {
+ Self {
+ sign,
+ duration: Duration::new(secs, nanosecs),
+ }
+ }
+
+ #[cfg(any(feature = "chrono", feature = "time_0_3"))]
+ pub(crate) fn with_duration(sign: Sign, duration: Duration) -> Self {
+ Self { sign, duration }
+ }
+
+ pub(crate) fn to_system_time<'de, D>(self) -> Result<SystemTime, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ match self.sign {
+ Sign::Positive => SystemTime::UNIX_EPOCH.checked_add(self.duration),
+ Sign::Negative => SystemTime::UNIX_EPOCH.checked_sub(self.duration),
+ }
+ .ok_or_else(|| {
+ de::Error::custom("timestamp is outside the range for std::time::SystemTime")
+ })
+ }
+
+ pub(crate) fn to_std_duration<'de, D>(self) -> Result<Duration, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ match self.sign {
+ Sign::Positive => Ok(self.duration),
+ Sign::Negative => Err(de::Error::custom("std::time::Duration cannot be negative")),
+ }
+ }
+}
+
+impl From<&Duration> for DurationSigned {
+ fn from(&duration: &Duration) -> Self {
+ Self {
+ sign: Sign::Positive,
+ duration,
+ }
+ }
+}
+
+impl From<&SystemTime> for DurationSigned {
+ fn from(time: &SystemTime) -> Self {
+ match time.duration_since(SystemTime::UNIX_EPOCH) {
+ Ok(dur) => DurationSigned {
+ sign: Sign::Positive,
+ duration: dur,
+ },
+ Err(err) => DurationSigned {
+ sign: Sign::Negative,
+ duration: err.duration(),
+ },
+ }
+ }
+}
+
+impl core::ops::Mul<u32> for DurationSigned {
+ type Output = DurationSigned;
+
+ fn mul(mut self, rhs: u32) -> Self::Output {
+ self.duration *= rhs;
+ self
+ }
+}
+
+impl core::ops::Div<u32> for DurationSigned {
+ type Output = DurationSigned;
+
+ fn div(mut self, rhs: u32) -> Self::Output {
+ self.duration /= rhs;
+ self
+ }
+}
+
+impl<STRICTNESS> SerializeAs<DurationSigned> for DurationSeconds<u64, STRICTNESS>
+where
+ STRICTNESS: Strictness,
+{
+ fn serialize_as<S>(source: &DurationSigned, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ if source.sign.is_negative() {
+ return Err(ser::Error::custom(
+ "cannot serialize a negative Duration as u64",
+ ));
+ }
+
+ let mut secs = source.duration.as_secs();
+
+ // Properly round the value
+ if source.duration.subsec_millis() >= 500 {
+ if source.sign.is_positive() {
+ secs += 1;
+ } else {
+ secs -= 1;
+ }
+ }
+ secs.serialize(serializer)
+ }
+}
+
+impl<STRICTNESS> SerializeAs<DurationSigned> for DurationSeconds<i64, STRICTNESS>
+where
+ STRICTNESS: Strictness,
+{
+ fn serialize_as<S>(source: &DurationSigned, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut secs = source.sign.apply(source.duration.as_secs() as i64);
+
+ // Properly round the value
+ if source.duration.subsec_millis() >= 500 {
+ if source.sign.is_positive() {
+ secs += 1;
+ } else {
+ secs -= 1;
+ }
+ }
+ secs.serialize(serializer)
+ }
+}
+
+impl<STRICTNESS> SerializeAs<DurationSigned> for DurationSeconds<f64, STRICTNESS>
+where
+ STRICTNESS: Strictness,
+{
+ fn serialize_as<S>(source: &DurationSigned, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut secs = source.sign.apply(source.duration.as_secs() as f64);
+
+ // Properly round the value
+ if source.duration.subsec_millis() >= 500 {
+ if source.sign.is_positive() {
+ secs += 1.;
+ } else {
+ secs -= 1.;
+ }
+ }
+ secs.serialize(serializer)
+ }
+}
+
+impl<STRICTNESS> SerializeAs<DurationSigned> for DurationSeconds<String, STRICTNESS>
+where
+ STRICTNESS: Strictness,
+{
+ fn serialize_as<S>(source: &DurationSigned, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ let mut secs = source.sign.apply(source.duration.as_secs() as i64);
+
+ // Properly round the value
+ if source.duration.subsec_millis() >= 500 {
+ if source.sign.is_positive() {
+ secs += 1;
+ } else {
+ secs -= 1;
+ }
+ }
+ secs.to_string().serialize(serializer)
+ }
+}
+
+impl<STRICTNESS> SerializeAs<DurationSigned> for DurationSecondsWithFrac<f64, STRICTNESS>
+where
+ STRICTNESS: Strictness,
+{
+ fn serialize_as<S>(source: &DurationSigned, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ source
+ .sign
+ .apply(utils::duration_as_secs_f64(&source.duration))
+ .serialize(serializer)
+ }
+}
+
+impl<STRICTNESS> SerializeAs<DurationSigned> for DurationSecondsWithFrac<String, STRICTNESS>
+where
+ STRICTNESS: Strictness,
+{
+ fn serialize_as<S>(source: &DurationSigned, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ source
+ .sign
+ .apply(utils::duration_as_secs_f64(&source.duration))
+ .to_string()
+ .serialize(serializer)
+ }
+}
+
+macro_rules! duration_impls {
+ ($($inner:ident { $($factor:literal => $outer:ident,)+ })+) => {
+ $($(
+
+ impl<FORMAT, STRICTNESS> SerializeAs<DurationSigned> for $outer<FORMAT, STRICTNESS>
+ where
+ FORMAT: Format,
+ STRICTNESS: Strictness,
+ $inner<FORMAT, STRICTNESS>: SerializeAs<DurationSigned>
+ {
+ fn serialize_as<S>(source: &DurationSigned, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ $inner::<FORMAT, STRICTNESS>::serialize_as(&(*source * $factor), serializer)
+ }
+ }
+
+ impl<'de, FORMAT, STRICTNESS> DeserializeAs<'de, DurationSigned> for $outer<FORMAT, STRICTNESS>
+ where
+ FORMAT: Format,
+ STRICTNESS: Strictness,
+ $inner<FORMAT, STRICTNESS>: DeserializeAs<'de, DurationSigned>,
+ {
+ fn deserialize_as<D>(deserializer: D) -> Result<DurationSigned, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let dur = $inner::<FORMAT, STRICTNESS>::deserialize_as(deserializer)?;
+ Ok(dur / $factor)
+ }
+ }
+
+ )+)+ };
+}
+duration_impls!(
+ DurationSeconds {
+ 1000u32 => DurationMilliSeconds,
+ 1_000_000u32 => DurationMicroSeconds,
+ 1_000_000_000u32 => DurationNanoSeconds,
+ }
+ DurationSecondsWithFrac {
+ 1000u32 => DurationMilliSecondsWithFrac,
+ 1_000_000u32 => DurationMicroSecondsWithFrac,
+ 1_000_000_000u32 => DurationNanoSecondsWithFrac,
+ }
+);
+
+struct DurationVisitorFlexible;
+impl<'de> Visitor<'de> for DurationVisitorFlexible {
+ type Value = DurationSigned;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ formatter.write_str("an integer, a float, or a string containing a number")
+ }
+
+ fn visit_i64<E>(self, value: i64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ if value >= 0 {
+ Ok(DurationSigned::new(Sign::Positive, value as u64, 0))
+ } else {
+ Ok(DurationSigned::new(Sign::Negative, (-value) as u64, 0))
+ }
+ }
+
+ fn visit_u64<E>(self, secs: u64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ Ok(DurationSigned::new(Sign::Positive, secs, 0))
+ }
+
+ fn visit_f64<E>(self, secs: f64) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ utils::duration_signed_from_secs_f64(secs).map_err(de::Error::custom)
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ match parse_float_into_time_parts(value) {
+ Ok((sign, seconds, subseconds)) => Ok(DurationSigned::new(sign, seconds, subseconds)),
+ Err(ParseFloatError::InvalidValue) => {
+ Err(de::Error::invalid_value(Unexpected::Str(value), &self))
+ }
+ Err(ParseFloatError::Custom(msg)) => Err(de::Error::custom(msg)),
+ }
+ }
+}
+
+impl<'de> DeserializeAs<'de, DurationSigned> for DurationSeconds<u64, Strict> {
+ fn deserialize_as<D>(deserializer: D) -> Result<DurationSigned, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ u64::deserialize(deserializer).map(|secs: u64| DurationSigned::new(Sign::Positive, secs, 0))
+ }
+}
+
+impl<'de> DeserializeAs<'de, DurationSigned> for DurationSeconds<i64, Strict> {
+ fn deserialize_as<D>(deserializer: D) -> Result<DurationSigned, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ i64::deserialize(deserializer).map(|mut secs: i64| {
+ let mut sign = Sign::Positive;
+ if secs.is_negative() {
+ secs = -secs;
+ sign = Sign::Negative;
+ }
+ DurationSigned::new(sign, secs as u64, 0)
+ })
+ }
+}
+
+impl<'de> DeserializeAs<'de, DurationSigned> for DurationSeconds<f64, Strict> {
+ fn deserialize_as<D>(deserializer: D) -> Result<DurationSigned, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let val = f64::deserialize(deserializer)?.round();
+ utils::duration_signed_from_secs_f64(val).map_err(de::Error::custom)
+ }
+}
+
+impl<'de> DeserializeAs<'de, DurationSigned> for DurationSeconds<String, Strict> {
+ fn deserialize_as<D>(deserializer: D) -> Result<DurationSigned, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct DurationDeserializationVisitor;
+
+ impl<'de> Visitor<'de> for DurationDeserializationVisitor {
+ type Value = DurationSigned;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(formatter, "a string containing a number")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ let mut secs: i64 = value.parse().map_err(de::Error::custom)?;
+ let mut sign = Sign::Positive;
+ if secs.is_negative() {
+ secs = -secs;
+ sign = Sign::Negative;
+ }
+ Ok(DurationSigned::new(sign, secs as u64, 0))
+ }
+ }
+
+ deserializer.deserialize_str(DurationDeserializationVisitor)
+ }
+}
+
+impl<'de, FORMAT> DeserializeAs<'de, DurationSigned> for DurationSeconds<FORMAT, Flexible>
+where
+ FORMAT: Format,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<DurationSigned, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_any(DurationVisitorFlexible)
+ }
+}
+
+impl<'de> DeserializeAs<'de, DurationSigned> for DurationSecondsWithFrac<f64, Strict> {
+ fn deserialize_as<D>(deserializer: D) -> Result<DurationSigned, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let val = f64::deserialize(deserializer)?;
+ utils::duration_signed_from_secs_f64(val).map_err(de::Error::custom)
+ }
+}
+
+impl<'de> DeserializeAs<'de, DurationSigned> for DurationSecondsWithFrac<String, Strict> {
+ fn deserialize_as<D>(deserializer: D) -> Result<DurationSigned, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let value = String::deserialize(deserializer)?;
+ match parse_float_into_time_parts(&value) {
+ Ok((sign, seconds, subseconds)) => Ok(DurationSigned {
+ sign,
+ duration: Duration::new(seconds, subseconds),
+ }),
+ Err(ParseFloatError::InvalidValue) => Err(de::Error::invalid_value(
+ Unexpected::Str(&value),
+ &"a string containing an integer or float",
+ )),
+ Err(ParseFloatError::Custom(msg)) => Err(de::Error::custom(msg)),
+ }
+ }
+}
+
+impl<'de, FORMAT> DeserializeAs<'de, DurationSigned> for DurationSecondsWithFrac<FORMAT, Flexible>
+where
+ FORMAT: Format,
+{
+ fn deserialize_as<D>(deserializer: D) -> Result<DurationSigned, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_any(DurationVisitorFlexible)
+ }
+}
+
+#[derive(Debug, Eq, PartialEq)]
+pub(crate) enum ParseFloatError {
+ InvalidValue,
+ Custom(String),
+}
+
+fn parse_float_into_time_parts(mut value: &str) -> Result<(Sign, u64, u32), ParseFloatError> {
+ let sign = match value.chars().next() {
+ // Advance by the size of the parsed char
+ Some('+') => {
+ value = &value[1..];
+ Sign::Positive
+ }
+ Some('-') => {
+ value = &value[1..];
+ Sign::Negative
+ }
+ _ => Sign::Positive,
+ };
+
+ let parts: Vec<_> = value.split('.').collect();
+ match *parts.as_slice() {
+ [seconds] => {
+ if let Ok(seconds) = seconds.parse() {
+ Ok((sign, seconds, 0))
+ } else {
+ Err(ParseFloatError::InvalidValue)
+ }
+ }
+ [seconds, subseconds] => {
+ if let Ok(seconds) = seconds.parse() {
+ let subseclen = subseconds.chars().count() as u32;
+ if subseclen > 9 {
+ return Err(ParseFloatError::Custom(format!(
+ "Duration and Timestamps with no more than 9 digits precision, but '{}' has more",
+ value
+ )));
+ }
+
+ if let Ok(mut subseconds) = subseconds.parse() {
+ // convert subseconds to nanoseconds (10^-9), require 9 places for nanoseconds
+ subseconds *= 10u32.pow(9 - subseclen);
+ Ok((sign, seconds, subseconds))
+ } else {
+ Err(ParseFloatError::InvalidValue)
+ }
+ } else {
+ Err(ParseFloatError::InvalidValue)
+ }
+ }
+
+ _ => Err(ParseFloatError::InvalidValue),
+ }
+}
+
+#[test]
+fn test_parse_float_into_time_parts() {
+ // Test normal behavior
+ assert_eq!(
+ Ok((Sign::Positive, 123, 456_000_000)),
+ parse_float_into_time_parts("+123.456")
+ );
+ assert_eq!(
+ Ok((Sign::Negative, 123, 987_000)),
+ parse_float_into_time_parts("-123.000987")
+ );
+ assert_eq!(
+ Ok((Sign::Positive, 18446744073709551615, 123_456_789)),
+ parse_float_into_time_parts("18446744073709551615.123456789")
+ );
+
+ // Test behavior around 0
+ assert_eq!(
+ Ok((Sign::Positive, 0, 456_000_000)),
+ parse_float_into_time_parts("+0.456")
+ );
+ assert_eq!(
+ Ok((Sign::Negative, 0, 987_000)),
+ parse_float_into_time_parts("-0.000987")
+ );
+ assert_eq!(
+ Ok((Sign::Positive, 0, 123_456_789)),
+ parse_float_into_time_parts("0.123456789")
+ );
+}
diff --git a/third_party/rust/serde_with/src/with_prefix.rs b/third_party/rust/serde_with/src/with_prefix.rs
new file mode 100644
index 0000000000..b4b483c983
--- /dev/null
+++ b/third_party/rust/serde_with/src/with_prefix.rs
@@ -0,0 +1,612 @@
+use alloc::string::String;
+use core::fmt;
+use serde::{
+ de::{self, DeserializeSeed, Deserializer, IgnoredAny, IntoDeserializer, MapAccess, Visitor},
+ forward_to_deserialize_any,
+ ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer},
+};
+
+/// Serialize with an added prefix on every field name and deserialize by
+/// trimming away the prefix.
+///
+/// You can set the visibility of the generated module by prefixing the module name with a module visibility.
+/// `with_prefix!(pub(crate) prefix_foo "foo_");` creates a module with `pub(crate)` visibility.
+/// The visibility is optional and by default `pub(self)`, i.e., private visibility is assumed.
+///
+/// **Note:** Use of this macro is incompatible with applying the [`deny_unknown_fields`] attribute
+/// on the container.
+/// While deserializing, it will always warn about unknown fields, even though they are processed
+/// by the `with_prefix` wrapper.
+/// More details can be found in [this issue][issue-with_prefix-deny_unknown_fields].
+///
+/// # Example
+///
+/// The [Challonge REST API] likes to use prefixes to group related fields. In
+/// simplified form, their JSON may resemble the following:
+///
+/// [Challonge REST API]: https://api.challonge.com/v1/documents/matches/show
+///
+/// ```json
+/// {
+/// "player1_name": "name1",
+/// "player1_votes": 1,
+/// "player2_name": "name2",
+/// "player2_votes": 2
+/// }
+/// ```
+///
+/// In Rust, we would ideally like to model this data as a pair of `Player`
+/// structs, rather than repeating the fields of `Player` for each prefix.
+///
+/// ```rust
+/// # #[allow(dead_code)]
+/// struct Match {
+/// player1: Player,
+/// player2: Player,
+/// }
+///
+/// # #[allow(dead_code)]
+/// struct Player {
+/// name: String,
+/// votes: u64,
+/// }
+/// ```
+///
+/// This `with_prefix!` macro produces an adapter that adds a prefix onto field
+/// names during serialization and trims away the prefix during deserialization.
+/// An implementation of the Challonge API would use `with_prefix!` like this:
+///
+/// ```rust
+/// use serde::{Deserialize, Serialize};
+/// use serde_with::with_prefix;
+///
+/// #[derive(Serialize, Deserialize)]
+/// struct Match {
+/// #[serde(flatten, with = "prefix_player1")]
+/// player1: Player,
+/// #[serde(flatten, with = "prefix_player2")]
+/// player2: Player,
+/// }
+///
+/// #[derive(Serialize, Deserialize)]
+/// struct Player {
+/// name: String,
+/// votes: u64,
+/// }
+///
+/// with_prefix!(prefix_player1 "player1_");
+/// // You can also set the visibility of the generated prefix module, the default is private.
+/// with_prefix!(pub prefix_player2 "player2_");
+/// #
+/// # const EXPECTED: &str = r#"{
+/// # "player1_name": "name1",
+/// # "player1_votes": 1,
+/// # "player2_name": "name2",
+/// # "player2_votes": 2
+/// # }"#;
+///
+/// fn main() {
+/// let m = Match {
+/// player1: Player {
+/// name: "name1".to_owned(),
+/// votes: 1,
+/// },
+/// player2: Player {
+/// name: "name2".to_owned(),
+/// votes: 2,
+/// },
+/// };
+///
+/// let j = serde_json::to_string_pretty(&m).unwrap();
+/// println!("{}", j);
+/// #
+/// # assert_eq!(j, EXPECTED);
+/// }
+/// ```
+///
+/// [`deny_unknown_fields`]: https://serde.rs/container-attrs.html#deny_unknown_fields
+/// [issue-with_prefix-deny_unknown_fields]: https://github.com/jonasbb/serde_with/issues/57
+#[macro_export]
+macro_rules! with_prefix {
+ ($module:ident $prefix:expr) => {$crate::with_prefix!(pub(self) $module $prefix);};
+ ($vis:vis $module:ident $prefix:expr) => {
+ $vis mod $module {
+ use $crate::serde::{Deserialize, Deserializer, Serialize, Serializer};
+ use $crate::with_prefix::WithPrefix;
+
+ #[allow(dead_code)]
+ pub fn serialize<T, S>(object: &T, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
+ where
+ T: Serialize,
+ S: Serializer,
+ {
+ object.serialize(WithPrefix {
+ delegate: serializer,
+ prefix: $prefix,
+ })
+ }
+
+ #[allow(dead_code)]
+ pub fn deserialize<'de, T, D>(deserializer: D) -> ::std::result::Result<T, D::Error>
+ where
+ T: Deserialize<'de>,
+ D: Deserializer<'de>,
+ {
+ T::deserialize(WithPrefix {
+ delegate: deserializer,
+ prefix: $prefix,
+ })
+ }
+ }
+ };
+}
+
+#[allow(missing_debug_implementations)]
+pub struct WithPrefix<'a, T> {
+ pub delegate: T,
+ pub prefix: &'a str,
+}
+
+impl<'a, T> Serialize for WithPrefix<'a, T>
+where
+ T: Serialize,
+{
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.delegate.serialize(WithPrefix {
+ delegate: serializer,
+ prefix: self.prefix,
+ })
+ }
+}
+
+impl<'a, S> Serializer for WithPrefix<'a, S>
+where
+ S: Serializer,
+{
+ type Ok = S::Ok;
+ type Error = S::Error;
+ type SerializeSeq = Impossible<Self::Ok, Self::Error>;
+ type SerializeTuple = Impossible<Self::Ok, Self::Error>;
+ type SerializeTupleStruct = Impossible<Self::Ok, Self::Error>;
+ type SerializeTupleVariant = Impossible<Self::Ok, Self::Error>;
+ type SerializeMap = WithPrefix<'a, S::SerializeMap>;
+ type SerializeStruct = WithPrefix<'a, S::SerializeMap>;
+ type SerializeStructVariant = Impossible<Self::Ok, Self::Error>;
+
+ fn serialize_bool(self, _v: bool) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_i8(self, _v: i8) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_i16(self, _v: i16) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_i32(self, _v: i32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_i64(self, _v: i64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_u8(self, _v: u8) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_u16(self, _v: u16) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_u32(self, _v: u32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_u64(self, _v: u64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_f32(self, _v: f32) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_f64(self, _v: f64) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_char(self, _v: char) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error> {
+ self.delegate
+ .collect_str(&format_args!("{}{}", self.prefix, v))
+ }
+
+ fn serialize_bytes(self, _v: &[u8]) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_none(self) -> Result<Self::Ok, Self::Error> {
+ self.delegate.serialize_none()
+ }
+
+ fn serialize_some<T>(self, value: &T) -> Result<Self::Ok, Self::Error>
+ where
+ T: ?Sized + Serialize,
+ {
+ self.delegate.serialize_some(&WithPrefix {
+ delegate: value,
+ prefix: self.prefix,
+ })
+ }
+
+ fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Self::Ok, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ variant: &'static str,
+ ) -> Result<Self::Ok, Self::Error> {
+ self.serialize_str(variant)
+ }
+
+ fn serialize_newtype_struct<T>(
+ self,
+ _name: &'static str,
+ _value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _value: &T,
+ ) -> Result<Self::Ok, Self::Error>
+ where
+ T: ?Sized + Serialize,
+ {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_seq(self, _len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_tuple(self, _len: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ _name: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleStruct, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeTupleVariant, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ Ok(WithPrefix {
+ delegate: self.delegate.serialize_map(len)?,
+ prefix: self.prefix,
+ })
+ }
+
+ fn serialize_struct(
+ self,
+ _name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStruct, Self::Error> {
+ self.serialize_map(Some(len))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _name: &'static str,
+ _variant_index: u32,
+ _variant: &'static str,
+ _len: usize,
+ ) -> Result<Self::SerializeStructVariant, Self::Error> {
+ Err(ser::Error::custom("wrong type for with_prefix"))
+ }
+}
+
+impl<'a, S> SerializeMap for WithPrefix<'a, S>
+where
+ S: SerializeMap,
+{
+ type Ok = S::Ok;
+ type Error = S::Error;
+
+ fn serialize_key<T>(&mut self, key: &T) -> Result<(), Self::Error>
+ where
+ T: ?Sized + Serialize,
+ {
+ self.delegate.serialize_key(&WithPrefix {
+ delegate: key,
+ prefix: self.prefix,
+ })
+ }
+
+ fn serialize_value<T>(&mut self, value: &T) -> Result<(), Self::Error>
+ where
+ T: ?Sized + Serialize,
+ {
+ self.delegate.serialize_value(value)
+ }
+
+ fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<(), Self::Error>
+ where
+ K: ?Sized + Serialize,
+ V: ?Sized + Serialize,
+ {
+ self.delegate.serialize_entry(
+ &WithPrefix {
+ delegate: key,
+ prefix: self.prefix,
+ },
+ value,
+ )
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ self.delegate.end()
+ }
+}
+
+impl<'a, S> SerializeStruct for WithPrefix<'a, S>
+where
+ S: SerializeMap,
+{
+ type Ok = S::Ok;
+ type Error = S::Error;
+
+ fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<(), Self::Error>
+ where
+ T: ?Sized + Serialize,
+ {
+ let mut prefixed_key = String::with_capacity(self.prefix.len() + key.len());
+ prefixed_key.push_str(self.prefix);
+ prefixed_key.push_str(key);
+ self.delegate.serialize_entry(&prefixed_key, value)
+ }
+
+ fn end(self) -> Result<Self::Ok, Self::Error> {
+ self.delegate.end()
+ }
+}
+
+impl<'de, 'a, T> DeserializeSeed<'de> for WithPrefix<'a, T>
+where
+ T: DeserializeSeed<'de>,
+{
+ type Value = T::Value;
+
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ self.delegate.deserialize(WithPrefix {
+ delegate: deserializer,
+ prefix: self.prefix,
+ })
+ }
+}
+
+impl<'de, 'a, D> Deserializer<'de> for WithPrefix<'a, D>
+where
+ D: Deserializer<'de>,
+{
+ type Error = D::Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.delegate.deserialize_map(WithPrefix {
+ delegate: visitor,
+ prefix: self.prefix,
+ })
+ }
+
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.delegate.deserialize_any(WithPrefixOption {
+ first_key: None,
+ delegate: visitor,
+ prefix: self.prefix,
+ })
+ }
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.delegate.deserialize_identifier(WithPrefix {
+ delegate: visitor,
+ prefix: self.prefix,
+ })
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct
+ map struct enum ignored_any
+ }
+}
+
+impl<'de, 'a, V> Visitor<'de> for WithPrefix<'a, V>
+where
+ V: Visitor<'de>,
+{
+ type Value = V::Value;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.delegate.expecting(formatter)
+ }
+
+ fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ self.delegate.visit_map(WithPrefix {
+ delegate: map,
+ prefix: self.prefix,
+ })
+ }
+}
+
+impl<'de, 'a, A> MapAccess<'de> for WithPrefix<'a, A>
+where
+ A: MapAccess<'de>,
+{
+ type Error = A::Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
+ where
+ K: DeserializeSeed<'de>,
+ {
+ while let Some(s) = self.delegate.next_key::<String>()? {
+ if let Some(without_prefix) = s.strip_prefix(self.prefix) {
+ return seed
+ .deserialize(without_prefix.into_deserializer())
+ .map(Some);
+ }
+ self.delegate.next_value::<IgnoredAny>()?;
+ }
+ Ok(None)
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ self.delegate.next_value_seed(seed)
+ }
+}
+
+#[allow(missing_debug_implementations)]
+pub struct WithPrefixOption<'a, T> {
+ first_key: Option<String>,
+ delegate: T,
+ prefix: &'a str,
+}
+
+impl<'de, 'a, V> Visitor<'de> for WithPrefixOption<'a, V>
+where
+ V: Visitor<'de>,
+{
+ type Value = V::Value;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
+ self.delegate.expecting(formatter)
+ }
+
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: de::Error,
+ {
+ self.delegate.visit_none()
+ }
+
+ fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ while let Some(s) = map.next_key::<String>()? {
+ if s.starts_with(self.prefix) {
+ return self.delegate.visit_some(WithPrefixOption {
+ first_key: Some(s),
+ delegate: map,
+ prefix: self.prefix,
+ });
+ }
+ map.next_value::<IgnoredAny>()?;
+ }
+ self.delegate.visit_none()
+ }
+}
+
+impl<'de, 'a, A> Deserializer<'de> for WithPrefixOption<'a, A>
+where
+ A: MapAccess<'de>,
+{
+ type Error = A::Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_map(self)
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+impl<'de, 'a, A> MapAccess<'de> for WithPrefixOption<'a, A>
+where
+ A: MapAccess<'de>,
+{
+ type Error = A::Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error>
+ where
+ K: DeserializeSeed<'de>,
+ {
+ if let Some(s) = self.first_key.take() {
+ let without_prefix = s[self.prefix.len()..].into_deserializer();
+ return seed.deserialize(without_prefix).map(Some);
+ }
+ while let Some(s) = self.delegate.next_key::<String>()? {
+ if let Some(without_prefix) = s.strip_prefix(self.prefix) {
+ return seed
+ .deserialize(without_prefix.into_deserializer())
+ .map(Some);
+ }
+ self.delegate.next_value::<IgnoredAny>()?;
+ }
+ Ok(None)
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ self.delegate.next_value_seed(seed)
+ }
+}
diff --git a/third_party/rust/serde_with/tests/base64.rs b/third_party/rust/serde_with/tests/base64.rs
new file mode 100644
index 0000000000..5b84c0c6f0
--- /dev/null
+++ b/third_party/rust/serde_with/tests/base64.rs
@@ -0,0 +1,144 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+ // This allows the tests to be written more uniform and not have to special case the last clone().
+ clippy::redundant_clone,
+)]
+
+mod utils;
+
+use crate::utils::{check_deserialization, check_error_deserialization, is_equal};
+use expect_test::expect;
+use serde::{Deserialize, Serialize};
+use serde_with::{
+ base64::{Base64, Bcrypt, BinHex, Crypt, ImapMutf7, Standard, UrlSafe},
+ formats::{Padded, Unpadded},
+ serde_as,
+};
+
+#[test]
+fn base64_vec() {
+ let check_equal = vec![vec![0, 1, 2, 13], vec![14, 5, 6, 7]];
+ let check_deser = vec![vec![0xaa, 0xbc, 0xff], vec![0xe0, 0x7d], vec![0xe0, 0x7d]];
+ let check_deser_from = r#"["qrz/","4H0=","4H0"]"#;
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct BDefault(#[serde_as(as = "Vec<Base64>")] Vec<Vec<u8>>);
+
+ is_equal(
+ BDefault(check_equal.clone()),
+ expect![[r#"
+ [
+ "AAECDQ==",
+ "DgUGBw=="
+ ]"#]],
+ );
+
+ // Check mixed padding deserialization
+ check_deserialization(BDefault(check_deser.clone()), check_deser_from);
+
+ check_error_deserialization::<BDefault>(
+ r#"["0"]"#,
+ expect![[r#"Encoded text cannot have a 6-bit remainder. at line 1 column 5"#]],
+ );
+ check_error_deserialization::<BDefault>(
+ r#"["zz"]"#,
+ expect![[r#"Invalid last symbol 122, offset 1. at line 1 column 6"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct BPadded(#[serde_as(as = "Vec<Base64<Standard, Padded>>")] Vec<Vec<u8>>);
+
+ is_equal(
+ BPadded(check_equal.clone()),
+ expect![[r#"
+ [
+ "AAECDQ==",
+ "DgUGBw=="
+ ]"#]],
+ );
+ check_deserialization(BPadded(check_deser.clone()), check_deser_from);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct BUnpadded(#[serde_as(as = "Vec<Base64<Standard, Unpadded>>")] Vec<Vec<u8>>);
+
+ is_equal(
+ BUnpadded(check_equal.clone()),
+ expect![[r#"
+ [
+ "AAECDQ",
+ "DgUGBw"
+ ]"#]],
+ );
+ check_deserialization(BUnpadded(check_deser.clone()), check_deser_from);
+}
+
+#[test]
+fn base64_different_charsets() {
+ let bytes = [
+ 0x69_u8, 0xb7, 0x1d, 0x79, 0xf8, 0x21, 0x8a, 0x39, 0x25, 0x9a, 0x7a, 0x29, 0xaa, 0xbb,
+ 0x2d, 0xba, 0xfc, 0x31, 0xcb, 0x30, 0x01, 0x08, 0x31, 0x05, 0x18, 0x72, 0x09, 0x28, 0xb3,
+ 0x0d, 0x38, 0xf4, 0x11, 0x49, 0x35, 0x15, 0x59, 0x76, 0x19, 0xd3, 0x5d, 0xb7, 0xe3, 0x9e,
+ 0xbb, 0xf3, 0xdf, 0xbf, 0x00,
+ ];
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct B64Standard(#[serde_as(as = "Base64<Standard, Padded>")] Vec<u8>);
+
+ is_equal(
+ B64Standard(bytes.to_vec()),
+ expect![[r#""abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/AA==""#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct B64UrlSafe(#[serde_as(as = "Base64<UrlSafe, Padded>")] Vec<u8>);
+
+ is_equal(
+ B64UrlSafe(bytes.to_vec()),
+ expect![[r#""abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_AA==""#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct B64Crypt(#[serde_as(as = "Base64<Crypt, Padded>")] Vec<u8>);
+
+ is_equal(
+ B64Crypt(bytes.to_vec()),
+ expect![[r#""OPQRSTUVWXYZabcdefghijklmn./0123456789ABCDEFGHIJKLMNopqrstuvwxyz..==""#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct B64Bcrypt(#[serde_as(as = "Base64<Bcrypt, Padded>")] Vec<u8>);
+
+ is_equal(
+ B64Bcrypt(bytes.to_vec()),
+ expect![[r#""YZabcdefghijklmnopqrstuvwx./ABCDEFGHIJKLMNOPQRSTUVWXyz0123456789..==""#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct B64ImapMutf7(#[serde_as(as = "Base64<ImapMutf7, Padded>")] Vec<u8>);
+
+ is_equal(
+ B64ImapMutf7(bytes.to_vec()),
+ expect![[r#""abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+,AA==""#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct B64BinHex(#[serde_as(as = "Base64<BinHex, Padded>")] Vec<u8>);
+
+ is_equal(
+ B64BinHex(bytes.to_vec()),
+ expect![[r##""CDEFGHIJKLMNPQRSTUVXYZ[`ab!\"#$%&'()*+,-0123456789@ABcdehijklmpqr!!==""##]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/chrono.rs b/third_party/rust/serde_with/tests/chrono.rs
new file mode 100644
index 0000000000..4bcb778a89
--- /dev/null
+++ b/third_party/rust/serde_with/tests/chrono.rs
@@ -0,0 +1,740 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+
+extern crate alloc;
+
+mod utils;
+
+use crate::utils::{
+ check_deserialization, check_error_deserialization, check_serialization, is_equal,
+};
+use alloc::collections::BTreeMap;
+use chrono_crate::{DateTime, Duration, Local, NaiveDateTime, Utc};
+use core::{iter::FromIterator, str::FromStr};
+use expect_test::expect;
+use serde::{Deserialize, Serialize};
+use serde_with::{
+ formats::Flexible, serde_as, DurationMicroSeconds, DurationMicroSecondsWithFrac,
+ DurationMilliSeconds, DurationMilliSecondsWithFrac, DurationNanoSeconds,
+ DurationNanoSecondsWithFrac, DurationSeconds, DurationSecondsWithFrac, TimestampMicroSeconds,
+ TimestampMicroSecondsWithFrac, TimestampMilliSeconds, TimestampMilliSecondsWithFrac,
+ TimestampNanoSeconds, TimestampNanoSecondsWithFrac, TimestampSeconds, TimestampSecondsWithFrac,
+};
+
+fn new_datetime(secs: i64, nsecs: u32) -> DateTime<Utc> {
+ DateTime::from_utc(NaiveDateTime::from_timestamp(secs, nsecs), Utc)
+}
+
+#[test]
+fn json_datetime_from_any_to_string_deserialization() {
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct S(#[serde(with = "serde_with::chrono::datetime_utc_ts_seconds_from_any")] DateTime<Utc>);
+
+ // just integers
+ check_deserialization(
+ vec![
+ S(new_datetime(1_478_563_200, 0)),
+ S(new_datetime(0, 0)),
+ S(new_datetime(-86000, 0)),
+ ],
+ r#"[
+ 1478563200,
+ 0,
+ -86000
+ ]"#,
+ );
+
+ // floats, shows precision errors in subsecond part
+ check_deserialization(
+ vec![
+ S(new_datetime(1_478_563_200, 122_999_906)),
+ S(new_datetime(0, 0)),
+ S(new_datetime(-86000, 998_999_999)),
+ ],
+ r#"[
+ 1478563200.123,
+ 0.000,
+ -86000.999
+ ]"#,
+ );
+
+ // string representation of floats
+ check_deserialization(
+ vec![
+ S(new_datetime(1_478_563_200, 123_000_000)),
+ S(new_datetime(0, 0)),
+ S(new_datetime(-86000, 999_000_000)),
+ ],
+ r#"[
+ "1478563200.123",
+ "0.000",
+ "-86000.999"
+ ]"#,
+ );
+}
+
+#[test]
+fn test_chrono_naive_date_time() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct S(#[serde_as(as = "DateTime<Utc>")] NaiveDateTime);
+
+ is_equal(
+ S(NaiveDateTime::from_str("1994-11-05T08:15:30").unwrap()),
+ expect![[r#""1994-11-05T08:15:30Z""#]],
+ );
+}
+
+#[test]
+fn test_chrono_option_naive_date_time() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct S(#[serde_as(as = "Option<DateTime<Utc>>")] Option<NaiveDateTime>);
+
+ is_equal(
+ S(NaiveDateTime::from_str("1994-11-05T08:15:30").ok()),
+ expect![[r#""1994-11-05T08:15:30Z""#]],
+ );
+}
+
+#[test]
+fn test_chrono_vec_option_naive_date_time() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct S(#[serde_as(as = "Vec<Option<DateTime<Utc>>>")] Vec<Option<NaiveDateTime>>);
+
+ is_equal(
+ S(vec![
+ NaiveDateTime::from_str("1994-11-05T08:15:30").ok(),
+ NaiveDateTime::from_str("1994-11-05T08:15:31").ok(),
+ ]),
+ expect![[r#"
+ [
+ "1994-11-05T08:15:30Z",
+ "1994-11-05T08:15:31Z"
+ ]"#]],
+ );
+}
+
+#[test]
+fn test_chrono_btreemap_naive_date_time() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct S(#[serde_as(as = "BTreeMap<_, DateTime<Utc>>")] BTreeMap<i32, NaiveDateTime>);
+
+ is_equal(
+ S(BTreeMap::from_iter(vec![
+ (1, NaiveDateTime::from_str("1994-11-05T08:15:30").unwrap()),
+ (2, NaiveDateTime::from_str("1994-11-05T08:15:31").unwrap()),
+ ])),
+ expect![[r#"
+ {
+ "1": "1994-11-05T08:15:30Z",
+ "2": "1994-11-05T08:15:31Z"
+ }"#]],
+ );
+}
+
+#[test]
+fn test_chrono_duration_seconds() {
+ let zero = Duration::zero();
+ let one_second = Duration::seconds(1);
+ let half_second = Duration::nanoseconds(500_000_000);
+ let minus_one_second = zero - one_second;
+ let minus_half_second = zero - half_second;
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructIntStrict(#[serde_as(as = "DurationSeconds<i64>")] Duration);
+
+ is_equal(StructIntStrict(zero), expect![[r#"0"#]]);
+ is_equal(StructIntStrict(one_second), expect![[r#"1"#]]);
+ is_equal(StructIntStrict(minus_one_second), expect![[r#"-1"#]]);
+ check_serialization(StructIntStrict(half_second), expect![[r#"1"#]]);
+ check_serialization(StructIntStrict(minus_half_second), expect![[r#"-1"#]]);
+ check_error_deserialization::<StructIntStrict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected i64 at line 1 column 3"#]],
+ );
+ check_error_deserialization::<StructIntStrict>(
+ r#"9223372036854775808"#,
+ expect![[
+ r#"invalid value: integer `9223372036854775808`, expected i64 at line 1 column 19"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructIntFlexible(#[serde_as(as = "DurationSeconds<i64, Flexible>")] Duration);
+
+ is_equal(StructIntFlexible(zero), expect![[r#"0"#]]);
+ is_equal(StructIntFlexible(one_second), expect![[r#"1"#]]);
+ check_serialization(StructIntFlexible(half_second), expect![[r#"1"#]]);
+ check_serialization(StructIntFlexible(minus_half_second), expect![[r#"-1"#]]);
+ check_deserialization(StructIntFlexible(half_second), r#""0.5""#);
+ check_deserialization(StructIntFlexible(minus_half_second), r#""-0.5""#);
+ check_deserialization(StructIntFlexible(one_second), r#""1""#);
+ check_deserialization(StructIntFlexible(minus_one_second), r#""-1""#);
+ check_deserialization(StructIntFlexible(zero), r#""0""#);
+ check_error_deserialization::<StructIntFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Strict(#[serde_as(as = "DurationSeconds<f64>")] Duration);
+
+ is_equal(Structf64Strict(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Strict(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Strict(minus_one_second), expect![[r#"-1.0"#]]);
+ check_serialization(Structf64Strict(half_second), expect![[r#"1.0"#]]);
+ check_serialization(Structf64Strict(minus_half_second), expect![[r#"-1.0"#]]);
+ check_deserialization(Structf64Strict(one_second), r#"0.5"#);
+ check_deserialization(Structf64Strict(minus_one_second), r#"-0.5"#);
+ check_error_deserialization::<Structf64Strict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected f64 at line 1 column 3"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Flexible(#[serde_as(as = "DurationSeconds<f64, Flexible>")] Duration);
+
+ is_equal(Structf64Flexible(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Flexible(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Flexible(minus_one_second), expect![[r#"-1.0"#]]);
+ check_serialization(Structf64Flexible(half_second), expect![[r#"1.0"#]]);
+ check_serialization(Structf64Flexible(minus_half_second), expect![[r#"-1.0"#]]);
+ check_deserialization(Structf64Flexible(half_second), r#""0.5""#);
+ check_deserialization(Structf64Flexible(minus_half_second), r#""-0.5""#);
+ check_deserialization(Structf64Flexible(one_second), r#""1""#);
+ check_deserialization(Structf64Flexible(minus_one_second), r#""-1""#);
+ check_deserialization(Structf64Flexible(zero), r#""0""#);
+ check_error_deserialization::<Structf64Flexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringStrict(#[serde_as(as = "DurationSeconds<String>")] Duration);
+
+ is_equal(StructStringStrict(zero), expect![[r#""0""#]]);
+ is_equal(StructStringStrict(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringStrict(minus_one_second), expect![[r#""-1""#]]);
+ check_serialization(StructStringStrict(half_second), expect![[r#""1""#]]);
+ check_serialization(StructStringStrict(minus_half_second), expect![[r#""-1""#]]);
+ check_error_deserialization::<StructStringStrict>(
+ r#"1"#,
+ expect![[
+ r#"invalid type: integer `1`, expected a string containing a number at line 1 column 1"#
+ ]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"-1"#,
+ expect![[
+ r#"invalid type: integer `-1`, expected a string containing a number at line 1 column 2"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringFlexible(#[serde_as(as = "DurationSeconds<String, Flexible>")] Duration);
+
+ is_equal(StructStringFlexible(zero), expect![[r#""0""#]]);
+ is_equal(StructStringFlexible(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringFlexible(minus_one_second), expect![[r#""-1""#]]);
+ check_serialization(StructStringFlexible(half_second), expect![[r#""1""#]]);
+ check_deserialization(StructStringFlexible(half_second), r#""0.5""#);
+ check_deserialization(StructStringFlexible(one_second), r#""1""#);
+ check_deserialization(StructStringFlexible(zero), r#""0""#);
+ check_error_deserialization::<StructStringFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+}
+
+#[test]
+fn test_chrono_duration_seconds_with_frac() {
+ let zero = Duration::zero();
+ let one_second = Duration::seconds(1);
+ let half_second = Duration::nanoseconds(500_000_000);
+ let minus_one_second = zero - one_second;
+ let minus_half_second = zero - half_second;
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Strict(#[serde_as(as = "DurationSecondsWithFrac<f64>")] Duration);
+
+ is_equal(Structf64Strict(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Strict(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Strict(minus_one_second), expect![[r#"-1.0"#]]);
+ is_equal(Structf64Strict(half_second), expect![[r#"0.5"#]]);
+ is_equal(Structf64Strict(minus_half_second), expect![[r#"-0.5"#]]);
+ check_error_deserialization::<Structf64Strict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected f64 at line 1 column 3"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Flexible(#[serde_as(as = "DurationSecondsWithFrac<f64, Flexible>")] Duration);
+
+ is_equal(Structf64Flexible(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Flexible(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Flexible(minus_one_second), expect![[r#"-1.0"#]]);
+ is_equal(Structf64Flexible(minus_half_second), expect![[r#"-0.5"#]]);
+ check_deserialization(Structf64Flexible(one_second), r#""1""#);
+ check_deserialization(Structf64Flexible(minus_one_second), r#""-1""#);
+ check_deserialization(Structf64Flexible(half_second), r#""0.5""#);
+ check_deserialization(Structf64Flexible(zero), r#""0""#);
+ check_error_deserialization::<Structf64Flexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringStrict(#[serde_as(as = "DurationSecondsWithFrac<String>")] Duration);
+
+ is_equal(StructStringStrict(zero), expect![[r#""0""#]]);
+ is_equal(StructStringStrict(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringStrict(minus_one_second), expect![[r#""-1""#]]);
+ is_equal(StructStringStrict(half_second), expect![[r#""0.5""#]]);
+ is_equal(
+ StructStringStrict(minus_half_second),
+ expect![[r#""-0.5""#]],
+ );
+ is_equal(
+ StructStringStrict(minus_half_second),
+ expect![[r#""-0.5""#]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"1"#,
+ expect![[r#"invalid type: integer `1`, expected a string at line 1 column 1"#]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"-1"#,
+ expect![[r#"invalid type: integer `-1`, expected a string at line 1 column 2"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringFlexible(
+ #[serde_as(as = "DurationSecondsWithFrac<String, Flexible>")] Duration,
+ );
+
+ is_equal(StructStringFlexible(zero), expect![[r#""0""#]]);
+ is_equal(StructStringFlexible(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringFlexible(minus_one_second), expect![[r#""-1""#]]);
+ is_equal(StructStringFlexible(half_second), expect![[r#""0.5""#]]);
+ is_equal(
+ StructStringFlexible(minus_half_second),
+ expect![[r#""-0.5""#]],
+ );
+ check_deserialization(StructStringFlexible(one_second), r#""1""#);
+ check_deserialization(StructStringFlexible(zero), r#""0""#);
+ check_error_deserialization::<StructStringFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+}
+
+#[test]
+fn test_chrono_timestamp_seconds() {
+ let zero = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc);
+ let one_second = zero + Duration::seconds(1);
+ let half_second = zero + Duration::nanoseconds(500_000_000);
+ let minus_one_second = zero - Duration::seconds(1);
+ let minus_half_second = zero - Duration::nanoseconds(500_000_000);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructIntStrict(#[serde_as(as = "TimestampSeconds")] DateTime<Utc>);
+
+ is_equal(StructIntStrict(zero), expect![[r#"0"#]]);
+ is_equal(StructIntStrict(one_second), expect![[r#"1"#]]);
+ is_equal(StructIntStrict(minus_one_second), expect![[r#"-1"#]]);
+ check_serialization(StructIntStrict(half_second), expect![[r#"1"#]]);
+ check_serialization(StructIntStrict(minus_half_second), expect![[r#"-1"#]]);
+ check_error_deserialization::<StructIntStrict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected i64 at line 1 column 3"#]],
+ );
+ check_error_deserialization::<StructIntStrict>(
+ r#"0.123"#,
+ expect![[r#"invalid type: floating point `0.123`, expected i64 at line 1 column 5"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructIntFlexible(#[serde_as(as = "TimestampSeconds<i64, Flexible>")] DateTime<Utc>);
+
+ is_equal(StructIntFlexible(zero), expect![[r#"0"#]]);
+ is_equal(StructIntFlexible(one_second), expect![[r#"1"#]]);
+ is_equal(StructIntFlexible(minus_one_second), expect![[r#"-1"#]]);
+ check_serialization(StructIntFlexible(half_second), expect![[r#"1"#]]);
+ check_serialization(StructIntFlexible(minus_half_second), expect![[r#"-1"#]]);
+ check_deserialization(StructIntFlexible(one_second), r#""1""#);
+ check_deserialization(StructIntFlexible(one_second), r#"1.0"#);
+ check_deserialization(StructIntFlexible(minus_half_second), r#""-0.5""#);
+ check_deserialization(StructIntFlexible(half_second), r#"0.5"#);
+ check_error_deserialization::<StructIntFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Strict(#[serde_as(as = "TimestampSeconds<f64>")] DateTime<Utc>);
+
+ is_equal(Structf64Strict(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Strict(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Strict(minus_one_second), expect![[r#"-1.0"#]]);
+ check_serialization(Structf64Strict(half_second), expect![[r#"1.0"#]]);
+ check_serialization(Structf64Strict(minus_half_second), expect![[r#"-1.0"#]]);
+ check_deserialization(Structf64Strict(one_second), r#"0.5"#);
+ check_error_deserialization::<Structf64Strict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected f64 at line 1 column 3"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Flexible(#[serde_as(as = "TimestampSeconds<f64, Flexible>")] DateTime<Utc>);
+
+ is_equal(Structf64Flexible(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Flexible(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Flexible(minus_one_second), expect![[r#"-1.0"#]]);
+ check_serialization(Structf64Flexible(half_second), expect![[r#"1.0"#]]);
+ check_serialization(Structf64Flexible(minus_half_second), expect![[r#"-1.0"#]]);
+ check_deserialization(Structf64Flexible(one_second), r#""1""#);
+ check_deserialization(Structf64Flexible(one_second), r#"1.0"#);
+ check_deserialization(Structf64Flexible(minus_half_second), r#""-0.5""#);
+ check_deserialization(Structf64Flexible(half_second), r#"0.5"#);
+ check_error_deserialization::<Structf64Flexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringStrict(#[serde_as(as = "TimestampSeconds<String>")] DateTime<Utc>);
+
+ is_equal(StructStringStrict(zero), expect![[r#""0""#]]);
+ is_equal(StructStringStrict(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringStrict(minus_one_second), expect![[r#""-1""#]]);
+ check_serialization(StructStringStrict(half_second), expect![[r#""1""#]]);
+ check_serialization(StructStringStrict(minus_half_second), expect![[r#""-1""#]]);
+ check_deserialization(StructStringStrict(one_second), r#""1""#);
+ check_error_deserialization::<StructStringStrict>(
+ r#""0.5""#,
+ expect![[r#"invalid digit found in string at line 1 column 5"#]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#""-0.5""#,
+ expect![[r#"invalid digit found in string at line 1 column 6"#]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"1"#,
+ expect![[
+ r#"invalid type: integer `1`, expected a string containing a number at line 1 column 1"#
+ ]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"0.0"#,
+ expect![[
+ r#"invalid type: floating point `0`, expected a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringFlexible(
+ #[serde_as(as = "TimestampSeconds<String, Flexible>")] DateTime<Utc>,
+ );
+
+ is_equal(StructStringFlexible(zero), expect![[r#""0""#]]);
+ is_equal(StructStringFlexible(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringFlexible(minus_one_second), expect![[r#""-1""#]]);
+ check_serialization(StructStringFlexible(half_second), expect![[r#""1""#]]);
+ check_serialization(
+ StructStringFlexible(minus_half_second),
+ expect![[r#""-1""#]],
+ );
+ check_deserialization(StructStringFlexible(one_second), r#"1"#);
+ check_deserialization(StructStringFlexible(one_second), r#"1.0"#);
+ check_deserialization(StructStringFlexible(minus_half_second), r#""-0.5""#);
+ check_deserialization(StructStringFlexible(half_second), r#"0.5"#);
+ check_error_deserialization::<StructStringFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+}
+
+#[test]
+fn test_chrono_timestamp_seconds_with_frac() {
+ let zero = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc);
+ let one_second = zero + Duration::seconds(1);
+ let half_second = zero + Duration::nanoseconds(500_000_000);
+ let minus_one_second = zero - Duration::seconds(1);
+ let minus_half_second = zero - Duration::nanoseconds(500_000_000);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Strict(#[serde_as(as = "TimestampSecondsWithFrac<f64>")] DateTime<Utc>);
+
+ is_equal(Structf64Strict(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Strict(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Strict(minus_one_second), expect![[r#"-1.0"#]]);
+ is_equal(Structf64Strict(half_second), expect![[r#"0.5"#]]);
+ is_equal(Structf64Strict(minus_half_second), expect![[r#"-0.5"#]]);
+ check_error_deserialization::<Structf64Strict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected f64 at line 1 column 3"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Flexible(
+ #[serde_as(as = "TimestampSecondsWithFrac<f64, Flexible>")] DateTime<Utc>,
+ );
+
+ is_equal(Structf64Flexible(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Flexible(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Flexible(minus_one_second), expect![[r#"-1.0"#]]);
+ is_equal(Structf64Flexible(half_second), expect![[r#"0.5"#]]);
+ is_equal(Structf64Flexible(minus_half_second), expect![[r#"-0.5"#]]);
+ check_deserialization(Structf64Flexible(one_second), r#""1""#);
+ check_deserialization(Structf64Flexible(minus_half_second), r#""-0.5""#);
+ check_error_deserialization::<Structf64Flexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringStrict(#[serde_as(as = "TimestampSecondsWithFrac<String>")] DateTime<Utc>);
+
+ is_equal(StructStringStrict(zero), expect![[r#""0""#]]);
+ is_equal(StructStringStrict(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringStrict(minus_one_second), expect![[r#""-1""#]]);
+ is_equal(StructStringStrict(half_second), expect![[r#""0.5""#]]);
+ is_equal(
+ StructStringStrict(minus_half_second),
+ expect![[r#""-0.5""#]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"1"#,
+ expect![[r#"invalid type: integer `1`, expected a string at line 1 column 1"#]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"0.0"#,
+ expect![[r#"invalid type: floating point `0`, expected a string at line 1 column 3"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringFlexible(
+ #[serde_as(as = "TimestampSecondsWithFrac<String, Flexible>")] DateTime<Utc>,
+ );
+
+ is_equal(StructStringFlexible(zero), expect![[r#""0""#]]);
+ is_equal(StructStringFlexible(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringFlexible(minus_one_second), expect![[r#""-1""#]]);
+ is_equal(StructStringFlexible(half_second), expect![[r#""0.5""#]]);
+ is_equal(
+ StructStringFlexible(minus_half_second),
+ expect![[r#""-0.5""#]],
+ );
+ check_deserialization(StructStringFlexible(one_second), r#"1"#);
+ check_deserialization(StructStringFlexible(one_second), r#"1.0"#);
+ check_deserialization(StructStringFlexible(half_second), r#"0.5"#);
+ check_error_deserialization::<StructStringFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+}
+
+macro_rules! smoketest {
+ ($($valuety:ty, $adapter:literal, $value:expr, $expect:tt;)*) => {
+ $({
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = $adapter)] $valuety);
+ #[allow(unused_braces)]
+ is_equal(S($value), $expect);
+ })*
+ };
+}
+
+#[test]
+fn test_duration_smoketest() {
+ let zero = Duration::seconds(0);
+ let one_second = Duration::seconds(1);
+
+ smoketest! {
+ Duration, "DurationSeconds<i64>", one_second, {expect![[r#"1"#]]};
+ Duration, "DurationSeconds<f64>", one_second, {expect![[r#"1.0"#]]};
+ Duration, "DurationMilliSeconds<i64>", one_second, {expect![[r#"1000"#]]};
+ Duration, "DurationMilliSeconds<f64>", one_second, {expect![[r#"1000.0"#]]};
+ Duration, "DurationMicroSeconds<i64>", one_second, {expect![[r#"1000000"#]]};
+ Duration, "DurationMicroSeconds<f64>", one_second, {expect![[r#"1000000.0"#]]};
+ Duration, "DurationNanoSeconds<i64>", one_second, {expect![[r#"1000000000"#]]};
+ Duration, "DurationNanoSeconds<f64>", one_second, {expect![[r#"1000000000.0"#]]};
+ };
+
+ smoketest! {
+ Duration, "DurationSecondsWithFrac", one_second, {expect![[r#"1.0"#]]};
+ Duration, "DurationSecondsWithFrac<String>", one_second, {expect![[r#""1""#]]};
+ Duration, "DurationMilliSecondsWithFrac", one_second, {expect![[r#"1000.0"#]]};
+ Duration, "DurationMilliSecondsWithFrac<String>", one_second, {expect![[r#""1000""#]]};
+ Duration, "DurationMicroSecondsWithFrac", one_second, {expect![[r#"1000000.0"#]]};
+ Duration, "DurationMicroSecondsWithFrac<String>", one_second, {expect![[r#""1000000""#]]};
+ Duration, "DurationNanoSecondsWithFrac", one_second, {expect![[r#"1000000000.0"#]]};
+ Duration, "DurationNanoSecondsWithFrac<String>", one_second, {expect![[r#""1000000000""#]]};
+ };
+
+ smoketest! {
+ Duration, "DurationSecondsWithFrac", zero, {expect![[r#"0.0"#]]};
+ Duration, "DurationSecondsWithFrac", zero + Duration::nanoseconds(500_000_000), {expect![[r#"0.5"#]]};
+ Duration, "DurationSecondsWithFrac", zero + Duration::seconds(1), {expect![[r#"1.0"#]]};
+ Duration, "DurationSecondsWithFrac", zero - Duration::nanoseconds(500_000_000), {expect![[r#"-0.5"#]]};
+ Duration, "DurationSecondsWithFrac", zero - Duration::seconds(1), {expect![[r#"-1.0"#]]};
+ };
+}
+
+#[test]
+fn test_datetime_utc_smoketest() {
+ let zero = DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc);
+ let one_second = zero + Duration::seconds(1);
+
+ smoketest! {
+ DateTime<Utc>, "TimestampSeconds<i64>", one_second, {expect![[r#"1"#]]};
+ DateTime<Utc>, "TimestampSeconds<f64>", one_second, {expect![[r#"1.0"#]]};
+ DateTime<Utc>, "TimestampMilliSeconds<i64>", one_second, {expect![[r#"1000"#]]};
+ DateTime<Utc>, "TimestampMilliSeconds<f64>", one_second, {expect![[r#"1000.0"#]]};
+ DateTime<Utc>, "TimestampMicroSeconds<i64>", one_second, {expect![[r#"1000000"#]]};
+ DateTime<Utc>, "TimestampMicroSeconds<f64>", one_second, {expect![[r#"1000000.0"#]]};
+ DateTime<Utc>, "TimestampNanoSeconds<i64>", one_second, {expect![[r#"1000000000"#]]};
+ DateTime<Utc>, "TimestampNanoSeconds<f64>", one_second, {expect![[r#"1000000000.0"#]]};
+ };
+
+ smoketest! {
+ DateTime<Utc>, "TimestampSecondsWithFrac", one_second, {expect![[r#"1.0"#]]};
+ DateTime<Utc>, "TimestampSecondsWithFrac<String>", one_second, {expect![[r#""1""#]]};
+ DateTime<Utc>, "TimestampMilliSecondsWithFrac", one_second, {expect![[r#"1000.0"#]]};
+ DateTime<Utc>, "TimestampMilliSecondsWithFrac<String>", one_second, {expect![[r#""1000""#]]};
+ DateTime<Utc>, "TimestampMicroSecondsWithFrac", one_second, {expect![[r#"1000000.0"#]]};
+ DateTime<Utc>, "TimestampMicroSecondsWithFrac<String>", one_second, {expect![[r#""1000000""#]]};
+ DateTime<Utc>, "TimestampNanoSecondsWithFrac", one_second, {expect![[r#"1000000000.0"#]]};
+ DateTime<Utc>, "TimestampNanoSecondsWithFrac<String>", one_second, {expect![[r#""1000000000""#]]};
+ };
+
+ smoketest! {
+ DateTime<Utc>, "TimestampSecondsWithFrac", zero, {expect![[r#"0.0"#]]};
+ DateTime<Utc>, "TimestampSecondsWithFrac", zero + Duration::nanoseconds(500_000_000), {expect![[r#"0.5"#]]};
+ DateTime<Utc>, "TimestampSecondsWithFrac", zero + Duration::seconds(1), {expect![[r#"1.0"#]]};
+ DateTime<Utc>, "TimestampSecondsWithFrac", zero - Duration::nanoseconds(500_000_000), {expect![[r#"-0.5"#]]};
+ DateTime<Utc>, "TimestampSecondsWithFrac", zero - Duration::seconds(1), {expect![[r#"-1.0"#]]};
+ };
+}
+
+#[test]
+fn test_datetime_local_smoketest() {
+ let zero =
+ DateTime::<Utc>::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc).with_timezone(&Local);
+ let one_second = zero + Duration::seconds(1);
+
+ smoketest! {
+ DateTime<Local>, "TimestampSeconds<i64>", one_second, {expect![[r#"1"#]]};
+ DateTime<Local>, "TimestampSeconds<f64>", one_second, {expect![[r#"1.0"#]]};
+ DateTime<Local>, "TimestampMilliSeconds<i64>", one_second, {expect![[r#"1000"#]]};
+ DateTime<Local>, "TimestampMilliSeconds<f64>", one_second, {expect![[r#"1000.0"#]]};
+ DateTime<Local>, "TimestampMicroSeconds<i64>", one_second, {expect![[r#"1000000"#]]};
+ DateTime<Local>, "TimestampMicroSeconds<f64>", one_second, {expect![[r#"1000000.0"#]]};
+ DateTime<Local>, "TimestampNanoSeconds<i64>", one_second, {expect![[r#"1000000000"#]]};
+ DateTime<Local>, "TimestampNanoSeconds<f64>", one_second, {expect![[r#"1000000000.0"#]]};
+ };
+
+ smoketest! {
+ DateTime<Local>, "TimestampSecondsWithFrac", one_second, {expect![[r#"1.0"#]]};
+ DateTime<Local>, "TimestampSecondsWithFrac<String>", one_second, {expect![[r#""1""#]]};
+ DateTime<Local>, "TimestampMilliSecondsWithFrac", one_second, {expect![[r#"1000.0"#]]};
+ DateTime<Local>, "TimestampMilliSecondsWithFrac<String>", one_second, {expect![[r#""1000""#]]};
+ DateTime<Local>, "TimestampMicroSecondsWithFrac", one_second, {expect![[r#"1000000.0"#]]};
+ DateTime<Local>, "TimestampMicroSecondsWithFrac<String>", one_second, {expect![[r#""1000000""#]]};
+ DateTime<Local>, "TimestampNanoSecondsWithFrac", one_second, {expect![[r#"1000000000.0"#]]};
+ DateTime<Local>, "TimestampNanoSecondsWithFrac<String>", one_second, {expect![[r#""1000000000""#]]};
+ };
+
+ smoketest! {
+ DateTime<Local>, "TimestampSecondsWithFrac", zero, {expect![[r#"0.0"#]]};
+ DateTime<Local>, "TimestampSecondsWithFrac", zero + Duration::nanoseconds(500_000_000), {expect![[r#"0.5"#]]};
+ DateTime<Local>, "TimestampSecondsWithFrac", zero + Duration::seconds(1), {expect![[r#"1.0"#]]};
+ DateTime<Local>, "TimestampSecondsWithFrac", zero - Duration::nanoseconds(500_000_000), {expect![[r#"-0.5"#]]};
+ DateTime<Local>, "TimestampSecondsWithFrac", zero - Duration::seconds(1), {expect![[r#"-1.0"#]]};
+ };
+}
+
+#[test]
+fn test_naive_datetime_smoketest() {
+ let zero = NaiveDateTime::from_timestamp(0, 0);
+ let one_second = zero + Duration::seconds(1);
+
+ smoketest! {
+ NaiveDateTime, "TimestampSeconds<i64>", one_second, {expect![[r#"1"#]]};
+ NaiveDateTime, "TimestampSeconds<f64>", one_second, {expect![[r#"1.0"#]]};
+ NaiveDateTime, "TimestampMilliSeconds<i64>", one_second, {expect![[r#"1000"#]]};
+ NaiveDateTime, "TimestampMilliSeconds<f64>", one_second, {expect![[r#"1000.0"#]]};
+ NaiveDateTime, "TimestampMicroSeconds<i64>", one_second, {expect![[r#"1000000"#]]};
+ NaiveDateTime, "TimestampMicroSeconds<f64>", one_second, {expect![[r#"1000000.0"#]]};
+ NaiveDateTime, "TimestampNanoSeconds<i64>", one_second, {expect![[r#"1000000000"#]]};
+ NaiveDateTime, "TimestampNanoSeconds<f64>", one_second, {expect![[r#"1000000000.0"#]]};
+ };
+
+ smoketest! {
+ NaiveDateTime, "TimestampSecondsWithFrac", one_second, {expect![[r#"1.0"#]]};
+ NaiveDateTime, "TimestampSecondsWithFrac<String>", one_second, {expect![[r#""1""#]]};
+ NaiveDateTime, "TimestampMilliSecondsWithFrac", one_second, {expect![[r#"1000.0"#]]};
+ NaiveDateTime, "TimestampMilliSecondsWithFrac<String>", one_second, {expect![[r#""1000""#]]};
+ NaiveDateTime, "TimestampMicroSecondsWithFrac", one_second, {expect![[r#"1000000.0"#]]};
+ NaiveDateTime, "TimestampMicroSecondsWithFrac<String>", one_second, {expect![[r#""1000000""#]]};
+ NaiveDateTime, "TimestampNanoSecondsWithFrac", one_second, {expect![[r#"1000000000.0"#]]};
+ NaiveDateTime, "TimestampNanoSecondsWithFrac<String>", one_second, {expect![[r#""1000000000""#]]};
+ };
+
+ smoketest! {
+ NaiveDateTime, "TimestampSecondsWithFrac", zero, {expect![[r#"0.0"#]]};
+ NaiveDateTime, "TimestampSecondsWithFrac", zero + Duration::nanoseconds(500_000_000), {expect![[r#"0.5"#]]};
+ NaiveDateTime, "TimestampSecondsWithFrac", zero + Duration::seconds(1), {expect![[r#"1.0"#]]};
+ NaiveDateTime, "TimestampSecondsWithFrac", zero - Duration::nanoseconds(500_000_000), {expect![[r#"-0.5"#]]};
+ NaiveDateTime, "TimestampSecondsWithFrac", zero - Duration::seconds(1), {expect![[r#"-1.0"#]]};
+ };
+}
diff --git a/third_party/rust/serde_with/tests/derives/deserialize_fromstr.rs b/third_party/rust/serde_with/tests/derives/deserialize_fromstr.rs
new file mode 100644
index 0000000000..26d60bf08f
--- /dev/null
+++ b/third_party/rust/serde_with/tests/derives/deserialize_fromstr.rs
@@ -0,0 +1,96 @@
+use super::*;
+use core::{
+ num::ParseIntError,
+ str::{FromStr, ParseBoolError},
+};
+use pretty_assertions::assert_eq;
+use serde_with::DeserializeFromStr;
+
+#[derive(Debug, PartialEq, DeserializeFromStr)]
+struct A {
+ a: u32,
+ b: bool,
+}
+
+impl FromStr for A {
+ type Err = String;
+
+ /// Parse a value like `123<>true`
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ let mut parts = s.split("<>");
+ let number = parts
+ .next()
+ .ok_or_else(|| "Missing first value".to_string())?
+ .parse()
+ .map_err(|err: ParseIntError| err.to_string())?;
+ let bool = parts
+ .next()
+ .ok_or_else(|| "Missing second value".to_string())?
+ .parse()
+ .map_err(|err: ParseBoolError| err.to_string())?;
+ Ok(Self { a: number, b: bool })
+ }
+}
+
+#[test]
+fn test_deserialize_fromstr() {
+ check_deserialization(A { a: 159, b: true }, "\"159<>true\"");
+ check_deserialization(A { a: 999, b: false }, "\"999<>false\"");
+ check_deserialization(A { a: 0, b: true }, "\"0<>true\"");
+}
+
+#[test]
+fn test_deserialize_from_bytes() {
+ use serde::de::{value::Error, Deserialize, Deserializer, Visitor};
+
+ // Unfortunately serde_json is too clever (i.e. handles bytes gracefully)
+ // so instead create a custom deserializer which can only deserialize bytes.
+ // All other deserialize_* fns are forwarded to deserialize_bytes
+ struct ByteDeserializer(&'static [u8]);
+
+ impl<'de> Deserializer<'de> for ByteDeserializer {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_bytes(visitor)
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_bytes(self.0)
+ }
+
+ serde::forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+ }
+
+ // callstack: A::deserialize -> deserialize_str -> deserialize_any ->
+ // deserialize_bytes -> visit_bytes -> visit_str -> success!
+ let a = A::deserialize(ByteDeserializer(b"159<>true")).unwrap();
+
+ assert_eq!(A { a: 159, b: true }, a);
+}
+
+#[test]
+fn test_deserialize_fromstr_in_vec() {
+ check_deserialization(
+ vec![
+ A { a: 123, b: false },
+ A { a: 0, b: true },
+ A { a: 999, b: true },
+ ],
+ r#"[
+ "123<>false",
+ "0<>true",
+ "999<>true"
+ ]"#,
+ );
+}
diff --git a/third_party/rust/serde_with/tests/derives/lib.rs b/third_party/rust/serde_with/tests/derives/lib.rs
new file mode 100644
index 0000000000..a43a3c3535
--- /dev/null
+++ b/third_party/rust/serde_with/tests/derives/lib.rs
@@ -0,0 +1,15 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+
+mod deserialize_fromstr;
+mod serialize_display;
+#[path = "../utils.rs"]
+mod utils;
+
+use expect_test::expect;
+use utils::*;
diff --git a/third_party/rust/serde_with/tests/derives/serialize_display.rs b/third_party/rust/serde_with/tests/derives/serialize_display.rs
new file mode 100644
index 0000000000..e660fa7535
--- /dev/null
+++ b/third_party/rust/serde_with/tests/derives/serialize_display.rs
@@ -0,0 +1,39 @@
+use super::*;
+use core::fmt;
+use serde_with::SerializeDisplay;
+
+#[derive(Debug, SerializeDisplay)]
+struct A {
+ a: u32,
+ b: bool,
+}
+
+impl fmt::Display for A {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "->{} <> {}<-", self.a, self.b)
+ }
+}
+
+#[test]
+fn test_serialize_display() {
+ check_serialization(A { a: 123, b: false }, expect![[r#""->123 <> false<-""#]]);
+ check_serialization(A { a: 0, b: true }, expect![[r#""->0 <> true<-""#]]);
+ check_serialization(A { a: 999, b: true }, expect![[r#""->999 <> true<-""#]]);
+}
+
+#[test]
+fn test_serialize_display_in_vec() {
+ check_serialization(
+ vec![
+ A { a: 123, b: false },
+ A { a: 0, b: true },
+ A { a: 999, b: true },
+ ],
+ expect![[r#"
+ [
+ "->123 <> false<-",
+ "->0 <> true<-",
+ "->999 <> true<-"
+ ]"#]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/hex.rs b/third_party/rust/serde_with/tests/hex.rs
new file mode 100644
index 0000000000..2994ae475e
--- /dev/null
+++ b/third_party/rust/serde_with/tests/hex.rs
@@ -0,0 +1,93 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+
+mod utils;
+
+use crate::utils::{check_deserialization, check_error_deserialization, is_equal};
+use expect_test::expect;
+use serde::{Deserialize, Serialize};
+use serde_with::{
+ formats::{Lowercase, Uppercase},
+ hex::Hex,
+ serde_as,
+};
+
+#[test]
+fn hex_vec() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct B(#[serde_as(as = "Vec<Hex>")] Vec<Vec<u8>>);
+
+ is_equal(
+ B(vec![vec![0, 1, 2, 13], vec![14, 5, 6, 7]]),
+ expect![[r#"
+ [
+ "0001020d",
+ "0e050607"
+ ]"#]],
+ );
+
+ // Check mixed case deserialization
+ check_deserialization(
+ B(vec![vec![0xaa, 0xbc, 0xff], vec![0xe0, 0x7d]]),
+ r#"["aaBCff","E07d"]"#,
+ );
+
+ check_error_deserialization::<B>(
+ r#"["0"]"#,
+ expect![[r#"Odd number of digits at line 1 column 5"#]],
+ );
+ check_error_deserialization::<B>(
+ r#"["zz"]"#,
+ expect![[r#"Invalid character 'z' at position 0 at line 1 column 6"#]],
+ );
+}
+
+#[test]
+fn hex_vec_lowercase() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct B(#[serde_as(as = "Vec<Hex<Lowercase>>")] Vec<Vec<u8>>);
+
+ is_equal(
+ B(vec![vec![0, 1, 2, 13], vec![14, 5, 6, 7]]),
+ expect![[r#"
+ [
+ "0001020d",
+ "0e050607"
+ ]"#]],
+ );
+
+ // Check mixed case deserialization
+ check_deserialization(
+ B(vec![vec![0xaa, 0xbc, 0xff], vec![0xe0, 0x7d]]),
+ r#"["aaBCff","E07d"]"#,
+ );
+}
+
+#[test]
+fn hex_vec_uppercase() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ pub struct B(#[serde_as(as = "Vec<Hex<Uppercase>>")] Vec<Vec<u8>>);
+
+ is_equal(
+ B(vec![vec![0, 1, 2, 13], vec![14, 5, 6, 7]]),
+ expect![[r#"
+ [
+ "0001020D",
+ "0E050607"
+ ]"#]],
+ );
+
+ // Check mixed case deserialization
+ check_deserialization(
+ B(vec![vec![0xaa, 0xbc, 0xff], vec![0xe0, 0x7d]]),
+ r#"["aaBCff","E07d"]"#,
+ );
+}
diff --git a/third_party/rust/serde_with/tests/indexmap.rs b/third_party/rust/serde_with/tests/indexmap.rs
new file mode 100644
index 0000000000..7e46b9c5c5
--- /dev/null
+++ b/third_party/rust/serde_with/tests/indexmap.rs
@@ -0,0 +1,285 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+
+mod utils;
+
+use crate::utils::{check_deserialization, check_error_deserialization, is_equal};
+use core::iter::FromIterator;
+use expect_test::expect;
+use indexmap_crate::{IndexMap, IndexSet};
+use serde::{Deserialize, Serialize};
+use serde_with::{serde_as, DisplayFromStr, Same};
+use std::net::IpAddr;
+
+#[test]
+fn test_indexmap() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "IndexMap<DisplayFromStr, DisplayFromStr>")] IndexMap<u8, u32>);
+
+ // Normal
+ is_equal(
+ S([(1, 1), (3, 3), (111, 111)].iter().cloned().collect()),
+ expect![[r#"
+ {
+ "1": "1",
+ "3": "3",
+ "111": "111"
+ }"#]],
+ );
+ is_equal(S(IndexMap::default()), expect![[r#"{}"#]]);
+}
+
+#[test]
+fn test_indexset() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "IndexSet<DisplayFromStr>")] IndexSet<u32>);
+
+ // Normal
+ is_equal(
+ S([1, 2, 3, 4, 5].iter().cloned().collect()),
+ expect![[r#"
+ [
+ "1",
+ "2",
+ "3",
+ "4",
+ "5"
+ ]"#]],
+ );
+ is_equal(S(IndexSet::default()), expect![[r#"[]"#]]);
+}
+
+#[test]
+fn test_map_as_tuple_list() {
+ let ip = "1.2.3.4".parse().unwrap();
+ let ip2 = "255.255.255.255".parse().unwrap();
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SI(#[serde_as(as = "Vec<(DisplayFromStr, DisplayFromStr)>")] IndexMap<u32, IpAddr>);
+
+ let map: IndexMap<_, _> = vec![(1, ip), (10, ip), (200, ip2)].into_iter().collect();
+ is_equal(
+ SI(map.clone()),
+ expect![[r#"
+ [
+ [
+ "1",
+ "1.2.3.4"
+ ],
+ [
+ "10",
+ "1.2.3.4"
+ ],
+ [
+ "200",
+ "255.255.255.255"
+ ]
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SI2(#[serde_as(as = "Vec<(Same, DisplayFromStr)>")] IndexMap<u32, IpAddr>);
+
+ is_equal(
+ SI2(map),
+ expect![[r#"
+ [
+ [
+ 1,
+ "1.2.3.4"
+ ],
+ [
+ 10,
+ "1.2.3.4"
+ ],
+ [
+ 200,
+ "255.255.255.255"
+ ]
+ ]"#]],
+ );
+}
+
+#[test]
+fn test_tuple_list_as_map() {
+ let ip = "1.2.3.4".parse().unwrap();
+ let ip2 = "255.255.255.255".parse().unwrap();
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SI(
+ #[serde_as(as = "std::collections::HashMap<DisplayFromStr, DisplayFromStr>")]
+ IndexSet<(u32, IpAddr)>,
+ );
+
+ is_equal(
+ SI(IndexSet::from_iter(vec![(1, ip), (10, ip), (200, ip2)])),
+ expect![[r#"
+ {
+ "1": "1.2.3.4",
+ "10": "1.2.3.4",
+ "200": "255.255.255.255"
+ }"#]],
+ );
+}
+
+#[test]
+fn duplicate_key_first_wins_indexmap() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::maps_first_key_wins")] IndexMap<usize, usize>);
+
+ // Different value and key always works
+ is_equal(
+ S(IndexMap::from_iter(vec![(1, 1), (2, 2), (3, 3)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 2,
+ "3": 3
+ }"#]],
+ );
+
+ // Same value for different keys is ok
+ is_equal(
+ S(IndexMap::from_iter(vec![(1, 1), (2, 1), (3, 1)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 1,
+ "3": 1
+ }"#]],
+ );
+
+ // Duplicate keys, the first one is used
+ check_deserialization(
+ S(IndexMap::from_iter(vec![(1, 1), (2, 2)])),
+ r#"{"1": 1, "2": 2, "1": 3}"#,
+ );
+}
+
+#[test]
+fn prohibit_duplicate_key_indexmap() {
+ #[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
+ struct S(
+ #[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")] IndexMap<usize, usize>,
+ );
+
+ // Different value and key always works
+ is_equal(
+ S(IndexMap::from_iter(vec![(1, 1), (2, 2), (3, 3)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 2,
+ "3": 3
+ }"#]],
+ );
+
+ // Same value for different keys is ok
+ is_equal(
+ S(IndexMap::from_iter(vec![(1, 1), (2, 1), (3, 1)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 1,
+ "3": 1
+ }"#]],
+ );
+
+ // Duplicate keys are an error
+ check_error_deserialization::<S>(
+ r#"{"1": 1, "2": 2, "1": 3}"#,
+ expect![[r#"invalid entry: found duplicate key at line 1 column 24"#]],
+ );
+}
+
+#[test]
+fn duplicate_value_last_wins_indexset() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::sets_last_value_wins")] IndexSet<W>);
+
+ #[derive(Debug, Eq, Deserialize, Serialize)]
+ struct W(i32, bool);
+ impl PartialEq for W {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+ }
+ impl std::hash::Hash for W {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: std::hash::Hasher,
+ {
+ self.0.hash(state)
+ }
+ }
+
+ // Different values always work
+ is_equal(
+ S(IndexSet::from_iter(vec![
+ W(1, true),
+ W(2, false),
+ W(3, true),
+ ])),
+ expect![[r#"
+ [
+ [
+ 1,
+ true
+ ],
+ [
+ 2,
+ false
+ ],
+ [
+ 3,
+ true
+ ]
+ ]"#]],
+ );
+
+ let value: S = serde_json::from_str(
+ r#"[
+ [1, false],
+ [1, true],
+ [2, true],
+ [2, false]
+ ]"#,
+ )
+ .unwrap();
+ let entries: Vec<_> = value.0.into_iter().collect();
+ assert_eq!(1, entries[0].0);
+ assert!(entries[0].1);
+ assert_eq!(2, entries[1].0);
+ assert!(!entries[1].1);
+}
+
+#[test]
+fn prohibit_duplicate_value_indexset() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::sets_duplicate_value_is_error")] IndexSet<usize>);
+
+ is_equal(
+ S(IndexSet::from_iter(vec![1, 2, 3, 4])),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3,
+ 4
+ ]"#]],
+ );
+ check_error_deserialization::<S>(
+ r#"[1, 2, 3, 4, 1]"#,
+ expect![[r#"invalid entry: found duplicate value at line 1 column 15"#]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/json.rs b/third_party/rust/serde_with/tests/json.rs
new file mode 100644
index 0000000000..53c0baa146
--- /dev/null
+++ b/third_party/rust/serde_with/tests/json.rs
@@ -0,0 +1,41 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+
+mod utils;
+
+use crate::utils::is_equal;
+use expect_test::expect;
+use serde::{Deserialize, Serialize};
+use serde_with::{json::JsonString, serde_as, DisplayFromStr};
+
+#[test]
+fn test_nested_json() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Struct {
+ #[serde_as(as = "JsonString")]
+ value: Nested,
+ }
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Nested {
+ #[serde_as(as = "DisplayFromStr")]
+ value: u32,
+ }
+
+ is_equal(
+ Struct {
+ value: Nested { value: 444 },
+ },
+ expect![[r#"
+ {
+ "value": "{\"value\":\"444\"}"
+ }"#]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/rust.rs b/third_party/rust/serde_with/tests/rust.rs
new file mode 100644
index 0000000000..14accdb157
--- /dev/null
+++ b/third_party/rust/serde_with/tests/rust.rs
@@ -0,0 +1,676 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+
+extern crate alloc;
+
+mod utils;
+
+use crate::utils::{check_deserialization, check_error_deserialization, is_equal};
+use alloc::collections::{BTreeMap, BTreeSet, LinkedList, VecDeque};
+use core::{cmp, iter::FromIterator as _};
+use expect_test::expect;
+use fnv::{FnvHashMap as HashMap, FnvHashSet as HashSet};
+use pretty_assertions::assert_eq;
+use serde::{de::DeserializeOwned, Deserialize, Serialize};
+use serde_with::CommaSeparator;
+
+#[test]
+fn string_collection() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(
+ #[serde(with = "serde_with::rust::StringWithSeparator::<CommaSeparator>")] Vec<String>,
+ );
+
+ is_equal(S(vec![]), expect![[r#""""#]]);
+ is_equal(
+ S(vec![
+ "A".to_string(),
+ "B".to_string(),
+ "c".to_string(),
+ "D".to_string(),
+ ]),
+ expect![[r#""A,B,c,D""#]],
+ );
+ is_equal(
+ S(vec!["".to_string(), "".to_string(), "".to_string()]),
+ expect![[r#"",,""#]],
+ );
+ is_equal(
+ S(vec!["AVeryLongString".to_string()]),
+ expect![[r#""AVeryLongString""#]],
+ );
+}
+
+#[test]
+fn prohibit_duplicate_value_hashset() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::sets_duplicate_value_is_error")] HashSet<usize>);
+
+ is_equal(
+ S(HashSet::from_iter(vec![1, 2, 3, 4])),
+ expect![[r#"
+ [
+ 4,
+ 1,
+ 3,
+ 2
+ ]"#]],
+ );
+ check_error_deserialization::<S>(
+ r#"[1, 2, 3, 4, 1]"#,
+ expect![[r#"invalid entry: found duplicate value at line 1 column 15"#]],
+ );
+}
+
+#[test]
+fn prohibit_duplicate_value_btreeset() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::sets_duplicate_value_is_error")] BTreeSet<usize>);
+
+ is_equal(
+ S(BTreeSet::from_iter(vec![1, 2, 3, 4])),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3,
+ 4
+ ]"#]],
+ );
+ check_error_deserialization::<S>(
+ r#"[1, 2, 3, 4, 1]"#,
+ expect![[r#"invalid entry: found duplicate value at line 1 column 15"#]],
+ );
+}
+
+#[test]
+fn prohibit_duplicate_key_hashmap() {
+ #[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
+ struct S(
+ #[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")] HashMap<usize, usize>,
+ );
+
+ // Different value and key always works
+ is_equal(
+ S(HashMap::from_iter(vec![(1, 1), (2, 2), (3, 3)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "3": 3,
+ "2": 2
+ }"#]],
+ );
+
+ // Same value for different keys is ok
+ is_equal(
+ S(HashMap::from_iter(vec![(1, 1), (2, 1), (3, 1)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "3": 1,
+ "2": 1
+ }"#]],
+ );
+
+ // Duplicate keys are an error
+ check_error_deserialization::<S>(
+ r#"{"1": 1, "2": 2, "1": 3}"#,
+ expect![[r#"invalid entry: found duplicate key at line 1 column 24"#]],
+ );
+}
+
+#[test]
+fn prohibit_duplicate_key_btreemap() {
+ #[derive(Debug, Eq, PartialEq, Deserialize, Serialize)]
+ struct S(
+ #[serde(with = "::serde_with::rust::maps_duplicate_key_is_error")] BTreeMap<usize, usize>,
+ );
+
+ // Different value and key always works
+ is_equal(
+ S(BTreeMap::from_iter(vec![(1, 1), (2, 2), (3, 3)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 2,
+ "3": 3
+ }"#]],
+ );
+
+ // Same value for different keys is ok
+ is_equal(
+ S(BTreeMap::from_iter(vec![(1, 1), (2, 1), (3, 1)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 1,
+ "3": 1
+ }"#]],
+ );
+
+ // Duplicate keys are an error
+ check_error_deserialization::<S>(
+ r#"{"1": 1, "2": 2, "1": 3}"#,
+ expect![[r#"invalid entry: found duplicate key at line 1 column 24"#]],
+ );
+}
+
+#[test]
+fn duplicate_key_first_wins_hashmap() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::maps_first_key_wins")] HashMap<usize, usize>);
+
+ // Different value and key always works
+ is_equal(
+ S(HashMap::from_iter(vec![(1, 1), (2, 2), (3, 3)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "3": 3,
+ "2": 2
+ }"#]],
+ );
+
+ // Same value for different keys is ok
+ is_equal(
+ S(HashMap::from_iter(vec![(1, 1), (2, 1), (3, 1)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "3": 1,
+ "2": 1
+ }"#]],
+ );
+
+ // Duplicate keys, the first one is used
+ check_deserialization(
+ S(HashMap::from_iter(vec![(1, 1), (2, 2)])),
+ r#"{"1": 1, "2": 2, "1": 3}"#,
+ );
+}
+
+#[test]
+fn duplicate_key_first_wins_btreemap() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::maps_first_key_wins")] BTreeMap<usize, usize>);
+
+ // Different value and key always works
+ is_equal(
+ S(BTreeMap::from_iter(vec![(1, 1), (2, 2), (3, 3)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 2,
+ "3": 3
+ }"#]],
+ );
+
+ // Same value for different keys is ok
+ is_equal(
+ S(BTreeMap::from_iter(vec![(1, 1), (2, 1), (3, 1)])),
+ expect![[r#"
+ {
+ "1": 1,
+ "2": 1,
+ "3": 1
+ }"#]],
+ );
+
+ // Duplicate keys, the first one is used
+ check_deserialization(
+ S(BTreeMap::from_iter(vec![(1, 1), (2, 2)])),
+ r#"{"1": 1, "2": 2, "1": 3}"#,
+ );
+}
+
+#[test]
+fn duplicate_value_first_wins_hashset() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(HashSet<W>);
+ // struct S(#[serde(with = "::serde_with::rust::sets_first_value_wins")] HashSet<W>);
+
+ #[derive(Debug, Eq, Deserialize, Serialize)]
+ struct W(i32, bool);
+ impl PartialEq for W {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+ }
+ impl std::hash::Hash for W {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: std::hash::Hasher,
+ {
+ self.0.hash(state)
+ }
+ }
+
+ // Different values always work
+ is_equal(
+ S(HashSet::from_iter(vec![
+ W(1, true),
+ W(2, false),
+ W(3, true),
+ ])),
+ expect![[r#"
+ [
+ [
+ 1,
+ true
+ ],
+ [
+ 3,
+ true
+ ],
+ [
+ 2,
+ false
+ ]
+ ]"#]],
+ );
+
+ let value: S = serde_json::from_str(
+ r#"[
+ [1, false],
+ [1, true],
+ [2, true],
+ [2, false]
+ ]"#,
+ )
+ .unwrap();
+ let entries: Vec<_> = value.0.into_iter().collect();
+ assert_eq!(1, entries[0].0);
+ assert!(!entries[0].1);
+ assert_eq!(2, entries[1].0);
+ assert!(entries[1].1);
+}
+
+#[test]
+fn duplicate_value_last_wins_hashset() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::sets_last_value_wins")] HashSet<W>);
+
+ #[derive(Debug, Eq, Deserialize, Serialize)]
+ struct W(i32, bool);
+ impl PartialEq for W {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+ }
+ impl std::hash::Hash for W {
+ fn hash<H>(&self, state: &mut H)
+ where
+ H: std::hash::Hasher,
+ {
+ self.0.hash(state)
+ }
+ }
+
+ // Different values always work
+ is_equal(
+ S(HashSet::from_iter(vec![
+ W(1, true),
+ W(2, false),
+ W(3, true),
+ ])),
+ expect![[r#"
+ [
+ [
+ 1,
+ true
+ ],
+ [
+ 3,
+ true
+ ],
+ [
+ 2,
+ false
+ ]
+ ]"#]],
+ );
+
+ let value: S = serde_json::from_str(
+ r#"[
+ [1, false],
+ [1, true],
+ [2, true],
+ [2, false]
+ ]"#,
+ )
+ .unwrap();
+ let entries: Vec<_> = value.0.into_iter().collect();
+ assert_eq!(1, entries[0].0);
+ assert!(entries[0].1);
+ assert_eq!(2, entries[1].0);
+ assert!(!entries[1].1);
+}
+
+#[test]
+fn duplicate_value_last_wins_btreeset() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "::serde_with::rust::sets_last_value_wins")] BTreeSet<W>);
+ #[derive(Debug, Eq, Deserialize, Serialize)]
+ struct W(i32, bool);
+ impl PartialEq for W {
+ fn eq(&self, other: &Self) -> bool {
+ self.0 == other.0
+ }
+ }
+ impl Ord for W {
+ fn cmp(&self, other: &Self) -> cmp::Ordering {
+ self.0.cmp(&other.0)
+ }
+ }
+ impl PartialOrd for W {
+ fn partial_cmp(&self, other: &Self) -> Option<cmp::Ordering> {
+ Some(self.cmp(other))
+ }
+ }
+
+ // Different values always work
+ is_equal(
+ S(BTreeSet::from_iter(vec![
+ W(1, true),
+ W(2, false),
+ W(3, true),
+ ])),
+ expect![[r#"
+ [
+ [
+ 1,
+ true
+ ],
+ [
+ 2,
+ false
+ ],
+ [
+ 3,
+ true
+ ]
+ ]"#]],
+ );
+
+ let value: S = serde_json::from_str(
+ r#"[
+ [1, false],
+ [1, true],
+ [2, true],
+ [2, false]
+ ]"#,
+ )
+ .unwrap();
+ let entries: Vec<_> = value.0.into_iter().collect();
+ assert_eq!(1, entries[0].0);
+ assert!(entries[0].1);
+ assert_eq!(2, entries[1].0);
+ assert!(!entries[1].1);
+}
+
+#[test]
+fn test_map_as_tuple_list() {
+ #[derive(Debug, Deserialize, Serialize, PartialEq)]
+ struct Hash(#[serde(with = "serde_with::rust::map_as_tuple_list")] HashMap<String, u8>);
+
+ is_equal(
+ Hash(HashMap::from_iter(vec![
+ ("ABC".to_string(), 1),
+ ("Hello".to_string(), 0),
+ ("World".to_string(), 20),
+ ])),
+ expect![[r#"
+ [
+ [
+ "ABC",
+ 1
+ ],
+ [
+ "Hello",
+ 0
+ ],
+ [
+ "World",
+ 20
+ ]
+ ]"#]],
+ );
+ is_equal(
+ Hash(HashMap::from_iter(vec![("Hello".to_string(), 0)])),
+ expect![[r#"
+ [
+ [
+ "Hello",
+ 0
+ ]
+ ]"#]],
+ );
+ is_equal(Hash(HashMap::default()), expect![[r#"[]"#]]);
+
+ // Test parse error, only single element instead of tuple
+ check_error_deserialization::<Hash>(
+ r#"[ [1] ]"#,
+ expect![[r#"invalid type: integer `1`, expected a string at line 1 column 4"#]],
+ );
+
+ #[derive(Debug, Deserialize, Serialize, PartialEq)]
+ struct BTree(#[serde(with = "serde_with::rust::map_as_tuple_list")] BTreeMap<String, u8>);
+
+ is_equal(
+ BTree(BTreeMap::from_iter(vec![
+ ("ABC".to_string(), 1),
+ ("Hello".to_string(), 0),
+ ("World".to_string(), 20),
+ ])),
+ expect![[r#"
+ [
+ [
+ "ABC",
+ 1
+ ],
+ [
+ "Hello",
+ 0
+ ],
+ [
+ "World",
+ 20
+ ]
+ ]"#]],
+ );
+ is_equal(
+ BTree(BTreeMap::from_iter(vec![("Hello".to_string(), 0)])),
+ expect![[r#"
+ [
+ [
+ "Hello",
+ 0
+ ]
+ ]"#]],
+ );
+ is_equal(BTree(BTreeMap::default()), expect![[r#"[]"#]]);
+
+ // Test parse error, only single element instead of tuple
+ check_error_deserialization::<BTree>(
+ r#"[ [1] ]"#,
+ expect![[r#"invalid type: integer `1`, expected a string at line 1 column 4"#]],
+ );
+}
+
+#[test]
+fn tuple_list_as_map_vec() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(
+ #[serde(with = "serde_with::rust::tuple_list_as_map")] Vec<(Wrapper<i32>, Wrapper<String>)>,
+ );
+ #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+ #[serde(transparent)]
+ struct Wrapper<T>(T);
+
+ is_equal(
+ S(vec![
+ (Wrapper(1), Wrapper("Hi".into())),
+ (Wrapper(2), Wrapper("Cake".into())),
+ (Wrapper(99), Wrapper("Lie".into())),
+ ]),
+ expect![[r#"
+ {
+ "1": "Hi",
+ "2": "Cake",
+ "99": "Lie"
+ }"#]],
+ );
+ is_equal(S(Vec::new()), expect![[r#"{}"#]]);
+ check_error_deserialization::<S>(
+ r#"[]"#,
+ expect![[r#"invalid type: sequence, expected a map at line 1 column 0"#]],
+ );
+ check_error_deserialization::<S>(
+ r#"null"#,
+ expect![[r#"invalid type: null, expected a map at line 1 column 4"#]],
+ );
+}
+
+#[test]
+fn tuple_list_as_map_linkedlist() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(
+ #[serde(with = "serde_with::rust::tuple_list_as_map")]
+ LinkedList<(Wrapper<i32>, Wrapper<String>)>,
+ );
+ #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+ #[serde(transparent)]
+ struct Wrapper<T>(T);
+
+ is_equal(
+ S(LinkedList::from_iter(vec![
+ (Wrapper(1), Wrapper("Hi".into())),
+ (Wrapper(2), Wrapper("Cake".into())),
+ (Wrapper(99), Wrapper("Lie".into())),
+ ])),
+ expect![[r#"
+ {
+ "1": "Hi",
+ "2": "Cake",
+ "99": "Lie"
+ }"#]],
+ );
+ is_equal(S(LinkedList::new()), expect![[r#"{}"#]]);
+ check_error_deserialization::<S>(
+ r#"[]"#,
+ expect![[r#"invalid type: sequence, expected a map at line 1 column 0"#]],
+ );
+ check_error_deserialization::<S>(
+ r#"null"#,
+ expect![[r#"invalid type: null, expected a map at line 1 column 4"#]],
+ );
+}
+
+#[test]
+fn tuple_list_as_map_vecdeque() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(
+ #[serde(with = "serde_with::rust::tuple_list_as_map")]
+ VecDeque<(Wrapper<i32>, Wrapper<String>)>,
+ );
+ #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
+ #[serde(transparent)]
+ struct Wrapper<T>(T);
+
+ is_equal(
+ S(VecDeque::from_iter(vec![
+ (Wrapper(1), Wrapper("Hi".into())),
+ (Wrapper(2), Wrapper("Cake".into())),
+ (Wrapper(99), Wrapper("Lie".into())),
+ ])),
+ expect![[r#"
+ {
+ "1": "Hi",
+ "2": "Cake",
+ "99": "Lie"
+ }"#]],
+ );
+ is_equal(S(VecDeque::new()), expect![[r#"{}"#]]);
+ check_error_deserialization::<S>(
+ r#"[]"#,
+ expect![[r#"invalid type: sequence, expected a map at line 1 column 0"#]],
+ );
+ check_error_deserialization::<S>(
+ r#"null"#,
+ expect![[r#"invalid type: null, expected a map at line 1 column 4"#]],
+ );
+}
+
+#[test]
+fn test_string_empty_as_none() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde(with = "serde_with::rust::string_empty_as_none")] Option<String>);
+
+ is_equal(S(Some("str".to_string())), expect![[r#""str""#]]);
+ check_deserialization(S(None), r#""""#);
+ check_deserialization(S(None), r#"null"#);
+}
+
+#[test]
+fn test_default_on_error() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S<T>(#[serde(with = "serde_with::rust::default_on_error")] T)
+ where
+ T: Default + Serialize + DeserializeOwned;
+
+ is_equal(S(123), expect![[r#"123"#]]);
+ is_equal(S("Hello World".to_string()), expect![[r#""Hello World""#]]);
+ is_equal(
+ S(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3
+ ]"#]],
+ );
+
+ check_deserialization(S(0), r#"{}"#);
+ check_deserialization(S(0), r#"[]"#);
+ check_deserialization(S(0), r#"null"#);
+ check_deserialization(S(0), r#""A""#);
+
+ check_deserialization(S("".to_string()), r#"{}"#);
+ check_deserialization(S("".to_string()), r#"[]"#);
+ check_deserialization(S("".to_string()), r#"null"#);
+ check_deserialization(S("".to_string()), r#"0"#);
+
+ check_deserialization(S::<Vec<i32>>(vec![]), r#"{}"#);
+ check_deserialization(S::<Vec<i32>>(vec![]), r#"null"#);
+ check_deserialization(S::<Vec<i32>>(vec![]), r#"0"#);
+ check_deserialization(S::<Vec<i32>>(vec![]), r#""A""#);
+}
+
+#[test]
+fn test_default_on_null() {
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S<T>(#[serde(with = "serde_with::rust::default_on_null")] T)
+ where
+ T: Default + Serialize + DeserializeOwned;
+
+ is_equal(S(123), expect![[r#"123"#]]);
+ is_equal(S("Hello World".to_string()), expect![[r#""Hello World""#]]);
+ is_equal(
+ S(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3
+ ]"#]],
+ );
+
+ check_deserialization(S(0), r#"null"#);
+ check_deserialization(S("".to_string()), r#"null"#);
+ check_deserialization(S::<Vec<i32>>(vec![]), r#"null"#);
+}
diff --git a/third_party/rust/serde_with/tests/serde_as/collections.rs b/third_party/rust/serde_with/tests/serde_as/collections.rs
new file mode 100644
index 0000000000..dad84c4978
--- /dev/null
+++ b/third_party/rust/serde_with/tests/serde_as/collections.rs
@@ -0,0 +1,44 @@
+use super::*;
+use fnv::{FnvHashMap, FnvHashSet};
+
+/// Test that HashSets are also supported with non-default hashers.
+#[test]
+fn test_fnv_hashset() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "FnvHashSet<DisplayFromStr>")] FnvHashSet<u32>);
+
+ // Normal
+ is_equal(
+ S([1, 2, 3, 4, 5].iter().cloned().collect()),
+ expect![[r#"
+ [
+ "5",
+ "4",
+ "1",
+ "3",
+ "2"
+ ]"#]],
+ );
+ is_equal(S(FnvHashSet::default()), expect![[r#"[]"#]]);
+}
+
+/// Test that HashSets are also supported with non-default hashers.
+#[test]
+fn test_fnv_hashmap() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "FnvHashMap<DisplayFromStr, DisplayFromStr>")] FnvHashMap<u8, u32>);
+
+ // Normal
+ is_equal(
+ S([(1, 1), (3, 3), (111, 111)].iter().cloned().collect()),
+ expect![[r#"
+ {
+ "1": "1",
+ "3": "3",
+ "111": "111"
+ }"#]],
+ );
+ is_equal(S(FnvHashMap::default()), expect![[r#"{}"#]]);
+}
diff --git a/third_party/rust/serde_with/tests/serde_as/default_on.rs b/third_party/rust/serde_with/tests/serde_as/default_on.rs
new file mode 100644
index 0000000000..ea3678b166
--- /dev/null
+++ b/third_party/rust/serde_with/tests/serde_as/default_on.rs
@@ -0,0 +1,130 @@
+use super::*;
+use serde_with::{DefaultOnError, DefaultOnNull};
+
+#[test]
+fn test_default_on_error() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "DefaultOnError<DisplayFromStr>")] u32);
+
+ // Normal
+ is_equal(S(123), expect![[r#""123""#]]);
+ is_equal(S(0), expect![[r#""0""#]]);
+ // Error cases
+ check_deserialization(S(0), r#""""#);
+ check_deserialization(S(0), r#""12+3""#);
+ check_deserialization(S(0), r#""abc""#);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2(#[serde_as(as = "DefaultOnError<Vec<DisplayFromStr>>")] Vec<u32>);
+
+ // Normal
+ is_equal(
+ S2(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ "1",
+ "2",
+ "3"
+ ]"#]],
+ );
+ is_equal(S2(vec![]), expect![[r#"[]"#]]);
+ // Error cases
+ check_deserialization(S2(vec![]), r#"2"#);
+ check_deserialization(S2(vec![]), r#""not_a_list""#);
+ check_deserialization(S2(vec![]), r#"{}"#);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Struct2 {
+ #[serde_as(as = "DefaultOnError<Vec<DisplayFromStr>>")]
+ value: Vec<u32>,
+ }
+ check_deserialization(Struct2 { value: vec![] }, r#"{"value":}"#);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S3(#[serde_as(as = "Vec<DefaultOnError<DisplayFromStr>>")] Vec<u32>);
+
+ // Normal
+ is_equal(
+ S3(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ "1",
+ "2",
+ "3"
+ ]"#]],
+ );
+ is_equal(S3(vec![]), expect![[r#"[]"#]]);
+ // Error cases
+ check_deserialization(S3(vec![0, 3, 0]), r#"[2,"3",4]"#);
+ check_deserialization(S3(vec![0, 0]), r#"["AA",5]"#);
+}
+
+#[test]
+fn test_default_on_null() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "DefaultOnNull<DisplayFromStr>")] u32);
+
+ // Normal
+ is_equal(S(123), expect![[r#""123""#]]);
+ is_equal(S(0), expect![[r#""0""#]]);
+ // Null case
+ check_deserialization(S(0), r#"null"#);
+ // Error cases
+ check_error_deserialization::<S>(
+ r#""12+3""#,
+ expect![[r#"invalid digit found in string at line 1 column 6"#]],
+ );
+ check_error_deserialization::<S>(
+ r#""abc""#,
+ expect![[r#"invalid digit found in string at line 1 column 5"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2(#[serde_as(as = "Vec<DefaultOnNull>")] Vec<u32>);
+
+ // Normal
+ is_equal(
+ S2(vec![1, 2, 0, 3]),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 0,
+ 3
+ ]"#]],
+ );
+ is_equal(S2(vec![]), expect![[r#"[]"#]]);
+ // Null cases
+ check_deserialization(S2(vec![1, 0, 2]), r#"[1, null, 2]"#);
+ check_error_deserialization::<S2>(
+ r#"["not_a_number"]"#,
+ expect![[r#"invalid type: string "not_a_number", expected u32 at line 1 column 15"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S3(#[serde_as(as = "Vec<DefaultOnNull<DisplayFromStr>>")] Vec<u32>);
+
+ // Normal
+ is_equal(
+ S3(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ "1",
+ "2",
+ "3"
+ ]"#]],
+ );
+ // Null case
+ check_deserialization(S3(vec![0, 3, 0]), r#"[null,"3",null]"#);
+ check_error_deserialization::<S3>(
+ r#"[null,3,null]"#,
+ expect![[r#"invalid type: integer `3`, expected a string at line 1 column 7"#]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/serde_as/enum_map.rs b/third_party/rust/serde_with/tests/serde_as/enum_map.rs
new file mode 100644
index 0000000000..57a0b8ade4
--- /dev/null
+++ b/third_party/rust/serde_with/tests/serde_as/enum_map.rs
@@ -0,0 +1,459 @@
+use super::*;
+use core::{fmt::Write as _, str::FromStr};
+use serde_test::Configure;
+use serde_with::EnumMap;
+use std::net::IpAddr;
+
+fn bytes_debug_readable(bytes: &[u8]) -> String {
+ let mut result = String::with_capacity(bytes.len() * 2);
+ for &byte in bytes {
+ match byte {
+ non_printable if !(0x20..0x7f).contains(&non_printable) => {
+ write!(result, "\\x{:02x}", byte).unwrap();
+ }
+ b'\\' => result.push_str("\\\\"),
+ _ => {
+ result.push(byte as char);
+ }
+ }
+ }
+ result
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+enum EnumValue {
+ Int(i32),
+ String(String),
+ Unit,
+ Tuple(i32, String, bool),
+ Struct {
+ a: i32,
+ b: String,
+ c: bool,
+ },
+ Ip(IpAddr, IpAddr),
+ #[serde(rename = "$value")]
+ Extra(serde_json::Value),
+}
+
+#[serde_as]
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
+struct VecEnumValues {
+ #[serde_as(as = "EnumMap")]
+ vec: Vec<EnumValue>,
+}
+
+#[test]
+fn json_round_trip() {
+ let values = VecEnumValues {
+ vec: vec![
+ EnumValue::Int(123),
+ EnumValue::String("FooBar".to_string()),
+ EnumValue::Int(456),
+ EnumValue::String("XXX".to_string()),
+ EnumValue::Unit,
+ EnumValue::Tuple(1, "Middle".to_string(), false),
+ EnumValue::Struct {
+ a: 666,
+ b: "BBB".to_string(),
+ c: true,
+ },
+ ],
+ };
+
+ let json = serde_json::to_string_pretty(&values).unwrap();
+ expect_test::expect![[r#"
+ {
+ "vec": {
+ "Int": 123,
+ "String": "FooBar",
+ "Int": 456,
+ "String": "XXX",
+ "Unit": null,
+ "Tuple": [
+ 1,
+ "Middle",
+ false
+ ],
+ "Struct": {
+ "a": 666,
+ "b": "BBB",
+ "c": true
+ }
+ }
+ }"#]]
+ .assert_eq(&json);
+ let deser_values: VecEnumValues = serde_json::from_str(&json).unwrap();
+ assert_eq!(values, deser_values);
+}
+
+#[test]
+fn ron_serialize() {
+ let values = VecEnumValues {
+ vec: vec![
+ EnumValue::Int(123),
+ EnumValue::String("FooBar".to_string()),
+ EnumValue::Int(456),
+ EnumValue::String("XXX".to_string()),
+ EnumValue::Unit,
+ EnumValue::Tuple(1, "Middle".to_string(), false),
+ EnumValue::Struct {
+ a: 666,
+ b: "BBB".to_string(),
+ c: true,
+ },
+ ],
+ };
+
+ let pretty_config = ron::ser::PrettyConfig::new().new_line("\n".into());
+ let ron = ron::ser::to_string_pretty(&values, pretty_config).unwrap();
+ expect_test::expect![[r#"
+ (
+ vec: {
+ "Int": 123,
+ "String": "FooBar",
+ "Int": 456,
+ "String": "XXX",
+ "Unit": (),
+ "Tuple": (1, "Middle", false),
+ "Struct": (
+ a: 666,
+ b: "BBB",
+ c: true,
+ ),
+ },
+ )"#]]
+ .assert_eq(&ron);
+ // TODO deserializing a Strings as an Identifier seems unsupported
+ let deser_values: ron::Value = ron::de::from_str(&ron).unwrap();
+ expect_test::expect![[r#"
+ Map(
+ Map(
+ {
+ String(
+ "vec",
+ ): Map(
+ Map(
+ {
+ String(
+ "Int",
+ ): Number(
+ Integer(
+ 456,
+ ),
+ ),
+ String(
+ "String",
+ ): String(
+ "XXX",
+ ),
+ String(
+ "Struct",
+ ): Map(
+ Map(
+ {
+ String(
+ "a",
+ ): Number(
+ Integer(
+ 666,
+ ),
+ ),
+ String(
+ "b",
+ ): String(
+ "BBB",
+ ),
+ String(
+ "c",
+ ): Bool(
+ true,
+ ),
+ },
+ ),
+ ),
+ String(
+ "Tuple",
+ ): Seq(
+ [
+ Number(
+ Integer(
+ 1,
+ ),
+ ),
+ String(
+ "Middle",
+ ),
+ Bool(
+ false,
+ ),
+ ],
+ ),
+ String(
+ "Unit",
+ ): Unit,
+ },
+ ),
+ ),
+ },
+ ),
+ )
+ "#]]
+ .assert_debug_eq(&deser_values);
+}
+
+#[test]
+fn xml_round_trip() {
+ let values = VecEnumValues {
+ vec: vec![
+ EnumValue::Int(123),
+ EnumValue::String("FooBar".to_string()),
+ EnumValue::Int(456),
+ EnumValue::String("XXX".to_string()),
+ EnumValue::Unit,
+ // serialize_tuple and variants are not supported by XML
+ // EnumValue::Tuple(1, "Middle".to_string(), false),
+ // Cannot be deserialized. It serializes to:
+ // <Struct><EnumValue><a>666</a><b>BBB</b><c>true</c></EnumValue></Struct>
+ // EnumValue::Struct {
+ // a: 666,
+ // b: "BBB".to_string(),
+ // c: true,
+ // },
+ ],
+ };
+
+ let xml = serde_xml_rs::to_string(&values).unwrap();
+ expect_test::expect![[r#"<VecEnumValues><vec><Int>123</Int><String>FooBar</String><Int>456</Int><String>XXX</String><Unit></Unit></vec></VecEnumValues>"#]]
+ .assert_eq(&xml);
+ let deser_values: VecEnumValues = serde_xml_rs::from_str(&xml).unwrap();
+ assert_eq!(values, deser_values);
+}
+
+#[test]
+fn serde_test_round_trip() {
+ let values = VecEnumValues {
+ vec: vec![
+ EnumValue::Int(123),
+ EnumValue::String("FooBar".to_string()),
+ EnumValue::Int(456),
+ EnumValue::String("XXX".to_string()),
+ EnumValue::Unit,
+ EnumValue::Tuple(1, "Middle".to_string(), false),
+ EnumValue::Struct {
+ a: 666,
+ b: "BBB".to_string(),
+ c: true,
+ },
+ ],
+ };
+
+ use serde_test::Token::*;
+ serde_test::assert_tokens(
+ &values.readable(),
+ &[
+ Struct {
+ name: "VecEnumValues",
+ len: 1,
+ },
+ Str("vec"),
+ Map {
+ len: Option::Some(7),
+ },
+ Str("Int"),
+ I32(123),
+ Str("String"),
+ Str("FooBar"),
+ Str("Int"),
+ I32(456),
+ Str("String"),
+ Str("XXX"),
+ Str("Unit"),
+ Unit,
+ Str("Tuple"),
+ TupleStruct {
+ name: "EnumValue",
+ len: 3,
+ },
+ I32(1),
+ Str("Middle"),
+ Bool(false),
+ TupleStructEnd,
+ Str("Struct"),
+ Struct {
+ name: "EnumValue",
+ len: 3,
+ },
+ Str("a"),
+ I32(666),
+ Str("b"),
+ Str("BBB"),
+ Str("c"),
+ Bool(true),
+ StructEnd,
+ MapEnd,
+ StructEnd,
+ ],
+ );
+}
+
+#[test]
+fn serde_test_round_trip_human_readable() {
+ let values = VecEnumValues {
+ vec: vec![EnumValue::Ip(
+ IpAddr::from_str("127.0.0.1").unwrap(),
+ IpAddr::from_str("::7777:dead:beef").unwrap(),
+ )],
+ };
+
+ use serde_test::Token::*;
+ serde_test::assert_tokens(
+ &values.clone().readable(),
+ &[
+ Struct {
+ name: "VecEnumValues",
+ len: 1,
+ },
+ Str("vec"),
+ Map {
+ len: Option::Some(1),
+ },
+ Str("Ip"),
+ TupleStruct {
+ name: "EnumValue",
+ len: 2,
+ },
+ Str("127.0.0.1"),
+ Str("::7777:dead:beef"),
+ TupleStructEnd,
+ MapEnd,
+ StructEnd,
+ ],
+ );
+
+ serde_test::assert_tokens(
+ &values.compact(),
+ &[
+ Struct {
+ name: "VecEnumValues",
+ len: 1,
+ },
+ Str("vec"),
+ Map {
+ len: Option::Some(1),
+ },
+ Str("Ip"),
+ TupleStruct {
+ name: "EnumValue",
+ len: 2,
+ },
+ NewtypeVariant {
+ name: "IpAddr",
+ variant: "V4",
+ },
+ Tuple { len: 4 },
+ U8(127),
+ U8(0),
+ U8(0),
+ U8(1),
+ TupleEnd,
+ NewtypeVariant {
+ name: "IpAddr",
+ variant: "V6",
+ },
+ Tuple { len: 16 },
+ U8(0),
+ U8(0),
+ U8(0),
+ U8(0),
+ U8(0),
+ U8(0),
+ U8(0),
+ U8(0),
+ U8(0),
+ U8(0),
+ U8(0x77),
+ U8(0x77),
+ U8(0xde),
+ U8(0xad),
+ U8(0xbe),
+ U8(0xef),
+ TupleEnd,
+ TupleStructEnd,
+ MapEnd,
+ StructEnd,
+ ],
+ );
+}
+
+// Bincode does not support Deserializer::deserialize_identifier
+// https://github.com/bincode-org/bincode/blob/e0ac3245162ba668ba04591897dd88ff5b3096b8/src/de/mod.rs#L442
+
+#[test]
+fn rmp_round_trip() {
+ let values = VecEnumValues {
+ vec: vec![
+ EnumValue::Int(123),
+ EnumValue::String("FooBar".to_string()),
+ EnumValue::Int(456),
+ EnumValue::String("XXX".to_string()),
+ EnumValue::Unit,
+ EnumValue::Tuple(1, "Middle".to_string(), false),
+ EnumValue::Struct {
+ a: 666,
+ b: "BBB".to_string(),
+ c: true,
+ },
+ EnumValue::Ip(
+ IpAddr::from_str("127.0.0.1").unwrap(),
+ IpAddr::from_str("::7777:dead:beef").unwrap(),
+ ),
+ ],
+ };
+
+ let rmp = rmp_serde::to_vec(&values).unwrap();
+ expect_test::expect![[r#"\x91\x88\xa3Int{\xa6String\xa6FooBar\xa3Int\xcd\x01\xc8\xa6String\xa3XXX\xa4Unit\xc0\xa5Tuple\x93\x01\xa6Middle\xc2\xa6Struct\x93\xcd\x02\x9a\xa3BBB\xc3\xa2Ip\x92\x81\xa2V4\x94\x7f\x00\x00\x01\x81\xa2V6\xdc\x00\x10\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00ww\xcc\xde\xcc\xad\xcc\xbe\xcc\xef"#]]
+ .assert_eq(&bytes_debug_readable(&rmp));
+ let deser_values: VecEnumValues = rmp_serde::from_read(&*rmp).unwrap();
+ assert_eq!(values, deser_values);
+}
+
+#[test]
+fn yaml_round_trip() {
+ // Duplicate enum variants do not work with YAML
+ let values = VecEnumValues {
+ vec: vec![
+ EnumValue::Int(123),
+ EnumValue::String("FooBar".to_string()),
+ // EnumValue::Int(456),
+ // EnumValue::String("XXX".to_string()),
+ EnumValue::Unit,
+ EnumValue::Tuple(1, "Middle".to_string(), false),
+ EnumValue::Struct {
+ a: 666,
+ b: "BBB".to_string(),
+ c: true,
+ },
+ ],
+ };
+
+ let yaml = serde_yaml::to_string(&values).unwrap();
+ expect_test::expect![[r#"
+ ---
+ vec:
+ Int: 123
+ String: FooBar
+ Unit: ~
+ Tuple:
+ - 1
+ - Middle
+ - false
+ Struct:
+ a: 666
+ b: BBB
+ c: true
+ "#]]
+ .assert_eq(&yaml);
+ let deser_values: VecEnumValues = serde_yaml::from_str(&yaml).unwrap();
+ assert_eq!(values, deser_values);
+}
diff --git a/third_party/rust/serde_with/tests/serde_as/frominto.rs b/third_party/rust/serde_with/tests/serde_as/frominto.rs
new file mode 100644
index 0000000000..f7f3cac213
--- /dev/null
+++ b/third_party/rust/serde_with/tests/serde_as/frominto.rs
@@ -0,0 +1,187 @@
+use super::*;
+use core::convert::TryFrom;
+use serde_with::{FromInto, TryFromInto};
+
+#[derive(Clone, Debug, PartialEq)]
+enum IntoSerializable {
+ A,
+ B,
+ C,
+}
+
+impl From<IntoSerializable> for String {
+ fn from(value: IntoSerializable) -> Self {
+ match value {
+ IntoSerializable::A => "String A",
+ IntoSerializable::B => "Some other value",
+ IntoSerializable::C => "Looks like 123",
+ }
+ .to_string()
+ }
+}
+
+#[derive(Debug, PartialEq)]
+enum FromDeserializable {
+ Zero,
+ Odd(u32),
+ Even(u32),
+}
+
+impl From<u32> for FromDeserializable {
+ fn from(value: u32) -> Self {
+ match value {
+ 0 => FromDeserializable::Zero,
+ e if e % 2 == 0 => FromDeserializable::Even(e),
+ o => FromDeserializable::Odd(o),
+ }
+ }
+}
+
+#[derive(Clone, Debug, PartialEq)]
+enum LikeBool {
+ Trueish,
+ Falseisch,
+}
+
+impl From<bool> for LikeBool {
+ fn from(b: bool) -> Self {
+ if b {
+ LikeBool::Trueish
+ } else {
+ LikeBool::Falseisch
+ }
+ }
+}
+
+impl From<LikeBool> for bool {
+ fn from(lb: LikeBool) -> Self {
+ match lb {
+ LikeBool::Trueish => true,
+ LikeBool::Falseisch => false,
+ }
+ }
+}
+
+#[test]
+fn test_frominto_ser() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Serialize)]
+ struct S(#[serde_as(serialize_as = "FromInto<String>")] IntoSerializable);
+
+ check_serialization(S(IntoSerializable::A), expect![[r#""String A""#]]);
+ check_serialization(S(IntoSerializable::B), expect![[r#""Some other value""#]]);
+ check_serialization(S(IntoSerializable::C), expect![[r#""Looks like 123""#]]);
+}
+
+#[test]
+fn test_tryfrominto_ser() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Serialize)]
+ struct S(#[serde_as(serialize_as = "TryFromInto<String>")] IntoSerializable);
+
+ check_serialization(S(IntoSerializable::A), expect![[r#""String A""#]]);
+ check_serialization(S(IntoSerializable::B), expect![[r#""Some other value""#]]);
+ check_serialization(S(IntoSerializable::C), expect![[r#""Looks like 123""#]]);
+}
+
+#[test]
+fn test_frominto_de() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct S(#[serde_as(deserialize_as = "FromInto<u32>")] FromDeserializable);
+
+ check_deserialization(S(FromDeserializable::Zero), "0");
+ check_deserialization(S(FromDeserializable::Odd(1)), "1");
+ check_deserialization(S(FromDeserializable::Odd(101)), "101");
+ check_deserialization(S(FromDeserializable::Even(2)), "2");
+ check_deserialization(S(FromDeserializable::Even(202)), "202");
+}
+
+#[test]
+fn test_tryfrominto_de() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct S(#[serde_as(deserialize_as = "TryFromInto<u32>")] FromDeserializable);
+
+ check_deserialization(S(FromDeserializable::Zero), "0");
+ check_deserialization(S(FromDeserializable::Odd(1)), "1");
+ check_deserialization(S(FromDeserializable::Odd(101)), "101");
+ check_deserialization(S(FromDeserializable::Even(2)), "2");
+ check_deserialization(S(FromDeserializable::Even(202)), "202");
+}
+
+#[test]
+fn test_frominto_de_and_ser() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde_as(as = "FromInto<bool>")] LikeBool);
+
+ is_equal(S(LikeBool::Trueish), expect![[r#"true"#]]);
+ is_equal(S(LikeBool::Falseisch), expect![[r#"false"#]]);
+}
+
+#[test]
+fn test_tryfrominto_de_and_ser() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde_as(as = "TryFromInto<bool>")] LikeBool);
+
+ is_equal(S(LikeBool::Trueish), expect![[r#"true"#]]);
+ is_equal(S(LikeBool::Falseisch), expect![[r#"false"#]]);
+}
+
+#[derive(Clone, Debug, PartialEq)]
+enum TryIntoSerializable {
+ Works,
+ Fails,
+}
+
+impl TryFrom<TryIntoSerializable> for String {
+ type Error = &'static str;
+
+ fn try_from(value: TryIntoSerializable) -> Result<Self, Self::Error> {
+ match value {
+ TryIntoSerializable::Works => Ok("Works".to_string()),
+ TryIntoSerializable::Fails => Err("Fails cannot be turned into String"),
+ }
+ }
+}
+
+#[derive(Debug, PartialEq)]
+enum TryFromDeserializable {
+ Zero,
+}
+
+impl TryFrom<u32> for TryFromDeserializable {
+ type Error = &'static str;
+
+ fn try_from(value: u32) -> Result<Self, Self::Error> {
+ match value {
+ 0 => Ok(TryFromDeserializable::Zero),
+ _ => Err("Number is not zero"),
+ }
+ }
+}
+
+#[test]
+fn test_tryfrominto_ser_with_error() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Serialize)]
+ struct S(#[serde_as(serialize_as = "TryFromInto<String>")] TryIntoSerializable);
+
+ check_serialization(S(TryIntoSerializable::Works), expect![[r#""Works""#]]);
+ check_error_serialization(
+ S(TryIntoSerializable::Fails),
+ expect![[r#"Fails cannot be turned into String"#]],
+ );
+}
+
+#[test]
+fn test_tryfrominto_de_with_error() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Deserialize)]
+ struct S(#[serde_as(deserialize_as = "TryFromInto<u32>")] TryFromDeserializable);
+
+ check_deserialization(S(TryFromDeserializable::Zero), "0");
+ check_error_deserialization::<S>("1", expect![[r#"Number is not zero"#]]);
+}
diff --git a/third_party/rust/serde_with/tests/serde_as/lib.rs b/third_party/rust/serde_with/tests/serde_as/lib.rs
new file mode 100644
index 0000000000..0b40ce0c26
--- /dev/null
+++ b/third_party/rust/serde_with/tests/serde_as/lib.rs
@@ -0,0 +1,1129 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+
+extern crate alloc;
+
+mod collections;
+mod default_on;
+mod enum_map;
+mod frominto;
+mod map_tuple_list;
+mod pickfirst;
+mod serde_as_macro;
+mod serde_conv;
+mod time;
+#[path = "../utils.rs"]
+mod utils;
+
+use crate::utils::*;
+use alloc::{
+ collections::{BTreeMap, BTreeSet, LinkedList, VecDeque},
+ rc::{Rc, Weak as RcWeak},
+ sync::{Arc, Weak as ArcWeak},
+};
+use core::cell::{Cell, RefCell};
+use expect_test::expect;
+use serde::{Deserialize, Serialize};
+use serde_with::{
+ formats::{Flexible, Strict},
+ serde_as, BoolFromInt, BytesOrString, CommaSeparator, DisplayFromStr, NoneAsEmptyString,
+ OneOrMany, Same, StringWithSeparator,
+};
+use std::{
+ collections::HashMap,
+ sync::{Mutex, RwLock},
+};
+
+#[test]
+fn test_basic_wrappers() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SBox(#[serde_as(as = "Box<DisplayFromStr>")] Box<u32>);
+
+ is_equal(SBox(Box::new(123)), expect![[r#""123""#]]);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SRc(#[serde_as(as = "Rc<DisplayFromStr>")] Rc<u32>);
+
+ is_equal(SRc(Rc::new(123)), expect![[r#""123""#]]);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize)]
+ struct SRcWeak(#[serde_as(as = "RcWeak<DisplayFromStr>")] RcWeak<u32>);
+
+ check_serialization(SRcWeak(RcWeak::new()), expect![[r#"null"#]]);
+ let s: SRcWeak = serde_json::from_str("null").unwrap();
+ assert!(s.0.upgrade().is_none());
+ let s: SRcWeak = serde_json::from_str("\"123\"").unwrap();
+ assert!(s.0.upgrade().is_none());
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SArc(#[serde_as(as = "Arc<DisplayFromStr>")] Arc<u32>);
+
+ is_equal(SArc(Arc::new(123)), expect![[r#""123""#]]);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize)]
+ struct SArcWeak(#[serde_as(as = "ArcWeak<DisplayFromStr>")] ArcWeak<u32>);
+
+ check_serialization(SArcWeak(ArcWeak::new()), expect![[r#"null"#]]);
+ let s: SArcWeak = serde_json::from_str("null").unwrap();
+ assert!(s.0.upgrade().is_none());
+ let s: SArcWeak = serde_json::from_str("\"123\"").unwrap();
+ assert!(s.0.upgrade().is_none());
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SCell(#[serde_as(as = "Cell<DisplayFromStr>")] Cell<u32>);
+
+ is_equal(SCell(Cell::new(123)), expect![[r#""123""#]]);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SRefCell(#[serde_as(as = "RefCell<DisplayFromStr>")] RefCell<u32>);
+
+ is_equal(SRefCell(RefCell::new(123)), expect![[r#""123""#]]);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize)]
+ struct SMutex(#[serde_as(as = "Mutex<DisplayFromStr>")] Mutex<u32>);
+
+ check_serialization(SMutex(Mutex::new(123)), expect![[r#""123""#]]);
+ let s: SMutex = serde_json::from_str("\"123\"").unwrap();
+ assert_eq!(*s.0.lock().unwrap(), 123);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize)]
+ struct SRwLock(#[serde_as(as = "RwLock<DisplayFromStr>")] RwLock<u32>);
+
+ let expected = expect![[r#""123""#]];
+ check_serialization(SRwLock(RwLock::new(123)), expected);
+ let s: SRwLock = serde_json::from_str("\"123\"").unwrap();
+ assert_eq!(*s.0.read().unwrap(), 123);
+}
+
+#[test]
+fn test_option() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "_")] Option<u32>);
+
+ is_equal(S(None), expect![[r#"null"#]]);
+ is_equal(S(Some(9)), expect![[r#"9"#]]);
+ check_error_deserialization::<S>(
+ r#"{}"#,
+ expect![[r#"invalid type: map, expected u32 at line 1 column 0"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Struct {
+ #[serde_as(as = "_")]
+ value: Option<u32>,
+ }
+ check_error_deserialization::<Struct>(
+ r#"{}"#,
+ expect![[r#"missing field `value` at line 1 column 2"#]],
+ );
+}
+
+#[test]
+fn test_result() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(
+ #[serde_as(as = "Result<StringWithSeparator<CommaSeparator, u32>, DisplayFromStr>")]
+ Result<Vec<u32>, u32>,
+ );
+
+ is_equal(
+ S(Ok(vec![1, 2, 3])),
+ expect![[r#"
+ {
+ "Ok": "1,2,3"
+ }"#]],
+ );
+ is_equal(
+ S(Err(9)),
+ expect![[r#"
+ {
+ "Err": "9"
+ }"#]],
+ );
+ check_error_deserialization::<S>(r#"{}"#, expect![[r#"expected value at line 1 column 2"#]]);
+}
+
+#[test]
+fn test_display_fromstr() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "DisplayFromStr")] u32);
+
+ is_equal(S(123), expect![[r#""123""#]]);
+}
+
+#[test]
+fn test_tuples() {
+ use std::net::IpAddr;
+ let ip = "1.2.3.4".parse().unwrap();
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S1(#[serde_as(as = "(DisplayFromStr,)")] (u32,));
+ is_equal(
+ S1((1,)),
+ expect![[r#"
+ [
+ "1"
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2a(#[serde_as(as = "(DisplayFromStr, DisplayFromStr)")] (u32, IpAddr));
+ is_equal(
+ S2a((555_888, ip)),
+ expect![[r#"
+ [
+ "555888",
+ "1.2.3.4"
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2b(#[serde_as(as = "(_, DisplayFromStr)")] (u32, IpAddr));
+ is_equal(
+ S2b((987, ip)),
+ expect![[r#"
+ [
+ 987,
+ "1.2.3.4"
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2c(#[serde_as(as = "(Same, DisplayFromStr)")] (u32, IpAddr));
+ is_equal(
+ S2c((987, ip)),
+ expect![[r#"
+ [
+ 987,
+ "1.2.3.4"
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S6(
+ #[serde_as(as = "(Same, Same, Same, Same, Same, Same)")] (u8, u16, u32, i8, i16, i32),
+ );
+ is_equal(
+ S6((8, 16, 32, -8, 16, -32)),
+ expect![[r#"
+ [
+ 8,
+ 16,
+ 32,
+ -8,
+ 16,
+ -32
+ ]"#]],
+ );
+}
+
+#[test]
+fn test_arrays() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S0(#[serde_as(as = "[DisplayFromStr; 0]")] [u32; 0]);
+ is_equal(S0([]), expect![[r#"[]"#]]);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S1(#[serde_as(as = "[DisplayFromStr; 1]")] [u32; 1]);
+ is_equal(
+ S1([1]),
+ expect![[r#"
+ [
+ "1"
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2(#[serde_as(as = "[Same; 2]")] [u32; 2]);
+ is_equal(
+ S2([11, 22]),
+ expect![[r#"
+ [
+ 11,
+ 22
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S32(#[serde_as(as = "[Same; 32]")] [u32; 32]);
+ is_equal(
+ S32([
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ ]),
+ expect![[r#"
+ [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 27,
+ 28,
+ 29,
+ 30,
+ 31
+ ]"#]],
+ );
+}
+
+#[test]
+fn test_sequence_like_types() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S1(#[serde_as(as = "Box<[Same]>")] Box<[u32]>);
+ is_equal(
+ S1(vec![1, 2, 3, 99].into()),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3,
+ 99
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2(#[serde_as(as = "BTreeSet<Same>")] BTreeSet<u32>);
+ is_equal(
+ S2(vec![1, 2, 3, 99].into_iter().collect()),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3,
+ 99
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S3(#[serde_as(as = "LinkedList<Same>")] LinkedList<u32>);
+ is_equal(
+ S3(vec![1, 2, 3, 99].into_iter().collect()),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3,
+ 99
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S4(#[serde_as(as = "Vec<Same>")] Vec<u32>);
+ is_equal(
+ S4(vec![1, 2, 3, 99]),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3,
+ 99
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S5(#[serde_as(as = "VecDeque<Same>")] VecDeque<u32>);
+ is_equal(
+ S5(vec![1, 2, 3, 99].into()),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3,
+ 99
+ ]"#]],
+ );
+}
+
+#[test]
+fn test_none_as_empty_string() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "NoneAsEmptyString")] Option<String>);
+
+ is_equal(S(None), expect![[r#""""#]]);
+ is_equal(S(Some("Hello".to_string())), expect![[r#""Hello""#]]);
+}
+
+#[test]
+fn test_bytes_or_string() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "BytesOrString")] Vec<u8>);
+
+ is_equal(
+ S(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3
+ ]"#]],
+ );
+ check_deserialization(S(vec![72, 101, 108, 108, 111]), r#""Hello""#);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SVec(#[serde_as(as = "Vec<BytesOrString>")] Vec<Vec<u8>>);
+
+ is_equal(
+ SVec(vec![vec![1, 2, 3]]),
+ expect![[r#"
+ [
+ [
+ 1,
+ 2,
+ 3
+ ]
+ ]"#]],
+ );
+ check_deserialization(
+ SVec(vec![
+ vec![72, 101, 108, 108, 111],
+ vec![87, 111, 114, 108, 100],
+ vec![1, 2, 3],
+ ]),
+ r#"["Hello","World",[1,2,3]]"#,
+ );
+}
+
+#[test]
+fn string_with_separator() {
+ use serde_with::{rust::StringWithSeparator, CommaSeparator, SpaceSeparator};
+
+ #[serde_as]
+ #[derive(Deserialize, Serialize)]
+ struct A {
+ #[serde_as(as = "StringWithSeparator::<SpaceSeparator, String>")]
+ tags: Vec<String>,
+ #[serde_as(as = "StringWithSeparator::<CommaSeparator, String>")]
+ // more_tags: Vec<String>,
+ more_tags: BTreeSet<String>,
+ }
+
+ let v: A = serde_json::from_str(
+ r##"{
+ "tags": "#hello #world",
+ "more_tags": "foo,bar,bar"
+}"##,
+ )
+ .unwrap();
+ assert_eq!(vec!["#hello", "#world"], v.tags);
+ assert_eq!(2, v.more_tags.len());
+
+ let x = A {
+ tags: vec!["1".to_string(), "2".to_string(), "3".to_string()],
+ more_tags: Default::default(),
+ };
+ assert_eq!(
+ r#"{"tags":"1 2 3","more_tags":""}"#,
+ serde_json::to_string(&x).unwrap()
+ );
+}
+
+#[test]
+fn test_vec_skip_error() {
+ use serde_with::VecSkipError;
+
+ #[serde_as]
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S {
+ tag: String,
+ #[serde_as(as = "VecSkipError<_>")]
+ values: Vec<u8>,
+ }
+
+ check_deserialization(
+ S {
+ tag: "type".into(),
+ values: vec![0, 1],
+ },
+ r#"{"tag":"type","values":[0, "str", 1, [10, 11], -2, {}, 300]}"#,
+ );
+ is_equal(
+ S {
+ tag: "round-trip".into(),
+ values: vec![0, 255],
+ },
+ expect![[r#"
+ {
+ "tag": "round-trip",
+ "values": [
+ 0,
+ 255
+ ]
+ }"#]],
+ );
+}
+
+#[test]
+fn test_serialize_reference() {
+ #[serde_as]
+ #[derive(Debug, Serialize)]
+ struct S1<'a>(#[serde_as(as = "Vec<DisplayFromStr>")] &'a Vec<u32>);
+ check_serialization(
+ S1(&vec![1, 2]),
+ expect![[r#"
+ [
+ "1",
+ "2"
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize)]
+ struct S1a<'a>(#[serde_as(as = "&Vec<DisplayFromStr>")] &'a Vec<u32>);
+ check_serialization(
+ S1(&vec![1, 2]),
+ expect![[r#"
+ [
+ "1",
+ "2"
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize)]
+ struct S1Mut<'a>(#[serde_as(as = "Vec<DisplayFromStr>")] &'a mut Vec<u32>);
+ check_serialization(
+ S1(&vec![1, 2]),
+ expect![[r#"
+ [
+ "1",
+ "2"
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize)]
+ struct S1aMut<'a>(#[serde_as(as = "&mut Vec<DisplayFromStr>")] &'a mut Vec<u32>);
+ check_serialization(
+ S1(&vec![1, 2]),
+ expect![[r#"
+ [
+ "1",
+ "2"
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize)]
+ struct S2<'a>(#[serde_as(as = "&[DisplayFromStr]")] &'a [u32]);
+ check_serialization(
+ S2(&[1, 2]),
+ expect![[r#"
+ [
+ "1",
+ "2"
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize)]
+ struct S3<'a>(
+ #[serde_as(as = "&BTreeMap<DisplayFromStr, DisplayFromStr>")] &'a BTreeMap<bool, u32>,
+ );
+ let bmap = vec![(false, 123), (true, 456)].into_iter().collect();
+ check_serialization(
+ S3(&bmap),
+ expect![[r#"
+ {
+ "false": "123",
+ "true": "456"
+ }"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize)]
+ struct S4<'a>(#[serde_as(as = "&Vec<(_, DisplayFromStr)>")] &'a BTreeMap<bool, u32>);
+ let bmap = vec![(false, 123), (true, 456)].into_iter().collect();
+ check_serialization(
+ S4(&bmap),
+ expect![[r#"
+ [
+ [
+ false,
+ "123"
+ ],
+ [
+ true,
+ "456"
+ ]
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize)]
+ struct S5<'a>(
+ #[serde_as(as = "&BTreeMap<DisplayFromStr, &Vec<(_, _)>>")]
+ &'a Vec<(u32, &'a BTreeMap<bool, String>)>,
+ );
+ let bmap0 = vec![(false, "123".to_string()), (true, "456".to_string())]
+ .into_iter()
+ .collect();
+ let bmap1 = vec![(true, "Hello".to_string()), (false, "World".to_string())]
+ .into_iter()
+ .collect();
+ let vec = vec![(111, &bmap0), (999, &bmap1)];
+ check_serialization(
+ S5(&vec),
+ expect![[r#"
+ {
+ "111": [
+ [
+ false,
+ "123"
+ ],
+ [
+ true,
+ "456"
+ ]
+ ],
+ "999": [
+ [
+ false,
+ "World"
+ ],
+ [
+ true,
+ "Hello"
+ ]
+ ]
+ }"#]],
+ );
+}
+
+#[test]
+fn test_big_arrays() {
+ // Single Big Array
+ #[serde_as]
+ #[derive(Debug, PartialEq, Serialize, Deserialize)]
+ struct S1(#[serde_as(as = "[_; 64]")] [u8; 64]);
+ is_equal_compact(
+ S1([0; 64]),
+ expect![[
+ r#"[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]"#
+ ]],
+ );
+ // Too few entries
+ check_error_deserialization::<S1>(
+ r#"[0,0,0,0,0,0,0,0,0,0,0,0,0,0]"#,
+ expect![[r#"invalid length 14, expected an array of size 64 at line 1 column 29"#]],
+ );
+ // Too many entries
+ check_error_deserialization::<S1>(
+ r#"[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]"#,
+ expect![[r#"trailing characters at line 1 column 130"#]],
+ );
+
+ // Single Big Array
+ #[serde_as]
+ #[derive(Debug, PartialEq, Serialize, Deserialize)]
+ struct S2(#[serde_as(as = "[DisplayFromStr; 40]")] [u8; 40]);
+ is_equal_compact(
+ S2([0; 40]),
+ expect![[
+ r#"["0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0","0"]"#
+ ]],
+ );
+
+ // Nested Big Arrays
+ #[serde_as]
+ #[derive(Debug, PartialEq, Serialize, Deserialize)]
+ struct S3(#[serde_as(as = "[[_; 34]; 33]")] [[u8; 34]; 33]);
+ is_equal_compact(
+ S3([[0; 34]; 33]),
+ expect![[
+ r#"[[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]]"#
+ ]],
+ );
+}
+
+#[test]
+fn test_bytes() {
+ // The test case is copied from
+ // https://github.com/serde-rs/bytes/blob/cbae606b9dc225fc094b031cc84eac9493da2058/tests/test_derive.rs
+ // Original code by @dtolnay
+
+ use alloc::borrow::Cow;
+ use serde_test::{assert_de_tokens, assert_tokens, Token};
+ use serde_with::Bytes;
+
+ #[serde_as]
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Test<'a> {
+ #[serde_as(as = "Bytes")]
+ array: [u8; 52],
+
+ #[serde_as(as = "Bytes")]
+ slice: &'a [u8],
+
+ #[serde_as(as = "Bytes")]
+ vec: Vec<u8>,
+
+ #[serde_as(as = "Bytes")]
+ cow_slice: Cow<'a, [u8]>,
+
+ #[serde_as(as = "Box<Bytes>")]
+ boxed_array: Box<[u8; 52]>,
+
+ #[serde_as(as = "Bytes")]
+ boxed_array2: Box<[u8; 52]>,
+
+ #[serde_as(as = "Bytes")]
+ boxed_slice: Box<[u8]>,
+
+ #[serde_as(as = "Option<Bytes>")]
+ opt_slice: Option<&'a [u8]>,
+
+ #[serde_as(as = "Option<Bytes>")]
+ opt_vec: Option<Vec<u8>>,
+
+ #[serde_as(as = "Option<Bytes>")]
+ opt_cow_slice: Option<Cow<'a, [u8]>>,
+ }
+
+ let test = Test {
+ array: *b"ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz",
+ slice: b"...",
+ vec: b"...".to_vec(),
+ cow_slice: Cow::Borrowed(b"..."),
+ boxed_array: Box::new(*b"ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz"),
+ boxed_array2: Box::new(*b"ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz"),
+ boxed_slice: b"...".to_vec().into_boxed_slice(),
+ opt_slice: Some(b"..."),
+ opt_vec: Some(b"...".to_vec()),
+ opt_cow_slice: Some(Cow::Borrowed(b"...")),
+ };
+
+ assert_tokens(
+ &test,
+ &[
+ Token::Struct {
+ name: "Test",
+ len: 10,
+ },
+ Token::Str("array"),
+ Token::BorrowedBytes(b"ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz"),
+ Token::Str("slice"),
+ Token::BorrowedBytes(b"..."),
+ Token::Str("vec"),
+ Token::Bytes(b"..."),
+ Token::Str("cow_slice"),
+ Token::BorrowedBytes(b"..."),
+ Token::Str("boxed_array"),
+ Token::BorrowedBytes(b"ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz"),
+ Token::Str("boxed_array2"),
+ Token::BorrowedBytes(b"ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz"),
+ Token::Str("boxed_slice"),
+ Token::Bytes(b"..."),
+ Token::Str("opt_slice"),
+ Token::Some,
+ Token::BorrowedBytes(b"..."),
+ Token::Str("opt_vec"),
+ Token::Some,
+ Token::Bytes(b"..."),
+ Token::Str("opt_cow_slice"),
+ Token::Some,
+ Token::BorrowedBytes(b"..."),
+ Token::StructEnd,
+ ],
+ );
+
+ // Test string deserialization
+ assert_de_tokens(
+ &test,
+ &[
+ Token::Struct {
+ name: "Test",
+ len: 10,
+ },
+ Token::Str("array"),
+ Token::BorrowedStr("ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz"),
+ Token::Str("slice"),
+ Token::BorrowedStr("..."),
+ Token::Str("vec"),
+ Token::Bytes(b"..."),
+ Token::Str("cow_slice"),
+ Token::BorrowedStr("..."),
+ Token::Str("boxed_array"),
+ Token::BorrowedStr("ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz"),
+ Token::Str("boxed_array2"),
+ Token::BorrowedStr("ABCDEFGHIJKLMNOPQRSTUVWXZYabcdefghijklmnopqrstuvwxyz"),
+ Token::Str("boxed_slice"),
+ Token::Bytes(b"..."),
+ Token::Str("opt_slice"),
+ Token::Some,
+ Token::BorrowedStr("..."),
+ Token::Str("opt_vec"),
+ Token::Some,
+ Token::Bytes(b"..."),
+ Token::Str("opt_cow_slice"),
+ Token::Some,
+ Token::BorrowedStr("..."),
+ Token::StructEnd,
+ ],
+ );
+}
+
+#[test]
+fn test_one_or_many_prefer_one() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S1Vec(#[serde_as(as = "OneOrMany<_>")] Vec<u32>);
+
+ // Normal
+ is_equal(S1Vec(vec![]), expect![[r#"[]"#]]);
+ is_equal(S1Vec(vec![1]), expect![[r#"1"#]]);
+ is_equal(
+ S1Vec(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3
+ ]"#]],
+ );
+ check_deserialization(S1Vec(vec![1]), r#"1"#);
+ check_deserialization(S1Vec(vec![1]), r#"[1]"#);
+ check_error_deserialization::<S1Vec>(r#"{}"#, expect![[r#"a list or single element"#]]);
+ check_error_deserialization::<S1Vec>(r#""xx""#, expect![[r#"a list or single element"#]]);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2Vec(#[serde_as(as = "OneOrMany<DisplayFromStr>")] Vec<u32>);
+
+ // Normal
+ is_equal(S2Vec(vec![]), expect![[r#"[]"#]]);
+ is_equal(S2Vec(vec![1]), expect![[r#""1""#]]);
+ is_equal(
+ S2Vec(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ "1",
+ "2",
+ "3"
+ ]"#]],
+ );
+ check_deserialization(S2Vec(vec![1]), r#""1""#);
+ check_deserialization(S2Vec(vec![1]), r#"["1"]"#);
+ check_error_deserialization::<S2Vec>(r#"{}"#, expect![[r#"a list or single element"#]]);
+ check_error_deserialization::<S2Vec>(r#""xx""#, expect![[r#"a list or single element"#]]);
+}
+
+#[test]
+fn test_one_or_many_prefer_many() {
+ use serde_with::formats::PreferMany;
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S1Vec(#[serde_as(as = "OneOrMany<_, PreferMany>")] Vec<u32>);
+
+ // Normal
+ is_equal(S1Vec(vec![]), expect![[r#"[]"#]]);
+ is_equal(
+ S1Vec(vec![1]),
+ expect![[r#"
+ [
+ 1
+ ]"#]],
+ );
+ is_equal(
+ S1Vec(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3
+ ]"#]],
+ );
+ check_deserialization(S1Vec(vec![1]), r#"1"#);
+ check_deserialization(S1Vec(vec![1]), r#"[1]"#);
+ check_error_deserialization::<S1Vec>(r#"{}"#, expect![[r#"a list or single element"#]]);
+ check_error_deserialization::<S1Vec>(r#""xx""#, expect![[r#"a list or single element"#]]);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2Vec(#[serde_as(as = "OneOrMany<DisplayFromStr, PreferMany>")] Vec<u32>);
+
+ // Normal
+ is_equal(S2Vec(vec![]), expect![[r#"[]"#]]);
+ is_equal(
+ S2Vec(vec![1]),
+ expect![[r#"
+ [
+ "1"
+ ]"#]],
+ );
+ is_equal(
+ S2Vec(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ "1",
+ "2",
+ "3"
+ ]"#]],
+ );
+ check_deserialization(S2Vec(vec![1]), r#""1""#);
+ check_deserialization(S2Vec(vec![1]), r#"["1"]"#);
+ check_error_deserialization::<S2Vec>(r#"{}"#, expect![[r#"a list or single element"#]]);
+ check_error_deserialization::<S2Vec>(r#""xx""#, expect![[r#"a list or single element"#]]);
+}
+
+/// Test that Cow borrows from the input
+#[test]
+fn test_borrow_cow_str() {
+ use alloc::borrow::Cow;
+ use serde_test::{assert_ser_tokens, Token};
+ use serde_with::BorrowCow;
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S1<'a> {
+ #[serde_as(as = "BorrowCow")]
+ cow: Cow<'a, str>,
+ #[serde_as(as = "Option<BorrowCow>")]
+ opt: Option<Cow<'a, str>>,
+ #[serde_as(as = "Box<BorrowCow>")]
+ b: Box<Cow<'a, str>>,
+ #[serde_as(as = "[BorrowCow; 1]")]
+ arr: [Cow<'a, str>; 1],
+ }
+
+ assert_ser_tokens(
+ &S1 {
+ cow: "abc".into(),
+ opt: Some("foo".into()),
+ b: Box::new("bar".into()),
+ arr: ["def".into()],
+ },
+ &[
+ Token::Struct { name: "S1", len: 4 },
+ Token::Str("cow"),
+ Token::BorrowedStr("abc"),
+ Token::Str("opt"),
+ Token::Some,
+ Token::BorrowedStr("foo"),
+ Token::Str("b"),
+ Token::BorrowedStr("bar"),
+ Token::Str("arr"),
+ Token::Tuple { len: 1 },
+ Token::BorrowedStr("def"),
+ Token::TupleEnd,
+ Token::StructEnd,
+ ],
+ );
+ let s1: S1<'_> = serde_json::from_str(
+ r#"{
+ "cow": "abc",
+ "opt": "foo",
+ "b": "bar",
+ "arr": ["def"]
+ }"#,
+ )
+ .unwrap();
+ assert!(matches!(s1.cow, Cow::Borrowed(_)));
+ assert!(matches!(s1.opt, Some(Cow::Borrowed(_))));
+ assert!(matches!(*s1.b, Cow::Borrowed(_)));
+ assert!(matches!(s1.arr, [Cow::Borrowed(_)]));
+ let s1: S1<'_> = serde_json::from_str(
+ r#"{
+ "cow": "a\"c",
+ "opt": "f\"o",
+ "b": "b\"r",
+ "arr": ["d\"f"]
+ }"#,
+ )
+ .unwrap();
+ assert!(matches!(s1.cow, Cow::Owned(_)));
+ assert!(matches!(s1.opt, Some(Cow::Owned(_))));
+ assert!(matches!(*s1.b, Cow::Owned(_)));
+ assert!(matches!(s1.arr, [Cow::Owned(_)]));
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2<'a> {
+ #[serde_as(as = "BorrowCow")]
+ cow: Cow<'a, [u8]>,
+ #[serde_as(as = "Option<BorrowCow>")]
+ opt: Option<Cow<'a, [u8]>>,
+ }
+
+ assert_ser_tokens(
+ &S2 {
+ cow: b"abc"[..].into(),
+ opt: Some(b"foo"[..].into()),
+ },
+ &[
+ Token::Struct { name: "S2", len: 2 },
+ Token::Str("cow"),
+ Token::Seq { len: Some(3) },
+ Token::U8(b'a'),
+ Token::U8(b'b'),
+ Token::U8(b'c'),
+ Token::SeqEnd,
+ Token::Str("opt"),
+ Token::Some,
+ Token::Seq { len: Some(3) },
+ Token::U8(b'f'),
+ Token::U8(b'o'),
+ Token::U8(b'o'),
+ Token::SeqEnd,
+ Token::StructEnd,
+ ],
+ );
+ let tokens = &[
+ Token::Struct { name: "S2", len: 2 },
+ Token::Str("cow"),
+ Token::BorrowedBytes(b"abc"),
+ Token::Str("opt"),
+ Token::Some,
+ Token::BorrowedBytes(b"foo"),
+ Token::StructEnd,
+ ];
+ let mut deser = serde_test::Deserializer::new(tokens);
+ let s2 = S2::deserialize(&mut deser).unwrap();
+ assert!(matches!(s2.cow, Cow::Borrowed(_)));
+ assert!(matches!(s2.opt, Some(Cow::Borrowed(_))));
+
+ // Check that a manual borrow works too
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S3<'a>(
+ #[serde(borrow = "'a")]
+ #[serde_as(as = "BorrowCow")]
+ Cow<'a, [u8]>,
+ // TODO add a test for Cow<'b, [u8; N]>
+ // #[serde_as(as = "BorrowCow")]
+ // Cow<'b, [u8; N]>,
+ );
+ let tokens = &[
+ Token::NewtypeStruct { name: "S3" },
+ Token::BorrowedBytes(b"abc"),
+ ];
+
+ let mut deser = serde_test::Deserializer::new(tokens);
+ let s3 = S3::deserialize(&mut deser).unwrap();
+ assert!(matches!(s3.0, Cow::Borrowed(_)));
+}
+
+#[test]
+fn test_boolfromint() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "BoolFromInt")] bool);
+
+ is_equal(S(false), expect![[r#"0"#]]);
+ is_equal(S(true), expect![[r#"1"#]]);
+ check_error_deserialization::<S>(
+ "2",
+ expect![[r#"invalid value: integer `2`, expected 0 or 1 at line 1 column 1"#]],
+ );
+ check_error_deserialization::<S>(
+ "-100",
+ expect![[r#"invalid value: integer `-100`, expected 0 or 1 at line 1 column 4"#]],
+ );
+ check_error_deserialization::<S>(
+ "18446744073709551615",
+ expect![[
+ r#"invalid value: integer `18446744073709551615`, expected 0 or 1 at line 1 column 20"#
+ ]],
+ );
+ check_error_deserialization::<S>(
+ r#""""#,
+ expect![[r#"invalid type: string "", expected an integer 0 or 1 at line 1 column 2"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SStrict(#[serde_as(as = "BoolFromInt<Strict>")] bool);
+
+ is_equal(SStrict(false), expect![[r#"0"#]]);
+ is_equal(SStrict(true), expect![[r#"1"#]]);
+ check_error_deserialization::<SStrict>(
+ "2",
+ expect![[r#"invalid value: integer `2`, expected 0 or 1 at line 1 column 1"#]],
+ );
+ check_error_deserialization::<SStrict>(
+ "-100",
+ expect![[r#"invalid value: integer `-100`, expected 0 or 1 at line 1 column 4"#]],
+ );
+ check_error_deserialization::<SStrict>(
+ "18446744073709551615",
+ expect![[
+ r#"invalid value: integer `18446744073709551615`, expected 0 or 1 at line 1 column 20"#
+ ]],
+ );
+ check_error_deserialization::<SStrict>(
+ r#""""#,
+ expect![[r#"invalid type: string "", expected an integer 0 or 1 at line 1 column 2"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SFlexible(#[serde_as(as = "BoolFromInt<Flexible>")] bool);
+
+ is_equal(SFlexible(false), expect![[r#"0"#]]);
+ is_equal(SFlexible(true), expect![[r#"1"#]]);
+ check_deserialization::<SFlexible>(SFlexible(true), "2");
+ check_deserialization::<SFlexible>(SFlexible(true), "-100");
+ check_deserialization::<SFlexible>(SFlexible(true), "18446744073709551615");
+ check_error_deserialization::<SFlexible>(
+ r#""""#,
+ expect![[r#"invalid type: string "", expected an integer at line 1 column 2"#]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/serde_as/map_tuple_list.rs b/third_party/rust/serde_with/tests/serde_as/map_tuple_list.rs
new file mode 100644
index 0000000000..332dcf676e
--- /dev/null
+++ b/third_party/rust/serde_with/tests/serde_as/map_tuple_list.rs
@@ -0,0 +1,272 @@
+use super::*;
+use std::net::IpAddr;
+
+#[test]
+fn test_map_as_tuple_list() {
+ let ip = "1.2.3.4".parse().unwrap();
+ let ip2 = "255.255.255.255".parse().unwrap();
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SB(#[serde_as(as = "Vec<(DisplayFromStr, DisplayFromStr)>")] BTreeMap<u32, IpAddr>);
+
+ let map: BTreeMap<_, _> = vec![(1, ip), (10, ip), (200, ip2)].into_iter().collect();
+ is_equal(
+ SB(map.clone()),
+ expect![[r#"
+ [
+ [
+ "1",
+ "1.2.3.4"
+ ],
+ [
+ "10",
+ "1.2.3.4"
+ ],
+ [
+ "200",
+ "255.255.255.255"
+ ]
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SB2(#[serde_as(as = "Vec<(Same, DisplayFromStr)>")] BTreeMap<u32, IpAddr>);
+
+ is_equal(
+ SB2(map),
+ expect![[r#"
+ [
+ [
+ 1,
+ "1.2.3.4"
+ ],
+ [
+ 10,
+ "1.2.3.4"
+ ],
+ [
+ 200,
+ "255.255.255.255"
+ ]
+ ]"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SH(#[serde_as(as = "Vec<(DisplayFromStr, DisplayFromStr)>")] HashMap<u32, IpAddr>);
+
+ // HashMap serialization tests with more than 1 entry are unreliable
+ let map1: HashMap<_, _> = vec![(200, ip2)].into_iter().collect();
+ let map: HashMap<_, _> = vec![(1, ip), (10, ip), (200, ip2)].into_iter().collect();
+ is_equal(
+ SH(map1.clone()),
+ expect![[r#"
+ [
+ [
+ "200",
+ "255.255.255.255"
+ ]
+ ]"#]],
+ );
+ check_deserialization(
+ SH(map.clone()),
+ r#"[["1","1.2.3.4"],["10","1.2.3.4"],["200","255.255.255.255"]]"#,
+ );
+ check_error_deserialization::<SH>(
+ r#"{"200":"255.255.255.255"}"#,
+ expect![[r#"invalid type: map, expected a sequence at line 1 column 0"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SH2(#[serde_as(as = "Vec<(Same, DisplayFromStr)>")] HashMap<u32, IpAddr>);
+
+ is_equal(
+ SH2(map1),
+ expect![[r#"
+ [
+ [
+ 200,
+ "255.255.255.255"
+ ]
+ ]"#]],
+ );
+ check_deserialization(
+ SH2(map),
+ r#"[[1,"1.2.3.4"],[10,"1.2.3.4"],[200,"255.255.255.255"]]"#,
+ );
+ check_error_deserialization::<SH2>(
+ r#"1"#,
+ expect![[r#"invalid type: integer `1`, expected a sequence at line 1 column 1"#]],
+ );
+}
+
+#[test]
+fn test_tuple_list_as_map() {
+ let ip = "1.2.3.4".parse().unwrap();
+ let ip2 = "255.255.255.255".parse().unwrap();
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SH(#[serde_as(as = "HashMap<DisplayFromStr, DisplayFromStr>")] Vec<(u32, IpAddr)>);
+
+ is_equal(
+ SH(vec![(1, ip), (10, ip), (200, ip2)]),
+ expect![[r#"
+ {
+ "1": "1.2.3.4",
+ "10": "1.2.3.4",
+ "200": "255.255.255.255"
+ }"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SB(#[serde_as(as = "BTreeMap<DisplayFromStr, DisplayFromStr>")] Vec<(u32, IpAddr)>);
+
+ is_equal(
+ SB(vec![(1, ip), (10, ip), (200, ip2)]),
+ expect![[r#"
+ {
+ "1": "1.2.3.4",
+ "10": "1.2.3.4",
+ "200": "255.255.255.255"
+ }"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SD(#[serde_as(as = "BTreeMap<DisplayFromStr, DisplayFromStr>")] VecDeque<(u32, IpAddr)>);
+
+ is_equal(
+ SD(vec![(1, ip), (10, ip), (200, ip2)].into()),
+ expect![[r#"
+ {
+ "1": "1.2.3.4",
+ "10": "1.2.3.4",
+ "200": "255.255.255.255"
+ }"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Sll(
+ #[serde_as(as = "HashMap<DisplayFromStr, DisplayFromStr>")] LinkedList<(u32, IpAddr)>,
+ );
+
+ is_equal(
+ Sll(vec![(1, ip), (10, ip), (200, ip2)].into_iter().collect()),
+ expect![[r#"
+ {
+ "1": "1.2.3.4",
+ "10": "1.2.3.4",
+ "200": "255.255.255.255"
+ }"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct SO(#[serde_as(as = "HashMap<DisplayFromStr, DisplayFromStr>")] Option<(u32, IpAddr)>);
+
+ is_equal(
+ SO(Some((1, ip))),
+ expect![[r#"
+ {
+ "1": "1.2.3.4"
+ }"#]],
+ );
+ is_equal(SO(None), expect![[r#"{}"#]]);
+}
+
+#[test]
+fn test_tuple_array_as_map() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Serialize, Deserialize)]
+ struct S1(#[serde_as(as = "BTreeMap<_, _>")] [(u8, u8); 1]);
+ is_equal(
+ S1([(1, 2)]),
+ expect![[r#"
+ {
+ "1": 2
+ }"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, PartialEq, Serialize, Deserialize)]
+ struct S2(#[serde_as(as = "HashMap<_, _>")] [(u8, u8); 33]);
+ is_equal(
+ S2([
+ (0, 0),
+ (1, 1),
+ (2, 2),
+ (3, 3),
+ (4, 4),
+ (5, 5),
+ (6, 6),
+ (7, 7),
+ (8, 8),
+ (9, 9),
+ (10, 10),
+ (11, 11),
+ (12, 12),
+ (13, 13),
+ (14, 14),
+ (15, 15),
+ (16, 16),
+ (17, 17),
+ (18, 18),
+ (19, 19),
+ (20, 20),
+ (21, 21),
+ (22, 22),
+ (23, 23),
+ (24, 24),
+ (25, 25),
+ (26, 26),
+ (27, 27),
+ (28, 28),
+ (29, 29),
+ (30, 30),
+ (31, 31),
+ (32, 32),
+ ]),
+ expect![[r#"
+ {
+ "0": 0,
+ "1": 1,
+ "2": 2,
+ "3": 3,
+ "4": 4,
+ "5": 5,
+ "6": 6,
+ "7": 7,
+ "8": 8,
+ "9": 9,
+ "10": 10,
+ "11": 11,
+ "12": 12,
+ "13": 13,
+ "14": 14,
+ "15": 15,
+ "16": 16,
+ "17": 17,
+ "18": 18,
+ "19": 19,
+ "20": 20,
+ "21": 21,
+ "22": 22,
+ "23": 23,
+ "24": 24,
+ "25": 25,
+ "26": 26,
+ "27": 27,
+ "28": 28,
+ "29": 29,
+ "30": 30,
+ "31": 31,
+ "32": 32
+ }"#]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/serde_as/pickfirst.rs b/third_party/rust/serde_with/tests/serde_as/pickfirst.rs
new file mode 100644
index 0000000000..ed3cacb1dd
--- /dev/null
+++ b/third_party/rust/serde_with/tests/serde_as/pickfirst.rs
@@ -0,0 +1,134 @@
+use super::*;
+use serde_with::{CommaSeparator, PickFirst, SpaceSeparator, StringWithSeparator};
+
+#[test]
+fn test_pick_first_two() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "PickFirst<(_, DisplayFromStr)>")] u32);
+
+ is_equal(S(123), expect![[r#"123"#]]);
+ check_deserialization(S(123), r#""123""#);
+ check_error_deserialization::<S>(
+ r#""Abc""#,
+ expect![[r#"PickFirst could not deserialize data"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2(#[serde_as(as = "PickFirst<(DisplayFromStr, _)>")] u32);
+
+ is_equal(S2(123), expect![[r#""123""#]]);
+ check_deserialization(S2(123), r#"123"#);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S3(
+ #[serde_as(as = "PickFirst<(_, StringWithSeparator::<SpaceSeparator, String>,)>")]
+ Vec<String>,
+ );
+ is_equal(
+ S3(vec!["A".to_string(), "B".to_string(), "C".to_string()]),
+ expect![[r#"
+ [
+ "A",
+ "B",
+ "C"
+ ]"#]],
+ );
+ check_deserialization(
+ S3(vec!["A".to_string(), "B".to_string(), "C".to_string()]),
+ r#""A B C""#,
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S4(
+ #[serde_as(as = "PickFirst<(StringWithSeparator::<CommaSeparator, String>, _,)>")]
+ Vec<String>,
+ );
+ is_equal(
+ S4(vec!["A".to_string(), "B".to_string(), "C".to_string()]),
+ expect![[r#""A,B,C""#]],
+ );
+ check_deserialization(
+ S4(vec!["A".to_string(), "B".to_string(), "C".to_string()]),
+ r#"["A", "B", "C"]"#,
+ );
+}
+
+#[test]
+fn test_pick_first_three() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(
+ #[serde_as(
+ as = "PickFirst<(_, Vec<DisplayFromStr>, StringWithSeparator::<CommaSeparator, u32>)>"
+ )]
+ Vec<u32>,
+ );
+ is_equal(
+ S(vec![1, 2, 3]),
+ expect![[r#"
+ [
+ 1,
+ 2,
+ 3
+ ]"#]],
+ );
+ check_deserialization(
+ S(vec![1, 2, 3]),
+ r#"
+ [
+ "1",
+ "2",
+ "3"
+ ]"#,
+ );
+ check_deserialization(S(vec![1, 2, 3]), r#""1,2,3""#);
+ check_error_deserialization::<S>(
+ r#""Abc""#,
+ expect![[r#"PickFirst could not deserialize data"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S2(
+ #[serde_as(
+ as = "PickFirst<(StringWithSeparator::<CommaSeparator, u32>, _, Vec<DisplayFromStr>)>"
+ )]
+ Vec<u32>,
+ );
+ is_equal(S2(vec![1, 2, 3]), expect![[r#""1,2,3""#]]);
+ check_deserialization(
+ S2(vec![1, 2, 3]),
+ r#"
+ [
+ "1",
+ "2",
+ "3"
+ ]"#,
+ );
+ check_deserialization(
+ S2(vec![1, 2, 3]),
+ r#"
+ [
+ 1,
+ 2,
+ 3
+ ]"#,
+ );
+}
+
+#[test]
+fn test_pick_first_four() {
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = "PickFirst<(_, _, _, _)>")] u32);
+
+ is_equal(S(123), expect![[r#"123"#]]);
+ check_error_deserialization::<S>(
+ r#""Abc""#,
+ expect![[r#"PickFirst could not deserialize data"#]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/serde_as/serde_as_macro.rs b/third_party/rust/serde_with/tests/serde_as/serde_as_macro.rs
new file mode 100644
index 0000000000..b180079d46
--- /dev/null
+++ b/third_party/rust/serde_with/tests/serde_as/serde_as_macro.rs
@@ -0,0 +1,191 @@
+use super::*;
+
+/// Test that the [`serde_as`] macro can replace the `_` type and the resulting code compiles.
+#[test]
+fn test_serde_as_macro_replace_infer_type() {
+ #[serde_as]
+ #[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
+ struct Data {
+ #[serde_as(as = "_")]
+ a: u32,
+ #[serde_as(as = "std::vec::Vec<_>")]
+ b: Vec<u32>,
+ #[serde_as(as = "Vec<(_, _)>")]
+ c: Vec<(u32, String)>,
+ #[serde_as(as = "[_; 2]")]
+ d: [u32; 2],
+ #[serde_as(as = "Box<[_]>")]
+ e: Box<[u32]>,
+ }
+
+ is_equal(
+ Data {
+ a: 10,
+ b: vec![20, 33],
+ c: vec![(40, "Hello".into()), (55, "World".into()), (60, "!".into())],
+ d: [70, 88],
+ e: vec![99, 100, 110].into_boxed_slice(),
+ },
+ expect![[r#"
+ {
+ "a": 10,
+ "b": [
+ 20,
+ 33
+ ],
+ "c": [
+ [
+ 40,
+ "Hello"
+ ],
+ [
+ 55,
+ "World"
+ ],
+ [
+ 60,
+ "!"
+ ]
+ ],
+ "d": [
+ 70,
+ 88
+ ],
+ "e": [
+ 99,
+ 100,
+ 110
+ ]
+ }"#]],
+ );
+}
+
+/// Test that the [`serde_as`] macro supports `deserialize_as`
+#[test]
+fn test_serde_as_macro_deserialize() {
+ #[serde_as]
+ #[derive(Debug, Eq, PartialEq, Deserialize)]
+ struct Data {
+ #[serde_as(deserialize_as = "DisplayFromStr")]
+ a: u32,
+ #[serde_as(deserialize_as = "Vec<DisplayFromStr>")]
+ b: Vec<u32>,
+ #[serde_as(deserialize_as = "(DisplayFromStr, _)")]
+ c: (u32, u32),
+ }
+
+ check_deserialization(
+ Data {
+ a: 10,
+ b: vec![20, 33],
+ c: (40, 55),
+ },
+ r##"{
+ "a": "10",
+ "b": [
+ "20",
+ "33"
+ ],
+ "c": [
+ "40",
+ 55
+ ]
+}"##,
+ );
+}
+
+/// Test that the [`serde_as`] macro supports `serialize_as`
+#[test]
+fn test_serde_as_macro_serialize() {
+ #[serde_as]
+ #[derive(Debug, Eq, PartialEq, Serialize)]
+ struct Data {
+ #[serde_as(serialize_as = "DisplayFromStr")]
+ a: u32,
+ #[serde_as(serialize_as = "Vec<DisplayFromStr>")]
+ b: Vec<u32>,
+ #[serde_as(serialize_as = "(DisplayFromStr, _)")]
+ c: (u32, u32),
+ }
+
+ check_serialization(
+ Data {
+ a: 10,
+ b: vec![20, 33],
+ c: (40, 55),
+ },
+ expect![[r#"
+ {
+ "a": "10",
+ "b": [
+ "20",
+ "33"
+ ],
+ "c": [
+ "40",
+ 55
+ ]
+ }"#]],
+ );
+}
+
+/// Test that the [`serde_as`] macro supports `serialize_as` and `deserialize_as`
+#[test]
+fn test_serde_as_macro_serialize_deserialize() {
+ #[serde_as]
+ #[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
+ struct Data {
+ #[serde_as(serialize_as = "DisplayFromStr", deserialize_as = "DisplayFromStr")]
+ a: u32,
+ #[serde_as(
+ serialize_as = "Vec<DisplayFromStr>",
+ deserialize_as = "Vec<DisplayFromStr>"
+ )]
+ b: Vec<u32>,
+ #[serde_as(
+ serialize_as = "(DisplayFromStr, _)",
+ deserialize_as = "(DisplayFromStr, _)"
+ )]
+ c: (u32, u32),
+ }
+
+ is_equal(
+ Data {
+ a: 10,
+ b: vec![20, 33],
+ c: (40, 55),
+ },
+ expect![[r#"
+ {
+ "a": "10",
+ "b": [
+ "20",
+ "33"
+ ],
+ "c": [
+ "40",
+ 55
+ ]
+ }"#]],
+ );
+}
+
+/// Test that the [`serde_as`] macro works correctly if applied multiple times to a field
+#[test]
+fn test_serde_as_macro_multiple_field_attributes() {
+ #[serde_as]
+ #[derive(Debug, Eq, PartialEq, Serialize, Deserialize)]
+ struct Data {
+ #[serde_as(serialize_as = "DisplayFromStr")]
+ #[serde_as(deserialize_as = "DisplayFromStr")]
+ a: u32,
+ }
+
+ is_equal(
+ Data { a: 10 },
+ expect![[r#"
+ {
+ "a": "10"
+ }"#]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/serde_as/serde_conv.rs b/third_party/rust/serde_with/tests/serde_as/serde_conv.rs
new file mode 100644
index 0000000000..1e510f72a3
--- /dev/null
+++ b/third_party/rust/serde_with/tests/serde_as/serde_conv.rs
@@ -0,0 +1,52 @@
+use super::*;
+use serde_with::serde_conv;
+
+#[test]
+fn test_bool_as_string() {
+ serde_conv!(BoolAsString, bool, |x: &bool| x.to_string(), |x: String| x
+ .parse());
+
+ #[derive(Debug, PartialEq, Serialize, Deserialize)]
+ struct SWith(#[serde(with = "BoolAsString")] bool);
+
+ is_equal(SWith(false), expect![[r#""false""#]]);
+ is_equal(SWith(true), expect![[r#""true""#]]);
+ check_error_deserialization::<SWith>(
+ "123",
+ expect![[r#"invalid type: integer `123`, expected a string at line 1 column 3"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, PartialEq, Serialize, Deserialize)]
+ struct SAs(#[serde_as(as = "BoolAsString")] bool);
+
+ is_equal(SAs(false), expect![[r#""false""#]]);
+ is_equal(SAs(true), expect![[r#""true""#]]);
+ check_error_deserialization::<SAs>(
+ "123",
+ expect![[r#"invalid type: integer `123`, expected a string at line 1 column 3"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, PartialEq, Serialize, Deserialize)]
+ struct SAsVec(#[serde_as(as = "Vec<BoolAsString>")] Vec<bool>);
+
+ is_equal(
+ SAsVec(vec![false]),
+ expect![[r#"
+ [
+ "false"
+ ]"#]],
+ );
+ is_equal(
+ SAsVec(vec![true]),
+ expect![[r#"
+ [
+ "true"
+ ]"#]],
+ );
+ check_error_deserialization::<SAsVec>(
+ "123",
+ expect![[r#"invalid type: integer `123`, expected a sequence at line 1 column 3"#]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/serde_as/time.rs b/third_party/rust/serde_with/tests/serde_as/time.rs
new file mode 100644
index 0000000000..91808b4d8c
--- /dev/null
+++ b/third_party/rust/serde_with/tests/serde_as/time.rs
@@ -0,0 +1,521 @@
+use super::*;
+use core::time::Duration;
+use serde_with::{
+ DurationMicroSeconds, DurationMicroSecondsWithFrac, DurationMilliSeconds,
+ DurationMilliSecondsWithFrac, DurationNanoSeconds, DurationNanoSecondsWithFrac,
+ DurationSeconds, DurationSecondsWithFrac, TimestampMicroSeconds, TimestampMicroSecondsWithFrac,
+ TimestampMilliSeconds, TimestampMilliSecondsWithFrac, TimestampNanoSeconds,
+ TimestampNanoSecondsWithFrac, TimestampSeconds, TimestampSecondsWithFrac,
+};
+use std::time::SystemTime;
+
+#[test]
+fn test_duration_seconds() {
+ let zero = Duration::new(0, 0);
+ let one_second = Duration::new(1, 0);
+ let half_second = Duration::new(0, 500_000_000);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct IntStrict(#[serde_as(as = "DurationSeconds")] Duration);
+
+ is_equal(IntStrict(zero), expect![[r#"0"#]]);
+ is_equal(IntStrict(one_second), expect![[r#"1"#]]);
+ check_serialization(IntStrict(half_second), expect![[r#"1"#]]);
+ check_error_deserialization::<IntStrict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected u64 at line 1 column 3"#]],
+ );
+ check_error_deserialization::<IntStrict>(
+ r#"-1"#,
+ expect![[r#"invalid value: integer `-1`, expected u64 at line 1 column 2"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct IntFlexible(#[serde_as(as = "DurationSeconds<u64, Flexible>")] Duration);
+
+ is_equal(IntFlexible(zero), expect![[r#"0"#]]);
+ is_equal(IntFlexible(one_second), expect![[r#"1"#]]);
+ check_serialization(IntFlexible(half_second), expect![[r#"1"#]]);
+ check_deserialization(IntFlexible(half_second), r#""0.5""#);
+ check_deserialization(IntFlexible(one_second), r#""1""#);
+ check_deserialization(IntFlexible(zero), r#""0""#);
+ check_error_deserialization::<IntFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+ check_error_deserialization::<IntFlexible>(
+ r#"-1"#,
+ expect![[r#"std::time::Duration cannot be negative"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct F64Strict(#[serde_as(as = "DurationSeconds<f64>")] Duration);
+
+ is_equal(F64Strict(zero), expect![[r#"0.0"#]]);
+ is_equal(F64Strict(one_second), expect![[r#"1.0"#]]);
+ check_serialization(F64Strict(half_second), expect![[r#"1.0"#]]);
+ check_deserialization(F64Strict(one_second), r#"0.5"#);
+ check_error_deserialization::<F64Strict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected f64 at line 1 column 3"#]],
+ );
+ check_error_deserialization::<F64Strict>(
+ r#"-1.0"#,
+ expect![[r#"std::time::Duration cannot be negative"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct F64Flexible(#[serde_as(as = "DurationSeconds<f64, Flexible>")] Duration);
+
+ is_equal(F64Flexible(zero), expect![[r#"0.0"#]]);
+ is_equal(F64Flexible(one_second), expect![[r#"1.0"#]]);
+ check_serialization(F64Flexible(half_second), expect![[r#"1.0"#]]);
+ check_deserialization(F64Flexible(half_second), r#""0.5""#);
+ check_deserialization(F64Flexible(one_second), r#""1""#);
+ check_deserialization(F64Flexible(zero), r#""0""#);
+ check_error_deserialization::<F64Flexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+ check_error_deserialization::<F64Flexible>(
+ r#"-1"#,
+ expect![[r#"std::time::Duration cannot be negative"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StringStrict(#[serde_as(as = "DurationSeconds<String>")] Duration);
+
+ is_equal(StringStrict(zero), expect![[r#""0""#]]);
+ is_equal(StringStrict(one_second), expect![[r#""1""#]]);
+ check_serialization(StringStrict(half_second), expect![[r#""1""#]]);
+ check_error_deserialization::<StringStrict>(
+ r#"1"#,
+ expect![[
+ r#"invalid type: integer `1`, expected a string containing a number at line 1 column 1"#
+ ]],
+ );
+ check_error_deserialization::<StringStrict>(
+ r#"-1"#,
+ expect![[
+ r#"invalid type: integer `-1`, expected a string containing a number at line 1 column 2"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StringFlexible(#[serde_as(as = "DurationSeconds<String, Flexible>")] Duration);
+
+ is_equal(StringFlexible(zero), expect![[r#""0""#]]);
+ is_equal(StringFlexible(one_second), expect![[r#""1""#]]);
+ check_serialization(StringFlexible(half_second), expect![[r#""1""#]]);
+ check_deserialization(StringFlexible(half_second), r#""0.5""#);
+ check_deserialization(StringFlexible(one_second), r#""1""#);
+ check_deserialization(StringFlexible(zero), r#""0""#);
+ check_error_deserialization::<StringFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+ check_error_deserialization::<StringFlexible>(
+ r#"-1"#,
+ expect![[r#"std::time::Duration cannot be negative"#]],
+ );
+}
+
+#[test]
+fn test_duration_seconds_with_frac() {
+ let zero = Duration::new(0, 0);
+ let one_second = Duration::new(1, 0);
+ let half_second = Duration::new(0, 500_000_000);
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct F64Strict(#[serde_as(as = "DurationSecondsWithFrac<f64>")] Duration);
+
+ is_equal(F64Strict(zero), expect![[r#"0.0"#]]);
+ is_equal(F64Strict(one_second), expect![[r#"1.0"#]]);
+ is_equal(F64Strict(half_second), expect![[r#"0.5"#]]);
+ check_error_deserialization::<F64Strict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected f64 at line 1 column 3"#]],
+ );
+ check_error_deserialization::<F64Strict>(
+ r#"-1.0"#,
+ expect![[r#"std::time::Duration cannot be negative"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct F64Flexible(#[serde_as(as = "DurationSecondsWithFrac<f64, Flexible>")] Duration);
+
+ is_equal(F64Flexible(zero), expect![[r#"0.0"#]]);
+ is_equal(F64Flexible(one_second), expect![[r#"1.0"#]]);
+ is_equal(F64Flexible(half_second), expect![[r#"0.5"#]]);
+ check_deserialization(F64Flexible(one_second), r#""1""#);
+ check_deserialization(F64Flexible(zero), r#""0""#);
+ check_error_deserialization::<F64Flexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+ check_error_deserialization::<F64Flexible>(
+ r#"-1"#,
+ expect![[r#"std::time::Duration cannot be negative"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StringStrict(#[serde_as(as = "DurationSecondsWithFrac<String>")] Duration);
+
+ is_equal(StringStrict(zero), expect![[r#""0""#]]);
+ is_equal(StringStrict(one_second), expect![[r#""1""#]]);
+ is_equal(StringStrict(half_second), expect![[r#""0.5""#]]);
+ check_error_deserialization::<StringStrict>(
+ r#"1"#,
+ expect![[r#"invalid type: integer `1`, expected a string at line 1 column 1"#]],
+ );
+ check_error_deserialization::<StringStrict>(
+ r#"-1"#,
+ expect![[r#"invalid type: integer `-1`, expected a string at line 1 column 2"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StringFlexible(#[serde_as(as = "DurationSecondsWithFrac<String, Flexible>")] Duration);
+
+ is_equal(StringFlexible(zero), expect![[r#""0""#]]);
+ is_equal(StringFlexible(one_second), expect![[r#""1""#]]);
+ is_equal(StringFlexible(half_second), expect![[r#""0.5""#]]);
+ check_deserialization(StringFlexible(zero), r#""0""#);
+ check_error_deserialization::<StringFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+ check_error_deserialization::<StringFlexible>(
+ r#"-1"#,
+ expect![[r#"std::time::Duration cannot be negative"#]],
+ );
+}
+
+#[test]
+fn test_timestamp_seconds_systemtime() {
+ let zero = SystemTime::UNIX_EPOCH;
+ let one_second = SystemTime::UNIX_EPOCH
+ .checked_add(Duration::new(1, 0))
+ .unwrap();
+ let half_second = SystemTime::UNIX_EPOCH
+ .checked_add(Duration::new(0, 500_000_000))
+ .unwrap();
+ let minus_one_second = SystemTime::UNIX_EPOCH
+ .checked_sub(Duration::new(1, 0))
+ .unwrap();
+ let minus_half_second = SystemTime::UNIX_EPOCH
+ .checked_sub(Duration::new(0, 500_000_000))
+ .unwrap();
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructIntStrict(#[serde_as(as = "TimestampSeconds")] SystemTime);
+
+ is_equal(StructIntStrict(zero), expect![[r#"0"#]]);
+ is_equal(StructIntStrict(one_second), expect![[r#"1"#]]);
+ is_equal(StructIntStrict(minus_one_second), expect![[r#"-1"#]]);
+ check_serialization(StructIntStrict(half_second), expect![[r#"1"#]]);
+ check_serialization(StructIntStrict(minus_half_second), expect![[r#"-1"#]]);
+ check_error_deserialization::<StructIntStrict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected i64 at line 1 column 3"#]],
+ );
+ check_error_deserialization::<StructIntStrict>(
+ r#"0.123"#,
+ expect![[r#"invalid type: floating point `0.123`, expected i64 at line 1 column 5"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructIntFlexible(#[serde_as(as = "TimestampSeconds<i64, Flexible>")] SystemTime);
+
+ is_equal(StructIntFlexible(zero), expect![[r#"0"#]]);
+ is_equal(StructIntFlexible(one_second), expect![[r#"1"#]]);
+ is_equal(StructIntFlexible(minus_one_second), expect![[r#"-1"#]]);
+ check_serialization(StructIntFlexible(half_second), expect![[r#"1"#]]);
+ check_serialization(StructIntFlexible(minus_half_second), expect![[r#"-1"#]]);
+ check_deserialization(StructIntFlexible(one_second), r#""1""#);
+ check_deserialization(StructIntFlexible(one_second), r#"1.0"#);
+ check_deserialization(StructIntFlexible(minus_half_second), r#""-0.5""#);
+ check_deserialization(StructIntFlexible(half_second), r#"0.5"#);
+ check_error_deserialization::<StructIntFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Strict(#[serde_as(as = "TimestampSeconds<f64>")] SystemTime);
+
+ is_equal(Structf64Strict(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Strict(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Strict(minus_one_second), expect![[r#"-1.0"#]]);
+ check_serialization(Structf64Strict(half_second), expect![[r#"1.0"#]]);
+ check_serialization(Structf64Strict(minus_half_second), expect![[r#"-1.0"#]]);
+ check_deserialization(Structf64Strict(one_second), r#"0.5"#);
+ check_error_deserialization::<Structf64Strict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected f64 at line 1 column 3"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Flexible(#[serde_as(as = "TimestampSeconds<f64, Flexible>")] SystemTime);
+
+ is_equal(Structf64Flexible(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Flexible(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Flexible(minus_one_second), expect![[r#"-1.0"#]]);
+ check_serialization(Structf64Flexible(half_second), expect![[r#"1.0"#]]);
+ check_serialization(Structf64Flexible(minus_half_second), expect![[r#"-1.0"#]]);
+ check_deserialization(Structf64Flexible(one_second), r#""1""#);
+ check_deserialization(Structf64Flexible(one_second), r#"1.0"#);
+ check_deserialization(Structf64Flexible(minus_half_second), r#""-0.5""#);
+ check_deserialization(Structf64Flexible(half_second), r#"0.5"#);
+ check_error_deserialization::<Structf64Flexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringStrict(#[serde_as(as = "TimestampSeconds<String>")] SystemTime);
+
+ is_equal(StructStringStrict(zero), expect![[r#""0""#]]);
+ is_equal(StructStringStrict(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringStrict(minus_one_second), expect![[r#""-1""#]]);
+ check_serialization(StructStringStrict(half_second), expect![[r#""1""#]]);
+ check_serialization(StructStringStrict(minus_half_second), expect![[r#""-1""#]]);
+ check_deserialization(StructStringStrict(one_second), r#""1""#);
+ check_error_deserialization::<StructStringStrict>(
+ r#""0.5""#,
+ expect![[r#"invalid digit found in string at line 1 column 5"#]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#""-0.5""#,
+ expect![[r#"invalid digit found in string at line 1 column 6"#]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"1"#,
+ expect![[
+ r#"invalid type: integer `1`, expected a string containing a number at line 1 column 1"#
+ ]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"0.0"#,
+ expect![[
+ r#"invalid type: floating point `0`, expected a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringFlexible(#[serde_as(as = "TimestampSeconds<String, Flexible>")] SystemTime);
+
+ is_equal(StructStringFlexible(zero), expect![[r#""0""#]]);
+ is_equal(StructStringFlexible(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringFlexible(minus_one_second), expect![[r#""-1""#]]);
+ check_serialization(StructStringFlexible(half_second), expect![[r#""1""#]]);
+ check_serialization(
+ StructStringFlexible(minus_half_second),
+ expect![[r#""-1""#]],
+ );
+ check_deserialization(StructStringFlexible(one_second), r#"1"#);
+ check_deserialization(StructStringFlexible(one_second), r#"1.0"#);
+ check_deserialization(StructStringFlexible(minus_half_second), r#""-0.5""#);
+ check_deserialization(StructStringFlexible(half_second), r#"0.5"#);
+ check_error_deserialization::<StructStringFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+}
+
+#[test]
+fn test_timestamp_seconds_with_frac_systemtime() {
+ let zero = SystemTime::UNIX_EPOCH;
+ let one_second = SystemTime::UNIX_EPOCH
+ .checked_add(Duration::new(1, 0))
+ .unwrap();
+ let half_second = SystemTime::UNIX_EPOCH
+ .checked_add(Duration::new(0, 500_000_000))
+ .unwrap();
+ let minus_one_second = SystemTime::UNIX_EPOCH
+ .checked_sub(Duration::new(1, 0))
+ .unwrap();
+ let minus_half_second = SystemTime::UNIX_EPOCH
+ .checked_sub(Duration::new(0, 500_000_000))
+ .unwrap();
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Strict(#[serde_as(as = "TimestampSecondsWithFrac<f64>")] SystemTime);
+
+ is_equal(Structf64Strict(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Strict(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Strict(minus_one_second), expect![[r#"-1.0"#]]);
+ is_equal(Structf64Strict(half_second), expect![[r#"0.5"#]]);
+ is_equal(Structf64Strict(minus_half_second), expect![[r#"-0.5"#]]);
+ check_error_deserialization::<Structf64Strict>(
+ r#""1""#,
+ expect![[r#"invalid type: string "1", expected f64 at line 1 column 3"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct Structf64Flexible(
+ #[serde_as(as = "TimestampSecondsWithFrac<f64, Flexible>")] SystemTime,
+ );
+
+ is_equal(Structf64Flexible(zero), expect![[r#"0.0"#]]);
+ is_equal(Structf64Flexible(one_second), expect![[r#"1.0"#]]);
+ is_equal(Structf64Flexible(minus_one_second), expect![[r#"-1.0"#]]);
+ is_equal(Structf64Flexible(half_second), expect![[r#"0.5"#]]);
+ is_equal(Structf64Flexible(minus_half_second), expect![[r#"-0.5"#]]);
+ check_deserialization(Structf64Flexible(one_second), r#""1""#);
+ check_deserialization(Structf64Flexible(one_second), r#"1.0"#);
+ check_deserialization(Structf64Flexible(minus_half_second), r#""-0.5""#);
+ check_deserialization(Structf64Flexible(half_second), r#"0.5"#);
+ check_error_deserialization::<Structf64Flexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringStrict(#[serde_as(as = "TimestampSecondsWithFrac<String>")] SystemTime);
+
+ is_equal(StructStringStrict(zero), expect![[r#""0""#]]);
+ is_equal(StructStringStrict(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringStrict(minus_one_second), expect![[r#""-1""#]]);
+ is_equal(StructStringStrict(half_second), expect![[r#""0.5""#]]);
+ is_equal(
+ StructStringStrict(minus_half_second),
+ expect![[r#""-0.5""#]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"1"#,
+ expect![[r#"invalid type: integer `1`, expected a string at line 1 column 1"#]],
+ );
+ check_error_deserialization::<StructStringStrict>(
+ r#"0.0"#,
+ expect![[r#"invalid type: floating point `0`, expected a string at line 1 column 3"#]],
+ );
+
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct StructStringFlexible(
+ #[serde_as(as = "TimestampSecondsWithFrac<String, Flexible>")] SystemTime,
+ );
+
+ is_equal(StructStringFlexible(zero), expect![[r#""0""#]]);
+ is_equal(StructStringFlexible(one_second), expect![[r#""1""#]]);
+ is_equal(StructStringFlexible(minus_one_second), expect![[r#""-1""#]]);
+ is_equal(StructStringFlexible(half_second), expect![[r#""0.5""#]]);
+ is_equal(
+ StructStringFlexible(minus_half_second),
+ expect![[r#""-0.5""#]],
+ );
+ check_deserialization(StructStringFlexible(one_second), r#"1"#);
+ check_deserialization(StructStringFlexible(one_second), r#"1.0"#);
+ check_deserialization(StructStringFlexible(half_second), r#"0.5"#);
+ check_error_deserialization::<StructStringFlexible>(
+ r#""a""#,
+ expect![[
+ r#"invalid value: string "a", expected an integer, a float, or a string containing a number at line 1 column 3"#
+ ]],
+ );
+}
+
+macro_rules! smoketest {
+ ($($valuety:ty, $adapter:literal, $value:ident, $expect:tt;)*) => {
+ $({
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = $adapter)] $valuety);
+ #[allow(unused_braces)]
+ is_equal(S($value), $expect);
+ })*
+ };
+}
+
+#[test]
+fn test_duration_smoketest() {
+ let one_second = Duration::new(1, 0);
+
+ smoketest! {
+ Duration, "DurationSeconds<u64>", one_second, {expect![[r#"1"#]]};
+ Duration, "DurationSeconds<f64>", one_second, {expect![[r#"1.0"#]]};
+ Duration, "DurationMilliSeconds<u64>", one_second, {expect![[r#"1000"#]]};
+ Duration, "DurationMilliSeconds<f64>", one_second, {expect![[r#"1000.0"#]]};
+ Duration, "DurationMicroSeconds<u64>", one_second, {expect![[r#"1000000"#]]};
+ Duration, "DurationMicroSeconds<f64>", one_second, {expect![[r#"1000000.0"#]]};
+ Duration, "DurationNanoSeconds<u64>", one_second, {expect![[r#"1000000000"#]]};
+ Duration, "DurationNanoSeconds<f64>", one_second, {expect![[r#"1000000000.0"#]]};
+ };
+
+ smoketest! {
+ Duration, "DurationSecondsWithFrac", one_second, {expect![[r#"1.0"#]]};
+ Duration, "DurationSecondsWithFrac<String>", one_second, {expect![[r#""1""#]]};
+ Duration, "DurationMilliSecondsWithFrac", one_second, {expect![[r#"1000.0"#]]};
+ Duration, "DurationMilliSecondsWithFrac<String>", one_second, {expect![[r#""1000""#]]};
+ Duration, "DurationMicroSecondsWithFrac", one_second, {expect![[r#"1000000.0"#]]};
+ Duration, "DurationMicroSecondsWithFrac<String>", one_second, {expect![[r#""1000000""#]]};
+ Duration, "DurationNanoSecondsWithFrac", one_second, {expect![[r#"1000000000.0"#]]};
+ Duration, "DurationNanoSecondsWithFrac<String>", one_second, {expect![[r#""1000000000""#]]};
+ };
+}
+
+#[test]
+fn test_timestamp_systemtime_smoketest() {
+ let one_second = SystemTime::UNIX_EPOCH
+ .checked_add(Duration::new(1, 0))
+ .unwrap();
+
+ smoketest! {
+ SystemTime, "TimestampSeconds<i64>", one_second, {expect![[r#"1"#]]};
+ SystemTime, "TimestampSeconds<f64>", one_second, {expect![[r#"1.0"#]]};
+ SystemTime, "TimestampMilliSeconds<i64>", one_second, {expect![[r#"1000"#]]};
+ SystemTime, "TimestampMilliSeconds<f64>", one_second, {expect![[r#"1000.0"#]]};
+ SystemTime, "TimestampMicroSeconds<i64>", one_second, {expect![[r#"1000000"#]]};
+ SystemTime, "TimestampMicroSeconds<f64>", one_second, {expect![[r#"1000000.0"#]]};
+ SystemTime, "TimestampNanoSeconds<i64>", one_second, {expect![[r#"1000000000"#]]};
+ SystemTime, "TimestampNanoSeconds<f64>", one_second, {expect![[r#"1000000000.0"#]]};
+ };
+
+ smoketest! {
+ SystemTime, "TimestampSecondsWithFrac", one_second, {expect![[r#"1.0"#]]};
+ SystemTime, "TimestampSecondsWithFrac<String>", one_second, {expect![[r#""1""#]]};
+ SystemTime, "TimestampMilliSecondsWithFrac", one_second, {expect![[r#"1000.0"#]]};
+ SystemTime, "TimestampMilliSecondsWithFrac<String>", one_second, {expect![[r#""1000""#]]};
+ SystemTime, "TimestampMicroSecondsWithFrac", one_second, {expect![[r#"1000000.0"#]]};
+ SystemTime, "TimestampMicroSecondsWithFrac<String>", one_second, {expect![[r#""1000000""#]]};
+ SystemTime, "TimestampNanoSecondsWithFrac", one_second, {expect![[r#"1000000000.0"#]]};
+ SystemTime, "TimestampNanoSecondsWithFrac<String>", one_second, {expect![[r#""1000000000""#]]};
+ };
+}
diff --git a/third_party/rust/serde_with/tests/time_0_3.rs b/third_party/rust/serde_with/tests/time_0_3.rs
new file mode 100644
index 0000000000..4c89dbd7d4
--- /dev/null
+++ b/third_party/rust/serde_with/tests/time_0_3.rs
@@ -0,0 +1,229 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+
+mod utils;
+
+use crate::utils::{check_deserialization, check_error_deserialization, is_equal};
+use expect_test::expect;
+use serde::{Deserialize, Serialize};
+use serde_with::{
+ serde_as, DurationMicroSeconds, DurationMicroSecondsWithFrac, DurationMilliSeconds,
+ DurationMilliSecondsWithFrac, DurationNanoSeconds, DurationNanoSecondsWithFrac,
+ DurationSeconds, DurationSecondsWithFrac, TimestampMicroSeconds, TimestampMicroSecondsWithFrac,
+ TimestampMilliSeconds, TimestampMilliSecondsWithFrac, TimestampNanoSeconds,
+ TimestampNanoSecondsWithFrac, TimestampSeconds, TimestampSecondsWithFrac,
+};
+use time_0_3::{Duration, OffsetDateTime, PrimitiveDateTime, UtcOffset};
+
+/// Create a [`PrimitiveDateTime`] for the Unix Epoch
+fn unix_epoch_primitive() -> PrimitiveDateTime {
+ PrimitiveDateTime::new(
+ time_0_3::Date::from_ordinal_date(1970, 1).unwrap(),
+ time_0_3::Time::from_hms_nano(0, 0, 0, 0).unwrap(),
+ )
+}
+
+macro_rules! smoketest {
+ ($($valuety:ty, $adapter:literal, $value:expr, $expect:tt;)*) => {
+ $({
+ #[serde_as]
+ #[derive(Debug, Serialize, Deserialize, PartialEq)]
+ struct S(#[serde_as(as = $adapter)] $valuety);
+ #[allow(unused_braces)]
+ is_equal(S($value), $expect);
+ })*
+ };
+}
+
+#[test]
+fn test_duration_smoketest() {
+ let zero = Duration::seconds(0);
+ let one_second = Duration::seconds(1);
+
+ smoketest! {
+ Duration, "DurationSeconds<i64>", one_second, {expect![[r#"1"#]]};
+ Duration, "DurationSeconds<f64>", one_second, {expect![[r#"1.0"#]]};
+ Duration, "DurationMilliSeconds<i64>", one_second, {expect![[r#"1000"#]]};
+ Duration, "DurationMilliSeconds<f64>", one_second, {expect![[r#"1000.0"#]]};
+ Duration, "DurationMicroSeconds<i64>", one_second, {expect![[r#"1000000"#]]};
+ Duration, "DurationMicroSeconds<f64>", one_second, {expect![[r#"1000000.0"#]]};
+ Duration, "DurationNanoSeconds<i64>", one_second, {expect![[r#"1000000000"#]]};
+ Duration, "DurationNanoSeconds<f64>", one_second, {expect![[r#"1000000000.0"#]]};
+ };
+
+ smoketest! {
+ Duration, "DurationSecondsWithFrac", one_second, {expect![[r#"1.0"#]]};
+ Duration, "DurationSecondsWithFrac<String>", one_second, {expect![[r#""1""#]]};
+ Duration, "DurationMilliSecondsWithFrac", one_second, {expect![[r#"1000.0"#]]};
+ Duration, "DurationMilliSecondsWithFrac<String>", one_second, {expect![[r#""1000""#]]};
+ Duration, "DurationMicroSecondsWithFrac", one_second, {expect![[r#"1000000.0"#]]};
+ Duration, "DurationMicroSecondsWithFrac<String>", one_second, {expect![[r#""1000000""#]]};
+ Duration, "DurationNanoSecondsWithFrac", one_second, {expect![[r#"1000000000.0"#]]};
+ Duration, "DurationNanoSecondsWithFrac<String>", one_second, {expect![[r#""1000000000""#]]};
+ };
+
+ smoketest! {
+ Duration, "DurationSecondsWithFrac", zero, {expect![[r#"0.0"#]]};
+ Duration, "DurationSecondsWithFrac", zero + Duration::nanoseconds(500_000_000), {expect![[r#"0.5"#]]};
+ Duration, "DurationSecondsWithFrac", zero + Duration::seconds(1), {expect![[r#"1.0"#]]};
+ Duration, "DurationSecondsWithFrac", zero - Duration::nanoseconds(500_000_000), {expect![[r#"-0.5"#]]};
+ Duration, "DurationSecondsWithFrac", zero - Duration::seconds(1), {expect![[r#"-1.0"#]]};
+ };
+}
+
+#[test]
+fn test_datetime_utc_smoketest() {
+ let zero = OffsetDateTime::UNIX_EPOCH;
+ let one_second = zero + Duration::seconds(1);
+
+ smoketest! {
+ OffsetDateTime, "TimestampSeconds<i64>", one_second, {expect![[r#"1"#]]};
+ OffsetDateTime, "TimestampSeconds<f64>", one_second, {expect![[r#"1.0"#]]};
+ OffsetDateTime, "TimestampMilliSeconds<i64>", one_second, {expect![[r#"1000"#]]};
+ OffsetDateTime, "TimestampMilliSeconds<f64>", one_second, {expect![[r#"1000.0"#]]};
+ OffsetDateTime, "TimestampMicroSeconds<i64>", one_second, {expect![[r#"1000000"#]]};
+ OffsetDateTime, "TimestampMicroSeconds<f64>", one_second, {expect![[r#"1000000.0"#]]};
+ OffsetDateTime, "TimestampNanoSeconds<i64>", one_second, {expect![[r#"1000000000"#]]};
+ OffsetDateTime, "TimestampNanoSeconds<f64>", one_second, {expect![[r#"1000000000.0"#]]};
+ };
+
+ smoketest! {
+ OffsetDateTime, "TimestampSecondsWithFrac", one_second, {expect![[r#"1.0"#]]};
+ OffsetDateTime, "TimestampSecondsWithFrac<String>", one_second, {expect![[r#""1""#]]};
+ OffsetDateTime, "TimestampMilliSecondsWithFrac", one_second, {expect![[r#"1000.0"#]]};
+ OffsetDateTime, "TimestampMilliSecondsWithFrac<String>", one_second, {expect![[r#""1000""#]]};
+ OffsetDateTime, "TimestampMicroSecondsWithFrac", one_second, {expect![[r#"1000000.0"#]]};
+ OffsetDateTime, "TimestampMicroSecondsWithFrac<String>", one_second, {expect![[r#""1000000""#]]};
+ OffsetDateTime, "TimestampNanoSecondsWithFrac", one_second, {expect![[r#"1000000000.0"#]]};
+ OffsetDateTime, "TimestampNanoSecondsWithFrac<String>", one_second, {expect![[r#""1000000000""#]]};
+ };
+
+ smoketest! {
+ OffsetDateTime, "TimestampSecondsWithFrac", zero, {expect![[r#"0.0"#]]};
+ OffsetDateTime, "TimestampSecondsWithFrac", zero + Duration::nanoseconds(500_000_000), {expect![[r#"0.5"#]]};
+ OffsetDateTime, "TimestampSecondsWithFrac", zero + Duration::seconds(1), {expect![[r#"1.0"#]]};
+ OffsetDateTime, "TimestampSecondsWithFrac", zero - Duration::nanoseconds(500_000_000), {expect![[r#"-0.5"#]]};
+ OffsetDateTime, "TimestampSecondsWithFrac", zero - Duration::seconds(1), {expect![[r#"-1.0"#]]};
+ };
+}
+
+#[test]
+fn test_naive_datetime_smoketest() {
+ let zero = unix_epoch_primitive();
+ let one_second = zero + Duration::seconds(1);
+
+ smoketest! {
+ PrimitiveDateTime, "TimestampSeconds<i64>", one_second, {expect![[r#"1"#]]};
+ PrimitiveDateTime, "TimestampSeconds<f64>", one_second, {expect![[r#"1.0"#]]};
+ PrimitiveDateTime, "TimestampMilliSeconds<i64>", one_second, {expect![[r#"1000"#]]};
+ PrimitiveDateTime, "TimestampMilliSeconds<f64>", one_second, {expect![[r#"1000.0"#]]};
+ PrimitiveDateTime, "TimestampMicroSeconds<i64>", one_second, {expect![[r#"1000000"#]]};
+ PrimitiveDateTime, "TimestampMicroSeconds<f64>", one_second, {expect![[r#"1000000.0"#]]};
+ PrimitiveDateTime, "TimestampNanoSeconds<i64>", one_second, {expect![[r#"1000000000"#]]};
+ PrimitiveDateTime, "TimestampNanoSeconds<f64>", one_second, {expect![[r#"1000000000.0"#]]};
+ };
+
+ smoketest! {
+ PrimitiveDateTime, "TimestampSecondsWithFrac", one_second, {expect![[r#"1.0"#]]};
+ PrimitiveDateTime, "TimestampSecondsWithFrac<String>", one_second, {expect![[r#""1""#]]};
+ PrimitiveDateTime, "TimestampMilliSecondsWithFrac", one_second, {expect![[r#"1000.0"#]]};
+ PrimitiveDateTime, "TimestampMilliSecondsWithFrac<String>", one_second, {expect![[r#""1000""#]]};
+ PrimitiveDateTime, "TimestampMicroSecondsWithFrac", one_second, {expect![[r#"1000000.0"#]]};
+ PrimitiveDateTime, "TimestampMicroSecondsWithFrac<String>", one_second, {expect![[r#""1000000""#]]};
+ PrimitiveDateTime, "TimestampNanoSecondsWithFrac", one_second, {expect![[r#"1000000000.0"#]]};
+ PrimitiveDateTime, "TimestampNanoSecondsWithFrac<String>", one_second, {expect![[r#""1000000000""#]]};
+ };
+
+ smoketest! {
+ PrimitiveDateTime, "TimestampSecondsWithFrac", zero, {expect![[r#"0.0"#]]};
+ PrimitiveDateTime, "TimestampSecondsWithFrac", zero + Duration::nanoseconds(500_000_000), {expect![[r#"0.5"#]]};
+ PrimitiveDateTime, "TimestampSecondsWithFrac", zero + Duration::seconds(1), {expect![[r#"1.0"#]]};
+ PrimitiveDateTime, "TimestampSecondsWithFrac", zero - Duration::nanoseconds(500_000_000), {expect![[r#"-0.5"#]]};
+ PrimitiveDateTime, "TimestampSecondsWithFrac", zero - Duration::seconds(1), {expect![[r#"-1.0"#]]};
+ };
+}
+
+#[test]
+fn test_offset_datetime_rfc2822() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde_as(as = "time_0_3::format_description::well_known::Rfc2822")] OffsetDateTime);
+
+ is_equal(
+ S(OffsetDateTime::UNIX_EPOCH),
+ expect![[r#""Thu, 01 Jan 1970 00:00:00 +0000""#]],
+ );
+
+ check_error_deserialization::<S>(
+ r#""Foobar""#,
+ expect![[r#"the 'weekday' component could not be parsed at line 1 column 8"#]],
+ );
+ check_error_deserialization::<S>(
+ r#""Fri, 2000""#,
+ expect![[r#"a character literal was not valid at line 1 column 11"#]],
+ );
+}
+
+#[test]
+fn test_offset_datetime_rfc3339() {
+ #[serde_as]
+ #[derive(Debug, PartialEq, Deserialize, Serialize)]
+ struct S(#[serde_as(as = "time_0_3::format_description::well_known::Rfc3339")] OffsetDateTime);
+
+ is_equal(
+ S(OffsetDateTime::UNIX_EPOCH),
+ expect![[r#""1970-01-01T00:00:00Z""#]],
+ );
+ check_deserialization::<S>(
+ S(
+ OffsetDateTime::from_unix_timestamp_nanos(482_196_050_520_000_000)
+ .unwrap()
+ .to_offset(UtcOffset::from_hms(0, 0, 0).unwrap()),
+ ),
+ r#""1985-04-12T23:20:50.52Z""#,
+ );
+ check_deserialization::<S>(
+ S(OffsetDateTime::from_unix_timestamp(851_042_397)
+ .unwrap()
+ .to_offset(UtcOffset::from_hms(-8, 0, 0).unwrap())),
+ r#""1996-12-19T16:39:57-08:00""#,
+ );
+ check_deserialization::<S>(
+ S(
+ OffsetDateTime::from_unix_timestamp_nanos(662_687_999_999_999_999)
+ .unwrap()
+ .to_offset(UtcOffset::from_hms(0, 0, 0).unwrap()),
+ ),
+ r#""1990-12-31T23:59:60Z""#,
+ );
+ check_deserialization::<S>(
+ S(
+ OffsetDateTime::from_unix_timestamp_nanos(662_687_999_999_999_999)
+ .unwrap()
+ .to_offset(UtcOffset::from_hms(-8, 0, 0).unwrap()),
+ ),
+ r#""1990-12-31T15:59:60-08:00""#,
+ );
+ check_deserialization::<S>(
+ S(
+ OffsetDateTime::from_unix_timestamp_nanos(-1_041_337_172_130_000_000)
+ .unwrap()
+ .to_offset(UtcOffset::from_hms(0, 20, 0).unwrap()),
+ ),
+ r#""1937-01-01T12:00:27.87+00:20""#,
+ );
+
+ check_error_deserialization::<S>(
+ r#""Foobar""#,
+ expect![[r#"the 'year' component could not be parsed at line 1 column 8"#]],
+ );
+ check_error_deserialization::<S>(
+ r#""2000-AA""#,
+ expect![[r#"the 'month' component could not be parsed at line 1 column 9"#]],
+ );
+}
diff --git a/third_party/rust/serde_with/tests/utils.rs b/third_party/rust/serde_with/tests/utils.rs
new file mode 100644
index 0000000000..d9247ffff9
--- /dev/null
+++ b/third_party/rust/serde_with/tests/utils.rs
@@ -0,0 +1,79 @@
+#![allow(dead_code)]
+
+use core::fmt::Debug;
+use expect_test::Expect;
+use pretty_assertions::assert_eq;
+use serde::{de::DeserializeOwned, Serialize};
+
+#[track_caller]
+pub fn is_equal<T>(value: T, expected: Expect)
+where
+ T: Debug + DeserializeOwned + PartialEq + Serialize,
+{
+ let serialized = serde_json::to_string_pretty(&value).unwrap();
+ expected.assert_eq(&serialized);
+ assert_eq!(
+ value,
+ serde_json::from_str::<T>(&serialized).unwrap(),
+ "Deserialization differs from expected value."
+ );
+}
+
+/// Like [`is_equal`] but not pretty-print
+#[track_caller]
+pub fn is_equal_compact<T>(value: T, expected: Expect)
+where
+ T: Debug + DeserializeOwned + PartialEq + Serialize,
+{
+ let serialized = serde_json::to_string(&value).unwrap();
+ expected.assert_eq(&serialized);
+ assert_eq!(
+ value,
+ serde_json::from_str::<T>(&serialized).unwrap(),
+ "Deserialization differs from expected value."
+ );
+}
+
+#[track_caller]
+pub fn check_deserialization<T>(value: T, deserialize_from: &str)
+where
+ T: Debug + DeserializeOwned + PartialEq,
+{
+ assert_eq!(
+ value,
+ serde_json::from_str::<T>(deserialize_from).unwrap(),
+ "Deserialization differs from expected value."
+ );
+}
+
+#[track_caller]
+pub fn check_serialization<T>(value: T, serialize_to: Expect)
+where
+ T: Debug + Serialize,
+{
+ serialize_to.assert_eq(&serde_json::to_string_pretty(&value).unwrap());
+}
+
+#[track_caller]
+pub fn check_error_serialization<T>(value: T, error_msg: Expect)
+where
+ T: Debug + Serialize,
+{
+ error_msg.assert_eq(
+ &serde_json::to_string_pretty(&value)
+ .unwrap_err()
+ .to_string(),
+ );
+}
+
+#[track_caller]
+pub fn check_error_deserialization<T>(deserialize_from: &str, error_msg: Expect)
+where
+ T: Debug + DeserializeOwned,
+{
+ error_msg.assert_eq(
+ &serde_json::from_str::<T>(deserialize_from)
+ .unwrap_err()
+ .to_string(),
+ )
+}
diff --git a/third_party/rust/serde_with/tests/version_numbers.rs b/third_party/rust/serde_with/tests/version_numbers.rs
new file mode 100644
index 0000000000..5c478d91ed
--- /dev/null
+++ b/third_party/rust/serde_with/tests/version_numbers.rs
@@ -0,0 +1,80 @@
+// Needed to supress a 2021 incompatability warning in the macro generated code
+// The non_fmt_panic lint is not yet available on most Rust versions
+#![allow(unknown_lints, non_fmt_panics)]
+
+use version_sync::{
+ assert_contains_regex, assert_html_root_url_updated, assert_markdown_deps_updated,
+};
+
+#[test]
+fn test_readme_deps() {
+ assert_markdown_deps_updated!("README.md");
+}
+
+#[test]
+fn test_readme_deps_in_lib() {
+ assert_contains_regex!("src/lib.rs", r#"^//! version = "{version}""#);
+}
+
+#[test]
+fn test_changelog() {
+ assert_contains_regex!("CHANGELOG.md", r#"## \[{version}\]"#);
+}
+
+#[test]
+fn test_html_root_url() {
+ assert_html_root_url_updated!("src/lib.rs");
+}
+
+/// Check that all docs.rs links point to the current version
+///
+/// Parse all docs.rs links in `*.rs` and `*.md` files and check that they point to the current version.
+/// If a link should point to latest version this can be done by using `latest` in the version.
+/// The `*` version specifier is not allowed.
+///
+/// Arguably this should be part of version-sync. There is an open issue for this feature:
+/// https://github.com/mgeisler/version-sync/issues/72
+#[test]
+fn test_docs_rs_url_point_to_current_version() -> Result<(), Box<dyn std::error::Error>> {
+ let pkg_name = env!("CARGO_PKG_NAME");
+ let pkg_version = env!("CARGO_PKG_VERSION");
+
+ let re = regex::Regex::new(&format!(
+ "https?://docs.rs/{}/((\\d[^/]+|\\*|latest))/",
+ pkg_name
+ ))?;
+ let mut error = false;
+
+ for entry in glob::glob("**/*.rs")?.chain(glob::glob("**/README.md")?) {
+ let entry = entry?;
+ let content = std::fs::read_to_string(&entry)?;
+ for (line_number, line) in content.split('\n').enumerate() {
+ for capture in re.captures_iter(line) {
+ match capture
+ .get(1)
+ .expect("Will exist if regex matches")
+ .as_str()
+ {
+ "latest" => {}
+ version if version != pkg_version => {
+ error = true;
+ println!(
+ "{}:{} pkg_version is {} but found URL {}",
+ entry.display(),
+ line_number + 1,
+ pkg_version,
+ capture.get(0).expect("Group 0 always exists").as_str()
+ )
+ }
+ _ => {}
+ }
+ }
+ }
+ }
+
+ if error {
+ panic!("Found wrong URLs in file(s)");
+ } else {
+ Ok(())
+ }
+}
diff --git a/third_party/rust/serde_with/tests/with_prefix.rs b/third_party/rust/serde_with/tests/with_prefix.rs
new file mode 100644
index 0000000000..bc7a78711e
--- /dev/null
+++ b/third_party/rust/serde_with/tests/with_prefix.rs
@@ -0,0 +1,164 @@
+#![allow(
+ // clippy is broken and shows wrong warnings
+ // clippy on stable does not know yet about the lint name
+ unknown_lints,
+ // https://github.com/rust-lang/rust-clippy/issues/8867
+ clippy::derive_partial_eq_without_eq,
+)]
+
+extern crate alloc;
+
+mod utils;
+
+use crate::utils::is_equal;
+use alloc::collections::BTreeMap;
+use core::iter::FromIterator;
+use expect_test::expect;
+use serde::{Deserialize, Serialize};
+use serde_with::with_prefix;
+use std::collections::HashMap;
+
+#[test]
+fn test_flatten_with_prefix() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Match {
+ #[serde(flatten, with = "prefix_player1")]
+ player1: Player,
+ #[serde(flatten, with = "prefix_player2")]
+ player2: Option<Player>,
+ #[serde(flatten, with = "prefix_player3")]
+ player3: Option<Player>,
+ #[serde(flatten, with = "prefix_tag")]
+ tags: HashMap<String, String>,
+ }
+
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Player {
+ name: String,
+ votes: u64,
+ }
+
+ with_prefix!(prefix_player1 "player1_");
+ with_prefix!(prefix_player2 "player2_");
+ with_prefix!(prefix_player3 "player3_");
+ with_prefix!(prefix_tag "tag_");
+
+ let m = Match {
+ player1: Player {
+ name: "name1".to_owned(),
+ votes: 1,
+ },
+ player2: Some(Player {
+ name: "name2".to_owned(),
+ votes: 2,
+ }),
+ player3: None,
+ tags: HashMap::from_iter(vec![("t".to_owned(), "T".to_owned())]),
+ };
+
+ is_equal(
+ m,
+ expect![[r#"
+ {
+ "player1_name": "name1",
+ "player1_votes": 1,
+ "player2_name": "name2",
+ "player2_votes": 2,
+ "tag_t": "T"
+ }"#]],
+ );
+}
+
+#[test]
+fn test_plain_with_prefix() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Match {
+ #[serde(with = "prefix_player1")]
+ player1: Player,
+ #[serde(with = "prefix_player2")]
+ player2: Option<Player>,
+ #[serde(with = "prefix_player3")]
+ player3: Option<Player>,
+ #[serde(with = "prefix_tag")]
+ tags: HashMap<String, String>,
+ }
+
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Player {
+ name: String,
+ votes: u64,
+ }
+
+ with_prefix!(prefix_player1 "player1_");
+ with_prefix!(prefix_player2 "player2_");
+ with_prefix!(prefix_player3 "player3_");
+ with_prefix!(prefix_tag "tag_");
+
+ let m = Match {
+ player1: Player {
+ name: "name1".to_owned(),
+ votes: 1,
+ },
+ player2: Some(Player {
+ name: "name2".to_owned(),
+ votes: 2,
+ }),
+ player3: None,
+ tags: HashMap::from_iter(vec![("t".to_owned(), "T".to_owned())]),
+ };
+
+ is_equal(
+ m,
+ expect![[r#"
+ {
+ "player1": {
+ "player1_name": "name1",
+ "player1_votes": 1
+ },
+ "player2": {
+ "player2_name": "name2",
+ "player2_votes": 2
+ },
+ "player3": null,
+ "tags": {
+ "tag_t": "T"
+ }
+ }"#]],
+ );
+}
+
+/// Ensure that with_prefix works for unit type enum variants.
+#[test]
+fn test_enum_unit_variant_with_prefix() {
+ #[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize, Ord, PartialOrd)]
+ enum Foo {
+ One,
+ Two,
+ Three,
+ }
+
+ #[derive(Hash, PartialEq, Eq, Debug, Serialize, Deserialize, Ord, PartialOrd)]
+ struct Data {
+ stuff: String,
+
+ #[serde(flatten, with = "foo")]
+ foo: BTreeMap<Foo, i32>,
+ }
+ with_prefix!(foo "foo_");
+
+ let d = Data {
+ stuff: "Stuff".to_owned(),
+ foo: BTreeMap::from_iter(vec![(Foo::One, 1), (Foo::Two, 2), (Foo::Three, 3)]),
+ };
+
+ is_equal(
+ d,
+ expect![[r#"
+ {
+ "stuff": "Stuff",
+ "foo_One": 1,
+ "foo_Two": 2,
+ "foo_Three": 3
+ }"#]],
+ );
+}
diff --git a/third_party/rust/serde_with_macros/.cargo-checksum.json b/third_party/rust/serde_with_macros/.cargo-checksum.json
new file mode 100644
index 0000000000..c147c72da5
--- /dev/null
+++ b/third_party/rust/serde_with_macros/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"880c29c4c3ce0b1ff845ab7d65d1d993e16556e8086748f711a1f79c2436815f","Cargo.toml":"bb1a43583596e4ab00d1d584026e0c3f8d442f6e1edbc861ca0754bfbbf4655d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7576269ea71f767b99297934c0b2367532690f8c4badc695edf8e04ab6a1e545","README.md":"1bb8ac615b1f41460d5ebb22784ccb6ff0f028fb8756b43e911b3584400b0fe0","src/lib.rs":"e37b7afbce72225a66b5c55b4a51730d4830298949b12d59e0c2718f68fa5cb5","src/utils.rs":"2b64a8ae74104034691e43befba768daf954501d7eed988b12953fa765a14c8d"},"package":"e182d6ec6f05393cc0e5ed1bf81ad6db3a8feedf8ee515ecdd369809bcce8082"} \ No newline at end of file
diff --git a/third_party/rust/serde_with_macros/CHANGELOG.md b/third_party/rust/serde_with_macros/CHANGELOG.md
new file mode 100644
index 0000000000..c8153d018b
--- /dev/null
+++ b/third_party/rust/serde_with_macros/CHANGELOG.md
@@ -0,0 +1,157 @@
+# Changelog
+
+All notable changes to this project will be documented in this file.
+
+The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
+and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
+
+## [Unreleased]
+
+## [1.5.2] - 2022-04-07
+
+### Fixed
+
+* Account for generics when deriving implementations with `SerializeDisplay` and `DeserializeFromStr` #413
+* Provide better error messages when parsing types fails #423
+
+## [1.5.1] - 2021-10-18
+
+### Added
+
+* The minimal supported Rust version (MSRV) is now specified in the `Cargo.toml` via the `rust-version` field. The field is supported in Rust 1.56 and has no effect on versions before.
+
+ More details: https://doc.rust-lang.org/nightly/cargo/reference/manifest.html#the-rust-version-field
+
+## [1.5.0] - 2021-09-04
+
+### Added
+
+* Add the attribute `#[serde(borrow)]` on a field if `serde_as` is used in combination with the `BorrowCow` type.
+
+## [1.4.2] - 2021-06-07
+
+### Fixed
+
+* Describe how the `serde_as` macro works on a high level.
+* The derive macros `SerializeDisplay` and `DeserializeFromStr` were relying on the prelude where they were used.
+ Properly name all types and traits required for the expanded code to work.
+ The tests were improved to be better able to catch such problems.
+
+## [1.4.2] - 2021-02-16
+
+### Fixed
+
+* Fix compiling when having a struct field without the `serde_as` annotation.
+ This broke in 1.4.0 [#267](https://github.com/jonasbb/serde_with/issues/267)
+
+## [1.4.0] - 2021-02-15
+
+### Changed
+
+* Improve error messages when `#[serde_as(..)]` is misused as a field attribute.
+ Thanks to @Lehona for reporting the bug in #233.
+* Internal cleanup for assembling and parsing attributes during `serde_as` processing.
+* Change processing on `#[serde_as(...)]` attributes on fields.
+
+ The attributes will no longer be stripped during proc-macro processing.
+ Instead, a private derive macro is applied to the struct/enum which captures them and makes them inert, thus allowing compilation.
+
+ This should have no effect on the generated code and on the runtime behavior.
+ It eases integration of third-party crates with `serde_with`, since they can now process the `#[serde_as(...)]` field attributes reliably.
+ Before this was impossible for derive macros and lead to awkward ordering constraints on the attribute macros.
+
+ Thanks to @Lehona for reporting this problem and to @dtolnay for suggesting the dummy derive macro.
+
+## [1.3.0] - 2020-11-22
+
+### Added
+
+* Support specifying a path to the `serde_with` crate for the `serde_as` and derive macros.
+ This is useful when using crate renaming in Cargo.toml or while re-exporting the macros.
+
+ Many thanks to @tobz1000 for raising the issue and contributing fixes.
+
+### Changed
+
+* Bump minimum supported rust version to 1.40.0
+
+## [1.2.2] - 2020-10-06
+
+### Fixed
+
+* @adwhit contributed an improvement to `DeserializeFromStr` which allows it to deserialize from bytes (#186).
+ This makes the derived implementation applicable in more situations.
+
+## [1.2.1] - 2020-10-04
+
+### Fixed
+
+* The derive macros `SerializeDisplay` and `DeserializeFromStr` now use the properly namespaced types and traits.
+ This solves conflicts with `Result` if `Result` is not `std::result::Result`, e.g., a type alias.
+ Additionally, the code assumed that `FromStr` was in scope, which is now also not required.
+
+ Thanks goes to @adwhit for reporting and fixing the problem in #186.
+
+## [1.2.0] - 2020-10-01
+
+### Added
+
+* Add `serde_as` macro. Refer to the `serde_with` crate for details.
+* Add two derive macros, `SerializeDisplay` and `DeserializeFromStr`, which implement the `Serialize`/`Deserialize` traits based on `Display` and `FromStr`.
+ This is in addition to the already existing methods like `DisplayFromStr`, which act locally, whereas the derive macros provide the traits expected by the rest of the ecosystem.
+
+### Changed
+
+* Convert the code to use 2018 edition.
+
+### Fixed
+
+* The `serde_as` macro now supports serde attributes and no longer panic on unrecognized values in the attribute.
+
+## [1.2.0-alpha.3] - 2020-08-16
+
+### Added
+
+* Add two derive macros, `SerializeDisplay` and `DeserializeFromStr`, which implement the `Serialize`/`Deserialize` traits based on `Display` and `FromStr`.
+ This is in addition to the already existing methods like `DisplayFromStr`, which act locally, whereas the derive macros provide the traits expected by the rest of the ecosystem.
+
+## [1.2.0-alpha.2] - 2020-08-08
+
+### Fixed
+
+* The `serde_as` macro now supports serde attributes and no longer panic on unrecognized values in the attribute.
+
+## [1.2.0-alpha.1] - 2020-06-27
+
+### Added
+
+* Add `serde_as` macro. Refer to the `serde_with` crate for details.
+
+### Changed
+
+* Convert the code to use 2018 edition.
+
+## [1.1.0] - 2020-01-16
+
+### Changed
+
+* Bump minimal Rust version to 1.36.0 to support Rust Edition 2018
+* Improved CI pipeline by running `cargo audit` and `tarpaulin` in all configurations now.
+
+## [1.0.1] - 2019-04-09
+
+### Fixed
+
+* Features for the `syn` dependency were missing.
+ This was hidden due to the dev-dependencies whose features leaked into the normal build.
+
+## [1.0.0] - 2019-04-02
+
+Initial Release
+
+### Added
+
+* Add `skip_serializing_none` attribute, which adds `#[serde(skip_serializing_if = "Option::is_none")]` for each Option in a struct.
+ This is helpful for APIs which have many optional fields.
+ The effect of can be negated by adding `serialize_always` on those fields, which should always be serialized.
+ Existing `skip_serializing_if` will never be modified and those fields keep their behavior.
diff --git a/third_party/rust/serde_with_macros/Cargo.toml b/third_party/rust/serde_with_macros/Cargo.toml
new file mode 100644
index 0000000000..f7bb663141
--- /dev/null
+++ b/third_party/rust/serde_with_macros/Cargo.toml
@@ -0,0 +1,62 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2018"
+rust-version = "1.46"
+name = "serde_with_macros"
+version = "1.5.2"
+authors = ["Jonas Bushart"]
+include = ["src/**/*", "LICENSE-*", "README.md", "CHANGELOG.md"]
+description = "proc-macro library for serde_with"
+documentation = "https://docs.rs/serde_with_macros/"
+readme = "README.md"
+keywords = ["serde", "utilities", "serialization", "deserialization"]
+categories = ["encoding"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/jonasbb/serde_with/"
+[package.metadata.docs.rs]
+all-features = true
+
+[lib]
+proc-macro = true
+[dependencies.darling]
+version = "0.13.4"
+
+[dependencies.proc-macro2]
+version = "1.0.1"
+
+[dependencies.quote]
+version = "1.0.0"
+
+[dependencies.syn]
+version = "1.0.3"
+features = ["full", "parsing"]
+[dev-dependencies.pretty_assertions]
+version = "1.0.0"
+
+[dev-dependencies.rustversion]
+version = "1.0.0"
+
+[dev-dependencies.serde]
+version = "1.0.75"
+features = ["derive"]
+
+[dev-dependencies.serde_json]
+version = "1.0.25"
+
+[dev-dependencies.trybuild]
+version = "1.0.14"
+
+[dev-dependencies.version-sync]
+version = "0.9.1"
+[badges.maintenance]
+status = "actively-developed"
diff --git a/third_party/rust/serde_with_macros/LICENSE-APACHE b/third_party/rust/serde_with_macros/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/serde_with_macros/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/third_party/rust/serde_with_macros/LICENSE-MIT b/third_party/rust/serde_with_macros/LICENSE-MIT
new file mode 100644
index 0000000000..9203baa055
--- /dev/null
+++ b/third_party/rust/serde_with_macros/LICENSE-MIT
@@ -0,0 +1,25 @@
+Copyright (c) 2015
+
+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.
diff --git a/third_party/rust/serde_with_macros/README.md b/third_party/rust/serde_with_macros/README.md
new file mode 100644
index 0000000000..d9d466e5c9
--- /dev/null
+++ b/third_party/rust/serde_with_macros/README.md
@@ -0,0 +1,186 @@
+# Custom de/serialization functions for Rust's [serde](https://serde.rs)
+
+[![crates.io badge](https://img.shields.io/crates/v/serde_with.svg)](https://crates.io/crates/serde_with/)
+[![Build Status](https://github.com/jonasbb/serde_with/workflows/Rust%20CI/badge.svg)](https://github.com/jonasbb/serde_with)
+[![codecov](https://codecov.io/gh/jonasbb/serde_with/branch/master/graph/badge.svg)](https://codecov.io/gh/jonasbb/serde_with)
+[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/4322/badge)](https://bestpractices.coreinfrastructure.org/projects/4322)
+[![Binder](https://img.shields.io/badge/Try%20on%20-binder-579ACA.svg?logo=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFkAAABZCAMAAABi1XidAAAB8lBMVEX///9XmsrmZYH1olJXmsr1olJXmsrmZYH1olJXmsr1olJXmsrmZYH1olL1olJXmsr1olJXmsrmZYH1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olJXmsrmZYH1olL1olL0nFf1olJXmsrmZYH1olJXmsq8dZb1olJXmsrmZYH1olJXmspXmspXmsr1olL1olJXmsrmZYH1olJXmsr1olL1olJXmsrmZYH1olL1olLeaIVXmsrmZYH1olL1olL1olJXmsrmZYH1olLna31Xmsr1olJXmsr1olJXmsrmZYH1olLqoVr1olJXmsr1olJXmsrmZYH1olL1olKkfaPobXvviGabgadXmsqThKuofKHmZ4Dobnr1olJXmsr1olJXmspXmsr1olJXmsrfZ4TuhWn1olL1olJXmsqBi7X1olJXmspZmslbmMhbmsdemsVfl8ZgmsNim8Jpk8F0m7R4m7F5nLB6jbh7jbiDirOEibOGnKaMhq+PnaCVg6qWg6qegKaff6WhnpKofKGtnomxeZy3noG6dZi+n3vCcpPDcpPGn3bLb4/Mb47UbIrVa4rYoGjdaIbeaIXhoWHmZYHobXvpcHjqdHXreHLroVrsfG/uhGnuh2bwj2Hxk17yl1vzmljzm1j0nlX1olL3AJXWAAAAbXRSTlMAEBAQHx8gICAuLjAwMDw9PUBAQEpQUFBXV1hgYGBkcHBwcXl8gICAgoiIkJCQlJicnJ2goKCmqK+wsLC4usDAwMjP0NDQ1NbW3Nzg4ODi5+3v8PDw8/T09PX29vb39/f5+fr7+/z8/Pz9/v7+zczCxgAABC5JREFUeAHN1ul3k0UUBvCb1CTVpmpaitAGSLSpSuKCLWpbTKNJFGlcSMAFF63iUmRccNG6gLbuxkXU66JAUef/9LSpmXnyLr3T5AO/rzl5zj137p136BISy44fKJXuGN/d19PUfYeO67Znqtf2KH33Id1psXoFdW30sPZ1sMvs2D060AHqws4FHeJojLZqnw53cmfvg+XR8mC0OEjuxrXEkX5ydeVJLVIlV0e10PXk5k7dYeHu7Cj1j+49uKg7uLU61tGLw1lq27ugQYlclHC4bgv7VQ+TAyj5Zc/UjsPvs1sd5cWryWObtvWT2EPa4rtnWW3JkpjggEpbOsPr7F7EyNewtpBIslA7p43HCsnwooXTEc3UmPmCNn5lrqTJxy6nRmcavGZVt/3Da2pD5NHvsOHJCrdc1G2r3DITpU7yic7w/7Rxnjc0kt5GC4djiv2Sz3Fb2iEZg41/ddsFDoyuYrIkmFehz0HR2thPgQqMyQYb2OtB0WxsZ3BeG3+wpRb1vzl2UYBog8FfGhttFKjtAclnZYrRo9ryG9uG/FZQU4AEg8ZE9LjGMzTmqKXPLnlWVnIlQQTvxJf8ip7VgjZjyVPrjw1te5otM7RmP7xm+sK2Gv9I8Gi++BRbEkR9EBw8zRUcKxwp73xkaLiqQb+kGduJTNHG72zcW9LoJgqQxpP3/Tj//c3yB0tqzaml05/+orHLksVO+95kX7/7qgJvnjlrfr2Ggsyx0eoy9uPzN5SPd86aXggOsEKW2Prz7du3VID3/tzs/sSRs2w7ovVHKtjrX2pd7ZMlTxAYfBAL9jiDwfLkq55Tm7ifhMlTGPyCAs7RFRhn47JnlcB9RM5T97ASuZXIcVNuUDIndpDbdsfrqsOppeXl5Y+XVKdjFCTh+zGaVuj0d9zy05PPK3QzBamxdwtTCrzyg/2Rvf2EstUjordGwa/kx9mSJLr8mLLtCW8HHGJc2R5hS219IiF6PnTusOqcMl57gm0Z8kanKMAQg0qSyuZfn7zItsbGyO9QlnxY0eCuD1XL2ys/MsrQhltE7Ug0uFOzufJFE2PxBo/YAx8XPPdDwWN0MrDRYIZF0mSMKCNHgaIVFoBbNoLJ7tEQDKxGF0kcLQimojCZopv0OkNOyWCCg9XMVAi7ARJzQdM2QUh0gmBozjc3Skg6dSBRqDGYSUOu66Zg+I2fNZs/M3/f/Grl/XnyF1Gw3VKCez0PN5IUfFLqvgUN4C0qNqYs5YhPL+aVZYDE4IpUk57oSFnJm4FyCqqOE0jhY2SMyLFoo56zyo6becOS5UVDdj7Vih0zp+tcMhwRpBeLyqtIjlJKAIZSbI8SGSF3k0pA3mR5tHuwPFoa7N7reoq2bqCsAk1HqCu5uvI1n6JuRXI+S1Mco54YmYTwcn6Aeic+kssXi8XpXC4V3t7/ADuTNKaQJdScAAAAAElFTkSuQmCC)](https://mybinder.org/v2/gist/jonasbb/18b9aece4c17f617b1c2b3946d29eeb0/HEAD?filepath=serde-with-demo.ipynb)
+
+---
+
+This crate provides custom de/serialization helpers to use in combination with [serde's with-annotation][with-annotation] and with the improved [`serde_as`][as-annotation]-annotation.
+Some common use cases are:
+
+* De/Serializing a type using the `Display` and `FromStr` traits, e.g., for `u8`, `url::Url`, or `mime::Mime`.
+ Check [`DisplayFromStr`][] or [`serde_with::rust::display_fromstr`][display_fromstr] for details.
+* Support for arrays larger than 32 elements or using const generics.
+ With `serde_as` large arrays are supported, even if they are nested in other types.
+ `[bool; 64]`, `Option<[u8; M]>`, and `Box<[[u8; 64]; N]>` are all supported, as [this examples shows](#large-and-const-generic-arrays).
+* Skip serializing all empty `Option` types with [`#[skip_serializing_none]`][skip_serializing_none].
+* Apply a prefix to each field name of a struct, without changing the de/serialize implementations of the struct using [`with_prefix!`][].
+* Deserialize a comma separated list like `#hash,#tags,#are,#great` into a `Vec<String>`.
+ Check the documentation for [`serde_with::rust::StringWithSeparator::<CommaSeparator>`][StringWithSeparator].
+
+### Getting Help
+
+**Check out the [user guide][user guide] to find out more tips and tricks about this crate.**
+
+For further help using this crate you can [open a new discussion](https://github.com/jonasbb/serde_with/discussions/new) or ask on [users.rust-lang.org](https://users.rust-lang.org/).
+For bugs please open a [new issue](https://github.com/jonasbb/serde_with/issues/new) on Github.
+
+## Use `serde_with` in your Project
+
+Add this to your `Cargo.toml`:
+
+```toml
+[dependencies.serde_with]
+version = "1.12.1"
+features = [ "..." ]
+```
+
+The crate contains different features for integration with other common crates.
+Check the [feature flags][] section for information about all available features.
+
+## Examples
+
+Annotate your struct or enum to enable the custom de/serializer.
+
+### `DisplayFromStr`
+
+```rust
+#[serde_as]
+#[derive(Deserialize, Serialize)]
+struct Foo {
+ // Serialize with Display, deserialize with FromStr
+ #[serde_as(as = "DisplayFromStr")]
+ bar: u8,
+}
+
+// This will serialize
+Foo {bar: 12}
+
+// into this JSON
+{"bar": "12"}
+```
+
+### Large and const-generic arrays
+
+serde does not support arrays with more than 32 elements or using const-generics.
+The `serde_as` attribute allows to circumvent this restriction, even for nested types and nested arrays.
+
+```rust
+#[serde_as]
+#[derive(Deserialize, Serialize)]
+struct Arrays<const N: usize, const M: usize> {
+ #[serde_as(as = "[_; N]")]
+ constgeneric: [bool; N],
+
+ #[serde_as(as = "Box<[[_; 64]; N]>")]
+ nested: Box<[[u8; 64]; N]>,
+
+ #[serde_as(as = "Option<[_; M]>")]
+ optional: Option<[u8; M]>,
+}
+
+// This allows us to serialize a struct like this
+let arrays: Arrays<100, 128> = Arrays {
+ constgeneric: [true; 100],
+ nested: Box::new([[111; 64]; 100]),
+ optional: Some([222; 128])
+};
+assert!(serde_json::to_string(&arrays).is_ok());
+```
+
+### `skip_serializing_none`
+
+This situation often occurs with JSON, but other formats also support optional fields.
+If many fields are optional, putting the annotations on the structs can become tedious.
+
+```rust
+#[skip_serializing_none]
+#[derive(Deserialize, Serialize)]
+struct Foo {
+ a: Option<usize>,
+ b: Option<usize>,
+ c: Option<usize>,
+ d: Option<usize>,
+ e: Option<usize>,
+ f: Option<usize>,
+ g: Option<usize>,
+}
+
+// This will serialize
+Foo {a: None, b: None, c: None, d: Some(4), e: None, f: None, g: Some(7)}
+
+// into this JSON
+{"d": 4, "g": 7}
+```
+
+### Advanced `serde_as` usage
+
+This example is mainly supposed to highlight the flexibility of the `serde_as`-annotation compared to [serde's with-annotation][with-annotation].
+More details about `serde_as` can be found in the [user guide][].
+
+```rust
+#[serde_as]
+#[derive(Deserialize, Serialize)]
+struct Foo {
+ // Serialize them into a list of number as seconds
+ #[serde_as(as = "Vec<DurationSeconds>")]
+ durations: Vec<Duration>,
+ // We can treat a Vec like a map with duplicates.
+ // JSON only allows string keys, so convert i32 to strings
+ // The bytes will be hex encoded
+ #[serde_as(as = "BTreeMap<DisplayFromStr, Hex>")]
+ bytes: Vec<(i32, Vec<u8>)>,
+}
+
+// This will serialize
+Foo {
+ durations: vec![Duration::new(5, 0), Duration::new(3600, 0), Duration::new(0, 0)],
+ bytes: vec![
+ (1, vec![0, 1, 2]),
+ (-100, vec![100, 200, 255]),
+ (1, vec![0, 111, 222]),
+ ],
+}
+
+// into this JSON
+{
+ "durations": [5, 3600, 0],
+ "bytes": {
+ "1": "000102",
+ "-100": "64c8ff",
+ "1": "006fde"
+ }
+}
+```
+
+[`DisplayFromStr`]: https://docs.rs/serde_with/1.12.1/serde_with/struct.DisplayFromStr.html
+[`with_prefix!`]: https://docs.rs/serde_with/1.12.1/serde_with/macro.with_prefix.html
+[display_fromstr]: https://docs.rs/serde_with/1.12.1/serde_with/rust/display_fromstr/index.html
+[feature flags]: https://docs.rs/serde_with/1.12.1/serde_with/guide/feature_flags/index.html
+[skip_serializing_none]: https://docs.rs/serde_with/1.12.1/serde_with/attr.skip_serializing_none.html
+[StringWithSeparator]: https://docs.rs/serde_with/1.12.1/serde_with/rust/struct.StringWithSeparator.html
+[user guide]: https://docs.rs/serde_with/1.12.1/serde_with/guide/index.html
+[with-annotation]: https://serde.rs/field-attrs.html#with
+[as-annotation]: https://docs.rs/serde_with/1.12.1/serde_with/guide/serde_as/index.html
+
+## License
+
+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
+
+For detailed contribution instructions please read [`CONTRIBUTING.md`].
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall
+be dual licensed as above, without any additional terms or conditions.
+
+[`CONTRIBUTING.md`]: https://github.com/jonasbb/serde_with/blob/master/CONTRIBUTING.md
diff --git a/third_party/rust/serde_with_macros/src/lib.rs b/third_party/rust/serde_with_macros/src/lib.rs
new file mode 100644
index 0000000000..9798c13d32
--- /dev/null
+++ b/third_party/rust/serde_with_macros/src/lib.rs
@@ -0,0 +1,1016 @@
+#![forbid(unsafe_code)]
+#![warn(
+ clippy::semicolon_if_nothing_returned,
+ missing_copy_implementations,
+ // missing_crate_level_docs, not available in MSRV
+ missing_debug_implementations,
+ missing_docs,
+ rust_2018_idioms,
+ trivial_casts,
+ trivial_numeric_casts,
+ unused_extern_crates,
+ unused_import_braces,
+ unused_qualifications,
+ variant_size_differences
+)]
+#![doc(test(attr(forbid(unsafe_code))))]
+#![doc(test(attr(deny(
+ missing_copy_implementations,
+ missing_debug_implementations,
+ trivial_casts,
+ trivial_numeric_casts,
+ unused_extern_crates,
+ unused_import_braces,
+ unused_qualifications,
+))))]
+#![doc(test(attr(warn(rust_2018_idioms))))]
+// Not needed for 2018 edition and conflicts with `rust_2018_idioms`
+#![doc(test(no_crate_inject))]
+#![doc(html_root_url = "https://docs.rs/serde_with_macros/1.5.2")]
+// Necessary to silence the warning about clippy::unknown_clippy_lints on nightly
+#![allow(renamed_and_removed_lints)]
+// Necessary for nightly clippy lints
+#![allow(clippy::unknown_clippy_lints)]
+
+//! proc-macro extensions for [`serde_with`].
+//!
+//! This crate should **NEVER** be used alone.
+//! All macros **MUST** be used via the re-exports in the [`serde_with`] crate.
+//!
+//! [`serde_with`]: https://crates.io/crates/serde_with/
+
+#[allow(unused_extern_crates)]
+extern crate proc_macro;
+
+mod utils;
+
+use crate::utils::{split_with_de_lifetime, DeriveOptions, IteratorExt as _};
+use darling::util::Override;
+use darling::{Error as DarlingError, FromField, FromMeta};
+use proc_macro::TokenStream;
+use proc_macro2::{Span, TokenStream as TokenStream2};
+use quote::quote;
+use syn::punctuated::Pair;
+use syn::spanned::Spanned;
+use syn::{
+ parse_macro_input, parse_quote, AttributeArgs, DeriveInput, Error, Field, Fields,
+ GenericArgument, ItemEnum, ItemStruct, Meta, NestedMeta, Path, PathArguments, ReturnType, Type,
+};
+
+/// Apply function on every field of structs or enums
+fn apply_function_to_struct_and_enum_fields<F>(
+ input: TokenStream,
+ function: F,
+) -> Result<TokenStream2, Error>
+where
+ F: Copy,
+ F: Fn(&mut Field) -> Result<(), String>,
+{
+ /// Handle a single struct or a single enum variant
+ fn apply_on_fields<F>(fields: &mut Fields, function: F) -> Result<(), Error>
+ where
+ F: Fn(&mut Field) -> Result<(), String>,
+ {
+ match fields {
+ // simple, no fields, do nothing
+ Fields::Unit => Ok(()),
+ Fields::Named(ref mut fields) => fields
+ .named
+ .iter_mut()
+ .map(|field| function(field).map_err(|err| Error::new(field.span(), err)))
+ .collect_error(),
+ Fields::Unnamed(ref mut fields) => fields
+ .unnamed
+ .iter_mut()
+ .map(|field| function(field).map_err(|err| Error::new(field.span(), err)))
+ .collect_error(),
+ }
+ }
+
+ // For each field in the struct given by `input`, add the `skip_serializing_if` attribute,
+ // if and only if, it is of type `Option`
+ if let Ok(mut input) = syn::parse::<ItemStruct>(input.clone()) {
+ apply_on_fields(&mut input.fields, function)?;
+ Ok(quote!(#input))
+ } else if let Ok(mut input) = syn::parse::<ItemEnum>(input) {
+ input
+ .variants
+ .iter_mut()
+ .map(|variant| apply_on_fields(&mut variant.fields, function))
+ .collect_error()?;
+ Ok(quote!(#input))
+ } else {
+ Err(Error::new(
+ Span::call_site(),
+ "The attribute can only be applied to struct or enum definitions.",
+ ))
+ }
+}
+
+/// Like [apply_function_to_struct_and_enum_fields] but for darling errors
+fn apply_function_to_struct_and_enum_fields_darling<F>(
+ input: TokenStream,
+ serde_with_crate_path: &Path,
+ function: F,
+) -> Result<TokenStream2, DarlingError>
+where
+ F: Copy,
+ F: Fn(&mut Field) -> Result<(), DarlingError>,
+{
+ /// Handle a single struct or a single enum variant
+ fn apply_on_fields<F>(fields: &mut Fields, function: F) -> Result<(), DarlingError>
+ where
+ F: Fn(&mut Field) -> Result<(), DarlingError>,
+ {
+ match fields {
+ // simple, no fields, do nothing
+ Fields::Unit => Ok(()),
+ Fields::Named(ref mut fields) => {
+ let errors: Vec<DarlingError> = fields
+ .named
+ .iter_mut()
+ .map(|field| function(field).map_err(|err| err.with_span(&field)))
+ // turn the Err variant into the Some, such that we only collect errors
+ .filter_map(|res| match res {
+ Err(e) => Some(e),
+ Ok(()) => None,
+ })
+ .collect();
+ if errors.is_empty() {
+ Ok(())
+ } else {
+ Err(DarlingError::multiple(errors))
+ }
+ }
+ Fields::Unnamed(ref mut fields) => {
+ let errors: Vec<DarlingError> = fields
+ .unnamed
+ .iter_mut()
+ .map(|field| function(field).map_err(|err| err.with_span(&field)))
+ // turn the Err variant into the Some, such that we only collect errors
+ .filter_map(|res| match res {
+ Err(e) => Some(e),
+ Ok(()) => None,
+ })
+ .collect();
+ if errors.is_empty() {
+ Ok(())
+ } else {
+ Err(DarlingError::multiple(errors))
+ }
+ }
+ }
+ }
+
+ // Add a dummy derive macro which consumes (makes inert) all field attributes
+ let consume_serde_as_attribute = parse_quote!(
+ #[derive(#serde_with_crate_path::__private_consume_serde_as_attributes)]
+ );
+
+ // For each field in the struct given by `input`, add the `skip_serializing_if` attribute,
+ // if and only if, it is of type `Option`
+ if let Ok(mut input) = syn::parse::<ItemStruct>(input.clone()) {
+ apply_on_fields(&mut input.fields, function)?;
+ input.attrs.push(consume_serde_as_attribute);
+ Ok(quote!(#input))
+ } else if let Ok(mut input) = syn::parse::<ItemEnum>(input) {
+ let errors: Vec<DarlingError> = input
+ .variants
+ .iter_mut()
+ .map(|variant| apply_on_fields(&mut variant.fields, function))
+ // turn the Err variant into the Some, such that we only collect errors
+ .filter_map(|res| match res {
+ Err(e) => Some(e),
+ Ok(()) => None,
+ })
+ .collect();
+ if errors.is_empty() {
+ input.attrs.push(consume_serde_as_attribute);
+ Ok(quote!(#input))
+ } else {
+ Err(DarlingError::multiple(errors))
+ }
+ } else {
+ Err(DarlingError::custom(
+ "The attribute can only be applied to struct or enum definitions.",
+ )
+ .with_span(&Span::call_site()))
+ }
+}
+
+/// Add `skip_serializing_if` annotations to [`Option`] fields.
+///
+/// The attribute can be added to structs and enums.
+///
+/// Import this attribute with `use serde_with::skip_serializing_none;`.
+///
+/// # Example
+///
+/// JSON APIs sometimes have many optional values.
+/// Missing values should not be serialized, to keep the serialized format smaller.
+/// Such a data type might look like:
+///
+/// ```rust
+/// # use serde::Serialize;
+/// #
+/// #[derive(Serialize)]
+/// struct Data {
+/// #[serde(skip_serializing_if = "Option::is_none")]
+/// a: Option<String>,
+/// #[serde(skip_serializing_if = "Option::is_none")]
+/// b: Option<u64>,
+/// #[serde(skip_serializing_if = "Option::is_none")]
+/// c: Option<String>,
+/// #[serde(skip_serializing_if = "Option::is_none")]
+/// d: Option<bool>,
+/// }
+/// ```
+///
+/// The `skip_serializing_if` annotation is repetitive and harms readability.
+/// Instead, the same struct can be written as:
+///
+/// ```rust
+/// # use serde::Serialize;
+/// # use serde_with_macros::skip_serializing_none;
+/// #[skip_serializing_none]
+/// #[derive(Serialize)]
+/// struct Data {
+/// a: Option<String>,
+/// b: Option<u64>,
+/// c: Option<String>,
+/// // Always serialize field d even if None
+/// #[serialize_always]
+/// d: Option<bool>,
+/// }
+/// ```
+///
+/// Existing `skip_serializing_if` annotations will not be altered.
+///
+/// If some values should always be serialized, then the `serialize_always` can be used.
+///
+/// # Limitations
+///
+/// The `serialize_always` cannot be used together with a manual `skip_serializing_if` annotations, as these conflict in their meaning.
+/// A compile error will be generated if this occurs.
+///
+/// The `skip_serializing_none` only works if the type is called [`Option`], [`std::option::Option`], or [`core::option::Option`].
+/// Type aliasing an [`Option`] and giving it another name, will cause this field to be ignored.
+/// This cannot be supported, as proc-macros run before type checking, thus it is not possible to determine if a type alias refers to an [`Option`].
+///
+/// ```rust
+/// # use serde::Serialize;
+/// # use serde_with_macros::skip_serializing_none;
+/// type MyOption<T> = Option<T>;
+///
+/// #[skip_serializing_none]
+/// #[derive(Serialize)]
+/// struct Data {
+/// a: MyOption<String>, // This field will not be skipped
+/// }
+/// ```
+///
+/// Likewise, if you import a type and name it `Option`, the `skip_serializing_if` attributes will be added and compile errors will occur, if `Option::is_none` is not a valid function.
+/// Here the function `Vec::is_none` does not exist and therefore the example fails to compile.
+///
+/// ```rust,compile_fail
+/// # use serde::Serialize;
+/// # use serde_with_macros::skip_serializing_none;
+/// use std::vec::Vec as Option;
+///
+/// #[skip_serializing_none]
+/// #[derive(Serialize)]
+/// struct Data {
+/// a: Option<String>,
+/// }
+/// ```
+#[proc_macro_attribute]
+pub fn skip_serializing_none(_args: TokenStream, input: TokenStream) -> TokenStream {
+ let res = match apply_function_to_struct_and_enum_fields(
+ input,
+ skip_serializing_none_add_attr_to_field,
+ ) {
+ Ok(res) => res,
+ Err(err) => err.to_compile_error(),
+ };
+ TokenStream::from(res)
+}
+
+/// Add the skip_serializing_if annotation to each field of the struct
+fn skip_serializing_none_add_attr_to_field(field: &mut Field) -> Result<(), String> {
+ if let Type::Path(path) = &field.ty {
+ if is_std_option(&path.path) {
+ let has_skip_serializing_if =
+ field_has_attribute(field, "serde", "skip_serializing_if");
+
+ // Remove the `serialize_always` attribute
+ let mut has_always_attr = false;
+ field.attrs.retain(|attr| {
+ let has_attr = attr.path.is_ident("serialize_always");
+ has_always_attr |= has_attr;
+ !has_attr
+ });
+
+ // Error on conflicting attributes
+ if has_always_attr && has_skip_serializing_if {
+ let mut msg = r#"The attributes `serialize_always` and `serde(skip_serializing_if = "...")` cannot be used on the same field"#.to_string();
+ if let Some(ident) = &field.ident {
+ msg += ": `";
+ msg += &ident.to_string();
+ msg += "`";
+ }
+ msg += ".";
+ return Err(msg);
+ }
+
+ // Do nothing if `skip_serializing_if` or `serialize_always` is already present
+ if has_skip_serializing_if || has_always_attr {
+ return Ok(());
+ }
+
+ // Add the `skip_serializing_if` attribute
+ let attr = parse_quote!(
+ #[serde(skip_serializing_if = "Option::is_none")]
+ );
+ field.attrs.push(attr);
+ } else {
+ // Warn on use of `serialize_always` on non-Option fields
+ let has_attr = field
+ .attrs
+ .iter()
+ .any(|attr| attr.path.is_ident("serialize_always"));
+ if has_attr {
+ return Err(
+ "`serialize_always` may only be used on fields of type `Option`.".into(),
+ );
+ }
+ }
+ }
+ Ok(())
+}
+
+/// Return `true`, if the type path refers to `std::option::Option`
+///
+/// Accepts
+///
+/// * `Option`
+/// * `std::option::Option`, with or without leading `::`
+/// * `core::option::Option`, with or without leading `::`
+fn is_std_option(path: &Path) -> bool {
+ (path.leading_colon.is_none() && path.segments.len() == 1 && path.segments[0].ident == "Option")
+ || (path.segments.len() == 3
+ && (path.segments[0].ident == "std" || path.segments[0].ident == "core")
+ && path.segments[1].ident == "option"
+ && path.segments[2].ident == "Option")
+}
+
+/// Determine if the `field` has an attribute with given `namespace` and `name`
+///
+/// On the example of
+/// `#[serde(skip_serializing_if = "Option::is_none")]`
+///
+/// * `serde` is the outermost path, here namespace
+/// * it contains a Meta::List
+/// * which contains in another Meta a Meta::NameValue
+/// * with the name being `skip_serializing_if`
+fn field_has_attribute(field: &Field, namespace: &str, name: &str) -> bool {
+ for attr in &field.attrs {
+ if attr.path.is_ident(namespace) {
+ // Ignore non parsable attributes, as these are not important for us
+ if let Ok(Meta::List(expr)) = attr.parse_meta() {
+ for expr in expr.nested {
+ if let NestedMeta::Meta(Meta::NameValue(expr)) = expr {
+ if let Some(ident) = expr.path.get_ident() {
+ if *ident == name {
+ return true;
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ false
+}
+
+/// Convenience macro to use the [`serde_as`] system.
+///
+/// The [`serde_as`] system is designed as a more flexible alternative to serde's with-annotation.
+///
+/// # Example
+///
+/// ```rust,ignore
+/// use serde_with::{serde_as, DisplayFromStr};
+/// use std::collections::HashMap;
+///
+/// #[serde_as]
+/// #[derive(Serialize, Deserialize)]
+/// struct Data {
+/// /// Serialize into number
+/// #[serde_as(as = "_")]
+/// a: u32,
+///
+/// /// Serialize into String
+/// #[serde_as(as = "DisplayFromStr")]
+/// b: u32,
+///
+/// /// Serialize into a map from String to String
+/// #[serde_as(as = "HashMap<DisplayFromStr, _>")]
+/// c: Vec<(u32, String)>,
+/// }
+/// ```
+///
+/// # Alternative path to `serde_with` crate
+///
+/// If `serde_with` is not available at the default path, its path should be specified with the
+/// `crate` argument. See [re-exporting `serde_as`] for more use case information.
+///
+/// ```rust,ignore
+/// #[serde_as(crate = "::some_other_lib::serde_with")]
+/// #[derive(Deserialize)]
+/// struct Data {
+/// #[serde_as(as = "_")]
+/// a: u32,
+/// }
+/// ```
+///
+/// # What this macro does
+///
+/// The `serde_as` macro only serves a convenience function.
+/// All the steps it performs, can easily be done manually, in case the cost of an attribute macro is deemed to high.
+/// The functionality can best be described with an example.
+///
+/// ```rust,ignore
+/// #[serde_as]
+/// #[derive(serde::Serialize)]
+/// struct Foo {
+/// #[serde_as(as = "Vec<_>")]
+/// bar: Vec<u32>,
+/// }
+/// ```
+///
+/// 1. All the placeholder type `_` will be replaced with `::serde_with::Same`.
+/// The placeholder type `_` marks all the places where the types `Serialize` implementation should be used.
+/// In the example, it means that the `u32` values will serialize with the `Serialize` implementation of `u32`.
+/// The `Same` type implements `SerializeAs` whenever the underlying type implements `Serialize` and is used to make the two traits compatible.
+///
+/// If you specify a custom path for `serde_with` via the `crate` attribute, the path to the `Same` type will be altered accordingly.
+/// 2. Wrap the type from the annotation inside a `::serde_with::As`.
+/// In the above example we know have something like `::serde_with::As::<Vec<::serde_with::Same>>`.
+/// The `As` type acts as the opposite of the `Same` type.
+/// It allows using a `SerializeAs` type whenever a `Serialize` is required.
+/// 3. Translate the `*as` attributes into the serde equivalent ones.
+/// `#[serde_as(as = ...)]` will become `#[serde(with = ...)]`.
+/// Similarly, `serialize_as` is translated to `serialize_with`.
+///
+/// The field attributes will be kept on the struct/enum such that other macros can use them too.
+/// 4. It searches `#[serde_as(as = ...)]` if there is a type named `BorrowCow` under any path.
+/// If `BorrowCow` is found, the attribute `#[serde(borrow)]` is added to the field.
+/// If `#[serde(borrow)]` or `#[serde(borrow = "...")]` is already present, this step will be skipped.
+///
+/// After all these steps, the code snippet will have transformed into roughly this.
+///
+/// ```rust,ignore
+/// #[derive(serde::Serialize)]
+/// struct Foo {
+/// #[serde_as(as = "Vec<_>")]
+/// #[serde(with = "::serde_with::As::<Vec<::serde_with::Same>>")]
+/// bar: Vec<u32>,
+/// }
+/// ```
+///
+/// [`serde_as`]: https://docs.rs/serde_with/1.12.1/serde_with/guide/index.html
+/// [re-exporting `serde_as`]: https://docs.rs/serde_with/1.12.1/serde_with/guide/serde_as/index.html#re-exporting-serde_as
+#[proc_macro_attribute]
+pub fn serde_as(args: TokenStream, input: TokenStream) -> TokenStream {
+ #[derive(FromMeta, Debug)]
+ struct SerdeContainerOptions {
+ #[darling(rename = "crate", default)]
+ alt_crate_path: Option<String>,
+ }
+
+ let args: AttributeArgs = parse_macro_input!(args);
+ let container_options = match SerdeContainerOptions::from_list(&args) {
+ Ok(v) => v,
+ Err(e) => {
+ return TokenStream::from(e.write_errors());
+ }
+ };
+
+ let serde_with_crate_path = container_options
+ .alt_crate_path
+ .as_deref()
+ .unwrap_or("::serde_with");
+ let serde_with_crate_path = match syn::parse_str(serde_with_crate_path) {
+ Ok(path) => path,
+ Err(err) => return TokenStream::from(DarlingError::from(err).write_errors()),
+ };
+
+ // Convert any error message into a nice compiler error
+ let res = match apply_function_to_struct_and_enum_fields_darling(
+ input,
+ &serde_with_crate_path,
+ |field| serde_as_add_attr_to_field(field, &serde_with_crate_path),
+ ) {
+ Ok(res) => res,
+ Err(err) => err.write_errors(),
+ };
+ TokenStream::from(res)
+}
+
+/// Inspect the field and convert the `serde_as` attribute into the classical `serde`
+fn serde_as_add_attr_to_field(
+ field: &mut Field,
+ serde_with_crate_path: &Path,
+) -> Result<(), DarlingError> {
+ #[derive(FromField, Debug)]
+ #[darling(attributes(serde_as))]
+ struct SerdeAsOptions {
+ #[darling(rename = "as", default)]
+ r#as: Option<Type>,
+ #[darling(default)]
+ deserialize_as: Option<Type>,
+ #[darling(default)]
+ serialize_as: Option<Type>,
+ }
+
+ impl SerdeAsOptions {
+ fn has_any_set(&self) -> bool {
+ self.r#as.is_some() || self.deserialize_as.is_some() || self.serialize_as.is_some()
+ }
+ }
+
+ #[derive(FromField, Debug)]
+ #[darling(attributes(serde), allow_unknown_fields)]
+ struct SerdeOptions {
+ #[darling(default)]
+ with: Option<String>,
+ #[darling(default)]
+ deserialize_with: Option<String>,
+ #[darling(default)]
+ serialize_with: Option<String>,
+
+ #[darling(default)]
+ borrow: Option<Override<String>>,
+ }
+
+ impl SerdeOptions {
+ fn has_any_set(&self) -> bool {
+ self.with.is_some() || self.deserialize_with.is_some() || self.serialize_with.is_some()
+ }
+ }
+
+ // Check if there even is any `serde_as` attribute and exit early if not.
+ if !field
+ .attrs
+ .iter()
+ .any(|attr| attr.path.is_ident("serde_as"))
+ {
+ return Ok(());
+ }
+ let serde_as_options = SerdeAsOptions::from_field(field)?;
+ let serde_options = SerdeOptions::from_field(field)?;
+
+ let mut errors = Vec::new();
+ if !serde_as_options.has_any_set() {
+ errors.push(DarlingError::custom("An empty `serde_as` attribute on a field has no effect. You are missing an `as`, `serialize_as`, or `deserialize_as` parameter."));
+ }
+
+ // Check if there are any conflicting attributes
+ if serde_as_options.has_any_set() && serde_options.has_any_set() {
+ errors.push(DarlingError::custom("Cannot combine `serde_as` with serde's `with`, `deserialize_with`, or `serialize_with`."));
+ }
+
+ if serde_as_options.r#as.is_some() && serde_as_options.deserialize_as.is_some() {
+ errors.push(DarlingError::custom("Cannot combine `as` with `deserialize_as`. Use `serialize_as` to specify different serialization code."));
+ } else if serde_as_options.r#as.is_some() && serde_as_options.serialize_as.is_some() {
+ errors.push(DarlingError::custom("Cannot combine `as` with `serialize_as`. Use `deserialize_as` to specify different deserialization code."));
+ }
+
+ if !errors.is_empty() {
+ return Err(DarlingError::multiple(errors));
+ }
+
+ let type_same = &syn::parse_quote!(#serde_with_crate_path::Same);
+ let type_borrowcow = &syn::parse_quote!(BorrowCow);
+ if let Some(type_) = serde_as_options.r#as {
+ // If the field is not borrowed yet, check if we need to borrow it.
+ if serde_options.borrow.is_none() && has_type_embedded(&type_, type_borrowcow) {
+ let attr_borrow = parse_quote!(#[serde(borrow)]);
+ field.attrs.push(attr_borrow);
+ }
+
+ let replacement_type = replace_infer_type_with_type(type_, type_same);
+ let attr_inner_tokens = quote!(#serde_with_crate_path::As::<#replacement_type>).to_string();
+ let attr = parse_quote!(#[serde(with = #attr_inner_tokens)]);
+ field.attrs.push(attr);
+ }
+ if let Some(type_) = serde_as_options.deserialize_as {
+ // If the field is not borrowed yet, check if we need to borrow it.
+ if serde_options.borrow.is_none() && has_type_embedded(&type_, type_borrowcow) {
+ let attr_borrow = parse_quote!(#[serde(borrow)]);
+ field.attrs.push(attr_borrow);
+ }
+
+ let replacement_type = replace_infer_type_with_type(type_, type_same);
+ let attr_inner_tokens =
+ quote!(#serde_with_crate_path::As::<#replacement_type>::deserialize).to_string();
+ let attr = parse_quote!(#[serde(deserialize_with = #attr_inner_tokens)]);
+ field.attrs.push(attr);
+ }
+ if let Some(type_) = serde_as_options.serialize_as {
+ let replacement_type = replace_infer_type_with_type(type_, type_same);
+ let attr_inner_tokens =
+ quote!(#serde_with_crate_path::As::<#replacement_type>::serialize).to_string();
+ let attr = parse_quote!(#[serde(serialize_with = #attr_inner_tokens)]);
+ field.attrs.push(attr);
+ }
+
+ Ok(())
+}
+
+/// Recursively replace all occurrences of `_` with `replacement` in a [Type][]
+///
+/// The [serde_as][macro@serde_as] macro allows to use the infer type, i.e., `_`, as shortcut for `serde_with::As`.
+/// This function replaces all occurrences of the infer type with another type.
+fn replace_infer_type_with_type(to_replace: Type, replacement: &Type) -> Type {
+ match to_replace {
+ // Base case
+ // Replace the infer type with the actual replacement type
+ Type::Infer(_) => replacement.clone(),
+
+ // Recursive cases
+ // Iterate through all positions where a type could occur and recursively call this function
+ Type::Array(mut inner) => {
+ *inner.elem = replace_infer_type_with_type(*inner.elem, replacement);
+ Type::Array(inner)
+ }
+ Type::Group(mut inner) => {
+ *inner.elem = replace_infer_type_with_type(*inner.elem, replacement);
+ Type::Group(inner)
+ }
+ Type::Never(inner) => Type::Never(inner),
+ Type::Paren(mut inner) => {
+ *inner.elem = replace_infer_type_with_type(*inner.elem, replacement);
+ Type::Paren(inner)
+ }
+ Type::Path(mut inner) => {
+ match inner.path.segments.pop() {
+ Some(Pair::End(mut t)) | Some(Pair::Punctuated(mut t, _)) => {
+ t.arguments = match t.arguments {
+ PathArguments::None => PathArguments::None,
+ PathArguments::AngleBracketed(mut inner) => {
+ // Iterate over the args between the angle brackets
+ inner.args = inner
+ .args
+ .into_iter()
+ .map(|generic_argument| match generic_argument {
+ // replace types within the generics list, but leave other stuff like lifetimes untouched
+ GenericArgument::Type(type_) => GenericArgument::Type(
+ replace_infer_type_with_type(type_, replacement),
+ ),
+ ga => ga,
+ })
+ .collect();
+ PathArguments::AngleBracketed(inner)
+ }
+ PathArguments::Parenthesized(mut inner) => {
+ inner.inputs = inner
+ .inputs
+ .into_iter()
+ .map(|type_| replace_infer_type_with_type(type_, replacement))
+ .collect();
+ inner.output = match inner.output {
+ ReturnType::Type(arrow, mut type_) => {
+ *type_ = replace_infer_type_with_type(*type_, replacement);
+ ReturnType::Type(arrow, type_)
+ }
+ default => default,
+ };
+ PathArguments::Parenthesized(inner)
+ }
+ };
+ inner.path.segments.push(t);
+ }
+ None => {}
+ }
+ Type::Path(inner)
+ }
+ Type::Ptr(mut inner) => {
+ *inner.elem = replace_infer_type_with_type(*inner.elem, replacement);
+ Type::Ptr(inner)
+ }
+ Type::Reference(mut inner) => {
+ *inner.elem = replace_infer_type_with_type(*inner.elem, replacement);
+ Type::Reference(inner)
+ }
+ Type::Slice(mut inner) => {
+ *inner.elem = replace_infer_type_with_type(*inner.elem, replacement);
+ Type::Slice(inner)
+ }
+ Type::Tuple(mut inner) => {
+ inner.elems = inner
+ .elems
+ .into_pairs()
+ .map(|pair| match pair {
+ Pair::Punctuated(type_, p) => {
+ Pair::Punctuated(replace_infer_type_with_type(type_, replacement), p)
+ }
+ Pair::End(type_) => Pair::End(replace_infer_type_with_type(type_, replacement)),
+ })
+ .collect();
+ Type::Tuple(inner)
+ }
+
+ // Pass unknown types or non-handleable types (e.g., bare Fn) without performing any replacements
+ type_ => type_,
+ }
+}
+
+/// Check if a type ending in the `syn::Ident` `embedded_type` is contained in `type_`.
+fn has_type_embedded(type_: &Type, embedded_type: &syn::Ident) -> bool {
+ match type_ {
+ // Base cases
+ Type::Infer(_) => false,
+ Type::Never(_inner) => false,
+
+ // Recursive cases
+ // Iterate through all positions where a type could occur and recursively call this function
+ Type::Array(inner) => has_type_embedded(&inner.elem, embedded_type),
+ Type::Group(inner) => has_type_embedded(&inner.elem, embedded_type),
+ Type::Paren(inner) => has_type_embedded(&inner.elem, embedded_type),
+ Type::Path(inner) => {
+ match inner.path.segments.last() {
+ Some(t) => {
+ if t.ident == *embedded_type {
+ return true;
+ }
+
+ match &t.arguments {
+ PathArguments::None => false,
+ PathArguments::AngleBracketed(inner) => {
+ // Iterate over the args between the angle brackets
+ inner
+ .args
+ .iter()
+ .any(|generic_argument| match generic_argument {
+ // replace types within the generics list, but leave other stuff like lifetimes untouched
+ GenericArgument::Type(type_) => {
+ has_type_embedded(type_, embedded_type)
+ }
+ _ga => false,
+ })
+ }
+ PathArguments::Parenthesized(inner) => {
+ inner
+ .inputs
+ .iter()
+ .any(|type_| has_type_embedded(type_, embedded_type))
+ || match &inner.output {
+ ReturnType::Type(_arrow, type_) => {
+ has_type_embedded(type_, embedded_type)
+ }
+ _default => false,
+ }
+ }
+ }
+ }
+ None => false,
+ }
+ }
+ Type::Ptr(inner) => has_type_embedded(&inner.elem, embedded_type),
+ Type::Reference(inner) => has_type_embedded(&inner.elem, embedded_type),
+ Type::Slice(inner) => has_type_embedded(&inner.elem, embedded_type),
+ Type::Tuple(inner) => inner.elems.pairs().any(|pair| match pair {
+ Pair::Punctuated(type_, _) | Pair::End(type_) => {
+ has_type_embedded(type_, embedded_type)
+ }
+ }),
+
+ // Pass unknown types or non-handleable types (e.g., bare Fn) without performing any replacements
+ _type_ => false,
+ }
+}
+
+/// Deserialize value by using its [`FromStr`] implementation
+///
+/// This is an alternative way to implement `Deserialize` for types which also implement [`FromStr`] by deserializing the type from string.
+/// Ensure that the struct/enum also implements [`FromStr`].
+/// If the implementation is missing, you will get an error message like
+/// ```text
+/// error[E0277]: the trait bound `Struct: std::str::FromStr` is not satisfied
+/// ```
+/// Additionally, `FromStr::Err` **must** implement [`Display`] as otherwise you will see a rather unhelpful error message
+///
+/// Serialization with [`Display`] is available with the matching [`SerializeDisplay`] derive.
+///
+/// # Attributes
+///
+/// Attributes for the derive can be specified via the `#[serde_with(...)]` attribute on the struct or enum.
+/// Currently, these arguments to the attribute are possible:
+///
+/// * **`#[serde_with(crate = "...")]`**: This allows using `DeserializeFromStr` when `serde_with` is not available from the crate root.
+/// This happens while [renaming dependencies in Cargo.toml][cargo-toml-rename] or when re-exporting the macro from a different crate.
+///
+/// This argument is analogue to [serde's crate argument][serde-crate] and the [crate argument to `serde_as`][serde-as-crate].
+///
+/// # Example
+///
+/// ```rust,ignore
+/// use std::str::FromStr;
+///
+/// #[derive(DeserializeFromStr)]
+/// struct A {
+/// a: u32,
+/// b: bool,
+/// }
+///
+/// impl FromStr for A {
+/// type Err = String;
+///
+/// /// Parse a value like `123<>true`
+/// fn from_str(s: &str) -> Result<Self, Self::Err> {
+/// let mut parts = s.split("<>");
+/// let number = parts
+/// .next()
+/// .ok_or_else(|| "Missing first value".to_string())?
+/// .parse()
+/// .map_err(|err: ParseIntError| err.to_string())?;
+/// let bool = parts
+/// .next()
+/// .ok_or_else(|| "Missing second value".to_string())?
+/// .parse()
+/// .map_err(|err: ParseBoolError| err.to_string())?;
+/// Ok(Self { a: number, b: bool })
+/// }
+/// }
+///
+/// let a: A = serde_json::from_str("\"159<>true\"").unwrap();
+/// assert_eq!(A { a: 159, b: true }, a);
+/// ```
+///
+/// [`Display`]: std::fmt::Display
+/// [`FromStr`]: std::str::FromStr
+/// [cargo-toml-rename]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml
+/// [serde-as-crate]: https://docs.rs/serde_with/1.12.1/serde_with/guide/serde_as/index.html#re-exporting-serde_as
+/// [serde-crate]: https://serde.rs/container-attrs.html#crate
+#[proc_macro_derive(DeserializeFromStr, attributes(serde_with))]
+pub fn derive_deserialize_fromstr(item: TokenStream) -> TokenStream {
+ let input: DeriveInput = parse_macro_input!(item);
+ let derive_options = match DeriveOptions::from_derive_input(&input) {
+ Ok(opt) => opt,
+ Err(err) => {
+ return err;
+ }
+ };
+ TokenStream::from(deserialize_fromstr(
+ input,
+ derive_options.get_serde_with_path(),
+ ))
+}
+
+fn deserialize_fromstr(mut input: DeriveInput, serde_with_crate_path: Path) -> TokenStream2 {
+ let ident = input.ident;
+ let where_clause = &mut input.generics.make_where_clause().predicates;
+ where_clause.push(parse_quote!(Self: ::std::str::FromStr));
+ where_clause.push(parse_quote!(
+ <Self as ::std::str::FromStr>::Err: ::std::fmt::Display
+ ));
+ let (de_impl_generics, ty_generics, where_clause) = split_with_de_lifetime(&input.generics);
+ quote! {
+ #[automatically_derived]
+ impl #de_impl_generics #serde_with_crate_path::serde::Deserialize<'de> for #ident #ty_generics #where_clause {
+ fn deserialize<D>(deserializer: D) -> ::std::result::Result<Self, D::Error>
+ where
+ D: #serde_with_crate_path::serde::Deserializer<'de>,
+ {
+ struct Helper<S>(::std::marker::PhantomData<S>);
+
+ impl<'de, S> #serde_with_crate_path::serde::de::Visitor<'de> for Helper<S>
+ where
+ S: ::std::str::FromStr,
+ <S as ::std::str::FromStr>::Err: ::std::fmt::Display,
+ {
+ type Value = S;
+
+ fn expecting(&self, formatter: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
+ ::std::write!(formatter, "string")
+ }
+
+ fn visit_str<E>(self, value: &str) -> ::std::result::Result<Self::Value, E>
+ where
+ E: #serde_with_crate_path::serde::de::Error,
+ {
+ value.parse::<Self::Value>().map_err(#serde_with_crate_path::serde::de::Error::custom)
+ }
+
+ fn visit_bytes<E>(self, value: &[u8]) -> ::std::result::Result<Self::Value, E>
+ where
+ E: #serde_with_crate_path::serde::de::Error,
+ {
+ let utf8 = ::std::str::from_utf8(value).map_err(#serde_with_crate_path::serde::de::Error::custom)?;
+ self.visit_str(utf8)
+ }
+ }
+
+ deserializer.deserialize_str(Helper(::std::marker::PhantomData))
+ }
+ }
+ }
+}
+
+/// Serialize value by using it's [`Display`] implementation
+///
+/// This is an alternative way to implement `Serialize` for types which also implement [`Display`] by serializing the type as string.
+/// Ensure that the struct/enum also implements [`Display`].
+/// If the implementation is missing, you will get an error message like
+/// ```text
+/// error[E0277]: `Struct` doesn't implement `std::fmt::Display`
+/// ```
+///
+/// Deserialization with [`FromStr`] is available with the matching [`DeserializeFromStr`] derive.
+///
+/// # Attributes
+///
+/// Attributes for the derive can be specified via the `#[serde_with(...)]` attribute on the struct or enum.
+/// Currently, these arguments to the attribute are possible:
+///
+/// * **`#[serde_with(crate = "...")]`**: This allows using `SerializeDisplay` when `serde_with` is not available from the crate root.
+/// This happens while [renaming dependencies in Cargo.toml][cargo-toml-rename] or when re-exporting the macro from a different crate.
+///
+/// This argument is analogue to [serde's crate argument][serde-crate] and the [crate argument to `serde_as`][serde-as-crate].
+///
+/// # Example
+///
+/// ```rust,ignore
+/// use std::fmt;
+///
+/// #[derive(SerializeDisplay)]
+/// struct A {
+/// a: u32,
+/// b: bool,
+/// }
+///
+/// impl fmt::Display for A {
+/// fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+/// write!(f, "{}<>{}", self.a, self.b)
+/// }
+/// }
+///
+/// let a = A { a: 123, b: false };
+/// assert_eq!(r#""123<>false""#, serde_json::to_string(&a).unwrap());
+/// ```
+///
+/// [`Display`]: std::fmt::Display
+/// [`FromStr`]: std::str::FromStr
+/// [cargo-toml-rename]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml
+/// [serde-as-crate]: https://docs.rs/serde_with/1.12.1/serde_with/guide/serde_as/index.html#re-exporting-serde_as
+/// [serde-crate]: https://serde.rs/container-attrs.html#crate
+#[proc_macro_derive(SerializeDisplay, attributes(serde_with))]
+pub fn derive_serialize_display(item: TokenStream) -> TokenStream {
+ let input: DeriveInput = parse_macro_input!(item);
+ let derive_options = match DeriveOptions::from_derive_input(&input) {
+ Ok(opt) => opt,
+ Err(err) => {
+ return err;
+ }
+ };
+ TokenStream::from(serialize_display(
+ input,
+ derive_options.get_serde_with_path(),
+ ))
+}
+
+fn serialize_display(mut input: DeriveInput, serde_with_crate_path: Path) -> TokenStream2 {
+ let ident = input.ident;
+ input
+ .generics
+ .make_where_clause()
+ .predicates
+ .push(parse_quote!(Self: ::std::fmt::Display));
+ let (impl_generics, ty_generics, where_clause) = input.generics.split_for_impl();
+ quote! {
+ #[automatically_derived]
+ impl #impl_generics #serde_with_crate_path::serde::Serialize for #ident #ty_generics #where_clause {
+ fn serialize<S>(&self, serializer: S) -> ::std::result::Result<S::Ok, S::Error>
+ where
+ S: #serde_with_crate_path::serde::Serializer,
+ {
+ serializer.collect_str(&self)
+ }
+ }
+ }
+}
+
+#[doc(hidden)]
+/// Private function. Not part of the public API
+///
+/// The only task of this derive macro is to consume any `serde_as` attributes and turn them into inert attributes.
+/// This allows the serde_as macro to keep the field attributes without causing compiler errors.
+/// The intend is that keeping the field attributes allows downstream crates to consume and act on them without causing an ordering dependency to the serde_as macro.
+/// Otherwise, downstream proc-macros would need to be placed *in front of* the main `#[serde_as]` attribute, since otherwise the field attributes would already be stripped off.
+///
+/// More details about the use-cases in the Github discussion: <https://github.com/jonasbb/serde_with/discussions/260>.
+#[proc_macro_derive(__private_consume_serde_as_attributes, attributes(serde_as))]
+pub fn __private_consume_serde_as_attributes(_: TokenStream) -> TokenStream {
+ TokenStream::new()
+}
diff --git a/third_party/rust/serde_with_macros/src/utils.rs b/third_party/rust/serde_with_macros/src/utils.rs
new file mode 100644
index 0000000000..d7a380af63
--- /dev/null
+++ b/third_party/rust/serde_with_macros/src/utils.rs
@@ -0,0 +1,77 @@
+use darling::FromDeriveInput;
+use proc_macro::TokenStream;
+use proc_macro2::TokenStream as TokenStream2;
+use quote::ToTokens;
+use std::iter::Iterator;
+use syn::{parse_quote, Error, Generics, Path, TypeGenerics};
+
+/// Merge multiple [`syn::Error`] into one.
+pub(crate) trait IteratorExt {
+ fn collect_error(self) -> Result<(), Error>
+ where
+ Self: Iterator<Item = Result<(), Error>> + Sized,
+ {
+ let accu = Ok(());
+ self.fold(accu, |accu, error| match (accu, error) {
+ (Ok(()), error) => error,
+ (accu, Ok(())) => accu,
+ (Err(mut err), Err(error)) => {
+ err.combine(error);
+ Err(err)
+ }
+ })
+ }
+}
+impl<I> IteratorExt for I where I: Iterator<Item = Result<(), Error>> + Sized {}
+
+/// Attributes usable for derive macros
+#[derive(FromDeriveInput, Debug)]
+#[darling(attributes(serde_with))]
+pub(crate) struct DeriveOptions {
+ /// Path to the crate
+ #[darling(rename = "crate", default)]
+ pub(crate) alt_crate_path: Option<Path>,
+}
+
+impl DeriveOptions {
+ pub(crate) fn from_derive_input(input: &syn::DeriveInput) -> Result<Self, TokenStream> {
+ match <Self as FromDeriveInput>::from_derive_input(input) {
+ Ok(v) => Ok(v),
+ Err(e) => Err(TokenStream::from(e.write_errors())),
+ }
+ }
+
+ pub(crate) fn get_serde_with_path(&self) -> Path {
+ self.alt_crate_path
+ .clone()
+ .unwrap_or_else(|| syn::parse_str("::serde_with").unwrap())
+ }
+}
+
+// Inspired by https://github.com/serde-rs/serde/blob/fb2fe409c8f7ad6c95e3096e5e9ede865c8cfb49/serde_derive/src/de.rs#L3120
+// Serde is also licences Apache 2 + MIT
+pub(crate) fn split_with_de_lifetime(
+ generics: &Generics,
+) -> (
+ DeImplGenerics<'_>,
+ TypeGenerics<'_>,
+ Option<&syn::WhereClause>,
+) {
+ let de_impl_generics = DeImplGenerics(generics);
+ let (_, ty_generics, where_clause) = generics.split_for_impl();
+ (de_impl_generics, ty_generics, where_clause)
+}
+
+pub(crate) struct DeImplGenerics<'a>(&'a Generics);
+
+impl<'a> ToTokens for DeImplGenerics<'a> {
+ fn to_tokens(&self, tokens: &mut TokenStream2) {
+ let mut generics = self.0.clone();
+ generics.params = Some(parse_quote!('de))
+ .into_iter()
+ .chain(generics.params)
+ .collect();
+ let (impl_generics, _, _) = generics.split_for_impl();
+ impl_generics.to_tokens(tokens);
+ }
+}
diff --git a/third_party/rust/serde_yaml/.cargo-checksum.json b/third_party/rust/serde_yaml/.cargo-checksum.json
new file mode 100644
index 0000000000..eb1d4afddc
--- /dev/null
+++ b/third_party/rust/serde_yaml/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"Cargo.toml":"1e01ffba9fa6c48ceda8bd7b3b936b5909c7adbfb05b6a5f8deb3f679d7da37e","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"8b6df65d390bc4f9d5e05d0a4ccc860d6e5dc2668d82cd304e6c95b472a21f35","src/de.rs":"414b82334d78cf57b7cdc2fc1ed000594791b2f675648f5286678370f460a74d","src/error.rs":"96a49b8ea102d010760b3ade9b475d0c88d4014c17625302ddc145a9fea2988c","src/lib.rs":"a3276a7da395021e34547fe2f4336a5658f07d4d606a865b707a592f7b084e10","src/mapping.rs":"6607911090c89a41ade38f1717b9c0bd6c3c253cc4711890b77b2bda18d6bac7","src/number.rs":"4edf78ad75bf66bae31c1ee4d785ba2b7a2c14c082802d54c9feb93067bcf063","src/path.rs":"44d339ce1814effd10ba131ae0393df215f09dbfb35ab4d678f49d4081f58dd4","src/ser.rs":"e32c77b3e8087ca1b68a8f093e9f1e27b93ad1aac70a9bb22054b4179973cae1","src/value/de.rs":"84b213b23a8d4bf6bd9aacd18fc1091254382c4edc479f9a9abc87c416b370f0","src/value/from.rs":"cd66c76c4ab03bed32f8c4b22ffbd96274a837d587624a62d0584c7090633862","src/value/index.rs":"16f0e4fecd4a4cd149af89a7426864f58735f7dacc90f33d92c647b044c8f112","src/value/mod.rs":"171a98133de3445ccd4cfa3991b5c3f96baa1c05542fc1927e6eccf3e4ddbe09","src/value/partial_eq.rs":"0b28c8d2f10a58581dbe2a69d25742fa0f8bf3da797f3046e38e300d1f9691bf","src/value/ser.rs":"7ddb9bfadfbfe16a79c872888ea25f8fb7df14b862fea47dd603d576e162db86","tests/test_de.rs":"c7d8d71e8b0aa966ad4003657c1024405abeca0d49aec9f66f749db81bb1f061","tests/test_error.rs":"4ef5c9001f140e1aee1e9d6238c668d26b5b264e237773741d5f65bfff036e75","tests/test_serde.rs":"56aa2623b1aca1ba00d028edc60d6f74cde6eba83529d5bcd3340c4b0487db04","tests/test_value.rs":"f360eeaa7d281d52df18a452a6f67c6095bcf50b92f1a87c5a9e3c27b7a69f33"},"package":"578a7433b776b56a35785ed5ce9a7e777ac0598aac5a6dd1b4b18a307c7fc71b"} \ No newline at end of file
diff --git a/third_party/rust/serde_yaml/Cargo.toml b/third_party/rust/serde_yaml/Cargo.toml
new file mode 100644
index 0000000000..3fd065aa35
--- /dev/null
+++ b/third_party/rust/serde_yaml/Cargo.toml
@@ -0,0 +1,53 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies.
+#
+# If you are reading this file be aware that the original Cargo.toml
+# will likely look very different (and much more reasonable).
+# See Cargo.toml.orig for the original contents.
+
+[package]
+edition = "2021"
+rust-version = "1.56"
+name = "serde_yaml"
+version = "0.8.26"
+authors = ["David Tolnay <dtolnay@gmail.com>"]
+description = "YAML support for Serde"
+documentation = "https://docs.rs/serde_yaml/"
+readme = "README.md"
+keywords = [
+ "yaml",
+ "serde",
+]
+categories = ["encoding"]
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/dtolnay/serde-yaml"
+resolver = "2"
+
+[package.metadata.docs.rs]
+targets = ["x86_64-unknown-linux-gnu"]
+
+[dependencies.indexmap]
+version = "1.5.2"
+features = ["std"]
+
+[dependencies.ryu]
+version = "1.0"
+
+[dependencies.serde]
+version = "1.0.69"
+
+[dependencies.yaml-rust]
+version = "0.4.5"
+
+[dev-dependencies.anyhow]
+version = "1.0"
+
+[dev-dependencies.indoc]
+version = "1.0"
+
+[dev-dependencies.serde_derive]
+version = "1.0"
diff --git a/third_party/rust/serde_yaml/LICENSE-APACHE b/third_party/rust/serde_yaml/LICENSE-APACHE
new file mode 100644
index 0000000000..16fe87b06e
--- /dev/null
+++ b/third_party/rust/serde_yaml/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/third_party/rust/serde_yaml/LICENSE-MIT b/third_party/rust/serde_yaml/LICENSE-MIT
new file mode 100644
index 0000000000..31aa79387f
--- /dev/null
+++ b/third_party/rust/serde_yaml/LICENSE-MIT
@@ -0,0 +1,23 @@
+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.
diff --git a/third_party/rust/serde_yaml/README.md b/third_party/rust/serde_yaml/README.md
new file mode 100644
index 0000000000..4500865cb0
--- /dev/null
+++ b/third_party/rust/serde_yaml/README.md
@@ -0,0 +1,104 @@
+Serde YAML
+==========
+
+[<img alt="github" src="https://img.shields.io/badge/github-dtolnay/serde--yaml-8da0cb?style=for-the-badge&labelColor=555555&logo=github" height="20">](https://github.com/dtolnay/serde-yaml)
+[<img alt="crates.io" src="https://img.shields.io/crates/v/serde_yaml.svg?style=for-the-badge&color=fc8d62&logo=rust" height="20">](https://crates.io/crates/serde_yaml)
+[<img alt="docs.rs" src="https://img.shields.io/badge/docs.rs-serde__yaml-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs" height="20">](https://docs.rs/serde_yaml)
+[<img alt="build status" src="https://img.shields.io/github/workflow/status/dtolnay/serde-yaml/CI/master?style=for-the-badge" height="20">](https://github.com/dtolnay/serde-yaml/actions?query=branch%3Amaster)
+
+This crate is a Rust library for using the [Serde] serialization framework with
+data in [YAML] file format.
+
+[Serde]: https://github.com/serde-rs/serde
+[YAML]: https://yaml.org/
+
+This library does not reimplement a YAML parser; it uses [yaml-rust] which is a
+pure Rust YAML 1.2 implementation.
+
+[yaml-rust]: https://github.com/chyh1990/yaml-rust
+
+## Dependency
+
+```toml
+[dependencies]
+serde = "1.0"
+serde_yaml = "0.8"
+```
+
+Release notes are available under [GitHub releases].
+
+[GitHub releases]: https://github.com/dtolnay/serde-yaml/releases
+
+## Using Serde YAML
+
+[API documentation is available in rustdoc form][docs.rs] but the general idea
+is:
+
+[docs.rs]: https://docs.rs/serde_yaml
+
+```rust
+use std::collections::BTreeMap;
+
+fn main() -> Result<(), serde_yaml::Error> {
+ // You have some type.
+ let mut map = BTreeMap::new();
+ map.insert("x".to_string(), 1.0);
+ map.insert("y".to_string(), 2.0);
+
+ // Serialize it to a YAML string.
+ let s = serde_yaml::to_string(&map)?;
+ assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
+
+ // Deserialize it back to a Rust type.
+ let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&s)?;
+ assert_eq!(map, deserialized_map);
+ Ok(())
+}
+```
+
+It can also be used with Serde's derive macros to handle structs and enums
+defined by your program.
+
+```toml
+[dependencies]
+serde = { version = "1.0", features = ["derive"] }
+serde_yaml = "0.8"
+```
+
+```rust
+use serde::{Serialize, Deserialize};
+
+#[derive(Debug, PartialEq, Serialize, Deserialize)]
+struct Point {
+ x: f64,
+ y: f64,
+}
+
+fn main() -> Result<(), serde_yaml::Error> {
+ let point = Point { x: 1.0, y: 2.0 };
+
+ let s = serde_yaml::to_string(&point)?;
+ assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
+
+ let deserialized_point: Point = serde_yaml::from_str(&s)?;
+ assert_eq!(point, deserialized_point);
+ Ok(())
+}
+```
+
+<br>
+
+#### License
+
+<sup>
+Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
+2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
+</sup>
+
+<br>
+
+<sub>
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in this crate by you, as defined in the Apache-2.0 license, shall
+be dual licensed as above, without any additional terms or conditions.
+</sub>
diff --git a/third_party/rust/serde_yaml/src/de.rs b/third_party/rust/serde_yaml/src/de.rs
new file mode 100644
index 0000000000..8ccf271093
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/de.rs
@@ -0,0 +1,1525 @@
+use crate::error::{self, Error, ErrorImpl, Result};
+use crate::path::Path;
+use serde::de::{
+ self, Deserialize, DeserializeOwned, DeserializeSeed, Expected, IgnoredAny as Ignore,
+ IntoDeserializer, Unexpected, Visitor,
+};
+use std::collections::BTreeMap;
+use std::f64;
+use std::fmt;
+use std::io;
+use std::marker::PhantomData;
+use std::mem;
+use std::str;
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::Arc;
+use yaml_rust::parser::{Event as YamlEvent, MarkedEventReceiver, Parser};
+use yaml_rust::scanner::{Marker, TScalarStyle, TokenType};
+
+/// A structure that deserializes YAML into Rust values.
+///
+/// # Examples
+///
+/// Deserializing a single document:
+///
+/// ```
+/// use anyhow::Result;
+/// use serde::Deserialize;
+/// use serde_yaml::Value;
+///
+/// fn main() -> Result<()> {
+/// let input = "---\nk: 107\n";
+/// let de = serde_yaml::Deserializer::from_str(input);
+/// let value = Value::deserialize(de)?;
+/// println!("{:?}", value);
+/// Ok(())
+/// }
+/// ```
+///
+/// Deserializing multi-doc YAML:
+///
+/// ```
+/// use anyhow::Result;
+/// use serde::Deserialize;
+/// use serde_yaml::Value;
+///
+/// fn main() -> Result<()> {
+/// let input = "---\nk: 107\n...\n---\nj: 106\n";
+///
+/// for document in serde_yaml::Deserializer::from_str(input) {
+/// let value = Value::deserialize(document)?;
+/// println!("{:?}", value);
+/// }
+///
+/// Ok(())
+/// }
+/// ```
+pub struct Deserializer<'a> {
+ input: Input<'a>,
+}
+
+enum Input<'a> {
+ Str(&'a str),
+ Slice(&'a [u8]),
+ Read(Box<dyn io::Read + 'a>),
+ Multidoc(Arc<Multidoc>),
+ Fail(Arc<ErrorImpl>),
+}
+
+impl<'a> Deserializer<'a> {
+ /// Creates a YAML deserializer from a `&str`.
+ pub fn from_str(s: &'a str) -> Self {
+ let input = Input::Str(s);
+ Deserializer { input }
+ }
+
+ /// Creates a YAML deserializer from a `&[u8]`.
+ pub fn from_slice(v: &'a [u8]) -> Self {
+ let input = Input::Slice(v);
+ Deserializer { input }
+ }
+
+ /// Creates a YAML deserializer from an `io::Read`.
+ ///
+ /// Reader-based deserializers do not support deserializing borrowed types
+ /// like `&str`, since the `std::io::Read` trait has no non-copying methods
+ /// -- everything it does involves copying bytes out of the data source.
+ pub fn from_reader<R>(rdr: R) -> Self
+ where
+ R: io::Read + 'a,
+ {
+ let input = Input::Read(Box::new(rdr));
+ Deserializer { input }
+ }
+
+ fn de<T>(self, f: impl FnOnce(&mut DeserializerFromEvents) -> Result<T>) -> Result<T> {
+ if let Input::Multidoc(multidoc) = &self.input {
+ let mut pos = multidoc.pos.load(Ordering::Relaxed);
+ let t = f(&mut DeserializerFromEvents {
+ events: &multidoc.loader.events,
+ aliases: &multidoc.loader.aliases,
+ pos: &mut pos,
+ path: Path::Root,
+ remaining_depth: 128,
+ })?;
+ multidoc.pos.store(pos, Ordering::Relaxed);
+ return Ok(t);
+ }
+
+ let loader = loader(self.input)?;
+ if loader.events.is_empty() {
+ return Err(error::end_of_stream());
+ }
+ let mut pos = 0;
+ let t = f(&mut DeserializerFromEvents {
+ events: &loader.events,
+ aliases: &loader.aliases,
+ pos: &mut pos,
+ path: Path::Root,
+ remaining_depth: 128,
+ })?;
+ if pos == loader.events.len() {
+ Ok(t)
+ } else {
+ Err(error::more_than_one_document())
+ }
+ }
+}
+
+fn loader(input: Input) -> Result<Loader> {
+ enum Input2<'a> {
+ Str(&'a str),
+ Slice(&'a [u8]),
+ }
+
+ let mut buffer;
+ let input = match input {
+ Input::Str(s) => Input2::Str(s),
+ Input::Slice(bytes) => Input2::Slice(bytes),
+ Input::Read(mut rdr) => {
+ buffer = Vec::new();
+ rdr.read_to_end(&mut buffer).map_err(error::io)?;
+ Input2::Slice(&buffer)
+ }
+ Input::Multidoc(_) => unreachable!(),
+ Input::Fail(err) => return Err(error::shared(err)),
+ };
+
+ let input = match input {
+ Input2::Str(s) => s,
+ Input2::Slice(bytes) => str::from_utf8(bytes).map_err(error::str_utf8)?,
+ };
+
+ let mut parser = Parser::new(input.chars());
+ let mut loader = Loader {
+ events: Vec::new(),
+ aliases: BTreeMap::new(),
+ };
+ parser.load(&mut loader, true).map_err(error::scanner)?;
+ Ok(loader)
+}
+
+struct Multidoc {
+ loader: Loader,
+ pos: AtomicUsize,
+}
+
+impl<'de> Iterator for Deserializer<'de> {
+ type Item = Self;
+
+ fn next(&mut self) -> Option<Self> {
+ match &self.input {
+ Input::Multidoc(multidoc) => {
+ let pos = multidoc.pos.load(Ordering::Relaxed);
+ return if pos < multidoc.loader.events.len() {
+ Some(Deserializer {
+ input: Input::Multidoc(Arc::clone(multidoc)),
+ })
+ } else {
+ None
+ };
+ }
+ Input::Fail(err) => {
+ return Some(Deserializer {
+ input: Input::Fail(Arc::clone(err)),
+ });
+ }
+ _ => {}
+ }
+
+ let dummy = Input::Str("");
+ let input = mem::replace(&mut self.input, dummy);
+ match loader(input) {
+ Ok(loader) => {
+ let multidoc = Arc::new(Multidoc {
+ loader,
+ pos: AtomicUsize::new(0),
+ });
+ self.input = Input::Multidoc(Arc::clone(&multidoc));
+ if multidoc.loader.events.is_empty() {
+ None
+ } else {
+ Some(Deserializer {
+ input: Input::Multidoc(multidoc),
+ })
+ }
+ }
+ Err(err) => {
+ let fail = err.shared();
+ self.input = Input::Fail(Arc::clone(&fail));
+ Some(Deserializer {
+ input: Input::Fail(fail),
+ })
+ }
+ }
+ }
+}
+
+impl<'de> de::Deserializer<'de> for Deserializer<'de> {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_any(visitor))
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_bool(visitor))
+ }
+
+ fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_i8(visitor))
+ }
+
+ fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_i16(visitor))
+ }
+
+ fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_i32(visitor))
+ }
+
+ fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_i64(visitor))
+ }
+
+ fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_i128(visitor))
+ }
+
+ fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_u8(visitor))
+ }
+
+ fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_u16(visitor))
+ }
+
+ fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_u32(visitor))
+ }
+
+ fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_u64(visitor))
+ }
+
+ fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_u128(visitor))
+ }
+
+ fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_f32(visitor))
+ }
+
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_f64(visitor))
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_char(visitor))
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_str(visitor))
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_string(visitor))
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_bytes(visitor))
+ }
+
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_byte_buf(visitor))
+ }
+
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_option(visitor))
+ }
+
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_unit(visitor))
+ }
+
+ fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_unit_struct(name, visitor))
+ }
+
+ fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_newtype_struct(name, visitor))
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_seq(visitor))
+ }
+
+ fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_tuple(len, visitor))
+ }
+
+ fn deserialize_tuple_struct<V>(
+ self,
+ name: &'static str,
+ len: usize,
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_tuple_struct(name, len, visitor))
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_map(visitor))
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ name: &'static str,
+ fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_struct(name, fields, visitor))
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ name: &'static str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_enum(name, variants, visitor))
+ }
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_identifier(visitor))
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.de(|state| state.deserialize_ignored_any(visitor))
+ }
+}
+
+pub struct Loader {
+ events: Vec<(Event, Marker)>,
+ /// Map from alias id to index in events.
+ aliases: BTreeMap<usize, usize>,
+}
+
+impl MarkedEventReceiver for Loader {
+ fn on_event(&mut self, event: YamlEvent, marker: Marker) {
+ let event = match event {
+ YamlEvent::Nothing
+ | YamlEvent::StreamStart
+ | YamlEvent::StreamEnd
+ | YamlEvent::DocumentStart
+ | YamlEvent::DocumentEnd => return,
+
+ YamlEvent::Alias(id) => Event::Alias(id),
+ YamlEvent::Scalar(value, style, id, tag) => {
+ self.aliases.insert(id, self.events.len());
+ Event::Scalar(value, style, tag)
+ }
+ YamlEvent::SequenceStart(id) => {
+ self.aliases.insert(id, self.events.len());
+ Event::SequenceStart
+ }
+ YamlEvent::SequenceEnd => Event::SequenceEnd,
+ YamlEvent::MappingStart(id) => {
+ self.aliases.insert(id, self.events.len());
+ Event::MappingStart
+ }
+ YamlEvent::MappingEnd => Event::MappingEnd,
+ };
+ self.events.push((event, marker));
+ }
+}
+
+#[derive(Debug, PartialEq)]
+enum Event {
+ Alias(usize),
+ Scalar(String, TScalarStyle, Option<TokenType>),
+ SequenceStart,
+ SequenceEnd,
+ MappingStart,
+ MappingEnd,
+}
+
+struct DeserializerFromEvents<'a> {
+ events: &'a [(Event, Marker)],
+ /// Map from alias id to index in events.
+ aliases: &'a BTreeMap<usize, usize>,
+ pos: &'a mut usize,
+ path: Path<'a>,
+ remaining_depth: u8,
+}
+
+impl<'a> DeserializerFromEvents<'a> {
+ fn peek(&self) -> Result<(&'a Event, Marker)> {
+ match self.events.get(*self.pos) {
+ Some(event) => Ok((&event.0, event.1)),
+ None => Err(error::end_of_stream()),
+ }
+ }
+
+ fn next(&mut self) -> Result<(&'a Event, Marker)> {
+ self.opt_next().ok_or_else(error::end_of_stream)
+ }
+
+ fn opt_next(&mut self) -> Option<(&'a Event, Marker)> {
+ self.events.get(*self.pos).map(|event| {
+ *self.pos += 1;
+ (&event.0, event.1)
+ })
+ }
+
+ fn jump(&'a self, pos: &'a mut usize) -> Result<DeserializerFromEvents<'a>> {
+ match self.aliases.get(pos) {
+ Some(&found) => {
+ *pos = found;
+ Ok(DeserializerFromEvents {
+ events: self.events,
+ aliases: self.aliases,
+ pos,
+ path: Path::Alias { parent: &self.path },
+ remaining_depth: self.remaining_depth,
+ })
+ }
+ None => panic!("unresolved alias: {}", *pos),
+ }
+ }
+
+ fn ignore_any(&mut self) {
+ enum Nest {
+ Sequence,
+ Mapping,
+ }
+
+ let mut stack = Vec::new();
+
+ while let Some((event, _)) = self.opt_next() {
+ match event {
+ Event::Alias(_) | Event::Scalar(_, _, _) => {}
+ Event::SequenceStart => {
+ stack.push(Nest::Sequence);
+ }
+ Event::MappingStart => {
+ stack.push(Nest::Mapping);
+ }
+ Event::SequenceEnd => match stack.pop() {
+ Some(Nest::Sequence) => {}
+ None | Some(Nest::Mapping) => {
+ panic!("unexpected end of sequence");
+ }
+ },
+ Event::MappingEnd => match stack.pop() {
+ Some(Nest::Mapping) => {}
+ None | Some(Nest::Sequence) => {
+ panic!("unexpected end of mapping");
+ }
+ },
+ }
+ if stack.is_empty() {
+ return;
+ }
+ }
+
+ if !stack.is_empty() {
+ panic!("missing end event");
+ }
+ }
+
+ fn visit_sequence<'de, V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let (value, len) = self.recursion_check(|de| {
+ let mut seq = SeqAccess { de, len: 0 };
+ let value = visitor.visit_seq(&mut seq)?;
+ Ok((value, seq.len))
+ })?;
+ self.end_sequence(len)?;
+ Ok(value)
+ }
+
+ fn visit_mapping<'de, V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let (value, len) = self.recursion_check(|de| {
+ let mut map = MapAccess {
+ de,
+ len: 0,
+ key: None,
+ };
+ let value = visitor.visit_map(&mut map)?;
+ Ok((value, map.len))
+ })?;
+ self.end_mapping(len)?;
+ Ok(value)
+ }
+
+ fn end_sequence(&mut self, len: usize) -> Result<()> {
+ let total = {
+ let mut seq = SeqAccess { de: self, len };
+ while de::SeqAccess::next_element::<Ignore>(&mut seq)?.is_some() {}
+ seq.len
+ };
+ assert_eq!(Event::SequenceEnd, *self.next()?.0);
+ if total == len {
+ Ok(())
+ } else {
+ struct ExpectedSeq(usize);
+ impl Expected for ExpectedSeq {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ if self.0 == 1 {
+ write!(formatter, "sequence of 1 element")
+ } else {
+ write!(formatter, "sequence of {} elements", self.0)
+ }
+ }
+ }
+ Err(de::Error::invalid_length(total, &ExpectedSeq(len)))
+ }
+ }
+
+ fn end_mapping(&mut self, len: usize) -> Result<()> {
+ let total = {
+ let mut map = MapAccess {
+ de: self,
+ len,
+ key: None,
+ };
+ while de::MapAccess::next_entry::<Ignore, Ignore>(&mut map)?.is_some() {}
+ map.len
+ };
+ assert_eq!(Event::MappingEnd, *self.next()?.0);
+ if total == len {
+ Ok(())
+ } else {
+ struct ExpectedMap(usize);
+ impl Expected for ExpectedMap {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ if self.0 == 1 {
+ write!(formatter, "map containing 1 entry")
+ } else {
+ write!(formatter, "map containing {} entries", self.0)
+ }
+ }
+ }
+ Err(de::Error::invalid_length(total, &ExpectedMap(len)))
+ }
+ }
+
+ fn recursion_check<F: FnOnce(&mut Self) -> Result<T>, T>(&mut self, f: F) -> Result<T> {
+ let previous_depth = self.remaining_depth;
+ self.remaining_depth = previous_depth
+ .checked_sub(1)
+ .ok_or_else(error::recursion_limit_exceeded)?;
+ let result = f(self);
+ self.remaining_depth = previous_depth;
+ result
+ }
+}
+
+fn visit_scalar<'de, V>(
+ v: &str,
+ style: TScalarStyle,
+ tag: &Option<TokenType>,
+ visitor: V,
+) -> Result<V::Value>
+where
+ V: Visitor<'de>,
+{
+ if let Some(TokenType::Tag(handle, suffix)) = tag {
+ if handle == "!!" {
+ match suffix.as_ref() {
+ "bool" => match v.parse::<bool>() {
+ Ok(v) => visitor.visit_bool(v),
+ Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &"a boolean")),
+ },
+ "int" => match v.parse::<i64>() {
+ Ok(v) => visitor.visit_i64(v),
+ Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &"an integer")),
+ },
+ "float" => match v.parse::<f64>() {
+ Ok(v) => visitor.visit_f64(v),
+ Err(_) => Err(de::Error::invalid_value(Unexpected::Str(v), &"a float")),
+ },
+ "null" => match v {
+ "~" | "null" => visitor.visit_unit(),
+ _ => Err(de::Error::invalid_value(Unexpected::Str(v), &"null")),
+ },
+ _ => visitor.visit_str(v),
+ }
+ } else {
+ visitor.visit_str(v)
+ }
+ } else if style == TScalarStyle::Plain {
+ visit_untagged_str(visitor, v)
+ } else {
+ visitor.visit_str(v)
+ }
+}
+
+struct SeqAccess<'a: 'r, 'r> {
+ de: &'r mut DeserializerFromEvents<'a>,
+ len: usize,
+}
+
+impl<'de, 'a, 'r> de::SeqAccess<'de> for SeqAccess<'a, 'r> {
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.de.peek()?.0 {
+ Event::SequenceEnd => Ok(None),
+ _ => {
+ let mut element_de = DeserializerFromEvents {
+ events: self.de.events,
+ aliases: self.de.aliases,
+ pos: self.de.pos,
+ path: Path::Seq {
+ parent: &self.de.path,
+ index: self.len,
+ },
+ remaining_depth: self.de.remaining_depth,
+ };
+ self.len += 1;
+ seed.deserialize(&mut element_de).map(Some)
+ }
+ }
+ }
+}
+
+struct MapAccess<'a: 'r, 'r> {
+ de: &'r mut DeserializerFromEvents<'a>,
+ len: usize,
+ key: Option<&'a str>,
+}
+
+impl<'de, 'a, 'r> de::MapAccess<'de> for MapAccess<'a, 'r> {
+ type Error = Error;
+
+ fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
+ where
+ K: DeserializeSeed<'de>,
+ {
+ match self.de.peek()?.0 {
+ Event::MappingEnd => Ok(None),
+ Event::Scalar(key, _, _) => {
+ self.len += 1;
+ self.key = Some(key);
+ seed.deserialize(&mut *self.de).map(Some)
+ }
+ _ => {
+ self.len += 1;
+ self.key = None;
+ seed.deserialize(&mut *self.de).map(Some)
+ }
+ }
+ }
+
+ fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ let mut value_de = DeserializerFromEvents {
+ events: self.de.events,
+ aliases: self.de.aliases,
+ pos: self.de.pos,
+ path: if let Some(key) = self.key {
+ Path::Map {
+ parent: &self.de.path,
+ key,
+ }
+ } else {
+ Path::Unknown {
+ parent: &self.de.path,
+ }
+ },
+ remaining_depth: self.de.remaining_depth,
+ };
+ seed.deserialize(&mut value_de)
+ }
+}
+
+struct EnumAccess<'a: 'r, 'r> {
+ de: &'r mut DeserializerFromEvents<'a>,
+ name: &'static str,
+ tag: Option<&'static str>,
+}
+
+impl<'de, 'a, 'r> de::EnumAccess<'de> for EnumAccess<'a, 'r> {
+ type Error = Error;
+ type Variant = DeserializerFromEvents<'r>;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ #[derive(Debug)]
+ enum Nope {}
+
+ struct BadKey {
+ name: &'static str,
+ }
+
+ impl<'de> Visitor<'de> for BadKey {
+ type Value = Nope;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ write!(formatter, "variant of enum `{}`", self.name)
+ }
+ }
+
+ let variant = if let Some(tag) = self.tag {
+ tag
+ } else {
+ match self.de.next()?.0 {
+ Event::Scalar(s, _, _) => &**s,
+ _ => {
+ *self.de.pos -= 1;
+ let bad = BadKey { name: self.name };
+ return Err(de::Deserializer::deserialize_any(&mut *self.de, bad).unwrap_err());
+ }
+ }
+ };
+
+ let str_de = IntoDeserializer::<Error>::into_deserializer(variant);
+ let ret = seed.deserialize(str_de)?;
+ let variant_visitor = DeserializerFromEvents {
+ events: self.de.events,
+ aliases: self.de.aliases,
+ pos: self.de.pos,
+ path: Path::Map {
+ parent: &self.de.path,
+ key: variant,
+ },
+ remaining_depth: self.de.remaining_depth,
+ };
+ Ok((ret, variant_visitor))
+ }
+}
+
+impl<'de, 'a> de::VariantAccess<'de> for DeserializerFromEvents<'a> {
+ type Error = Error;
+
+ fn unit_variant(mut self) -> Result<()> {
+ Deserialize::deserialize(&mut self)
+ }
+
+ fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ seed.deserialize(&mut self)
+ }
+
+ fn tuple_variant<V>(mut self, _len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ de::Deserializer::deserialize_seq(&mut self, visitor)
+ }
+
+ fn struct_variant<V>(mut self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ de::Deserializer::deserialize_struct(&mut self, "", fields, visitor)
+ }
+}
+
+struct UnitVariantAccess<'a: 'r, 'r> {
+ de: &'r mut DeserializerFromEvents<'a>,
+}
+
+impl<'de, 'a, 'r> de::EnumAccess<'de> for UnitVariantAccess<'a, 'r> {
+ type Error = Error;
+ type Variant = Self;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ Ok((seed.deserialize(&mut *self.de)?, self))
+ }
+}
+
+impl<'de, 'a, 'r> de::VariantAccess<'de> for UnitVariantAccess<'a, 'r> {
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<()> {
+ Ok(())
+ }
+
+ fn newtype_variant_seed<T>(self, _seed: T) -> Result<T::Value>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"newtype variant",
+ ))
+ }
+
+ fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"tuple variant",
+ ))
+ }
+
+ fn struct_variant<V>(self, _fields: &'static [&'static str], _visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ Err(de::Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"struct variant",
+ ))
+ }
+}
+
+fn visit_untagged_str<'de, V>(visitor: V, v: &str) -> Result<V::Value>
+where
+ V: Visitor<'de>,
+{
+ if v == "~" || v == "null" {
+ return visitor.visit_unit();
+ }
+ if v == "true" {
+ return visitor.visit_bool(true);
+ }
+ if v == "false" {
+ return visitor.visit_bool(false);
+ }
+ if let Some(rest) = Option::or(v.strip_prefix("0x"), v.strip_prefix("+0x")) {
+ if let Ok(n) = u64::from_str_radix(rest, 16) {
+ return visitor.visit_u64(n);
+ }
+ }
+ if let Some(rest) = v.strip_prefix("-0x") {
+ let negative = format!("-{}", rest);
+ if let Ok(n) = i64::from_str_radix(&negative, 16) {
+ return visitor.visit_i64(n);
+ }
+ }
+ if let Some(rest) = Option::or(v.strip_prefix("0o"), v.strip_prefix("+0o")) {
+ if let Ok(n) = u64::from_str_radix(rest, 8) {
+ return visitor.visit_u64(n);
+ }
+ }
+ if let Some(rest) = v.strip_prefix("-0o") {
+ let negative = format!("-{}", rest);
+ if let Ok(n) = i64::from_str_radix(&negative, 8) {
+ return visitor.visit_i64(n);
+ }
+ }
+ if let Some(rest) = Option::or(v.strip_prefix("0b"), v.strip_prefix("+0b")) {
+ if let Ok(n) = u64::from_str_radix(rest, 2) {
+ return visitor.visit_u64(n);
+ }
+ }
+ if let Some(rest) = v.strip_prefix("-0b") {
+ let negative = format!("-{}", rest);
+ if let Ok(n) = i64::from_str_radix(&negative, 2) {
+ return visitor.visit_i64(n);
+ }
+ }
+ if {
+ let v = v.trim_start_matches(&['-', '+'][..]);
+ v.len() > 1 && v.starts_with('0') && v[1..].bytes().all(|b| b.is_ascii_digit())
+ } {
+ // After handling the different number encodings above if we are left
+ // with leading zero(s) followed by numeric characters this is in fact a
+ // string according to the YAML 1.2 spec.
+ // https://yaml.org/spec/1.2/spec.html#id2761292
+ return visitor.visit_str(v);
+ }
+ if let Ok(n) = v.parse() {
+ return visitor.visit_u64(n);
+ }
+ if let Ok(n) = v.parse() {
+ return visitor.visit_u128(n);
+ }
+ if let Ok(n) = v.parse() {
+ return visitor.visit_i64(n);
+ }
+ if let Ok(n) = v.parse() {
+ return visitor.visit_i128(n);
+ }
+ match v.trim_start_matches('+') {
+ ".inf" | ".Inf" | ".INF" => return visitor.visit_f64(f64::INFINITY),
+ _ => (),
+ }
+ if v == "-.inf" || v == "-.Inf" || v == "-.INF" {
+ return visitor.visit_f64(f64::NEG_INFINITY);
+ }
+ if v == ".nan" || v == ".NaN" || v == ".NAN" {
+ return visitor.visit_f64(f64::NAN);
+ }
+ if let Ok(n) = v.parse::<f64>() {
+ if n.is_finite() {
+ return visitor.visit_f64(n);
+ }
+ }
+ visitor.visit_str(v)
+}
+
+fn invalid_type(event: &Event, exp: &dyn Expected) -> Error {
+ enum Void {}
+
+ struct InvalidType<'a> {
+ exp: &'a dyn Expected,
+ }
+
+ impl<'de, 'a> Visitor<'de> for InvalidType<'a> {
+ type Value = Void;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ self.exp.fmt(formatter)
+ }
+ }
+
+ match event {
+ Event::Alias(_) => unreachable!(),
+ Event::Scalar(v, style, tag) => {
+ let get_type = InvalidType { exp };
+ match visit_scalar(v, *style, tag, get_type) {
+ Ok(void) => match void {},
+ Err(invalid_type) => invalid_type,
+ }
+ }
+ Event::SequenceStart => de::Error::invalid_type(Unexpected::Seq, exp),
+ Event::MappingStart => de::Error::invalid_type(Unexpected::Map, exp),
+ Event::SequenceEnd => panic!("unexpected end of sequence"),
+ Event::MappingEnd => panic!("unexpected end of mapping"),
+ }
+}
+
+impl<'a> DeserializerFromEvents<'a> {
+ fn deserialize_scalar<'de, V>(&mut self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let (next, marker) = self.next()?;
+ match next {
+ Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_scalar(visitor),
+ Event::Scalar(v, style, tag) => visit_scalar(v, *style, tag, visitor),
+ other => Err(invalid_type(other, &visitor)),
+ }
+ .map_err(|err| error::fix_marker(err, marker, self.path))
+ }
+}
+
+impl<'de, 'a, 'r> de::Deserializer<'de> for &'r mut DeserializerFromEvents<'a> {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let (next, marker) = self.next()?;
+ match next {
+ Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_any(visitor),
+ Event::Scalar(v, style, tag) => visit_scalar(v, *style, tag, visitor),
+ Event::SequenceStart => self.visit_sequence(visitor),
+ Event::MappingStart => self.visit_mapping(visitor),
+ Event::SequenceEnd => panic!("unexpected end of sequence"),
+ Event::MappingEnd => panic!("unexpected end of mapping"),
+ }
+ // The de::Error impl creates errors with unknown line and column. Fill
+ // in the position here by looking at the current index in the input.
+ .map_err(|err| error::fix_marker(err, marker, self.path))
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let (next, marker) = self.next()?;
+ match next {
+ Event::Scalar(v, _, _) => visitor.visit_str(v),
+ Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_str(visitor),
+ other => Err(invalid_type(other, &visitor)),
+ }
+ .map_err(|err: Error| error::fix_marker(err, marker, self.path))
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_any(visitor)
+ }
+
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_bytes(visitor)
+ }
+
+ /// Parses `null` as None and any other values as `Some(...)`.
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let is_some = match self.peek()?.0 {
+ Event::Alias(mut pos) => {
+ *self.pos += 1;
+ return self.jump(&mut pos)?.deserialize_option(visitor);
+ }
+ Event::Scalar(v, style, tag) => {
+ if *style != TScalarStyle::Plain {
+ true
+ } else if let Some(TokenType::Tag(handle, suffix)) = tag {
+ if handle == "!!" && suffix == "null" {
+ if v == "~" || v == "null" {
+ false
+ } else {
+ return Err(de::Error::invalid_value(Unexpected::Str(v), &"null"));
+ }
+ } else {
+ true
+ }
+ } else {
+ v != "~" && v != "null"
+ }
+ }
+ Event::SequenceStart | Event::MappingStart => true,
+ Event::SequenceEnd => panic!("unexpected end of sequence"),
+ Event::MappingEnd => panic!("unexpected end of mapping"),
+ };
+ if is_some {
+ visitor.visit_some(self)
+ } else {
+ *self.pos += 1;
+ visitor.visit_none()
+ }
+ }
+
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_scalar(visitor)
+ }
+
+ fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_unit(visitor)
+ }
+
+ /// Parses a newtype struct as the underlying value.
+ fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_newtype_struct(self)
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let (next, marker) = self.next()?;
+ match next {
+ Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_seq(visitor),
+ Event::SequenceStart => self.visit_sequence(visitor),
+ other => Err(invalid_type(other, &visitor)),
+ }
+ .map_err(|err| error::fix_marker(err, marker, self.path))
+ }
+
+ fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_tuple_struct<V>(
+ self,
+ _name: &'static str,
+ _len: usize,
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let (next, marker) = self.next()?;
+ match next {
+ Event::Alias(mut pos) => self.jump(&mut pos)?.deserialize_map(visitor),
+ Event::MappingStart => self.visit_mapping(visitor),
+ other => Err(invalid_type(other, &visitor)),
+ }
+ .map_err(|err| error::fix_marker(err, marker, self.path))
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ name: &'static str,
+ fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let (next, marker) = self.next()?;
+ match next {
+ Event::Alias(mut pos) => self
+ .jump(&mut pos)?
+ .deserialize_struct(name, fields, visitor),
+ Event::SequenceStart => self.visit_sequence(visitor),
+ Event::MappingStart => self.visit_mapping(visitor),
+ other => Err(invalid_type(other, &visitor)),
+ }
+ .map_err(|err| error::fix_marker(err, marker, self.path))
+ }
+
+ /// Parses an enum as a single key:value pair where the key identifies the
+ /// variant and the value gives the content. A String will also parse correctly
+ /// to a unit enum value.
+ fn deserialize_enum<V>(
+ self,
+ name: &'static str,
+ variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ let (next, marker) = self.peek()?;
+ match next {
+ Event::Alias(mut pos) => {
+ *self.pos += 1;
+ self.jump(&mut pos)?
+ .deserialize_enum(name, variants, visitor)
+ }
+ Event::Scalar(_, _, t) => {
+ if let Some(TokenType::Tag(handle, suffix)) = t {
+ if handle == "!" {
+ if let Some(tag) = variants.iter().find(|v| *v == suffix) {
+ return visitor.visit_enum(EnumAccess {
+ de: self,
+ name,
+ tag: Some(tag),
+ });
+ }
+ }
+ }
+ visitor.visit_enum(UnitVariantAccess { de: self })
+ }
+ Event::MappingStart => {
+ *self.pos += 1;
+ let value = visitor.visit_enum(EnumAccess {
+ de: self,
+ name,
+ tag: None,
+ })?;
+ self.end_mapping(1)?;
+ Ok(value)
+ }
+ Event::SequenceStart => {
+ let err = de::Error::invalid_type(Unexpected::Seq, &"string or singleton map");
+ Err(error::fix_marker(err, marker, self.path))
+ }
+ Event::SequenceEnd => panic!("unexpected end of sequence"),
+ Event::MappingEnd => panic!("unexpected end of mapping"),
+ }
+ }
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_str(visitor)
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
+ where
+ V: Visitor<'de>,
+ {
+ self.ignore_any();
+ visitor.visit_unit()
+ }
+}
+
+/// Deserialize an instance of type `T` from a string of YAML text.
+///
+/// This conversion can fail if the structure of the Value does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the Value
+/// contains something other than a YAML map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the YAML map or some number is too big to fit in the expected primitive
+/// type.
+///
+/// YAML currently does not support zero-copy deserialization.
+pub fn from_str<T>(s: &str) -> Result<T>
+where
+ T: DeserializeOwned,
+{
+ from_str_seed(s, PhantomData)
+}
+
+/// Deserialize an instance of type `T` from a string of YAML text with a seed.
+///
+/// This conversion can fail if the structure of the Value does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the Value
+/// contains something other than a YAML map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the YAML map or some number is too big to fit in the expected primitive
+/// type.
+///
+/// YAML currently does not support zero-copy deserialization.
+pub fn from_str_seed<T, S>(s: &str, seed: S) -> Result<T>
+where
+ S: for<'de> DeserializeSeed<'de, Value = T>,
+{
+ seed.deserialize(Deserializer::from_str(s))
+}
+
+/// Deserialize an instance of type `T` from an IO stream of YAML.
+///
+/// This conversion can fail if the structure of the Value does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the Value
+/// contains something other than a YAML map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the YAML map or some number is too big to fit in the expected primitive
+/// type.
+pub fn from_reader<R, T>(rdr: R) -> Result<T>
+where
+ R: io::Read,
+ T: DeserializeOwned,
+{
+ from_reader_seed(rdr, PhantomData)
+}
+
+/// Deserialize an instance of type `T` from an IO stream of YAML with a seed.
+///
+/// This conversion can fail if the structure of the Value does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the Value
+/// contains something other than a YAML map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the YAML map or some number is too big to fit in the expected primitive
+/// type.
+pub fn from_reader_seed<R, T, S>(rdr: R, seed: S) -> Result<T>
+where
+ R: io::Read,
+ S: for<'de> DeserializeSeed<'de, Value = T>,
+{
+ seed.deserialize(Deserializer::from_reader(rdr))
+}
+
+/// Deserialize an instance of type `T` from bytes of YAML text.
+///
+/// This conversion can fail if the structure of the Value does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the Value
+/// contains something other than a YAML map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the YAML map or some number is too big to fit in the expected primitive
+/// type.
+///
+/// YAML currently does not support zero-copy deserialization.
+pub fn from_slice<T>(v: &[u8]) -> Result<T>
+where
+ T: DeserializeOwned,
+{
+ from_slice_seed(v, PhantomData)
+}
+
+/// Deserialize an instance of type `T` from bytes of YAML text with a seed.
+///
+/// This conversion can fail if the structure of the Value does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the Value
+/// contains something other than a YAML map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the YAML map or some number is too big to fit in the expected primitive
+/// type.
+///
+/// YAML currently does not support zero-copy deserialization.
+pub fn from_slice_seed<T, S>(v: &[u8], seed: S) -> Result<T>
+where
+ S: for<'de> DeserializeSeed<'de, Value = T>,
+{
+ seed.deserialize(Deserializer::from_slice(v))
+}
diff --git a/third_party/rust/serde_yaml/src/error.rs b/third_party/rust/serde_yaml/src/error.rs
new file mode 100644
index 0000000000..dc8321435f
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/error.rs
@@ -0,0 +1,244 @@
+use crate::path::Path;
+use serde::{de, ser};
+use std::error;
+use std::fmt::{self, Debug, Display};
+use std::io;
+use std::result;
+use std::str;
+use std::string;
+use std::sync::Arc;
+use yaml_rust::emitter;
+use yaml_rust::scanner::{self, Marker, ScanError};
+
+/// An error that happened serializing or deserializing YAML data.
+pub struct Error(Box<ErrorImpl>);
+
+/// Alias for a `Result` with the error type `serde_yaml::Error`.
+pub type Result<T> = result::Result<T, Error>;
+
+#[derive(Debug)]
+pub enum ErrorImpl {
+ Message(String, Option<Pos>),
+
+ Emit(emitter::EmitError),
+ Scan(scanner::ScanError),
+ Io(io::Error),
+ Utf8(str::Utf8Error),
+ FromUtf8(string::FromUtf8Error),
+
+ EndOfStream,
+ MoreThanOneDocument,
+ RecursionLimitExceeded,
+
+ Shared(Arc<ErrorImpl>),
+}
+
+#[derive(Debug)]
+pub struct Pos {
+ marker: Marker,
+ path: String,
+}
+
+/// The input location that an error occured.
+#[derive(Debug)]
+pub struct Location {
+ index: usize,
+ line: usize,
+ column: usize,
+}
+
+impl Location {
+ /// The byte index of the error
+ pub fn index(&self) -> usize {
+ self.index
+ }
+
+ /// The line of the error
+ pub fn line(&self) -> usize {
+ self.line
+ }
+
+ /// The column of the error
+ pub fn column(&self) -> usize {
+ self.column
+ }
+
+ // This is to keep decoupled with the yaml crate
+ #[doc(hidden)]
+ fn from_marker(marker: &Marker) -> Self {
+ Location {
+ // `col` returned from the `yaml` crate is 0-indexed but all error messages add + 1 to this value
+ column: marker.col() + 1,
+ index: marker.index(),
+ line: marker.line(),
+ }
+ }
+}
+
+impl Error {
+ /// Returns the Location from the error if one exists.
+ ///
+ /// Not all types of errors have a location so this can return `None`.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Error};
+ /// #
+ /// // The `@` character as the first character makes this invalid yaml
+ /// let invalid_yaml: Result<Value, Error> = serde_yaml::from_str("@invalid_yaml");
+ ///
+ /// let location = invalid_yaml.unwrap_err().location().unwrap();
+ ///
+ /// assert_eq!(location.line(), 1);
+ /// assert_eq!(location.column(), 1);
+ /// ```
+ pub fn location(&self) -> Option<Location> {
+ match self.0.as_ref() {
+ ErrorImpl::Message(_, Some(pos)) => Some(Location::from_marker(&pos.marker)),
+ ErrorImpl::Scan(scan) => Some(Location::from_marker(scan.marker())),
+ _ => None,
+ }
+ }
+}
+
+pub(crate) fn end_of_stream() -> Error {
+ Error(Box::new(ErrorImpl::EndOfStream))
+}
+
+pub(crate) fn more_than_one_document() -> Error {
+ Error(Box::new(ErrorImpl::MoreThanOneDocument))
+}
+
+pub(crate) fn io(err: io::Error) -> Error {
+ Error(Box::new(ErrorImpl::Io(err)))
+}
+
+pub(crate) fn emitter(err: emitter::EmitError) -> Error {
+ Error(Box::new(ErrorImpl::Emit(err)))
+}
+
+pub(crate) fn scanner(err: scanner::ScanError) -> Error {
+ Error(Box::new(ErrorImpl::Scan(err)))
+}
+
+pub(crate) fn str_utf8(err: str::Utf8Error) -> Error {
+ Error(Box::new(ErrorImpl::Utf8(err)))
+}
+
+pub(crate) fn string_utf8(err: string::FromUtf8Error) -> Error {
+ Error(Box::new(ErrorImpl::FromUtf8(err)))
+}
+
+pub(crate) fn recursion_limit_exceeded() -> Error {
+ Error(Box::new(ErrorImpl::RecursionLimitExceeded))
+}
+
+pub(crate) fn shared(shared: Arc<ErrorImpl>) -> Error {
+ Error(Box::new(ErrorImpl::Shared(shared)))
+}
+
+pub(crate) fn fix_marker(mut error: Error, marker: Marker, path: Path) -> Error {
+ if let ErrorImpl::Message(_, none @ None) = error.0.as_mut() {
+ *none = Some(Pos {
+ marker,
+ path: path.to_string(),
+ });
+ }
+ error
+}
+
+impl Error {
+ pub(crate) fn shared(self) -> Arc<ErrorImpl> {
+ if let ErrorImpl::Shared(err) = *self.0 {
+ err
+ } else {
+ Arc::from(self.0)
+ }
+ }
+}
+
+impl error::Error for Error {
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+ self.0.source()
+ }
+}
+
+impl Display for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.0.display(f)
+ }
+}
+
+// Remove two layers of verbosity from the debug representation. Humans often
+// end up seeing this representation because it is what unwrap() shows.
+impl Debug for Error {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ self.0.debug(f)
+ }
+}
+
+impl ser::Error for Error {
+ fn custom<T: Display>(msg: T) -> Self {
+ Error(Box::new(ErrorImpl::Message(msg.to_string(), None)))
+ }
+}
+
+impl de::Error for Error {
+ fn custom<T: Display>(msg: T) -> Self {
+ Error(Box::new(ErrorImpl::Message(msg.to_string(), None)))
+ }
+}
+
+impl ErrorImpl {
+ fn source(&self) -> Option<&(dyn error::Error + 'static)> {
+ match self {
+ ErrorImpl::Scan(err) => Some(err),
+ ErrorImpl::Io(err) => Some(err),
+ ErrorImpl::Utf8(err) => Some(err),
+ ErrorImpl::FromUtf8(err) => Some(err),
+ ErrorImpl::Shared(err) => err.source(),
+ _ => None,
+ }
+ }
+
+ fn display(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ ErrorImpl::Message(msg, None) => Display::fmt(msg, f),
+ ErrorImpl::Message(msg, Some(Pos { marker, path })) => {
+ if path == "." {
+ write!(f, "{}", ScanError::new(*marker, msg))
+ } else {
+ write!(f, "{}: {}", path, ScanError::new(*marker, msg))
+ }
+ }
+ ErrorImpl::Emit(emitter::EmitError::FmtError(_)) => f.write_str("yaml-rust fmt error"),
+ ErrorImpl::Emit(emitter::EmitError::BadHashmapKey) => f.write_str("bad hash map key"),
+ ErrorImpl::Scan(err) => Display::fmt(err, f),
+ ErrorImpl::Io(err) => Display::fmt(err, f),
+ ErrorImpl::Utf8(err) => Display::fmt(err, f),
+ ErrorImpl::FromUtf8(err) => Display::fmt(err, f),
+ ErrorImpl::EndOfStream => f.write_str("EOF while parsing a value"),
+ ErrorImpl::MoreThanOneDocument => f.write_str(
+ "deserializing from YAML containing more than one document is not supported",
+ ),
+ ErrorImpl::RecursionLimitExceeded => f.write_str("recursion limit exceeded"),
+ ErrorImpl::Shared(err) => err.display(f),
+ }
+ }
+
+ fn debug(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ ErrorImpl::Message(msg, pos) => f.debug_tuple("Message").field(msg).field(pos).finish(),
+ ErrorImpl::Emit(emit) => f.debug_tuple("Emit").field(emit).finish(),
+ ErrorImpl::Scan(scan) => f.debug_tuple("Scan").field(scan).finish(),
+ ErrorImpl::Io(io) => f.debug_tuple("Io").field(io).finish(),
+ ErrorImpl::Utf8(utf8) => f.debug_tuple("Utf8").field(utf8).finish(),
+ ErrorImpl::FromUtf8(from_utf8) => f.debug_tuple("FromUtf8").field(from_utf8).finish(),
+ ErrorImpl::EndOfStream => f.debug_tuple("EndOfStream").finish(),
+ ErrorImpl::MoreThanOneDocument => f.debug_tuple("MoreThanOneDocument").finish(),
+ ErrorImpl::RecursionLimitExceeded => f.debug_tuple("RecursionLimitExceeded").finish(),
+ ErrorImpl::Shared(err) => err.debug(f),
+ }
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/lib.rs b/third_party/rust/serde_yaml/src/lib.rs
new file mode 100644
index 0000000000..f3fc6a9d3c
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/lib.rs
@@ -0,0 +1,125 @@
+//! [![github]](https://github.com/dtolnay/serde-yaml)&ensp;[![crates-io]](https://crates.io/crates/serde-yaml)&ensp;[![docs-rs]](https://docs.rs/serde-yaml)
+//!
+//! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+//! [crates-io]: https://img.shields.io/badge/crates.io-fc8d62?style=for-the-badge&labelColor=555555&logo=rust
+//! [docs-rs]: https://img.shields.io/badge/docs.rs-66c2a5?style=for-the-badge&labelColor=555555&logo=docs.rs
+//!
+//! <br>
+//!
+//! This crate is a Rust library for using the [Serde] serialization framework
+//! with data in [YAML] file format.
+//!
+//! This library does not reimplement a YAML parser; it uses [yaml-rust] which
+//! is a pure Rust YAML 1.2 implementation.
+//!
+//! [Serde]: https://github.com/serde-rs/serde
+//! [YAML]: https://yaml.org/
+//! [yaml-rust]: https://github.com/chyh1990/yaml-rust
+//!
+//! # Examples
+//!
+//! ```
+//! use std::collections::BTreeMap;
+//!
+//! fn main() -> Result<(), serde_yaml::Error> {
+//! // You have some type.
+//! let mut map = BTreeMap::new();
+//! map.insert("x".to_string(), 1.0);
+//! map.insert("y".to_string(), 2.0);
+//!
+//! // Serialize it to a YAML string.
+//! let s = serde_yaml::to_string(&map)?;
+//! assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
+//!
+//! // Deserialize it back to a Rust type.
+//! let deserialized_map: BTreeMap<String, f64> = serde_yaml::from_str(&s)?;
+//! assert_eq!(map, deserialized_map);
+//! Ok(())
+//! }
+//! ```
+//!
+//! ## Using Serde derive
+//!
+//! It can also be used with Serde's serialization code generator `serde_derive` to
+//! handle structs and enums defined in your own program.
+//!
+//! ```
+//! # use serde_derive::{Serialize, Deserialize};
+//! use serde::{Serialize, Deserialize};
+//!
+//! #[derive(Debug, PartialEq, Serialize, Deserialize)]
+//! struct Point {
+//! x: f64,
+//! y: f64,
+//! }
+//!
+//! fn main() -> Result<(), serde_yaml::Error> {
+//! let point = Point { x: 1.0, y: 2.0 };
+//!
+//! let s = serde_yaml::to_string(&point)?;
+//! assert_eq!(s, "---\nx: 1.0\ny: 2.0\n");
+//!
+//! let deserialized_point: Point = serde_yaml::from_str(&s)?;
+//! assert_eq!(point, deserialized_point);
+//! Ok(())
+//! }
+//! ```
+
+#![doc(html_root_url = "https://docs.rs/serde_yaml/0.8.26")]
+#![deny(missing_docs)]
+// Suppressed clippy_pedantic lints
+#![allow(
+ // buggy
+ clippy::iter_not_returning_iterator, // https://github.com/rust-lang/rust-clippy/issues/8285
+ clippy::question_mark, // https://github.com/rust-lang/rust-clippy/issues/7859
+ // private Deserializer::next
+ clippy::should_implement_trait,
+ // things are often more readable this way
+ clippy::cast_lossless,
+ clippy::checked_conversions,
+ clippy::if_not_else,
+ clippy::manual_assert,
+ clippy::match_like_matches_macro,
+ clippy::match_same_arms,
+ clippy::module_name_repetitions,
+ clippy::needless_pass_by_value,
+ clippy::option_if_let_else,
+ clippy::redundant_else,
+ clippy::single_match_else,
+ // code is acceptable
+ clippy::blocks_in_if_conditions,
+ clippy::cast_possible_wrap,
+ clippy::cast_precision_loss,
+ clippy::derive_partial_eq_without_eq,
+ clippy::doc_markdown,
+ clippy::items_after_statements,
+ clippy::return_self_not_must_use,
+ // noisy
+ clippy::missing_errors_doc,
+ clippy::must_use_candidate,
+)]
+
+pub use crate::de::{from_reader, from_slice, from_str, Deserializer};
+pub use crate::error::{Error, Location, Result};
+pub use crate::ser::{to_string, to_vec, to_writer, Serializer};
+pub use crate::value::{from_value, to_value, Index, Number, Sequence, Value};
+
+#[doc(inline)]
+pub use crate::mapping::Mapping;
+
+/// Entry points for deserializing with pre-existing state.
+///
+/// These functions are only exposed this way because we don't yet expose a
+/// Deserializer type. Data formats that have a public Deserializer should not
+/// copy these signatures.
+pub mod seed {
+ pub use super::de::{from_reader_seed, from_slice_seed, from_str_seed};
+}
+
+mod de;
+mod error;
+pub mod mapping;
+mod number;
+mod path;
+mod ser;
+mod value;
diff --git a/third_party/rust/serde_yaml/src/mapping.rs b/third_party/rust/serde_yaml/src/mapping.rs
new file mode 100644
index 0000000000..89f6e413a0
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/mapping.rs
@@ -0,0 +1,512 @@
+//! A YAML mapping and its iterator types.
+
+use crate::Value;
+use indexmap::IndexMap;
+use serde::{Deserialize, Deserializer, Serialize};
+use std::cmp::Ordering;
+use std::collections::hash_map::DefaultHasher;
+use std::fmt;
+use std::hash::{Hash, Hasher};
+use std::iter::FromIterator;
+use std::ops::{Index, IndexMut};
+
+/// A YAML mapping in which the keys and values are both `serde_yaml::Value`.
+#[derive(Clone, Debug, Default, Eq, PartialEq)]
+pub struct Mapping {
+ map: IndexMap<Value, Value>,
+}
+
+impl Mapping {
+ /// Creates an empty YAML map.
+ #[inline]
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ /// Creates an empty YAML map with the given initial capacity.
+ #[inline]
+ pub fn with_capacity(capacity: usize) -> Self {
+ Mapping {
+ map: IndexMap::with_capacity(capacity),
+ }
+ }
+
+ /// Reserves capacity for at least `additional` more elements to be inserted
+ /// into the map. The map may reserve more space to avoid frequent
+ /// allocations.
+ ///
+ /// # Panics
+ ///
+ /// Panics if the new allocation size overflows `usize`.
+ #[inline]
+ pub fn reserve(&mut self, additional: usize) {
+ self.map.reserve(additional);
+ }
+
+ /// Shrinks the capacity of the map as much as possible. It will drop down
+ /// as much as possible while maintaining the internal rules and possibly
+ /// leaving some space in accordance with the resize policy.
+ #[inline]
+ pub fn shrink_to_fit(&mut self) {
+ self.map.shrink_to_fit();
+ }
+
+ /// Inserts a key-value pair into the map. If the key already existed, the
+ /// old value is returned.
+ #[inline]
+ pub fn insert(&mut self, k: Value, v: Value) -> Option<Value> {
+ self.map.insert(k, v)
+ }
+
+ /// Checks if the map contains the given key.
+ #[inline]
+ pub fn contains_key(&self, k: &Value) -> bool {
+ self.map.contains_key(k)
+ }
+
+ /// Returns the value corresponding to the key in the map.
+ #[inline]
+ pub fn get(&self, k: &Value) -> Option<&Value> {
+ self.map.get(k)
+ }
+
+ /// Returns the mutable reference corresponding to the key in the map.
+ #[inline]
+ pub fn get_mut(&mut self, k: &Value) -> Option<&mut Value> {
+ self.map.get_mut(k)
+ }
+
+ /// Gets the given key’s corresponding entry in the map for insertion and/or
+ /// in-place manipulation.
+ #[inline]
+ pub fn entry(&mut self, k: Value) -> Entry {
+ match self.map.entry(k) {
+ indexmap::map::Entry::Occupied(occupied) => Entry::Occupied(OccupiedEntry { occupied }),
+ indexmap::map::Entry::Vacant(vacant) => Entry::Vacant(VacantEntry { vacant }),
+ }
+ }
+
+ /// Removes and returns the value corresponding to the key from the map.
+ #[inline]
+ pub fn remove(&mut self, k: &Value) -> Option<Value> {
+ self.map.remove(k)
+ }
+
+ /// Returns the maximum number of key-value pairs the map can hold without
+ /// reallocating.
+ #[inline]
+ pub fn capacity(&self) -> usize {
+ self.map.capacity()
+ }
+
+ /// Returns the number of key-value pairs in the map.
+ #[inline]
+ pub fn len(&self) -> usize {
+ self.map.len()
+ }
+
+ /// Returns whether the map is currently empty.
+ #[inline]
+ pub fn is_empty(&self) -> bool {
+ self.map.is_empty()
+ }
+
+ /// Clears the map of all key-value pairs.
+ #[inline]
+ pub fn clear(&mut self) {
+ self.map.clear();
+ }
+
+ /// Returns a double-ended iterator visiting all key-value pairs in order of
+ /// insertion. Iterator element type is `(&'a Value, &'a Value)`.
+ #[inline]
+ pub fn iter(&self) -> Iter {
+ Iter {
+ iter: self.map.iter(),
+ }
+ }
+
+ /// Returns a double-ended iterator visiting all key-value pairs in order of
+ /// insertion. Iterator element type is `(&'a Value, &'a mut ValuE)`.
+ #[inline]
+ pub fn iter_mut(&mut self) -> IterMut {
+ IterMut {
+ iter: self.map.iter_mut(),
+ }
+ }
+}
+
+#[allow(clippy::derive_hash_xor_eq)]
+impl Hash for Mapping {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ // Hash the kv pairs in a way that is not sensitive to their order.
+ let mut xor = 0;
+ for (k, v) in self {
+ let mut hasher = DefaultHasher::new();
+ k.hash(&mut hasher);
+ v.hash(&mut hasher);
+ xor ^= hasher.finish();
+ }
+ xor.hash(state);
+ }
+}
+
+impl PartialOrd for Mapping {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ let mut self_entries = Vec::from_iter(self);
+ let mut other_entries = Vec::from_iter(other);
+
+ // Sort in an arbitrary order that is consistent with Value's PartialOrd
+ // impl.
+ fn total_cmp(a: &Value, b: &Value) -> Ordering {
+ match (a, b) {
+ (Value::Null, Value::Null) => Ordering::Equal,
+ (Value::Null, _) => Ordering::Less,
+ (_, Value::Null) => Ordering::Greater,
+
+ (Value::Bool(a), Value::Bool(b)) => a.cmp(b),
+ (Value::Bool(_), _) => Ordering::Less,
+ (_, Value::Bool(_)) => Ordering::Greater,
+
+ (Value::Number(a), Value::Number(b)) => a.total_cmp(b),
+ (Value::Number(_), _) => Ordering::Less,
+ (_, Value::Number(_)) => Ordering::Greater,
+
+ (Value::String(a), Value::String(b)) => a.cmp(b),
+ (Value::String(_), _) => Ordering::Less,
+ (_, Value::String(_)) => Ordering::Greater,
+
+ (Value::Sequence(a), Value::Sequence(b)) => iter_cmp_by(a, b, total_cmp),
+ (Value::Sequence(_), _) => Ordering::Less,
+ (_, Value::Sequence(_)) => Ordering::Greater,
+
+ (Value::Mapping(a), Value::Mapping(b)) => {
+ iter_cmp_by(a, b, |(ak, av), (bk, bv)| {
+ total_cmp(ak, bk).then_with(|| total_cmp(av, bv))
+ })
+ }
+ }
+ }
+
+ fn iter_cmp_by<I, F>(this: I, other: I, mut cmp: F) -> Ordering
+ where
+ I: IntoIterator,
+ F: FnMut(I::Item, I::Item) -> Ordering,
+ {
+ let mut this = this.into_iter();
+ let mut other = other.into_iter();
+
+ loop {
+ let x = match this.next() {
+ None => {
+ if other.next().is_none() {
+ return Ordering::Equal;
+ } else {
+ return Ordering::Less;
+ }
+ }
+ Some(val) => val,
+ };
+
+ let y = match other.next() {
+ None => return Ordering::Greater,
+ Some(val) => val,
+ };
+
+ match cmp(x, y) {
+ Ordering::Equal => {}
+ non_eq => return non_eq,
+ }
+ }
+ }
+
+ // While sorting by map key, we get to assume that no two keys are
+ // equal, otherwise they wouldn't both be in the map. This is not a safe
+ // assumption outside of this situation.
+ let total_cmp = |&(a, _): &_, &(b, _): &_| total_cmp(a, b);
+ self_entries.sort_by(total_cmp);
+ other_entries.sort_by(total_cmp);
+ self_entries.partial_cmp(&other_entries)
+ }
+}
+
+impl<'a> Index<&'a Value> for Mapping {
+ type Output = Value;
+ #[inline]
+ fn index(&self, index: &'a Value) -> &Value {
+ self.map.index(index)
+ }
+}
+
+impl<'a> IndexMut<&'a Value> for Mapping {
+ #[inline]
+ fn index_mut(&mut self, index: &'a Value) -> &mut Value {
+ self.map.index_mut(index)
+ }
+}
+
+impl Extend<(Value, Value)> for Mapping {
+ #[inline]
+ fn extend<I: IntoIterator<Item = (Value, Value)>>(&mut self, iter: I) {
+ self.map.extend(iter);
+ }
+}
+
+impl FromIterator<(Value, Value)> for Mapping {
+ #[inline]
+ fn from_iter<I: IntoIterator<Item = (Value, Value)>>(iter: I) -> Self {
+ Mapping {
+ map: IndexMap::from_iter(iter),
+ }
+ }
+}
+
+macro_rules! delegate_iterator {
+ (($name:ident $($generics:tt)*) => $item:ty) => {
+ impl $($generics)* Iterator for $name $($generics)* {
+ type Item = $item;
+ #[inline]
+ fn next(&mut self) -> Option<Self::Item> {
+ self.iter.next()
+ }
+ #[inline]
+ fn size_hint(&self) -> (usize, Option<usize>) {
+ self.iter.size_hint()
+ }
+ }
+
+ impl $($generics)* ExactSizeIterator for $name $($generics)* {
+ #[inline]
+ fn len(&self) -> usize {
+ self.iter.len()
+ }
+ }
+ }
+}
+
+/// Iterator over `&serde_yaml::Mapping`.
+pub struct Iter<'a> {
+ iter: indexmap::map::Iter<'a, Value, Value>,
+}
+
+delegate_iterator!((Iter<'a>) => (&'a Value, &'a Value));
+
+impl<'a> IntoIterator for &'a Mapping {
+ type Item = (&'a Value, &'a Value);
+ type IntoIter = Iter<'a>;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ Iter {
+ iter: self.map.iter(),
+ }
+ }
+}
+
+/// Iterator over `&mut serde_yaml::Mapping`.
+pub struct IterMut<'a> {
+ iter: indexmap::map::IterMut<'a, Value, Value>,
+}
+
+delegate_iterator!((IterMut<'a>) => (&'a Value, &'a mut Value));
+
+impl<'a> IntoIterator for &'a mut Mapping {
+ type Item = (&'a Value, &'a mut Value);
+ type IntoIter = IterMut<'a>;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ IterMut {
+ iter: self.map.iter_mut(),
+ }
+ }
+}
+
+/// Iterator over `serde_yaml::Mapping` by value.
+pub struct IntoIter {
+ iter: indexmap::map::IntoIter<Value, Value>,
+}
+
+delegate_iterator!((IntoIter) => (Value, Value));
+
+impl IntoIterator for Mapping {
+ type Item = (Value, Value);
+ type IntoIter = IntoIter;
+ #[inline]
+ fn into_iter(self) -> Self::IntoIter {
+ IntoIter {
+ iter: self.map.into_iter(),
+ }
+ }
+}
+
+/// Entry for an existing key-value pair or a vacant location to insert one.
+pub enum Entry<'a> {
+ /// Existing slot with equivalent key.
+ Occupied(OccupiedEntry<'a>),
+ /// Vacant slot (no equivalent key in the map).
+ Vacant(VacantEntry<'a>),
+}
+
+/// A view into an occupied entry in a [`Mapping`]. It is part of the [`Entry`]
+/// enum.
+pub struct OccupiedEntry<'a> {
+ occupied: indexmap::map::OccupiedEntry<'a, Value, Value>,
+}
+
+/// A view into a vacant entry in a [`Mapping`]. It is part of the [`Entry`]
+/// enum.
+pub struct VacantEntry<'a> {
+ vacant: indexmap::map::VacantEntry<'a, Value, Value>,
+}
+
+impl<'a> Entry<'a> {
+ /// Returns a reference to this entry's key.
+ pub fn key(&self) -> &Value {
+ match self {
+ Entry::Vacant(e) => e.key(),
+ Entry::Occupied(e) => e.key(),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting the default if empty, and
+ /// returns a mutable reference to the value in the entry.
+ pub fn or_insert(self, default: Value) -> &'a mut Value {
+ match self {
+ Entry::Vacant(entry) => entry.insert(default),
+ Entry::Occupied(entry) => entry.into_mut(),
+ }
+ }
+
+ /// Ensures a value is in the entry by inserting the result of the default
+ /// function if empty, and returns a mutable reference to the value in the
+ /// entry.
+ pub fn or_insert_with<F>(self, default: F) -> &'a mut Value
+ where
+ F: FnOnce() -> Value,
+ {
+ match self {
+ Entry::Vacant(entry) => entry.insert(default()),
+ Entry::Occupied(entry) => entry.into_mut(),
+ }
+ }
+
+ /// Provides in-place mutable access to an occupied entry before any
+ /// potential inserts into the map.
+ pub fn and_modify<F>(self, f: F) -> Self
+ where
+ F: FnOnce(&mut Value),
+ {
+ match self {
+ Entry::Occupied(mut entry) => {
+ f(entry.get_mut());
+ Entry::Occupied(entry)
+ }
+ Entry::Vacant(entry) => Entry::Vacant(entry),
+ }
+ }
+}
+
+impl<'a> OccupiedEntry<'a> {
+ /// Gets a reference to the key in the entry.
+ #[inline]
+ pub fn key(&self) -> &Value {
+ self.occupied.key()
+ }
+
+ /// Gets a reference to the value in the entry.
+ #[inline]
+ pub fn get(&self) -> &Value {
+ self.occupied.get()
+ }
+
+ /// Gets a mutable reference to the value in the entry.
+ #[inline]
+ pub fn get_mut(&mut self) -> &mut Value {
+ self.occupied.get_mut()
+ }
+
+ /// Converts the entry into a mutable reference to its value.
+ #[inline]
+ pub fn into_mut(self) -> &'a mut Value {
+ self.occupied.into_mut()
+ }
+
+ /// Sets the value of the entry with the `OccupiedEntry`'s key, and returns
+ /// the entry's old value.
+ #[inline]
+ pub fn insert(&mut self, value: Value) -> Value {
+ self.occupied.insert(value)
+ }
+
+ /// Takes the value of the entry out of the map, and returns it.
+ #[inline]
+ pub fn remove(self) -> Value {
+ self.occupied.swap_remove()
+ }
+}
+
+impl<'a> VacantEntry<'a> {
+ /// Gets a reference to the key that would be used when inserting a value
+ /// through the VacantEntry.
+ #[inline]
+ pub fn key(&self) -> &Value {
+ self.vacant.key()
+ }
+
+ /// Sets the value of the entry with the VacantEntry's key, and returns a
+ /// mutable reference to it.
+ #[inline]
+ pub fn insert(self, value: Value) -> &'a mut Value {
+ self.vacant.insert(value)
+ }
+}
+
+impl Serialize for Mapping {
+ #[inline]
+ fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
+ use serde::ser::SerializeMap;
+ let mut map_serializer = serializer.serialize_map(Some(self.len()))?;
+ for (k, v) in self {
+ map_serializer.serialize_entry(k, v)?;
+ }
+ map_serializer.end()
+ }
+}
+
+impl<'de> Deserialize<'de> for Mapping {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct Visitor;
+
+ impl<'de> serde::de::Visitor<'de> for Visitor {
+ type Value = Mapping;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a YAML mapping")
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<Self::Value, E>
+ where
+ E: serde::de::Error,
+ {
+ Ok(Mapping::new())
+ }
+
+ #[inline]
+ fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ where
+ V: serde::de::MapAccess<'de>,
+ {
+ let mut values = Mapping::new();
+ while let Some((k, v)) = visitor.next_entry()? {
+ values.insert(k, v);
+ }
+ Ok(values)
+ }
+ }
+
+ deserializer.deserialize_map(Visitor)
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/number.rs b/third_party/rust/serde_yaml/src/number.rs
new file mode 100644
index 0000000000..b3643ba8b1
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/number.rs
@@ -0,0 +1,550 @@
+use crate::Error;
+use serde::de::{Unexpected, Visitor};
+use serde::{forward_to_deserialize_any, Deserialize, Deserializer, Serialize, Serializer};
+use std::cmp::Ordering;
+use std::fmt::{self, Debug, Display};
+use std::hash::{Hash, Hasher};
+use std::i64;
+
+/// Represents a YAML number, whether integer or floating point.
+#[derive(Clone, PartialEq, PartialOrd)]
+pub struct Number {
+ n: N,
+}
+
+// "N" is a prefix of "NegInt"... this is a false positive.
+// https://github.com/Manishearth/rust-clippy/issues/1241
+#[allow(clippy::enum_variant_names)]
+#[derive(Copy, Clone, Debug)]
+enum N {
+ PosInt(u64),
+ /// Always less than zero.
+ NegInt(i64),
+ /// May be infinite or NaN.
+ Float(f64),
+}
+
+impl Number {
+ /// Returns true if the `Number` is an integer between `i64::MIN` and
+ /// `i64::MAX`.
+ ///
+ /// For any Number on which `is_i64` returns true, `as_i64` is guaranteed to
+ /// return the integer value.
+ ///
+ /// ```
+ /// # use std::i64;
+ /// #
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let big = i64::MAX as u64 + 10;
+ /// let v = yaml(r#"
+ /// a: 64
+ /// b: 9223372036854775817
+ /// c: 256.0
+ /// "#);
+ ///
+ /// assert!(v["a"].is_i64());
+ ///
+ /// // Greater than i64::MAX.
+ /// assert!(!v["b"].is_i64());
+ ///
+ /// // Numbers with a decimal point are not considered integers.
+ /// assert!(!v["c"].is_i64());
+ /// ```
+ #[inline]
+ #[allow(clippy::cast_sign_loss)]
+ pub fn is_i64(&self) -> bool {
+ match self.n {
+ N::PosInt(v) => v <= i64::max_value() as u64,
+ N::NegInt(_) => true,
+ N::Float(_) => false,
+ }
+ }
+
+ /// Returns true if the `Number` is an integer between zero and `u64::MAX`.
+ ///
+ /// For any Number on which `is_u64` returns true, `as_u64` is guaranteed to
+ /// return the integer value.
+ ///
+ /// ```
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let v = yaml(r#"
+ /// a: 64
+ /// b: -64
+ /// c: 256.0
+ /// "#);
+ ///
+ /// assert!(v["a"].is_u64());
+ ///
+ /// // Negative integer.
+ /// assert!(!v["b"].is_u64());
+ ///
+ /// // Numbers with a decimal point are not considered integers.
+ /// assert!(!v["c"].is_u64());
+ /// ```
+ #[inline]
+ pub fn is_u64(&self) -> bool {
+ match self.n {
+ N::PosInt(_) => true,
+ N::NegInt(_) | N::Float(_) => false,
+ }
+ }
+
+ /// Returns true if the `Number` can be represented by f64.
+ ///
+ /// For any Number on which `is_f64` returns true, `as_f64` is guaranteed to
+ /// return the floating point value.
+ ///
+ /// Currently this function returns true if and only if both `is_i64` and
+ /// `is_u64` return false but this is not a guarantee in the future.
+ ///
+ /// ```
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let v = yaml(r#"
+ /// ---
+ /// a: 256.0
+ /// b: 64
+ /// c: -64
+ /// "#);
+ ///
+ /// assert!(v["a"].is_f64());
+ ///
+ /// // Integers.
+ /// assert!(!v["b"].is_f64());
+ /// assert!(!v["c"].is_f64());
+ /// ```
+ #[inline]
+ pub fn is_f64(&self) -> bool {
+ match self.n {
+ N::Float(_) => true,
+ N::PosInt(_) | N::NegInt(_) => false,
+ }
+ }
+
+ /// If the `Number` is an integer, represent it as i64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use std::i64;
+ /// #
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let big = i64::MAX as u64 + 10;
+ /// let v = yaml(r#"
+ /// ---
+ /// a: 64
+ /// b: 9223372036854775817
+ /// c: 256.0
+ /// "#);
+ ///
+ /// assert_eq!(v["a"].as_i64(), Some(64));
+ /// assert_eq!(v["b"].as_i64(), None);
+ /// assert_eq!(v["c"].as_i64(), None);
+ /// ```
+ #[inline]
+ pub fn as_i64(&self) -> Option<i64> {
+ match self.n {
+ N::PosInt(n) => {
+ if n <= i64::max_value() as u64 {
+ Some(n as i64)
+ } else {
+ None
+ }
+ }
+ N::NegInt(n) => Some(n),
+ N::Float(_) => None,
+ }
+ }
+
+ /// If the `Number` is an integer, represent it as u64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let v = yaml(r#"
+ /// ---
+ /// a: 64
+ /// b: -64
+ /// c: 256.0
+ /// "#);
+ ///
+ /// assert_eq!(v["a"].as_u64(), Some(64));
+ /// assert_eq!(v["b"].as_u64(), None);
+ /// assert_eq!(v["c"].as_u64(), None);
+ /// ```
+ #[inline]
+ pub fn as_u64(&self) -> Option<u64> {
+ match self.n {
+ N::PosInt(n) => Some(n),
+ N::NegInt(_) | N::Float(_) => None,
+ }
+ }
+
+ /// Represents the number as f64 if possible. Returns None otherwise.
+ ///
+ /// ```
+ /// #
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// let v = yaml(r#"
+ /// ---
+ /// a: 256.0
+ /// b: 64
+ /// c: -64
+ /// "#);
+ ///
+ /// assert_eq!(v["a"].as_f64(), Some(256.0));
+ /// assert_eq!(v["b"].as_f64(), Some(64.0));
+ /// assert_eq!(v["c"].as_f64(), Some(-64.0));
+ /// ```
+ ///
+ /// ```
+ /// # use std::f64;
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// assert_eq!(yaml(".inf").as_f64(), Some(f64::INFINITY));
+ /// assert_eq!(yaml("-.inf").as_f64(), Some(f64::NEG_INFINITY));
+ /// assert!(yaml(".nan").as_f64().unwrap().is_nan());
+ /// ```
+ #[inline]
+ pub fn as_f64(&self) -> Option<f64> {
+ match self.n {
+ N::PosInt(n) => Some(n as f64),
+ N::NegInt(n) => Some(n as f64),
+ N::Float(n) => Some(n),
+ }
+ }
+
+ /// Returns true if this value is NaN and false otherwise.
+ ///
+ /// ```
+ /// # use std::f64;
+ /// #
+ /// # use serde_yaml::Number;
+ /// #
+ /// assert!(!Number::from(256.0).is_nan());
+ ///
+ /// assert!(Number::from(f64::NAN).is_nan());
+ ///
+ /// assert!(!Number::from(f64::INFINITY).is_nan());
+ ///
+ /// assert!(!Number::from(f64::NEG_INFINITY).is_nan());
+ ///
+ /// assert!(!Number::from(1).is_nan());
+ /// ```
+ #[inline]
+ pub fn is_nan(&self) -> bool {
+ match self.n {
+ N::PosInt(_) | N::NegInt(_) => false,
+ N::Float(f) => f.is_nan(),
+ }
+ }
+
+ /// Returns true if this value is positive infinity or negative infinity and
+ /// false otherwise.
+ ///
+ /// ```
+ /// # use std::f64;
+ /// #
+ /// # use serde_yaml::Number;
+ /// #
+ /// assert!(!Number::from(256.0).is_infinite());
+ ///
+ /// assert!(!Number::from(f64::NAN).is_infinite());
+ ///
+ /// assert!(Number::from(f64::INFINITY).is_infinite());
+ ///
+ /// assert!(Number::from(f64::NEG_INFINITY).is_infinite());
+ ///
+ /// assert!(!Number::from(1).is_infinite());
+ /// ```
+ #[inline]
+ pub fn is_infinite(&self) -> bool {
+ match self.n {
+ N::PosInt(_) | N::NegInt(_) => false,
+ N::Float(f) => f.is_infinite(),
+ }
+ }
+
+ /// Returns true if this number is neither infinite nor NaN.
+ ///
+ /// ```
+ /// # use std::f64;
+ /// #
+ /// # use serde_yaml::Number;
+ /// #
+ /// assert!(Number::from(256.0).is_finite());
+ ///
+ /// assert!(!Number::from(f64::NAN).is_finite());
+ ///
+ /// assert!(!Number::from(f64::INFINITY).is_finite());
+ ///
+ /// assert!(!Number::from(f64::NEG_INFINITY).is_finite());
+ ///
+ /// assert!(Number::from(1).is_finite());
+ /// ```
+ #[inline]
+ pub fn is_finite(&self) -> bool {
+ match self.n {
+ N::PosInt(_) | N::NegInt(_) => true,
+ N::Float(f) => f.is_finite(),
+ }
+ }
+}
+
+impl fmt::Display for Number {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self.n {
+ N::PosInt(i) => Display::fmt(&i, formatter),
+ N::NegInt(i) => Display::fmt(&i, formatter),
+ N::Float(f) if f.is_nan() => formatter.write_str(".nan"),
+ N::Float(f) if f.is_infinite() => {
+ if f.is_sign_negative() {
+ formatter.write_str("-.inf")
+ } else {
+ formatter.write_str(".inf")
+ }
+ }
+ N::Float(f) => Display::fmt(&f, formatter),
+ }
+ }
+}
+
+impl Debug for Number {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ Debug::fmt(&self.n, formatter)
+ }
+}
+
+impl PartialEq for N {
+ fn eq(&self, other: &N) -> bool {
+ match (*self, *other) {
+ (N::PosInt(a), N::PosInt(b)) => a == b,
+ (N::NegInt(a), N::NegInt(b)) => a == b,
+ (N::Float(a), N::Float(b)) => {
+ if a.is_nan() && b.is_nan() {
+ // YAML only has one NaN;
+ // the bit representation isn't preserved
+ true
+ } else {
+ a == b
+ }
+ }
+ _ => false,
+ }
+ }
+}
+
+impl PartialOrd for N {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ match (*self, *other) {
+ (N::Float(a), N::Float(b)) => {
+ if a.is_nan() && b.is_nan() {
+ // YAML only has one NaN
+ Some(Ordering::Equal)
+ } else {
+ a.partial_cmp(&b)
+ }
+ }
+ _ => Some(self.total_cmp(other)),
+ }
+ }
+}
+
+impl N {
+ fn total_cmp(&self, other: &Self) -> Ordering {
+ match (*self, *other) {
+ (N::PosInt(a), N::PosInt(b)) => a.cmp(&b),
+ (N::NegInt(a), N::NegInt(b)) => a.cmp(&b),
+ // negint is always less than zero
+ (N::NegInt(_), N::PosInt(_)) => Ordering::Less,
+ (N::PosInt(_), N::NegInt(_)) => Ordering::Greater,
+ (N::Float(a), N::Float(b)) => a.partial_cmp(&b).unwrap_or_else(|| {
+ // arbitrarily sort the NaN last
+ if !a.is_nan() {
+ Ordering::Less
+ } else if !b.is_nan() {
+ Ordering::Greater
+ } else {
+ Ordering::Equal
+ }
+ }),
+ // arbitrarily sort integers below floats
+ // FIXME: maybe something more sensible?
+ (_, N::Float(_)) => Ordering::Less,
+ (N::Float(_), _) => Ordering::Greater,
+ }
+ }
+}
+
+impl Number {
+ pub(crate) fn total_cmp(&self, other: &Self) -> Ordering {
+ self.n.total_cmp(&other.n)
+ }
+}
+
+impl Serialize for Number {
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ match self.n {
+ N::PosInt(i) => serializer.serialize_u64(i),
+ N::NegInt(i) => serializer.serialize_i64(i),
+ N::Float(f) => serializer.serialize_f64(f),
+ }
+ }
+}
+
+impl<'de> Deserialize<'de> for Number {
+ #[inline]
+ fn deserialize<D>(deserializer: D) -> Result<Number, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct NumberVisitor;
+
+ impl<'de> Visitor<'de> for NumberVisitor {
+ type Value = Number;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a number")
+ }
+
+ #[inline]
+ fn visit_i64<E>(self, value: i64) -> Result<Number, E> {
+ Ok(value.into())
+ }
+
+ #[inline]
+ fn visit_u64<E>(self, value: u64) -> Result<Number, E> {
+ Ok(value.into())
+ }
+
+ #[inline]
+ fn visit_f64<E>(self, value: f64) -> Result<Number, E> {
+ Ok(value.into())
+ }
+ }
+
+ deserializer.deserialize_any(NumberVisitor)
+ }
+}
+
+impl<'de> Deserializer<'de> for Number {
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.n {
+ N::PosInt(i) => visitor.visit_u64(i),
+ N::NegInt(i) => visitor.visit_i64(i),
+ N::Float(f) => visitor.visit_f64(f),
+ }
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+impl<'de, 'a> Deserializer<'de> for &'a Number {
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.n {
+ N::PosInt(i) => visitor.visit_u64(i),
+ N::NegInt(i) => visitor.visit_i64(i),
+ N::Float(f) => visitor.visit_f64(f),
+ }
+ }
+
+ forward_to_deserialize_any! {
+ bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
+ bytes byte_buf option unit unit_struct newtype_struct seq tuple
+ tuple_struct map struct enum identifier ignored_any
+ }
+}
+
+macro_rules! from_signed {
+ ($($signed_ty:ident)*) => {
+ $(
+ impl From<$signed_ty> for Number {
+ #[inline]
+ #[allow(clippy::cast_sign_loss)]
+ fn from(i: $signed_ty) -> Self {
+ if i < 0 {
+ Number { n: N::NegInt(i as i64) }
+ } else {
+ Number { n: N::PosInt(i as u64) }
+ }
+ }
+ }
+ )*
+ };
+}
+
+macro_rules! from_unsigned {
+ ($($unsigned_ty:ident)*) => {
+ $(
+ impl From<$unsigned_ty> for Number {
+ #[inline]
+ fn from(u: $unsigned_ty) -> Self {
+ Number { n: N::PosInt(u as u64) }
+ }
+ }
+ )*
+ };
+}
+
+macro_rules! from_float {
+ ($($float_ty:ident)*) => {
+ $(
+ impl From<$float_ty> for Number {
+ #[inline]
+ fn from(f: $float_ty) -> Self {
+ Number { n: N::Float(f as f64) }
+ }
+ }
+ )*
+ }
+}
+
+from_signed!(i8 i16 i32 i64 isize);
+from_unsigned!(u8 u16 u32 u64 usize);
+from_float!(f32 f64);
+
+// This is fine, because we don't _really_ implement hash for floats
+// all other hash functions should work as expected
+#[allow(clippy::derive_hash_xor_eq)]
+impl Hash for Number {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ match self.n {
+ N::Float(_) => {
+ // you should feel bad for using f64 as a map key
+ 3.hash(state);
+ }
+ N::PosInt(u) => u.hash(state),
+ N::NegInt(i) => i.hash(state),
+ }
+ }
+}
+
+pub(crate) fn unexpected(number: &Number) -> Unexpected {
+ match number.n {
+ N::PosInt(u) => Unexpected::Unsigned(u),
+ N::NegInt(i) => Unexpected::Signed(i),
+ N::Float(f) => Unexpected::Float(f),
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/path.rs b/third_party/rust/serde_yaml/src/path.rs
new file mode 100644
index 0000000000..095add017b
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/path.rs
@@ -0,0 +1,34 @@
+use std::fmt::{self, Display};
+
+/// Path to the current value in the input, like `dependencies.serde.typo1`.
+#[derive(Copy, Clone)]
+pub enum Path<'a> {
+ Root,
+ Seq { parent: &'a Path<'a>, index: usize },
+ Map { parent: &'a Path<'a>, key: &'a str },
+ Alias { parent: &'a Path<'a> },
+ Unknown { parent: &'a Path<'a> },
+}
+
+impl<'a> Display for Path<'a> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ struct Parent<'a>(&'a Path<'a>);
+
+ impl<'a> Display for Parent<'a> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
+ match self.0 {
+ Path::Root => Ok(()),
+ path => write!(formatter, "{}.", path),
+ }
+ }
+ }
+
+ match self {
+ Path::Root => formatter.write_str("."),
+ Path::Seq { parent, index } => write!(formatter, "{}[{}]", parent, index),
+ Path::Map { parent, key } => write!(formatter, "{}{}", Parent(parent), key),
+ Path::Alias { parent } => write!(formatter, "{}", parent),
+ Path::Unknown { parent } => write!(formatter, "{}?", Parent(parent)),
+ }
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/ser.rs b/third_party/rust/serde_yaml/src/ser.rs
new file mode 100644
index 0000000000..6ce5995dff
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/ser.rs
@@ -0,0 +1,887 @@
+//! YAML Serialization
+//!
+//! This module provides YAML serialization with the type `Serializer`.
+
+use crate::{error, Error, Result};
+use serde::ser;
+use std::{fmt, io, num, str};
+use yaml_rust::{yaml, Yaml, YamlEmitter};
+
+/// A structure for serializing Rust values into YAML.
+///
+/// # Example
+///
+/// ```
+/// use anyhow::Result;
+/// use serde::Serialize;
+/// use std::collections::BTreeMap;
+///
+/// fn main() -> Result<()> {
+/// let mut buffer = Vec::new();
+/// let mut ser = serde_yaml::Serializer::new(&mut buffer);
+///
+/// let mut object = BTreeMap::new();
+/// object.insert("k", 107);
+/// object.serialize(&mut ser)?;
+///
+/// object.insert("J", 74);
+/// object.serialize(&mut ser)?;
+///
+/// assert_eq!(buffer, b"---\nk: 107\n...\n---\nJ: 74\nk: 107\n");
+/// Ok(())
+/// }
+/// ```
+pub struct Serializer<W> {
+ documents: usize,
+ writer: W,
+}
+
+impl<W> Serializer<W>
+where
+ W: io::Write,
+{
+ /// Creates a new YAML serializer.
+ pub fn new(writer: W) -> Self {
+ Serializer {
+ documents: 0,
+ writer,
+ }
+ }
+
+ /// Calls [`.flush()`](io::Write::flush) on the underlying `io::Write`
+ /// object.
+ pub fn flush(&mut self) -> io::Result<()> {
+ self.writer.flush()
+ }
+
+ /// Unwrap the underlying `io::Write` object from the `Serializer`.
+ pub fn into_inner(self) -> W {
+ self.writer
+ }
+
+ fn write(&mut self, doc: Yaml) -> Result<()> {
+ if self.documents > 0 {
+ self.writer.write_all(b"...\n").map_err(error::io)?;
+ }
+ self.documents += 1;
+ let mut writer_adapter = FmtToIoWriter {
+ writer: &mut self.writer,
+ };
+ YamlEmitter::new(&mut writer_adapter)
+ .dump(&doc)
+ .map_err(error::emitter)?;
+ writer_adapter.writer.write_all(b"\n").map_err(error::io)?;
+ Ok(())
+ }
+}
+
+impl<'a, W> ser::Serializer for &'a mut Serializer<W>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ type SerializeSeq = ThenWrite<'a, W, SerializeArray>;
+ type SerializeTuple = ThenWrite<'a, W, SerializeArray>;
+ type SerializeTupleStruct = ThenWrite<'a, W, SerializeArray>;
+ type SerializeTupleVariant = ThenWrite<'a, W, SerializeTupleVariant>;
+ type SerializeMap = ThenWrite<'a, W, SerializeMap>;
+ type SerializeStruct = ThenWrite<'a, W, SerializeStruct>;
+ type SerializeStructVariant = ThenWrite<'a, W, SerializeStructVariant>;
+
+ fn serialize_bool(self, v: bool) -> Result<()> {
+ let doc = SerializerToYaml.serialize_bool(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<()> {
+ let doc = SerializerToYaml.serialize_i8(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<()> {
+ let doc = SerializerToYaml.serialize_i16(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<()> {
+ let doc = SerializerToYaml.serialize_i32(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<()> {
+ let doc = SerializerToYaml.serialize_i64(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_i128(self, v: i128) -> Result<()> {
+ let doc = SerializerToYaml.serialize_i128(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<()> {
+ let doc = SerializerToYaml.serialize_u8(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<()> {
+ let doc = SerializerToYaml.serialize_u16(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<()> {
+ let doc = SerializerToYaml.serialize_u32(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<()> {
+ let doc = SerializerToYaml.serialize_u64(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_u128(self, v: u128) -> Result<()> {
+ let doc = SerializerToYaml.serialize_u128(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<()> {
+ let doc = SerializerToYaml.serialize_f32(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<()> {
+ let doc = SerializerToYaml.serialize_f64(v)?;
+ self.write(doc)
+ }
+
+ fn serialize_char(self, value: char) -> Result<()> {
+ let doc = SerializerToYaml.serialize_char(value)?;
+ self.write(doc)
+ }
+
+ fn serialize_str(self, value: &str) -> Result<()> {
+ let doc = SerializerToYaml.serialize_str(value)?;
+ self.write(doc)
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<()> {
+ let doc = SerializerToYaml.serialize_bytes(value)?;
+ self.write(doc)
+ }
+
+ fn serialize_unit(self) -> Result<()> {
+ let doc = SerializerToYaml.serialize_unit()?;
+ self.write(doc)
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
+ let doc = SerializerToYaml.serialize_unit_struct(name)?;
+ self.write(doc)
+ }
+
+ fn serialize_unit_variant(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ ) -> Result<()> {
+ let doc = SerializerToYaml.serialize_unit_variant(name, variant_index, variant)?;
+ self.write(doc)
+ }
+
+ fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ let doc = SerializerToYaml.serialize_newtype_struct(name, value)?;
+ self.write(doc)
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T,
+ ) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ let doc =
+ SerializerToYaml.serialize_newtype_variant(name, variant_index, variant, value)?;
+ self.write(doc)
+ }
+
+ fn serialize_none(self) -> Result<()> {
+ let doc = SerializerToYaml.serialize_none()?;
+ self.write(doc)
+ }
+
+ fn serialize_some<V>(self, value: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ let doc = SerializerToYaml.serialize_some(value)?;
+ self.write(doc)
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq> {
+ let delegate = SerializerToYaml.serialize_seq(len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple> {
+ let delegate = SerializerToYaml.serialize_tuple(len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_tuple_struct(
+ self,
+ name: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleStruct> {
+ let delegate = SerializerToYaml.serialize_tuple_struct(name, len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ enm: &'static str,
+ idx: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeTupleVariant> {
+ let delegate = SerializerToYaml.serialize_tuple_variant(enm, idx, variant, len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap> {
+ let delegate = SerializerToYaml.serialize_map(len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self::SerializeStruct> {
+ let delegate = SerializerToYaml.serialize_struct(name, len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+
+ fn serialize_struct_variant(
+ self,
+ enm: &'static str,
+ idx: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<Self::SerializeStructVariant> {
+ let delegate = SerializerToYaml.serialize_struct_variant(enm, idx, variant, len)?;
+ Ok(ThenWrite::new(self, delegate))
+ }
+}
+
+pub struct ThenWrite<'a, W, D> {
+ serializer: &'a mut Serializer<W>,
+ delegate: D,
+}
+
+impl<'a, W, D> ThenWrite<'a, W, D> {
+ fn new(serializer: &'a mut Serializer<W>, delegate: D) -> Self {
+ ThenWrite {
+ serializer,
+ delegate,
+ }
+ }
+}
+
+impl<'a, W> ser::SerializeSeq for ThenWrite<'a, W, SerializeArray>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_element(elem)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeTuple for ThenWrite<'a, W, SerializeArray>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_element(elem)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeTupleStruct for ThenWrite<'a, W, SerializeArray>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, value: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_field(value)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeTupleVariant for ThenWrite<'a, W, SerializeTupleVariant>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, v: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_field(v)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeMap for ThenWrite<'a, W, SerializeMap>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_key<T>(&mut self, key: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_key(key)
+ }
+
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_value(value)
+ }
+
+ fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>
+ where
+ K: ?Sized + ser::Serialize,
+ V: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_entry(key, value)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeStruct for ThenWrite<'a, W, SerializeStruct>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, key: &'static str, value: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_field(key, value)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+impl<'a, W> ser::SerializeStructVariant for ThenWrite<'a, W, SerializeStructVariant>
+where
+ W: io::Write,
+{
+ type Ok = ();
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, field: &'static str, v: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.delegate.serialize_field(field, v)
+ }
+
+ fn end(self) -> Result<()> {
+ let doc = self.delegate.end()?;
+ self.serializer.write(doc)
+ }
+}
+
+pub struct SerializerToYaml;
+
+impl ser::Serializer for SerializerToYaml {
+ type Ok = Yaml;
+ type Error = Error;
+
+ type SerializeSeq = SerializeArray;
+ type SerializeTuple = SerializeArray;
+ type SerializeTupleStruct = SerializeArray;
+ type SerializeTupleVariant = SerializeTupleVariant;
+ type SerializeMap = SerializeMap;
+ type SerializeStruct = SerializeStruct;
+ type SerializeStructVariant = SerializeStructVariant;
+
+ fn serialize_bool(self, v: bool) -> Result<Yaml> {
+ Ok(Yaml::Boolean(v))
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<Yaml> {
+ Ok(Yaml::Integer(v))
+ }
+
+ #[allow(clippy::cast_possible_truncation)]
+ fn serialize_i128(self, v: i128) -> Result<Yaml> {
+ if v <= i64::max_value() as i128 && v >= i64::min_value() as i128 {
+ self.serialize_i64(v as i64)
+ } else {
+ Ok(Yaml::Real(v.to_string()))
+ }
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<Yaml> {
+ self.serialize_i64(v as i64)
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<Yaml> {
+ if v <= i64::max_value() as u64 {
+ self.serialize_i64(v as i64)
+ } else {
+ Ok(Yaml::Real(v.to_string()))
+ }
+ }
+
+ #[allow(clippy::cast_possible_truncation)]
+ fn serialize_u128(self, v: u128) -> Result<Yaml> {
+ if v <= i64::max_value() as u128 {
+ self.serialize_i64(v as i64)
+ } else {
+ Ok(Yaml::Real(v.to_string()))
+ }
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<Yaml> {
+ Ok(Yaml::Real(match v.classify() {
+ num::FpCategory::Infinite if v.is_sign_positive() => ".inf".into(),
+ num::FpCategory::Infinite => "-.inf".into(),
+ num::FpCategory::Nan => ".nan".into(),
+ _ => ryu::Buffer::new().format_finite(v).into(),
+ }))
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<Yaml> {
+ Ok(Yaml::Real(match v.classify() {
+ num::FpCategory::Infinite if v.is_sign_positive() => ".inf".into(),
+ num::FpCategory::Infinite => "-.inf".into(),
+ num::FpCategory::Nan => ".nan".into(),
+ _ => ryu::Buffer::new().format_finite(v).into(),
+ }))
+ }
+
+ fn serialize_char(self, value: char) -> Result<Yaml> {
+ Ok(Yaml::String(value.to_string()))
+ }
+
+ fn serialize_str(self, value: &str) -> Result<Yaml> {
+ Ok(Yaml::String(value.to_owned()))
+ }
+
+ fn serialize_bytes(self, value: &[u8]) -> Result<Yaml> {
+ let vec = value.iter().map(|&b| Yaml::Integer(b as i64)).collect();
+ Ok(Yaml::Array(vec))
+ }
+
+ fn serialize_unit(self) -> Result<Yaml> {
+ Ok(Yaml::Null)
+ }
+
+ fn serialize_unit_struct(self, _name: &'static str) -> Result<Yaml> {
+ self.serialize_unit()
+ }
+
+ fn serialize_unit_variant(
+ self,
+ _name: &str,
+ _variant_index: u32,
+ variant: &str,
+ ) -> Result<Yaml> {
+ Ok(Yaml::String(variant.to_owned()))
+ }
+
+ fn serialize_newtype_struct<T>(self, _name: &'static str, value: &T) -> Result<Yaml>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_newtype_variant<T>(
+ self,
+ _name: &str,
+ _variant_index: u32,
+ variant: &str,
+ value: &T,
+ ) -> Result<Yaml>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ Ok(singleton_hash(to_yaml(variant)?, to_yaml(value)?))
+ }
+
+ fn serialize_none(self) -> Result<Yaml> {
+ self.serialize_unit()
+ }
+
+ fn serialize_some<V>(self, value: &V) -> Result<Yaml>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ value.serialize(self)
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<SerializeArray> {
+ let array = match len {
+ None => yaml::Array::new(),
+ Some(len) => yaml::Array::with_capacity(len),
+ };
+ Ok(SerializeArray { array })
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<SerializeArray> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_struct(self, _name: &'static str, len: usize) -> Result<SerializeArray> {
+ self.serialize_seq(Some(len))
+ }
+
+ fn serialize_tuple_variant(
+ self,
+ _enum: &'static str,
+ _idx: u32,
+ variant: &'static str,
+ len: usize,
+ ) -> Result<SerializeTupleVariant> {
+ Ok(SerializeTupleVariant {
+ name: variant,
+ array: yaml::Array::with_capacity(len),
+ })
+ }
+
+ fn serialize_map(self, _len: Option<usize>) -> Result<SerializeMap> {
+ Ok(SerializeMap {
+ hash: yaml::Hash::new(),
+ next_key: None,
+ })
+ }
+
+ fn serialize_struct(self, _name: &'static str, _len: usize) -> Result<SerializeStruct> {
+ Ok(SerializeStruct {
+ hash: yaml::Hash::new(),
+ })
+ }
+
+ fn serialize_struct_variant(
+ self,
+ _enum: &'static str,
+ _idx: u32,
+ variant: &'static str,
+ _len: usize,
+ ) -> Result<SerializeStructVariant> {
+ Ok(SerializeStructVariant {
+ name: variant,
+ hash: yaml::Hash::new(),
+ })
+ }
+}
+
+#[doc(hidden)]
+pub struct SerializeArray {
+ array: yaml::Array,
+}
+
+#[doc(hidden)]
+pub struct SerializeTupleVariant {
+ name: &'static str,
+ array: yaml::Array,
+}
+
+#[doc(hidden)]
+pub struct SerializeMap {
+ hash: yaml::Hash,
+ next_key: Option<yaml::Yaml>,
+}
+
+#[doc(hidden)]
+pub struct SerializeStruct {
+ hash: yaml::Hash,
+}
+
+#[doc(hidden)]
+pub struct SerializeStructVariant {
+ name: &'static str,
+ hash: yaml::Hash,
+}
+
+impl ser::SerializeSeq for SerializeArray {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.array.push(to_yaml(elem)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Yaml> {
+ Ok(Yaml::Array(self.array))
+ }
+}
+
+impl ser::SerializeTuple for SerializeArray {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_element<T>(&mut self, elem: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ ser::SerializeSeq::serialize_element(self, elem)
+ }
+
+ fn end(self) -> Result<Yaml> {
+ ser::SerializeSeq::end(self)
+ }
+}
+
+impl ser::SerializeTupleStruct for SerializeArray {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, value: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ ser::SerializeSeq::serialize_element(self, value)
+ }
+
+ fn end(self) -> Result<Yaml> {
+ ser::SerializeSeq::end(self)
+ }
+}
+
+impl ser::SerializeTupleVariant for SerializeTupleVariant {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, v: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.array.push(to_yaml(v)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Yaml> {
+ Ok(singleton_hash(to_yaml(self.name)?, Yaml::Array(self.array)))
+ }
+}
+
+impl ser::SerializeMap for SerializeMap {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_key<T>(&mut self, key: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ self.next_key = Some(to_yaml(key)?);
+ Ok(())
+ }
+
+ fn serialize_value<T>(&mut self, value: &T) -> Result<()>
+ where
+ T: ?Sized + ser::Serialize,
+ {
+ match self.next_key.take() {
+ Some(key) => self.hash.insert(key, to_yaml(value)?),
+ None => panic!("serialize_value called before serialize_key"),
+ };
+ Ok(())
+ }
+
+ fn serialize_entry<K, V>(&mut self, key: &K, value: &V) -> Result<()>
+ where
+ K: ?Sized + ser::Serialize,
+ V: ?Sized + ser::Serialize,
+ {
+ self.hash.insert(to_yaml(key)?, to_yaml(value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Yaml> {
+ Ok(Yaml::Hash(self.hash))
+ }
+}
+
+impl ser::SerializeStruct for SerializeStruct {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, key: &'static str, value: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.hash.insert(to_yaml(key)?, to_yaml(value)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Yaml> {
+ Ok(Yaml::Hash(self.hash))
+ }
+}
+
+impl ser::SerializeStructVariant for SerializeStructVariant {
+ type Ok = yaml::Yaml;
+ type Error = Error;
+
+ fn serialize_field<V>(&mut self, field: &'static str, v: &V) -> Result<()>
+ where
+ V: ?Sized + ser::Serialize,
+ {
+ self.hash.insert(to_yaml(field)?, to_yaml(v)?);
+ Ok(())
+ }
+
+ fn end(self) -> Result<Yaml> {
+ Ok(singleton_hash(to_yaml(self.name)?, Yaml::Hash(self.hash)))
+ }
+}
+
+/// Serialize the given data structure as YAML into the IO stream.
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// return an error.
+pub fn to_writer<W, T>(writer: W, value: &T) -> Result<()>
+where
+ W: io::Write,
+ T: ?Sized + ser::Serialize,
+{
+ value.serialize(&mut Serializer::new(writer))
+}
+
+/// Serialize the given data structure as a YAML byte vector.
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// return an error.
+pub fn to_vec<T>(value: &T) -> Result<Vec<u8>>
+where
+ T: ?Sized + ser::Serialize,
+{
+ let mut vec = Vec::with_capacity(128);
+ to_writer(&mut vec, value)?;
+ Ok(vec)
+}
+
+/// Serialize the given data structure as a String of YAML.
+///
+/// Serialization can fail if `T`'s implementation of `Serialize` decides to
+/// return an error.
+pub fn to_string<T>(value: &T) -> Result<String>
+where
+ T: ?Sized + ser::Serialize,
+{
+ String::from_utf8(to_vec(value)?).map_err(error::string_utf8)
+}
+
+/// The yaml-rust library uses `fmt::Write` intead of `io::Write` so this is a
+/// simple adapter.
+struct FmtToIoWriter<W> {
+ writer: W,
+}
+
+impl<W> fmt::Write for FmtToIoWriter<W>
+where
+ W: io::Write,
+{
+ fn write_str(&mut self, s: &str) -> fmt::Result {
+ if self.writer.write_all(s.as_bytes()).is_err() {
+ return Err(fmt::Error);
+ }
+ Ok(())
+ }
+}
+
+fn to_yaml<T>(elem: T) -> Result<Yaml>
+where
+ T: ser::Serialize,
+{
+ elem.serialize(SerializerToYaml)
+}
+
+fn singleton_hash(k: Yaml, v: Yaml) -> Yaml {
+ let mut hash = yaml::Hash::new();
+ hash.insert(k, v);
+ Yaml::Hash(hash)
+}
diff --git a/third_party/rust/serde_yaml/src/value/de.rs b/third_party/rust/serde_yaml/src/value/de.rs
new file mode 100644
index 0000000000..61e0469693
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/de.rs
@@ -0,0 +1,707 @@
+use crate::{number, Error, Mapping, Sequence, Value};
+use serde::de::{
+ self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error as SError, Expected,
+ MapAccess, SeqAccess, Unexpected, VariantAccess, Visitor,
+};
+use serde::forward_to_deserialize_any;
+use std::fmt;
+use std::vec;
+
+impl<'de> Deserialize<'de> for Value {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct ValueVisitor;
+
+ impl<'de> Visitor<'de> for ValueVisitor {
+ type Value = Value;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("any YAML value")
+ }
+
+ fn visit_bool<E>(self, b: bool) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Bool(b))
+ }
+
+ fn visit_i64<E>(self, i: i64) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Number(i.into()))
+ }
+
+ fn visit_u64<E>(self, u: u64) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Number(u.into()))
+ }
+
+ fn visit_f64<E>(self, f: f64) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Number(f.into()))
+ }
+
+ fn visit_str<E>(self, s: &str) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::String(s.to_owned()))
+ }
+
+ fn visit_string<E>(self, s: String) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::String(s))
+ }
+
+ fn visit_unit<E>(self) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Null)
+ }
+
+ fn visit_none<E>(self) -> Result<Value, E>
+ where
+ E: SError,
+ {
+ Ok(Value::Null)
+ }
+
+ fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer)
+ }
+
+ fn visit_seq<V>(self, mut visitor: V) -> Result<Value, V::Error>
+ where
+ V: SeqAccess<'de>,
+ {
+ let mut vec = Vec::new();
+
+ while let Some(element) = visitor.next_element()? {
+ vec.push(element);
+ }
+
+ Ok(Value::Sequence(vec))
+ }
+
+ fn visit_map<V>(self, mut visitor: V) -> Result<Value, V::Error>
+ where
+ V: MapAccess<'de>,
+ {
+ let mut values = Mapping::new();
+
+ while let Some((key, value)) = visitor.next_entry()? {
+ values.insert(key, value);
+ }
+
+ Ok(Value::Mapping(values))
+ }
+ }
+
+ deserializer.deserialize_any(ValueVisitor)
+ }
+}
+
+impl Value {
+ fn deserialize_number<'de, V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Number(n) => n.deserialize_any(visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+}
+
+fn visit_sequence<'de, V>(sequence: Sequence, visitor: V) -> Result<V::Value, Error>
+where
+ V: Visitor<'de>,
+{
+ let len = sequence.len();
+ let mut deserializer = SeqDeserializer::new(sequence);
+ let seq = visitor.visit_seq(&mut deserializer)?;
+ let remaining = deserializer.iter.len();
+ if remaining == 0 {
+ Ok(seq)
+ } else {
+ Err(Error::invalid_length(len, &"fewer elements in sequence"))
+ }
+}
+
+fn visit_mapping<'de, V>(mapping: Mapping, visitor: V) -> Result<V::Value, Error>
+where
+ V: Visitor<'de>,
+{
+ let len = mapping.len();
+ let mut deserializer = MapDeserializer::new(mapping);
+ let map = visitor.visit_map(&mut deserializer)?;
+ let remaining = deserializer.iter.len();
+ if remaining == 0 {
+ Ok(map)
+ } else {
+ Err(Error::invalid_length(len, &"fewer elements in map"))
+ }
+}
+
+impl<'de> Deserializer<'de> for Value {
+ type Error = Error;
+
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Null => visitor.visit_unit(),
+ Value::Bool(v) => visitor.visit_bool(v),
+ Value::Number(n) => n.deserialize_any(visitor),
+ Value::String(v) => visitor.visit_string(v),
+ Value::Sequence(v) => visit_sequence(v, visitor),
+ Value::Mapping(v) => visit_mapping(v, visitor),
+ }
+ }
+
+ fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Bool(v) => visitor.visit_bool(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_number(visitor)
+ }
+
+ fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_string(visitor)
+ }
+
+ fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_string(visitor)
+ }
+
+ fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::String(v) => visitor.visit_string(v),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_byte_buf(visitor)
+ }
+
+ fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::String(v) => visitor.visit_string(v),
+ Value::Sequence(v) => visit_sequence(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Null => visitor.visit_none(),
+ _ => visitor.visit_some(self),
+ }
+ }
+
+ fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Null => visitor.visit_unit(),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_unit(visitor)
+ }
+
+ fn deserialize_newtype_struct<V>(
+ self,
+ _name: &'static str,
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_newtype_struct(self)
+ }
+
+ fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Sequence(v) => visit_sequence(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, 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, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_seq(visitor)
+ }
+
+ fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Mapping(v) => visit_mapping(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_struct<V>(
+ self,
+ _name: &'static str,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self {
+ Value::Sequence(v) => visit_sequence(v, visitor),
+ Value::Mapping(v) => visit_mapping(v, visitor),
+ _ => Err(self.invalid_type(&visitor)),
+ }
+ }
+
+ fn deserialize_enum<V>(
+ self,
+ _name: &str,
+ _variants: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ let (variant, value) = match self {
+ Value::Mapping(value) => {
+ let mut iter = value.into_iter();
+ let (variant, value) = match iter.next() {
+ Some(v) => v,
+ None => {
+ return Err(Error::invalid_value(
+ Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ };
+ // enums are encoded in json as maps with a single key:value pair
+ if iter.next().is_some() {
+ return Err(Error::invalid_value(
+ Unexpected::Map,
+ &"map with a single key",
+ ));
+ }
+ (variant, Some(value))
+ }
+ Value::String(variant) => (Value::String(variant), None),
+ other => {
+ return Err(Error::invalid_type(other.unexpected(), &"string or map"));
+ }
+ };
+
+ visitor.visit_enum(EnumDeserializer { variant, value })
+ }
+
+ fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ self.deserialize_string(visitor)
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ drop(self);
+ visitor.visit_unit()
+ }
+}
+
+struct EnumDeserializer {
+ variant: Value,
+ value: Option<Value>,
+}
+
+impl<'de> EnumAccess<'de> for EnumDeserializer {
+ type Error = Error;
+ type Variant = VariantDeserializer;
+
+ fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer), Error>
+ where
+ V: DeserializeSeed<'de>,
+ {
+ let visitor = VariantDeserializer { value: self.value };
+ seed.deserialize(self.variant).map(|v| (v, visitor))
+ }
+}
+
+struct VariantDeserializer {
+ value: Option<Value>,
+}
+
+impl<'de> VariantAccess<'de> for VariantDeserializer {
+ type Error = Error;
+
+ fn unit_variant(self) -> Result<(), Error> {
+ match self.value {
+ Some(value) => Deserialize::deserialize(value),
+ None => Ok(()),
+ }
+ }
+
+ fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.value {
+ Some(value) => seed.deserialize(value),
+ None => Err(Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"newtype variant",
+ )),
+ }
+ }
+
+ fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.value {
+ Some(Value::Sequence(v)) => {
+ Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
+ }
+ Some(other) => Err(Error::invalid_type(other.unexpected(), &"tuple variant")),
+ None => Err(Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"tuple variant",
+ )),
+ }
+ }
+
+ fn struct_variant<V>(
+ self,
+ _fields: &'static [&'static str],
+ visitor: V,
+ ) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.value {
+ Some(Value::Mapping(v)) => {
+ Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
+ }
+ Some(other) => Err(Error::invalid_type(other.unexpected(), &"struct variant")),
+ None => Err(Error::invalid_type(
+ Unexpected::UnitVariant,
+ &"struct variant",
+ )),
+ }
+ }
+}
+
+struct SeqDeserializer {
+ iter: vec::IntoIter<Value>,
+}
+
+impl SeqDeserializer {
+ fn new(vec: Vec<Value>) -> Self {
+ SeqDeserializer {
+ iter: vec.into_iter(),
+ }
+ }
+}
+
+impl<'de> Deserializer<'de> for SeqDeserializer {
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(mut self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ let len = self.iter.len();
+ if len == 0 {
+ visitor.visit_unit()
+ } else {
+ let ret = visitor.visit_seq(&mut self)?;
+ let remaining = self.iter.len();
+ if remaining == 0 {
+ Ok(ret)
+ } else {
+ Err(Error::invalid_length(len, &"fewer elements in sequence"))
+ }
+ }
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ drop(self);
+ visitor.visit_unit()
+ }
+
+ 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 newtype_struct seq tuple tuple_struct
+ map struct enum identifier
+ }
+}
+
+impl<'de> SeqAccess<'de> for SeqDeserializer {
+ type Error = Error;
+
+ fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some(value) => seed.deserialize(value).map(Some),
+ None => Ok(None),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ match self.iter.size_hint() {
+ (lower, Some(upper)) if lower == upper => Some(upper),
+ _ => None,
+ }
+ }
+}
+
+struct MapDeserializer {
+ iter: <Mapping as IntoIterator>::IntoIter,
+ value: Option<Value>,
+}
+
+impl MapDeserializer {
+ fn new(map: Mapping) -> Self {
+ MapDeserializer {
+ iter: map.into_iter(),
+ value: None,
+ }
+ }
+}
+
+impl<'de> MapAccess<'de> for MapDeserializer {
+ type Error = Error;
+
+ fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.iter.next() {
+ Some((key, value)) => {
+ self.value = Some(value);
+ seed.deserialize(key).map(Some)
+ }
+ None => Ok(None),
+ }
+ }
+
+ fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Error>
+ where
+ T: DeserializeSeed<'de>,
+ {
+ match self.value.take() {
+ Some(value) => seed.deserialize(value),
+ None => panic!("visit_value called before visit_key"),
+ }
+ }
+
+ fn size_hint(&self) -> Option<usize> {
+ match self.iter.size_hint() {
+ (lower, Some(upper)) if lower == upper => Some(upper),
+ _ => None,
+ }
+ }
+}
+
+impl<'de> Deserializer<'de> for MapDeserializer {
+ type Error = Error;
+
+ #[inline]
+ fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ visitor.visit_map(self)
+ }
+
+ fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Error>
+ where
+ V: Visitor<'de>,
+ {
+ drop(self);
+ visitor.visit_unit()
+ }
+
+ 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 newtype_struct seq tuple tuple_struct
+ map struct enum identifier
+ }
+}
+
+impl Value {
+ #[cold]
+ fn invalid_type<E>(&self, exp: &dyn Expected) -> E
+ where
+ E: de::Error,
+ {
+ de::Error::invalid_type(self.unexpected(), exp)
+ }
+
+ #[cold]
+ fn unexpected(&self) -> Unexpected {
+ match self {
+ Value::Null => Unexpected::Unit,
+ Value::Bool(b) => Unexpected::Bool(*b),
+ Value::Number(n) => number::unexpected(n),
+ Value::String(s) => Unexpected::Str(s),
+ Value::Sequence(_) => Unexpected::Seq,
+ Value::Mapping(_) => Unexpected::Map,
+ }
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/value/from.rs b/third_party/rust/serde_yaml/src/value/from.rs
new file mode 100644
index 0000000000..c02855d3b1
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/from.rs
@@ -0,0 +1,180 @@
+use crate::{Mapping, Value};
+
+// Implement a bunch of conversion to make it easier to create YAML values
+// on the fly.
+
+macro_rules! from_number {
+ ($($ty:ident)*) => {
+ $(
+ impl From<$ty> for Value {
+ fn from(n: $ty) -> Self {
+ Value::Number(n.into())
+ }
+ }
+ )*
+ };
+}
+
+from_number! {
+ i8 i16 i32 i64 isize
+ u8 u16 u32 u64 usize
+ f32 f64
+}
+
+impl From<bool> for Value {
+ /// Convert boolean to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let b = false;
+ /// let x: Value = b.into();
+ /// ```
+ fn from(f: bool) -> Self {
+ Value::Bool(f)
+ }
+}
+
+impl From<String> for Value {
+ /// Convert `String` to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let s: String = "lorem".to_string();
+ /// let x: Value = s.into();
+ /// ```
+ fn from(f: String) -> Self {
+ Value::String(f)
+ }
+}
+
+impl<'a> From<&'a str> for Value {
+ /// Convert string slice to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let s: &str = "lorem";
+ /// let x: Value = s.into();
+ /// ```
+ fn from(f: &str) -> Self {
+ Value::String(f.to_string())
+ }
+}
+
+use std::borrow::Cow;
+
+impl<'a> From<Cow<'a, str>> for Value {
+ /// Convert copy-on-write string to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ /// use std::borrow::Cow;
+ ///
+ /// let s: Cow<str> = Cow::Borrowed("lorem");
+ /// let x: Value = s.into();
+ /// ```
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ /// use std::borrow::Cow;
+ ///
+ /// let s: Cow<str> = Cow::Owned("lorem".to_string());
+ /// let x: Value = s.into();
+ /// ```
+ fn from(f: Cow<'a, str>) -> Self {
+ Value::String(f.to_string())
+ }
+}
+
+impl From<Mapping> for Value {
+ /// Convert map (with string keys) to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::{Mapping, Value};
+ ///
+ /// let mut m = Mapping::new();
+ /// m.insert("Lorem".into(), "ipsum".into());
+ /// let x: Value = m.into();
+ /// ```
+ fn from(f: Mapping) -> Self {
+ Value::Mapping(f)
+ }
+}
+
+impl<T: Into<Value>> From<Vec<T>> for Value {
+ /// Convert a `Vec` to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let v = vec!["lorem", "ipsum", "dolor"];
+ /// let x: Value = v.into();
+ /// ```
+ fn from(f: Vec<T>) -> Self {
+ Value::Sequence(f.into_iter().map(Into::into).collect())
+ }
+}
+
+impl<'a, T: Clone + Into<Value>> From<&'a [T]> for Value {
+ /// Convert a slice to `Value`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let v: &[&str] = &["lorem", "ipsum", "dolor"];
+ /// let x: Value = v.into();
+ /// ```
+ fn from(f: &'a [T]) -> Self {
+ Value::Sequence(f.iter().cloned().map(Into::into).collect())
+ }
+}
+
+use std::iter::FromIterator;
+
+impl<T: Into<Value>> FromIterator<T> for Value {
+ /// Convert an iteratable type to a YAML sequence
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let v = std::iter::repeat(42).take(5);
+ /// let x: Value = v.collect();
+ /// ```
+ ///
+ /// ```
+ /// use serde_yaml::Value;
+ ///
+ /// let v: Vec<_> = vec!["lorem", "ipsum", "dolor"];
+ /// let x: Value = v.into_iter().collect();
+ /// ```
+ ///
+ /// ```
+ /// use std::iter::FromIterator;
+ /// use serde_yaml::Value;
+ ///
+ /// let x: Value = Value::from_iter(vec!["lorem", "ipsum", "dolor"]);
+ /// ```
+ fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
+ let vec = iter.into_iter().map(T::into).collect();
+
+ Value::Sequence(vec)
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/value/index.rs b/third_party/rust/serde_yaml/src/value/index.rs
new file mode 100644
index 0000000000..b5f5e90160
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/index.rs
@@ -0,0 +1,260 @@
+use crate::{Mapping, Value};
+use std::fmt;
+use std::ops;
+
+/// A type that can be used to index into a `serde_yaml::Value`. See the `get`
+/// and `get_mut` methods of `Value`.
+///
+/// This trait is sealed and cannot be implemented for types outside of
+/// `serde_yaml`.
+pub trait Index: private::Sealed {
+ /// Return None if the key is not already in the sequence or object.
+ #[doc(hidden)]
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value>;
+
+ /// Return None if the key is not already in the sequence or object.
+ #[doc(hidden)]
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value>;
+
+ /// Panic if sequence index out of bounds. If key is not already in the object,
+ /// insert it with a value of null. Panic if Value is a type that cannot be
+ /// indexed into, except if Value is null then it can be treated as an empty
+ /// object.
+ #[doc(hidden)]
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value;
+}
+
+impl Index for usize {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ match v {
+ Value::Sequence(vec) => vec.get(*self),
+ Value::Mapping(vec) => vec.get(&Value::Number((*self).into())),
+ _ => None,
+ }
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ match v {
+ Value::Sequence(vec) => vec.get_mut(*self),
+ Value::Mapping(vec) => vec.get_mut(&Value::Number((*self).into())),
+ _ => None,
+ }
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ match v {
+ Value::Sequence(vec) => {
+ let len = vec.len();
+ vec.get_mut(*self).unwrap_or_else(|| {
+ panic!(
+ "cannot access index {} of YAML sequence of length {}",
+ self, len
+ )
+ })
+ }
+ Value::Mapping(map) => {
+ let n = Value::Number((*self).into());
+ // TODO: use entry() once LinkedHashMap supports entry()
+ // https://github.com/contain-rs/linked-hash-map/issues/5
+ if !map.contains_key(&n) {
+ map.insert(n.clone(), Value::Null);
+ }
+ map.get_mut(&n).unwrap()
+ }
+ _ => panic!("cannot access index {} of YAML {}", self, Type(v)),
+ }
+ }
+}
+
+impl Index for Value {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ match v {
+ Value::Mapping(map) => map.get(self),
+ _ => None,
+ }
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ match v {
+ Value::Mapping(map) => map.get_mut(self),
+ _ => None,
+ }
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ if let Value::Null = *v {
+ let mut map = Mapping::new();
+ map.insert(self.clone(), Value::Null);
+ *v = Value::Mapping(map);
+ }
+ match v {
+ Value::Mapping(map) => {
+ // TODO: use entry() once LinkedHashMap supports entry()
+ // https://github.com/contain-rs/linked-hash-map/issues/5
+ if !map.contains_key(self) {
+ map.insert(self.clone(), Value::Null);
+ }
+ map.get_mut(self).unwrap()
+ }
+ _ => panic!("cannot access key {:?} in YAML {}", self, Type(v)),
+ }
+ }
+}
+
+impl Index for str {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ Value::String(self.into()).index_into(v)
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ Value::String(self.into()).index_into_mut(v)
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ Value::String(self.into()).index_or_insert(v)
+ }
+}
+
+impl Index for String {
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ Value::String(self.clone()).index_into(v)
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ Value::String(self.clone()).index_into_mut(v)
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ Value::String(self.clone()).index_or_insert(v)
+ }
+}
+
+impl<'a, T> Index for &'a T
+where
+ T: ?Sized + Index,
+{
+ fn index_into<'v>(&self, v: &'v Value) -> Option<&'v Value> {
+ (**self).index_into(v)
+ }
+ fn index_into_mut<'v>(&self, v: &'v mut Value) -> Option<&'v mut Value> {
+ (**self).index_into_mut(v)
+ }
+ fn index_or_insert<'v>(&self, v: &'v mut Value) -> &'v mut Value {
+ (**self).index_or_insert(v)
+ }
+}
+
+// Prevent users from implementing the Index trait.
+mod private {
+ pub trait Sealed {}
+ impl Sealed for usize {}
+ impl Sealed for str {}
+ impl Sealed for String {}
+ impl Sealed for super::Value {}
+ impl<'a, T> Sealed for &'a T where T: ?Sized + Sealed {}
+}
+
+/// Used in panic messages.
+struct Type<'a>(&'a Value);
+
+impl<'a> fmt::Display for Type<'a> {
+ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ match self.0 {
+ Value::Null => formatter.write_str("null"),
+ Value::Bool(_) => formatter.write_str("boolean"),
+ Value::Number(_) => formatter.write_str("number"),
+ Value::String(_) => formatter.write_str("string"),
+ Value::Sequence(_) => formatter.write_str("sequence"),
+ Value::Mapping(_) => formatter.write_str("mapping"),
+ }
+ }
+}
+
+// The usual semantics of Index is to panic on invalid indexing.
+//
+// That said, the usual semantics are for things like `Vec` and `BTreeMap` which
+// have different use cases than Value. If you are working with a Vec, you know
+// that you are working with a Vec and you can get the len of the Vec and make
+// sure your indices are within bounds. The Value use cases are more
+// loosey-goosey. You got some YAML from an endpoint and you want to pull values
+// out of it. Outside of this Index impl, you already have the option of using
+// `value.as_sequence()` and working with the Vec directly, or matching on
+// `Value::Sequence` and getting the Vec directly. The Index impl means you can
+// skip that and index directly into the thing using a concise syntax. You don't
+// have to check the type, you don't have to check the len, it is all about what
+// you expect the Value to look like.
+//
+// Basically the use cases that would be well served by panicking here are
+// better served by using one of the other approaches: `get` and `get_mut`,
+// `as_sequence`, or match. The value of this impl is that it adds a way of
+// working with Value that is not well served by the existing approaches:
+// concise and careless and sometimes that is exactly what you want.
+impl<I> ops::Index<I> for Value
+where
+ I: Index,
+{
+ type Output = Value;
+
+ /// Index into a `serde_yaml::Value` using the syntax `value[0]` or
+ /// `value["k"]`.
+ ///
+ /// Returns `Value::Null` if the type of `self` does not match the type of
+ /// the index, for example if the index is a string and `self` is a sequence
+ /// or a number. Also returns `Value::Null` if the given key does not exist
+ /// in the map or the given index is not within the bounds of the sequence.
+ ///
+ /// For retrieving deeply nested values, you should have a look at the
+ /// `Value::pointer` method.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let data = yaml(r#"{ x: { y: [z, zz] } }"#);
+ ///
+ /// assert_eq!(data["x"]["y"], yaml(r#"["z", "zz"]"#));
+ /// assert_eq!(data["x"]["y"][0], yaml(r#""z""#));
+ ///
+ /// assert_eq!(data["a"], yaml(r#"null"#)); // returns null for undefined values
+ /// assert_eq!(data["a"]["b"], yaml(r#"null"#)); // does not panic
+ /// ```
+ fn index(&self, index: I) -> &Value {
+ static NULL: Value = Value::Null;
+ index.index_into(self).unwrap_or(&NULL)
+ }
+}
+
+impl<I> ops::IndexMut<I> for Value
+where
+ I: Index,
+{
+ /// Write into a `serde_yaml::Value` using the syntax `value[0] = ...` or
+ /// `value["k"] = ...`.
+ ///
+ /// If the index is a number, the value must be a sequence of length bigger
+ /// than the index. Indexing into a value that is not a sequence or a
+ /// sequence that is too small will panic.
+ ///
+ /// If the index is a string, the value must be an object or null which is
+ /// treated like an empty object. If the key is not already present in the
+ /// object, it will be inserted with a value of null. Indexing into a value
+ /// that is neither an object nor null will panic.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let mut data = yaml(r#"{x: 0}"#);
+ ///
+ /// // replace an existing key
+ /// data["x"] = yaml(r#"1"#);
+ ///
+ /// // insert a new key
+ /// data["y"] = yaml(r#"[false, false, false]"#);
+ ///
+ /// // replace a value in a sequence
+ /// data["y"][0] = yaml(r#"true"#);
+ ///
+ /// // inserted a deeply nested key
+ /// data["a"]["b"]["c"]["d"] = yaml(r#"true"#);
+ ///
+ /// println!("{:?}", data);
+ /// ```
+ fn index_mut(&mut self, index: I) -> &mut Value {
+ index.index_or_insert(self)
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/value/mod.rs b/third_party/rust/serde_yaml/src/value/mod.rs
new file mode 100644
index 0000000000..a71091bffb
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/mod.rs
@@ -0,0 +1,648 @@
+mod de;
+mod from;
+mod index;
+mod partial_eq;
+mod ser;
+
+use crate::ser::SerializerToYaml;
+use crate::{Error, Mapping};
+use serde::de::{Deserialize, DeserializeOwned, IntoDeserializer};
+use serde::Serialize;
+use std::f64;
+use std::hash::{Hash, Hasher};
+use std::str::FromStr;
+use yaml_rust::Yaml;
+
+pub use self::index::Index;
+pub use crate::number::Number;
+
+/// Represents any valid YAML value.
+#[derive(Clone, PartialOrd, Debug)]
+pub enum Value {
+ /// Represents a YAML null value.
+ Null,
+ /// Represents a YAML boolean.
+ Bool(bool),
+ /// Represents a YAML numerical value, whether integer or floating point.
+ Number(Number),
+ /// Represents a YAML string.
+ String(String),
+ /// Represents a YAML sequence in which the elements are
+ /// `serde_yaml::Value`.
+ Sequence(Sequence),
+ /// Represents a YAML mapping in which the keys and values are both
+ /// `serde_yaml::Value`.
+ Mapping(Mapping),
+}
+
+/// The default value is `Value::Null`.
+///
+/// This is useful for handling omitted `Value` fields when deserializing.
+///
+/// # Examples
+///
+/// ```
+/// # use serde_derive::Deserialize;
+/// use serde::Deserialize;
+/// use serde_yaml::Value;
+///
+/// #[derive(Deserialize)]
+/// struct Settings {
+/// level: i32,
+/// #[serde(default)]
+/// extras: Value,
+/// }
+///
+/// # fn try_main() -> Result<(), serde_yaml::Error> {
+/// let data = r#" { "level": 42 } "#;
+/// let s: Settings = serde_yaml::from_str(data)?;
+///
+/// assert_eq!(s.level, 42);
+/// assert_eq!(s.extras, Value::Null);
+/// #
+/// # Ok(())
+/// # }
+/// #
+/// # try_main().unwrap()
+/// ```
+impl Default for Value {
+ fn default() -> Value {
+ Value::Null
+ }
+}
+
+/// A YAML sequence in which the elements are `serde_yaml::Value`.
+pub type Sequence = Vec<Value>;
+
+/// Convert a `T` into `serde_yaml::Value` which is an enum that can represent
+/// any valid YAML data.
+///
+/// This conversion can fail if `T`'s implementation of `Serialize` decides to
+/// return an error.
+///
+/// ```
+/// # use serde_yaml::Value;
+/// let val = serde_yaml::to_value("s").unwrap();
+/// assert_eq!(val, Value::String("s".to_owned()));
+/// ```
+pub fn to_value<T>(value: T) -> Result<Value, Error>
+where
+ T: Serialize,
+{
+ value.serialize(SerializerToYaml).map(yaml_to_value)
+}
+
+/// Interpret a `serde_yaml::Value` as an instance of type `T`.
+///
+/// This conversion can fail if the structure of the Value does not match the
+/// structure expected by `T`, for example if `T` is a struct type but the Value
+/// contains something other than a YAML map. It can also fail if the structure
+/// is correct but `T`'s implementation of `Deserialize` decides that something
+/// is wrong with the data, for example required struct fields are missing from
+/// the YAML map or some number is too big to fit in the expected primitive
+/// type.
+///
+/// ```
+/// # use serde_yaml::Value;
+/// let val = Value::String("foo".to_owned());
+/// let s: String = serde_yaml::from_value(val).unwrap();
+/// assert_eq!("foo", s);
+/// ```
+pub fn from_value<T>(value: Value) -> Result<T, Error>
+where
+ T: DeserializeOwned,
+{
+ Deserialize::deserialize(value)
+}
+
+impl Value {
+ /// Index into a YAML sequence or map. A string index can be used to access
+ /// a value in a map, and a usize index can be used to access an element of
+ /// an sequence.
+ ///
+ /// Returns `None` if the type of `self` does not match the type of the
+ /// index, for example if the index is a string and `self` is a sequence or
+ /// a number. Also returns `None` if the given key does not exist in the map
+ /// or the given index is not within the bounds of the sequence.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// #
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let object: Value = yaml(r#"{ A: 65, B: 66, C: 67 }"#);
+ /// let x = object.get("A").unwrap();
+ /// assert_eq!(x, 65);
+ ///
+ /// let sequence: Value = yaml(r#"[ "A", "B", "C" ]"#);
+ /// let x = sequence.get(2).unwrap();
+ /// assert_eq!(x, &Value::String("C".into()));
+ ///
+ /// assert_eq!(sequence.get("A"), None);
+ /// ```
+ ///
+ /// Square brackets can also be used to index into a value in a more concise
+ /// way. This returns `Value::Null` in cases where `get` would have returned
+ /// `None`.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// #
+ /// # fn yaml(i: &str) -> serde_yaml::Value { serde_yaml::from_str(i).unwrap() }
+ /// #
+ /// let object = yaml(r#"
+ /// ---
+ /// A: [a, á, à]
+ /// B: [b, bÌ]
+ /// C: [c, ć, ć̣, ḉ]
+ /// 42: true
+ /// "#);
+ /// assert_eq!(object["B"][0], Value::String("b".into()));
+ ///
+ /// assert_eq!(object[Value::String("D".into())], Value::Null);
+ /// assert_eq!(object["D"], Value::Null);
+ /// assert_eq!(object[0]["x"]["y"]["z"], Value::Null);
+ ///
+ /// assert_eq!(object[42], Value::Bool(true));
+ /// ```
+ pub fn get<I: Index>(&self, index: I) -> Option<&Value> {
+ index.index_into(self)
+ }
+
+ /// Index into a YAML sequence or map. A string index can be used to access
+ /// a value in a map, and a usize index can be used to access an element of
+ /// an sequence.
+ ///
+ /// Returns `None` if the type of `self` does not match the type of the
+ /// index, for example if the index is a string and `self` is a sequence or
+ /// a number. Also returns `None` if the given key does not exist in the map
+ /// or the given index is not within the bounds of the sequence.
+ pub fn get_mut<I: Index>(&mut self, index: I) -> Option<&mut Value> {
+ index.index_into_mut(self)
+ }
+
+ /// Returns true if the `Value` is a Null. Returns false otherwise.
+ ///
+ /// For any Value on which `is_null` returns true, `as_null` is guaranteed
+ /// to return `Some(())`.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("null").unwrap();
+ /// assert!(v.is_null());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert!(!v.is_null());
+ /// ```
+ pub fn is_null(&self) -> bool {
+ if let Value::Null = *self {
+ true
+ } else {
+ false
+ }
+ }
+
+ /// If the `Value` is a Null, returns (). Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("null").unwrap();
+ /// assert_eq!(v.as_null(), Some(()));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_null(), None);
+ /// ```
+ pub fn as_null(&self) -> Option<()> {
+ match self {
+ Value::Null => Some(()),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a Boolean. Returns false otherwise.
+ ///
+ /// For any Value on which `is_boolean` returns true, `as_bool` is
+ /// guaranteed to return the boolean value.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert!(v.is_bool());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("42").unwrap();
+ /// assert!(!v.is_bool());
+ /// ```
+ pub fn is_bool(&self) -> bool {
+ self.as_bool().is_some()
+ }
+
+ /// If the `Value` is a Boolean, returns the associated bool. Returns None
+ /// otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert_eq!(v.as_bool(), Some(true));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("42").unwrap();
+ /// assert_eq!(v.as_bool(), None);
+ /// ```
+ pub fn as_bool(&self) -> Option<bool> {
+ match self {
+ Value::Bool(b) => Some(*b),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a Number. Returns false otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("5").unwrap();
+ /// assert!(v.is_number());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert!(!v.is_number());
+ /// ```
+ pub fn is_number(&self) -> bool {
+ match self {
+ Value::Number(_) => true,
+ _ => false,
+ }
+ }
+
+ /// Returns true if the `Value` is an integer between `i64::MIN` and
+ /// `i64::MAX`.
+ ///
+ /// For any Value on which `is_i64` returns true, `as_i64` is guaranteed to
+ /// return the integer value.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("1337").unwrap();
+ /// assert!(v.is_i64());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("null").unwrap();
+ /// assert!(!v.is_i64());
+ /// ```
+ pub fn is_i64(&self) -> bool {
+ self.as_i64().is_some()
+ }
+
+ /// If the `Value` is an integer, represent it as i64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("1337").unwrap();
+ /// assert_eq!(v.as_i64(), Some(1337));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_i64(), None);
+ /// ```
+ pub fn as_i64(&self) -> Option<i64> {
+ match self {
+ Value::Number(n) => n.as_i64(),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is an integer between `u64::MIN` and
+ /// `u64::MAX`.
+ ///
+ /// For any Value on which `is_u64` returns true, `as_u64` is guaranteed to
+ /// return the integer value.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("1337").unwrap();
+ /// assert!(v.is_u64());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("null").unwrap();
+ /// assert!(!v.is_u64());
+ /// ```
+ pub fn is_u64(&self) -> bool {
+ self.as_u64().is_some()
+ }
+
+ /// If the `Value` is an integer, represent it as u64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("1337").unwrap();
+ /// assert_eq!(v.as_u64(), Some(1337));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_u64(), None);
+ /// ```
+ pub fn as_u64(&self) -> Option<u64> {
+ match self {
+ Value::Number(n) => n.as_u64(),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a number that can be represented by f64.
+ ///
+ /// For any Value on which `is_f64` returns true, `as_f64` is guaranteed to
+ /// return the floating point value.
+ ///
+ /// Currently this function returns true if and only if both `is_i64` and
+ /// `is_u64` return false but this is not a guarantee in the future.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("256.01").unwrap();
+ /// assert!(v.is_f64());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert!(!v.is_f64());
+ /// ```
+ pub fn is_f64(&self) -> bool {
+ match self {
+ Value::Number(n) => n.is_f64(),
+ _ => false,
+ }
+ }
+
+ /// If the `Value` is a number, represent it as f64 if possible. Returns
+ /// None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("13.37").unwrap();
+ /// assert_eq!(v.as_f64(), Some(13.37));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_f64(), None);
+ /// ```
+ pub fn as_f64(&self) -> Option<f64> {
+ match self {
+ Value::Number(i) => i.as_f64(),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a String. Returns false otherwise.
+ ///
+ /// For any Value on which `is_string` returns true, `as_str` is guaranteed
+ /// to return the string slice.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("'lorem ipsum'").unwrap();
+ /// assert!(v.is_string());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("42").unwrap();
+ /// assert!(!v.is_string());
+ /// ```
+ pub fn is_string(&self) -> bool {
+ self.as_str().is_some()
+ }
+
+ /// If the `Value` is a String, returns the associated str. Returns None
+ /// otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("'lorem ipsum'").unwrap();
+ /// assert_eq!(v.as_str(), Some("lorem ipsum"));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_str(), None);
+ /// ```
+ pub fn as_str(&self) -> Option<&str> {
+ match self {
+ Value::String(s) => Some(s),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a sequence. Returns false otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("[1, 2, 3]").unwrap();
+ /// assert!(v.is_sequence());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert!(!v.is_sequence());
+ /// ```
+ pub fn is_sequence(&self) -> bool {
+ self.as_sequence().is_some()
+ }
+
+ /// If the `Value` is a sequence, return a reference to it if possible.
+ /// Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Number};
+ /// let v: Value = serde_yaml::from_str("[1, 2]").unwrap();
+ /// assert_eq!(v.as_sequence(), Some(&vec![Value::Number(Number::from(1)), Value::Number(Number::from(2))]));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_sequence(), None);
+ /// ```
+ pub fn as_sequence(&self) -> Option<&Sequence> {
+ match self {
+ Value::Sequence(seq) => Some(seq),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a sequence, return a mutable reference to it if
+ /// possible. Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Number};
+ /// let mut v: Value = serde_yaml::from_str("[1]").unwrap();
+ /// let s = v.as_sequence_mut().unwrap();
+ /// s.push(Value::Number(Number::from(2)));
+ /// assert_eq!(s, &vec![Value::Number(Number::from(1)), Value::Number(Number::from(2))]);
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let mut v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_sequence_mut(), None);
+ /// ```
+ pub fn as_sequence_mut(&mut self) -> Option<&mut Sequence> {
+ match self {
+ Value::Sequence(seq) => Some(seq),
+ _ => None,
+ }
+ }
+
+ /// Returns true if the `Value` is a mapping. Returns false otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("a: 42").unwrap();
+ /// assert!(v.is_mapping());
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("true").unwrap();
+ /// assert!(!v.is_mapping());
+ /// ```
+ pub fn is_mapping(&self) -> bool {
+ self.as_mapping().is_some()
+ }
+
+ /// If the `Value` is a mapping, return a reference to it if possible.
+ /// Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Mapping, Number};
+ /// let v: Value = serde_yaml::from_str("a: 42").unwrap();
+ ///
+ /// let mut expected = Mapping::new();
+ /// expected.insert(Value::String("a".into()),Value::Number(Number::from(42)));
+ ///
+ /// assert_eq!(v.as_mapping(), Some(&expected));
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// let v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_mapping(), None);
+ /// ```
+ pub fn as_mapping(&self) -> Option<&Mapping> {
+ match self {
+ Value::Mapping(map) => Some(map),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a mapping, return a reference to it if possible.
+ /// Returns None otherwise.
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Mapping, Number};
+ /// let mut v: Value = serde_yaml::from_str("a: 42").unwrap();
+ /// let m = v.as_mapping_mut().unwrap();
+ /// m.insert(Value::String("b".into()), Value::Number(Number::from(21)));
+ ///
+ /// let mut expected = Mapping::new();
+ /// expected.insert(Value::String("a".into()), Value::Number(Number::from(42)));
+ /// expected.insert(Value::String("b".into()), Value::Number(Number::from(21)));
+ ///
+ /// assert_eq!(m, &expected);
+ /// ```
+ ///
+ /// ```
+ /// # use serde_yaml::{Value, Mapping};
+ /// let mut v: Value = serde_yaml::from_str("false").unwrap();
+ /// assert_eq!(v.as_mapping_mut(), None);
+ /// ```
+ pub fn as_mapping_mut(&mut self) -> Option<&mut Mapping> {
+ match self {
+ Value::Mapping(map) => Some(map),
+ _ => None,
+ }
+ }
+}
+
+fn yaml_to_value(yaml: Yaml) -> Value {
+ match yaml {
+ Yaml::Real(f) => {
+ if f == ".inf" {
+ Value::Number(f64::INFINITY.into())
+ } else if f == "-.inf" {
+ Value::Number(f64::NEG_INFINITY.into())
+ } else if f == ".nan" {
+ Value::Number(f64::NAN.into())
+ } else if let Ok(n) = u64::from_str(&f) {
+ Value::Number(n.into())
+ } else if let Ok(n) = i64::from_str(&f) {
+ Value::Number(n.into())
+ } else if let Ok(n) = f64::from_str(&f) {
+ Value::Number(n.into())
+ } else {
+ Value::String(f)
+ }
+ }
+ Yaml::Integer(i) => Value::Number(i.into()),
+ Yaml::String(s) => Value::String(s),
+ Yaml::Boolean(b) => Value::Bool(b),
+ Yaml::Array(sequence) => Value::Sequence(sequence.into_iter().map(yaml_to_value).collect()),
+ Yaml::Hash(hash) => Value::Mapping(
+ hash.into_iter()
+ .map(|(k, v)| (yaml_to_value(k), yaml_to_value(v)))
+ .collect(),
+ ),
+ Yaml::Alias(_) => panic!("alias unsupported"),
+ Yaml::Null => Value::Null,
+ Yaml::BadValue => panic!("bad value"),
+ }
+}
+
+impl Eq for Value {}
+
+impl Hash for Value {
+ fn hash<H: Hasher>(&self, state: &mut H) {
+ match self {
+ Value::Null => 0.hash(state),
+ Value::Bool(b) => (1, b).hash(state),
+ Value::Number(i) => (2, i).hash(state),
+ Value::String(s) => (3, s).hash(state),
+ Value::Sequence(seq) => (4, seq).hash(state),
+ Value::Mapping(map) => (5, map).hash(state),
+ }
+ }
+}
+
+impl<'de> IntoDeserializer<'de, Error> for Value {
+ type Deserializer = Self;
+
+ fn into_deserializer(self) -> Self::Deserializer {
+ self
+ }
+}
diff --git a/third_party/rust/serde_yaml/src/value/partial_eq.rs b/third_party/rust/serde_yaml/src/value/partial_eq.rs
new file mode 100644
index 0000000000..ff9b1f8f8a
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/partial_eq.rs
@@ -0,0 +1,149 @@
+use crate::Value;
+
+impl PartialEq for Value {
+ fn eq(&self, other: &Value) -> bool {
+ match (self, other) {
+ (Value::Null, Value::Null) => true,
+ (Value::Bool(a), Value::Bool(b)) => a == b,
+ (Value::Number(a), Value::Number(b)) => a == b,
+ (Value::String(a), Value::String(b)) => a == b,
+ (Value::Sequence(a), Value::Sequence(b)) => a == b,
+ (Value::Mapping(a), Value::Mapping(b)) => a == b,
+ _ => false,
+ }
+ }
+}
+
+impl PartialEq<str> for Value {
+ /// Compare `str` with YAML value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!(Value::String("lorem".into()) == *"lorem");
+ /// ```
+ fn eq(&self, other: &str) -> bool {
+ self.as_str().map_or(false, |s| s == other)
+ }
+}
+
+impl<'a> PartialEq<&'a str> for Value {
+ /// Compare `&str` with YAML value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!(Value::String("lorem".into()) == "lorem");
+ /// ```
+ fn eq(&self, other: &&str) -> bool {
+ self.as_str().map_or(false, |s| s == *other)
+ }
+}
+
+impl PartialEq<Value> for str {
+ /// Compare YAML value with `str`
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!(*"lorem" == Value::String("lorem".into()));
+ /// ```
+ fn eq(&self, other: &Value) -> bool {
+ other.as_str().map_or(false, |s| s == self)
+ }
+}
+
+impl<'a> PartialEq<Value> for &'a str {
+ /// Compare `&str` with YAML value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!("lorem" == Value::String("lorem".into()));
+ /// ```
+ fn eq(&self, other: &Value) -> bool {
+ other.as_str().map_or(false, |s| s == *self)
+ }
+}
+
+impl PartialEq<String> for Value {
+ /// Compare YAML value with String
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!(Value::String("lorem".into()) == "lorem".to_string());
+ /// ```
+ fn eq(&self, other: &String) -> bool {
+ self.as_str().map_or(false, |s| s == other)
+ }
+}
+
+impl PartialEq<Value> for String {
+ /// Compare `String` with YAML value
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!("lorem".to_string() == Value::String("lorem".into()));
+ /// ```
+ fn eq(&self, other: &Value) -> bool {
+ other.as_str().map_or(false, |s| s == self)
+ }
+}
+
+impl PartialEq<bool> for Value {
+ /// Compare YAML value with bool
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use serde_yaml::Value;
+ /// assert!(Value::Bool(true) == true);
+ /// ```
+ fn eq(&self, other: &bool) -> bool {
+ self.as_bool().map_or(false, |b| b == *other)
+ }
+}
+
+macro_rules! partialeq_numeric {
+ ($([$($ty:ty)*], $conversion:ident, $base:ty)*) => {
+ $($(
+ impl PartialEq<$ty> for Value {
+ fn eq(&self, other: &$ty) -> bool {
+ self.$conversion().map_or(false, |i| i == (*other as $base))
+ }
+ }
+
+ impl PartialEq<Value> for $ty {
+ fn eq(&self, other: &Value) -> bool {
+ other.$conversion().map_or(false, |i| i == (*self as $base))
+ }
+ }
+
+ impl<'a> PartialEq<$ty> for &'a Value {
+ fn eq(&self, other: &$ty) -> bool {
+ self.$conversion().map_or(false, |i| i == (*other as $base))
+ }
+ }
+
+ impl<'a> PartialEq<$ty> for &'a mut Value {
+ fn eq(&self, other: &$ty) -> bool {
+ self.$conversion().map_or(false, |i| i == (*other as $base))
+ }
+ }
+ )*)*
+ }
+}
+
+partialeq_numeric! {
+ [i8 i16 i32 i64 isize], as_i64, i64
+ [u8 u16 u32 u64 usize], as_u64, u64
+ [f32 f64], as_f64, f64
+}
diff --git a/third_party/rust/serde_yaml/src/value/ser.rs b/third_party/rust/serde_yaml/src/value/ser.rs
new file mode 100644
index 0000000000..f2c4bb438c
--- /dev/null
+++ b/third_party/rust/serde_yaml/src/value/ser.rs
@@ -0,0 +1,25 @@
+use crate::Value;
+use serde::Serialize;
+
+impl Serialize for Value {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: serde::Serializer,
+ {
+ match self {
+ Value::Null => serializer.serialize_unit(),
+ Value::Bool(b) => serializer.serialize_bool(*b),
+ Value::Number(n) => n.serialize(serializer),
+ Value::String(s) => serializer.serialize_str(s),
+ Value::Sequence(seq) => seq.serialize(serializer),
+ Value::Mapping(hash) => {
+ use serde::ser::SerializeMap;
+ let mut map = serializer.serialize_map(Some(hash.len()))?;
+ for (k, v) in hash {
+ map.serialize_entry(k, v)?;
+ }
+ map.end()
+ }
+ }
+ }
+}
diff --git a/third_party/rust/serde_yaml/tests/test_de.rs b/third_party/rust/serde_yaml/tests/test_de.rs
new file mode 100644
index 0000000000..e3a8c0da12
--- /dev/null
+++ b/third_party/rust/serde_yaml/tests/test_de.rs
@@ -0,0 +1,396 @@
+#![allow(
+ clippy::cast_lossless,
+ clippy::cast_possible_wrap,
+ clippy::derive_partial_eq_without_eq
+)]
+
+use indoc::indoc;
+use serde_derive::Deserialize;
+use serde_yaml::Value;
+use std::collections::BTreeMap;
+use std::fmt::Debug;
+
+fn test_de<T>(yaml: &str, expected: &T)
+where
+ T: serde::de::DeserializeOwned + PartialEq + Debug,
+{
+ let deserialized: T = serde_yaml::from_str(yaml).unwrap();
+ assert_eq!(*expected, deserialized);
+
+ serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap();
+ serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
+}
+
+fn test_de_seed<T, S>(yaml: &str, seed: S, expected: &T)
+where
+ T: PartialEq + Debug,
+ S: for<'de> serde::de::DeserializeSeed<'de, Value = T>,
+{
+ let deserialized: T = serde_yaml::seed::from_str_seed(yaml, seed).unwrap();
+ assert_eq!(*expected, deserialized);
+
+ serde_yaml::from_str::<serde_yaml::Value>(yaml).unwrap();
+ serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
+}
+
+#[test]
+fn test_alias() {
+ let yaml = indoc! {"
+ ---
+ first:
+ &alias
+ 1
+ second:
+ *alias
+ third: 3
+ "};
+ let mut expected = BTreeMap::new();
+ {
+ expected.insert(String::from("first"), 1);
+ expected.insert(String::from("second"), 1);
+ expected.insert(String::from("third"), 3);
+ }
+ test_de(yaml, &expected);
+}
+
+#[test]
+fn test_option() {
+ #[derive(Deserialize, PartialEq, Debug)]
+ struct Data {
+ a: Option<f64>,
+ b: Option<String>,
+ c: Option<bool>,
+ }
+ let yaml = indoc! {"
+ ---
+ b:
+ c: true
+ "};
+ let expected = Data {
+ a: None,
+ b: None,
+ c: Some(true),
+ };
+ test_de(yaml, &expected);
+}
+
+#[test]
+fn test_option_alias() {
+ #[derive(Deserialize, PartialEq, Debug)]
+ struct Data {
+ a: Option<f64>,
+ b: Option<String>,
+ c: Option<bool>,
+ d: Option<f64>,
+ e: Option<String>,
+ f: Option<bool>,
+ }
+ let yaml = indoc! {"
+ ---
+ none_f:
+ &none_f
+ ~
+ none_s:
+ &none_s
+ ~
+ none_b:
+ &none_b
+ ~
+
+ some_f:
+ &some_f
+ 1.0
+ some_s:
+ &some_s
+ x
+ some_b:
+ &some_b
+ true
+
+ a: *none_f
+ b: *none_s
+ c: *none_b
+ d: *some_f
+ e: *some_s
+ f: *some_b
+ "};
+ let expected = Data {
+ a: None,
+ b: None,
+ c: None,
+ d: Some(1.0),
+ e: Some("x".to_owned()),
+ f: Some(true),
+ };
+ test_de(yaml, &expected);
+}
+
+#[test]
+fn test_enum_alias() {
+ #[derive(Deserialize, PartialEq, Debug)]
+ enum E {
+ A,
+ B(u8, u8),
+ }
+ #[derive(Deserialize, PartialEq, Debug)]
+ struct Data {
+ a: E,
+ b: E,
+ }
+ let yaml = indoc! {"
+ ---
+ aref:
+ &aref
+ A
+ bref:
+ &bref
+ B:
+ - 1
+ - 2
+
+ a: *aref
+ b: *bref
+ "};
+ let expected = Data {
+ a: E::A,
+ b: E::B(1, 2),
+ };
+ test_de(yaml, &expected);
+}
+
+#[test]
+fn test_enum_tag() {
+ #[derive(Deserialize, PartialEq, Debug)]
+ enum E {
+ A(String),
+ B(String),
+ }
+ #[derive(Deserialize, PartialEq, Debug)]
+ struct Data {
+ a: E,
+ b: E,
+ }
+ let yaml = indoc! {"
+ ---
+ a: !A foo
+ b: !B bar
+ "};
+ let expected = Data {
+ a: E::A("foo".into()),
+ b: E::B("bar".into()),
+ };
+ test_de(yaml, &expected);
+}
+
+#[test]
+fn test_number_as_string() {
+ #[derive(Deserialize, PartialEq, Debug)]
+ struct Num {
+ value: String,
+ }
+ let yaml = indoc! {"
+ ---
+ # Cannot be represented as u128
+ value: 340282366920938463463374607431768211457
+ "};
+ let expected = Num {
+ value: "340282366920938463463374607431768211457".to_owned(),
+ };
+ test_de(yaml, &expected);
+}
+
+#[test]
+fn test_i128_big() {
+ let expected: i128 = ::std::i64::MIN as i128 - 1;
+ let yaml = indoc! {"
+ ---
+ -9223372036854775809
+ "};
+ assert_eq!(expected, serde_yaml::from_str::<i128>(yaml).unwrap());
+}
+
+#[test]
+fn test_u128_big() {
+ let expected: u128 = ::std::u64::MAX as u128 + 1;
+ let yaml = indoc! {"
+ ---
+ 18446744073709551616
+ "};
+ assert_eq!(expected, serde_yaml::from_str::<u128>(yaml).unwrap());
+}
+
+#[test]
+fn test_number_alias_as_string() {
+ #[derive(Deserialize, PartialEq, Debug)]
+ struct Num {
+ version: String,
+ value: String,
+ }
+ let yaml = indoc! {"
+ ---
+ version: &a 1.10
+ value: *a
+ "};
+ let expected = Num {
+ version: "1.10".to_owned(),
+ value: "1.10".to_owned(),
+ };
+ test_de(yaml, &expected);
+}
+
+#[test]
+fn test_de_mapping() {
+ #[derive(Debug, Deserialize, PartialEq)]
+ struct Data {
+ pub substructure: serde_yaml::Mapping,
+ }
+ let yaml = indoc! {"
+ ---
+ substructure:
+ a: 'foo'
+ b: 'bar'
+ "};
+
+ let mut expected = Data {
+ substructure: serde_yaml::Mapping::new(),
+ };
+ expected.substructure.insert(
+ serde_yaml::Value::String("a".to_owned()),
+ serde_yaml::Value::String("foo".to_owned()),
+ );
+ expected.substructure.insert(
+ serde_yaml::Value::String("b".to_owned()),
+ serde_yaml::Value::String("bar".to_owned()),
+ );
+
+ test_de(yaml, &expected);
+}
+
+#[test]
+fn test_bomb() {
+ #[derive(Debug, Deserialize, PartialEq)]
+ struct Data {
+ expected: String,
+ }
+
+ // This would deserialize an astronomical number of elements if we were
+ // vulnerable.
+ let yaml = indoc! {"
+ ---
+ a: &a ~
+ b: &b [*a,*a,*a,*a,*a,*a,*a,*a,*a]
+ c: &c [*b,*b,*b,*b,*b,*b,*b,*b,*b]
+ d: &d [*c,*c,*c,*c,*c,*c,*c,*c,*c]
+ e: &e [*d,*d,*d,*d,*d,*d,*d,*d,*d]
+ f: &f [*e,*e,*e,*e,*e,*e,*e,*e,*e]
+ g: &g [*f,*f,*f,*f,*f,*f,*f,*f,*f]
+ h: &h [*g,*g,*g,*g,*g,*g,*g,*g,*g]
+ i: &i [*h,*h,*h,*h,*h,*h,*h,*h,*h]
+ j: &j [*i,*i,*i,*i,*i,*i,*i,*i,*i]
+ k: &k [*j,*j,*j,*j,*j,*j,*j,*j,*j]
+ l: &l [*k,*k,*k,*k,*k,*k,*k,*k,*k]
+ m: &m [*l,*l,*l,*l,*l,*l,*l,*l,*l]
+ n: &n [*m,*m,*m,*m,*m,*m,*m,*m,*m]
+ o: &o [*n,*n,*n,*n,*n,*n,*n,*n,*n]
+ p: &p [*o,*o,*o,*o,*o,*o,*o,*o,*o]
+ q: &q [*p,*p,*p,*p,*p,*p,*p,*p,*p]
+ r: &r [*q,*q,*q,*q,*q,*q,*q,*q,*q]
+ s: &s [*r,*r,*r,*r,*r,*r,*r,*r,*r]
+ t: &t [*s,*s,*s,*s,*s,*s,*s,*s,*s]
+ u: &u [*t,*t,*t,*t,*t,*t,*t,*t,*t]
+ v: &v [*u,*u,*u,*u,*u,*u,*u,*u,*u]
+ w: &w [*v,*v,*v,*v,*v,*v,*v,*v,*v]
+ x: &x [*w,*w,*w,*w,*w,*w,*w,*w,*w]
+ y: &y [*x,*x,*x,*x,*x,*x,*x,*x,*x]
+ z: &z [*y,*y,*y,*y,*y,*y,*y,*y,*y]
+ expected: string
+ "};
+
+ let expected = Data {
+ expected: "string".to_owned(),
+ };
+
+ assert_eq!(expected, serde_yaml::from_str::<Data>(yaml).unwrap());
+}
+
+#[test]
+fn test_numbers() {
+ let cases = [
+ ("0xF0", "240"),
+ ("+0xF0", "240"),
+ ("-0xF0", "-240"),
+ ("0o70", "56"),
+ ("+0o70", "56"),
+ ("-0o70", "-56"),
+ ("0b10", "2"),
+ ("+0b10", "2"),
+ ("-0b10", "-2"),
+ ("127", "127"),
+ ("+127", "127"),
+ ("-127", "-127"),
+ (".inf", ".inf"),
+ (".Inf", ".inf"),
+ (".INF", ".inf"),
+ ("-.inf", "-.inf"),
+ ("-.Inf", "-.inf"),
+ ("-.INF", "-.inf"),
+ (".nan", ".nan"),
+ (".NaN", ".nan"),
+ (".NAN", ".nan"),
+ ("0.1", "0.1"),
+ ];
+ for &(yaml, expected) in &cases {
+ let value = serde_yaml::from_str::<Value>(yaml).unwrap();
+ match value {
+ Value::Number(number) => assert_eq!(number.to_string(), expected),
+ _ => panic!("expected number. input={:?}, result={:?}", yaml, value),
+ }
+ }
+
+ // NOT numbers.
+ let cases = ["0127", "+0127", "-0127"];
+ for yaml in &cases {
+ let value = serde_yaml::from_str::<Value>(yaml).unwrap();
+ match value {
+ Value::String(string) => assert_eq!(string, *yaml),
+ _ => panic!("expected string. input={:?}, result={:?}", yaml, value),
+ }
+ }
+}
+
+#[test]
+fn test_stateful() {
+ struct Seed(i64);
+
+ impl<'de> serde::de::DeserializeSeed<'de> for Seed {
+ type Value = i64;
+ fn deserialize<D>(self, deserializer: D) -> Result<i64, D::Error>
+ where
+ D: serde::de::Deserializer<'de>,
+ {
+ struct Visitor(i64);
+ impl<'de> serde::de::Visitor<'de> for Visitor {
+ type Value = i64;
+
+ fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
+ write!(formatter, "an integer")
+ }
+
+ fn visit_i64<E: serde::de::Error>(self, v: i64) -> Result<i64, E> {
+ Ok(v * self.0)
+ }
+
+ fn visit_u64<E: serde::de::Error>(self, v: u64) -> Result<i64, E> {
+ Ok(v as i64 * self.0)
+ }
+ }
+
+ deserializer.deserialize_any(Visitor(self.0))
+ }
+ }
+
+ let cases = [("3", 5, 15), ("6", 7, 42), ("-5", 9, -45)];
+ for &(yaml, seed, expected) in &cases {
+ test_de_seed(yaml, Seed(seed), &expected);
+ }
+}
diff --git a/third_party/rust/serde_yaml/tests/test_error.rs b/third_party/rust/serde_yaml/tests/test_error.rs
new file mode 100644
index 0000000000..bd830c0fc0
--- /dev/null
+++ b/third_party/rust/serde_yaml/tests/test_error.rs
@@ -0,0 +1,287 @@
+use indoc::indoc;
+use serde_derive::Deserialize;
+use std::fmt::Debug;
+
+fn test_error<T>(yaml: &str, expected: &str)
+where
+ T: serde::de::DeserializeOwned + Debug,
+{
+ let result = serde_yaml::from_str::<T>(yaml);
+ assert_eq!(expected, format!("{}", result.unwrap_err()));
+}
+
+#[test]
+fn test_incorrect_type() {
+ let yaml = indoc! {"
+ ---
+ str
+ "};
+ let expected = "invalid type: string \"str\", expected i16 at line 2 column 1";
+ test_error::<i16>(yaml, expected);
+}
+
+#[test]
+fn test_incorrect_nested_type() {
+ #[derive(Deserialize, Debug)]
+ struct A {
+ #[allow(dead_code)]
+ b: Vec<B>,
+ }
+ #[derive(Deserialize, Debug)]
+ enum B {
+ C(C),
+ }
+ #[derive(Deserialize, Debug)]
+ struct C {
+ #[allow(dead_code)]
+ d: bool,
+ }
+ let yaml = indoc! {"
+ ---
+ b:
+ - C:
+ d: fase
+ "};
+ let expected =
+ "b[0].C.d: invalid type: string \"fase\", expected a boolean at line 4 column 10";
+ test_error::<A>(yaml, expected);
+}
+
+#[test]
+fn test_empty() {
+ let expected = "EOF while parsing a value";
+ test_error::<String>("", expected);
+}
+
+#[test]
+fn test_missing_field() {
+ #[derive(Deserialize, Debug)]
+ struct Basic {
+ #[allow(dead_code)]
+ v: bool,
+ #[allow(dead_code)]
+ w: bool,
+ }
+ let yaml = indoc! {"
+ ---
+ v: true
+ "};
+ let expected = "missing field `w` at line 2 column 2";
+ test_error::<Basic>(yaml, expected);
+}
+
+#[test]
+fn test_unknown_anchor() {
+ let yaml = indoc! {"
+ ---
+ *some
+ "};
+ let expected = "while parsing node, found unknown anchor at line 2 column 1";
+ test_error::<String>(yaml, expected);
+}
+
+#[test]
+fn test_ignored_unknown_anchor() {
+ #[derive(Deserialize, Debug)]
+ struct Wrapper {
+ #[allow(dead_code)]
+ c: (),
+ }
+ let yaml = indoc! {"
+ ---
+ b: [*a]
+ c: ~
+ "};
+ let expected = "while parsing node, found unknown anchor at line 2 column 5";
+ test_error::<Wrapper>(yaml, expected);
+}
+
+#[test]
+fn test_two_documents() {
+ let yaml = indoc! {"
+ ---
+ 0
+ ---
+ 1
+ "};
+ let expected = "deserializing from YAML containing more than one document is not supported";
+ test_error::<usize>(yaml, expected);
+}
+
+#[test]
+fn test_variant_map_wrong_size() {
+ #[derive(Deserialize, Debug)]
+ enum E {
+ V(usize),
+ }
+ let yaml = indoc! {r#"
+ ---
+ "V": 16
+ "other": 32
+ "#};
+ let expected = "invalid length 2, expected map containing 1 entry";
+ test_error::<E>(yaml, expected);
+}
+
+#[test]
+fn test_variant_not_a_map() {
+ #[derive(Deserialize, Debug)]
+ enum E {
+ V(usize),
+ }
+ let yaml = indoc! {r#"
+ ---
+ - "V"
+ "#};
+ let expected = "invalid type: sequence, expected string or singleton map at line 2 column 1";
+ test_error::<E>(yaml, expected);
+}
+
+#[test]
+fn test_variant_not_string() {
+ #[derive(Deserialize, Debug)]
+ enum E {
+ V(bool),
+ }
+ let yaml = indoc! {r#"
+ ---
+ {}: true
+ "#};
+ let expected = "invalid type: map, expected variant of enum `E` at line 2 column 1";
+ test_error::<E>(yaml, expected);
+}
+
+#[test]
+fn test_bad_bool() {
+ let yaml = indoc! {"
+ ---
+ !!bool str
+ "};
+ let expected = "invalid value: string \"str\", expected a boolean at line 2 column 8";
+ test_error::<bool>(yaml, expected);
+}
+
+#[test]
+fn test_bad_int() {
+ let yaml = indoc! {"
+ ---
+ !!int str
+ "};
+ let expected = "invalid value: string \"str\", expected an integer at line 2 column 7";
+ test_error::<i64>(yaml, expected);
+}
+
+#[test]
+fn test_bad_float() {
+ let yaml = indoc! {"
+ ---
+ !!float str
+ "};
+ let expected = "invalid value: string \"str\", expected a float at line 2 column 9";
+ test_error::<f64>(yaml, expected);
+}
+
+#[test]
+fn test_bad_null() {
+ let yaml = indoc! {"
+ ---
+ !!null str
+ "};
+ let expected = "invalid value: string \"str\", expected null at line 2 column 8";
+ test_error::<()>(yaml, expected);
+}
+
+#[test]
+fn test_short_tuple() {
+ let yaml = indoc! {"
+ ---
+ [0, 0]
+ "};
+ let expected = "invalid length 2, expected a tuple of size 3 at line 2 column 1";
+ test_error::<(u8, u8, u8)>(yaml, expected);
+}
+
+#[test]
+fn test_long_tuple() {
+ let yaml = indoc! {"
+ ---
+ [0, 0, 0]
+ "};
+ let expected = "invalid length 3, expected sequence of 2 elements at line 2 column 1";
+ test_error::<(u8, u8)>(yaml, expected);
+}
+
+#[test]
+fn test_no_location() {
+ let invalid_utf8: Result<serde_yaml::Value, serde_yaml::Error> =
+ serde_yaml::from_slice(b"\x80\xae");
+
+ let utf8_location = invalid_utf8.unwrap_err().location();
+
+ assert!(utf8_location.is_none());
+}
+
+#[test]
+fn test_invalid_scalar_type() {
+ #[derive(Deserialize, Debug)]
+ struct S {
+ #[allow(dead_code)]
+ x: [(); 1],
+ }
+
+ let yaml = "x:\n";
+ let expected = "x: invalid type: unit value, expected an array of length 1 at line 2 column 1";
+ test_error::<S>(yaml, expected);
+}
+
+#[test]
+fn test_infinite_recursion_objects() {
+ #[derive(Deserialize, Debug)]
+ struct S {
+ #[allow(dead_code)]
+ x: Option<Box<S>>,
+ }
+
+ let yaml = "&a {x: *a}";
+ let expected = "recursion limit exceeded";
+ test_error::<S>(yaml, expected);
+}
+
+#[test]
+fn test_infinite_recursion_arrays() {
+ #[derive(Deserialize, Debug)]
+ struct S {
+ #[allow(dead_code)]
+ x: Option<Box<S>>,
+ }
+
+ let yaml = "&a [*a]";
+ let expected = "recursion limit exceeded";
+ test_error::<S>(yaml, expected);
+}
+
+#[test]
+fn test_finite_recursion_objects() {
+ #[derive(Deserialize, Debug)]
+ struct S {
+ #[allow(dead_code)]
+ x: Option<Box<S>>,
+ }
+
+ let yaml = "{x:".repeat(1_000) + &"}".repeat(1_000);
+ let expected = "recursion limit exceeded at line 1 column 766";
+ test_error::<i32>(&yaml, expected);
+}
+
+#[test]
+fn test_finite_recursion_arrays() {
+ #[derive(Deserialize, Debug)]
+ struct S {
+ #[allow(dead_code)]
+ x: Option<Box<S>>,
+ }
+
+ let yaml = "[".repeat(1_000) + &"]".repeat(1_000);
+ let expected = "recursion limit exceeded at line 1 column 256";
+ test_error::<S>(&yaml, expected);
+}
diff --git a/third_party/rust/serde_yaml/tests/test_serde.rs b/third_party/rust/serde_yaml/tests/test_serde.rs
new file mode 100644
index 0000000000..8b3f34b3fc
--- /dev/null
+++ b/third_party/rust/serde_yaml/tests/test_serde.rs
@@ -0,0 +1,434 @@
+#![allow(
+ clippy::decimal_literal_representation,
+ clippy::derive_partial_eq_without_eq,
+ clippy::unreadable_literal,
+ clippy::shadow_unrelated
+)]
+
+use indoc::indoc;
+use serde_derive::{Deserialize, Serialize};
+use serde_yaml::Value;
+use std::collections::BTreeMap;
+use std::f64;
+use std::fmt::Debug;
+
+fn test_serde<T>(thing: &T, yaml: &str)
+where
+ T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug,
+{
+ let serialized = serde_yaml::to_string(&thing).unwrap();
+ assert_eq!(yaml, serialized);
+
+ let value = serde_yaml::to_value(&thing).unwrap();
+ let serialized = serde_yaml::to_string(&value).unwrap();
+ assert_eq!(yaml, serialized);
+
+ let deserialized: T = serde_yaml::from_str(yaml).unwrap();
+ assert_eq!(*thing, deserialized);
+
+ let value: Value = serde_yaml::from_str(yaml).unwrap();
+ let deserialized: T = serde_yaml::from_value(value).unwrap();
+ assert_eq!(*thing, deserialized);
+
+ serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
+}
+
+#[test]
+fn test_default() {
+ assert_eq!(Value::default(), Value::Null);
+}
+
+#[test]
+fn test_int() {
+ let thing = 256;
+ let yaml = indoc! {"
+ ---
+ 256
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_int_max_u64() {
+ let thing = ::std::u64::MAX;
+ let yaml = indoc! {"
+ ---
+ 18446744073709551615
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_int_min_i64() {
+ let thing = ::std::i64::MIN;
+ let yaml = indoc! {"
+ ---
+ -9223372036854775808
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_int_max_i64() {
+ let thing = ::std::i64::MAX;
+ let yaml = indoc! {"
+ ---
+ 9223372036854775807
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_i128_small() {
+ let thing: i128 = -256;
+ let yaml = indoc! {"
+ ---
+ -256
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_u128_small() {
+ let thing: u128 = 256;
+ let yaml = indoc! {"
+ ---
+ 256
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_float() {
+ let thing = 25.6;
+ let yaml = indoc! {"
+ ---
+ 25.6
+ "};
+ test_serde(&thing, yaml);
+
+ let thing = 25.;
+ let yaml = indoc! {"
+ ---
+ 25.0
+ "};
+ test_serde(&thing, yaml);
+
+ let thing = f64::INFINITY;
+ let yaml = indoc! {"
+ ---
+ .inf
+ "};
+ test_serde(&thing, yaml);
+
+ let thing = f64::NEG_INFINITY;
+ let yaml = indoc! {"
+ ---
+ -.inf
+ "};
+ test_serde(&thing, yaml);
+
+ let float: f64 = serde_yaml::from_str(indoc! {"
+ ---
+ .nan
+ "})
+ .unwrap();
+ assert!(float.is_nan());
+}
+
+#[test]
+fn test_float32() {
+ let thing: f32 = 25.6;
+ let yaml = indoc! {"
+ ---
+ 25.6
+ "};
+ test_serde(&thing, yaml);
+
+ let thing = f32::INFINITY;
+ let yaml = indoc! {"
+ ---
+ .inf
+ "};
+ test_serde(&thing, yaml);
+
+ let thing = f32::NEG_INFINITY;
+ let yaml = indoc! {"
+ ---
+ -.inf
+ "};
+ test_serde(&thing, yaml);
+
+ let single_float: f32 = serde_yaml::from_str(indoc! {"
+ ---
+ .nan
+ "})
+ .unwrap();
+ assert!(single_float.is_nan());
+}
+
+#[test]
+fn test_vec() {
+ let thing = vec![1, 2, 3];
+ let yaml = indoc! {"
+ ---
+ - 1
+ - 2
+ - 3
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_map() {
+ let mut thing = BTreeMap::new();
+ thing.insert(String::from("x"), 1);
+ thing.insert(String::from("y"), 2);
+ let yaml = indoc! {"
+ ---
+ x: 1
+ y: 2
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_basic_struct() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Basic {
+ x: isize,
+ y: String,
+ z: bool,
+ }
+ let thing = Basic {
+ x: -4,
+ y: String::from("hi\tquoted"),
+ z: true,
+ };
+ let yaml = indoc! {r#"
+ ---
+ x: -4
+ y: "hi\tquoted"
+ z: true
+ "#};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_nested_vec() {
+ let thing = vec![vec![1, 2, 3], vec![4, 5, 6]];
+ let yaml = indoc! {"
+ ---
+ - - 1
+ - 2
+ - 3
+ - - 4
+ - 5
+ - 6
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_nested_struct() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Outer {
+ inner: Inner,
+ }
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Inner {
+ v: u16,
+ }
+ let thing = Outer {
+ inner: Inner { v: 512 },
+ };
+ let yaml = indoc! {"
+ ---
+ inner:
+ v: 512
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_option() {
+ let thing = vec![Some(1), None, Some(3)];
+ let yaml = indoc! {"
+ ---
+ - 1
+ - ~
+ - 3
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_unit() {
+ let thing = vec![(), ()];
+ let yaml = indoc! {"
+ ---
+ - ~
+ - ~
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_unit_struct() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Foo;
+ let thing = Foo;
+ let yaml = indoc! {"
+ ---
+ ~
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_unit_variant() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ enum Variant {
+ First,
+ Second,
+ }
+ let thing = Variant::First;
+ let yaml = indoc! {"
+ ---
+ First
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_newtype_struct() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct OriginalType {
+ v: u16,
+ }
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct NewType(OriginalType);
+ let thing = NewType(OriginalType { v: 1 });
+ let yaml = indoc! {"
+ ---
+ v: 1
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_newtype_variant() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ enum Variant {
+ Size(usize),
+ }
+ let thing = Variant::Size(127);
+ let yaml = indoc! {"
+ ---
+ Size: 127
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_tuple_variant() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ enum Variant {
+ Rgb(u8, u8, u8),
+ }
+ let thing = Variant::Rgb(32, 64, 96);
+ let yaml = indoc! {"
+ ---
+ Rgb:
+ - 32
+ - 64
+ - 96
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_struct_variant() {
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ enum Variant {
+ Color { r: u8, g: u8, b: u8 },
+ }
+ let thing = Variant::Color {
+ r: 32,
+ g: 64,
+ b: 96,
+ };
+ let yaml = indoc! {"
+ ---
+ Color:
+ r: 32
+ g: 64
+ b: 96
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_value() {
+ use serde_yaml::{Mapping, Number};
+
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ pub struct GenericInstructions {
+ #[serde(rename = "type")]
+ pub typ: String,
+ pub config: Value,
+ }
+ let thing = GenericInstructions {
+ typ: "primary".to_string(),
+ config: Value::Sequence(vec![
+ Value::Null,
+ Value::Bool(true),
+ Value::Number(Number::from(65535)),
+ Value::Number(Number::from(0.54321)),
+ Value::String("s".into()),
+ Value::Mapping(Mapping::new()),
+ ]),
+ };
+ let yaml = indoc! {"
+ ---
+ type: primary
+ config:
+ - ~
+ - true
+ - 65535
+ - 0.54321
+ - s
+ - {}
+ "};
+ test_serde(&thing, yaml);
+}
+
+#[test]
+fn test_mapping() {
+ use serde_yaml::Mapping;
+ #[derive(Serialize, Deserialize, PartialEq, Debug)]
+ struct Data {
+ pub substructure: Mapping,
+ }
+
+ let mut thing = Data {
+ substructure: Mapping::new(),
+ };
+ thing.substructure.insert(
+ Value::String("a".to_owned()),
+ Value::String("foo".to_owned()),
+ );
+ thing.substructure.insert(
+ Value::String("b".to_owned()),
+ Value::String("bar".to_owned()),
+ );
+
+ let yaml = indoc! {"
+ ---
+ substructure:
+ a: foo
+ b: bar
+ "};
+
+ test_serde(&thing, yaml);
+}
diff --git a/third_party/rust/serde_yaml/tests/test_value.rs b/third_party/rust/serde_yaml/tests/test_value.rs
new file mode 100644
index 0000000000..c001b9d73d
--- /dev/null
+++ b/third_party/rust/serde_yaml/tests/test_value.rs
@@ -0,0 +1,55 @@
+#![allow(clippy::derive_partial_eq_without_eq, clippy::eq_op)]
+
+use serde::de::IntoDeserializer;
+use serde::Deserialize;
+use serde_derive::Deserialize;
+use serde_yaml::{Number, Value};
+use std::f64;
+
+#[test]
+fn test_nan() {
+ let pos_nan = serde_yaml::from_str::<Value>(".nan").unwrap();
+ assert!(pos_nan.is_f64());
+ assert_eq!(pos_nan, pos_nan);
+
+ let neg_fake_nan = serde_yaml::from_str::<Value>("-.nan").unwrap();
+ assert!(neg_fake_nan.is_string());
+
+ let significand_mask = 0xF_FFFF_FFFF_FFFF;
+ let bits = (f64::NAN.to_bits() ^ significand_mask) | 1;
+ let different_pos_nan = Value::Number(Number::from(f64::from_bits(bits)));
+ assert_eq!(pos_nan, different_pos_nan);
+}
+
+#[test]
+fn test_digits() {
+ let num_string = serde_yaml::from_str::<Value>("01").unwrap();
+ assert!(num_string.is_string());
+}
+
+#[test]
+fn test_into_deserializer() {
+ #[derive(Debug, Deserialize, PartialEq)]
+ struct Test {
+ first: String,
+ second: u32,
+ }
+
+ let value = serde_yaml::from_str::<Value>("xyz").unwrap();
+ let s = String::deserialize(value.into_deserializer()).unwrap();
+ assert_eq!(s, "xyz");
+
+ let value = serde_yaml::from_str::<Value>("- first\n- second\n- third").unwrap();
+ let arr = Vec::<String>::deserialize(value.into_deserializer()).unwrap();
+ assert_eq!(arr, &["first", "second", "third"]);
+
+ let value = serde_yaml::from_str::<Value>("first: abc\nsecond: 99").unwrap();
+ let test = Test::deserialize(value.into_deserializer()).unwrap();
+ assert_eq!(
+ test,
+ Test {
+ first: "abc".to_string(),
+ second: 99
+ }
+ );
+}