Compare commits

...

64 Commits

Author SHA1 Message Date
David Tolnay b6685cf9dd Release 1.0.182 2023-08-05 22:16:46 -07:00
David Tolnay fc273c6763 Resolve needless_return clippy lint in PR 2553
warning: unneeded `return` statement
        --> serde_derive/src/de.rs:2986:13
         |
    2986 |             return quote!(#assign_to __default.#member);
         |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_return
         = note: `-W clippy::needless-return` implied by `-W clippy::all`
    help: remove `return`
         |
    2986 -             return quote!(#assign_to __default.#member);
    2986 +             quote!(#assign_to __default.#member)
         |
2023-08-05 22:16:19 -07:00
David Tolnay bd7b0e257e Touch up PR 2553 2023-08-05 22:13:09 -07:00
David Tolnay 73931692b2 Merge pull request #2553 from Mingun/default-on-tuples
Allow `#[serde(default)]` on tuple structs
2023-08-05 22:12:10 -07:00
David Tolnay 4d93e9f44c Keep deserialize aliases as a sorted set 2023-08-05 17:06:11 -07:00
David Tolnay da55ed7e8d Remove some clones of names of things 2023-08-05 17:01:34 -07:00
David Tolnay e3617e1f28 Update explanation of correct_aliases 2023-08-05 16:39:38 -07:00
David Tolnay 431636af0d Merge pull request #2458 from Mingun/identifier
Keep aliases always sorted and include aliases in expecting message for field/variant_identifier
2023-08-05 16:39:14 -07:00
David Tolnay 891ced598a Update test suite to nightly-2023-08-05
error: the feature `lang_items` is internal to the compiler or standard library
     --> src/main.rs:1:12
      |
    1 | #![feature(lang_items, start)]
      |            ^^^^^^^^^^
      |
      = note: using it is strongly discouraged
      = note: `#[deny(internal_features)]` on by default
2023-08-04 19:09:00 -07:00
David Tolnay 57dc0ee769 Release 1.0.181 2023-08-03 16:58:45 -07:00
David Tolnay 5e102c4da1 Relocate private size_hint module
Let's keep crate::__private for only things that *need* to be accessible
to the macro-generated code. Size_hint can be pub(crate).
2023-08-03 16:53:44 -07:00
Mingun 5c33931422 Allow #[serde(default)] on tuple structs 2023-08-03 22:32:34 +05:00
David Tolnay 4aa54222f4 Delete double reference when setting up adjacently tagged variant seed 2023-08-01 22:54:47 -07:00
David Tolnay ef4f860384 Improve "expecting" message of adjacently tagged enum variant 2023-08-01 22:49:44 -07:00
David Tolnay 9bd52ec5c1 Inline AdjacentlyTaggedEnumVariant::new 2023-08-01 22:38:47 -07:00
David Tolnay 5cdd82d41e Remove Serializer from name of private type that is not a Serializer 2023-08-01 22:26:04 -07:00
David Tolnay 110bf10481 Condense AdjacentlyTaggedEnummVariantVisitor implementation 2023-08-01 22:26:03 -07:00
David Tolnay 43035f6f37 Merge pull request #2505 from Baptistemontan/rework_adjacently_tagged_enum
Revisit of the representation of adjacently tagged enums tag
2023-08-01 22:25:31 -07:00
David Tolnay 83b1a3d5dc Merge pull request #2443 from Mingun/deserialize-in-place
Simplify code in deserialize_in_place_struct and implement #2387 for in-place case
2023-08-01 21:51:22 -07:00
Mingun 878110a4bc Simplify code after dead code elimination 2023-08-01 19:03:21 +05:00
Mingun 59ec8b7db2 Remove dead code - variant_ident and deserializer are always None 2023-08-01 19:03:20 +05:00
Mingun cae1b43829 Inline deserialize_newtype_struct_in_place 2023-08-01 19:03:19 +05:00
Mingun 99fde4ee3e Implement #2387 also for deserialize_in_place method 2023-08-01 19:03:19 +05:00
Mingun afe3872810 Simplify check for missing fields 2023-08-01 19:03:18 +05:00
Mingun 3a3e6bf103 Reorder variables to match order in final quote! 2023-08-01 19:03:18 +05:00
Mingun 935f0bd70f Merge some quote! blocks 2023-08-01 19:03:17 +05:00
Mingun 5c18bfeda6 Inline deserialize_struct_as_struct_in_place_visitor 2023-08-01 19:03:17 +05:00
Baptiste de Montangon 957ef206d1 Revisit of the representation of adjacently tagged enums tag 2023-07-31 20:53:02 +02:00
David Tolnay 0c367838cc Merge pull request #2548 from dtolnay/toolattr
Adopt tool attrs for clippy lint level attributes
2023-07-31 11:48:33 -07:00
David Tolnay 2023cf345f Adopt tool attrs for clippy lint level attributes
Requires rustc 1.31+.
2023-07-31 11:39:31 -07:00
David Tolnay 033d05f70b Release 1.0.180 2023-07-31 11:16:12 -07:00
David Tolnay fe4e3fd3b0 Merge pull request #2547 from dtolnay/tombstone
Delete tombstones of the `__private` module
2023-07-30 22:48:34 -07:00
David Tolnay 8a8a8a70ee Delete tombstones of the __private module
These are previous names of the `__private` module -- first
`serde::export` then `serde::private` then `serde::__private` -- in all
cases marked `doc(hidden)` and documented as not public API. Leaving a
tombstone made rustc give a better diagnostic "module is private" rather
than "unresolved import". But the rename to `__private` was 2.5 years
ago in dd1f4b483e so it's unlikely anyone
is still benefiting from the tombstone at this point.
2023-07-30 22:44:59 -07:00
David Tolnay 339dca828d Merge pull request #2546 from dtolnay/edition
Update to 2018 edition
2023-07-30 22:11:44 -07:00
David Tolnay 0d7349fa4e Resolve ambiguous core import on rustc 1.64 through 1.71
In 1.72+, this is fixed by https://github.com/rust-lang/rust/pull/112086.

    error[E0659]: `core` is ambiguous
       --> serde/src/lib.rs:227:13
        |
    227 |     pub use core::ffi::CStr;
        |             ^^^^ ambiguous name
        |
        = note: ambiguous because of multiple potential import sources
        = note: `core` could refer to a built-in crate
        = help: use `::core` to refer to this crate unambiguously
    note: `core` could also refer to the module defined here
       --> serde/src/lib.rs:166:5
        |
    166 | /     mod core {
    167 | |         #[cfg(not(feature = "std"))]
    168 | |         pub use core::*;
    169 | |         #[cfg(feature = "std")]
    170 | |         pub use std::*;
    171 | |     }
        | |_____^
        = help: use `self::core` to refer to this module unambiguously
2023-07-30 22:06:18 -07:00
David Tolnay 830528d5b1 Update to 2018 edition 2023-07-30 21:45:35 -07:00
David Tolnay ab90fbc7c9 Apply 'cargo fix --edition' 2023-07-30 21:42:57 -07:00
David Tolnay 3eec111e8f Delete support for compilers without crate::-based module system 2023-07-30 21:42:57 -07:00
David Tolnay 9388433642 Rename 'try!' macro to 'tri!' in preparation for 2018 edition
Because 'try' is a keyword in 2018+.
2023-07-30 21:29:53 -07:00
David Tolnay ba12070665 Merge pull request #2545 from dtolnay/up
Delete support for rustc versions 1.19 through 1.27
2023-07-30 21:25:58 -07:00
David Tolnay a57a324d72 Delete support for compilers without NonZero integer types 2023-07-30 21:14:32 -07:00
David Tolnay 92e91b3557 Delete support for compilers without Iterator::try_for_each 2023-07-30 21:14:31 -07:00
David Tolnay 4dcf791706 Delete support for compilers without inclusive range accessors 2023-07-30 21:11:43 -07:00
David Tolnay e77900fb94 Update integer128 case in build script 2023-07-30 21:11:09 -07:00
David Tolnay 1b14cadf20 Delete support for compilers without core::ops::Bound 2023-07-30 21:11:02 -07:00
David Tolnay 4f59cd217a Delete support for compilers without core::time 2023-07-30 21:10:49 -07:00
David Tolnay 27c8b2d66a Delete support for compilers without dynamically sized Rc construction 2023-07-30 20:48:27 -07:00
David Tolnay 89976c2712 Delete support for compilers without PathBuf::into_boxed_path 2023-07-30 20:48:27 -07:00
David Tolnay c91737fef1 Delete support for compilers without CString::into_boxed_c_str 2023-07-30 20:48:27 -07:00
David Tolnay a100719bc6 Delete support for compilers without core::cmp::Reverse 2023-07-30 20:48:27 -07:00
David Tolnay 9a0e149225 Sort version checks in build.rs 2023-07-30 20:48:27 -07:00
David Tolnay 9350927903 Delete support for compilers without std::collections::Bound 2023-07-30 20:48:27 -07:00
David Tolnay 677c13a4ec Merge pull request #2544 from dtolnay/testprecompiled
Add CI job to run test suite against precompiled serde_derive
2023-07-30 18:58:13 -07:00
David Tolnay ee8e1ee7ff Add CI job to run test suite against precompiled serde_derive 2023-07-30 18:50:16 -07:00
David Tolnay f969080b9f Pull in syn fix that makes serde test suite independent of "full" feature
See https://github.com/dtolnay/syn/pull/1491.
2023-07-30 17:39:44 -07:00
Mingun f709fc05b0 Do not run the code when results are not used 2023-07-23 15:23:39 +05:00
Mingun 089aae1292 Eliminate even more allocations 2023-07-23 15:23:39 +05:00
Mingun 855acaf112 Eliminate additional allocations for flattening aliases 2023-07-23 15:23:38 +05:00
Mingun 7ca7720262 Slightly reduced number of allocations 2023-07-23 15:23:37 +05:00
Mingun 78fea3aa4a Show possible aliases in the expected message
Fixes tests
2023-07-23 15:23:37 +05:00
Mingun 1efb8b6a53 Add tests for aliases
failures (2):
    field_identifier::unknown
    variant_identifier::unknown
2023-07-23 15:23:36 +05:00
Mingun bc1960b106 Add tests for unknown field / variant 2023-07-23 15:23:33 +05:00
Mingun 967023b755 Group field_identifier and variant_identifier tests in sub-modules
(review this commit with "ignore whitespace changes" option on)
2023-07-23 15:21:22 +05:00
Mingun bb51e68f16 Keep aliases sorted 2023-07-23 15:21:21 +05:00
46 changed files with 1076 additions and 869 deletions
+24 -19
View File
@@ -77,7 +77,7 @@ jobs:
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
rust: [1.19.0, 1.20.0, 1.21.0, 1.25.0, 1.26.0, 1.34.0] rust: [1.31.0, 1.34.0]
timeout-minutes: 45 timeout-minutes: 45
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@@ -88,24 +88,6 @@ jobs:
- run: cd serde && cargo build --no-default-features - run: cd serde && cargo build --no-default-features
- run: cd serde && cargo build - run: cd serde && cargo build
more:
name: Rust ${{matrix.rust}}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
rust: [1.27.0, 1.28.0]
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
# Work around failing to parse manifest because editions are unstable.
- run: sed -i /test_suite/d Cargo.toml
- run: cd serde && cargo build --no-default-features
- run: cd serde && cargo build
derive: derive:
name: Rust 1.56.0 name: Rust 1.56.0
runs-on: ubuntu-latest runs-on: ubuntu-latest
@@ -127,6 +109,29 @@ jobs:
- uses: dtolnay/rust-toolchain@1.36.0 - uses: dtolnay/rust-toolchain@1.36.0
- run: cd serde && cargo build --no-default-features --features alloc - run: cd serde && cargo build --no-default-features --features alloc
precompiled:
name: Precompiled
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
with:
components: rust-src
targets: x86_64-unknown-linux-musl
- run: precompiled/build.sh
- name: replace serde_derive dependency with precompiled
run: |
# FIXME: consider using `cargo rm serde_derive` but it's currently broken
# https://github.com/rust-lang/cargo/issues/12419
sed -i '/serde_derive =/d' serde/Cargo.toml
sed -i '/derive = \["serde_derive"\]/d' serde/Cargo.toml
sed -i '/"serde_derive"/d' Cargo.toml
sed -i '/\[workspace\]/d' precompiled/serde_derive/Cargo.toml
cargo add --dev serde_derive --path precompiled/serde_derive --manifest-path test_suite/Cargo.toml
git diff
- run: cd test_suite && cargo test --features unstable -- --skip ui --exact
macos: macos:
name: macOS name: macOS
runs-on: macos-latest runs-on: macos-latest
+3 -3
View File
@@ -1,12 +1,12 @@
# Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.19+]][Rust 1.19] [![serde_derive: rustc 1.56+]][Rust 1.56] # Serde   [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.31+]][Rust 1.31] [![serde_derive: rustc 1.56+]][Rust 1.56]
[Build Status]: https://img.shields.io/github/actions/workflow/status/serde-rs/serde/ci.yml?branch=master [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 [actions]: https://github.com/serde-rs/serde/actions?query=branch%3Amaster
[Latest Version]: https://img.shields.io/crates/v/serde.svg [Latest Version]: https://img.shields.io/crates/v/serde.svg
[crates.io]: https://crates.io/crates/serde [crates.io]: https://crates.io/crates/serde
[serde: rustc 1.19+]: https://img.shields.io/badge/serde-rustc_1.19+-lightgray.svg [serde: rustc 1.31+]: https://img.shields.io/badge/serde-rustc_1.31+-lightgray.svg
[serde_derive: rustc 1.56+]: https://img.shields.io/badge/serde_derive-rustc_1.56+-lightgray.svg [serde_derive: rustc 1.56+]: https://img.shields.io/badge/serde_derive-rustc_1.56+-lightgray.svg
[Rust 1.19]: https://blog.rust-lang.org/2017/07/20/Rust-1.19.html [Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html
[Rust 1.56]: https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html [Rust 1.56]: https://blog.rust-lang.org/2021/10/21/Rust-1.56.0.html
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.** **Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.179" version = "1.0.182"
authors = ["David Tolnay <dtolnay@gmail.com>"] authors = ["David Tolnay <dtolnay@gmail.com>"]
publish = false publish = false
@@ -14,4 +14,4 @@ path = "main.rs"
[dependencies] [dependencies]
proc-macro2 = "1" proc-macro2 = "1"
quote = { version = "1", default-features = false } quote = { version = "1", default-features = false }
syn = { version = "2.0.25", default-features = false, features = ["clone-impls", "derive", "full", "parsing", "printing"] } syn = { version = "2.0.28", default-features = false, features = ["clone-impls", "derive", "full", "parsing", "printing"] }
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.179" version = "1.0.182"
authors = ["David Tolnay <dtolnay@gmail.com>"] authors = ["David Tolnay <dtolnay@gmail.com>"]
categories = ["no-std", "no-std::no-alloc"] categories = ["no-std", "no-std::no-alloc"]
description = "Implementation of #[derive(Serialize, Deserialize)]" description = "Implementation of #[derive(Serialize, Deserialize)]"
@@ -24,7 +24,7 @@ proc-macro = true
[target.'cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))'.dependencies] [target.'cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))'.dependencies]
proc-macro2 = "1" proc-macro2 = "1"
quote = "1" quote = "1"
syn = "2.0.25" syn = "2.0.28"
[dev-dependencies] [dev-dependencies]
serde = { version = "1", path = "../../serde" } serde = { version = "1", path = "../../serde" }
+1 -1
View File
@@ -13,7 +13,7 @@
//! //!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.179")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.182")]
#[cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))] #[cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))]
include!("lib_from_source.rs"); include!("lib_from_source.rs");
+4 -3
View File
@@ -1,20 +1,21 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.179" # remember to update html_root_url and serde_derive dependency version = "1.0.182" # remember to update html_root_url and serde_derive dependency
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
build = "build.rs" build = "build.rs"
categories = ["encoding", "no-std", "no-std::no-alloc"] categories = ["encoding", "no-std", "no-std::no-alloc"]
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
documentation = "https://docs.rs/serde" documentation = "https://docs.rs/serde"
edition = "2018"
homepage = "https://serde.rs" homepage = "https://serde.rs"
keywords = ["serde", "serialization", "no_std"] keywords = ["serde", "serialization", "no_std"]
license = "MIT OR Apache-2.0" license = "MIT OR Apache-2.0"
readme = "crates-io.md" readme = "crates-io.md"
repository = "https://github.com/serde-rs/serde" repository = "https://github.com/serde-rs/serde"
rust-version = "1.19" rust-version = "1.31"
[dependencies] [dependencies]
serde_derive = { version = "=1.0.179", optional = true, path = "../serde_derive" } serde_derive = { version = "=1.0.182", optional = true, path = "../serde_derive" }
[dev-dependencies] [dev-dependencies]
serde_derive = { version = "1", path = "../serde_derive" } serde_derive = { version = "1", path = "../serde_derive" }
+7 -62
View File
@@ -16,68 +16,6 @@ fn main() {
let target = env::var("TARGET").unwrap(); let target = env::var("TARGET").unwrap();
let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten"; 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");
}
// TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add // TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add
// stabilized in Rust 1.34: // 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#tryfrom-and-tryinto
@@ -89,6 +27,13 @@ fn main() {
println!("cargo:rustc-cfg=no_relaxed_trait_bounds"); println!("cargo:rustc-cfg=no_relaxed_trait_bounds");
} }
// 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 emscripten && minor < 40 {
println!("cargo:rustc-cfg=no_integer128");
}
// Current minimum supported version of serde_derive crate is Rust 1.56. // Current minimum supported version of serde_derive crate is Rust 1.56.
if minor < 56 { if minor < 56 {
println!("cargo:rustc-cfg=no_serde_derive"); println!("cargo:rustc-cfg=no_serde_derive");
+2 -2
View File
@@ -1,5 +1,5 @@
use lib::fmt::{self, Write}; use crate::lib::fmt::{self, Write};
use lib::str; use crate::lib::str;
pub(super) struct Buf<'a> { pub(super) struct Buf<'a> {
bytes: &'a mut [u8], bytes: &'a mut [u8],
+5 -5
View File
@@ -1,6 +1,6 @@
use lib::*; use crate::lib::*;
use de::{ use crate::de::{
Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor, Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, VariantAccess, Visitor,
}; };
@@ -197,7 +197,7 @@ impl<'de> Visitor<'de> for IgnoredAny {
where where
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
while let Some(IgnoredAny) = try!(seq.next_element()) { while let Some(IgnoredAny) = tri!(seq.next_element()) {
// Gobble // Gobble
} }
Ok(IgnoredAny) Ok(IgnoredAny)
@@ -208,7 +208,7 @@ impl<'de> Visitor<'de> for IgnoredAny {
where where
A: MapAccess<'de>, A: MapAccess<'de>,
{ {
while let Some((IgnoredAny, IgnoredAny)) = try!(map.next_entry()) { while let Some((IgnoredAny, IgnoredAny)) = tri!(map.next_entry()) {
// Gobble // Gobble
} }
Ok(IgnoredAny) Ok(IgnoredAny)
@@ -227,7 +227,7 @@ impl<'de> Visitor<'de> for IgnoredAny {
where where
A: EnumAccess<'de>, A: EnumAccess<'de>,
{ {
try!(data.variant::<IgnoredAny>()).1.newtype_variant() tri!(data.variant::<IgnoredAny>()).1.newtype_variant()
} }
} }
+72 -117
View File
@@ -1,16 +1,14 @@
use lib::*; use crate::lib::*;
use de::{ use crate::de::{
Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor, Deserialize, Deserializer, EnumAccess, Error, MapAccess, SeqAccess, Unexpected, VariantAccess,
Visitor,
}; };
#[cfg(any(feature = "std", feature = "alloc", not(no_core_duration)))] use crate::seed::InPlaceSeed;
use de::MapAccess;
use seed::InPlaceSeed;
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use __private::size_hint; use crate::de::size_hint;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -84,7 +82,7 @@ macro_rules! impl_deserialize_num {
($primitive:ident, $nonzero:ident $(cfg($($cfg:tt)*))*, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => { ($primitive:ident, $nonzero:ident $(cfg($($cfg:tt)*))*, $deserialize:ident $($method:ident!($($val:ident : $visit:ident)*);)*) => {
impl_deserialize_num!($primitive, $deserialize $($method!($($val : $visit)*);)*); impl_deserialize_num!($primitive, $deserialize $($method!($($val : $visit)*);)*);
#[cfg(all(not(no_num_nonzero), $($($cfg)*)*))] $(#[cfg($($cfg)*)])*
impl<'de> Deserialize<'de> for num::$nonzero { impl<'de> Deserialize<'de> for num::$nonzero {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@@ -684,7 +682,7 @@ impl<'de> Visitor<'de> for CStringVisitor {
let capacity = size_hint::cautious::<u8>(seq.size_hint()); let capacity = size_hint::cautious::<u8>(seq.size_hint());
let mut values = Vec::<u8>::with_capacity(capacity); let mut values = Vec::<u8>::with_capacity(capacity);
while let Some(value) = try!(seq.next_element()) { while let Some(value) = tri!(seq.next_element()) {
values.push(value); values.push(value);
} }
@@ -747,13 +745,9 @@ macro_rules! forwarded_impl {
} }
} }
#[cfg(all( #[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))]
any(feature = "std", all(not(no_core_cstr), feature = "alloc")),
not(no_de_boxed_c_str)
))]
forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str); forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
#[cfg(not(no_core_reverse))]
forwarded_impl!((T), Reverse<T>, Reverse); forwarded_impl!((T), Reverse<T>, Reverse);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -901,7 +895,7 @@ macro_rules! seq_impl {
{ {
let mut values = $with_capacity; let mut values = $with_capacity;
while let Some(value) = try!($access.next_element()) { while let Some(value) = tri!($access.next_element()) {
$insert(&mut values, value); $insert(&mut values, value);
} }
@@ -939,7 +933,7 @@ macro_rules! seq_impl {
$reserve(&mut self.0, size_hint::cautious::<T>($access.size_hint())); $reserve(&mut self.0, size_hint::cautious::<T>($access.size_hint()));
// FIXME: try to overwrite old values here? (Vec, VecDeque, LinkedList) // FIXME: try to overwrite old values here? (Vec, VecDeque, LinkedList)
while let Some(value) = try!($access.next_element()) { while let Some(value) = tri!($access.next_element()) {
$insert(&mut self.0, value); $insert(&mut self.0, value);
} }
@@ -1039,7 +1033,7 @@ where
let capacity = size_hint::cautious::<T>(seq.size_hint()); let capacity = size_hint::cautious::<T>(seq.size_hint());
let mut values = Vec::<T>::with_capacity(capacity); let mut values = Vec::<T>::with_capacity(capacity);
while let Some(value) = try!(seq.next_element()) { while let Some(value) = tri!(seq.next_element()) {
values.push(value); values.push(value);
} }
@@ -1081,7 +1075,7 @@ where
for i in 0..self.0.len() { for i in 0..self.0.len() {
let next = { let next = {
let next_place = InPlaceSeed(&mut self.0[i]); let next_place = InPlaceSeed(&mut self.0[i]);
try!(seq.next_element_seed(next_place)) tri!(seq.next_element_seed(next_place))
}; };
if next.is_none() { if next.is_none() {
self.0.truncate(i); self.0.truncate(i);
@@ -1089,7 +1083,7 @@ where
} }
} }
while let Some(value) = try!(seq.next_element()) { while let Some(value) = tri!(seq.next_element()) {
self.0.push(value); self.0.push(value);
} }
@@ -1161,7 +1155,7 @@ macro_rules! array_impls {
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
Ok([$( Ok([$(
match try!(seq.next_element()) { match tri!(seq.next_element()) {
Some(val) => val, Some(val) => val,
None => return Err(Error::invalid_length($n, &self)), None => return Err(Error::invalid_length($n, &self)),
} }
@@ -1186,7 +1180,7 @@ macro_rules! array_impls {
{ {
let mut fail_idx = None; let mut fail_idx = None;
for (idx, dest) in self.0[..].iter_mut().enumerate() { for (idx, dest) in self.0[..].iter_mut().enumerate() {
if try!(seq.next_element_seed(InPlaceSeed(dest))).is_none() { if tri!(seq.next_element_seed(InPlaceSeed(dest))).is_none() {
fail_idx = Some(idx); fail_idx = Some(idx);
break; break;
} }
@@ -1284,7 +1278,7 @@ macro_rules! tuple_impls {
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
$( $(
let $name = match try!(seq.next_element()) { let $name = match tri!(seq.next_element()) {
Some(value) => value, Some(value) => value,
None => return Err(Error::invalid_length($n, &self)), None => return Err(Error::invalid_length($n, &self)),
}; };
@@ -1318,7 +1312,7 @@ macro_rules! tuple_impls {
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
$( $(
if try!(seq.next_element_seed(InPlaceSeed(&mut (self.0).$n))).is_none() { if tri!(seq.next_element_seed(InPlaceSeed(&mut (self.0).$n))).is_none() {
return Err(Error::invalid_length($n, &self)); return Err(Error::invalid_length($n, &self));
} }
)+ )+
@@ -1395,7 +1389,7 @@ macro_rules! map_impl {
{ {
let mut values = $with_capacity; let mut values = $with_capacity;
while let Some((key, value)) = try!($access.next_entry()) { while let Some((key, value)) = tri!($access.next_entry()) {
values.insert(key, value); values.insert(key, value);
} }
@@ -1541,7 +1535,7 @@ macro_rules! deserialize_enum {
where where
A: EnumAccess<'de>, A: EnumAccess<'de>,
{ {
match try!(data.variant()) { match tri!(data.variant()) {
$( $(
($name_kind :: $variant, v) => v.newtype_variant().map($name :: $variant), ($name_kind :: $variant, v) => v.newtype_variant().map($name :: $variant),
)* )*
@@ -1561,7 +1555,7 @@ impl<'de> Deserialize<'de> for net::IpAddr {
if deserializer.is_human_readable() { if deserializer.is_human_readable() {
deserializer.deserialize_str(FromStrVisitor::new("IP address")) deserializer.deserialize_str(FromStrVisitor::new("IP address"))
} else { } else {
use lib::net::IpAddr; use crate::lib::net::IpAddr;
deserialize_enum! { deserialize_enum! {
IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1) IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
"`V4` or `V6`", "`V4` or `V6`",
@@ -1604,7 +1598,7 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
if deserializer.is_human_readable() { if deserializer.is_human_readable() {
deserializer.deserialize_str(FromStrVisitor::new("socket address")) deserializer.deserialize_str(FromStrVisitor::new("socket address"))
} else { } else {
use lib::net::SocketAddr; use crate::lib::net::SocketAddr;
deserialize_enum! { deserialize_enum! {
SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1) SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
"`V4` or `V6`", "`V4` or `V6`",
@@ -1714,7 +1708,7 @@ impl<'de> Deserialize<'de> for PathBuf {
} }
} }
#[cfg(all(feature = "std", not(no_de_boxed_path)))] #[cfg(feature = "std")]
forwarded_impl!((), Box<Path>, PathBuf::into_boxed_path); forwarded_impl!((), Box<Path>, PathBuf::into_boxed_path);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -1748,7 +1742,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
{ {
use std::os::unix::ffi::OsStringExt; use std::os::unix::ffi::OsStringExt;
match try!(data.variant()) { match tri!(data.variant()) {
(OsStringKind::Unix, v) => v.newtype_variant().map(OsString::from_vec), (OsStringKind::Unix, v) => v.newtype_variant().map(OsString::from_vec),
(OsStringKind::Windows, _) => Err(Error::custom( (OsStringKind::Windows, _) => Err(Error::custom(
"cannot deserialize Windows OS string on Unix", "cannot deserialize Windows OS string on Unix",
@@ -1763,7 +1757,7 @@ impl<'de> Visitor<'de> for OsStringVisitor {
{ {
use std::os::windows::ffi::OsStringExt; use std::os::windows::ffi::OsStringExt;
match try!(data.variant()) { match tri!(data.variant()) {
(OsStringKind::Windows, v) => v (OsStringKind::Windows, v) => v
.newtype_variant::<Vec<u16>>() .newtype_variant::<Vec<u16>>()
.map(|vec| OsString::from_wide(&vec)), .map(|vec| OsString::from_wide(&vec)),
@@ -1795,30 +1789,6 @@ forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice);
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
forwarded_impl!((), Box<str>, String::into_boxed_str); 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"))] #[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T> impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
where where
@@ -1849,7 +1819,7 @@ where
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
try!(Option::<T>::deserialize(deserializer)); tri!(Option::<T>::deserialize(deserializer));
Ok(RcWeak::new()) Ok(RcWeak::new())
} }
} }
@@ -1867,18 +1837,14 @@ where
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
try!(Option::<T>::deserialize(deserializer)); tri!(Option::<T>::deserialize(deserializer));
Ok(ArcWeak::new()) Ok(ArcWeak::new())
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(all( #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
not(no_de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
macro_rules! box_forwarded_impl { macro_rules! box_forwarded_impl {
( (
$(#[doc = $doc:tt])* $(#[doc = $doc:tt])*
@@ -1899,11 +1865,7 @@ macro_rules! box_forwarded_impl {
}; };
} }
#[cfg(all( #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
not(no_de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
box_forwarded_impl! { box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde. /// This impl requires the [`"rc"`] Cargo feature of Serde.
/// ///
@@ -1915,11 +1877,7 @@ box_forwarded_impl! {
Rc Rc
} }
#[cfg(all( #[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
not(no_de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
box_forwarded_impl! { box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde. /// This impl requires the [`"rc"`] Cargo feature of Serde.
/// ///
@@ -1963,7 +1921,6 @@ forwarded_impl!((T), RwLock<T>, RwLock::new);
// secs: u64, // secs: u64,
// nanos: u32, // nanos: u32,
// } // }
#[cfg(any(feature = "std", not(no_core_duration)))]
impl<'de> Deserialize<'de> for Duration { impl<'de> Deserialize<'de> for Duration {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where where
@@ -2011,7 +1968,7 @@ impl<'de> Deserialize<'de> for Duration {
b"secs" => Ok(Field::Secs), b"secs" => Ok(Field::Secs),
b"nanos" => Ok(Field::Nanos), b"nanos" => Ok(Field::Nanos),
_ => { _ => {
let value = ::__private::from_utf8_lossy(value); let value = crate::__private::from_utf8_lossy(value);
Err(Error::unknown_field(&*value, FIELDS)) Err(Error::unknown_field(&*value, FIELDS))
} }
} }
@@ -2046,19 +2003,19 @@ impl<'de> Deserialize<'de> for Duration {
where where
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
let secs: u64 = match try!(seq.next_element()) { let secs: u64 = match tri!(seq.next_element()) {
Some(value) => value, Some(value) => value,
None => { None => {
return Err(Error::invalid_length(0, &self)); return Err(Error::invalid_length(0, &self));
} }
}; };
let nanos: u32 = match try!(seq.next_element()) { let nanos: u32 = match tri!(seq.next_element()) {
Some(value) => value, Some(value) => value,
None => { None => {
return Err(Error::invalid_length(1, &self)); return Err(Error::invalid_length(1, &self));
} }
}; };
try!(check_overflow(secs, nanos)); tri!(check_overflow(secs, nanos));
Ok(Duration::new(secs, nanos)) Ok(Duration::new(secs, nanos))
} }
@@ -2068,19 +2025,19 @@ impl<'de> Deserialize<'de> for Duration {
{ {
let mut secs: Option<u64> = None; let mut secs: Option<u64> = None;
let mut nanos: Option<u32> = None; let mut nanos: Option<u32> = None;
while let Some(key) = try!(map.next_key()) { while let Some(key) = tri!(map.next_key()) {
match key { match key {
Field::Secs => { Field::Secs => {
if secs.is_some() { if secs.is_some() {
return Err(<A::Error as Error>::duplicate_field("secs")); return Err(<A::Error as Error>::duplicate_field("secs"));
} }
secs = Some(try!(map.next_value())); secs = Some(tri!(map.next_value()));
} }
Field::Nanos => { Field::Nanos => {
if nanos.is_some() { if nanos.is_some() {
return Err(<A::Error as Error>::duplicate_field("nanos")); return Err(<A::Error as Error>::duplicate_field("nanos"));
} }
nanos = Some(try!(map.next_value())); nanos = Some(tri!(map.next_value()));
} }
} }
} }
@@ -2092,7 +2049,7 @@ impl<'de> Deserialize<'de> for Duration {
Some(nanos) => nanos, Some(nanos) => nanos,
None => return Err(<A::Error as Error>::missing_field("nanos")), None => return Err(<A::Error as Error>::missing_field("nanos")),
}; };
try!(check_overflow(secs, nanos)); tri!(check_overflow(secs, nanos));
Ok(Duration::new(secs, nanos)) Ok(Duration::new(secs, nanos))
} }
} }
@@ -2184,19 +2141,19 @@ impl<'de> Deserialize<'de> for SystemTime {
where where
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
let secs: u64 = match try!(seq.next_element()) { let secs: u64 = match tri!(seq.next_element()) {
Some(value) => value, Some(value) => value,
None => { None => {
return Err(Error::invalid_length(0, &self)); return Err(Error::invalid_length(0, &self));
} }
}; };
let nanos: u32 = match try!(seq.next_element()) { let nanos: u32 = match tri!(seq.next_element()) {
Some(value) => value, Some(value) => value,
None => { None => {
return Err(Error::invalid_length(1, &self)); return Err(Error::invalid_length(1, &self));
} }
}; };
try!(check_overflow(secs, nanos)); tri!(check_overflow(secs, nanos));
Ok(Duration::new(secs, nanos)) Ok(Duration::new(secs, nanos))
} }
@@ -2206,7 +2163,7 @@ impl<'de> Deserialize<'de> for SystemTime {
{ {
let mut secs: Option<u64> = None; let mut secs: Option<u64> = None;
let mut nanos: Option<u32> = None; let mut nanos: Option<u32> = None;
while let Some(key) = try!(map.next_key()) { while let Some(key) = tri!(map.next_key()) {
match key { match key {
Field::Secs => { Field::Secs => {
if secs.is_some() { if secs.is_some() {
@@ -2214,7 +2171,7 @@ impl<'de> Deserialize<'de> for SystemTime {
"secs_since_epoch", "secs_since_epoch",
)); ));
} }
secs = Some(try!(map.next_value())); secs = Some(tri!(map.next_value()));
} }
Field::Nanos => { Field::Nanos => {
if nanos.is_some() { if nanos.is_some() {
@@ -2222,7 +2179,7 @@ impl<'de> Deserialize<'de> for SystemTime {
"nanos_since_epoch", "nanos_since_epoch",
)); ));
} }
nanos = Some(try!(map.next_value())); nanos = Some(tri!(map.next_value()));
} }
} }
} }
@@ -2234,13 +2191,13 @@ impl<'de> Deserialize<'de> for SystemTime {
Some(nanos) => nanos, Some(nanos) => nanos,
None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")), None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")),
}; };
try!(check_overflow(secs, nanos)); tri!(check_overflow(secs, nanos));
Ok(Duration::new(secs, nanos)) Ok(Duration::new(secs, nanos))
} }
} }
const FIELDS: &[&str] = &["secs_since_epoch", "nanos_since_epoch"]; const FIELDS: &[&str] = &["secs_since_epoch", "nanos_since_epoch"];
let duration = try!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor)); let duration = tri!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor));
#[cfg(not(no_systemtime_checked_add))] #[cfg(not(no_systemtime_checked_add))]
let ret = UNIX_EPOCH let ret = UNIX_EPOCH
.checked_add(duration) .checked_add(duration)
@@ -2269,7 +2226,7 @@ where
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let (start, end) = try!(deserializer.deserialize_struct( let (start, end) = tri!(deserializer.deserialize_struct(
"Range", "Range",
range::FIELDS, range::FIELDS,
range::RangeVisitor { range::RangeVisitor {
@@ -2281,7 +2238,6 @@ where
} }
} }
#[cfg(not(no_range_inclusive))]
impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx> impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx>
where where
Idx: Deserialize<'de>, Idx: Deserialize<'de>,
@@ -2290,7 +2246,7 @@ where
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let (start, end) = try!(deserializer.deserialize_struct( let (start, end) = tri!(deserializer.deserialize_struct(
"RangeInclusive", "RangeInclusive",
range::FIELDS, range::FIELDS,
range::RangeVisitor { range::RangeVisitor {
@@ -2303,9 +2259,9 @@ where
} }
mod range { mod range {
use lib::*; use crate::lib::*;
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
pub const FIELDS: &[&str] = &["start", "end"]; pub const FIELDS: &[&str] = &["start", "end"];
@@ -2351,7 +2307,7 @@ mod range {
b"start" => Ok(Field::Start), b"start" => Ok(Field::Start),
b"end" => Ok(Field::End), b"end" => Ok(Field::End),
_ => { _ => {
let value = ::__private::from_utf8_lossy(value); let value = crate::__private::from_utf8_lossy(value);
Err(Error::unknown_field(&*value, FIELDS)) Err(Error::unknown_field(&*value, FIELDS))
} }
} }
@@ -2381,13 +2337,13 @@ mod range {
where where
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
let start: Idx = match try!(seq.next_element()) { let start: Idx = match tri!(seq.next_element()) {
Some(value) => value, Some(value) => value,
None => { None => {
return Err(Error::invalid_length(0, &self)); return Err(Error::invalid_length(0, &self));
} }
}; };
let end: Idx = match try!(seq.next_element()) { let end: Idx = match tri!(seq.next_element()) {
Some(value) => value, Some(value) => value,
None => { None => {
return Err(Error::invalid_length(1, &self)); return Err(Error::invalid_length(1, &self));
@@ -2402,19 +2358,19 @@ mod range {
{ {
let mut start: Option<Idx> = None; let mut start: Option<Idx> = None;
let mut end: Option<Idx> = None; let mut end: Option<Idx> = None;
while let Some(key) = try!(map.next_key()) { while let Some(key) = tri!(map.next_key()) {
match key { match key {
Field::Start => { Field::Start => {
if start.is_some() { if start.is_some() {
return Err(<A::Error as Error>::duplicate_field("start")); return Err(<A::Error as Error>::duplicate_field("start"));
} }
start = Some(try!(map.next_value())); start = Some(tri!(map.next_value()));
} }
Field::End => { Field::End => {
if end.is_some() { if end.is_some() {
return Err(<A::Error as Error>::duplicate_field("end")); return Err(<A::Error as Error>::duplicate_field("end"));
} }
end = Some(try!(map.next_value())); end = Some(tri!(map.next_value()));
} }
} }
} }
@@ -2448,7 +2404,7 @@ where
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let start = try!(deserializer.deserialize_struct( let start = tri!(deserializer.deserialize_struct(
"RangeFrom", "RangeFrom",
range_from::FIELDS, range_from::FIELDS,
range_from::RangeFromVisitor { range_from::RangeFromVisitor {
@@ -2461,9 +2417,9 @@ where
} }
mod range_from { mod range_from {
use lib::*; use crate::lib::*;
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
pub const FIELDS: &[&str] = &["end"]; pub const FIELDS: &[&str] = &["end"];
@@ -2506,7 +2462,7 @@ mod range_from {
match value { match value {
b"end" => Ok(Field::End), b"end" => Ok(Field::End),
_ => { _ => {
let value = ::__private::from_utf8_lossy(value); let value = crate::__private::from_utf8_lossy(value);
Err(Error::unknown_field(&*value, FIELDS)) Err(Error::unknown_field(&*value, FIELDS))
} }
} }
@@ -2536,7 +2492,7 @@ mod range_from {
where where
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
let end: Idx = match try!(seq.next_element()) { let end: Idx = match tri!(seq.next_element()) {
Some(value) => value, Some(value) => value,
None => { None => {
return Err(Error::invalid_length(0, &self)); return Err(Error::invalid_length(0, &self));
@@ -2550,13 +2506,13 @@ mod range_from {
A: MapAccess<'de>, A: MapAccess<'de>,
{ {
let mut end: Option<Idx> = None; let mut end: Option<Idx> = None;
while let Some(key) = try!(map.next_key()) { while let Some(key) = tri!(map.next_key()) {
match key { match key {
Field::End => { Field::End => {
if end.is_some() { if end.is_some() {
return Err(<A::Error as Error>::duplicate_field("end")); return Err(<A::Error as Error>::duplicate_field("end"));
} }
end = Some(try!(map.next_value())); end = Some(tri!(map.next_value()));
} }
} }
} }
@@ -2586,7 +2542,7 @@ where
where where
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
let end = try!(deserializer.deserialize_struct( let end = tri!(deserializer.deserialize_struct(
"RangeTo", "RangeTo",
range_to::FIELDS, range_to::FIELDS,
range_to::RangeToVisitor { range_to::RangeToVisitor {
@@ -2599,9 +2555,9 @@ where
} }
mod range_to { mod range_to {
use lib::*; use crate::lib::*;
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; use crate::de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
pub const FIELDS: &[&str] = &["start"]; pub const FIELDS: &[&str] = &["start"];
@@ -2644,7 +2600,7 @@ mod range_to {
match value { match value {
b"start" => Ok(Field::Start), b"start" => Ok(Field::Start),
_ => { _ => {
let value = ::__private::from_utf8_lossy(value); let value = crate::__private::from_utf8_lossy(value);
Err(Error::unknown_field(&*value, FIELDS)) Err(Error::unknown_field(&*value, FIELDS))
} }
} }
@@ -2674,7 +2630,7 @@ mod range_to {
where where
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
let start: Idx = match try!(seq.next_element()) { let start: Idx = match tri!(seq.next_element()) {
Some(value) => value, Some(value) => value,
None => { None => {
return Err(Error::invalid_length(0, &self)); return Err(Error::invalid_length(0, &self));
@@ -2688,13 +2644,13 @@ mod range_to {
A: MapAccess<'de>, A: MapAccess<'de>,
{ {
let mut start: Option<Idx> = None; let mut start: Option<Idx> = None;
while let Some(key) = try!(map.next_key()) { while let Some(key) = tri!(map.next_key()) {
match key { match key {
Field::Start => { Field::Start => {
if start.is_some() { if start.is_some() {
return Err(<A::Error as Error>::duplicate_field("start")); return Err(<A::Error as Error>::duplicate_field("start"));
} }
start = Some(try!(map.next_value())); start = Some(tri!(map.next_value()));
} }
} }
} }
@@ -2709,7 +2665,6 @@ mod range_to {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
impl<'de, T> Deserialize<'de> for Bound<T> impl<'de, T> Deserialize<'de> for Bound<T>
where where
T: Deserialize<'de>, T: Deserialize<'de>,
@@ -2801,7 +2756,7 @@ where
where where
A: EnumAccess<'de>, A: EnumAccess<'de>,
{ {
match try!(data.variant()) { match tri!(data.variant()) {
(Field::Unbounded, v) => v.unit_variant().map(|()| Bound::Unbounded), (Field::Unbounded, v) => v.unit_variant().map(|()| Bound::Unbounded),
(Field::Included, v) => v.newtype_variant().map(Bound::Included), (Field::Included, v) => v.newtype_variant().map(Bound::Included),
(Field::Excluded, v) => v.newtype_variant().map(Bound::Excluded), (Field::Excluded, v) => v.newtype_variant().map(Bound::Excluded),
@@ -2910,7 +2865,7 @@ where
where where
A: EnumAccess<'de>, A: EnumAccess<'de>,
{ {
match try!(data.variant()) { match tri!(data.variant()) {
(Field::Ok, v) => v.newtype_variant().map(Ok), (Field::Ok, v) => v.newtype_variant().map(Ok),
(Field::Err, v) => v.newtype_variant().map(Err), (Field::Err, v) => v.newtype_variant().map(Err),
} }
+14 -13
View File
@@ -112,7 +112,7 @@
//! [derive section of the manual]: https://serde.rs/derive.html //! [derive section of the manual]: https://serde.rs/derive.html
//! [data formats]: https://serde.rs/#data-formats //! [data formats]: https://serde.rs/#data-formats
use lib::*; use crate::lib::*;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -122,19 +122,20 @@ pub mod value;
mod format; mod format;
mod ignored_any; mod ignored_any;
mod impls; mod impls;
pub(crate) mod size_hint;
mod utf8; mod utf8;
pub use self::ignored_any::IgnoredAny; pub use self::ignored_any::IgnoredAny;
#[cfg(not(any(feature = "std", feature = "unstable")))]
#[doc(no_inline)]
pub use crate::std_error::Error as StdError;
#[cfg(all(feature = "unstable", not(feature = "std")))] #[cfg(all(feature = "unstable", not(feature = "std")))]
#[doc(no_inline)] #[doc(no_inline)]
pub use core::error::Error as StdError; pub use core::error::Error as StdError;
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[doc(no_inline)] #[doc(no_inline)]
pub use std::error::Error as StdError; pub use std::error::Error as StdError;
#[cfg(not(any(feature = "std", feature = "unstable")))]
#[doc(no_inline)]
pub use std_error::Error as StdError;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -569,7 +570,7 @@ pub trait Deserialize<'de>: Sized {
D: Deserializer<'de>, D: Deserializer<'de>,
{ {
// Default implementation just delegates to `deserialize` impl. // Default implementation just delegates to `deserialize` impl.
*place = try!(Deserialize::deserialize(deserializer)); *place = tri!(Deserialize::deserialize(deserializer));
Ok(()) Ok(())
} }
} }
@@ -1229,11 +1230,11 @@ pub trait Deserializer<'de>: Sized {
#[doc(hidden)] #[doc(hidden)]
fn __deserialize_content<V>( fn __deserialize_content<V>(
self, self,
_: ::actually_private::T, _: crate::actually_private::T,
visitor: V, visitor: V,
) -> Result<::private::de::Content<'de>, Self::Error> ) -> Result<crate::__private::de::Content<'de>, Self::Error>
where where
V: Visitor<'de, Value = ::private::de::Content<'de>>, V: Visitor<'de, Value = crate::__private::de::Content<'de>>,
{ {
self.deserialize_any(visitor) self.deserialize_any(visitor)
} }
@@ -1834,9 +1835,9 @@ pub trait MapAccess<'de> {
K: DeserializeSeed<'de>, K: DeserializeSeed<'de>,
V: DeserializeSeed<'de>, V: DeserializeSeed<'de>,
{ {
match try!(self.next_key_seed(kseed)) { match tri!(self.next_key_seed(kseed)) {
Some(key) => { Some(key) => {
let value = try!(self.next_value_seed(vseed)); let value = tri!(self.next_value_seed(vseed));
Ok(Some((key, value))) Ok(Some((key, value)))
} }
None => Ok(None), None => Ok(None),
@@ -2284,12 +2285,12 @@ impl Display for OneOf {
1 => write!(formatter, "`{}`", self.names[0]), 1 => write!(formatter, "`{}`", self.names[0]),
2 => write!(formatter, "`{}` or `{}`", self.names[0], self.names[1]), 2 => write!(formatter, "`{}` or `{}`", self.names[0], self.names[1]),
_ => { _ => {
try!(write!(formatter, "one of ")); tri!(write!(formatter, "one of "));
for (i, alt) in self.names.iter().enumerate() { for (i, alt) in self.names.iter().enumerate() {
if i > 0 { if i > 0 {
try!(write!(formatter, ", ")); tri!(write!(formatter, ", "));
} }
try!(write!(formatter, "`{}`", alt)); tri!(write!(formatter, "`{}`", alt));
} }
Ok(()) Ok(())
} }
+1 -1
View File
@@ -1,4 +1,4 @@
use de::{Deserialize, DeserializeSeed, Deserializer}; use crate::de::{Deserialize, DeserializeSeed, Deserializer};
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors. /// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
/// ///
@@ -1,4 +1,4 @@
use lib::*; use crate::lib::*;
pub fn from_bounds<I>(iter: &I) -> Option<usize> pub fn from_bounds<I>(iter: &I) -> Option<usize>
where where
+1 -1
View File
@@ -1,4 +1,4 @@
use lib::*; use crate::lib::*;
const TAG_CONT: u8 = 0b1000_0000; const TAG_CONT: u8 = 0b1000_0000;
const TAG_TWO_B: u8 = 0b1100_0000; const TAG_TWO_B: u8 = 0b1100_0000;
+17 -16
View File
@@ -21,12 +21,11 @@
//! } //! }
//! ``` //! ```
use lib::*; use crate::lib::*;
use self::private::{First, Second}; use self::private::{First, Second};
use __private::size_hint; use crate::de::{self, size_hint, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
use de::{self, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor}; use crate::ser;
use ser;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -937,8 +936,8 @@ where
where where
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
let v = try!(visitor.visit_seq(&mut self)); let v = tri!(visitor.visit_seq(&mut self));
try!(self.end()); tri!(self.end());
Ok(v) Ok(v)
} }
@@ -1162,8 +1161,8 @@ where
where where
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
let value = try!(visitor.visit_map(&mut self)); let value = tri!(visitor.visit_map(&mut self));
try!(self.end()); tri!(self.end());
Ok(value) Ok(value)
} }
@@ -1171,8 +1170,8 @@ where
where where
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
let value = try!(visitor.visit_seq(&mut self)); let value = tri!(visitor.visit_seq(&mut self));
try!(self.end()); tri!(self.end());
Ok(value) Ok(value)
} }
@@ -1236,8 +1235,8 @@ where
{ {
match self.next_pair() { match self.next_pair() {
Some((key, value)) => { Some((key, value)) => {
let key = try!(kseed.deserialize(key.into_deserializer())); let key = tri!(kseed.deserialize(key.into_deserializer()));
let value = try!(vseed.deserialize(value.into_deserializer())); let value = tri!(vseed.deserialize(value.into_deserializer()));
Ok(Some((key, value))) Ok(Some((key, value)))
} }
None => Ok(None), None => Ok(None),
@@ -1341,7 +1340,7 @@ where
V: de::Visitor<'de>, V: de::Visitor<'de>,
{ {
let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), PhantomData); let mut pair_visitor = PairVisitor(Some(self.0), Some(self.1), PhantomData);
let pair = try!(visitor.visit_seq(&mut pair_visitor)); let pair = tri!(visitor.visit_seq(&mut pair_visitor));
if pair_visitor.1.is_none() { if pair_visitor.1.is_none() {
Ok(pair) Ok(pair)
} else { } else {
@@ -1501,7 +1500,7 @@ where
where where
T: de::DeserializeSeed<'de>, T: de::DeserializeSeed<'de>,
{ {
match try!(self.map.next_key_seed(seed)) { match tri!(self.map.next_key_seed(seed)) {
Some(key) => Ok((key, private::map_as_enum(self.map))), Some(key) => Ok((key, private::map_as_enum(self.map))),
None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")), None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")),
} }
@@ -1546,9 +1545,11 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
mod private { mod private {
use lib::*; use crate::lib::*;
use de::{self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor}; use crate::de::{
self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor,
};
pub struct UnitOnly<E> { pub struct UnitOnly<E> {
marker: PhantomData<E>, marker: PhantomData<E>,
+50 -72
View File
@@ -93,7 +93,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.179")] #![doc(html_root_url = "https://docs.rs/serde/1.0.182")]
// Support using Serde without the standard library! // Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and // Unstable functionality only if the user asks for it. For tracking and
@@ -102,55 +102,51 @@
// https://github.com/serde-rs/serde/issues/812 // https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(error_in_core, never_type))] #![cfg_attr(feature = "unstable", feature(error_in_core, never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)] #![allow(unknown_lints, bare_trait_objects, deprecated)]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
// Ignored clippy and clippy_pedantic lints // Ignored clippy and clippy_pedantic lints
#![cfg_attr( #![allow(
feature = "cargo-clippy", // clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
allow( clippy::unnested_or_patterns,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704 // clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768
unnested_or_patterns, clippy::semicolon_if_nothing_returned,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768 // not available in our oldest supported compiler
semicolon_if_nothing_returned, clippy::empty_enum,
// not available in our oldest supported compiler clippy::type_repetition_in_bounds, // https://github.com/rust-lang/rust-clippy/issues/8772
empty_enum, // integer and float ser/de requires these sorts of casts
type_repetition_in_bounds, // https://github.com/rust-lang/rust-clippy/issues/8772 clippy::cast_possible_truncation,
// integer and float ser/de requires these sorts of casts clippy::cast_possible_wrap,
cast_possible_truncation, clippy::cast_sign_loss,
cast_possible_wrap, // things are often more readable this way
cast_sign_loss, clippy::cast_lossless,
// things are often more readable this way clippy::module_name_repetitions,
cast_lossless, clippy::option_if_let_else,
module_name_repetitions, clippy::single_match_else,
option_if_let_else, clippy::type_complexity,
single_match_else, clippy::use_self,
type_complexity, clippy::zero_prefixed_literal,
use_self, // correctly used
zero_prefixed_literal, clippy::derive_partial_eq_without_eq,
// correctly used clippy::enum_glob_use,
derive_partial_eq_without_eq, clippy::explicit_auto_deref,
enum_glob_use, clippy::let_underscore_untyped,
explicit_auto_deref, clippy::map_err_ignore,
let_underscore_untyped, clippy::new_without_default,
map_err_ignore, clippy::result_unit_err,
new_without_default, clippy::wildcard_imports,
result_unit_err, // not practical
wildcard_imports, clippy::needless_pass_by_value,
// not practical clippy::similar_names,
needless_pass_by_value, clippy::too_many_lines,
similar_names, // preference
too_many_lines, clippy::doc_markdown,
// preference clippy::unseparated_literal_suffix,
doc_markdown, // false positive
unseparated_literal_suffix, clippy::needless_doctest_main,
// false positive // noisy
needless_doctest_main, clippy::missing_errors_doc,
// noisy clippy::must_use_candidate,
missing_errors_doc,
must_use_candidate,
)
)] )]
// Restrictions // Restrictions
#![cfg_attr(feature = "cargo-clippy", deny(question_mark_used))] #![deny(clippy::question_mark_used)]
// Rustc lints. // Rustc lints.
#![deny(missing_docs, unused_imports)] #![deny(missing_docs, unused_imports)]
@@ -177,14 +173,16 @@ mod lib {
pub use self::core::cell::{Cell, RefCell}; pub use self::core::cell::{Cell, RefCell};
pub use self::core::clone::{self, Clone}; pub use self::core::clone::{self, Clone};
pub use self::core::cmp::Reverse;
pub use self::core::convert::{self, From, Into}; pub use self::core::convert::{self, From, Into};
pub use self::core::default::{self, Default}; pub use self::core::default::{self, Default};
pub use self::core::fmt::{self, Debug, Display}; pub use self::core::fmt::{self, Debug, Display};
pub use self::core::marker::{self, PhantomData}; pub use self::core::marker::{self, PhantomData};
pub use self::core::num::Wrapping; pub use self::core::num::Wrapping;
pub use self::core::ops::{Range, RangeFrom, RangeTo}; pub use self::core::ops::{Bound, Range, RangeFrom, RangeInclusive, RangeTo};
pub use self::core::option::{self, Option}; pub use self::core::option::{self, Option};
pub use self::core::result::{self, Result}; pub use self::core::result::{self, Result};
pub use self::core::time::Duration;
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::borrow::{Cow, ToOwned}; pub use alloc::borrow::{Cow, ToOwned};
@@ -222,7 +220,7 @@ mod lib {
pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque}; pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
#[cfg(all(not(no_core_cstr), not(feature = "std")))] #[cfg(all(not(no_core_cstr), not(feature = "std")))]
pub use core::ffi::CStr; pub use self::core::ffi::CStr;
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::ffi::CStr; pub use std::ffi::CStr;
@@ -249,18 +247,6 @@ mod lib {
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::time::{SystemTime, UNIX_EPOCH}; 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)))] #[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic)))]
pub use std::sync::atomic::{ pub use std::sync::atomic::{
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8, AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
@@ -281,16 +267,13 @@ mod lib {
pub use std::sync::atomic::{AtomicI64, AtomicU64}; pub use std::sync::atomic::{AtomicI64, AtomicU64};
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "ptr"))] #[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "ptr"))]
pub use std::sync::atomic::{AtomicIsize, AtomicUsize}; 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 // None of this crate's error handling needs the `From::from` error conversion
// performed implicitly by the `?` operator or the standard library's `try!` // performed implicitly by the `?` operator or the standard library's `try!`
// macro. This simplified macro gives a 5.5% improvement in compile time // macro. This simplified macro gives a 5.5% improvement in compile time
// compared to standard `try!`, and 9% improvement compared to `?`. // compared to standard `try!`, and 9% improvement compared to `?`.
macro_rules! try { macro_rules! tri {
($expr:expr) => { ($expr:expr) => {
match $expr { match $expr {
Ok(val) => val, Ok(val) => val,
@@ -311,20 +294,15 @@ pub mod de;
pub mod ser; pub mod ser;
#[doc(inline)] #[doc(inline)]
pub use de::{Deserialize, Deserializer}; pub use crate::de::{Deserialize, Deserializer};
#[doc(inline)] #[doc(inline)]
pub use ser::{Serialize, Serializer}; pub use crate::ser::{Serialize, Serializer};
// Used by generated code and doc tests. Not public API. // Used by generated code and doc tests. Not public API.
#[doc(hidden)] #[doc(hidden)]
#[path = "private/mod.rs"] #[path = "private/mod.rs"]
pub mod __private; pub mod __private;
#[allow(unused_imports)]
use self::__private as export;
#[allow(unused_imports)]
use self::__private as private;
#[path = "de/seed.rs"] #[path = "de/seed.rs"]
mod seed; mod seed;
+83 -29
View File
@@ -1,10 +1,13 @@
use lib::*; use crate::lib::*;
use de::value::{BorrowedBytesDeserializer, BytesDeserializer}; use crate::de::value::{BorrowedBytesDeserializer, BytesDeserializer};
use de::{Deserialize, Deserializer, Error, IntoDeserializer, Visitor}; use crate::de::{
Deserialize, DeserializeSeed, Deserializer, EnumAccess, Error, IntoDeserializer, VariantAccess,
Visitor,
};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use de::{DeserializeSeed, MapAccess, Unexpected}; use crate::de::{MapAccess, Unexpected};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub use self::content::{ pub use self::content::{
@@ -13,7 +16,7 @@ pub use self::content::{
TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor, TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor,
}; };
pub use seed::InPlaceSeed; pub use crate::seed::InPlaceSeed;
/// If the missing field is of type `Option<T>` then treat is as `None`, /// If the missing field is of type `Option<T>` then treat is as `None`,
/// otherwise it is an error. /// otherwise it is an error.
@@ -203,14 +206,13 @@ mod content {
// This issue is tracking making some of this stuff public: // This issue is tracking making some of this stuff public:
// https://github.com/serde-rs/serde/issues/741 // https://github.com/serde-rs/serde/issues/741
use lib::*; use crate::lib::*;
use __private::size_hint; use crate::actually_private;
use actually_private; use crate::de::value::{MapDeserializer, SeqDeserializer};
use de::value::{MapDeserializer, SeqDeserializer}; use crate::de::{
use de::{ self, size_hint, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected,
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny, IgnoredAny, MapAccess, SeqAccess, Unexpected, Visitor,
MapAccess, SeqAccess, Unexpected, Visitor,
}; };
/// Used from generated code to buffer the contents of the Deserializer when /// Used from generated code to buffer the contents of the Deserializer when
@@ -488,7 +490,7 @@ mod content {
{ {
let mut vec = let mut vec =
Vec::<Content>::with_capacity(size_hint::cautious::<Content>(visitor.size_hint())); Vec::<Content>::with_capacity(size_hint::cautious::<Content>(visitor.size_hint()));
while let Some(e) = try!(visitor.next_element()) { while let Some(e) = tri!(visitor.next_element()) {
vec.push(e); vec.push(e);
} }
Ok(Content::Seq(vec)) Ok(Content::Seq(vec))
@@ -502,7 +504,7 @@ mod content {
Vec::<(Content, Content)>::with_capacity( Vec::<(Content, Content)>::with_capacity(
size_hint::cautious::<(Content, Content)>(visitor.size_hint()), size_hint::cautious::<(Content, Content)>(visitor.size_hint()),
); );
while let Some(kv) = try!(visitor.next_entry()) { while let Some(kv) = tri!(visitor.next_entry()) {
vec.push(kv); vec.push(kv);
} }
Ok(Content::Map(vec)) Ok(Content::Map(vec))
@@ -845,14 +847,14 @@ mod content {
where where
S: SeqAccess<'de>, S: SeqAccess<'de>,
{ {
let tag = match try!(seq.next_element()) { let tag = match tri!(seq.next_element()) {
Some(tag) => tag, Some(tag) => tag,
None => { None => {
return Err(de::Error::missing_field(self.tag_name)); return Err(de::Error::missing_field(self.tag_name));
} }
}; };
let rest = de::value::SeqAccessDeserializer::new(seq); let rest = de::value::SeqAccessDeserializer::new(seq);
Ok((tag, try!(Content::deserialize(rest)))) Ok((tag, tri!(Content::deserialize(rest))))
} }
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error> fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
@@ -864,16 +866,16 @@ mod content {
Content, Content,
Content, Content,
)>(map.size_hint())); )>(map.size_hint()));
while let Some(k) = try!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) { while let Some(k) = tri!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
match k { match k {
TagOrContent::Tag => { TagOrContent::Tag => {
if tag.is_some() { if tag.is_some() {
return Err(de::Error::duplicate_field(self.tag_name)); return Err(de::Error::duplicate_field(self.tag_name));
} }
tag = Some(try!(map.next_value())); tag = Some(tri!(map.next_value()));
} }
TagOrContent::Content(k) => { TagOrContent::Content(k) => {
let v = try!(map.next_value()); let v = tri!(map.next_value());
vec.push((k, v)); vec.push((k, v));
} }
} }
@@ -1087,8 +1089,8 @@ mod content {
{ {
let seq = content.into_iter().map(ContentDeserializer::new); let seq = content.into_iter().map(ContentDeserializer::new);
let mut seq_visitor = SeqDeserializer::new(seq); let mut seq_visitor = SeqDeserializer::new(seq);
let value = try!(visitor.visit_seq(&mut seq_visitor)); let value = tri!(visitor.visit_seq(&mut seq_visitor));
try!(seq_visitor.end()); tri!(seq_visitor.end());
Ok(value) Ok(value)
} }
@@ -1104,8 +1106,8 @@ mod content {
.into_iter() .into_iter()
.map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v))); .map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
let mut map_visitor = MapDeserializer::new(map); let mut map_visitor = MapDeserializer::new(map);
let value = try!(visitor.visit_map(&mut map_visitor)); let value = tri!(visitor.visit_map(&mut map_visitor));
try!(map_visitor.end()); tri!(map_visitor.end());
Ok(value) Ok(value)
} }
@@ -1683,8 +1685,8 @@ mod content {
{ {
let seq = content.iter().map(ContentRefDeserializer::new); let seq = content.iter().map(ContentRefDeserializer::new);
let mut seq_visitor = SeqDeserializer::new(seq); let mut seq_visitor = SeqDeserializer::new(seq);
let value = try!(visitor.visit_seq(&mut seq_visitor)); let value = tri!(visitor.visit_seq(&mut seq_visitor));
try!(seq_visitor.end()); tri!(seq_visitor.end());
Ok(value) Ok(value)
} }
@@ -1703,8 +1705,8 @@ mod content {
) )
}); });
let mut map_visitor = MapDeserializer::new(map); let mut map_visitor = MapDeserializer::new(map);
let value = try!(visitor.visit_map(&mut map_visitor)); let value = tri!(visitor.visit_map(&mut map_visitor));
try!(map_visitor.end()); tri!(map_visitor.end());
Ok(value) Ok(value)
} }
@@ -2224,7 +2226,7 @@ mod content {
if len == 0 { if len == 0 {
visitor.visit_unit() visitor.visit_unit()
} else { } else {
let ret = try!(visitor.visit_seq(&mut self)); let ret = tri!(visitor.visit_seq(&mut self));
let remaining = self.iter.len(); let remaining = self.iter.len();
if remaining == 0 { if remaining == 0 {
Ok(ret) Ok(ret)
@@ -2403,7 +2405,7 @@ mod content {
where where
M: MapAccess<'de>, M: MapAccess<'de>,
{ {
while try!(access.next_entry::<IgnoredAny, IgnoredAny>()).is_some() {} while tri!(access.next_entry::<IgnoredAny, IgnoredAny>()).is_some() {}
Ok(()) Ok(())
} }
} }
@@ -2836,3 +2838,55 @@ fn flat_map_take_entry<'de>(
None None
} }
} }
pub struct AdjacentlyTaggedEnumVariantSeed<F> {
pub enum_name: &'static str,
pub variants: &'static [&'static str],
pub fields_enum: PhantomData<F>,
}
pub struct AdjacentlyTaggedEnumVariantVisitor<F> {
enum_name: &'static str,
fields_enum: PhantomData<F>,
}
impl<'de, F> Visitor<'de> for AdjacentlyTaggedEnumVariantVisitor<F>
where
F: Deserialize<'de>,
{
type Value = F;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "variant of enum {}", self.enum_name)
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: EnumAccess<'de>,
{
let (variant, variant_access) = tri!(data.variant());
tri!(variant_access.unit_variant());
Ok(variant)
}
}
impl<'de, F> DeserializeSeed<'de> for AdjacentlyTaggedEnumVariantSeed<F>
where
F: Deserialize<'de>,
{
type Value = F;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_enum(
self.enum_name,
self.variants,
AdjacentlyTaggedEnumVariantVisitor {
enum_name: self.enum_name,
fields_enum: PhantomData,
},
)
}
}
+2 -2
View File
@@ -1,8 +1,8 @@
// Used only by Serde doc tests. Not public API. // Used only by Serde doc tests. Not public API.
use lib::*; use crate::lib::*;
use ser; use crate::ser;
#[doc(hidden)] #[doc(hidden)]
#[derive(Debug)] #[derive(Debug)]
+11 -13
View File
@@ -3,30 +3,28 @@ pub mod de;
#[cfg(not(no_serde_derive))] #[cfg(not(no_serde_derive))]
pub mod ser; pub mod ser;
pub mod size_hint;
// FIXME: #[cfg(doctest)] once https://github.com/rust-lang/rust/issues/67295 is fixed. // FIXME: #[cfg(doctest)] once https://github.com/rust-lang/rust/issues/67295 is fixed.
pub mod doc; pub mod doc;
pub use lib::clone::Clone; pub use crate::lib::clone::Clone;
pub use lib::convert::{From, Into}; pub use crate::lib::convert::{From, Into};
pub use lib::default::Default; pub use crate::lib::default::Default;
pub use lib::fmt::{self, Formatter}; pub use crate::lib::fmt::{self, Formatter};
pub use lib::marker::PhantomData; pub use crate::lib::marker::PhantomData;
pub use lib::option::Option::{self, None, Some}; pub use crate::lib::option::Option::{self, None, Some};
pub use lib::ptr; pub use crate::lib::ptr;
pub use lib::result::Result::{self, Err, Ok}; pub use crate::lib::result::Result::{self, Err, Ok};
pub use self::string::from_utf8_lossy; pub use self::string::from_utf8_lossy;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
pub use lib::{ToString, Vec}; pub use crate::lib::{ToString, Vec};
#[cfg(not(no_core_try_from))] #[cfg(not(no_core_try_from))]
pub use lib::convert::TryFrom; pub use crate::lib::convert::TryFrom;
mod string { mod string {
use lib::*; use crate::lib::*;
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> { pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
+81 -66
View File
@@ -1,6 +1,6 @@
use lib::*; use crate::lib::*;
use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer}; use crate::ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
use self::content::{ use self::content::{
@@ -182,14 +182,14 @@ where
} }
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> { fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
let mut map = try!(self.delegate.serialize_map(Some(1))); let mut map = tri!(self.delegate.serialize_map(Some(1)));
try!(map.serialize_entry(self.tag, self.variant_name)); tri!(map.serialize_entry(self.tag, self.variant_name));
map.end() map.end()
} }
fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> { fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
let mut map = try!(self.delegate.serialize_map(Some(1))); let mut map = tri!(self.delegate.serialize_map(Some(1)));
try!(map.serialize_entry(self.tag, self.variant_name)); tri!(map.serialize_entry(self.tag, self.variant_name));
map.end() map.end()
} }
@@ -199,9 +199,9 @@ where
_: u32, _: u32,
inner_variant: &'static str, inner_variant: &'static str,
) -> Result<Self::Ok, Self::Error> { ) -> Result<Self::Ok, Self::Error> {
let mut map = try!(self.delegate.serialize_map(Some(2))); let mut map = tri!(self.delegate.serialize_map(Some(2)));
try!(map.serialize_entry(self.tag, self.variant_name)); tri!(map.serialize_entry(self.tag, self.variant_name));
try!(map.serialize_entry(inner_variant, &())); tri!(map.serialize_entry(inner_variant, &()));
map.end() map.end()
} }
@@ -226,9 +226,9 @@ where
where where
T: Serialize, T: Serialize,
{ {
let mut map = try!(self.delegate.serialize_map(Some(2))); let mut map = tri!(self.delegate.serialize_map(Some(2)));
try!(map.serialize_entry(self.tag, self.variant_name)); tri!(map.serialize_entry(self.tag, self.variant_name));
try!(map.serialize_entry(inner_variant, inner_value)); tri!(map.serialize_entry(inner_variant, inner_value));
map.end() map.end()
} }
@@ -269,9 +269,9 @@ where
inner_variant: &'static str, inner_variant: &'static str,
len: usize, len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> { ) -> Result<Self::SerializeTupleVariant, Self::Error> {
let mut map = try!(self.delegate.serialize_map(Some(2))); let mut map = tri!(self.delegate.serialize_map(Some(2)));
try!(map.serialize_entry(self.tag, self.variant_name)); tri!(map.serialize_entry(self.tag, self.variant_name));
try!(map.serialize_key(inner_variant)); tri!(map.serialize_key(inner_variant));
Ok(SerializeTupleVariantAsMapValue::new( Ok(SerializeTupleVariantAsMapValue::new(
map, map,
inner_variant, inner_variant,
@@ -280,8 +280,8 @@ where
} }
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> { 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))); let mut map = tri!(self.delegate.serialize_map(len.map(|len| len + 1)));
try!(map.serialize_entry(self.tag, self.variant_name)); tri!(map.serialize_entry(self.tag, self.variant_name));
Ok(map) Ok(map)
} }
@@ -290,8 +290,8 @@ where
name: &'static str, name: &'static str,
len: usize, len: usize,
) -> Result<Self::SerializeStruct, Self::Error> { ) -> Result<Self::SerializeStruct, Self::Error> {
let mut state = try!(self.delegate.serialize_struct(name, len + 1)); let mut state = tri!(self.delegate.serialize_struct(name, len + 1));
try!(state.serialize_field(self.tag, self.variant_name)); tri!(state.serialize_field(self.tag, self.variant_name));
Ok(state) Ok(state)
} }
@@ -316,9 +316,9 @@ where
inner_variant: &'static str, inner_variant: &'static str,
len: usize, len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> { ) -> Result<Self::SerializeStructVariant, Self::Error> {
let mut map = try!(self.delegate.serialize_map(Some(2))); let mut map = tri!(self.delegate.serialize_map(Some(2)));
try!(map.serialize_entry(self.tag, self.variant_name)); tri!(map.serialize_entry(self.tag, self.variant_name));
try!(map.serialize_key(inner_variant)); tri!(map.serialize_key(inner_variant));
Ok(SerializeStructVariantAsMapValue::new( Ok(SerializeStructVariantAsMapValue::new(
map, map,
inner_variant, inner_variant,
@@ -337,9 +337,9 @@ where
#[cfg(any(feature = "std", feature = "alloc"))] #[cfg(any(feature = "std", feature = "alloc"))]
mod content { mod content {
use lib::*; use crate::lib::*;
use ser::{self, Serialize, Serializer}; use crate::ser::{self, Serialize, Serializer};
pub struct SerializeTupleVariantAsMapValue<M> { pub struct SerializeTupleVariantAsMapValue<M> {
map: M, map: M,
@@ -368,13 +368,13 @@ mod content {
where where
T: Serialize, T: Serialize,
{ {
let value = try!(value.serialize(ContentSerializer::<M::Error>::new())); let value = tri!(value.serialize(ContentSerializer::<M::Error>::new()));
self.fields.push(value); self.fields.push(value);
Ok(()) Ok(())
} }
fn end(mut self) -> Result<M::Ok, M::Error> { fn end(mut self) -> Result<M::Ok, M::Error> {
try!(self tri!(self
.map .map
.serialize_value(&Content::TupleStruct(self.name, self.fields))); .serialize_value(&Content::TupleStruct(self.name, self.fields)));
self.map.end() self.map.end()
@@ -412,13 +412,13 @@ mod content {
where where
T: Serialize, T: Serialize,
{ {
let value = try!(value.serialize(ContentSerializer::<M::Error>::new())); let value = tri!(value.serialize(ContentSerializer::<M::Error>::new()));
self.fields.push((key, value)); self.fields.push((key, value));
Ok(()) Ok(())
} }
fn end(mut self) -> Result<M::Ok, M::Error> { fn end(mut self) -> Result<M::Ok, M::Error> {
try!(self tri!(self
.map .map
.serialize_value(&Content::Struct(self.name, self.fields))); .serialize_value(&Content::Struct(self.name, self.fields)));
self.map.end() self.map.end()
@@ -499,50 +499,50 @@ mod content {
} }
Content::Seq(ref elements) => elements.serialize(serializer), Content::Seq(ref elements) => elements.serialize(serializer),
Content::Tuple(ref elements) => { Content::Tuple(ref elements) => {
use ser::SerializeTuple; use crate::ser::SerializeTuple;
let mut tuple = try!(serializer.serialize_tuple(elements.len())); let mut tuple = tri!(serializer.serialize_tuple(elements.len()));
for e in elements { for e in elements {
try!(tuple.serialize_element(e)); tri!(tuple.serialize_element(e));
} }
tuple.end() tuple.end()
} }
Content::TupleStruct(n, ref fields) => { Content::TupleStruct(n, ref fields) => {
use ser::SerializeTupleStruct; use crate::ser::SerializeTupleStruct;
let mut ts = try!(serializer.serialize_tuple_struct(n, fields.len())); let mut ts = tri!(serializer.serialize_tuple_struct(n, fields.len()));
for f in fields { for f in fields {
try!(ts.serialize_field(f)); tri!(ts.serialize_field(f));
} }
ts.end() ts.end()
} }
Content::TupleVariant(n, i, v, ref fields) => { Content::TupleVariant(n, i, v, ref fields) => {
use ser::SerializeTupleVariant; use crate::ser::SerializeTupleVariant;
let mut tv = try!(serializer.serialize_tuple_variant(n, i, v, fields.len())); let mut tv = tri!(serializer.serialize_tuple_variant(n, i, v, fields.len()));
for f in fields { for f in fields {
try!(tv.serialize_field(f)); tri!(tv.serialize_field(f));
} }
tv.end() tv.end()
} }
Content::Map(ref entries) => { Content::Map(ref entries) => {
use ser::SerializeMap; use crate::ser::SerializeMap;
let mut map = try!(serializer.serialize_map(Some(entries.len()))); let mut map = tri!(serializer.serialize_map(Some(entries.len())));
for (k, v) in entries { for (k, v) in entries {
try!(map.serialize_entry(k, v)); tri!(map.serialize_entry(k, v));
} }
map.end() map.end()
} }
Content::Struct(n, ref fields) => { Content::Struct(n, ref fields) => {
use ser::SerializeStruct; use crate::ser::SerializeStruct;
let mut s = try!(serializer.serialize_struct(n, fields.len())); let mut s = tri!(serializer.serialize_struct(n, fields.len()));
for &(k, ref v) in fields { for &(k, ref v) in fields {
try!(s.serialize_field(k, v)); tri!(s.serialize_field(k, v));
} }
s.end() s.end()
} }
Content::StructVariant(n, i, v, ref fields) => { Content::StructVariant(n, i, v, ref fields) => {
use ser::SerializeStructVariant; use crate::ser::SerializeStructVariant;
let mut sv = try!(serializer.serialize_struct_variant(n, i, v, fields.len())); let mut sv = tri!(serializer.serialize_struct_variant(n, i, v, fields.len()));
for &(k, ref v) in fields { for &(k, ref v) in fields {
try!(sv.serialize_field(k, v)); tri!(sv.serialize_field(k, v));
} }
sv.end() sv.end()
} }
@@ -639,7 +639,7 @@ mod content {
where where
T: Serialize, T: Serialize,
{ {
Ok(Content::Some(Box::new(try!(value.serialize(self))))) Ok(Content::Some(Box::new(tri!(value.serialize(self)))))
} }
fn serialize_unit(self) -> Result<Content, E> { fn serialize_unit(self) -> Result<Content, E> {
@@ -669,7 +669,7 @@ mod content {
{ {
Ok(Content::NewtypeStruct( Ok(Content::NewtypeStruct(
name, name,
Box::new(try!(value.serialize(self))), Box::new(tri!(value.serialize(self))),
)) ))
} }
@@ -687,7 +687,7 @@ mod content {
name, name,
variant_index, variant_index,
variant, variant,
Box::new(try!(value.serialize(self))), Box::new(tri!(value.serialize(self))),
)) ))
} }
@@ -786,7 +786,7 @@ mod content {
where where
T: Serialize, T: Serialize,
{ {
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = tri!(value.serialize(ContentSerializer::<E>::new()));
self.elements.push(value); self.elements.push(value);
Ok(()) Ok(())
} }
@@ -812,7 +812,7 @@ mod content {
where where
T: Serialize, T: Serialize,
{ {
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = tri!(value.serialize(ContentSerializer::<E>::new()));
self.elements.push(value); self.elements.push(value);
Ok(()) Ok(())
} }
@@ -839,7 +839,7 @@ mod content {
where where
T: Serialize, T: Serialize,
{ {
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = tri!(value.serialize(ContentSerializer::<E>::new()));
self.fields.push(value); self.fields.push(value);
Ok(()) Ok(())
} }
@@ -868,7 +868,7 @@ mod content {
where where
T: Serialize, T: Serialize,
{ {
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = tri!(value.serialize(ContentSerializer::<E>::new()));
self.fields.push(value); self.fields.push(value);
Ok(()) Ok(())
} }
@@ -900,7 +900,7 @@ mod content {
where where
T: Serialize, T: Serialize,
{ {
let key = try!(key.serialize(ContentSerializer::<E>::new())); let key = tri!(key.serialize(ContentSerializer::<E>::new()));
self.key = Some(key); self.key = Some(key);
Ok(()) Ok(())
} }
@@ -913,7 +913,7 @@ mod content {
.key .key
.take() .take()
.expect("serialize_value called before serialize_key"); .expect("serialize_value called before serialize_key");
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = tri!(value.serialize(ContentSerializer::<E>::new()));
self.entries.push((key, value)); self.entries.push((key, value));
Ok(()) Ok(())
} }
@@ -927,8 +927,8 @@ mod content {
K: Serialize, K: Serialize,
V: Serialize, V: Serialize,
{ {
let key = try!(key.serialize(ContentSerializer::<E>::new())); let key = tri!(key.serialize(ContentSerializer::<E>::new()));
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = tri!(value.serialize(ContentSerializer::<E>::new()));
self.entries.push((key, value)); self.entries.push((key, value));
Ok(()) Ok(())
} }
@@ -951,7 +951,7 @@ mod content {
where where
T: Serialize, T: Serialize,
{ {
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = tri!(value.serialize(ContentSerializer::<E>::new()));
self.fields.push((key, value)); self.fields.push((key, value));
Ok(()) Ok(())
} }
@@ -980,7 +980,7 @@ mod content {
where where
T: Serialize, T: Serialize,
{ {
let value = try!(value.serialize(ContentSerializer::<E>::new())); let value = tri!(value.serialize(ContentSerializer::<E>::new()));
self.fields.push((key, value)); self.fields.push((key, value));
Ok(()) Ok(())
} }
@@ -1133,7 +1133,7 @@ where
where where
T: Serialize, T: Serialize,
{ {
try!(self.0.serialize_key(variant)); tri!(self.0.serialize_key(variant));
self.0.serialize_value(value) self.0.serialize_value(value)
} }
@@ -1160,7 +1160,7 @@ where
variant: &'static str, variant: &'static str,
_: usize, _: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> { ) -> Result<Self::SerializeTupleVariant, Self::Error> {
try!(self.0.serialize_key(variant)); tri!(self.0.serialize_key(variant));
Ok(FlatMapSerializeTupleVariantAsMapValue::new(self.0)) Ok(FlatMapSerializeTupleVariantAsMapValue::new(self.0))
} }
@@ -1183,7 +1183,7 @@ where
inner_variant: &'static str, inner_variant: &'static str,
_: usize, _: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> { ) -> Result<Self::SerializeStructVariant, Self::Error> {
try!(self.0.serialize_key(inner_variant)); tri!(self.0.serialize_key(inner_variant));
Ok(FlatMapSerializeStructVariantAsMapValue::new( Ok(FlatMapSerializeStructVariantAsMapValue::new(
self.0, self.0,
inner_variant, inner_variant,
@@ -1293,13 +1293,13 @@ where
where where
T: Serialize, T: Serialize,
{ {
let value = try!(value.serialize(ContentSerializer::<M::Error>::new())); let value = tri!(value.serialize(ContentSerializer::<M::Error>::new()));
self.fields.push(value); self.fields.push(value);
Ok(()) Ok(())
} }
fn end(self) -> Result<(), Self::Error> { fn end(self) -> Result<(), Self::Error> {
try!(self.map.serialize_value(&Content::Seq(self.fields))); tri!(self.map.serialize_value(&Content::Seq(self.fields)));
Ok(()) Ok(())
} }
} }
@@ -1343,15 +1343,30 @@ where
where where
T: Serialize, T: Serialize,
{ {
let value = try!(value.serialize(ContentSerializer::<M::Error>::new())); let value = tri!(value.serialize(ContentSerializer::<M::Error>::new()));
self.fields.push((key, value)); self.fields.push((key, value));
Ok(()) Ok(())
} }
fn end(self) -> Result<(), Self::Error> { fn end(self) -> Result<(), Self::Error> {
try!(self tri!(self
.map .map
.serialize_value(&Content::Struct(self.name, self.fields))); .serialize_value(&Content::Struct(self.name, self.fields)));
Ok(()) Ok(())
} }
} }
pub struct AdjacentlyTaggedEnumVariant {
pub enum_name: &'static str,
pub variant_index: u32,
pub variant_name: &'static str,
}
impl Serialize for AdjacentlyTaggedEnumVariant {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_unit_variant(self.enum_name, self.variant_index, self.variant_name)
}
}
+2 -2
View File
@@ -1,5 +1,5 @@
use lib::*; use crate::lib::*;
use ser::{Error, Impossible, Serialize, Serializer}; use crate::ser::{Error, Impossible, Serialize, Serializer};
impl Error for fmt::Error { impl Error for fmt::Error {
fn custom<T: Display>(_msg: T) -> Self { fn custom<T: Display>(_msg: T) -> Self {
+23 -28
View File
@@ -1,6 +1,6 @@
use lib::*; use crate::lib::*;
use ser::{Error, Serialize, SerializeTuple, Serializer}; use crate::ser::{Error, Serialize, SerializeTuple, Serializer};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -133,7 +133,7 @@ impl<T> Serialize for [T; 0] {
where where
S: Serializer, S: Serializer,
{ {
try!(serializer.serialize_tuple(0)).end() tri!(serializer.serialize_tuple(0)).end()
} }
} }
@@ -149,9 +149,9 @@ macro_rules! array_impls {
where where
S: Serializer, S: Serializer,
{ {
let mut seq = try!(serializer.serialize_tuple($len)); let mut seq = tri!(serializer.serialize_tuple($len));
for e in self { for e in self {
try!(seq.serialize_element(e)); tri!(seq.serialize_element(e));
} }
seq.end() seq.end()
} }
@@ -248,9 +248,9 @@ where
S: Serializer, S: Serializer,
{ {
use super::SerializeStruct; use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("Range", 2)); let mut state = tri!(serializer.serialize_struct("Range", 2));
try!(state.serialize_field("start", &self.start)); tri!(state.serialize_field("start", &self.start));
try!(state.serialize_field("end", &self.end)); tri!(state.serialize_field("end", &self.end));
state.end() state.end()
} }
} }
@@ -266,15 +266,14 @@ where
S: Serializer, S: Serializer,
{ {
use super::SerializeStruct; use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("RangeFrom", 1)); let mut state = tri!(serializer.serialize_struct("RangeFrom", 1));
try!(state.serialize_field("start", &self.start)); tri!(state.serialize_field("start", &self.start));
state.end() state.end()
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(not(no_range_inclusive))]
impl<Idx> Serialize for RangeInclusive<Idx> impl<Idx> Serialize for RangeInclusive<Idx>
where where
Idx: Serialize, Idx: Serialize,
@@ -284,9 +283,9 @@ where
S: Serializer, S: Serializer,
{ {
use super::SerializeStruct; use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("RangeInclusive", 2)); let mut state = tri!(serializer.serialize_struct("RangeInclusive", 2));
try!(state.serialize_field("start", &self.start())); tri!(state.serialize_field("start", &self.start()));
try!(state.serialize_field("end", &self.end())); tri!(state.serialize_field("end", &self.end()));
state.end() state.end()
} }
} }
@@ -302,15 +301,14 @@ where
S: Serializer, S: Serializer,
{ {
use super::SerializeStruct; use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("RangeTo", 1)); let mut state = tri!(serializer.serialize_struct("RangeTo", 1));
try!(state.serialize_field("end", &self.end)); tri!(state.serialize_field("end", &self.end));
state.end() state.end()
} }
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
impl<T> Serialize for Bound<T> impl<T> Serialize for Bound<T>
where where
T: Serialize, T: Serialize,
@@ -367,9 +365,9 @@ macro_rules! tuple_impls {
where where
S: Serializer, S: Serializer,
{ {
let mut tuple = try!(serializer.serialize_tuple($len)); let mut tuple = tri!(serializer.serialize_tuple($len));
$( $(
try!(tuple.serialize_element(&self.$n)); tri!(tuple.serialize_element(&self.$n));
)+ )+
tuple.end() tuple.end()
} }
@@ -538,7 +536,6 @@ where
macro_rules! nonzero_integers { macro_rules! nonzero_integers {
($($T:ident,)+) => { ($($T:ident,)+) => {
$( $(
#[cfg(not(no_num_nonzero))]
impl Serialize for num::$T { impl Serialize for num::$T {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
@@ -662,16 +659,15 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", not(no_core_duration)))]
impl Serialize for Duration { impl Serialize for Duration {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where where
S: Serializer, S: Serializer,
{ {
use super::SerializeStruct; use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("Duration", 2)); let mut state = tri!(serializer.serialize_struct("Duration", 2));
try!(state.serialize_field("secs", &self.as_secs())); tri!(state.serialize_field("secs", &self.as_secs()));
try!(state.serialize_field("nanos", &self.subsec_nanos())); tri!(state.serialize_field("nanos", &self.subsec_nanos()));
state.end() state.end()
} }
} }
@@ -689,9 +685,9 @@ impl Serialize for SystemTime {
Ok(duration_since_epoch) => duration_since_epoch, Ok(duration_since_epoch) => duration_since_epoch,
Err(_) => return Err(S::Error::custom("SystemTime must be later than UNIX_EPOCH")), Err(_) => return Err(S::Error::custom("SystemTime must be later than UNIX_EPOCH")),
}; };
let mut state = try!(serializer.serialize_struct("SystemTime", 2)); let mut state = tri!(serializer.serialize_struct("SystemTime", 2));
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs())); tri!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos())); tri!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
state.end() state.end()
} }
} }
@@ -963,7 +959,6 @@ where
} }
} }
#[cfg(not(no_core_reverse))]
impl<T> Serialize for Reverse<T> impl<T> Serialize for Reverse<T>
where where
T: Serialize, T: Serialize,
+2 -2
View File
@@ -1,8 +1,8 @@
//! This module contains `Impossible` serializer and its implementations. //! This module contains `Impossible` serializer and its implementations.
use lib::*; use crate::lib::*;
use ser::{ use crate::ser::{
self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant, self, Serialize, SerializeMap, SerializeSeq, SerializeStruct, SerializeStructVariant,
SerializeTuple, SerializeTupleStruct, SerializeTupleVariant, SerializeTuple, SerializeTupleStruct, SerializeTupleVariant,
}; };
+11 -37
View File
@@ -107,7 +107,7 @@
//! [derive section of the manual]: https://serde.rs/derive.html //! [derive section of the manual]: https://serde.rs/derive.html
//! [data formats]: https://serde.rs/#data-formats //! [data formats]: https://serde.rs/#data-formats
use lib::*; use crate::lib::*;
mod fmt; mod fmt;
mod impls; mod impls;
@@ -115,15 +115,15 @@ mod impossible;
pub use self::impossible::Impossible; pub use self::impossible::Impossible;
#[cfg(not(any(feature = "std", feature = "unstable")))]
#[doc(no_inline)]
pub use crate::std_error::Error as StdError;
#[cfg(all(feature = "unstable", not(feature = "std")))] #[cfg(all(feature = "unstable", not(feature = "std")))]
#[doc(no_inline)] #[doc(no_inline)]
pub use core::error::Error as StdError; pub use core::error::Error as StdError;
#[cfg(feature = "std")] #[cfg(feature = "std")]
#[doc(no_inline)] #[doc(no_inline)]
pub use std::error::Error as StdError; pub use std::error::Error as StdError;
#[cfg(not(any(feature = "std", feature = "unstable")))]
#[doc(no_inline)]
pub use std_error::Error as StdError;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -1279,22 +1279,9 @@ pub trait Serializer: Sized {
I: IntoIterator, I: IntoIterator,
<I as IntoIterator>::Item: Serialize, <I as IntoIterator>::Item: Serialize,
{ {
let iter = iter.into_iter(); let mut iter = iter.into_iter();
let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter))); let mut serializer = tri!(self.serialize_seq(iterator_len_hint(&iter)));
tri!(iter.try_for_each(|item| serializer.serialize_element(&item)));
#[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() serializer.end()
} }
@@ -1330,22 +1317,9 @@ pub trait Serializer: Sized {
V: Serialize, V: Serialize,
I: IntoIterator<Item = (K, V)>, I: IntoIterator<Item = (K, V)>,
{ {
let iter = iter.into_iter(); let mut iter = iter.into_iter();
let mut serializer = try!(self.serialize_map(iterator_len_hint(&iter))); let mut serializer = tri!(self.serialize_map(iterator_len_hint(&iter)));
tri!(iter.try_for_each(|(key, value)| serializer.serialize_entry(&key, &value)));
#[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() serializer.end()
} }
@@ -1839,7 +1813,7 @@ pub trait SerializeMap {
K: Serialize, K: Serialize,
V: Serialize, V: Serialize,
{ {
try!(self.serialize_key(key)); tri!(self.serialize_key(key));
self.serialize_value(value) self.serialize_value(value)
} }
+1 -1
View File
@@ -1,4 +1,4 @@
use lib::{Debug, Display}; use crate::lib::{Debug, Display};
/// Either a re-export of std::error::Error or a new identical trait, depending /// Either a re-export of std::error::Error or a new identical trait, depending
/// on whether Serde's "std" feature is enabled. /// on whether Serde's "std" feature is enabled.
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.179" # remember to update html_root_url version = "1.0.182" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
categories = ["no-std", "no-std::no-alloc"] categories = ["no-std", "no-std::no-alloc"]
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -23,7 +23,7 @@ proc-macro = true
[dependencies] [dependencies]
proc-macro2 = "1.0" proc-macro2 = "1.0"
quote = "1.0" quote = "1.0"
syn = "2.0.25" syn = "2.0.28"
[dev-dependencies] [dev-dependencies]
serde = { version = "1", path = "../serde" } serde = { version = "1", path = "../serde" }
+151 -206
View File
@@ -324,10 +324,10 @@ fn deserialize_in_place_body(cont: &Container, params: &Parameters) -> Option<St
let code = match &cont.data { let code = match &cont.data {
Data::Struct(Style::Struct, fields) => { Data::Struct(Style::Struct, fields) => {
deserialize_struct_in_place(None, params, fields, &cont.attrs, None)? deserialize_struct_in_place(params, fields, &cont.attrs)?
} }
Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => { Data::Struct(Style::Tuple, fields) | Data::Struct(Style::Newtype, fields) => {
deserialize_tuple_in_place(None, params, fields, &cont.attrs, None) deserialize_tuple_in_place(params, fields, &cont.attrs)
} }
Data::Enum(_) | Data::Struct(Style::Unit, _) => { Data::Enum(_) | Data::Struct(Style::Unit, _) => {
return None; return None;
@@ -582,11 +582,9 @@ fn deserialize_tuple(
#[cfg(feature = "deserialize_in_place")] #[cfg(feature = "deserialize_in_place")]
fn deserialize_tuple_in_place( fn deserialize_tuple_in_place(
variant_ident: Option<syn::Ident>,
params: &Parameters, params: &Parameters,
fields: &[Field], fields: &[Field],
cattrs: &attr::Container, cattrs: &attr::Container,
deserializer: Option<TokenStream>,
) -> Fragment { ) -> Fragment {
assert!(!cattrs.has_flatten()); assert!(!cattrs.has_flatten());
@@ -600,17 +598,25 @@ fn deserialize_tuple_in_place(
split_with_de_lifetime(params); split_with_de_lifetime(params);
let delife = params.borrowed.de_lifetime(); let delife = params.borrowed.de_lifetime();
let is_enum = variant_ident.is_some(); let expecting = format!("tuple struct {}", params.type_name());
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 expecting = cattrs.expecting().unwrap_or(&expecting);
let nfields = fields.len(); let nfields = fields.len();
let visit_newtype_struct = if !is_enum && nfields == 1 { let visit_newtype_struct = if nfields == 1 {
Some(deserialize_newtype_struct_in_place(params, &fields[0])) // We do not generate deserialize_in_place if every field has a
// deserialize_with.
assert!(fields[0].attrs.deserialize_with().is_none());
Some(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)
}
})
} else { } else {
None None
}; };
@@ -624,15 +630,10 @@ fn deserialize_tuple_in_place(
} }
}; };
let dispatch = if let Some(deserializer) = deserializer { let type_name = cattrs.name().deserialize_name();
quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #field_count, #visitor_expr)) let dispatch = if nfields == 1 {
} else if is_enum {
quote!(_serde::de::VariantAccess::tuple_variant(__variant, #field_count, #visitor_expr))
} else if nfields == 1 {
let type_name = cattrs.name().deserialize_name();
quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr)) quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr))
} else { } else {
let type_name = cattrs.name().deserialize_name();
quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #field_count, #visitor_expr)) quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #field_count, #visitor_expr))
}; };
@@ -722,19 +723,11 @@ fn deserialize_seq(
}) })
} }
}; };
let value_if_none = match field.attrs.default() { let value_if_none = expr_is_missing_seq(None, index_in_seq, field, cattrs, expecting);
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 assign = quote! {
let #var = match #visit { let #var = match #visit {
_serde::__private::Some(__value) => __value, _serde::__private::Some(__value) => __value,
_serde::__private::None => { _serde::__private::None => #value_if_none,
#value_if_none
}
}; };
}; };
index_in_seq += 1; index_in_seq += 1;
@@ -810,24 +803,14 @@ fn deserialize_seq_in_place(
self.place.#member = #default; self.place.#member = #default;
} }
} else { } else {
let value_if_none = match field.attrs.default() { let value_if_none = expr_is_missing_seq(Some(quote!(self.place.#member = )), index_in_seq, field, cattrs, expecting);
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() { let write = match field.attrs.deserialize_with() {
None => { None => {
quote! { quote! {
if let _serde::__private::None = _serde::de::SeqAccess::next_element_seed(&mut __seq, if let _serde::__private::None = _serde::de::SeqAccess::next_element_seed(&mut __seq,
_serde::__private::de::InPlaceSeed(&mut self.place.#member))? _serde::__private::de::InPlaceSeed(&mut self.place.#member))?
{ {
#value_if_none #value_if_none;
} }
} }
} }
@@ -840,7 +823,7 @@ fn deserialize_seq_in_place(
self.place.#member = __wrap.value; self.place.#member = __wrap.value;
} }
_serde::__private::None => { _serde::__private::None => {
#value_if_none #value_if_none;
} }
} }
}) })
@@ -918,25 +901,6 @@ fn deserialize_newtype_struct(
} }
} }
#[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 StructForm<'a> { enum StructForm<'a> {
Struct, Struct,
/// Contains a variant name /// Contains a variant name
@@ -1058,7 +1022,7 @@ fn deserialize_struct(
} else { } else {
let field_names = field_names_idents let field_names = field_names_idents
.iter() .iter()
.flat_map(|(_, _, aliases)| aliases); .flat_map(|&(_, _, aliases)| aliases);
Some(quote! { Some(quote! {
#[doc(hidden)] #[doc(hidden)]
@@ -1133,14 +1097,10 @@ fn deserialize_struct(
#[cfg(feature = "deserialize_in_place")] #[cfg(feature = "deserialize_in_place")]
fn deserialize_struct_in_place( fn deserialize_struct_in_place(
variant_ident: Option<syn::Ident>,
params: &Parameters, params: &Parameters,
fields: &[Field], fields: &[Field],
cattrs: &attr::Container, cattrs: &attr::Container,
deserializer: Option<TokenStream>,
) -> Option<Fragment> { ) -> Option<Fragment> {
let is_enum = variant_ident.is_some();
// for now we do not support in_place deserialization for structs that // for now we do not support in_place deserialization for structs that
// are represented as map. // are represented as map.
if cattrs.has_flatten() { if cattrs.has_flatten() {
@@ -1152,58 +1112,40 @@ fn deserialize_struct_in_place(
split_with_de_lifetime(params); split_with_de_lifetime(params);
let delife = params.borrowed.de_lifetime(); let delife = params.borrowed.de_lifetime();
let expecting = match variant_ident { let expecting = format!("struct {}", params.type_name());
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 expecting = cattrs.expecting().unwrap_or(&expecting);
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting)); 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 (field_visitor, fields_stmt, visit_map) = let field_visitor = Stmts(deserialize_generated_identifier(
deserialize_struct_as_struct_in_place_visitor(params, fields, cattrs); &field_names_idents,
cattrs,
false,
None,
));
let field_visitor = Stmts(field_visitor); let mut_seq = if field_names_idents.is_empty() {
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!(_) quote!(_)
} else { } else {
quote!(mut __seq) quote!(mut __seq)
}; };
let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, expecting));
let visit_seq = quote! { let visit_map = Stmts(deserialize_map_in_place(params, fields, cattrs));
#[inline] let field_names = field_names_idents
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::__private::Result<Self::Value, __A::Error> .iter()
where .flat_map(|&(_, _, aliases)| aliases);
__A: _serde::de::SeqAccess<#delife>, let type_name = cattrs.name().deserialize_name();
{
#visit_seq
}
};
let in_place_impl_generics = de_impl_generics.in_place(); let in_place_impl_generics = de_impl_generics.in_place();
let in_place_ty_generics = de_ty_generics.in_place(); let in_place_ty_generics = de_ty_generics.in_place();
@@ -1225,7 +1167,13 @@ fn deserialize_struct_in_place(
_serde::__private::Formatter::write_str(__formatter, #expecting) _serde::__private::Formatter::write_str(__formatter, #expecting)
} }
#visit_seq #[inline]
fn visit_seq<__A>(self, #mut_seq: __A) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<#delife>,
{
#visit_seq
}
#[inline] #[inline]
fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error> fn visit_map<__A>(self, mut __map: __A) -> _serde::__private::Result<Self::Value, __A::Error>
@@ -1236,9 +1184,13 @@ fn deserialize_struct_in_place(
} }
} }
#fields_stmt #[doc(hidden)]
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
#dispatch _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, __Visitor {
place: __place,
lifetime: _serde::__private::PhantomData,
})
}) })
} }
@@ -1490,7 +1442,8 @@ fn deserialize_adjacently_tagged_enum(
}) })
.collect(); .collect();
let expecting = format!("adjacently tagged enum {}", params.type_name()); let rust_name = params.type_name();
let expecting = format!("adjacently tagged enum {}", rust_name);
let expecting = cattrs.expecting().unwrap_or(&expecting); let expecting = cattrs.expecting().unwrap_or(&expecting);
let type_name = cattrs.name().deserialize_name(); let type_name = cattrs.name().deserialize_name();
let deny_unknown_fields = cattrs.deny_unknown_fields(); let deny_unknown_fields = cattrs.deny_unknown_fields();
@@ -1510,6 +1463,14 @@ fn deserialize_adjacently_tagged_enum(
} }
}; };
let variant_seed = quote! {
_serde::__private::de::AdjacentlyTaggedEnumVariantSeed::<__Field> {
enum_name: #rust_name,
variants: VARIANTS,
fields_enum: _serde::__private::PhantomData
}
};
let mut missing_content = quote! { let mut missing_content = quote! {
_serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#content)) _serde::__private::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
}; };
@@ -1557,6 +1518,10 @@ fn deserialize_adjacently_tagged_enum(
_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)? _serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content)?
}; };
let variant_from_map = quote! {
_serde::de::MapAccess::next_value_seed(&mut __map, #variant_seed)?
};
// When allowing unknown fields, we want to transparently step through keys // 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. // we don't care about until we find `tag`, `content`, or run out of keys.
let next_relevant_key = if deny_unknown_fields { let next_relevant_key = if deny_unknown_fields {
@@ -1602,11 +1567,11 @@ fn deserialize_adjacently_tagged_enum(
let finish_content_then_tag = if variant_arms.is_empty() { let finish_content_then_tag = if variant_arms.is_empty() {
quote! { quote! {
match _serde::de::MapAccess::next_value::<__Field>(&mut __map)? {} match #variant_from_map {}
} }
} else { } else {
quote! { quote! {
let __ret = match _serde::de::MapAccess::next_value(&mut __map)? { let __ret = match #variant_from_map {
// Deserialize the buffered content now that we know the variant. // Deserialize the buffered content now that we know the variant.
#(#variant_arms)* #(#variant_arms)*
}?; }?;
@@ -1662,7 +1627,7 @@ fn deserialize_adjacently_tagged_enum(
// First key is the tag. // First key is the tag.
_serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => { _serde::__private::Some(_serde::__private::de::TagOrContentField::Tag) => {
// Parse the tag. // Parse the tag.
let __field = _serde::de::MapAccess::next_value(&mut __map)?; let __field = #variant_from_map;
// Visit the second key. // Visit the second key.
match #next_relevant_key { match #next_relevant_key {
// Second key is a duplicate of the tag. // Second key is a duplicate of the tag.
@@ -2018,7 +1983,7 @@ fn deserialize_untagged_newtype_variant(
} }
fn deserialize_generated_identifier( fn deserialize_generated_identifier(
fields: &[(String, Ident, Vec<String>)], fields: &[(&str, Ident, &BTreeSet<String>)],
cattrs: &attr::Container, cattrs: &attr::Container,
is_variant: bool, is_variant: bool,
other_idx: Option<usize>, other_idx: Option<usize>,
@@ -2148,7 +2113,7 @@ fn deserialize_custom_identifier(
}) })
.collect(); .collect();
let names = names_idents.iter().map(|(name, _, _)| name); let names = names_idents.iter().flat_map(|&(_, _, aliases)| aliases);
let names_const = if fallthrough.is_some() { let names_const = if fallthrough.is_some() {
None None
@@ -2204,32 +2169,24 @@ fn deserialize_custom_identifier(
fn deserialize_identifier( fn deserialize_identifier(
this_value: &TokenStream, this_value: &TokenStream,
fields: &[(String, Ident, Vec<String>)], fields: &[(&str, Ident, &BTreeSet<String>)],
is_variant: bool, is_variant: bool,
fallthrough: Option<TokenStream>, fallthrough: Option<TokenStream>,
fallthrough_borrowed: Option<TokenStream>, fallthrough_borrowed: Option<TokenStream>,
collect_other_fields: bool, collect_other_fields: bool,
expecting: Option<&str>, expecting: Option<&str>,
) -> Fragment { ) -> Fragment {
let mut flat_fields = Vec::new(); let str_mapping = fields.iter().map(|(_, ident, aliases)| {
for (_, ident, aliases) in fields { // `aliases` also contains a main name
flat_fields.extend(aliases.iter().map(|alias| (alias, ident))); quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
} });
let bytes_mapping = fields.iter().map(|(_, ident, aliases)| {
let field_strs: &Vec<_> = &flat_fields.iter().map(|(name, _)| name).collect(); // `aliases` also contains a main name
let field_bytes: &Vec<_> = &flat_fields let aliases = aliases
.iter() .iter()
.map(|(name, _)| Literal::byte_string(name.as_bytes())) .map(|alias| Literal::byte_string(alias.as_bytes()));
.collect(); quote!(#(#aliases)|* => _serde::__private::Ok(#this_value::#ident))
});
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 { let expecting = expecting.unwrap_or(if is_variant {
"variant identifier" "variant identifier"
@@ -2237,8 +2194,6 @@ fn deserialize_identifier(
"field identifier" "field identifier"
}); });
let index_expecting = if is_variant { "variant" } else { "field" };
let bytes_to_str = if fallthrough.is_some() || collect_other_fields { let bytes_to_str = if fallthrough.is_some() || collect_other_fields {
None None
} else { } else {
@@ -2286,21 +2241,6 @@ fn deserialize_identifier(
&fallthrough_arm_tokens &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 { let visit_other = if collect_other_fields {
quote! { quote! {
fn visit_bool<__E>(self, __value: bool) -> _serde::__private::Result<Self::Value, __E> fn visit_bool<__E>(self, __value: bool) -> _serde::__private::Result<Self::Value, __E>
@@ -2395,15 +2335,33 @@ fn deserialize_identifier(
} }
} }
} else { } else {
let u64_mapping = fields.iter().enumerate().map(|(i, (_, ident, _))| {
let i = i as u64;
quote!(#i => _serde::__private::Ok(#this_value::#ident))
});
let u64_fallthrough_arm_tokens;
let u64_fallthrough_arm = if let Some(fallthrough) = &fallthrough {
fallthrough
} else {
let index_expecting = if is_variant { "variant" } else { "field" };
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
};
quote! { quote! {
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E> fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
where where
__E: _serde::de::Error, __E: _serde::de::Error,
{ {
match __value { match __value {
#( #(#u64_mapping,)*
#variant_indices => _serde::__private::Ok(#main_constructors),
)*
_ => #u64_fallthrough_arm, _ => #u64_fallthrough_arm,
} }
} }
@@ -2411,6 +2369,8 @@ fn deserialize_identifier(
}; };
let visit_borrowed = if fallthrough_borrowed.is_some() || collect_other_fields { let visit_borrowed = if fallthrough_borrowed.is_some() || collect_other_fields {
let str_mapping = str_mapping.clone();
let bytes_mapping = bytes_mapping.clone();
let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(fallthrough_arm); let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(fallthrough_arm);
Some(quote! { Some(quote! {
fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::__private::Result<Self::Value, __E> fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::__private::Result<Self::Value, __E>
@@ -2418,9 +2378,7 @@ fn deserialize_identifier(
__E: _serde::de::Error, __E: _serde::de::Error,
{ {
match __value { match __value {
#( #(#str_mapping,)*
#field_strs => _serde::__private::Ok(#constructors),
)*
_ => { _ => {
#value_as_borrowed_str_content #value_as_borrowed_str_content
#fallthrough_borrowed_arm #fallthrough_borrowed_arm
@@ -2433,9 +2391,7 @@ fn deserialize_identifier(
__E: _serde::de::Error, __E: _serde::de::Error,
{ {
match __value { match __value {
#( #(#bytes_mapping,)*
#field_bytes => _serde::__private::Ok(#constructors),
)*
_ => { _ => {
#bytes_to_str #bytes_to_str
#value_as_borrowed_bytes_content #value_as_borrowed_bytes_content
@@ -2460,9 +2416,7 @@ fn deserialize_identifier(
__E: _serde::de::Error, __E: _serde::de::Error,
{ {
match __value { match __value {
#( #(#str_mapping,)*
#field_strs => _serde::__private::Ok(#constructors),
)*
_ => { _ => {
#value_as_str_content #value_as_str_content
#fallthrough_arm #fallthrough_arm
@@ -2475,9 +2429,7 @@ fn deserialize_identifier(
__E: _serde::de::Error, __E: _serde::de::Error,
{ {
match __value { match __value {
#( #(#bytes_mapping,)*
#field_bytes => _serde::__private::Ok(#constructors),
)*
_ => { _ => {
#bytes_to_str #bytes_to_str
#value_as_bytes_content #value_as_bytes_content
@@ -2707,42 +2659,6 @@ fn deserialize_map(
} }
} }
#[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! {
#[doc(hidden)]
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")] #[cfg(feature = "deserialize_in_place")]
fn deserialize_map_in_place( fn deserialize_map_in_place(
params: &Parameters, params: &Parameters,
@@ -3046,6 +2962,35 @@ fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
} }
} }
fn expr_is_missing_seq(
assign_to: Option<TokenStream>,
index: usize,
field: &Field,
cattrs: &attr::Container,
expecting: &str,
) -> TokenStream {
match field.attrs.default() {
attr::Default::Default => {
let span = field.original.span();
return quote_spanned!(span=> #assign_to _serde::__private::Default::default());
}
attr::Default::Path(path) => {
return quote_spanned!(path.span()=> #assign_to #path());
}
attr::Default::None => { /* below */ }
}
match *cattrs.default() {
attr::Default::Default | attr::Default::Path(_) => {
let member = &field.member;
quote!(#assign_to __default.#member)
}
attr::Default::None => quote!(
return _serde::__private::Err(_serde::de::Error::invalid_length(#index, &#expecting))
),
}
}
fn effective_style(variant: &Variant) -> Style { fn effective_style(variant: &Variant) -> Style {
match variant.style { match variant.style {
Style::Newtype if variant.fields[0].attrs.skip_deserializing() => Style::Unit, Style::Newtype if variant.fields[0].attrs.skip_deserializing() => Style::Unit,
+31 -34
View File
@@ -134,7 +134,7 @@ pub struct Name {
serialize_renamed: bool, serialize_renamed: bool,
deserialize: String, deserialize: String,
deserialize_renamed: bool, deserialize_renamed: bool,
deserialize_aliases: Vec<String>, deserialize_aliases: BTreeSet<String>,
} }
fn unraw(ident: &Ident) -> String { fn unraw(ident: &Ident) -> String {
@@ -148,16 +148,12 @@ impl Name {
de_name: Attr<String>, de_name: Attr<String>,
de_aliases: Option<VecAttr<String>>, de_aliases: Option<VecAttr<String>>,
) -> Name { ) -> Name {
let deserialize_aliases = match de_aliases { let mut alias_set = BTreeSet::new();
Some(de_aliases) => { if let Some(de_aliases) = de_aliases {
let mut alias_list = BTreeSet::new(); for alias_name in de_aliases.get() {
for alias_name in de_aliases.get() { alias_set.insert(alias_name);
alias_list.insert(alias_name);
}
alias_list.into_iter().collect()
} }
None => Vec::new(), }
};
let ser_name = ser_name.get(); let ser_name = ser_name.get();
let ser_renamed = ser_name.is_some(); let ser_renamed = ser_name.is_some();
@@ -168,27 +164,22 @@ impl Name {
serialize_renamed: ser_renamed, serialize_renamed: ser_renamed,
deserialize: de_name.unwrap_or(source_name), deserialize: de_name.unwrap_or(source_name),
deserialize_renamed: de_renamed, deserialize_renamed: de_renamed,
deserialize_aliases, deserialize_aliases: alias_set,
} }
} }
/// Return the container name for the container when serializing. /// Return the container name for the container when serializing.
pub fn serialize_name(&self) -> String { pub fn serialize_name(&self) -> &str {
self.serialize.clone() &self.serialize
} }
/// Return the container name for the container when deserializing. /// Return the container name for the container when deserializing.
pub fn deserialize_name(&self) -> String { pub fn deserialize_name(&self) -> &str {
self.deserialize.clone() &self.deserialize
} }
fn deserialize_aliases(&self) -> Vec<String> { fn deserialize_aliases(&self) -> &BTreeSet<String> {
let mut aliases = self.deserialize_aliases.clone(); &self.deserialize_aliases
let main_name = self.deserialize_name();
if !aliases.contains(&main_name) {
aliases.push(main_name);
}
aliases
} }
} }
@@ -405,20 +396,20 @@ impl Container {
if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? { if let Some(path) = parse_lit_into_expr_path(cx, DEFAULT, &meta)? {
match &item.data { match &item.data {
syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
syn::Fields::Named(_) => { syn::Fields::Named(_) | syn::Fields::Unnamed(_) => {
default.set(&meta.path, Default::Path(path)); default.set(&meta.path, Default::Path(path));
} }
syn::Fields::Unnamed(_) | syn::Fields::Unit => { syn::Fields::Unit => {
let msg = "#[serde(default = \"...\")] can only be used on structs with named fields"; let msg = "#[serde(default = \"...\")] can only be used on structs that have fields";
cx.syn_error(meta.error(msg)); cx.syn_error(meta.error(msg));
} }
}, },
syn::Data::Enum(_) => { syn::Data::Enum(_) => {
let msg = "#[serde(default = \"...\")] can only be used on structs with named fields"; let msg = "#[serde(default = \"...\")] can only be used on structs";
cx.syn_error(meta.error(msg)); cx.syn_error(meta.error(msg));
} }
syn::Data::Union(_) => { syn::Data::Union(_) => {
let msg = "#[serde(default = \"...\")] can only be used on structs with named fields"; let msg = "#[serde(default = \"...\")] can only be used on structs";
cx.syn_error(meta.error(msg)); cx.syn_error(meta.error(msg));
} }
} }
@@ -427,20 +418,20 @@ impl Container {
// #[serde(default)] // #[serde(default)]
match &item.data { match &item.data {
syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields { syn::Data::Struct(syn::DataStruct { fields, .. }) => match fields {
syn::Fields::Named(_) => { syn::Fields::Named(_) | syn::Fields::Unnamed(_) => {
default.set(meta.path, Default::Default); default.set(meta.path, Default::Default);
} }
syn::Fields::Unnamed(_) | syn::Fields::Unit => { syn::Fields::Unit => {
let msg = "#[serde(default)] can only be used on structs with named fields"; let msg = "#[serde(default)] can only be used on structs that have fields";
cx.error_spanned_by(fields, msg); cx.error_spanned_by(fields, msg);
} }
}, },
syn::Data::Enum(_) => { syn::Data::Enum(_) => {
let msg = "#[serde(default)] can only be used on structs with named fields"; let msg = "#[serde(default)] can only be used on structs";
cx.syn_error(meta.error(msg)); cx.syn_error(meta.error(msg));
} }
syn::Data::Union(_) => { syn::Data::Union(_) => {
let msg = "#[serde(default)] can only be used on structs with named fields"; let msg = "#[serde(default)] can only be used on structs";
cx.syn_error(meta.error(msg)); cx.syn_error(meta.error(msg));
} }
} }
@@ -977,7 +968,7 @@ impl Variant {
&self.name &self.name
} }
pub fn aliases(&self) -> Vec<String> { pub fn aliases(&self) -> &BTreeSet<String> {
self.name.deserialize_aliases() self.name.deserialize_aliases()
} }
@@ -988,6 +979,9 @@ impl Variant {
if !self.name.deserialize_renamed { if !self.name.deserialize_renamed {
self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize); self.name.deserialize = rules.deserialize.apply_to_variant(&self.name.deserialize);
} }
self.name
.deserialize_aliases
.insert(self.name.deserialize.clone());
} }
pub fn rename_all_rules(&self) -> RenameAllRules { pub fn rename_all_rules(&self) -> RenameAllRules {
@@ -1316,7 +1310,7 @@ impl Field {
&self.name &self.name
} }
pub fn aliases(&self) -> Vec<String> { pub fn aliases(&self) -> &BTreeSet<String> {
self.name.deserialize_aliases() self.name.deserialize_aliases()
} }
@@ -1327,6 +1321,9 @@ impl Field {
if !self.name.deserialize_renamed { if !self.name.deserialize_renamed {
self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize); self.name.deserialize = rules.deserialize.apply_to_field(&self.name.deserialize);
} }
self.name
.deserialize_aliases
.insert(self.name.deserialize.clone());
} }
pub fn skip_serializing(&self) -> bool { pub fn skip_serializing(&self) -> bool {
+35 -1
View File
@@ -1,11 +1,12 @@
use crate::internals::ast::{Container, Data, Field, Style}; use crate::internals::ast::{Container, Data, Field, Style};
use crate::internals::attr::{Identifier, TagType}; use crate::internals::attr::{Default, Identifier, TagType};
use crate::internals::{ungroup, Ctxt, Derive}; use crate::internals::{ungroup, Ctxt, Derive};
use syn::{Member, Type}; use syn::{Member, Type};
// Cross-cutting checks that require looking at more than a single attrs object. // Cross-cutting checks that require looking at more than a single attrs object.
// Simpler checks should happen when parsing and building the attrs. // Simpler checks should happen when parsing and building the attrs.
pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) { pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
check_default_on_tuple(cx, cont);
check_remote_generic(cx, cont); check_remote_generic(cx, cont);
check_getter(cx, cont); check_getter(cx, cont);
check_flatten(cx, cont); check_flatten(cx, cont);
@@ -17,6 +18,39 @@ pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
check_from_and_try_from(cx, cont); check_from_and_try_from(cx, cont);
} }
// If some field of a tuple struct is marked #[serde(default)] then all fields
// after it must also be marked with that attribute, or the struct must have a
// container-level serde(default) attribute. A field's default value is only
// used for tuple fields if the sequence is exhausted at that point; that means
// all subsequent fields will fail to deserialize if they don't have their own
// default.
fn check_default_on_tuple(cx: &Ctxt, cont: &Container) {
if let Default::None = cont.attrs.default() {
if let Data::Struct(Style::Tuple, fields) = &cont.data {
let mut first_default_index = None;
for (i, field) in fields.iter().enumerate() {
// Skipped fields automatically get the #[serde(default)]
// attribute. We are interested only on non-skipped fields here.
if field.attrs.skip_deserializing() {
continue;
}
if let Default::None = field.attrs.default() {
if let Some(first) = first_default_index {
cx.error_spanned_by(
field.ty,
format!("field must have #[serde(default)] because previous field {} has #[serde(default)]", first),
);
}
continue;
}
if first_default_index.is_none() {
first_default_index = Some(i);
}
}
}
}
}
// Remote derive definition type must have either all of the generics of the // Remote derive definition type must have either all of the generics of the
// remote type: // remote type:
// //
+1 -1
View File
@@ -13,7 +13,7 @@
//! //!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.179")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.182")]
// Ignored clippy lints // Ignored clippy lints
#![allow( #![allow(
// clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054 // clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054
+28 -13
View File
@@ -478,7 +478,14 @@ fn serialize_variant(
serialize_internally_tagged_variant(params, variant, cattrs, tag) serialize_internally_tagged_variant(params, variant, cattrs, tag)
} }
(attr::TagType::Adjacent { tag, content }, false) => { (attr::TagType::Adjacent { tag, content }, false) => {
serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content) serialize_adjacently_tagged_variant(
params,
variant,
cattrs,
variant_index,
tag,
content,
)
} }
(attr::TagType::None, _) | (_, true) => { (attr::TagType::None, _) | (_, true) => {
serialize_untagged_variant(params, variant, cattrs) serialize_untagged_variant(params, variant, cattrs)
@@ -559,7 +566,7 @@ fn serialize_externally_tagged_variant(
}, },
params, params,
&variant.fields, &variant.fields,
&type_name, type_name,
), ),
} }
} }
@@ -624,7 +631,7 @@ fn serialize_internally_tagged_variant(
StructVariant::InternallyTagged { tag, variant_name }, StructVariant::InternallyTagged { tag, variant_name },
params, params,
&variant.fields, &variant.fields,
&type_name, type_name,
), ),
Style::Tuple => unreachable!("checked in serde_derive_internals"), Style::Tuple => unreachable!("checked in serde_derive_internals"),
} }
@@ -634,12 +641,20 @@ fn serialize_adjacently_tagged_variant(
params: &Parameters, params: &Parameters,
variant: &Variant, variant: &Variant,
cattrs: &attr::Container, cattrs: &attr::Container,
variant_index: u32,
tag: &str, tag: &str,
content: &str, content: &str,
) -> Fragment { ) -> Fragment {
let this_type = &params.this_type; let this_type = &params.this_type;
let type_name = cattrs.name().serialize_name(); let type_name = cattrs.name().serialize_name();
let variant_name = variant.attrs.name().serialize_name(); let variant_name = variant.attrs.name().serialize_name();
let serialize_variant = quote! {
&_serde::__private::ser::AdjacentlyTaggedEnumVariant {
enum_name: #type_name,
variant_index: #variant_index,
variant_name: #variant_name,
}
};
let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() { let inner = Stmts(if let Some(path) = variant.attrs.serialize_with() {
let ser = wrap_serialize_variant_with(params, path, variant); let ser = wrap_serialize_variant_with(params, path, variant);
@@ -653,7 +668,7 @@ fn serialize_adjacently_tagged_variant(
let mut __struct = _serde::Serializer::serialize_struct( let mut __struct = _serde::Serializer::serialize_struct(
__serializer, #type_name, 1)?; __serializer, #type_name, 1)?;
_serde::ser::SerializeStruct::serialize_field( _serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)?; &mut __struct, #tag, #serialize_variant)?;
_serde::ser::SerializeStruct::end(__struct) _serde::ser::SerializeStruct::end(__struct)
}; };
} }
@@ -670,7 +685,7 @@ fn serialize_adjacently_tagged_variant(
let mut __struct = _serde::Serializer::serialize_struct( let mut __struct = _serde::Serializer::serialize_struct(
__serializer, #type_name, 2)?; __serializer, #type_name, 2)?;
_serde::ser::SerializeStruct::serialize_field( _serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)?; &mut __struct, #tag, #serialize_variant)?;
#func( #func(
&mut __struct, #content, #field_expr)?; &mut __struct, #content, #field_expr)?;
_serde::ser::SerializeStruct::end(__struct) _serde::ser::SerializeStruct::end(__struct)
@@ -683,7 +698,7 @@ fn serialize_adjacently_tagged_variant(
StructVariant::Untagged, StructVariant::Untagged,
params, params,
&variant.fields, &variant.fields,
&variant_name, variant_name,
), ),
} }
}); });
@@ -735,7 +750,7 @@ fn serialize_adjacently_tagged_variant(
let mut __struct = _serde::Serializer::serialize_struct( let mut __struct = _serde::Serializer::serialize_struct(
__serializer, #type_name, 2)?; __serializer, #type_name, 2)?;
_serde::ser::SerializeStruct::serialize_field( _serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)?; &mut __struct, #tag, #serialize_variant)?;
_serde::ser::SerializeStruct::serialize_field( _serde::ser::SerializeStruct::serialize_field(
&mut __struct, #content, &__AdjacentlyTagged { &mut __struct, #content, &__AdjacentlyTagged {
data: (#(#fields_ident,)*), data: (#(#fields_ident,)*),
@@ -779,16 +794,16 @@ fn serialize_untagged_variant(
Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields), Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
Style::Struct => { Style::Struct => {
let type_name = cattrs.name().serialize_name(); let type_name = cattrs.name().serialize_name();
serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, &type_name) serialize_struct_variant(StructVariant::Untagged, params, &variant.fields, type_name)
} }
} }
} }
enum TupleVariant { enum TupleVariant<'a> {
ExternallyTagged { ExternallyTagged {
type_name: String, type_name: &'a str,
variant_index: u32, variant_index: u32,
variant_name: String, variant_name: &'a str,
}, },
Untagged, Untagged,
} }
@@ -855,11 +870,11 @@ fn serialize_tuple_variant(
enum StructVariant<'a> { enum StructVariant<'a> {
ExternallyTagged { ExternallyTagged {
variant_index: u32, variant_index: u32,
variant_name: String, variant_name: &'a str,
}, },
InternallyTagged { InternallyTagged {
tag: &'a str, tag: &'a str,
variant_name: String, variant_name: &'a str,
}, },
Untagged, Untagged,
} }
+1 -1
View File
@@ -17,7 +17,7 @@ path = "lib.rs"
[dependencies] [dependencies]
proc-macro2 = "1.0" proc-macro2 = "1.0"
quote = "1.0" quote = "1.0"
syn = { version = "2.0.25", default-features = false, features = ["clone-impls", "derive", "parsing", "printing"] } syn = { version = "2.0.28", default-features = false, features = ["clone-impls", "derive", "parsing", "printing"] }
[package.metadata.docs.rs] [package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"] targets = ["x86_64-unknown-linux-gnu"]
+1
View File
@@ -1,3 +1,4 @@
#![allow(internal_features)]
#![feature(lang_items, start)] #![feature(lang_items, start)]
#![no_std] #![no_std]
+23 -8
View File
@@ -605,7 +605,7 @@ fn test_unknown_field_rename_struct() {
Token::Str("a4"), Token::Str("a4"),
Token::I32(3), Token::I32(3),
], ],
"unknown field `a4`, expected one of `a1`, `a3`, `a2`, `a5`, `a6`", "unknown field `a4`, expected one of `a1`, `a2`, `a3`, `a5`, `a6`",
); );
} }
@@ -799,7 +799,7 @@ fn test_unknown_field_rename_enum() {
Token::Str("d"), Token::Str("d"),
Token::I8(2), Token::I8(2),
], ],
"unknown field `d`, expected one of `a`, `c`, `b`, `e`, `f`", "unknown field `d`, expected one of `a`, `b`, `c`, `e`, `f`",
); );
} }
@@ -2108,7 +2108,10 @@ fn test_adjacently_tagged_enum_bytes() {
len: 2, len: 2,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("A"), Token::UnitVariant {
name: "Data",
variant: "A",
},
Token::Str("c"), Token::Str("c"),
Token::Struct { name: "A", len: 1 }, Token::Struct { name: "A", len: 1 },
Token::Str("a"), Token::Str("a"),
@@ -2126,7 +2129,10 @@ fn test_adjacently_tagged_enum_bytes() {
len: 2, len: 2,
}, },
Token::Bytes(b"t"), Token::Bytes(b"t"),
Token::Str("A"), Token::UnitVariant {
name: "Data",
variant: "A",
},
Token::Bytes(b"c"), Token::Bytes(b"c"),
Token::Struct { name: "A", len: 1 }, Token::Struct { name: "A", len: 1 },
Token::Str("a"), Token::Str("a"),
@@ -2167,7 +2173,10 @@ fn test_adjacently_tagged_enum_containing_flatten() {
len: 2, len: 2,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("A"), Token::UnitVariant {
name: "Data",
variant: "A",
},
Token::Str("c"), Token::Str("c"),
Token::Map { len: None }, Token::Map { len: None },
Token::Str("a"), Token::Str("a"),
@@ -2757,7 +2766,7 @@ fn test_expecting_message_adjacently_tagged_enum() {
// Check that #[serde(expecting = "...")] doesn't affect variant identifier error message // Check that #[serde(expecting = "...")] doesn't affect variant identifier error message
assert_de_tokens_error::<Enum>( assert_de_tokens_error::<Enum>(
&[Token::Map { len: None }, Token::Str("tag"), Token::Unit], &[Token::Map { len: None }, Token::Str("tag"), Token::Unit],
r#"invalid type: unit value, expected variant identifier"#, r#"invalid type: unit value, expected variant of enum Enum"#,
); );
} }
@@ -2992,7 +3001,10 @@ mod flatten {
Token::Str("outer"), Token::Str("outer"),
Token::U32(42), Token::U32(42),
Token::Str("tag"), Token::Str("tag"),
Token::Str("Struct"), Token::UnitVariant {
name: "Enum",
variant: "Struct",
},
Token::Str("content"), Token::Str("content"),
Token::Struct { Token::Struct {
len: 2, len: 2,
@@ -3020,7 +3032,10 @@ mod flatten {
Token::Str("outer"), Token::Str("outer"),
Token::U32(42), Token::U32(42),
Token::Str("tag"), Token::Str("tag"),
Token::Str("Newtype"), Token::UnitVariant {
name: "Enum",
variant: "Newtype",
},
Token::Str("content"), Token::Str("content"),
Token::Struct { Token::Struct {
len: 1, len: 1,
+158 -58
View File
@@ -3,86 +3,186 @@
#![allow(clippy::derive_partial_eq_without_eq)] #![allow(clippy::derive_partial_eq_without_eq)]
use serde_derive::Deserialize; use serde_derive::Deserialize;
use serde_test::{assert_de_tokens, Token}; use serde_test::{assert_de_tokens, assert_de_tokens_error, Token};
mod variant_identifier {
use super::*;
#[test]
fn test_variant_identifier() {
#[derive(Deserialize, Debug, PartialEq)] #[derive(Deserialize, Debug, PartialEq)]
#[serde(variant_identifier)] #[serde(variant_identifier)]
enum V { enum V {
Aaa, Aaa,
#[serde(alias = "Ccc", alias = "Ddd")]
Bbb, Bbb,
} }
assert_de_tokens(&V::Aaa, &[Token::U8(0)]); #[test]
assert_de_tokens(&V::Aaa, &[Token::U16(0)]); fn variant1() {
assert_de_tokens(&V::Aaa, &[Token::U32(0)]); assert_de_tokens(&V::Aaa, &[Token::U8(0)]);
assert_de_tokens(&V::Aaa, &[Token::U64(0)]); assert_de_tokens(&V::Aaa, &[Token::U16(0)]);
assert_de_tokens(&V::Aaa, &[Token::Str("Aaa")]); assert_de_tokens(&V::Aaa, &[Token::U32(0)]);
assert_de_tokens(&V::Aaa, &[Token::Bytes(b"Aaa")]); assert_de_tokens(&V::Aaa, &[Token::U64(0)]);
assert_de_tokens(&V::Aaa, &[Token::Str("Aaa")]);
assert_de_tokens(&V::Aaa, &[Token::Bytes(b"Aaa")]);
}
#[test]
fn aliases() {
assert_de_tokens(&V::Bbb, &[Token::U8(1)]);
assert_de_tokens(&V::Bbb, &[Token::U16(1)]);
assert_de_tokens(&V::Bbb, &[Token::U32(1)]);
assert_de_tokens(&V::Bbb, &[Token::U64(1)]);
assert_de_tokens(&V::Bbb, &[Token::Str("Bbb")]);
assert_de_tokens(&V::Bbb, &[Token::Bytes(b"Bbb")]);
assert_de_tokens(&V::Bbb, &[Token::Str("Ccc")]);
assert_de_tokens(&V::Bbb, &[Token::Bytes(b"Ccc")]);
assert_de_tokens(&V::Bbb, &[Token::Str("Ddd")]);
assert_de_tokens(&V::Bbb, &[Token::Bytes(b"Ddd")]);
}
#[test]
fn unknown() {
assert_de_tokens_error::<V>(
&[Token::U8(42)],
"invalid value: integer `42`, expected variant index 0 <= i < 2",
);
assert_de_tokens_error::<V>(
&[Token::U16(42)],
"invalid value: integer `42`, expected variant index 0 <= i < 2",
);
assert_de_tokens_error::<V>(
&[Token::U32(42)],
"invalid value: integer `42`, expected variant index 0 <= i < 2",
);
assert_de_tokens_error::<V>(
&[Token::U64(42)],
"invalid value: integer `42`, expected variant index 0 <= i < 2",
);
assert_de_tokens_error::<V>(
&[Token::Str("Unknown")],
"unknown variant `Unknown`, expected one of `Aaa`, `Bbb`, `Ccc`, `Ddd`",
);
assert_de_tokens_error::<V>(
&[Token::Bytes(b"Unknown")],
"unknown variant `Unknown`, expected one of `Aaa`, `Bbb`, `Ccc`, `Ddd`",
);
}
} }
#[test] mod field_identifier {
fn test_field_identifier() { use super::*;
#[derive(Deserialize, Debug, PartialEq)] #[derive(Deserialize, Debug, PartialEq)]
#[serde(field_identifier, rename_all = "snake_case")] #[serde(field_identifier, rename_all = "snake_case")]
enum F { enum F {
Aaa, Aaa,
#[serde(alias = "ccc", alias = "ddd")]
Bbb, Bbb,
} }
assert_de_tokens(&F::Aaa, &[Token::U8(0)]); #[test]
assert_de_tokens(&F::Aaa, &[Token::U16(0)]); fn field1() {
assert_de_tokens(&F::Aaa, &[Token::U32(0)]); assert_de_tokens(&F::Aaa, &[Token::U8(0)]);
assert_de_tokens(&F::Aaa, &[Token::U64(0)]); assert_de_tokens(&F::Aaa, &[Token::U16(0)]);
assert_de_tokens(&F::Aaa, &[Token::Str("aaa")]); assert_de_tokens(&F::Aaa, &[Token::U32(0)]);
assert_de_tokens(&F::Aaa, &[Token::Bytes(b"aaa")]); assert_de_tokens(&F::Aaa, &[Token::U64(0)]);
} assert_de_tokens(&F::Aaa, &[Token::Str("aaa")]);
assert_de_tokens(&F::Aaa, &[Token::Bytes(b"aaa")]);
#[test]
fn test_unit_fallthrough() {
#[derive(Deserialize, Debug, PartialEq)]
#[serde(field_identifier, rename_all = "snake_case")]
enum F {
Aaa,
Bbb,
#[serde(other)]
Other,
} }
assert_de_tokens(&F::Other, &[Token::U8(42)]); #[test]
assert_de_tokens(&F::Other, &[Token::U16(42)]); fn aliases() {
assert_de_tokens(&F::Other, &[Token::U32(42)]); assert_de_tokens(&F::Bbb, &[Token::U8(1)]);
assert_de_tokens(&F::Other, &[Token::U64(42)]); assert_de_tokens(&F::Bbb, &[Token::U16(1)]);
assert_de_tokens(&F::Other, &[Token::Str("x")]); assert_de_tokens(&F::Bbb, &[Token::U32(1)]);
} assert_de_tokens(&F::Bbb, &[Token::U64(1)]);
#[test] assert_de_tokens(&F::Bbb, &[Token::Str("bbb")]);
fn test_newtype_fallthrough() { assert_de_tokens(&F::Bbb, &[Token::Bytes(b"bbb")]);
#[derive(Deserialize, Debug, PartialEq)]
#[serde(field_identifier, rename_all = "snake_case")] assert_de_tokens(&F::Bbb, &[Token::Str("ccc")]);
enum F { assert_de_tokens(&F::Bbb, &[Token::Bytes(b"ccc")]);
Aaa,
Bbb, assert_de_tokens(&F::Bbb, &[Token::Str("ddd")]);
Other(String), assert_de_tokens(&F::Bbb, &[Token::Bytes(b"ddd")]);
} }
assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]); #[test]
} fn unknown() {
assert_de_tokens_error::<F>(
#[test] &[Token::U8(42)],
fn test_newtype_fallthrough_generic() { "invalid value: integer `42`, expected field index 0 <= i < 2",
#[derive(Deserialize, Debug, PartialEq)] );
#[serde(field_identifier, rename_all = "snake_case")] assert_de_tokens_error::<F>(
enum F<T> { &[Token::U16(42)],
Aaa, "invalid value: integer `42`, expected field index 0 <= i < 2",
Bbb, );
Other(T), assert_de_tokens_error::<F>(
&[Token::U32(42)],
"invalid value: integer `42`, expected field index 0 <= i < 2",
);
assert_de_tokens_error::<F>(
&[Token::U64(42)],
"invalid value: integer `42`, expected field index 0 <= i < 2",
);
assert_de_tokens_error::<F>(
&[Token::Str("unknown")],
"unknown field `unknown`, expected one of `aaa`, `bbb`, `ccc`, `ddd`",
);
assert_de_tokens_error::<F>(
&[Token::Bytes(b"unknown")],
"unknown field `unknown`, expected one of `aaa`, `bbb`, `ccc`, `ddd`",
);
} }
assert_de_tokens(&F::Other(42u8), &[Token::U8(42)]); #[test]
assert_de_tokens(&F::Other(42u16), &[Token::U16(42)]); fn unit_fallthrough() {
assert_de_tokens(&F::Other(42u32), &[Token::U32(42)]); #[derive(Deserialize, Debug, PartialEq)]
assert_de_tokens(&F::Other(42u64), &[Token::U64(42)]); #[serde(field_identifier, rename_all = "snake_case")]
assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]); enum F {
Aaa,
Bbb,
#[serde(other)]
Other,
}
assert_de_tokens(&F::Other, &[Token::U8(42)]);
assert_de_tokens(&F::Other, &[Token::U16(42)]);
assert_de_tokens(&F::Other, &[Token::U32(42)]);
assert_de_tokens(&F::Other, &[Token::U64(42)]);
assert_de_tokens(&F::Other, &[Token::Str("x")]);
}
#[test]
fn newtype_fallthrough() {
#[derive(Deserialize, Debug, PartialEq)]
#[serde(field_identifier, rename_all = "snake_case")]
enum F {
Aaa,
Bbb,
Other(String),
}
assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]);
}
#[test]
fn newtype_fallthrough_generic() {
#[derive(Deserialize, Debug, PartialEq)]
#[serde(field_identifier, rename_all = "snake_case")]
enum F<T> {
Aaa,
Bbb,
Other(T),
}
assert_de_tokens(&F::Other(42u8), &[Token::U8(42)]);
assert_de_tokens(&F::Other(42u16), &[Token::U16(42)]);
assert_de_tokens(&F::Other(42u32), &[Token::U32(42)]);
assert_de_tokens(&F::Other(42u64), &[Token::U64(42)]);
assert_de_tokens(&F::Other("x".to_owned()), &[Token::Str("x")]);
}
} }
+76 -19
View File
@@ -472,7 +472,10 @@ fn test_adjacently_tagged_newtype_struct() {
}, },
Token::U32(5), Token::U32(5),
Token::Str("t"), Token::Str("t"),
Token::Str("Newtype"), Token::UnitVariant {
name: "E",
variant: "Newtype",
},
Token::StructEnd, Token::StructEnd,
], ],
); );
@@ -1066,7 +1069,10 @@ fn test_adjacently_tagged_enum() {
len: 1, len: 1,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("Unit"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Unit",
},
Token::StructEnd, Token::StructEnd,
], ],
); );
@@ -1080,7 +1086,10 @@ fn test_adjacently_tagged_enum() {
len: 2, len: 2,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("Unit"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Unit",
},
Token::StructEnd, Token::StructEnd,
], ],
); );
@@ -1094,7 +1103,10 @@ fn test_adjacently_tagged_enum() {
len: 2, len: 2,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("Unit"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Unit",
},
Token::Str("c"), Token::Str("c"),
Token::Unit, Token::Unit,
Token::StructEnd, Token::StructEnd,
@@ -1112,7 +1124,10 @@ fn test_adjacently_tagged_enum() {
Token::Str("c"), Token::Str("c"),
Token::Unit, Token::Unit,
Token::Str("t"), Token::Str("t"),
Token::Str("Unit"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Unit",
},
Token::StructEnd, Token::StructEnd,
], ],
); );
@@ -1128,7 +1143,10 @@ fn test_adjacently_tagged_enum() {
Token::Str("f"), Token::Str("f"),
Token::Unit, Token::Unit,
Token::Str("t"), Token::Str("t"),
Token::Str("Unit"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Unit",
},
Token::Str("g"), Token::Str("g"),
Token::Unit, Token::Unit,
Token::Str("c"), Token::Str("c"),
@@ -1148,7 +1166,10 @@ fn test_adjacently_tagged_enum() {
len: 2, len: 2,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("Newtype"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Newtype",
},
Token::Str("c"), Token::Str("c"),
Token::U8(1), Token::U8(1),
Token::StructEnd, Token::StructEnd,
@@ -1166,7 +1187,10 @@ fn test_adjacently_tagged_enum() {
Token::Str("c"), Token::Str("c"),
Token::U8(1), Token::U8(1),
Token::Str("t"), Token::Str("t"),
Token::Str("Newtype"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Newtype",
},
Token::StructEnd, Token::StructEnd,
], ],
); );
@@ -1180,7 +1204,10 @@ fn test_adjacently_tagged_enum() {
len: 1, len: 1,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("Newtype"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Newtype",
},
Token::StructEnd, Token::StructEnd,
], ],
); );
@@ -1194,7 +1221,10 @@ fn test_adjacently_tagged_enum() {
len: 2, len: 2,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("Tuple"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Tuple",
},
Token::Str("c"), Token::Str("c"),
Token::Tuple { len: 2 }, Token::Tuple { len: 2 },
Token::U8(1), Token::U8(1),
@@ -1218,7 +1248,10 @@ fn test_adjacently_tagged_enum() {
Token::U8(1), Token::U8(1),
Token::TupleEnd, Token::TupleEnd,
Token::Str("t"), Token::Str("t"),
Token::Str("Tuple"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Tuple",
},
Token::StructEnd, Token::StructEnd,
], ],
); );
@@ -1232,7 +1265,10 @@ fn test_adjacently_tagged_enum() {
len: 2, len: 2,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("Struct"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Struct",
},
Token::Str("c"), Token::Str("c"),
Token::Struct { Token::Struct {
name: "Struct", name: "Struct",
@@ -1262,7 +1298,10 @@ fn test_adjacently_tagged_enum() {
Token::U8(1), Token::U8(1),
Token::StructEnd, Token::StructEnd,
Token::Str("t"), Token::Str("t"),
Token::Str("Struct"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Struct",
},
Token::StructEnd, Token::StructEnd,
], ],
); );
@@ -1278,7 +1317,10 @@ fn test_adjacently_tagged_enum() {
Token::U64(1), // content field Token::U64(1), // content field
Token::U8(1), Token::U8(1),
Token::U64(0), // tag field Token::U64(0), // tag field
Token::Str("Newtype"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Newtype",
},
Token::StructEnd, Token::StructEnd,
], ],
); );
@@ -1294,7 +1336,10 @@ fn test_adjacently_tagged_enum() {
Token::Bytes(b"c"), Token::Bytes(b"c"),
Token::U8(1), Token::U8(1),
Token::Bytes(b"t"), Token::Bytes(b"t"),
Token::Str("Newtype"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Newtype",
},
Token::StructEnd, Token::StructEnd,
], ],
); );
@@ -1316,7 +1361,10 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
len: 2, len: 2,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("Unit"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Unit",
},
Token::Str("c"), Token::Str("c"),
Token::Unit, Token::Unit,
Token::StructEnd, Token::StructEnd,
@@ -1330,7 +1378,10 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
len: 2, len: 2,
}, },
Token::Str("t"), Token::Str("t"),
Token::Str("Unit"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Unit",
},
Token::Str("c"), Token::Str("c"),
Token::Unit, Token::Unit,
Token::Str("h"), Token::Str("h"),
@@ -1369,7 +1420,10 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
len: 2, len: 2,
}, },
Token::U64(0), // tag field Token::U64(0), // tag field
Token::Str("Unit"), Token::UnitVariant {
name: "AdjacentlyTagged",
variant: "Unit",
},
Token::U64(3), Token::U64(3),
], ],
r#"invalid value: integer `3`, expected "t" or "c""#, r#"invalid value: integer `3`, expected "t" or "c""#,
@@ -1565,7 +1619,10 @@ fn test_internally_tagged_struct_with_flattened_field() {
Token::Str("tag_struct"), Token::Str("tag_struct"),
Token::Str("Struct"), Token::Str("Struct"),
Token::Str("tag_enum"), Token::Str("tag_enum"),
Token::Str("A"), Token::UnitVariant {
name: "Enum",
variant: "A",
},
Token::Str("content"), Token::Str("content"),
Token::U64(0), Token::U64(0),
Token::MapEnd, Token::MapEnd,
@@ -1,4 +1,4 @@
error: #[serde(default)] can only be used on structs with named fields error: #[serde(default)] can only be used on structs
--> tests/ui/default-attribute/enum.rs:4:9 --> tests/ui/default-attribute/enum.rs:4:9
| |
4 | #[serde(default)] 4 | #[serde(default)]
@@ -1,4 +1,4 @@
error: #[serde(default = "...")] can only be used on structs with named fields error: #[serde(default = "...")] can only be used on structs
--> tests/ui/default-attribute/enum_path.rs:4:9 --> tests/ui/default-attribute/enum_path.rs:4:9
| |
4 | #[serde(default = "default_e")] 4 | #[serde(default = "default_e")]
@@ -1,7 +0,0 @@
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(default)]
struct T(u8, u8);
fn main() {}
@@ -1,5 +0,0 @@
error: #[serde(default)] can only be used on structs with named fields
--> tests/ui/default-attribute/nameless_struct_fields.rs:5:9
|
5 | struct T(u8, u8);
| ^^^^^^^^
@@ -1,7 +0,0 @@
use serde_derive::Deserialize;
#[derive(Deserialize)]
#[serde(default = "default_t")]
struct T(u8, u8);
fn main() {}
@@ -1,5 +0,0 @@
error: #[serde(default = "...")] can only be used on structs with named fields
--> tests/ui/default-attribute/nameless_struct_fields_path.rs:4:9
|
4 | #[serde(default = "default_t")]
| ^^^^^^^^^^^^^^^^^^^^^
@@ -0,0 +1,47 @@
use serde_derive::Deserialize;
// No errors expected.
#[derive(Deserialize)]
struct T0(u8, u8);
// No errors expected:
// - If both fields are provided, both get value from data.
// - If only one field is provided, the second gets default value.
#[derive(Deserialize)]
struct T1(u8, #[serde(default)] u8);
// ERROR: The first field can get default value only if sequence is empty, but
// that mean that all other fields cannot be deserialized without errors.
#[derive(Deserialize)]
struct T2(#[serde(default)] u8, u8, u8);
// No errors expected:
// - If both fields are provided, both get value from data.
// - If only one field is provided, the second gets default value.
// - If no fields are provided, both get default value.
#[derive(Deserialize)]
struct T3(#[serde(default)] u8, #[serde(default)] u8);
////////////////////////////////////////////////////////////////////////////////
// No errors expected -- missing fields get default values.
#[derive(Deserialize, Default)]
#[serde(default)]
struct T4(u8, u8);
// No errors expected -- missing fields get default values.
#[derive(Deserialize, Default)]
#[serde(default)]
struct T5(#[serde(default)] u8, u8);
// No errors expected -- missing fields get default values.
#[derive(Deserialize, Default)]
#[serde(default)]
struct T6(u8, #[serde(default)] u8);
// No errors expected -- missing fields get default values.
#[derive(Deserialize, Default)]
#[serde(default)]
struct T7(#[serde(default)] u8, #[serde(default)] u8);
fn main() {}
@@ -0,0 +1,11 @@
error: field must have #[serde(default)] because previous field 0 has #[serde(default)]
--> tests/ui/default-attribute/tuple_struct.rs:16:33
|
16 | struct T2(#[serde(default)] u8, u8, u8);
| ^^
error: field must have #[serde(default)] because previous field 0 has #[serde(default)]
--> tests/ui/default-attribute/tuple_struct.rs:16:37
|
16 | struct T2(#[serde(default)] u8, u8, u8);
| ^^
@@ -0,0 +1,76 @@
use serde_derive::Deserialize;
fn d<T>() -> T {
unimplemented!()
}
// No errors expected:
// - If both fields are provided, both get value from data.
// - If only one field is provided, the second gets default value.
#[derive(Deserialize)]
struct T1(u8, #[serde(default = "d")] u8);
// ERROR: The first field can get default value only if sequence is empty, but
// that mean that all other fields cannot be deserialized without errors.
#[derive(Deserialize)]
struct T2(#[serde(default = "d")] u8, u8, u8);
// No errors expected:
// - If both fields are provided, both get value from data.
// - If only one field is provided, the second gets default value.
// - If no fields are provided, both get default value.
#[derive(Deserialize)]
struct T3(#[serde(default = "d")] u8, #[serde(default = "d")] u8);
////////////////////////////////////////////////////////////////////////////////
// No errors expected -- missing fields get default values.
#[derive(Deserialize, Default)]
#[serde(default)]
struct T1D(#[serde(default = "d")] u8, u8);
// No errors expected -- missing fields get default values.
#[derive(Deserialize, Default)]
#[serde(default)]
struct T2D(u8, #[serde(default = "d")] u8);
// No errors expected -- missing fields get default values.
#[derive(Deserialize, Default)]
#[serde(default)]
struct T3D(#[serde(default = "d")] u8, #[serde(default = "d")] u8);
////////////////////////////////////////////////////////////////////////////////
// No errors expected -- missing fields get default values.
#[derive(Deserialize)]
#[serde(default = "d")]
struct T1Path(#[serde(default)] u8, u8);
// No errors expected -- missing fields get default values.
#[derive(Deserialize)]
#[serde(default = "d")]
struct T2Path(u8, #[serde(default)] u8);
// No errors expected -- missing fields get default values.
#[derive(Deserialize)]
#[serde(default = "d")]
struct T3Path(#[serde(default)] u8, #[serde(default)] u8);
////////////////////////////////////////////////////////////////////////////////
// No errors expected -- missing fields get default values.
#[derive(Deserialize)]
#[serde(default = "d")]
struct T1PathD(#[serde(default = "d")] u8, u8);
// No errors expected -- missing fields get default values.
#[derive(Deserialize)]
#[serde(default = "d")]
struct T2PathD(u8, #[serde(default = "d")] u8);
// No errors expected -- missing fields get default values.
#[derive(Deserialize)]
#[serde(default = "d")]
struct T3PathD(#[serde(default = "d")] u8, #[serde(default = "d")] u8);
fn main() {}
@@ -0,0 +1,11 @@
error: field must have #[serde(default)] because previous field 0 has #[serde(default)]
--> tests/ui/default-attribute/tuple_struct_path.rs:16:39
|
16 | struct T2(#[serde(default = "d")] u8, u8, u8);
| ^^
error: field must have #[serde(default)] because previous field 0 has #[serde(default)]
--> tests/ui/default-attribute/tuple_struct_path.rs:16:43
|
16 | struct T2(#[serde(default = "d")] u8, u8, u8);
| ^^