Compare commits

...

571 Commits

Author SHA1 Message Date
David Tolnay 63c65ef742 Release 1.0.172 2023-07-19 14:13:56 -07:00
David Tolnay e838b0bd81 Release 1.0.172-alpha.0 2023-07-19 14:00:50 -07:00
David Tolnay 041e99c78a Implement fallback to compiling serde_derive from source 2023-07-19 13:53:49 -07:00
David Tolnay 07dcc4f7fe Remove unneeded 'include' Cargo.toml entries 2023-07-19 13:44:55 -07:00
David Tolnay b88052d875 Rearrange precompiled directory 2023-07-19 13:24:36 -07:00
David Tolnay a28292764c Publish precompiled deserialize_in_place 2023-07-19 12:29:30 -07:00
David Tolnay 2027088741 Support precompiled deserialize_in_place 2023-07-19 12:27:37 -07:00
David Tolnay e2d8589976 Publish span-related fixes 2023-07-19 09:41:11 -07:00
David Tolnay c8a9f99d14 Preserve Group span better on compilers without Span::join 2023-07-19 09:39:11 -07:00
David Tolnay 645d04012d Fix off by one span counter, 0 is used for call_site() 2023-07-19 09:26:56 -07:00
David Tolnay 100ddada2f Suppress dead_code on fields only accessed by deserialize_in_place
error: field `option` is never read
       --> test_suite/tests/test_gen.rs:666:9
        |
    665 |     struct ImplicitlyBorrowedOption<'a> {
        |            ------------------------ field in this struct
    666 |         option: std::option::Option<&'a str>,
        |         ^^^^^^
        |
    note: the lint level is defined here
       --> test_suite/tests/test_gen.rs:5:9
        |
    5   | #![deny(warnings)]
        |         ^^^^^^^^
        = note: `#[deny(dead_code)]` implied by `#[deny(warnings)]`

    error: fields `ty` and `id` are never read
       --> test_suite/tests/test_gen.rs:696:9
        |
    695 |     struct RelObject<'a> {
        |            --------- fields in this struct
    696 |         ty: &'a str,
        |         ^^
    697 |         id: String,
        |         ^^

    error: field `field` is never read
       --> test_suite/tests/test_gen.rs:740:17
        |
    739 |             struct MacroRules<'a> {
        |                    ---------- field in this struct
    740 |                 field: $field,
        |                 ^^^^^
    ...
    745 |     deriving!(&'a str);
        |     ------------------ in this macro invocation
        |
        = note: this error originates in the macro `deriving` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: field `f` is never read
       --> test_suite/tests/test_gen.rs:756:9
        |
    754 |     struct BorrowLifetimeInsideMacro<'a> {
        |            ------------------------- field in this struct
    755 |         #[serde(borrow = "'a")]
    756 |         f: mac!(Cow<'a, str>),
        |         ^

    warning: fields `question` and `answer` are never read
        --> test_suite/tests/test_annotations.rs:2969:9
         |
    2968 |     struct Struct {
         |            ------ fields in this struct
    2969 |         question: String,
         |         ^^^^^^^^
    2970 |         answer: u32,
         |         ^^^^^^
         |
         = note: `#[warn(dead_code)]` on by default
2023-07-19 09:12:35 -07:00
David Tolnay 2ef1cd4b35 Import macros exclusively through serde_derive in test suite
This makes it easier to execute tests against the precompiled serde_derive.
2023-07-19 09:08:05 -07:00
David Tolnay be9c3fd69d Publish raw string fix 2023-07-18 18:42:54 -07:00
David Tolnay ef522e1d16 Add a reminder about trim-paths 2023-07-18 18:39:40 -07:00
David Tolnay 1ddb6c2fdb Fix handling of raw idents in proc-macro2 shim 2023-07-18 18:29:24 -07:00
David Tolnay eb3f2329af Merge pull request #2514 from dtolnay/precompiled
Add experiment to produce precompiled builds of serde_derive
2023-07-18 13:48:17 -07:00
David Tolnay 9e8f14816b Add experiment to produce precompiled builds of serde_derive 2023-07-18 13:37:36 -07:00
David Tolnay 03da66c805 Release 1.0.171 2023-07-09 18:05:02 -07:00
David Tolnay f75426f47e Inline visitor_expr of unit struct deserialize impl 2023-07-09 18:03:58 -07:00
David Tolnay 662fc3861c Add test of const-generic unit struct where-clause edge case
Closes #2501.
2023-07-09 18:01:43 -07:00
David Tolnay 28c10020b9 Merge pull request #2500 from Baptistemontan/derive_generic_unit_struct
Allow `[derive(serde::Deserialize)]` for generic unit structs
2023-07-09 17:52:12 -07:00
Baptiste de Montangon 89c8d85de9 allow Deserialize derive to handle generic unit structs 2023-07-10 01:31:40 +02:00
David Tolnay 6502838f27 Release 1.0.170 2023-07-09 11:17:30 -07:00
David Tolnay c93a0f335a Merge pull request #2499 from dtolnay/strsuffix
Reject suffixed string literals inside serde attrs
2023-07-09 11:16:31 -07:00
David Tolnay 8264e002a7 Reject suffixed string literals inside serde attrs 2023-07-09 11:13:24 -07:00
David Tolnay 117ef22142 Add ui test with suffixed string literals in attribute 2023-07-09 11:09:38 -07:00
David Tolnay 3fb5e71c33 Release 1.0.169 2023-07-08 21:09:08 -07:00
David Tolnay 296db177e2 Pull in syn fix for issue 2414 2023-07-08 21:08:22 -07:00
David Tolnay e4a4389177 Delete excessive tests of adjacently tagged non-string keys 2023-07-08 18:23:31 -07:00
David Tolnay 7aa0453c3b Merge pull request 2475 from Baptistemontan/master 2023-07-08 18:07:16 -07:00
David Tolnay 09b78b24e9 Release 1.0.168 2023-07-08 17:52:06 -07:00
David Tolnay a622b8a74a Merge pull request #2495 from dtolnay/cautious
Allow larger preallocated capacity for smaller elements
2023-07-08 17:51:16 -07:00
David Tolnay 399ef081ec Allow larger preallocated capacity for smaller elements 2023-07-08 17:43:01 -07:00
David Tolnay 3686277e14 Merge pull request #2436 from Mingun/flatten-ignored-any
Allow to flatten `IgnoredAny`
2023-07-06 16:35:10 -07:00
David Tolnay 807bd20a64 Release 1.0.167 2023-07-06 16:25:48 -07:00
David Tolnay ed9a140348 Merge pull request #2444 from Mingun/dedup
Simplify code for generation of struct deserializers
2023-07-06 16:25:15 -07:00
David Tolnay 2de7c2bea2 Resolve redundant_static_lifetimes clippy lint from PR 2471
error: constants have by default a `'static` lifetime
        --> serde/src/de/impls.rs:2467:24
         |
    2467 |     pub const FIELDS: &'static [&'static str] = &["end"];
         |                       -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes
         = note: `-D clippy::redundant-static-lifetimes` implied by `-D clippy::all`

    error: constants have by default a `'static` lifetime
        --> serde/src/de/impls.rs:2467:34
         |
    2467 |     pub const FIELDS: &'static [&'static str] = &["end"];
         |                                 -^^^^^^^---- help: consider removing `'static`: `&str`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes

    error: constants have by default a `'static` lifetime
        --> serde/src/de/impls.rs:2605:24
         |
    2605 |     pub const FIELDS: &'static [&'static str] = &["start"];
         |                       -^^^^^^^--------------- help: consider removing `'static`: `&[&'static str]`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes

    error: constants have by default a `'static` lifetime
        --> serde/src/de/impls.rs:2605:34
         |
    2605 |     pub const FIELDS: &'static [&'static str] = &["start"];
         |                                 -^^^^^^^---- help: consider removing `'static`: `&str`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes
2023-07-06 16:18:39 -07:00
David Tolnay e6a4a3772e Delete unuseful RangeFull impls 2023-07-06 16:10:21 -07:00
David Tolnay 0fca04e1a6 Merge pull request 2471 from tbu-/pr_more_ranges 2023-07-06 16:09:13 -07:00
David Tolnay 92bfc8d3af Merge pull request #2290 from Mingun/enum-tests-and-cleanup
Remove unused `impl` and unnecessary struct-wrapper around tuple
2023-07-06 16:02:27 -07:00
David Tolnay fa0312ac45 More formatting of doc tests and example code 2023-07-06 15:56:47 -07:00
David Tolnay 1920b694aa Declare required automod dev-dependency
1.0.0 does not work with workspaces.

    error: No such file or directory (os error 2)
     --> test_suite/tests/regression.rs:2:5
      |
    2 |     automod::dir!("tests/regression");
      |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      |
      = note: this error originates in the macro `automod::dir` (in Nightly builds, run with -Z macro-backtrace for more info)
2023-07-06 15:50:32 -07:00
David Tolnay 3bfd41d624 Format doctests using rustfmt's format_code_in_doc_comments
cargo fmt -- --config format_code_in_doc_comments=true
2023-07-06 15:44:32 -07:00
David Tolnay 290449f19b Fix doc tests to work whether or not serde derive feature is used 2023-07-06 15:40:12 -07:00
David Tolnay 3a1f387e69 Merge pull request #2493 from dtolnay/docedition
Update documentation example code to 2021 edition
2023-07-06 15:40:03 -07:00
David Tolnay 541603ac94 Fix doc tests for 2021 edition 2023-07-06 15:36:17 -07:00
David Tolnay 0666fbfa20 Update documentation example code to 2021 edition 2023-07-06 15:17:05 -07:00
David Tolnay ea071ae1d4 Add CI job using minimal-versions 2023-07-05 10:01:33 -07:00
David Tolnay 992a01bad2 Sort dependency features in Cargo.toml 2023-07-04 12:12:31 -07:00
David Tolnay d640b5624f Add no-alloc category to the macro crate also 2023-07-03 14:05:32 -07:00
David Tolnay 48479e4bae Release 1.0.166 2023-07-03 11:33:19 -07:00
David Tolnay dfaf48bc09 Add no-std::no-alloc category 2023-07-03 11:32:55 -07:00
David Tolnay dcbc3e0162 Release 1.0.165 2023-07-03 04:21:59 -07:00
David Tolnay 0289d31724 Fix -Zminimal-versions build 2023-07-03 04:21:14 -07:00
David Tolnay 015e39776f No need for single-element vec for chaining one element 2023-07-02 21:11:09 -07:00
David Tolnay 6a9a21f178 Resolve useless_conversion clippy lint in test
error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
       --> test_suite/tests/test_de.rs:202:12
        |
    202 |     .chain(vec![Token::MapEnd].into_iter())
        |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![Token::MapEnd]`
        |
    note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
       --> /home/david/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/iter/traits/iterator.rs:522:12
        |
    522 |         U: IntoIterator<Item = Self::Item>,
        |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#useless_conversion
        = note: `-D clippy::useless-conversion` implied by `-D clippy::all`
2023-07-02 21:10:06 -07:00
David Tolnay 81ac54b20d Resolve redundant_closure_call clippy lint
error: try not to call a closure in the expression where it is declared
        --> serde/src/de/impls.rs:1590:76
         |
    1590 |                       <(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port))
         |                                                                              ^^^^^^^^^^^^^^
    ...
    1620 | / parse_socket_impl!("IPv6 socket address" net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(
    1621 | |     ip, port, 0, 0
    1622 | | ));
         | |__- in this macro invocation
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_call
         = note: `-D clippy::redundant-closure-call` implied by `-D clippy::all`
         = note: this error originates in the macro `parse_socket_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
2023-07-02 21:08:50 -07:00
David Tolnay 6b4e75520a Resolve explicit_iter_loop pedantic clippy lint
error: it is more concise to loop over references to containers instead of using explicit iteration methods
        --> serde/src/private/de.rs:2761:22
         |
    2761 |         for entry in self.0.iter_mut() {
         |                      ^^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *self.0`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop
         = note: `-D clippy::explicit-iter-loop` implied by `-D clippy::pedantic`

    error: it is more concise to loop over references to containers instead of using explicit iteration methods
       --> serde_derive/src/internals/check.rs:202:20
        |
    202 |     for variant in variants.iter() {
        |                    ^^^^^^^^^^^^^^^ help: to write this more concisely, try: `variants`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop
        = note: `-D clippy::explicit-iter-loop` implied by `-D clippy::pedantic`

    error: it is more concise to loop over references to containers instead of using explicit iteration methods
       --> serde_derive/src/bound.rs:262:28
        |
    262 |             for variant in variants.iter() {
        |                            ^^^^^^^^^^^^^^^ help: to write this more concisely, try: `variants`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_iter_loop
2023-07-02 21:08:44 -07:00
David Tolnay b053b4f492 Touch up early return in Enum checks 2023-07-02 21:08:44 -07:00
Mingun 4cf1fec575 Replace several linked variables with enumeration for tuples 2023-06-26 20:55:52 +05:00
Mingun ee7d77defa Replace several linked variables with enumeration for structs 2023-06-26 20:55:52 +05:00
Mingun d0dfc4577e Replace enum with boolean parameter 2023-06-26 20:55:52 +05:00
Mingun bbbd1d24c9 Move deserialize_generated_identifier out from if because the call is same in both arms 2023-06-26 20:55:51 +05:00
Mingun fb3a9e0d7c Simplify check for missing fields 2023-06-26 20:55:51 +05:00
Mingun 5ffebeb6ef Actually, field_names_idents can be calculated using the same code in both cases
When !cattrs.has_flatten() all fields is !field.attrs.flatten()

Co-authored-by: Oliver Schneider <oli-obk@users.noreply.github.com>
2023-06-26 20:55:51 +05:00
Mingun 75db73066b Inline deserialize_struct_as_map_visitor and deserialize_struct_as_struct_visitor 2023-06-26 20:55:51 +05:00
Mingun 2796833c82 Pull up call to deserialize_map because it's identical 2023-06-26 20:55:50 +05:00
Mingun 95730dc7f7 Reorder variables to match order in final quote! 2023-06-26 20:55:50 +05:00
Mingun 795261919f Generate visit_seq only when needed 2023-06-26 20:55:50 +05:00
Mingun 3783a30ae7 Remove TaggedContent, replace it by a tuple
That type does not give any benefits so we can avoid that hidden public but no-API struct
2023-06-24 20:49:49 +05:00
Mingun b61ec84886 Remove implementation of DeserializeSeed for TaggedContentVisitor
It is not used anywhere
2023-06-24 20:48:09 +05:00
Mingun 780a461d92 Generate one deserializer rather than in each arm 2023-06-24 20:48:08 +05:00
David Tolnay c0ba323166 Support a manual trigger on CI workflow 2023-06-23 22:50:52 -07:00
David Tolnay 20a48c9580 Remove .clippy.toml in favor of respecting rust-version from Cargo.toml 2023-06-15 18:31:38 -07:00
David Tolnay 09938803af Resolve redundant_static_lifetimes clippy lint 2023-06-15 18:31:38 -07:00
David Tolnay 6d0b43a220 Resolve redundant_field_names clippy lint 2023-06-15 18:31:38 -07:00
Baptiste de Montangon c604bdbfe4 Clarified tokens that represents tag and content for integer identifiers 2023-06-12 17:17:15 +02:00
Baptiste de Montangon 9fef892f6d fixed difference in error message for adjacently tagged enums 2023-06-12 16:02:19 +02:00
Baptiste de Montangon b1c7db47b8 Adjancently tagged enum field is determined with visit_identifier instead of only visit_str 2023-06-12 15:27:28 +02:00
Tobias Bucher e76e87a430 Add Serialize/Deserialize impls for Range{From,Full,To}
CC #796
CC #1466
CC #1713
2023-06-09 15:11:44 +02:00
David Tolnay 8a4dfa7231 Merge pull request #2466 from Mingun/fix-de-count-of-field
Fix incorrect count of fields passed to tuple deserialization methods
2023-06-07 22:13:08 -07:00
David Tolnay 107018c628 Release 1.0.164 2023-06-07 22:05:07 -07:00
David Tolnay a398237930 Point out serde(untagged) variants which are out of order
Previously if someone wrote an enum containing:

- `A` (untagged)
- `B` (tagged)
- `C` (tagged)
- `D` (untagged)
- `E` (tagged)
- `F` (untagged)

serde_derive would produce errors referring to B and E only, saying
you're supposed to put untagged variants at the end. The choice of B and
E for this error doesn't make a lot of sense because in order to resolve
the issue, the user must either:

- move A and D down

or:

- move B, C, and E up.

This commit changes the error to appear on A and D instead.
2023-06-07 21:49:30 -07:00
David Tolnay b63c65d7f5 Merge pull request #2470 from dtolnay/contentref
Reuse a single ContentRefDeserializer throughout untagged enum deserialization
2023-06-07 21:38:49 -07:00
David Tolnay f60324e883 Reuse a single ContentRefDeserializer throughout untagged enum deserialization 2023-06-07 21:33:14 -07:00
David Tolnay 361c23a09a Simplify enumerate().find(...) -> Iterator::position 2023-06-07 21:23:31 -07:00
David Tolnay 43b23c7ea0 Format PR 2403 with rustfmt 2023-06-07 21:18:30 -07:00
David Tolnay 6081497506 Resolve semicolon_if_nothing_returned pedantic clippy lint
error: consider adding a `;` to the last statement for consistent formatting
       --> serde_derive/src/internals/ast.rs:161:13
        |
    161 |             seen_untagged = variant.attrs.untagged()
        |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `seen_untagged = variant.attrs.untagged();`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
        = note: `-D clippy::semicolon-if-nothing-returned` implied by `-D clippy::pedantic`

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde_derive/src/internals/ast.rs:159:17
        |
    159 | ...   cx.error_spanned_by(&variant.ident, "all variants with the #[serde(untagged)] attribute must be placed at the end of the enum")
        |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `cx.error_spanned_by(&variant.ident, "all variants with the #[serde(untagged)] attribute must be placed at the end of the enum");`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
2023-06-07 21:17:24 -07:00
David Ewert 48e5753e76 Allowed Enum variants to be individually marked as untagged (#2403) 2023-06-07 20:58:59 -07:00
David Tolnay bbba632ab3 Revert "Ui tests with compile_error resolved at call site"
This reverts commit e77db40b8d.
2023-06-07 20:50:51 -07:00
David Tolnay e77db40b8d Ui tests with compile_error resolved at call site 2023-06-07 20:02:04 -07:00
Mingun 2c1f62d4b4 Fix incorrect count of fields passed to tuple deserialization methods
This count should mean the number of fields expected in the serialized form,
so if some fields are skipped, they shouldn't be counted

Methods affected:
- Deserializer::deserialize_tuple
- Deserializer::deserialize_tuple_struct
- VariantAccess::tuple_variant
2023-05-28 23:17:05 +05:00
David Tolnay 1aebdc2760 Release serde_derive_internals 0.28.0 2023-05-25 08:20:10 -07:00
David Tolnay 705e58be8c Merge pull request #2464 from serde-rs/combine
Use syn::Error's combine() API instead of Vec<syn::Error>
2023-05-25 08:19:16 -07:00
David Tolnay 7c2c12aa43 Use syn::Error's combine() API instead of Vec<syn::Error> 2023-05-25 08:10:14 -07:00
David Tolnay a0f850f15b Show error details during miri setup in CI
Without this, if it fails, the only information printed is useless:

    Preparing a sysroot for Miri (target: x86_64-unknown-linux-gnu)...
    fatal error: failed to build sysroot; run `cargo miri setup` to see the error details
2023-05-23 08:29:47 -07:00
David Tolnay fccb9499bc Release 1.0.163 2023-05-10 00:47:53 -07:00
David Tolnay a139ab2572 Adjust PR 2446 with less overgeneralized name 2023-05-10 00:45:52 -07:00
David Tolnay 1d910a484c Format with rustfmt 1.5.2-nightly 2023-05-10 00:40:39 -07:00
David Tolnay ee9166ec97 Revise comments on the FlatMapDeserializer entry taker 2023-05-10 00:39:10 -07:00
David Tolnay b5a9eff32e Resolve while_let_on_iterator clippy lint
warning: this loop could be written as a `for` loop
        --> serde/src/private/de.rs:2905:9
         |
    2905 |         while let Some(item) = self.iter.next() {
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for item in self.iter.by_ref()`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator
         = note: `#[warn(clippy::while_let_on_iterator)]` on by default
2023-05-10 00:23:38 -07:00
David Tolnay 9441a29663 Merge pull request #2446 from Mingun/dedup2
Eliminate some duplicated code
2023-05-10 00:13:44 -07:00
Mingun ab6588ef74 Extract duplicated code into a function 2023-05-08 10:39:30 +05:00
Mingun 1d11f03449 Extract logic of taking flattened fields into a function 2023-05-08 10:39:27 +05:00
Mingun e11d01fe1d Remove constructors for FlatMapAccess and FlatStructAccess
They are used only in one place each, so for simplifying understanding it is better to inline them
2023-05-08 09:40:06 +05:00
Mingun a901f50850 FlatMapAccess and FlatStructAccess does not need to be public 2023-05-08 09:37:15 +05:00
Mingun c399e9c368 Remove FlatInternallyTaggedAccess because it is the same as FlatMapAccess 2023-05-08 09:25:18 +05:00
David Tolnay 25381be0c9 Merge pull request #2442 from taiki-e/derive-build-script
Remove build script from serde_derive
2023-05-05 14:35:09 -07:00
Taiki Endo ef2a7c753f Remove build script from serde_derive
The current serde_derive's MSRV is 1.56, and both underscore consts and
ptr::addr_of! are always available.
2023-05-06 05:34:38 +09:00
David Tolnay 99f165b45a Release 1.0.162 2023-05-04 18:46:55 -07:00
David Tolnay 2fb5560746 Attempt to generate just one copy of TagContentOtherFieldVisitor's field matching 2023-05-04 18:42:21 -07:00
David Tolnay bd653ab30c Format PR 2377 with rustfmt 2023-05-04 18:42:21 -07:00
David Tolnay b5d68aedaa Merge pull request #2377 from mfro/master
Allow bytes for adjacently tagged enums
2023-05-04 18:39:57 -07:00
David Tolnay 624879c4c6 Merge pull request #2441 from dtolnay/test
Reimplement tests that touched serde_test internal API
2023-05-04 17:42:07 -07:00
David Tolnay bd9e9abf35 Reimplement tests that touched serde_test internal API 2023-05-04 17:38:58 -07:00
David Tolnay 3e4a23cbd0 Release 1.0.161 2023-05-04 16:45:18 -07:00
David Tolnay 6326ceec3f Don't panic in serde_test on running out of tokens 2023-05-04 16:38:20 -07:00
David Tolnay 8f4d37c7ec Convert serde_test's assert_next_token from macro to function 2023-05-04 16:34:14 -07:00
David Tolnay 1b8290b318 Convert serde_test's unexpected from macro to function 2023-05-04 16:30:34 -07:00
David Tolnay 48193fbccd Merge pull request #2435 from Mingun/hitchhiker-guide
Don't panic in serde_test
2023-05-04 16:27:35 -07:00
Mingun 51799dd654 Allow to flatten IgnoredAny to ignore any additional data
Although any additional fields in struct by default are ignored, sometimes
this can be useful, if you use generic structures, for example
2023-04-30 01:59:55 +05:00
Mingun 732ac49321 Implement PartialEq for IgnoredAny so it can be used in tests 2023-04-30 01:58:07 +05:00
Mingun ac8ea72d88 Don't panic in serde_test
Panics lead to reporting errors in tests inside of serde_test internals,
returning errors moves the report location to the corresponding assert_tokens
expression
2023-04-30 00:06:51 +05:00
David Tolnay f583401284 Merge pull request #2433 from Mingun/rm-gitattributes
Remove unused after .gitattributes
2023-04-26 12:04:04 -07:00
Mingun 2d88228b7d Remove unused after a649190a4d .gitattributes 2023-04-26 23:54:09 +05:00
David Tolnay 0c6a2bbf79 Release 1.0.160 2023-04-10 22:15:49 -07:00
David Tolnay a80d830f27 Merge pull request #2426 from compiler-errors/dont-doc-private
Make derived serializer/deserializer internals `doc(hidden)`
2023-04-10 22:12:35 -07:00
Michael Goulet 5f3fd9994e Make serializer/deserializer internals doc(hidden) 2023-04-10 21:41:50 -07:00
David Tolnay d6de911855 Release 1.0.159 2023-03-27 22:05:58 -07:00
David Tolnay 04af32230e Merge pull request #2422 from dtolnay/emptyattr
Accept empty #[serde()] attribute
2023-03-27 22:05:18 -07:00
David Tolnay 4cb8d079f8 Accept empty #[serde()] attribute 2023-03-27 22:00:46 -07:00
David Tolnay 6ab55a1e52 Add regression test for issue 2415
Currently fails:

    error: unexpected end of input, unexpected token in nested attribute, expected ident
     --> test_suite/tests/regression/issue2415.rs:4:9
      |
    4 | #[serde()]
      |         ^
2023-03-27 22:00:01 -07:00
David Tolnay acfd19cb46 Release serde_derive_internals 0.27.0 2023-03-20 04:32:49 -07:00
David Tolnay e3058105f0 Release 1.0.158 2023-03-20 04:24:27 -07:00
David Tolnay dc200a6450 Reformat comments of non-public serde_derive internals
Fixes these being treated as "tests" by `cargo test` in serde_derive:

    running 3 tests
    test src/internals/check.rs - internals::check::check_remote_generic (line 23) ... FAILED
    test src/internals/check.rs - internals::check::check_remote_generic (line 29) ... FAILED
    test src/lib.rs - (line 3) ... ok

    failures:

    ---- src/internals/check.rs - internals::check::check_remote_generic (line 23) stdout ----
    error: unknown start of token: \u{2026}
     --> src/internals/check.rs:25:20
      |
    4 | struct Generic<T> {…}
      |                    ^

    error: cannot find attribute `serde` in this scope
     --> src/internals/check.rs:24:3
      |
    3 | #[serde(remote = "Generic")]
      |   ^^^^^
      |
      = note: `serde` is in scope, but it is a crate, not an attribute

    error[E0392]: parameter `T` is never used
     --> src/internals/check.rs:25:16
      |
    4 | struct Generic<T> {…}
      |                ^ unused parameter
      |
      = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
      = help: if you intended `T` to be a const parameter, use `const T: usize` instead

    ---- src/internals/check.rs - internals::check::check_remote_generic (line 29) stdout ----
    error: unknown start of token: \u{2026}
     --> src/internals/check.rs:31:21
      |
    4 | struct ConcreteDef {…}
      |                     ^

    error: cannot find attribute `serde` in this scope
     --> src/internals/check.rs:30:3
      |
    3 | #[serde(remote = "Generic<T>")]
      |   ^^^^^
      |
      = note: `serde` is in scope, but it is a crate, not an attribute
2023-03-20 04:23:46 -07:00
David Tolnay 2c0999a0b9 Merge pull request #2410 from serde-rs/attrvalue
Check for None-delimited group in attribute value
2023-03-20 04:23:33 -07:00
David Tolnay dd460f82a1 Check for None-delimited group in attribute value 2023-03-20 04:16:52 -07:00
David Tolnay c3d637f397 Add regression test for issue 2409 2023-03-20 03:59:43 -07:00
David Tolnay 479a00a215 Release 1.0.157 2023-03-17 17:35:09 -07:00
David Tolnay c42e7c8012 Reflect serde_derive required compiler in build script and rust-version metadata 2023-03-17 17:34:46 -07:00
David Tolnay 5b8e0657d4 Ignore single_match_else pedantic clippy lint in serde_derive_internals
error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
        --> serde_derive_internals/src/attr.rs:1412:8
         |
    1412 |       Ok(match string.parse() {
         |  ________^
    1413 | |         Ok(path) => Some(path),
    1414 | |         Err(_) => {
    1415 | |             cx.error_spanned_by(
    ...    |
    1420 | |         }
    1421 | |     })
         | |_____^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else
         = note: `-D clippy::single-match-else` implied by `-D clippy::pedantic`
    help: try this
         |
    1412 ~     Ok(if let Ok(path) = string.parse() { Some(path) } else {
    1413 +         cx.error_spanned_by(
    1414 +             &string,
    1415 +             format!("failed to parse path: {:?}", string.value()),
    1416 +         );
    1417 +         None
    1418 ~     })
         |

    error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
        --> serde_derive_internals/src/attr.rs:1434:8
         |
    1434 |       Ok(match string.parse() {
         |  ________^
    1435 | |         Ok(expr) => Some(expr),
    1436 | |         Err(_) => {
    1437 | |             cx.error_spanned_by(
    ...    |
    1442 | |         }
    1443 | |     })
         | |_____^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else
    help: try this
         |
    1434 ~     Ok(if let Ok(expr) = string.parse() { Some(expr) } else {
    1435 +         cx.error_spanned_by(
    1436 +             &string,
    1437 +             format!("failed to parse path: {:?}", string.value()),
    1438 +         );
    1439 +         None
    1440 ~     })
         |

    error: you seem to be trying to use `match` for destructuring a single pattern. Consider using `if let`
        --> serde_derive_internals/src/attr.rs:1478:8
         |
    1478 |       Ok(match string.parse() {
         |  ________^
    1479 | |         Ok(ty) => Some(ty),
    1480 | |         Err(_) => {
    1481 | |             cx.error_spanned_by(
    ...    |
    1486 | |         }
    1487 | |     })
         | |_____^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#single_match_else
    help: try this
         |
    1478 ~     Ok(if let Ok(ty) = string.parse() { Some(ty) } else {
    1479 +         cx.error_spanned_by(
    1480 +             &string,
    1481 +             format!("failed to parse type: {} = {:?}", attr_name, string.value()),
    1482 +         );
    1483 +         None
    1484 ~     })
         |
2023-03-17 17:32:50 -07:00
David Tolnay 9fc0d13e2c Merge pull request #2406 from dtolnay/nestedmeta
Rewrite attribute parser using parse_nested_meta
2023-03-17 17:32:39 -07:00
David Tolnay bc22641359 Rewrite attribute parser using parse_nested_meta 2023-03-17 17:23:56 -07:00
David Tolnay 05098105a8 Update compiler version for serde_derive in readme 2023-03-17 17:23:33 -07:00
David Tolnay 5b23634dc6 Merge pull request #2405 from dtolnay/syn
Update to syn 2
2023-03-17 17:23:20 -07:00
David Tolnay 32f0d00ff9 Update to syn 2 2023-03-17 17:17:40 -07:00
David Tolnay 9d87851f0c Merge pull request #2404 from dtolnay/attributeexpr
Add ui test of malformed attribute containing expression
2023-03-17 17:14:54 -07:00
David Tolnay c0296ee11b Add ui test of malformed attribute containing expression 2023-03-16 00:15:54 -07:00
David Tolnay 54671259aa Release 1.0.156 2023-03-14 01:02:18 -07:00
David Tolnay 994f7c7924 Format with rustfmt 1.5.2-nightly 2023-03-14 00:50:38 -07:00
David Tolnay 7a8e4977e2 Merge pull request #2401 from dtolnay/docderive
Show derive macros in serde's rustdoc
2023-03-14 00:37:06 -07:00
David Tolnay fb7b6ea7ea Enable serde derive feature when built by docs.rs 2023-03-14 00:33:41 -07:00
David Tolnay 063dd5b93f Show derive macros in serde's rustdoc 2023-03-14 00:28:20 -07:00
David Tolnay a38aa31ade Merge pull request #2400 from Nilstrieb/explicit-reexport
Use explicit re-export of `serde_derive` to give rustc more info
2023-03-14 00:26:01 -07:00
nils f42b2581da Use explicit re-export of serde_derive to give rustc more info
rustc will start looking behind `#[cfg(FALSE)]` items to start giving
better diagnostics. By using an explicit re-export instead of a glob
export, we tell rustc that `Deserialize` and `Serialize` exist here.
2023-03-14 08:11:38 +01:00
David Tolnay 2ba406726f Release 1.0.155 2023-03-11 12:57:53 -08:00
David Tolnay 7e9826e17b Add link to core CStr stabilization announcement 2023-03-11 12:57:16 -08:00
David Tolnay f4dcc5c918 Merge pull request #2374 from safarir/master
Enable CStr and CString in no-std enviroment
2023-03-11 12:55:49 -08:00
David Tolnay 8b1887c440 Remove unneeded attr_name argument when parsing borrow attr 2023-03-11 11:35:03 -08:00
David Tolnay bbfb1d3504 Merge pull request #2399 from dtolnay/borrow
Eagerly parse variant-level borrow attribute instead of deferring entire Meta
2023-03-11 11:29:55 -08:00
David Tolnay e106feb5ec Eagerly parse variant-level borrow attribute instead of deferring entire Meta 2023-03-11 11:25:00 -08:00
David Tolnay 696f6f56db Merge pull request #2398 from dtolnay/borrow
Treat field-level borrow attr as duplicate of variant-level borrow attr
2023-03-11 11:24:50 -08:00
David Tolnay b7b636a23f Treat field-level borrow attr as duplicate of variant-level borrow attr 2023-03-11 11:17:40 -08:00
David Tolnay 183b91775e Fix some comments in parsing of from/try_from/into attributes 2023-03-10 14:16:11 -08:00
David Tolnay 0e70f59021 Merge pull request #2396 from dtolnay/msg
Rearrange parts of attr.rs that rustfmt has been refusing to format
2023-03-09 20:29:50 -08:00
David Tolnay 4d9b76db73 Rearrange parts of attr.rs that rustfmt has been refusing to format 2023-03-09 20:17:43 -08:00
David Tolnay 9af132f594 Factor out duplicated error messages into reused variable 2023-03-09 20:17:20 -08:00
David Tolnay 6c063569c0 Eliminate closure from Punctuated to Vec conversion 2023-03-09 00:43:33 -08:00
David Tolnay 7e9b98401d Merge pull request #2395 from dtolnay/parsewhere
Simplify parsing of where-predicates in bound attribute
2023-03-09 00:38:57 -08:00
David Tolnay f301e09e02 Simplify parsing of where-predicates in bound attribute 2023-03-09 00:20:51 -08:00
David Tolnay b80e722f81 Merge pull request #2394 from dtolnay/emptybound
Eliminate special case on empty string passed to bound=""
2023-03-08 19:53:07 -08:00
David Tolnay 1714c262c4 Eliminate special case on empty string passed to bound=""
This works just fine if we make syn parse "where " as a syn::WhereClause.

The serde(bound = "") attribute is definitely not common enough that it
would warrant a micro-optimization.
2023-03-08 19:20:06 -08:00
David Tolnay a42cdafdcd Merge pull request #2393 from dtolnay/testbound
Add a test of serde(bound = "") attribute
2023-03-08 19:19:59 -08:00
David Tolnay eb4c3f16f7 Add a test of serde(bound = "") attribute
Without serde(bound = ""), serde_derive infers a bound of `T: Serialize`
for the generated Serialize impl and `T: Deserialize<'de> + Default` for
the Deserialize impl. `X` implements none of these so the generated code
would fail to compile.

    error[E0277]: the trait bound `X: Serialize` is not satisfied
       --> test_suite/tests/test_gen.rs:268:14
        |
    268 |     assert::<PhantomDataWrapper<X>>();
        |              ^^^^^^^^^^^^^^^^^^^^^ the trait `Serialize` is not implemented for `X`
        |
        = help: the following other types implement trait `Serialize`:
                  &'a T
                  &'a mut T
                  ()
                  (T0, T1)
                  (T0, T1, T2)
                  (T0, T1, T2, T3)
                  (T0, T1, T2, T3, T4)
                  (T0, T1, T2, T3, T4, T5)
                and 248 others
    note: required for `PhantomDataWrapper<X>` to implement `Serialize`
       --> test_suite/tests/test_gen.rs:262:14
        |
    262 |     #[derive(Serialize, Deserialize)]
        |              ^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
    263 |     //#[serde(bound = "")]
    264 |     struct PhantomDataWrapper<T> {
        |            ^^^^^^^^^^^^^^^^^^^^^
    note: required by a bound in `assert`
       --> test_suite/tests/test_gen.rs:767:14
        |
    767 | fn assert<T: Serialize + DeserializeOwned>() {}
        |              ^^^^^^^^^ required by this bound in `assert`
        = note: this error originates in the derive macro `Serialize` (in Nightly builds, run with -Z macro-backtrace for more info)

    error[E0277]: the trait bound `X: Deserialize<'_>` is not satisfied
       --> test_suite/tests/test_gen.rs:268:14
        |
    268 |     assert::<PhantomDataWrapper<X>>();
        |              ^^^^^^^^^^^^^^^^^^^^^ the trait `Deserialize<'_>` is not implemented for `X`
        |
        = help: the following other types implement trait `Deserialize<'de>`:
                  <&'a Path as Deserialize<'de>>
                  <&'a [u8] as Deserialize<'de>>
                  <&'a str as Deserialize<'de>>
                  <() as Deserialize<'de>>
                  <(T0, T1) as Deserialize<'de>>
                  <(T0, T1, T2) as Deserialize<'de>>
                  <(T0, T1, T2, T3) as Deserialize<'de>>
                  <(T0, T1, T2, T3, T4) as Deserialize<'de>>
                and 331 others
    note: required for `PhantomDataWrapper<X>` to implement `for<'de> Deserialize<'de>`
       --> test_suite/tests/test_gen.rs:262:25
        |
    262 |     #[derive(Serialize, Deserialize)]
        |                         ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
    263 |     //#[serde(bound = "")]
    264 |     struct PhantomDataWrapper<T> {
        |            ^^^^^^^^^^^^^^^^^^^^^
        = note: required for `PhantomDataWrapper<X>` to implement `DeserializeOwned`
    note: required by a bound in `assert`
       --> test_suite/tests/test_gen.rs:767:26
        |
    767 | fn assert<T: Serialize + DeserializeOwned>() {}
        |                          ^^^^^^^^^^^^^^^^ required by this bound in `assert`
        = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)

    error[E0277]: the trait bound `X: Default` is not satisfied
       --> test_suite/tests/test_gen.rs:268:14
        |
    268 |     assert::<PhantomDataWrapper<X>>();
        |              ^^^^^^^^^^^^^^^^^^^^^ the trait `Default` is not implemented for `X`
        |
    note: required for `PhantomDataWrapper<X>` to implement `for<'de> Deserialize<'de>`
       --> test_suite/tests/test_gen.rs:262:25
        |
    262 |     #[derive(Serialize, Deserialize)]
        |                         ^^^^^^^^^^^ unsatisfied trait bound introduced in this `derive` macro
    263 |     //#[serde(bound = "")]
    264 |     struct PhantomDataWrapper<T> {
        |            ^^^^^^^^^^^^^^^^^^^^^
        = note: required for `PhantomDataWrapper<X>` to implement `DeserializeOwned`
    note: required by a bound in `assert`
       --> test_suite/tests/test_gen.rs:767:26
        |
    767 | fn assert<T: Serialize + DeserializeOwned>() {}
        |                          ^^^^^^^^^^^^^^^^ required by this bound in `assert`
        = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
    help: consider annotating `X` with `#[derive(Default)]`
        |
    779 | #[derive(Default)]
        |
2023-03-08 19:11:25 -08:00
David Tolnay ce86f351d6 Make a directory dedicated to regression tests
I have had a good experience with this pattern in many of my other
libraries.
2023-03-08 19:02:42 -08:00
David Tolnay 0b90f6c96a Remove the need for allow(dead_code) added by PR 2383 2023-03-08 18:59:56 -08:00
David Tolnay 2198463218 Merge pull request #2392 from dtolnay/emptylifetimes
Eliminate special case on empty string passed to borrow=""
2023-03-08 18:55:51 -08:00
David Tolnay be57a5e00a Eliminate special case on empty string passed to borrow="" 2023-03-08 18:50:19 -08:00
David Tolnay b1b09eba60 Add ui test with nonempty string containing no lifetimes 2023-03-08 18:49:59 -08:00
David Tolnay eb1e8c140d Merge pull request #2391 from dtolnay/parselifetimes
Simplify parsing of borrow="..." attributes
2023-03-08 18:44:57 -08:00
David Tolnay 43da87939d Simplify parsing of borrow="..." attributes 2023-03-08 18:38:12 -08:00
David Tolnay 06d99a13a6 Merge pull request #2390 from dtolnay/litstrparse
Replace serde_derive_internal's parse_lit_str with syn::LitStr::parse
2023-03-08 18:30:18 -08:00
David Tolnay 49a911d7de Replace serde_derive_internal's parse_lit_str with syn::LitStr::parse 2023-03-08 18:23:35 -08:00
David Tolnay 27d6628785 Refer to syn's parse result via syn instead of parse module 2023-03-08 18:20:30 -08:00
David Tolnay e4e2956e79 Handle repr attribute consistently with every other serde attribute 2023-03-08 13:57:43 -08:00
David Tolnay ea2f7b81d9 Sort symbol list in alphabetical order
PR 1916 put EXPECTING at the end instead of in order.
2023-03-08 13:14:45 -08:00
David Tolnay f0dfdb5247 Resolve wildcard_imports pedantic clippy lint in test suite
error: usage of wildcard import
       --> test_suite/tests/test_gen.rs:901:9
        |
    901 |     use super::*;
        |         ^^^^^^^^ help: try: `super::Deserialize`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#wildcard_imports
        = note: `-D clippy::wildcard-imports` implied by `-D clippy::pedantic`
2023-03-08 12:14:04 -08:00
David Tolnay 6a5da85fcd Release 1.0.154 2023-03-08 12:09:05 -08:00
David Tolnay 0750eee4ff Merge pull request #2383 from Mingun/fix-flatten+static
Fix generation of non-existent lifetime `'de` when enum contains a #[serde(flatten)] field and a `'static` reference
2023-03-08 12:05:41 -08:00
David Tolnay ef551a517c Merge pull request #2389 from dtolnay/trimstart
Replace use of deprecated trim_left_matches with trim_start_matches
2023-03-08 12:00:34 -08:00
David Tolnay 1c5ea24f76 Replace use of deprecated trim_left_matches with trim_start_matches 2023-03-08 11:54:44 -08:00
David Tolnay 88d73e5250 Format PR 2387 with rustfmt 2023-03-08 11:54:28 -08:00
David Tolnay 1ff2a972c6 Merge pull request #2388 from serde-rs/exhaustivepatterns
Update the comment on simpler exhaustive matching in derive
2023-03-08 11:53:45 -08:00
David Tolnay bb72fe2726 Update the comment on simpler exhaustive matching in derive 2023-03-08 11:46:26 -08:00
David Tolnay e50b14afee Release 1.0.153 2023-03-07 10:50:02 -08:00
David Tolnay cbd1cbef07 Merge pull request #2387 from bebecue/fix-1504
Make #[serde(alias)] works in #[serde(flatten)] context
2023-03-07 10:48:38 -08:00
bebecue 01da3f79c9 Add tests for #2387 2023-03-07 08:09:01 +08:00
bebecue f5e0fbcb14 Make #[serde(alias)] works in #[serde(flatten)] context
fix #1504
2023-03-05 15:14:51 +08:00
Mingun 38c130a303 Do not generate DeserializeSeed impl when not needed
This function is called for untagged, internally and externally tagged enums,
but `deserializer` parameter is `None` only for the latest. Only when it's `None`
`DeserializeSeed` impl is used
2023-02-27 21:08:30 +05:00
Mingun c7393614ff Fix generation of non-existent lifetime 'de when enum contains a #[serde(flatten)] field and a 'static reference 2023-02-27 21:03:34 +05:00
David Tolnay a13c6382b6 Ignore let_underscore_untyped pedantic clippy lint
error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:157:5
        |
    157 | /     forward_to_deserialize_any! {
    158 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    159 | |         bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct
    160 | |         map struct enum identifier ignored_any
    161 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: `-D clippy::let-underscore-untyped` implied by `-D clippy::pedantic`
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:157:5
        |
    157 | /     forward_to_deserialize_any! {
    158 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    159 | |         bytes byte_buf unit unit_struct newtype_struct seq tuple tuple_struct
    160 | |         map struct enum identifier ignored_any
    161 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:219:5
        |
    219 | /     forward_to_deserialize_any! {
    220 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    221 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    222 | |         tuple_struct map struct enum identifier ignored_any
    223 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:291:1
        |
    291 | primitive_deserializer!(bool, "a `bool`.", BoolDeserializer, visit_bool);
        | ------------------------------------------------------------------------ in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:292:1
        |
    292 | primitive_deserializer!(i8, "an `i8`.", I8Deserializer, visit_i8);
        | ----------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:293:1
        |
    293 | primitive_deserializer!(i16, "an `i16`.", I16Deserializer, visit_i16);
        | --------------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:294:1
        |
    294 | primitive_deserializer!(i32, "an `i32`.", I32Deserializer, visit_i32);
        | --------------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:295:1
        |
    295 | primitive_deserializer!(i64, "an `i64`.", I64Deserializer, visit_i64);
        | --------------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:296:1
        |
    296 | primitive_deserializer!(isize, "an `isize`.", IsizeDeserializer, visit_i64 as i64);
        | ---------------------------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:297:1
        |
    297 | primitive_deserializer!(u8, "a `u8`.", U8Deserializer, visit_u8);
        | ---------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:298:1
        |
    298 | primitive_deserializer!(u16, "a `u16`.", U16Deserializer, visit_u16);
        | -------------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:299:1
        |
    299 | primitive_deserializer!(u64, "a `u64`.", U64Deserializer, visit_u64);
        | -------------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:300:1
        |
    300 | primitive_deserializer!(usize, "a `usize`.", UsizeDeserializer, visit_u64 as u64);
        | --------------------------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:301:1
        |
    301 | primitive_deserializer!(f32, "an `f32`.", F32Deserializer, visit_f32);
        | --------------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:302:1
        |
    302 | primitive_deserializer!(f64, "an `f64`.", F64Deserializer, visit_f64);
        | --------------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:303:1
        |
    303 | primitive_deserializer!(char, "a `char`.", CharDeserializer, visit_char);
        | ------------------------------------------------------------------------ in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:306:5
        |
    306 |     primitive_deserializer!(i128, "an `i128`.", I128Deserializer, visit_i128);
        |     ------------------------------------------------------------------------- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                 let _ = $arg;
        |                 ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:307:5
        |
    307 |     primitive_deserializer!(u128, "a `u128`.", U128Deserializer, visit_u128);
        |     ------------------------------------------------------------------------ in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `primitive_deserializer` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:345:5
        |
    345 | /     forward_to_deserialize_any! {
    346 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    347 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    348 | |         tuple_struct map struct identifier ignored_any
    349 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/de/value.rs:367:9
        |
    367 |         let _ = name;
        |         ^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/value.rs:368:9
        |
    368 |         let _ = variants;
        |         ^^^^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/value.rs:450:9
        |
    450 |         let _ = name;
        |         ^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/value.rs:451:9
        |
    451 |         let _ = variants;
        |         ^^^^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:455:5
        |
    455 | /     forward_to_deserialize_any! {
    456 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    457 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    458 | |         tuple_struct map struct identifier ignored_any
    459 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/de/value.rs:529:9
        |
    529 |         let _ = name;
        |         ^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/value.rs:530:9
        |
    530 |         let _ = variants;
        |         ^^^^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:534:5
        |
    534 | /     forward_to_deserialize_any! {
    535 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    536 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    537 | |         tuple_struct map struct identifier ignored_any
    538 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/de/value.rs:630:9
        |
    630 |         let _ = name;
        |         ^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/value.rs:631:9
        |
    631 |         let _ = variants;
        |         ^^^^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:635:5
        |
    635 | /     forward_to_deserialize_any! {
    636 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    637 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    638 | |         tuple_struct map struct identifier ignored_any
    639 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/de/value.rs:736:9
        |
    736 |         let _ = name;
        |         ^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/value.rs:737:9
        |
    737 |         let _ = variants;
        |         ^^^^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:741:5
        |
    741 | /     forward_to_deserialize_any! {
    742 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    743 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    744 | |         tuple_struct map struct identifier ignored_any
    745 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:818:5
        |
    818 | /     forward_to_deserialize_any! {
    819 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    820 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    821 | |         tuple_struct map struct enum identifier ignored_any
    822 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:866:5
        |
    866 | /     forward_to_deserialize_any! {
    867 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    868 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    869 | |         tuple_struct map struct enum identifier ignored_any
    870 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/de/value.rs:945:5
        |
    945 | /     forward_to_deserialize_any! {
    946 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    947 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    948 | |         tuple_struct map struct enum identifier ignored_any
    949 | |     }
        | |_____- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/de/value.rs:1073:5
         |
    1073 | /     forward_to_deserialize_any! {
    1074 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    1075 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    1076 | |         tuple_struct map struct enum identifier ignored_any
    1077 | |     }
         | |_____- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/de/value.rs:1183:9
         |
    1183 |         let _ = len;
         |         ^^^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/de/value.rs:1187:5
         |
    1187 | /     forward_to_deserialize_any! {
    1188 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    1189 | |         bytes byte_buf option unit unit_struct newtype_struct tuple_struct map
    1190 | |         struct enum identifier ignored_any
    1191 | |     }
         | |_____- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/de/value.rs:1326:5
         |
    1326 | /     forward_to_deserialize_any! {
    1327 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    1328 | |         bytes byte_buf option unit unit_struct newtype_struct tuple_struct map
    1329 | |         struct enum identifier ignored_any
    1330 | |     }
         | |_____- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/de/value.rs:1486:5
         |
    1486 | /     forward_to_deserialize_any! {
    1487 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    1488 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    1489 | |         tuple_struct map struct identifier ignored_any
    1490 | |     }
         | |_____- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/de/value.rs:1539:5
         |
    1539 | /     forward_to_deserialize_any! {
    1540 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    1541 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    1542 | |         tuple_struct map struct enum identifier ignored_any
    1543 | |     }
         | |_____- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde/src/de/ignored_any.rs:123:9
        |
    123 |         let _ = x;
        |         ^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/ignored_any.rs:129:9
        |
    129 |         let _ = x;
        |         ^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/ignored_any.rs:136:13
        |
    136 |             let _ = x;
        |             ^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/ignored_any.rs:143:9
        |
    143 |         let _ = x;
        |         ^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/ignored_any.rs:150:13
        |
    150 |             let _ = x;
        |             ^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/ignored_any.rs:157:9
        |
    157 |         let _ = x;
        |         ^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/ignored_any.rs:166:9
        |
    166 |         let _ = s;
        |         ^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/ignored_any.rs:223:9
        |
    223 |         let _ = bytes;
        |         ^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/mod.rs:957:13
        |
    957 |             let _ = visitor;
        |             ^^^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/de/mod.rs:991:13
        |
    991 |             let _ = visitor;
        |             ^^^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/de/mod.rs:1554:9
         |
    1554 |         let _ = v;
         |         ^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/de/mod.rs:1615:9
         |
    1615 |         let _ = deserializer;
         |         ^^^^^^^^^^^^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/de/mod.rs:1639:9
         |
    1639 |         let _ = deserializer;
         |         ^^^^^^^^^^^^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/de/mod.rs:1650:9
         |
    1650 |         let _ = seq;
         |         ^^^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/de/mod.rs:1661:9
         |
    1661 |         let _ = map;
         |         ^^^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/de/mod.rs:1672:9
         |
    1672 |         let _ = data;
         |         ^^^^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
      --> serde/src/ser/impossible.rs:79:9
       |
    79 |         let _ = value;
       |         ^^^^^^^^^^^^^^
       |
       = help: consider adding a type annotation or removing the `let` keyword
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
      --> serde/src/ser/impossible.rs:99:9
       |
    99 |         let _ = value;
       |         ^^^^^^^^^^^^^^
       |
       = help: consider adding a type annotation or removing the `let` keyword
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/ser/impossible.rs:119:9
        |
    119 |         let _ = value;
        |         ^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/ser/impossible.rs:139:9
        |
    139 |         let _ = value;
        |         ^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/ser/impossible.rs:159:9
        |
    159 |         let _ = key;
        |         ^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/ser/impossible.rs:167:9
        |
    167 |         let _ = value;
        |         ^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/ser/impossible.rs:187:9
        |
    187 |         let _ = key;
        |         ^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/ser/impossible.rs:188:9
        |
    188 |         let _ = value;
        |         ^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/ser/impossible.rs:208:9
        |
    208 |         let _ = key;
        |         ^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/ser/impossible.rs:209:9
        |
    209 |         let _ = value;
        |         ^^^^^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/ser/mod.rs:512:13
        |
    512 |             let _ = v;
        |             ^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/ser/mod.rs:622:13
        |
    622 |             let _ = v;
        |             ^^^^^^^^^^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/ser/mod.rs:1906:9
         |
    1906 |         let _ = key;
         |         ^^^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/ser/mod.rs:1972:9
         |
    1972 |         let _ = key;
         |         ^^^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
       --> serde/src/macros.rs:132:17
        |
    132 |                   let _ = $arg;
        |                   ^^^^^^^^^^^^^
        |
       ::: serde/src/private/de.rs:47:9
        |
    47  | /         forward_to_deserialize_any! {
    48  | |             bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    49  | |             bytes byte_buf unit unit_struct newtype_struct seq tuple
    50  | |             tuple_struct map struct enum identifier ignored_any
    51  | |         }
        | |_________- in this macro invocation
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/private/de.rs:1451:13
         |
    1451 |             let _ = visitor;
         |             ^^^^^^^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/private/de.rs:1633:9
         |
    1633 | /         forward_to_deserialize_any! {
    1634 | |             bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    1635 | |             bytes byte_buf option unit unit_struct newtype_struct seq tuple
    1636 | |             tuple_struct map struct enum identifier ignored_any
    1637 | |         }
         | |_________- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/private/de.rs:1731:9
         |
    1731 | /         forward_to_deserialize_any! {
    1732 | |             bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    1733 | |             bytes byte_buf option unit unit_struct newtype_struct seq tuple
    1734 | |             tuple_struct map struct enum identifier ignored_any
    1735 | |         }
         | |_________- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/private/de.rs:2174:13
         |
    2174 |             let _ = visitor;
         |             ^^^^^^^^^^^^^^^^
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/private/de.rs:2343:9
         |
    2343 | /         forward_to_deserialize_any! {
    2344 | |             bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    2345 | |             bytes byte_buf option unit unit_struct newtype_struct seq tuple
    2346 | |             tuple_struct map struct enum identifier ignored_any
    2347 | |         }
         | |_________- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/private/de.rs:2443:9
         |
    2443 | /         forward_to_deserialize_any! {
    2444 | |             bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    2445 | |             bytes byte_buf option unit unit_struct newtype_struct seq tuple
    2446 | |             tuple_struct map struct enum identifier ignored_any
    2447 | |         }
         | |_________- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/private/de.rs:2611:5
         |
    2611 | /     forward_to_deserialize_any! {
    2612 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    2613 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    2614 | |         tuple_struct map struct enum identifier ignored_any
    2615 | |     }
         | |_____- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
        --> serde/src/macros.rs:132:17
         |
    132  |                   let _ = $arg;
         |                   ^^^^^^^^^^^^^
         |
        ::: serde/src/private/de.rs:2636:5
         |
    2636 | /     forward_to_deserialize_any! {
    2637 | |         bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
    2638 | |         bytes byte_buf option unit unit_struct newtype_struct seq tuple
    2639 | |         tuple_struct map struct enum identifier ignored_any
    2640 | |     }
         | |_____- in this macro invocation
         |
         = help: consider adding a type annotation or removing the `let` keyword
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
         = note: this error originates in the macro `forward_to_deserialize_any_method` which comes from the expansion of the macro `forward_to_deserialize_any` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: non-binding `let` without a type annotation
       --> serde_derive/src/internals/attr.rs:591:17
        |
    591 | /                 let _ = attr.parse_args_with(|input: ParseStream| {
    592 | |                     while let Some(token) = input.parse()? {
    593 | |                         if let TokenTree::Ident(ident) = token {
    594 | |                             is_packed |= ident == "packed";
    ...   |
    597 | |                     Ok(())
    598 | |                 });
        | |___________________^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: `-D clippy::let-underscore-untyped` implied by `-D clippy::pedantic`

    error: non-binding `let` without a type annotation
       --> serde_derive_internals/src/attr.rs:591:17
        |
    591 | /                 let _ = attr.parse_args_with(|input: ParseStream| {
    592 | |                     while let Some(token) = input.parse()? {
    593 | |                         if let TokenTree::Ident(ident) = token {
    594 | |                             is_packed |= ident == "packed";
    ...   |
    597 | |                     Ok(())
    598 | |                 });
        | |___________________^
        |
        = help: consider adding a type annotation or removing the `let` keyword
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_untyped
        = note: `-D clippy::let-underscore-untyped` implied by `-D clippy::pedantic`
2023-02-26 23:08:38 -07:00
Max Froehlich a803ec1c1f Allow bytes for adjantly tagged enums 2023-02-18 12:49:23 -08:00
Charles-Xavier Roy f7636428ed Add check for rust version 2023-02-17 16:25:16 -05:00
David Tolnay f85c4f2fa9 Delete unused toolchain_find dependency
Unused since bac90d19b9.
2023-02-10 19:29:34 -08:00
David Tolnay a9a9903107 Ignore extra_unused_type_parameters clippy lint in test
error: type parameter goes unused in function definition
       --> test_suite/tests/test_gen.rs:756:10
        |
    756 | fn assert<T: Serialize + DeserializeOwned>() {}
        |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: consider removing the parameter
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_type_parameters
        = note: `-D clippy::extra-unused-type-parameters` implied by `-D clippy::all`

    error: type parameter goes unused in function definition
       --> test_suite/tests/test_gen.rs:757:14
        |
    757 | fn assert_ser<T: Serialize>() {}
        |              ^^^^^^^^^^^^^^
        |
        = help: consider removing the parameter
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_type_parameters

    error: type parameter goes unused in function definition
      --> test_suite/tests/test_serde_path.rs:20:18
       |
    20 |     pub fn assert<T>()
       |                  ^^^
       |
       = help: consider removing the parameter
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_type_parameters
       = note: `-D clippy::extra-unused-type-parameters` implied by `-D clippy::all`
2023-02-10 19:14:43 -08:00
Charles-Xavier Roy bd4a0981ba Enable CStr and CString in no-std enviroment 2023-02-10 09:05:24 -05:00
David Tolnay 35e5cf3e15 Revert uninlined_format_args change in test
I no longer believe in clippy's pedantic recommendation on this.
2023-02-02 11:04:23 -08:00
David Tolnay 07fc9f689e Replace serialize_str+format -> collect_str+format_args 2023-02-02 10:50:34 -08:00
David Tolnay 14b0e18c57 Delete deny(unaligned_references) from test
warning: lint `unaligned_references` has been removed: converted into hard error, see issue #82523 <https://github.com/rust-lang/rust/issues/82523> for more information
        --> test_suite/tests/test_macros.rs:1931:8
         |
    1931 | #[deny(unaligned_references)]
         |        ^^^^^^^^^^^^^^^^^^^^
         |
         = note: `#[warn(renamed_and_removed_lints)]` on by default
2023-02-01 19:06:06 -08:00
David Tolnay dd27ec8703 Update ui test suite to nightly-2023-02-01 2023-01-31 19:19:53 -08:00
David Tolnay db3f00c3b3 Delete Emscripten CI
I don't think this build has ever worked.
It was added with `continue-on-error: true` right from the beginning
in https://github.com/serde-rs/serde/commit/5534bf4df13ae00a82aef0db0ee62cb17b33b892

That's been that way since the Travis CI days:
https://github.com/serde-rs/serde/commit/820107d15e6ffbfb0f7257653f8889cb8f2dc452

All recent builds have been failing with:

    error: linking with `emcc` failed: exit status: 1
      |
      = note: LC_ALL="C" PATH="/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/bin:/home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten:/opt/hostedtoolcache/node/9.11.2/x64/bin:/home/runner/.local/bin:/opt/pipx_bin:/home/runner/.cargo/bin:/home/runner/.config/composer/vendor/bin:/usr/local/.ghcup/bin:/home/runner/.dotnet/tools:/snap/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin" VSLANG="1033" "emcc" "-s" "EXPORTED_FUNCTIONS=[\"_main\"]" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.0.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.1.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.10.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.11.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.12.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.13.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.14.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.15.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.2.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.3.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.4.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.5.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.6.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.7.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.8.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.9.rcgu.o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.223vlrckyyi933ss.rcgu.o" "-L" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps" "-L" "/home/runner/work/serde/serde/target/debug/deps" "-L" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libtest-703577d2eeee5197.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libgetopts-f807ec4fb7e4e629.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libunicode_width-2225b28b6ec8c285.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/librustc_std_workspace_std-dd938caf8b49e472.rlib" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/libserde_test-001fc721a1bcc02c.rlib" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/libserde-37bd5f92207a3513.rlib" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/libfnv-0de3dbe391b66872.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libstd-1c8c16cd3fa53a03.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libpanic_unwind-867e5756a7547a66.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/librustc_demangle-da6ab903fe654069.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libstd_detect-835d918597331757.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libhashbrown-4f9cd32598223563.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libminiz_oxide-d0c628945bd9d914.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libadler-7a585625ea89f61a.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/librustc_std_workspace_alloc-aaebf0a065426c59.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libunwind-72125d94c0136926.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libcfg_if-8ab4a22614237c52.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/liblibc-f05314f278f4c449.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/liballoc-2163dfc98c888d9f.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/librustc_std_workspace_core-dc02b3faf448d54f.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libcore-f5d84c0c974a0cba.rlib" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib/libcompiler_builtins-556bf6604acc2e72.rlib" "-l" "c" "-s" "DISABLE_EXCEPTION_CATCHING=0" "-L" "/home/runner/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/asmjs-unknown-emscripten/lib" "-o" "/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.js" "-O0" "-g" "-s" "NO_EXIT_RUNTIME=0" "-s" "ALLOW_MEMORY_GROWTH=0" "-sABORTING_MALLOC=0" "-Wl,--fatal-warnings" "-sWASM=0" "--memory-init-file" "0"
      = note: /home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten/emcc.py:812: SyntaxWarning: "is not" with a literal. Did you mean "!="?
                newargs = [arg for arg in newargs if arg is not '']
              /home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten/emcc.py:923: SyntaxWarning: "is not" with a literal. Did you mean "!="?
                newargs = [a for a in newargs if a is not '']
              INFO:root:generating system asset: is_vanilla.txt... (this will be cached in "/home/runner/.emscripten_cache/is_vanilla.txt" for subsequent builds)
              INFO:root: - ok
              INFO:root:(Emscripten: Running sanity checks)
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.0.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.1.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.10.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.11.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.12.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.13.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.14.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.15.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.2.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.3.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.4.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.5.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.6.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.7.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.8.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.test_ser.946ae949-cgu.9.rcgu.o is not valid LLVM bitcode
              WARNING:root:/home/runner/work/serde/serde/target/asmjs-unknown-emscripten/debug/deps/test_ser-e9fdefc835cae810.223vlrckyyi933ss.rcgu.o is not valid LLVM bitcode
              WARNING:root:retrieving port: binaryen from https://github.com/WebAssembly/binaryen/archive/version_54.zip
              WARNING:root:unpacking port: binaryen
              INFO:root:generating port: binaryen_tag_version_54.txt... (this will be cached in "/home/runner/.emscripten_cache/asmjs/binaryen_tag_version_54.txt" for subsequent builds)
              INFO:root:building port: binaryen
              CMake Deprecation Warning at CMakeLists.txt:2 (CMAKE_MINIMUM_REQUIRED):
                Compatibility with CMake < 2.8.12 will be removed from a future version of
                CMake.

                Update the VERSION argument <min> value or use a ...<max> suffix to tell
                CMake that the project does not need compatibility with older versions.

              INFO:root: - ok
              multiprocessing.pool.RemoteTraceback:
              """
              Traceback (most recent call last):
                File "/usr/lib/python3.10/multiprocessing/pool.py", line 125, in worker
                  result = (True, func(*args, **kwds))
                File "/usr/lib/python3.10/multiprocessing/pool.py", line 48, in mapstar
                  return list(map(*args))
                File "/home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten/tools/shared.py", line 1425, in g_llvm_nm_uncached
                  return Building.llvm_nm_uncached(filename)
                File "/home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten/tools/shared.py", line 2226, in llvm_nm_uncached
                  proc = run_process([LLVM_NM, filename], stdout=stdout, stderr=stderr, check=False)
                File "/home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten/tools/shared.py", line 164, in run_process
                  return run_base(cmd, universal_newlines=universal_newlines, check=check, *args, **kw)
                File "/home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten/tools/shared.py", line 150, in run_base
                  return subprocess.run(cmd, check=check, input=input, *args, **kw)
                File "/usr/lib/python3.10/subprocess.py", line 503, in run
                  stdout, stderr = process.communicate(input, timeout=timeout)
                File "/usr/lib/python3.10/subprocess.py", line 1152, in communicate
                  stdout, stderr = self._communicate(input, endtime, timeout)
                File "/usr/lib/python3.10/subprocess.py", line 2045, in _communicate
                  stderr = self._translate_newlines(stderr,
                File "/usr/lib/python3.10/subprocess.py", line 1029, in _translate_newlines
                  data = data.decode(encoding, errors)
              UnicodeDecodeError: 'utf-8' codec can't decode byte 0xab in position 4530: invalid start byte
              """

              The above exception was the direct cause of the following exception:

              Traceback (most recent call last):
                File "/home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten/emcc.py", line 3091, in <module>
                  sys.exit(run())
                File "/home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten/emcc.py", line 1647, in run
                  extra_files_to_link += system_libs.calculate([f for _, f in sorted(temp_files)] + extra_files_to_link, in_temp, stdout_=None, stderr_=None, forced=forced_stdlibs)
                File "/home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten/tools/system_libs.py", line 544, in calculate
                  symbolses = shared.Building.parallel_llvm_nm([os.path.abspath(t) for t in temp_files])
                File "/home/runner/.local/share/cargo-web/emscripten/x86_64-unknown-linux-gnu/emscripten/tools/shared.py", line 1841, in parallel_llvm_nm
                  object_contents = pool.map(g_llvm_nm_uncached, files)
                File "/usr/lib/python3.10/multiprocessing/pool.py", line 367, in map
                  return self._map_async(func, iterable, mapstar, chunksize).get()
                File "/usr/lib/python3.10/multiprocessing/pool.py", line 774, in get
                  raise self._value
              UnicodeDecodeError: 'utf-8' codec can't decode byte 0xab in position 4530: invalid start byte
2023-01-27 19:47:13 -08:00
David Tolnay adcb11ca18 Replace cargo-web install step in CI with dtolnay/install 2023-01-27 19:34:12 -08:00
David Tolnay b7be637e8c Test_suite crate no longer has a build.rs 2023-01-14 12:18:11 -08:00
David Tolnay 30c4aa2cf4 Delete more macro test remnants 2023-01-14 12:15:20 -08:00
David Tolnay a649190a4d Delete macro expand tests
So far I haven't ended up being that pleased with the value proposition
of these tests.
2023-01-14 12:09:05 -08:00
David Tolnay d81f0ef652 Update rust-version metadata and readme to match CI 2023-01-12 21:19:16 -08:00
David Tolnay 1a3a49ce7c Delete 1.13.0 from CI
For some reasons old rustc 1.18.0 and older started failing to parse the
registry overnight.

    error: An unknown error occurred

    Caused by:
      Feature `pretty` depends on `syntex_syntax` which is not an optional dependency.
    Consider adding `optional = true` to the dependency
2023-01-12 21:17:42 -08:00
David Tolnay 6b948111ca Merge pull request #2355 from Niki4tap/remove_appendix
Remove appendix from LICENSE-APACHE
2022-12-30 11:47:38 -08:00
Niki4tap 6adfdc56e5 Remove appendix from LICENSE-APACHE 2022-12-30 22:32:44 +03:00
David Tolnay 61531ddd9e Link to serde_starlark data format 2022-12-26 22:06:47 -08:00
David Tolnay ccf9c6fc07 Release 1.0.152 2022-12-26 09:21:13 -08:00
David Tolnay b25d0ea7f9 Link to Hjson data format 2022-12-26 09:20:12 -08:00
David Tolnay 4f4557fd05 Link to bencode data format 2022-12-26 09:18:48 -08:00
David Tolnay bf400d6799 Link to serde_tokenstream data format 2022-12-26 09:14:59 -08:00
David Tolnay 4d2e36d19b Wrap flexbuffers bullet point to 80 columns 2022-12-26 09:14:23 -08:00
David Tolnay df6310e5f5 Merge pull request #2347 from dtolnay/docsrs
Replace docs.serde.rs links
2022-12-18 11:55:43 -08:00
David Tolnay 938ab5ddec Replace docs.serde.rs links with intra-rustdoc links 2022-12-18 11:48:57 -08:00
David Tolnay ef5a0de384 Point documentation links to docs.rs instead of docs.serde.rs 2022-12-18 11:45:23 -08:00
David Tolnay 5d186c77a6 Opt out -Zrustdoc-scrape-examples on docs.rs
I'd like a chance to audit all the code that rustdoc is inserting into
the docs. Currently I am skeptical that showing serde's internal usages
of APIs is a net benefit to the public documentation. I am also
skeptical that quite so many examples are needed, and that they should
be featured so prominently in comparison to handwritten docs. Lastly I
wish there were a way to turn this behavior off on a more granular
basis.
2022-12-18 09:31:17 -08:00
David Tolnay 44bf3633af Release 1.0.151 2022-12-16 10:35:12 -08:00
David Tolnay f261184416 Merge pull request #2344 from dtolnay/coreerror
Make StdError identical to core::error::Error on feature="unstable"
2022-12-16 10:22:04 -08:00
David Tolnay df40f80fcf Make StdError identical to core::error::Error on feature="unstable" 2022-12-16 10:11:37 -08:00
David Tolnay e7060ba83d Merge pull request #2342 from atouchet/badges
Update build status badge
2022-12-15 17:54:07 -08:00
Alex Touchet d98f0eea3d Update build status badge 2022-12-15 17:17:05 -08:00
David Tolnay 4f157a8b81 Prevent build.rs rerunning unnecessarily on all source changes 2022-12-12 14:37:41 -08:00
David Tolnay d493649f52 Release 1.0.150 2022-12-11 16:24:46 -08:00
David Tolnay 0e947e6c3b Merge pull request #2338 from serde-rs/atomic
Deduplicate atomic_impl implementations and atomic_impl calls from PR 2337
2022-12-11 16:22:28 -08:00
David Tolnay 9249dab54c Deduplicate atomic_impl macro calls 2022-12-11 16:12:51 -08:00
David Tolnay 7440e56c53 Deduplicate atomic_impl macro implementations 2022-12-11 16:09:26 -08:00
David Tolnay 0d79306285 Update atomic_impl macros to have same input syntax in all cfgs 2022-12-11 16:01:58 -08:00
David Tolnay 37faaf295e Mention target_has_atomic stabilization 2022-12-11 15:56:31 -08:00
David Tolnay 650358fa00 Replace obsolete comment about target_has_atomic support 2022-12-11 15:55:19 -08:00
David Tolnay 6159ead404 Invert use_target_has_atomic cfg
This way, a build system that does not want to run Cargo build scripts
can build serde without any cfgs defined, and get the most modern
feature set.
2022-12-11 15:51:19 -08:00
David Tolnay 692ac99c69 Format PR 2337 with rustfmt 2022-12-11 15:48:30 -08:00
David Tolnay 86161ce15f Adjust spacing in some macro matchers 2022-12-11 15:48:30 -08:00
David Tolnay 5361c790bb Merge pull request #2337 from badboy/use-target_has_atomic-when-available
Use `target_has_atomic` on Rust 1.60+ to enable atomic (de)serialization
2022-12-11 15:42:00 -08:00
Jan-Erik Rediger 126730edc8 Use target_has_atomic on Rust 1.60+ to enable atomic (de)serialization 2022-12-11 13:34:07 +01:00
David Tolnay 3aec2a96a8 Merge pull request #2334 from dtolnay/mapimpl
Reduce trait bounds in HashMap and BTreeMap serialize
2022-12-04 23:27:03 -08:00
David Tolnay 227d039b1e Reduce trait bounds in HashMap and BTreeMap serialize 2022-12-04 23:18:02 -08:00
David Tolnay 0353354d61 Release 1.0.149 2022-12-04 23:11:59 -08:00
David Tolnay 34ae0422f4 Merge pull request #2333 from jonasbb/remove-trait-bounds
Remove some Serialize trait bounds
2022-12-03 09:22:27 -08:00
Jonas Bushart cc128feb4c Remove some Serialize trait bounds
Containers for the most part do not have any trait requirements for
iterating over them. So these bounds are unnecessary when Serializing
only.

This relaxation is part of Rust 1.34
2022-12-03 16:03:37 +01:00
David Tolnay 7766103174 Release 1.0.148 2022-11-27 17:58:18 -08:00
David Tolnay 30f7c7110d Merge pull request #2331 from dtolnay/remote
Improve error message on remote derive duplicate generics
2022-11-27 17:57:35 -08:00
David Tolnay 50354c2d0b Improve error message on remote derive duplicate generics 2022-11-27 17:48:48 -08:00
David Tolnay c4f67e679f Add ui test of duplicate generics in remote derive 2022-11-27 17:48:48 -08:00
David Tolnay 0daafe423f Merge pull request #2330 from dtolnay/remote
Fix generated Into conversion involving generic remote derive with getter
2022-11-27 17:48:37 -08:00
David Tolnay 37021910c9 Fix Into conversion involving generic remote derive with getter 2022-11-27 17:18:10 -08:00
David Tolnay 7328b34810 Add test of generic remote derive with getter
Currently fails to compile.

    error[E0107]: missing generics for struct `StructGeneric`
       --> test_suite/tests/test_remote.rs:181:18
        |
    181 | #[serde(remote = "remote::StructGeneric")]
        |                  ^^^^^^^^^^^^^^^^^^^^^^^ expected 1 generic argument
        |
    note: struct defined here, with 1 generic parameter: `T`
       --> test_suite/tests/test_remote.rs:78:16
        |
    78  |     pub struct StructGeneric<T> {
        |                ^^^^^^^^^^^^^ -
    help: add missing generic argument
        |
    181 | #[serde(remote = StructGeneric<T>)]
        |                  ~~~~~~~~~~~~~~~~
2022-11-27 17:17:52 -08:00
David Tolnay fabbd2b097 Merge pull request #2329 from dtolnay/safety
Revert Buf::as_str safety change from PR 2319
2022-11-27 17:05:41 -08:00
David Tolnay 6814f978d7 Revert Buf::as_str safety change from PR 2319 2022-11-27 16:56:31 -08:00
David Tolnay 4ea403c54a Merge pull request #2328 from dtolnay/remote
Handle remote type written without turbofish
2022-11-27 16:41:23 -08:00
David Tolnay f4f6b5af3a Remove unneeded turbofish from remote attr test 2022-11-27 16:32:06 -08:00
David Tolnay 2062a3c16d Handle remote type written without turbofish 2022-11-27 16:32:06 -08:00
David Tolnay 9a53bd9125 Add tests of concrete def of generic remote type 2022-11-27 16:05:56 -08:00
David Tolnay 4873b48b02 Time out workflows after 45 minutes
GitHub's default timeout is 6 hours. Recently some of my GitHub Actions
jobs have started randomly stalling for that long, which is inconvenient
because it ties up a chunk of my runner quota. It apepars to be very
rare for a job to recover after stalling. It's better to time out
quicker and retry on a different runner.
2022-11-25 18:56:19 -08:00
David Tolnay e19844c659 Fix renamed let_underscore_drop lint
warning: lint `clippy::let_underscore_drop` has been renamed to `let_underscore_drop`
      --> serde_derive/src/lib.rs:46:5
       |
    46 |     clippy::let_underscore_drop,
       |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the new name: `let_underscore_drop`
       |
       = note: `#[warn(renamed_and_removed_lints)]` on by default
2022-11-22 19:04:29 -08:00
David Tolnay 93bb9e147c Resolve manual_let_else clippy lints
error: this could be rewritten as `let...else`
        --> test_suite/tests/test_annotations.rs:1247:5
         |
    1247 | /     let f1 = match pieces.next() {
    1248 | |         Some(x) => x,
    1249 | |         None => return Err(de::Error::invalid_length(0, &"2")),
    1250 | |     };
         | |______^ help: consider writing: `let Some(x) = pieces.next() else { return Err(de::Error::invalid_length(0, &"2")) };`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
         = note: `-D clippy::manual-let-else` implied by `-D clippy::pedantic`

    error: this could be rewritten as `let...else`
        --> test_suite/tests/test_annotations.rs:1251:5
         |
    1251 | /     let f2 = match pieces.next() {
    1252 | |         Some(x) => x,
    1253 | |         None => return Err(de::Error::invalid_length(1, &"2")),
    1254 | |     };
         | |______^ help: consider writing: `let Some(x) = pieces.next() else { return Err(de::Error::invalid_length(1, &"2")) };`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else

    error: this could be rewritten as `let...else`
        --> test_suite/tests/test_annotations.rs:1255:5
         |
    1255 | /     let f2 = match f2.parse() {
    1256 | |         Ok(n) => n,
    1257 | |         Err(_) => {
    1258 | |             return Err(de::Error::invalid_value(
    ...    |
    1262 | |         }
    1263 | |     };
         | |______^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#manual_let_else
    help: consider writing
         |
    1255 ~     let Ok(n) = f2.parse() else {
    1256 +             return Err(de::Error::invalid_value(
    1257 +                 Unexpected::Str(f2),
    1258 +                 &"an 8-bit signed integer",
    1259 +             ));
    1260 +         };
         |
2022-11-22 18:45:27 -08:00
David Tolnay ab230e6e44 Resolve needless_lifetimes clippy lints
error: the following explicit lifetimes could be elided: 'a
       --> serde_derive/src/ser.rs:869:1
        |
    869 | / fn serialize_struct_variant<'a>(
    870 | |     context: StructVariant<'a>,
    871 | |     params: &Parameters,
    872 | |     fields: &[Field],
    873 | |     name: &str,
    874 | | ) -> Fragment {
        | |_____________^
        |
    help: replace with `'_` in generic arguments such as here
       --> serde_derive/src/ser.rs:870:28
        |
    870 |     context: StructVariant<'a>,
        |                            ^^
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
        = note: `-D clippy::needless-lifetimes` implied by `-D clippy::all`

    error: the following explicit lifetimes could be elided: 'a
       --> serde_derive/src/ser.rs:953:1
        |
    953 | / fn serialize_struct_variant_with_flatten<'a>(
    954 | |     context: StructVariant<'a>,
    955 | |     params: &Parameters,
    956 | |     fields: &[Field],
    957 | |     name: &str,
    958 | | ) -> Fragment {
        | |_____________^
        |
    help: replace with `'_` in generic arguments such as here
       --> serde_derive/src/ser.rs:954:28
        |
    954 |     context: StructVariant<'a>,
        |                            ^^
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_lifetimes
2022-11-22 18:41:37 -08:00
David Tolnay 51ea34b217 Resolve needless_borrowed_reference clippy lints
error: dereferencing a tuple pattern where every element takes a reference
        --> serde/src/private/de.rs:1813:39
         |
    1813 |         let map = content.iter().map(|&(ref k, ref v)| {
         |                                       ^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
         = note: `-D clippy::needless-borrowed-reference` implied by `-D clippy::all`
    help: try removing the `&` and `ref` parts
         |
    1813 -         let map = content.iter().map(|&(ref k, ref v)| {
    1813 +         let map = content.iter().map(|(k, v)| {
         |

    error: dereferencing a tuple pattern where every element takes a reference
        --> serde/src/private/de.rs:2110:25
         |
    2110 |                     let &(ref variant, ref value) = match iter.next() {
         |                         ^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
    help: try removing the `&` and `ref` parts
         |
    2110 -                     let &(ref variant, ref value) = match iter.next() {
    2110 +                     let (variant, value) = match iter.next() {
         |

    error: dereferencing a tuple pattern where every element takes a reference
        --> serde/src/private/de.rs:2257:22
         |
    2257 |                 Some(&Content::Seq(ref v)) => {
         |                      ^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
    help: try removing the `&` and `ref` parts
         |
    2257 -                 Some(&Content::Seq(ref v)) => {
    2257 +                 Some(Content::Seq(v)) => {
         |

    error: dereferencing a tuple pattern where every element takes a reference
        --> serde/src/private/de.rs:2280:22
         |
    2280 |                 Some(&Content::Map(ref v)) => {
         |                      ^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
    help: try removing the `&` and `ref` parts
         |
    2280 -                 Some(&Content::Map(ref v)) => {
    2280 +                 Some(Content::Map(v)) => {
         |

    error: dereferencing a tuple pattern where every element takes a reference
        --> serde/src/private/de.rs:2283:22
         |
    2283 |                 Some(&Content::Seq(ref v)) => {
         |                      ^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
    help: try removing the `&` and `ref` parts
         |
    2283 -                 Some(&Content::Seq(ref v)) => {
    2283 +                 Some(Content::Seq(v)) => {
         |

    error: dereferencing a tuple pattern where every element takes a reference
        --> serde/src/private/de.rs:2406:22
         |
    2406 |                 Some(&(ref key, ref value)) => {
         |                      ^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
    help: try removing the `&` and `ref` parts
         |
    2406 -                 Some(&(ref key, ref value)) => {
    2406 +                 Some((key, value)) => {
         |

    error: dereferencing a tuple pattern where every element takes a reference
       --> serde/src/private/ser.rs:528:25
        |
    528 |                     for &(ref k, ref v) in entries {
        |                         ^^^^^^^^^^^^^^^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
    help: try removing the `&` and `ref` parts
        |
    528 -                     for &(ref k, ref v) in entries {
    528 +                     for (k, v) in entries {
        |
2022-11-22 18:40:34 -08:00
Erick Tryzelaar 1050f6b808 Change comment to // Safety: ...
This changes a comment to be explicit on how it's safe we can avoid
validating UTF-8.
2022-11-09 22:44:24 +00:00
Erick Tryzelaar 15ec95a98d Make Buf::as_str private and unsafe, add safety docs
serde::de::format::Buf is a private type, so this makes it explicit by
declaring the type `pub(super)`. In addition, it marks the function
`Buf::as_str` as unsafe, which lets us document the callsites with
`// Safety: ...` comments to explain why it is safe to use.
2022-11-09 22:40:40 +00:00
David Tolnay 072145e0e9 Update TOML link to a page that covers usage with serde 2022-11-08 17:33:39 -08:00
David Tolnay 92957f17f2 Merge pull request #2317 from TomAFrench/patch-1
Update link to `toml` crate repo
2022-11-08 17:32:56 -08:00
Tom French 667db558b6 chore: update link to toml crate repo 2022-11-09 01:07:53 +00:00
David Tolnay f41509261e Release 1.0.147 2022-10-21 10:04:43 -07:00
David Tolnay 6d009711a2 Merge pull request #2305 from serde-rs/enumaccessdeserializer
Add EnumAccessDeserializer to turn EnumAccess into a Deserializer
2022-10-21 10:04:08 -07:00
David Tolnay 354b48fd40 Add EnumAccessDeserializer to turn EnumAccess into a Deserializer 2022-10-21 09:51:42 -07:00
David Tolnay 3fd8e52f0c Release 1.0.146 2022-10-21 01:03:47 -07:00
David Tolnay 142dce0d3d Touch up PR 2303 2022-10-21 01:02:46 -07:00
David Tolnay 6aed101630 Merge pull request #2303 from tage64/master
Serialize and deserialize a tagged newtype variant over unit () as if it was a unit variant
2022-10-21 00:59:40 -07:00
Tage Johansson e2ccfd9ea7 Remove bad deserialization from sequence to internally tagged newtype variant over . 2022-10-21 09:07:27 +02:00
tage64 a07d794f74 Update test_suite/tests/test_annotations.rs
Co-authored-by: David Tolnay <dtolnay@gmail.com>
2022-10-21 08:53:55 +02:00
Tage Johansson 90d28fc314 Serialize and deserialize a tagged newtype variant over unit () as if it was a unit variant. 2022-10-21 00:27:46 +02:00
David Tolnay 55cf0ac51a Merge pull request #2297 from serde-rs/output
Switch from set-output to $GITHUB_OUTPUT
2022-10-13 09:47:29 -07:00
David Tolnay 07696c1674 Switch from set-output to $GITHUB_OUTPUT 2022-10-13 09:38:56 -07:00
David Tolnay f803b290f3 Ignore uninlined_format_args pedantic clippy lint false positive
Clippy's suggested fix is not valid in 2018 edition. The
serde_test_suite crate can't be updated to 2021 edition yet because CI
of the serde crate on old toolchains needs to be able to parse all
manifests in the workspace, even if serde_test_suite is not being
compiled in those builds.

    error: variables can be used directly in the `format!` string
        --> test_suite/tests/test_de.rs:2260:23
         |
    2260 |             Err(e) => panic!("tokens failed to deserialize: {}", e),
         |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
         = note: `-D clippy::uninlined-format-args` implied by `-D clippy::pedantic`
    help: change this to
         |
    2260 -             Err(e) => panic!("tokens failed to deserialize: {}", e),
    2260 +             Err(e) => panic!("tokens failed to deserialize: {e}"),
         |

    warning: unused variable: `e`
        --> test_suite/tests/test_de.rs:2260:17
         |
    2260 |             Err(e) => panic!("tokens failed to deserialize: {e}"),
         |                 ^ help: if this is intentional, prefix it with an underscore: `_e`
         |
         = note: `#[warn(unused_variables)]` on by default

    warning: panic message contains an unused formatting placeholder
        --> test_suite/tests/test_de.rs:2260:61
         |
    2260 |             Err(e) => panic!("tokens failed to deserialize: {e}"),
         |                                                             ^^^
         |
         = note: this message is not used as a format string when given without arguments, but will be in Rust 2021
         = note: `#[warn(non_fmt_panics)]` on by default
    help: add the missing argument
         |
    2260 |             Err(e) => panic!("tokens failed to deserialize: {e}", ...),
         |                                                                 +++++
    help: or add a "{}" format string to use the message literally
         |
    2260 |             Err(e) => panic!("{}", "tokens failed to deserialize: {e}"),
         |                              +++++
2022-10-07 21:46:25 -07:00
David Tolnay d96e181150 Resolve uninlined_format_args pedantic clippy lint in test suite
error: variables can be used directly in the `format!` string
        --> test_suite/tests/test_annotations.rs:1238:30
         |
    1238 |     serializer.serialize_str(format!("{};{:?}", f1, f2).as_str())
         |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#uninlined_format_args
         = note: `-D clippy::uninlined-format-args` implied by `-D clippy::pedantic`
    help: change this to
         |
    1238 -     serializer.serialize_str(format!("{};{:?}", f1, f2).as_str())
    1238 +     serializer.serialize_str(format!("{f1};{f2:?}").as_str())
         |
2022-10-07 21:45:03 -07:00
David Tolnay 3ffb86fc70 Ui test changes for trybuild 1.0.66 2022-10-04 22:28:38 -07:00
David Tolnay 649a72a587 Merge pull request 2284 from benediktwerner/patch-1 2022-09-22 23:35:24 -07:00
Benedikt Werner b2676348eb Fix "deserialize" -> "deserialize_any" in Deserializer documentation 2022-09-23 08:29:25 +02:00
David Tolnay 8c036ee5a3 Release 1.0.145 2022-09-22 10:50:08 -07:00
David Tolnay d99009f3c6 Merge pull request #2282 from ChayimFriedman2/sized-mutex-refcell-rwlock
Serialize unsized `RefCell`, `Mutex` and `RwLock`
2022-09-22 10:48:54 -07:00
Chayim Refael Friedman be3c37eb8b Serialize unsized RefCell, Mutex and RwLock 2022-09-22 09:57:55 +03:00
David Tolnay f0346ae054 Merge pull request #2281 from dtolnay/try
Redefine `try` macro to omit From::from error conversion
2022-09-21 22:15:10 -07:00
David Tolnay fa6ce42056 Redefine 'try' macro to omit From::from error conversion 2022-09-21 22:01:15 -07:00
David Tolnay a9320db6f9 Consistently avoid '?' throughout serde crate
This makes it easy to redefine a 'try' macro to compare compile-time
between `$expr?` and `match $expr { Ok=>v, Err=>return }`.
2022-09-21 21:34:04 -07:00
David Tolnay d208762c81 Command-line ignore let_underscore_drop clippy lint
For whatever reason, the #![cfg_attr(feature = "cargo-clippy", allow(let_underscore_drop))]
attributes already in the code stopped working in the most recent nightly (2022-09-03).
Likely in connection with https://github.com/rust-lang/rust/pull/97739 ?

    error: non-binding `let` on a type that implements `Drop`
       --> serde/src/de/mod.rs:958:13
        |
    958 |             let _ = visitor;
        |             ^^^^^^^^^^^^^^^^
        |
        = note: `-D clippy::let-underscore-drop` implied by `-D clippy::pedantic`
        = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop

    error: non-binding `let` on a type that implements `Drop`
       --> serde/src/de/mod.rs:992:13
        |
    992 |             let _ = visitor;
        |             ^^^^^^^^^^^^^^^^
        |
        = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop

    error: non-binding `let` on a type that implements `Drop`
        --> serde/src/de/mod.rs:1616:9
         |
    1616 |         let _ = deserializer;
         |         ^^^^^^^^^^^^^^^^^^^^^
         |
         = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop

    error: non-binding `let` on a type that implements `Drop`
        --> serde/src/de/mod.rs:1640:9
         |
    1640 |         let _ = deserializer;
         |         ^^^^^^^^^^^^^^^^^^^^^
         |
         = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop

    error: non-binding `let` on a type that implements `Drop`
        --> serde/src/de/mod.rs:1651:9
         |
    1651 |         let _ = seq;
         |         ^^^^^^^^^^^^
         |
         = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop

    error: non-binding `let` on a type that implements `Drop`
        --> serde/src/de/mod.rs:1662:9
         |
    1662 |         let _ = map;
         |         ^^^^^^^^^^^^
         |
         = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop

    error: non-binding `let` on a type that implements `Drop`
        --> serde/src/de/mod.rs:1673:9
         |
    1673 |         let _ = data;
         |         ^^^^^^^^^^^^^
         |
         = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop

    error: non-binding `let` on a type that implements `Drop`
        --> serde/src/private/de.rs:1440:13
         |
    1440 |             let _ = visitor;
         |             ^^^^^^^^^^^^^^^^
         |
         = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop

    error: non-binding `let` on a type that implements `Drop`
        --> serde/src/private/de.rs:2163:13
         |
    2163 |             let _ = visitor;
         |             ^^^^^^^^^^^^^^^^
         |
         = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#let_underscore_drop
2022-09-02 21:16:27 -07:00
David Tolnay 5386897d24 Merge pull request #2273 from sashashura/patch-1
GitHub Workflows security hardening
2022-09-02 15:01:40 -07:00
Alex 68eb59df0c Update ci.yml
Signed-off-by: sashashura <93376818+sashashura@users.noreply.github.com>
2022-09-02 16:43:23 +01:00
David Tolnay a7f4551669 Add dev-dependencies keyword for serde_test 2022-08-30 22:52:10 -07:00
David Tolnay f52d134c14 Release 1.0.144 2022-08-20 20:24:28 -07:00
David Tolnay 6660676b0d Merge pull request #2263 from taiki-e/ordering
Relax orderings of Serialize impl for atomic types to match the latest stable
2022-08-20 20:22:34 -07:00
Taiki Endo 1d42d3571a Relax orderings of Serialize impl for atomic types to match the latest stable 2022-08-20 22:27:22 +09:00
David Tolnay ebd06eebdb Link to apache-avro crate's published docs 2022-08-12 21:34:41 -07:00
David Tolnay f1985823a3 Merge pull request #2258 from Mottl/patch-1
Fixes link to Apache Avro in documentation
2022-08-12 21:33:43 -07:00
Dmitry Mottl 60e4092b8e Fixes link to Apache Avro in documentation 2022-08-12 18:52:26 +04:00
David Tolnay 3d0251666e Release 1.0.143 2022-08-08 19:12:43 -07:00
David Tolnay 7770da4929 Merge pull request #2253 from taiki-e/test-cfg
Invert build.rs cfgs in serde_test
2022-08-08 19:08:35 -07:00
Taiki Endo a5fd85a9ef Invert build.rs cfgs in serde_test 2022-08-04 20:20:31 +09:00
David Tolnay abb2a8494d Release 1.0.142 2022-08-03 07:09:15 -07:00
David Tolnay a31d0be191 Update keywords in crates.io metadata 2022-08-02 10:38:57 -07:00
David Tolnay d786e750d7 Release 1.0.141 2022-08-01 08:50:46 -07:00
David Tolnay 10e4839f83 Move Postcard link up to Bincode spot
Bincode has been in prerelease limbo for nearly a year and the readme
does not mention anything related to Serde, so it is not serving as a
good first link to a Serde binary format.
2022-08-01 08:49:45 -07:00
David Tolnay 85e72653c8 Add categories to crates.io metadata 2022-08-01 00:06:49 -07:00
David Tolnay c9cc8a8924 Add authors to Cargo.toml 2022-07-31 19:25:47 -07:00
David Tolnay a925ce4119 Sort package entries in Cargo.toml 2022-07-31 19:19:07 -07:00
David Tolnay c5f6338ce2 Release 1.0.140 2022-07-20 09:26:28 -07:00
David Tolnay 5185487d73 Merge pull request #2251 from taiki-e/derive-cfg
Invert build.rs cfgs in serde_derive
2022-07-20 09:25:14 -07:00
Taiki Endo efaafd4458 Invert build.rs cfgs in serde_derive 2022-07-21 01:15:37 +09:00
David Tolnay a0eb83a5d4 Resolve invalid_utf8_in_unchecked clippy lint in ancient test code
error: non UTF-8 literal in `std::str::from_utf8_unchecked`
       --> test_suite/tests/test_ser.rs:803:25
        |
    803 |     let path = unsafe { str::from_utf8_unchecked(b"Hello \xF0\x90\x80World") };
        |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = note: `-D clippy::invalid-utf8-in-unchecked` implied by `-D clippy::all`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#invalid_utf8_in_unchecked
2022-07-18 21:29:39 -07:00
David Tolnay 7cc6f7fbb0 Ignore new_without_default clippy lint
error: you should consider adding a `Default` implementation for `UnitDeserializer<E>`
       --> serde/src/de/value.rs:144:5
        |
    144 | /     pub fn new() -> Self {
    145 | |         UnitDeserializer {
    146 | |             marker: PhantomData,
    147 | |         }
    148 | |     }
        | |_____^
        |
        = note: `-D clippy::new-without-default` implied by `-D clippy::all`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#new_without_default
    help: try adding this
        |
    142 + impl<E> Default for UnitDeserializer<E> {
    143 +     fn default() -> Self {
    144 +         Self::new()
    145 +     }
    146 + }
        |
2022-07-11 21:19:58 -07:00
David Tolnay 44b9496c91 Release 1.0.139 2022-07-10 21:51:21 -07:00
David Tolnay 7e1486d0da Merge pull request #2246 from dtolnay/valuedenew
Add constructor function for all IntoDeserializer impls
2022-07-10 21:50:24 -07:00
David Tolnay 8170ffef2e Add constructor function for all IntoDeserializer impls 2022-07-10 21:42:03 -07:00
David Tolnay 4b622f6bbf Release 1.0.138 2022-07-01 20:09:56 -07:00
David Tolnay 0ee71c70af Ignore explicit_auto_deref clippy lint
error: deref which would be done by auto-deref
        --> serde/src/de/impls.rs:2014:59
         |
    2014 | ...                   Err(Error::unknown_field(&*value, FIELDS))
         |                                                 ^^^^^^ help: try this: `value`
         |
         = note: `-D clippy::explicit-auto-deref` implied by `-D clippy::all`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_auto_deref

    error: deref which would be done by auto-deref
        --> serde/src/de/impls.rs:2354:55
         |
    2354 | ...                   Err(Error::unknown_field(&*value, FIELDS))
         |                                                 ^^^^^^ help: try this: `value`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#explicit_auto_deref
2022-07-01 19:41:14 -07:00
David Tolnay 6c098e497e Merge pull request #2240 from Kixunil/patch-1
Call `reserve()` in `DeserializeSeed` example
2022-06-30 09:39:25 -07:00
Martin Habovštiak 41ffa6df7e Call reserve() in DeserializeSeed example
This suggests calling `reserve()` in example code so that people who ~blindly copy it get faster code.
2022-06-30 18:28:52 +02:00
David Tolnay 845b900fd5 Exclude deliberately pinned prettyplease crate from cargo outdated 2022-06-22 21:07:57 -07:00
David Tolnay 7891ae7184 Merge pull request #2228 from serde-rs/expandtest
Update macrotest to 1.0.9 and enable in CI
2022-06-20 03:53:50 -07:00
David Tolnay bac90d19b9 Update macrotest to 1.0.9 and enable in CI 2022-06-20 03:40:49 -07:00
David Tolnay 227bf3023a Merge pull request #2229 from dtolnay/expandlinguist
Mark expandtest outputs as generated code
2022-06-20 03:40:37 -07:00
David Tolnay f4535f68c1 Mark expandtest outputs as generated code 2022-06-20 03:27:20 -07:00
David Tolnay c6c35b5a31 Ignore buggy doc_link_with_quotes clippy lint
https://github.com/rust-lang/rust-clippy/issues/8961

    error: possible intra-doc link using quotes instead of backticks
       --> serde_test/src/token.rs:277:5
        |
    277 |     /// let vec = vec!['a', 'b', 'c'];
        |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = note: `-D clippy::doc-link-with-quotes` implied by `-D clippy::pedantic`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#doc_link_with_quotes
2022-06-07 00:30:50 -07:00
David Tolnay 31e51324e2 Add actions job to notice outdated dependencies 2022-06-06 16:09:41 -07:00
David Tolnay bc3f24e0e9 Update toolchain_find dependency to 0.2 2022-06-06 16:09:14 -07:00
David Tolnay 2e38e2bf2f Ignore derive_partial_eq_without_eq clippy lint
error: you are deriving `PartialEq` and can implement `Eq`
      --> serde/src/de/value.rs:51:17
       |
    51 | #[derive(Clone, PartialEq)]
       |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = note: `-D clippy::derive-partial-eq-without-eq` implied by `-D clippy::all`
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> serde_derive/src/internals/case.rs:13:23
       |
    13 | #[derive(Copy, Clone, PartialEq)]
       |                       ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
     --> test_suite/tests/unstable/mod.rs:6:21
      |
    6 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
      |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
      |
      = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
     --> test_suite/tests/test_ignored_any.rs:7:10
      |
    7 | #[derive(PartialEq, Debug, Deserialize)]
      |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
      |
      = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
     --> test_suite/tests/test_identifier.rs:7:34
      |
    7 |     #[derive(Deserialize, Debug, PartialEq)]
      |                                  ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
      |
      = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_identifier.rs:24:34
       |
    24 |     #[derive(Deserialize, Debug, PartialEq)]
       |                                  ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_identifier.rs:41:34
       |
    41 |     #[derive(Deserialize, Debug, PartialEq)]
       |                                  ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_identifier.rs:59:34
       |
    59 |     #[derive(Deserialize, Debug, PartialEq)]
       |                                  ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_ser.rs:46:10
       |
    46 | #[derive(PartialEq, Debug)]
       |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_value.rs:11:34
       |
    11 |     #[derive(Deserialize, Debug, PartialEq)]
       |                                  ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de_error.rs:15:23
       |
    15 | #[derive(Copy, Clone, PartialEq, Debug, Deserialize)]
       |                       ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de_error.rs:18:10
       |
    18 | #[derive(PartialEq, Debug, Deserialize)]
       |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de_error.rs:26:10
       |
    26 | #[derive(PartialEq, Debug, Deserialize)]
       |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de_error.rs:34:10
       |
    34 | #[derive(PartialEq, Debug, Deserialize)]
       |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de_error.rs:41:19
       |
    41 | #[derive(Default, PartialEq, Debug)]
       |                   ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de_error.rs:60:10
       |
    60 | #[derive(PartialEq, Debug, Deserialize)]
       |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_borrow.rs:70:34
       |
    70 |     #[derive(Deserialize, Debug, PartialEq)]
       |                                  ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_borrow.rs:97:34
       |
    97 |     #[derive(Deserialize, Debug, PartialEq)]
       |                                  ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_borrow.rs:106:34
        |
    106 |     #[derive(Deserialize, Debug, PartialEq)]
        |                                  ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de.rs:43:23
       |
    43 | #[derive(Copy, Clone, PartialEq, Debug, Deserialize)]
       |                       ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de.rs:46:10
       |
    46 | #[derive(PartialEq, Debug, Deserialize)]
       |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de.rs:49:10
       |
    49 | #[derive(PartialEq, Debug, Deserialize)]
       |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de.rs:52:10
       |
    52 | #[derive(PartialEq, Debug, Deserialize)]
       |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de.rs:76:10
       |
    76 | #[derive(PartialEq, Debug, Deserialize)]
       |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_de.rs:82:10
       |
    82 | #[derive(PartialEq, Debug, Deserialize)]
       |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_de.rs:102:10
        |
    102 | #[derive(PartialEq, Debug, Deserialize)]
        |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_de.rs:109:19
        |
    109 | #[derive(Default, PartialEq, Debug)]
        |                   ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_de.rs:128:10
        |
    128 | #[derive(PartialEq, Debug, Deserialize)]
        |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_de.rs:135:10
        |
    135 | #[derive(PartialEq, Debug)]
        |          ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_de.rs:185:14
        |
    185 |     #[derive(PartialEq, Debug, Deserialize)]
        |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
      --> test_suite/tests/test_macros.rs:25:17
       |
    25 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
       |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_macros.rs:110:17
        |
    110 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_macros.rs:580:21
        |
    580 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_macros.rs:607:21
        |
    607 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_macros.rs:681:21
        |
    681 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_macros.rs:684:21
        |
    684 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_macros.rs:816:21
        |
    816 |     #[derive(Debug, PartialEq, Deserialize)]
        |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_macros.rs:976:21
        |
    976 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1027:21
         |
    1027 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1273:21
         |
    1273 |     #[derive(Debug, PartialEq, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1342:21
         |
    1342 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1413:21
         |
    1413 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1450:21
         |
    1450 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1474:21
         |
    1474 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1509:21
         |
    1509 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1543:21
         |
    1543 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1601:21
         |
    1601 |     #[derive(Debug, PartialEq, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1743:45
         |
    1743 |     #[derive(Serialize, Deserialize, Debug, PartialEq)]
         |                                             ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1763:45
         |
    1763 |     #[derive(Serialize, Deserialize, Debug, PartialEq)]
         |                                             ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1770:45
         |
    1770 |     #[derive(Serialize, Deserialize, Debug, PartialEq)]
         |                                             ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1870:21
         |
    1870 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_macros.rs:1888:21
         |
    1888 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:108:17
        |
    108 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:124:17
        |
    124 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:147:17
        |
    147 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:344:17
        |
    344 | #[derive(Debug, PartialEq, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:394:17
        |
    394 | #[derive(Debug, PartialEq)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:413:17
        |
    413 | #[derive(Debug, PartialEq)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:458:17
        |
    458 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:512:17
        |
    512 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:520:17
        |
    520 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:528:17
        |
    528 | #[derive(Debug, PartialEq, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:647:17
        |
    647 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_gen.rs:835:17
        |
    835 | #[derive(Debug, PartialEq, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
       --> test_suite/tests/test_annotations.rs:675:17
        |
    675 | #[derive(Debug, PartialEq, Deserialize)]
        |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1047:17
         |
    1047 | #[derive(Debug, PartialEq)]
         |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1050:17
         |
    1050 | #[derive(Debug, PartialEq)]
         |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1196:17
         |
    1196 | #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1514:17
         |
    1514 | #[derive(Debug, PartialEq, Deserialize)]
         |                 ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1548:41
         |
    1548 | #[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
         |                                         ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1566:41
         |
    1566 | #[derive(Clone, Serialize, Deserialize, PartialEq, Debug)]
         |                                         ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1600:30
         |
    1600 | #[derive(Clone, Deserialize, PartialEq, Debug)]
         |                              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1803:21
         |
    1803 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1843:21
         |
    1843 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1852:21
         |
    1852 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:1947:21
         |
    1947 |     #[derive(Debug, PartialEq, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2003:21
         |
    2003 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2037:21
         |
    2037 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                     ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2074:45
         |
    2074 |     #[derive(Deserialize, Serialize, Debug, PartialEq)]
         |                                             ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2080:45
         |
    2080 |     #[derive(Deserialize, Serialize, Debug, PartialEq)]
         |                                             ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2157:38
         |
    2157 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2193:38
         |
    2193 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2200:38
         |
    2200 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2240:38
         |
    2240 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2279:38
         |
    2279 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2316:38
         |
    2316 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2359:38
         |
    2359 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2390:38
         |
    2390 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2421:38
         |
    2421 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2426:38
         |
    2426 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2483:38
         |
    2483 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2507:38
         |
    2507 |     #[derive(Serialize, Deserialize, PartialEq, Debug)]
         |                                      ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2521:27
         |
    2521 |     #[derive(Deserialize, PartialEq, Debug)]
         |                           ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2552:27
         |
    2552 |     #[derive(Deserialize, PartialEq, Debug)]
         |                           ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2558:27
         |
    2558 |     #[derive(Deserialize, PartialEq, Debug)]
         |                           ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2586:14
         |
    2586 |     #[derive(PartialEq, Debug)]
         |              ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2624:27
         |
    2624 |     #[derive(Deserialize, PartialEq, Debug)]
         |                           ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq

    error: you are deriving `PartialEq` and can implement `Eq`
        --> test_suite/tests/test_annotations.rs:2647:27
         |
    2647 |     #[derive(Deserialize, PartialEq, Debug)]
         |                           ^^^^^^^^^ help: consider deriving `Eq` as well: `PartialEq, Eq`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#derive_partial_eq_without_eq
2022-05-21 20:43:51 -07:00
David Tolnay 819f90d9f6 Ignore unused_macro_rules warning in test macros
warning: 1st rule of macro `btreeset` is never used
     --> test_suite/tests/macros/mod.rs:5:5
      |
    5 |     () => {
      |     ^^
      |
      = note: `#[warn(unused_macro_rules)]` on by default

    warning: 1st rule of macro `hashset` is never used
      --> test_suite/tests/macros/mod.rs:27:5
       |
    27 |     () => {
       |     ^^

    warning: 1st rule of macro `hashmap` is never used
      --> test_suite/tests/macros/mod.rs:44:5
       |
    44 |     () => {
       |     ^^

    warning: 1st rule of macro `hashset` is never used
      --> test_suite/tests/macros/mod.rs:27:5
       |
    27 |     () => {
       |     ^^
       |
       = note: `#[warn(unused_macro_rules)]` on by default
2022-05-12 21:33:43 -07:00
David Tolnay 2eed86cd67 Remove doc(hidden) attribute that is being phased out
warning: `#[doc(hidden)]` is ignored on trait impl items
       --> serde/src/de/impls.rs:796:5
        |
    796 |     #[doc(hidden)]
        |     ^^^^^^^^^^^^^^ help: remove this attribute
        |
        = note: `#[warn(unused_attributes)]` on by default
        = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
        = note: whether the impl item is `doc(hidden)` or not entirely depends on the corresponding trait item
2022-05-09 21:16:16 -07:00
David Tolnay 3921b57435 Run miri in stricter miri-strict-provenance mode 2022-05-06 04:01:35 -07:00
David Tolnay 68069d734a Fix needless_borrow for both value=Cow<str> and value=&str 2022-05-05 21:07:33 -07:00
David Tolnay dc84693507 Resolve needless_borrow clippy lint
error: this expression creates a reference which is immediately dereferenced by the compiler
        --> serde/src/de/impls.rs:2015:58
         |
    2015 | ...                   Err(Error::unknown_field(&value, FIELDS))
         |                                                ^^^^^^ help: change this to: `value`
         |
         = note: `-D clippy::needless-borrow` implied by `-D clippy::all`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

    error: this expression creates a reference which is immediately dereferenced by the compiler
        --> serde/src/de/impls.rs:2355:54
         |
    2355 | ...                   Err(Error::unknown_field(&value, FIELDS))
         |                                                ^^^^^^ help: change this to: `value`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
2022-05-05 21:01:03 -07:00
David Tolnay 4cf012c5be Resolve extra_unused_lifetimes clippy lint
error: this lifetime isn't used in the impl
       --> serde/src/de/value.rs:607:11
        |
    607 | impl<'de, 'a, E> de::EnumAccess<'de> for StringDeserializer<E>
        |           ^^
        |
        = note: `-D clippy::extra-unused-lifetimes` implied by `-D clippy::all`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#extra_unused_lifetimes
2022-05-05 21:00:37 -07:00
David Tolnay 17c3c0cf86 Release 1.0.137 2022-04-30 21:45:31 -07:00
David Tolnay 210e6c354e Clean up clippy allows which are superseded by msrv in clippy.toml 2022-04-30 21:35:00 -07:00
David Tolnay 41823a96df Ignore more type_repetition_in_bounds
I'm not sure what is going on with this lint but it's triggering in a
lot of test code. Will need to investigate further.

    error: this type has already been used as a bound predicate
       --> test_suite/tests/test_gen.rs:194:21
        |
    194 |             bound = "E: SerializeWith + DeserializeWith"
        |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = note: `-D clippy::type-repetition-in-bounds` implied by `-D clippy::pedantic`
        = help: consider combining the bounds: `"E: SerializeWith + DeserializeWith": "E: SerializeWith + DeserializeWith" + "E: SerializeWith + DeserializeWith"`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
       --> test_suite/tests/test_gen.rs:184:21
        |
    184 |     #[serde(bound = "D: SerializeWith + DeserializeWith")]
        |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: consider combining the bounds: `"D: SerializeWith + DeserializeWith": "D: SerializeWith + DeserializeWith" + "D: SerializeWith + DeserializeWith"`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
       --> test_suite/tests/test_gen.rs:210:31
        |
    210 |             bound(serialize = "E: SerializeWith")
        |                               ^^^^^^^^^^^^^^^^^^
        |
        = help: consider combining the bounds: `"E: SerializeWith": "E: SerializeWith"`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
       --> test_suite/tests/test_gen.rs:201:31
        |
    201 |     #[serde(bound(serialize = "D: SerializeWith", deserialize = "D: DeserializeWith"))]
        |                               ^^^^^^^^^^^^^^^^^^
        |
        = help: consider combining the bounds: `"D: SerializeWith": "D: SerializeWith"`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
       --> test_suite/tests/test_gen.rs:231:21
        |
    231 |             bound = "E: SerializeWith + DeserializeWith"
        |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: consider combining the bounds: `"E: SerializeWith + DeserializeWith": "E: SerializeWith + DeserializeWith" + "E: SerializeWith + DeserializeWith"`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
       --> test_suite/tests/test_gen.rs:221:21
        |
    221 |     #[serde(bound = "D: SerializeWith + DeserializeWith")]
        |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
        |
        = help: consider combining the bounds: `"D: SerializeWith + DeserializeWith": "D: SerializeWith + DeserializeWith" + "D: SerializeWith + DeserializeWith"`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
       --> test_suite/tests/test_gen.rs:247:31
        |
    247 |             bound(serialize = "E: SerializeWith")
        |                               ^^^^^^^^^^^^^^^^^^
        |
        = help: consider combining the bounds: `"E: SerializeWith": "E: SerializeWith"`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
       --> test_suite/tests/test_gen.rs:238:31
        |
    238 |     #[serde(bound(serialize = "D: SerializeWith", deserialize = "D: DeserializeWith"))]
        |                               ^^^^^^^^^^^^^^^^^^
        |
        = help: consider combining the bounds: `"D: SerializeWith": "D: SerializeWith"`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
      --> test_suite/tests/test_annotations.rs:84:5
       |
    84 |     C: MyDefault,
       |     ^^^^^^^^^^^^
       |
       = note: `-D clippy::type-repetition-in-bounds` implied by `-D clippy::pedantic`
       = help: consider combining the bounds: `C: MyDefault`
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
      --> test_suite/tests/test_annotations.rs:85:5
       |
    85 |     E: MyDefault,
       |     ^^^^^^^^^^^^
       |
       = help: consider combining the bounds: `E: MyDefault`
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
       --> test_suite/tests/test_annotations.rs:105:5
        |
    105 |     C: MyDefault;
        |     ^^^^^^^^^^^^
        |
        = help: consider combining the bounds: `C: MyDefault`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
        --> test_suite/tests/test_annotations.rs:1066:5
         |
    1066 |     B: 'a,
         |     ^^^^^
         |
         = help: consider combining the bounds: ``
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
        --> test_suite/tests/test_annotations.rs:1067:5
         |
    1067 |     D: SerializeWith,
         |     ^^^^^^^^^^^^^^^^
         |
         = help: consider combining the bounds: `D: SerializeWith`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
        --> test_suite/tests/test_annotations.rs:1106:5
         |
    1106 |     B: SerializeWith,
         |     ^^^^^^^^^^^^^^^^
         |
         = help: consider combining the bounds: `B: SerializeWith`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
        --> test_suite/tests/test_annotations.rs:1150:5
         |
    1150 |     B: SerializeWith,
         |     ^^^^^^^^^^^^^^^^
         |
         = help: consider combining the bounds: `B: SerializeWith`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds

    error: this type has already been used as a bound predicate
        --> test_suite/tests/test_annotations.rs:1368:5
         |
    1368 |     B: DeserializeWith,
         |     ^^^^^^^^^^^^^^^^^^
         |
         = help: consider combining the bounds: `B: DeserializeWith`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds
2022-04-30 21:32:36 -07:00
David Tolnay 7ca13ff240 Ignore type_repetition_in_bounds lint that is incompatible with msrv
https://github.com/rust-lang/rust-clippy/issues/8772
2022-04-30 21:32:26 -07:00
David Tolnay 52391fd868 Inform clippy of supported compiler version in clippy.toml 2022-04-30 20:40:23 -07:00
David Tolnay 9b2d8dfc6b Add a miri test job in CI 2022-04-28 20:43:03 -07:00
David Tolnay 07ba7ea8dd Update workflows to actions/checkout@v3 2022-04-24 19:06:18 -07:00
David Tolnay 9f29f6bb4a Disable expandtest on miri 2022-04-24 16:01:52 -07:00
David Tolnay f6c104fd1d Ignore unused ignore attribute warning in some configurations 2022-04-24 16:01:22 -07:00
David Tolnay 8a3a6fb101 Disable ui test on miri 2022-04-24 15:21:17 -07:00
David Tolnay b5c3b5e8e5 Update ui test suite to nightly-2022-04-17 2022-04-16 23:48:27 -07:00
David Tolnay 996d171461 Merge pull request #2201 from atouchet/urls
Update some URLs
2022-04-14 02:50:36 -07:00
Alex Touchet e1c4517335 Update some URLs 2022-04-13 21:42:37 -07:00
David Tolnay 6e94a27c76 Merge pull request #2194 from serde-rs/exhaustive
Update exhaustive matching to syn 1.0.90
2022-03-28 10:27:27 -07:00
David Tolnay b23a768414 Update exhaustive matching to syn 1.0.90 2022-03-28 10:21:37 -07:00
David Tolnay 7e19ae8c94 Fix rust-version in serde_test Cargo.toml too
#2168
2022-01-25 14:49:56 -08:00
David Tolnay 404a1d142a Fix rust-version in Cargo.toml
Closes #2168.
2022-01-25 14:42:09 -08:00
David Tolnay 02bd79a0ba Release 1.0.136 2022-01-25 13:34:29 -08:00
David Tolnay c3ce2c934a Merge pull request #2167 from serde-rs/error128
Render 128-bit integer value into Visitor errors
2022-01-25 13:07:01 -08:00
David Tolnay 0d71ac84b5 Render 128-bit integer value into Visitor errors 2022-01-25 12:06:35 -08:00
David Tolnay 82c3eb7ba4 Add test of visitor error messages 2022-01-25 11:24:53 -08:00
David Tolnay 8932c852a5 Release 1.0.135 2022-01-22 16:04:17 -08:00
David Tolnay 9f3dd3c7c4 Merge pull request #2163 from serde-rs/discord
Add discord invite links
2022-01-22 11:23:32 -08:00
David Tolnay dd9b415ff9 Add discord invite links 2022-01-22 11:21:08 -08:00
David Tolnay 3bb4a5a4f6 Release 1.0.134 2022-01-20 22:22:30 -08:00
David Tolnay 6164627bea Merge pull request #2159 from serde-rs/nonzero
Write better Visitor for NonZero integers
2022-01-20 22:22:02 -08:00
David Tolnay 51aaf496d4 Write better Visitor for NonZero integers 2022-01-20 22:15:16 -08:00
David Tolnay bc66aeb0d3 Add tests of deserializing NonZero 2022-01-20 21:55:50 -08:00
David Tolnay 7e7044d457 Ignore clippy in number conversion tests 2022-01-20 21:38:31 -08:00
David Tolnay 5498dc0550 Add tests of num conversion errors 2022-01-20 21:37:16 -08:00
David Tolnay ff04e8be9b Improve coverage of num conversion in test suite 2022-01-20 21:16:50 -08:00
David Tolnay 69240c17c5 Eliminate macro from serialization tests 2022-01-20 20:37:08 -08:00
David Tolnay 237434f19c Accept ?Sized references in assert_ser_tokens 2022-01-20 20:21:04 -08:00
David Tolnay 1833914346 Eliminate macro from deserialization error tests 2022-01-20 19:58:45 -08:00
David Tolnay ab848060f2 Extract tests of deserialization errors to separate file 2022-01-20 19:58:01 -08:00
David Tolnay 7e39623f72 Implement test suite seq macro without tt muncher 2022-01-20 19:40:58 -08:00
David Tolnay 157dc44c51 Clean up test suite's macro formatting 2022-01-20 19:40:32 -08:00
David Tolnay 80d01a3a79 Tweak seq iterators in test suite 2022-01-20 19:40:13 -08:00
David Tolnay 343c060fc1 Adapt seq macro to not derail rustfmt 2022-01-20 19:38:51 -08:00
David Tolnay 21c1ab6c50 Format deserialization tests with rustfmt 2022-01-20 19:24:35 -08:00
David Tolnay 594ab7745d Reimplement deserialization tests without macro 2022-01-20 18:09:48 -08:00
David Tolnay 8cf0ba7fe2 Make serde_test build script buildable with older rustc 2022-01-20 17:59:21 -08:00
David Tolnay 34b52c0b83 Include build script in packaged serde_test crate 2022-01-20 17:52:25 -08:00
David Tolnay ec7ddc93cd Include 128-bit integers in test suite unconditionally 2022-01-20 15:45:07 -08:00
David Tolnay 55a7cedd73 Invert all build.rs cfgs
This allows non-Cargo builds to generally not get involved in cfgs. As
long as one is using a reasonably recent toolchain, no cfgs need to be
set and you'll get a fully-featured build.
2022-01-01 21:09:49 -08:00
David Tolnay 7af97c66b8 Release 1.0.133 2022-01-01 13:16:35 -08:00
David Tolnay 1f57084365 Merge pull request #2148 from serde-rs/deserializecontent
Optimize deserialization of recursive buffered types
2022-01-01 13:16:02 -08:00
David Tolnay 56bd369422 Optimize deserialization of recursive buffered types 2022-01-01 13:01:38 -08:00
David Tolnay ff259ec66b Detect warnings in CI 2022-01-01 11:52:55 -08:00
David Tolnay 6c54aafeb9 Document the atomic ordering in the Serialize impl 2021-12-23 11:44:31 -08:00
David Tolnay 5d41404e67 No need for the SeqCst load in test suite 2021-12-23 11:42:41 -08:00
David Tolnay 1eccb3c350 Resolve unnecessary_to_owned clippy lint in test suite
error: unnecessary use of `to_vec`
       --> test_suite/tests/test_de.rs:251:12
        |
    251 |     .chain(ignorable_tokens.to_vec().into_iter())
        |            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use: `ignorable_tokens.iter().copied()`
        |
        = note: `-D clippy::unnecessary-to-owned` implied by `-D clippy::all`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_to_owned
2021-12-17 18:25:04 -08:00
David Tolnay 77ae1c3bf7 Release 1.0.132 2021-12-16 11:06:42 -08:00
David Tolnay b85e28166c Update path to rustc target spec files 2021-12-16 11:05:58 -08:00
David Tolnay 0508cb50fc Merge pull request #2141 from Avimitin/risc-v
Enable atomic64 on riscv64 arch
2021-12-16 11:05:14 -08:00
Avimitin 84fdc7df69 Enable atomic64 on riscv64 arch
Signed-off-by: Avimitin <avimitin@gmail.com>
2021-12-14 20:30:28 +08:00
David Tolnay ab1ca04b2e Release 1.0.131 2021-12-08 18:47:15 -08:00
David Tolnay fb2fe409c8 Touch up PR 2116 2021-12-08 18:44:41 -08:00
David Tolnay 549fac7235 Merge pull request #2116 from tyranron/fix-unused-results
Fix `unused_results` complaining rustc lint in codegen for adjacently tagged enum
2021-12-08 18:43:31 -08:00
David Tolnay c375d8b19b Merge pull request #2124 from dtolnay/cbor
Change cbor link to new repo
2021-11-26 14:48:40 -08:00
David Tolnay 6cf507f808 Change cbor link to new repo 2021-11-26 14:43:09 -08:00
David Tolnay c3c1641c06 Remove workaround for redundant_field_names Clippy bug 2021-11-04 20:23:25 -07:00
David Tolnay 1fcda0ebdb Enable pedantic lints on test suite in CI 2021-11-04 20:21:48 -07:00
David Tolnay 8f16ac0a94 Move deny(clippy) to command line arguments in the CI job 2021-11-04 20:09:35 -07:00
David Tolnay 737f78c315 Ignore enum_variant_names Clippy lint in test suite
error: all variants have the same prefix: `Serialize`
        --> test_suite/tests/test_macros.rs:1741:5
         |
    1741 | /     enum E {
    1742 | |         #[serde(rename_all = "camelCase")]
    1743 | |         Serialize {
    1744 | |             serialize: bool,
    ...    |
    1756 | |         },
    1757 | |     }
         | |_____^
         |
         = note: `-D clippy::enum-variant-names` implied by `-D clippy::all`
         = help: remove the prefixes and use full paths to the variants instead of glob imports
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#enum_variant_names
2021-11-04 20:06:02 -07:00
David Tolnay 4a97386cb9 Clippy if_then_panic lint has been renamed to manual_assert 2021-11-04 19:57:14 -07:00
tyranron 5b32217877 Fix unused_results complaining rustc lint in codegen for adjacently tagged enum 2021-10-29 14:13:26 +03:00
David Tolnay 5b140361a3 Merge pull request #2102 from atouchet/url
Update URL
2021-10-14 16:33:22 -07:00
Alex Touchet 678351eac7 Update URL 2021-10-14 16:27:49 -07:00
David Tolnay 999c261d11 Ui test changes for trybuild 1.0.49 2021-10-08 02:46:15 -04:00
David Tolnay efbe574209 Update ui test files 2021-10-07 00:56:29 -04:00
David Tolnay 33b2677384 Suppress broken semicolon_if_nothing_returned lint
https://github.com/rust-lang/rust-clippy/issues/7768

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde/src/de/impls.rs:849:1
        |
    849 | / seq_impl!(
    850 | |     BinaryHeap<T: Ord>,
    851 | |     seq,
    852 | |     BinaryHeap::clear,
    ...   |
    855 | |     BinaryHeap::push
    856 | | );
        | |__^
        |
    note: the lint level is defined here
       --> serde/src/lib.rs:97:52
        |
    97  | #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
        |                                                    ^^^^^^^^^^^^^^^
        = note: `#[deny(clippy::semicolon_if_nothing_returned)]` implied by `#[deny(clippy::pedantic)]`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    849 + seq_impl!(
    850 +     BinaryHeap<T: Ord>,
    851 +     seq,
    852 +     BinaryHeap::clear,
    853 +     BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
    854 +     BinaryHeap::reserve,
      ...

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde/src/de/impls.rs:859:1
        |
    859 | / seq_impl!(
    860 | |     BTreeSet<T: Eq + Ord>,
    861 | |     seq,
    862 | |     BTreeSet::clear,
    ...   |
    865 | |     BTreeSet::insert
    866 | | );
        | |__^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    859 + seq_impl!(
    860 +     BTreeSet<T: Eq + Ord>,
    861 +     seq,
    862 +     BTreeSet::clear,
    863 +     BTreeSet::new(),
    864 +     nop_reserve,
      ...

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde/src/de/impls.rs:869:1
        |
    869 | / seq_impl!(
    870 | |     LinkedList<T>,
    871 | |     seq,
    872 | |     LinkedList::clear,
    ...   |
    875 | |     LinkedList::push_back
    876 | | );
        | |__^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    869 + seq_impl!(
    870 +     LinkedList<T>,
    871 +     seq,
    872 +     LinkedList::clear,
    873 +     LinkedList::new(),
    874 +     nop_reserve,
      ...

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde/src/de/impls.rs:879:1
        |
    879 | / seq_impl!(
    880 | |     HashSet<T: Eq + Hash, S: BuildHasher + Default>,
    881 | |     seq,
    882 | |     HashSet::clear,
    883 | |     HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
    884 | |     HashSet::reserve,
    885 | |     HashSet::insert);
        | |_____________________^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    879 + seq_impl!(
    880 +     HashSet<T: Eq + Hash, S: BuildHasher + Default>,
    881 +     seq,
    882 +     HashSet::clear,
    883 +     HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
    884 +     HashSet::reserve,
      ...

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde/src/de/impls.rs:888:1
        |
    888 | / seq_impl!(
    889 | |     VecDeque<T>,
    890 | |     seq,
    891 | |     VecDeque::clear,
    ...   |
    894 | |     VecDeque::push_back
    895 | | );
        | |__^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    888 + seq_impl!(
    889 +     VecDeque<T>,
    890 +     seq,
    891 +     VecDeque::clear,
    892 +     VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
    893 +     VecDeque::reserve,
      ...

    error: consider adding a `;` to the last statement for consistent formatting
        --> serde/src/de/impls.rs:1300:1
         |
    1300 | / map_impl!(
    1301 | |     BTreeMap<K: Ord, V>,
    1302 | |     map,
    1303 | |     BTreeMap::new());
         | |_____________________^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
         |
    1300 + map_impl!(
    1301 +     BTreeMap<K: Ord, V>,
    1302 +     map,
    1303 +     BTreeMap::new());;
         |

    error: consider adding a `;` to the last statement for consistent formatting
        --> serde/src/de/impls.rs:1306:1
         |
    1306 | / map_impl!(
    1307 | |     HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
    1308 | |     map,
    1309 | |     HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));
         | |___________________________________________________________________________________________^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
         |
    1306 + map_impl!(
    1307 +     HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
    1308 +     map,
    1309 +     HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));;
         |
2021-10-04 23:57:05 -04:00
David Tolnay 01ded9f405 Declare minimum Rust version in Cargo metadata 2021-10-02 02:43:22 -04:00
David Tolnay fc827ecec2 Resolve redundant_closure_for_method_calls clippy lints
error: redundant closure
      --> serde_derive/src/bound.rs:53:19
       |
    53 |         .flat_map(|predicates| predicates.to_vec());
       |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `[T]::to_vec`
       |
    note: the lint level is defined here
      --> serde_derive/src/lib.rs:18:22
       |
    18 | #![deny(clippy::all, clippy::pedantic)]
       |                      ^^^^^^^^^^^^^^^^
       = note: `#[deny(clippy::redundant_closure_for_method_calls)]` implied by `#[deny(clippy::pedantic)]`
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_for_method_calls

    error: redundant closure
      --> serde_derive/src/bound.rs:75:19
       |
    75 |         .flat_map(|predicates| predicates.to_vec());
       |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `[T]::to_vec`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#redundant_closure_for_method_calls
2021-09-30 00:31:49 -04:00
David Tolnay 5c785eee58 Ignore if_then_panic clippy lint
error: only a `panic!` in `if`-then statement
      --> serde_derive/src/internals/ctxt.rs:58:9
       |
    58 | /         if !thread::panicking() && self.errors.borrow().is_some() {
    59 | |             panic!("forgot to check for errors");
    60 | |         }
       | |_________^ help: try: `assert!(!!thread::panicking() && self.errors.borrow().is_some(), "forgot to check for errors");`
       |
    note: the lint level is defined here
      --> serde_derive/src/lib.rs:18:9
       |
    18 | #![deny(clippy::all, clippy::pedantic)]
       |         ^^^^^^^^^^^
       = note: `#[deny(clippy::if_then_panic)]` implied by `#[deny(clippy::all)]`
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
       --> serde_test/src/assert.rs:73:5
        |
    73  | /     if ser.remaining() > 0 {
    74  | |         panic!("{} remaining tokens", ser.remaining());
    75  | |     }
        | |_____^ help: try: `assert!(!ser.remaining() > 0, "{} remaining tokens", ser.remaining());`
        |
    note: the lint level is defined here
       --> serde_test/src/lib.rs:149:44
        |
    149 | #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
        |                                            ^^^^^^
        = note: `#[deny(clippy::if_then_panic)]` implied by `#[deny(clippy::all)]`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
       --> serde_test/src/assert.rs:126:5
        |
    126 | /     if ser.remaining() > 0 {
    127 | |         panic!("{} remaining tokens", ser.remaining());
    128 | |     }
        | |_____^ help: try: `assert!(!ser.remaining() > 0, "{} remaining tokens", ser.remaining());`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
       --> serde_test/src/assert.rs:166:5
        |
    166 | /     if de.remaining() > 0 {
    167 | |         panic!("{} remaining tokens", de.remaining());
    168 | |     }
        | |_____^ help: try: `assert!(!de.remaining() > 0, "{} remaining tokens", de.remaining());`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
       --> serde_test/src/assert.rs:180:5
        |
    180 | /     if de.remaining() > 0 {
    181 | |         panic!("{} remaining tokens", de.remaining());
    182 | |     }
        | |_____^ help: try: `assert!(!de.remaining() > 0, "{} remaining tokens", de.remaining());`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
       --> serde_test/src/assert.rs:220:5
        |
    220 | /     if de.remaining() > 0 {
    221 | |         panic!("{} remaining tokens", de.remaining());
    222 | |     }
        | |_____^ help: try: `assert!(!de.remaining() > 0, "{} remaining tokens", de.remaining());`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic

    error: only a `panic!` in `if`-then statement
        --> test_suite/tests/test_de.rs:1349:9
         |
    1349 | /         if de.remaining() > 0 {
    1350 | |             panic!("{} remaining tokens", de.remaining());
    1351 | |         }
         | |_________^ help: try: `assert!(!de.remaining() > 0, "{} remaining tokens", de.remaining());`
         |
         = note: `-D clippy::if-then-panic` implied by `-D clippy::all`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#if_then_panic
2021-09-30 00:31:49 -04:00
David Tolnay 819db93a3d Format with rustfmt 2021-09-29 2021-09-30 00:31:49 -04:00
David Tolnay a6690ea2fe Update ui test suite to nightly-2021-09-14 2021-09-14 19:13:54 -07:00
David Tolnay 65e1a50749 Release 1.0.130 2021-08-28 11:31:38 -07:00
David Tolnay 87d41b59fd Merge pull request #2081 from dtolnay/accessunsized
Enable unsized Map/SeqAccess types to use the impl for &mut
2021-08-28 11:11:57 -07:00
David Tolnay 3f120fb355 Enable unsized Map/SeqAccess types to use the impl for &mut 2021-08-28 10:59:51 -07:00
David Tolnay 2b92c80cc1 Release 1.0.129 2021-08-23 15:01:24 -07:00
David Tolnay c1c0ede452 Merge pull request #2080 from dtolnay/packeddrop
Support packed remote struct without destructuring
2021-08-23 15:00:50 -07:00
David Tolnay 4a66c5f33d Support packed remote struct without destructuring 2021-08-23 14:38:33 -07:00
David Tolnay 714c8a5586 Add test of packed struct that cannot be destructured
Currently fails:

    error[E0509]: cannot move out of type `RemotePackedNonCopyDef`, which implements the `Drop` trait
       --> test_suite/tests/test_gen.rs:876:10
        |
    876 | #[derive(Deserialize)]
        |          ^^^^^^^^^^^
        |          |
        |          cannot move out of here
        |          data moved here
        |          move occurs because `__v1` has type `std::string::String`, which does not implement the `Copy` trait
        |
        = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
2021-08-23 14:38:33 -07:00
David Tolnay dc0c0dcba1 Merge pull request #2079 from dtolnay/packedremote
Fix unaligned reference warnings on packed remote def
2021-08-23 14:38:21 -07:00
David Tolnay 54102ee7d0 Avoid generating ref patterns for fields of packed remote struct 2021-08-23 10:18:28 -07:00
David Tolnay 14accf7518 Add test of remote with a packed struct
Currently fails to build:

    error: reference to packed field is unaligned
       --> test_suite/tests/test_gen.rs:858:10
        |
    858 | #[derive(Serialize, Deserialize)]
        |          ^^^^^^^^^
        |
    note: the lint level is defined here
       --> test_suite/tests/test_gen.rs:5:9
        |
    5   | #![deny(warnings)]
        |         ^^^^^^^^
        = note: `#[deny(unaligned_references)]` implied by `#[deny(warnings)]`
        = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
        = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
        = note: this error originates in the derive macro `Serialize` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: reference to packed field is unaligned
       --> test_suite/tests/test_gen.rs:858:21
        |
    858 | #[derive(Serialize, Deserialize)]
        |                     ^^^^^^^^^^^
        |
        = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
        = note: fields of packed structs are not properly aligned, and creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
        = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
2021-08-23 10:18:05 -07:00
David Tolnay 55fdbea20b Merge pull request #2077 from dtolnay/tryfold
Use try_fold in default implementation of collect_seq, collect_map
2021-08-21 14:08:20 -07:00
David Tolnay 75d8902371 Use try_fold in default implementation of collect_seq, collect_map 2021-08-21 14:00:51 -07:00
David Tolnay 9451ea8df1 Format PR 1992 with rustfmt 2021-08-21 12:49:58 -07:00
David Tolnay c1ce03b3dd Merge pull request 1992 from Mingun/unnecessary-deserialize-with 2021-08-21 12:49:39 -07:00
David Tolnay a587eb8953 Release 1.0.128 2021-08-21 10:39:32 -07:00
Oli Scherer 990f7eb6c1 Merge pull request #2076 from Manishearth/emscripten-i128
Enable 128-bit integers on emscripten post Rust 1.40
2021-08-21 19:19:30 +02:00
Manish Goregaokar 082e18f9a1 Rust supports i128/u128 on emscripten post Rust 1.40 2021-08-20 21:57:06 -07:00
David Tolnay f309485787 Ignore buggy collapsible_match clippy lint
https://github.com/rust-lang/rust-clippy/issues/7575
2021-08-16 19:32:10 -07:00
David Tolnay e2f85681fe Release 1.0.127 2021-07-30 20:59:13 -07:00
David Tolnay 8b840c3030 Resolve semicolon_in_expressions_from_macros warning in serde_test
warning: trailing semicolon in macro used in expression position
       --> serde_test/src/ser.rs:44:10
        |
    44  |         );
        |          ^
    ...
    152 |             Some(&Token::BorrowedStr(_)) => assert_next_token!(self, BorrowedStr(v)),
        |                                             ---------------------------------------- in this macro invocation
        |
        = note: `#[warn(semicolon_in_expressions_from_macros)]` on by default
        = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
        = note: this warning originates in the macro `assert_next_token` (in Nightly builds, run with -Z macro-backtrace for more info)

    warning: trailing semicolon in macro used in expression position
       --> serde_test/src/ser.rs:36:76
        |
    36  |         assert_next_token!($ser, stringify!($actual), Token::$actual, true);
        |                                                                            ^
    ...
    386 |             Token::TupleVariantEnd => assert_next_token!(self.ser, TupleVariantEnd),
        |                                       --------------------------------------------- in this macro invocation
        |
        = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
        = note: this warning originates in the macro `assert_next_token` (in Nightly builds, run with -Z macro-backtrace for more info)
2021-07-30 20:58:07 -07:00
David Tolnay 9c39115f82 Ignore buggy nonstandard_macro_braces clippy lint
Clippy bug: https://github.com/rust-lang/rust-clippy/issues/7422

    error: use of irregular braces for `format_args!` macro
       --> test_suite/tests/test_gen.rs:528:25
        |
    528 |     #[derive(Serialize, Deserialize)]
        |                         ^^^^^^^^^^^
        |
        = note: `-D clippy::nonstandard-macro-braces` implied by `-D clippy::all`
    help: consider writing `Deserialize`
       --> test_suite/tests/test_gen.rs:528:25
        |
    528 |     #[derive(Serialize, Deserialize)]
        |                         ^^^^^^^^^^^
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces
        = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)

    error: use of irregular braces for `format_args!` macro
        --> test_suite/tests/test_annotations.rs:1791:43
         |
    1791 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                                           ^^^^^^^^^^^
         |
         = note: `-D clippy::nonstandard-macro-braces` implied by `-D clippy::all`
    help: consider writing `Deserialize`
        --> test_suite/tests/test_annotations.rs:1791:43
         |
    1791 |     #[derive(Debug, PartialEq, Serialize, Deserialize)]
         |                                           ^^^^^^^^^^^
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#nonstandard_macro_braces
         = note: this error originates in the derive macro `Deserialize` (in Nightly builds, run with -Z macro-backtrace for more info)
2021-07-02 20:58:04 -07:00
David Tolnay 89342af71e Merge pull request #2047 from jsoref/spelling
spelling: implicitly
2021-06-24 22:25:58 -07:00
Josh Soref 3c5e2d11f6 spelling: implicitly
Signed-off-by: Josh Soref <jsoref@users.noreply.github.com>
2021-06-25 00:43:23 -04:00
David Tolnay 3805c037a8 Merge pull request #2040 from dtolnay/test
Fix outdated test instructions in CONTRIBUTING.md
2021-06-12 13:43:30 -07:00
David Tolnay 7045fee260 Fix outdated test instructions in CONTRIBUTING.md 2021-06-12 13:38:40 -07:00
David Tolnay 9d81532e41 Merge pull request #2039 from dtolnay/test
Update documented test command for the serde directory
2021-06-12 13:38:34 -07:00
David Tolnay 5e47432ef0 Update documented test command for the serde directory 2021-06-12 13:34:45 -07:00
Mingun e0fc46783d Add test with generic deserialize_with function 2021-06-12 18:47:08 +05:00
Mingun ca772a14f9 Get rid of useless DeserializeWith wrapper 2021-06-12 18:38:03 +05:00
David Tolnay 7b840897a9 Resolve needless_borrow clippy lints
error: this expression borrows a reference (`&syn::Type`) that is immediately dereferenced by the compiler
       --> serde_derive/src/internals/check.rs:399:37
        |
    399 |     if let Type::Path(ty) = ungroup(&field.ty) {
        |                                     ^^^^^^^^^ help: change this to: `field.ty`
        |
    note: the lint level is defined here
       --> serde_derive/src/lib.rs:18:9
        |
    18  | #![deny(clippy::all, clippy::pedantic)]
        |         ^^^^^^^^^^^
        = note: `#[deny(clippy::needless_borrow)]` implied by `#[deny(clippy::all)]`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

    error: this expression borrows a reference (`&str`) that is immediately dereferenced by the compiler
       --> serde_derive/src/de.rs:478:52
        |
    478 |         &type_path, params, fields, false, cattrs, &expecting,
        |                                                    ^^^^^^^^^^ help: change this to: `expecting`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

    error: this expression borrows a reference (`&str`) that is immediately dereferenced by the compiler
       --> serde_derive/src/de.rs:564:76
        |
    564 |     let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, &expecting));
        |                                                                            ^^^^^^^^^^ help: change this to: `expecting`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

    error: this expression borrows a reference (`&str`) that is immediately dereferenced by the compiler
       --> serde_derive/src/de.rs:925:51
        |
    925 |         &type_path, params, fields, true, cattrs, &expecting,
        |                                                   ^^^^^^^^^^ help: change this to: `expecting`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

    error: this expression borrows a reference (`&str`) that is immediately dereferenced by the compiler
        --> serde_derive/src/de.rs:1066:76
         |
    1066 |     let visit_seq = Stmts(deserialize_seq_in_place(params, fields, cattrs, &expecting));
         |                                                                            ^^^^^^^^^^ help: change this to: `expecting`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

    error: this expression borrows a reference (`&proc_macro2::TokenStream`) that is immediately dereferenced by the compiler
        --> serde_derive/src/de.rs:2288:80
         |
    2288 |         let fallthrough_borrowed_arm = fallthrough_borrowed.as_ref().unwrap_or(&fallthrough_arm);
         |                                                                                ^^^^^^^^^^^^^^^^ help: change this to: `fallthrough_arm`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow

    error: this expression borrows a reference (`&syn::Member`) that is immediately dereferenced by the compiler
        --> serde_derive/src/ser.rs:1102:43
         |
    1102 |                 get_member(params, field, &member)
         |                                           ^^^^^^^ help: change this to: `member`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
2021-06-04 20:58:23 -07:00
David Tolnay 967795414b Resolve semicolon_if_nothing_returned clippy lints
error: consider adding a `;` to the last statement for consistent formatting
       --> serde_derive/src/internals/attr.rs:559:25
        |
    559 |                         serde_path.set(&m.path, path)
        |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `serde_path.set(&m.path, path);`
        |
    note: the lint level is defined here
       --> serde_derive/src/lib.rs:18:22
        |
    18  | #![deny(clippy::all, clippy::pedantic)]
        |                      ^^^^^^^^^^^^^^^^
        = note: `#[deny(clippy::semicolon_if_nothing_returned)]` implied by `#[deny(clippy::pedantic)]`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned

    error: consider adding a `;` to the last statement for consistent formatting
        --> serde_derive/src/internals/attr.rs:1612:9
         |
    1612 |         cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()))
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()));`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned

    error: consider adding a `;` to the last statement for consistent formatting
        --> serde_derive/src/internals/attr.rs:1623:9
         |
    1623 |         cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()))
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `cx.error_spanned_by(lit, format!("failed to parse path: {:?}", string.value()));`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned

    error: consider adding a `;` to the last statement for consistent formatting
        --> serde_derive/src/internals/attr.rs:1649:9
         |
    1649 | /         cx.error_spanned_by(
    1650 | |             lit,
    1651 | |             format!("failed to parse type: {} = {:?}", attr_name, string.value()),
    1652 | |         )
         | |_________^
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
         |
    1649 |         cx.error_spanned_by(
    1650 |             lit,
    1651 |             format!("failed to parse type: {} = {:?}", attr_name, string.value()),
    1652 |         );
         |

    error: consider adding a `;` to the last statement for consistent formatting
       --> serde_derive/src/internals/check.rs:260:9
        |
    260 | /         cx.error_spanned_by(
    261 | |             cont.original,
    262 | |             format!("variant field name `{}` conflicts with internal tag", tag),
    263 | |         )
        | |_________^
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
    help: add a `;` here
        |
    260 |         cx.error_spanned_by(
    261 |             cont.original,
    262 |             format!("variant field name `{}` conflicts with internal tag", tag),
    263 |         );
        |

    error: consider adding a `;` to the last statement for consistent formatting
        --> serde_derive/src/de.rs:2090:9
         |
    2090 |         flat_fields.extend(aliases.iter().map(|alias| (alias, ident)))
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add a `;` here: `flat_fields.extend(aliases.iter().map(|alias| (alias, ident)));`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#semicolon_if_nothing_returned
2021-06-04 20:55:22 -07:00
David Tolnay 985725f820 Resolve while_let_on_iterator clippy lint
error: this loop could be written as a `for` loop
        --> serde/src/private/de.rs:2835:9
         |
    2835 |         while let Some(item) = self.iter.next() {
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for item in &mut self.iter`
         |
    note: the lint level is defined here
        --> serde/src/lib.rs:97:44
         |
    97   | #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
         |                                            ^^^^^^
         = note: `#[deny(clippy::while_let_on_iterator)]` implied by `#[deny(clippy::all)]`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator

    error: this loop could be written as a `for` loop
        --> serde/src/private/de.rs:2937:9
         |
    2937 |         while let Some(item) = self.iter.next() {
         |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `for item in &mut self.iter`
         |
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#while_let_on_iterator
2021-05-22 20:29:34 -07:00
David Tolnay 0c303d85d7 Merge pull request #2027 from striezel-stash/fix-typos
fix some typos
2021-05-15 10:14:13 -07:00
Dirk Stolle f68e9e901e fix some typos 2021-05-15 16:18:05 +02:00
David Tolnay 1094e2d334 Update ui test suite to nightly-2021-05-14 2021-05-13 19:16:07 -07:00
David Tolnay d9c338ec4a Release 1.0.126 2021-05-12 10:18:26 -07:00
David Tolnay 699bf3a75d Merge pull request #2026 from hyd-dev/warning
Allow only `unused_extern_crates` instead of the whole `rust_2018_idioms` lint group in `serde_derive`-generated code
2021-05-12 10:16:47 -07:00
hyd-dev dd29825217 Allow only unused_extern_crates instead of the whole rust_2018_idioms lint group in serde_derive-generated code 2021-05-12 18:29:45 +08:00
David Tolnay 6366f17da7 Ignore clone_instead_of_copied pedantic clippy lint
Iterator::copied was introduced in Rust 1.35, whereas serde_test
currently supports a minimum compiler version of 1.13.

    error: used `cloned` where `copied` could be used instead
       --> serde_test/src/de.rs:49:29
        |
    49  |         self.tokens.first().cloned()
        |                             ^^^^^^ help: try: `copied`
        |
    note: the lint level is defined here
       --> serde_test/src/lib.rs:149:52
        |
    149 | #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
        |                                                    ^^^^^^^^^^^^^^^
        = note: `#[deny(clippy::cloned_instead_of_copied)]` implied by `#[deny(clippy::pedantic)]`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#cloned_instead_of_copied
2021-04-24 19:26:19 -07:00
David Tolnay 1120e5af4a Remove suppression of removed clippy lint
warning: lint `clippy::filter_map` has been removed: this lint has been replaced by `manual_filter_map`, a more specific lint
      --> serde_derive/src/lib.rs:42:5
       |
    42 |     clippy::filter_map,
       |     ^^^^^^^^^^^^^^^^^^
       |
       = note: `#[warn(renamed_and_removed_lints)]` on by default

    warning: lint `clippy::filter_map` has been removed: this lint has been replaced by `manual_filter_map`, a more specific lint
      --> serde_derive/src/lib.rs:42:5
       |
    42 |     clippy::filter_map,
       |     ^^^^^^^^^^^^^^^^^^
2021-04-24 19:23:56 -07:00
David Tolnay 1093f7e232 Resolve flat_map_option pedantic clippy lint
error: used `flat_map` where `filter_map` could be used instead
      --> serde_derive/src/bound.rs:52:10
       |
    52 |         .flat_map(|field| from_field(&field.attrs))
       |          ^^^^^^^^ help: try: `filter_map`
       |
    note: the lint level is defined here
      --> serde_derive/src/lib.rs:18:22
       |
    18 | #![deny(clippy::all, clippy::pedantic)]
       |                      ^^^^^^^^^^^^^^^^
       = note: `#[deny(clippy::flat_map_option)]` implied by `#[deny(clippy::pedantic)]`
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#flat_map_option

    error: used `flat_map` where `filter_map` could be used instead
      --> serde_derive/src/bound.rs:74:10
       |
    74 |         .flat_map(|variant| from_variant(&variant.attrs))
       |          ^^^^^^^^ help: try: `filter_map`
       |
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#flat_map_option
2021-04-24 19:23:21 -07:00
David Tolnay 2ea132b8c4 Merge pull request #2018 from dtolnay/nonascii
Remove non_ascii_idents feature gate from test suite
2021-04-19 20:24:51 -07:00
David Tolnay 2ebc771b88 Remove non_ascii_idents feature gate from test suite
error: the feature `non_ascii_idents` has been stable since 1.53.0 and no longer requires an attribute to enable
     --> test_suite/tests/test_gen.rs:6:43
      |
    6 | #![cfg_attr(feature = "unstable", feature(non_ascii_idents))]
      |                                           ^^^^^^^^^^^^^^^^
      |
    note: the lint level is defined here
     --> test_suite/tests/test_gen.rs:5:9
      |
    5 | #![deny(warnings)]
      |         ^^^^^^^^
      = note: `#[deny(stable_features)]` implied by `#[deny(warnings)]`
2021-04-19 19:55:12 -07:00
David Tolnay c17c4eef18 Unify stable and beta CI workflow 2021-04-19 19:54:56 -07:00
David Tolnay 7aa4950504 Release serde_derive_internals 0.26.0 2021-04-09 14:23:13 -07:00
David Tolnay 47015a2727 Merge pull request #2015 from dtolnay/symlink
Build using relative path in repo if Windows lost the symlink
2021-04-09 14:20:55 -07:00
David Tolnay dc4c31eb50 Build using relative path in repo if Windows lost symlink 2021-04-09 14:16:17 -07:00
David Tolnay b53ebef438 Resolve safe_packed_borrows lint renamed to unaligned_references
warning: lint `safe_packed_borrows` has been renamed to `unaligned_references`
        --> test_suite/tests/test_macros.rs:1926:8
         |
    1926 | #[deny(safe_packed_borrows)]
         |        ^^^^^^^^^^^^^^^^^^^ help: use the new name: `unaligned_references`
         |
         = note: `#[warn(renamed_and_removed_lints)]` on by default
2021-04-08 20:08:42 -07:00
David Tolnay 6c3bf7a2fc Ignore poor suggestion from branches_sharing_code lint
https://github.com/rust-lang/rust-clippy/issues/7054

    error: all if blocks contain the same code at the end
        --> serde_derive/src/de.rs:2160:5
         |
    2160 | /         &fallthrough_arm_tokens
    2161 | |     };
         | |_____^
         |
    note: the lint level is defined here
        --> serde_derive/src/lib.rs:18:9
         |
    18   | #![deny(clippy::all, clippy::pedantic)]
         |         ^^^^^^^^^^^
         = note: `#[deny(clippy::branches_sharing_code)]` implied by `#[deny(clippy::all)]`
         = note: The end suggestion probably needs some adjustments to use the expression result correctly
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#branches_sharing_code
    help: consider moving the end statements out like this
         |
    2160 |     }
    2161 |     &fallthrough_arm_tokens;
         |
2021-04-08 20:08:42 -07:00
David Tolnay ce0844b9ec Suppress match_wildcard_for_single_variants clippy false positive
https://github.com/rust-lang/rust-clippy/issues/6984

    error: wildcard matches only a single variant and will also match any future added variants
        --> serde_derive/src/internals/attr.rs:1918:9
         |
    1918 |         _ => {}
         |         ^ help: try this: `syn::Type::__TestExhaustive(_)`
         |
    note: the lint level is defined here
        --> serde_derive/src/lib.rs:18:22
         |
    18   | #![deny(clippy::all, clippy::pedantic)]
         |                      ^^^^^^^^^^^^^^^^
         = note: `#[deny(clippy::match_wildcard_for_single_variants)]` implied by `#[deny(clippy::pedantic)]`
         = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants

    error: wildcard matches only a single variant and will also match any future added variants
       --> serde_derive/src/internals/receiver.rs:153:13
        |
    153 |             _ => {}
        |             ^ help: try this: `Type::__TestExhaustive(_)`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants

    error: wildcard matches only a single variant and will also match any future added variants
       --> serde_derive/src/bound.rs:190:17
        |
    190 |                 _ => {}
        |                 ^ help: try this: `syn::Type::__TestExhaustive(_)`
        |
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#match_wildcard_for_single_variants
2021-03-26 23:30:15 -04:00
David Tolnay e9270e59f0 Release 1.0.125 2021-03-22 16:15:57 -07:00
David Tolnay 72060b779a Extend test_format_u8 to include u8::MAX
This is equivalent to looping 0..=u8::MAX, except that `..=` syntax is
not supported on old rustc and `...` syntax is not supported on new
rustc, so loop it is.
2021-03-22 16:09:33 -07:00
David Tolnay 1bb23ad9d1 Remove format_u8 when not used by Ipv4Addr impl 2021-03-22 16:00:58 -07:00
David Tolnay 9be4c9654a Merge pull request 2001 from saethlin/optimize-ipaddr 2021-03-22 16:00:11 -07:00
Ben Kimock 4114e90bac Fix off-by-one mistake, explain the offset 2021-03-22 18:39:24 -04:00
Ben Kimock 8bb07b0743 skip UTF8 checking and initialize with b'.' 2021-03-22 18:15:50 -04:00
Ben Kimock ba8c1d63c8 use the algorithm from itoa 2021-03-16 17:33:42 -04:00
Ben Kimock 857a805993 Faster Ipv4 serialization prototype 2021-03-16 10:41:13 -04:00
David Tolnay 5a8dcac2ed Release 1.0.124 2021-03-05 19:55:40 -08:00
David Tolnay 697b082e90 Touch up PR 1997 2021-03-05 19:48:40 -08:00
David Tolnay d91075c8d5 Merge pull request #1997 from cyang1/systemtime-panics
Prevent various panics when deserializing malformed SystemTime
2021-03-05 18:35:48 -08:00
Cary Yang 4118cec731 Prevent various panics when deserializing malformed SystemTime 2021-03-05 17:52:51 -08:00
David Tolnay c261015325 Ignore incorrect suggestion from manual_map lint
https://github.com/rust-lang/rust-clippy/issues/6797

    error[E0382]: use of partially moved value: `self`
       --> serde_derive/src/internals/attr.rs:71:24
        |
    71  |         self.value.map(|value| (self.tokens, value))
        |                    ----^^^^^^^----------------------
        |                    |   |        |
        |                    |   |        use occurs due to use in closure
        |                    |   value used here after partial move
        |                    `self.value` partially moved due to this method call
        |
    note: this function takes ownership of the receiver `self`, which moves `self.value`
       --> /home/david/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/option.rs:485:38
        |
    485 |     pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Option<U> {
        |                                      ^^^^
        = note: partial move occurs because `self.value` has type `std::option::Option<T>`, which does not implement the `Copy` trait
2021-02-25 20:53:45 -08:00
David Tolnay 6b5e5a83d0 Ignore let_underscore_drop pedantic clippy lint 2021-02-18 19:31:39 -08:00
David Tolnay bc6b2b1dee Make json5 description capitalization consistent with other links 2021-02-10 23:13:12 -08:00
David Tolnay beb21cb640 Ignore new missing_panics_doc pedantic clippy lint 2021-02-03 20:07:44 -08:00
David Tolnay 7cfebbcd72 Merge pull request #1974 from Mingun/new-internally-tagged-tests
New internally tagged tests
2021-02-02 15:23:10 -08:00
Mingun b60c03ec3f Extend test_internally_tagged_newtype_variant_containing_unit_struct to cover structs and seqs 2021-02-02 09:00:04 +05:00
Mingun 3257851192 Extend test_internally_tagged_struct_variant_containing_unit_variant to cover maps and seqs 2021-02-02 08:59:59 +05:00
David Tolnay 9a84622c56 Merge pull request #1971 from arthurprs/untagged-enum-fix-pr
Allow floats to be deserialized from ints in untagged unions (part 2)
2021-01-26 14:41:56 -08:00
Arthur Silva de8ac1c0be Allow floats to be deserialized from ints in untagged unions 2021-01-26 17:47:20 +01:00
David Tolnay 3d6c4149b1 Release 1.0.123 2021-01-25 13:43:11 -08:00
David Tolnay 29cdf888c0 Merge pull request #1970 from serde-rs/self
Support `Self` inside fields that use serialize_with
2021-01-25 13:42:35 -08:00
David Tolnay 2ba97394fb Substitute Self in output of Serialize derive 2021-01-25 13:34:09 -08:00
David Tolnay 6699b0bc40 Add regression test for issue 1969 2021-01-25 13:34:08 -08:00
David Tolnay b054ea4105 Ignore some pedantic lints in serde_derive_internals from PR 1830
error: item name ends with its containing module's name
      --> serde_derive_internals/src/receiver.rs:11:1
       |
    11 | / pub fn replace_receiver(input: &mut DeriveInput) {
    12 | |     let self_ty = {
    13 | |         let ident = &input.ident;
    14 | |         let ty_generics = input.generics.split_for_impl().1;
    ...  |
    19 | |     visitor.visit_data_mut(&mut input.data);
    20 | | }
       | |_^
       |
    note: the lint level is defined here
      --> serde_derive_internals/lib.rs:3:22
       |
    3  | #![deny(clippy::all, clippy::pedantic)]
       |                      ^^^^^^^^^^^^^^^^
       = note: `#[deny(clippy::module_name_repetitions)]` implied by `#[deny(clippy::pedantic)]`
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#module_name_repetitions

    error: binding's name is too similar to existing binding
      --> serde_derive_internals/src/receiver.rs:31:29
       |
    31 |     fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) {
       |                             ^^^^^
       |
    note: the lint level is defined here
      --> serde_derive_internals/lib.rs:3:22
       |
    3  | #![deny(clippy::all, clippy::pedantic)]
       |                      ^^^^^^^^^^^^^^^^
       = note: `#[deny(clippy::similar_names)]` implied by `#[deny(clippy::pedantic)]`
    note: existing binding defined here
      --> serde_derive_internals/src/receiver.rs:31:23
       |
    31 |     fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) {
       |                       ^^^^
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#similar_names

    error: unused `self` argument
       --> serde_derive_internals/src/receiver.rs:286:24
        |
    286 |     fn visit_macro_mut(&mut self, _mac: &mut Macro) {}
        |                        ^^^^^^^^^
        |
    note: the lint level is defined here
       --> serde_derive_internals/lib.rs:3:22
        |
    3   | #![deny(clippy::all, clippy::pedantic)]
        |                      ^^^^^^^^^^^^^^^^
        = note: `#[deny(clippy::unused_self)]` implied by `#[deny(clippy::pedantic)]`
        = help: consider refactoring to a associated function
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unused_self
2021-01-25 00:03:03 -08:00
David Tolnay e5efb6ad93 Remove dependency on syn/visit-mut feature 2021-01-24 23:56:57 -08:00
David Tolnay 1f423580a5 Deduplicate token stream respanner 2021-01-24 23:06:08 -08:00
David Tolnay 033114a4ae Touch up PR 1830 2021-01-24 23:06:07 -08:00
David Tolnay 7cec99c7fd Pare down PR 1830
Unlike expr macros, macros in type position in a derive input are rare
enough that it's not worth supporting for an issue that has such an easy
workaround (just replace `Self` in the macro input with your type name).
2021-01-24 23:06:06 -08:00
David Tolnay 6c5bf701be Merge pull request 1830 from taiki-e/self 2021-01-24 23:05:51 -08:00
David Tolnay 6e800ff826 Test exhaustiveness of type match in collect_lifetimes 2021-01-24 23:04:01 -08:00
David Tolnay 68bda7a004 Include serde crate in 1.31 CI job 2021-01-24 20:42:20 -08:00
David Tolnay dfeaf77bb2 Merge pull request #1966 from serde-rs/private
Omit derive helpers in versions older than serde_derive msrv
2021-01-24 20:40:06 -08:00
David Tolnay b0cc213e57 Omit derive helpers in versions older than serde_derive msrv 2021-01-24 20:26:56 -08:00
David Tolnay 74ca06662e Omit size_hint::cautious when not allocating 2021-01-24 20:24:03 -08:00
David Tolnay 38edb473de Move size_hint module out of private::de 2021-01-24 20:23:07 -08:00
David Tolnay 1c03647656 Move InPlaceSeed out of private mod 2021-01-24 20:23:06 -08:00
David Tolnay aeee73fe92 Merge pull request #1831 from taiki-e/borrow-macro
Collect lifetimes inside macro invocations
2021-01-24 19:08:20 -08:00
David Tolnay 1a3ef39040 Merge pull request #1842 from Timmmm/fix2
Allow floats to be deserialized from ints in tagged unions
2021-01-24 18:48:46 -08:00
David Tolnay deaf600af7 Merge pull request #1965 from serde-rs/int
Reduce post-macro-expansion code in integer deserialize impls
2021-01-24 18:43:36 -08:00
David Tolnay 48556a4c7f Reduce post-macro-expansion code in integer deserialize impls 2021-01-24 18:26:50 -08:00
David Tolnay d88a4748f7 Remove unused $ty arg from internal impl_deserialize_num macro 2021-01-24 17:06:36 -08:00
David Tolnay ffed19243d Release 1.0.122 2021-01-24 16:17:29 -08:00
David Tolnay bb7f94df84 Add serde_derive_internals to clippy CI job 2021-01-24 16:11:37 -08:00
David Tolnay ff0f467e25 Opt in to pedantic clippy lints in serde_derive_internals 2021-01-24 16:10:36 -08:00
David Tolnay d1975f3661 Update serde_derive_internals to tool attrs 2021-01-24 16:08:42 -08:00
David Tolnay b91713e824 Suppress clippy should_implement_trait lint
I think there is no ambiguity in from_str as a method name so "choose a
less ambiguous method name" is unnecessary, and it can't be a FromStr
impl in this case because FromStr's error type cannot borrow from the
input string slice.

    warning: method `from_str` can be confused for the standard trait method `std::str::FromStr::from_str`
      --> serde_derive_internals/src/case.rs:50:5
       |
    50 | /     pub fn from_str(rename_all_str: &str) -> Result<Self, ParseError> {
    51 | |         for (name, rule) in RENAME_RULES {
    52 | |             if rename_all_str == *name {
    53 | |                 return Ok(*rule);
    ...  |
    58 | |         })
    59 | |     }
       | |_____^
       |
       = note: `#[warn(clippy::should_implement_trait)]` on by default
       = help: consider implementing the trait `std::str::FromStr` or choosing a less ambiguous method name
       = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#should_implement_trait
2021-01-24 16:04:51 -08:00
David Tolnay 6ea446fb4b Suppress clippy unused_self pedantic lint
This usage is fine. It's mirroring trait signatures in syn::visit::Visit.

    error: unused `self` argument
       --> serde_derive/src/bound.rs:241:24
        |
    241 |         fn visit_macro(&mut self, _mac: &'ast syn::Macro) {}
        |                        ^^^^^^^^^
        |
    note: the lint level is defined here
       --> serde_derive/src/lib.rs:18:22
        |
    18  | #![deny(clippy::all, clippy::pedantic)]
        |                      ^^^^^^^^^^^^^^^^
        = note: `#[deny(clippy::unused_self)]` implied by `#[deny(clippy::pedantic)]`
        = help: consider refactoring to a associated function
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#unused_self
2021-01-24 16:01:05 -08:00
David Tolnay 85c6904a93 Remove dependency on syn/visit feature
The builtin visitor is fairly expensive to compile (3700 lines of code),
particularly if something else in the dependency graph also enables
syn/full. For the usage in serde_derive, it turns out to be easy to
replace.
2021-01-24 15:50:41 -08:00
David Tolnay 2fd5212204 Remove unused trait impls on private MapAsEnum 2021-01-23 23:19:48 -08:00
David Tolnay 7d1bc1f0fc Merge pull request #1963 from serde-rs/valuedebug
Eliminate inferred bound on error type of value deserializer Debug impls
2021-01-23 23:19:36 -08:00
David Tolnay cdc2fa1b9f Eliminate inferred bound on error type of value deserializer Debug impls 2021-01-23 23:15:41 -08:00
David Tolnay ac4001e590 Remove some unused trait impls from private UnitOnly variant accessor 2021-01-23 23:07:13 -08:00
David Tolnay fbcb2230bb Make use of fmt::Result type alias from libcore 2021-01-23 22:57:13 -08:00
David Tolnay 86c88bea12 Hide some irrelevant detail from de::value::Error's Debug impl 2021-01-23 22:49:00 -08:00
David Tolnay 82d0fe00fd Add link to rust-lang/rust#67295 2021-01-23 22:32:30 -08:00
David Tolnay e61261e002 Move doctest-only helpers to a doc module 2021-01-23 22:32:30 -08:00
David Tolnay 9fd56cd41c Remove unused __private_deserialize macro, originally for doctests 2021-01-23 22:26:16 -08:00
Taiki Endo e81f54fbc8 Make AST borrow checker happy 2021-01-24 15:23:54 +09:00
Taiki Endo c67017d466 Fix handling of Self keyword in type definition 2021-01-24 15:23:51 +09:00
David Tolnay f6e7366b46 Remove unused Debug impl on private::ser::content::Content 2021-01-23 22:10:48 -08:00
David Tolnay 1f9f72bc48 Merge pull request 1898 from Mingun/bytes-into-deserializer 2021-01-23 22:04:20 -08:00
David Tolnay e24dbc418d Skip another clone of the fallthrough arm 2021-01-23 20:52:03 -08:00
David Tolnay 18e5b03fd1 Merge pull request #1962 from serde-rs/dupborrowed
Eliminate duplicated borrowed and non-borrowed identifier deserialization
2021-01-23 20:51:56 -08:00
David Tolnay 5aa163f27e Revert "Regenerate macrotest outputs for PR #1917"
This reverts commit 999b94d6ae.
2021-01-23 20:36:26 -08:00
David Tolnay 3728d3c67a Eliminate duplicated borrowed and non-borrowed identifier deserialization 2021-01-23 20:32:38 -08:00
David Tolnay 3f48ed36cc Restore compatibility with rustc <1.31 in Borrowed identifier deserializer
The implied lifetime bound on T only works on 1.31+. Older versions fail
with:

    error[E0309]: the parameter type `T` may not live long enough
        --> serde/src/private/de.rs:2548:37
         |
    2548 | pub struct Borrowed<'de, T: ?Sized>(pub &'de T);
         |                          --         ^^^^^^^^^^
         |                          |
         |                          help: consider adding an explicit lifetime bound `T: 'de`...
         |
    note: ...so that the reference type `&'de T` does not outlive the data it points at
        --> serde/src/private/de.rs:2548:37
         |
    2548 | pub struct Borrowed<'de, T: ?Sized>(pub &'de T);
         |                                     ^^^^^^^^^^
2021-01-23 20:19:33 -08:00
David Tolnay b6a2d07f26 Return IdentifierDeserializer to just one associated type
The BorrowedDeserializer was added in #1917, but only makes sense for
&str and &[u8], not for u64 which also needs to be have an
IdentifierDeserializer impl.
2021-01-23 20:04:58 -08:00
David Tolnay 84ad76b2e5 Ignore too_many_lines clippy pedantic lint in serde_test
error: this function has too many lines (107/100)
       --> serde_test/src/de.rs:128:5
        |
    128 | /     fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
    129 | |     where
    130 | |         V: Visitor<'de>,
    131 | |     {
    ...   |
    238 | |         }
    239 | |     }
        | |_____^
        |
    note: the lint level is defined here
       --> serde_test/src/lib.rs:149:52
        |
    149 | #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
        |                                                    ^^^^^^^^^^^^^^^
        = note: `#[deny(clippy::too_many_lines)]` implied by `#[deny(clippy::pedantic)]`
        = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#too_many_lines
2021-01-23 20:04:30 -08:00
David Tolnay e6b6602a42 Merge pull request 1914 from Mingun/seq-other 2021-01-23 19:50:39 -08:00
David Tolnay 999b94d6ae Regenerate macrotest outputs for PR #1917 2021-01-23 19:43:02 -08:00
David Tolnay fa6712d2bf Merge pull request #1918 from Mingun/fix-serde-test
Fix incorrect message in serializer tokens and correctly implement next_entry_seed
2021-01-23 15:02:32 -08:00
David Tolnay 012ea8eb84 Keep conditional compilation cfg naming consistent with serde crate
The serde crate's build.rs uses names like `core_duration` or
`integer128`, not `has_core_duration` / `has_integer128`.
2021-01-23 14:57:12 -08:00
David Tolnay 9add5812e2 Update track_caller cfg link to show what version it's in 2021-01-23 14:56:03 -08:00
David Tolnay 5fd52100b6 Merge pull request #1920 from Mingun/track_caller
Show correct location in error messages by tracking caller of utility `assert_tokens` functions
2021-01-23 14:54:24 -08:00
David Tolnay 6670a309ca Merge pull request #1961 from serde-rs/renamerule
Provide list of recognized rename rules on parse error
2021-01-23 14:50:02 -08:00
David Tolnay b7bad3a165 Restore compatibility with rustc 1.31 in RenameRule error
str::escape_debug wasn't stabilized until 1.34, whereas serde_derive
currently supports an oldest version of 1.31.
2021-01-23 14:40:44 -08:00
David Tolnay 4e002ece07 Provide list of recognized rename rules on parse error 2021-01-23 14:38:20 -08:00
David Tolnay eaccae2c46 Fix UPPERCASE rename rule variant to follow idiomatic variant naming
This shouldn't have been named this way in PR #1132.
2021-01-23 14:27:33 -08:00
David Tolnay 990a502c39 Parse rename rules based on table of rules
This will make it possible to reuse the same table of recognized rules
in the parse error message.
2021-01-23 14:24:21 -08:00
David Tolnay 661206d885 Merge pull request #1960 from serde-rs/renamerule
Deduplicate RenameRule parse error message generation
2021-01-23 14:23:09 -08:00
David Tolnay 51d4563ed1 Move RenameRule parse error message to a Display impl 2021-01-23 14:13:47 -08:00
David Tolnay 7db0982e58 Add error type to use for RenameRule parsing 2021-01-23 14:09:58 -08:00
David Tolnay ed04824f10 Move RenameRule parse from trait fn to associated
This will allow updating it to return an Err that borrows the input
string, which is not possible with FromStr.
2021-01-23 14:07:59 -08:00
David Tolnay 88ee470a1c Format PR #1916 with rustfmt 1.4.32 2021-01-23 13:39:12 -08:00
David Tolnay a5ecbdb4f4 Merge pull request 1916 from Mingun/expecting-customize 2021-01-23 13:38:45 -08:00
Mingun 5cbc8439ea Show correct location in error messages by tracking caller of utility assert_tokens functions 2020-10-28 09:11:54 +05:00
Mingun 97c350a95e Forward Readable|Compact next_entry_seed to underlying next_entry_seed instead of usage of default implementation
Difference is noticeable for deserializers that rely on call of next_entry_seed
(for example, current quick-xml supports only next_entry_seed)
2020-10-28 01:05:27 +05:00
Mingun 920a77ad61 Fix incorrect messages in serialized tokens assertions
Serializer contains expected tokens, called methods provide actual tokens
2020-10-28 01:05:27 +05:00
Taiki Endo a227a87865 Collect lifetimes inside macro invocations 2020-10-24 05:29:47 +09:00
Mingun 104ad9a7dd Allow to define custom expectation message for type with #[serde(expecting = "...")]
Closes #1883
2020-10-23 01:23:01 +05:00
Mingun 23c14e5f33 Allow to run assert_de_tokens_error on token sequence that is not expected by enum deserializer
Before that fix following code panics, because `Token::Unit` was unexpected by test deserializer:
```
#[derive(Deserialize)]
enum E { ... }

assert_de_tokens_error::<E>(&[Token::Unit], "...");
```
2020-10-22 23:50:48 +05:00
Mingun e80571751d Allow borrowed and owned strings and bytes and u8, u16, u64 for variant keys in serde_test 2020-10-22 20:43:14 +05:00
Mingun 0737474640 Allow field identifiers be any numbers if #[serde(other)] is used
Thus behavior synchronized between string/bytes identifiers and numeric identifiers
2020-10-22 16:35:28 +05:00
Mingun 34de1e00c8 Implement IdentifierDeserializer for u64 instead of u32 because all identifiers deserialized with visit_u64 2020-10-22 16:35:28 +05:00
Mingun f6eb34a830 Assert that numeric field identifiers correctly deserialized (now failing) 2020-10-22 16:35:28 +05:00
Mingun db3074a40f Implement IntoDeserializer for Cow<[u8]> 2020-10-04 13:38:31 +05:00
Mingun 2e821eab4b Make impl IntoDeserializer for &[u8] public 2020-10-03 16:43:31 +05:00
Tim Hutt 010444dfa4 Allow floats to be deserialized from ints in tagged unions 2020-06-22 16:31:13 +01:00
244 changed files with 11262 additions and 10083 deletions
+80 -64
View File
@@ -3,45 +3,52 @@ name: CI
on:
push:
pull_request:
workflow_dispatch:
schedule: [cron: "40 1 * * *"]
permissions:
contents: read
env:
RUSTFLAGS: -Dwarnings
jobs:
test:
name: Test suite
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
- run: cd test_suite && cargo test --features unstable
windows:
name: Test suite (windows)
runs-on: windows-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
- run: cd test_suite && cargo test --features unstable -- --skip ui --exact
stable:
name: Rust stable
name: Rust ${{matrix.rust}}
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
rust: [stable, beta]
timeout-minutes: 45
steps:
- uses: actions/checkout@v2
- uses: dtolnay/rust-toolchain@stable
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
- run: cd serde && cargo build --features rc
- run: cd serde && cargo build --no-default-features
- run: cd serde_test && cargo build
- run: cd serde_test && cargo test --features serde/derive,serde/rc
beta:
name: Rust beta
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: dtolnay/rust-toolchain@beta
- run: cd serde && cargo build --features rc
- run: cd test_suite && cargo test
nightly:
name: Rust nightly ${{matrix.os == 'windows' && '(windows)' || ''}}
runs-on: ${{matrix.os}}-latest
@@ -49,8 +56,9 @@ jobs:
fail-fast: false
matrix:
os: [ubuntu, windows]
timeout-minutes: 45
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
- run: cd serde && cargo build
- run: cd serde && cargo build --no-default-features
@@ -59,23 +67,10 @@ jobs:
- run: cd serde && cargo test --features derive,rc,unstable
- run: cd test_suite/no_std && cargo build
if: matrix.os != 'windows'
msrv:
name: Rust 1.13.0
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: dtolnay/rust-toolchain@1.13.0
- name: Get timestamp for cache
id: date
run: echo ::set-output name=yearmo::$(date +%Y%m)
- uses: actions/cache@v1
with:
path: ~/.cargo/registry/index
key: cargo-registry-index-${{steps.date.outputs.yearmo}}
- run: cd serde && cargo build --features rc
- run: cd serde && cargo build --no-default-features
- run: cd serde_test && cargo build
- run: cd serde_derive && cargo check --tests
env:
RUSTFLAGS: --cfg exhaustive ${{env.RUSTFLAGS}}
if: matrix.os != 'windows'
build:
name: Rust ${{matrix.rust}}
@@ -84,13 +79,16 @@ jobs:
fail-fast: false
matrix:
rust: [1.19.0, 1.20.0, 1.21.0, 1.25.0, 1.26.0, 1.34.0]
timeout-minutes: 45
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
- run: cd serde && cargo build --features rc
- run: cd serde && cargo build --no-default-features
- run: cd serde && cargo build
- run: cd serde_test && cargo build
more:
name: Rust ${{matrix.rust}}
@@ -99,8 +97,9 @@ jobs:
fail-fast: false
matrix:
rust: [1.27.0, 1.28.0]
timeout-minutes: 45
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@master
with:
toolchain: ${{matrix.rust}}
@@ -110,54 +109,71 @@ jobs:
- run: cd serde && cargo build
derive:
name: Rust 1.31.0
name: Rust 1.56.0
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v2
- uses: dtolnay/rust-toolchain@1.31.0
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@1.56.0
- run: cd serde && cargo check --no-default-features
- run: cd serde && cargo check
- run: cd serde_derive && cargo check
alloc:
name: Rust 1.36.0
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@1.36.0
- run: cd serde && cargo build --no-default-features --features alloc
emscripten:
name: Emscripten
minimal:
name: Minimal versions
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@nightly
- uses: actions/setup-node@v1
with:
node-version: 9
- name: Install cargo-web
run: |
CARGO_WEB_RELEASE=$(curl -L -s -H Accept:application/json https://github.com/koute/cargo-web/releases/latest)
CARGO_WEB_VERSION=$(echo "${CARGO_WEB_RELEASE}" | jq -r .tag_name)
CARGO_WEB_URL="https://github.com/koute/cargo-web/releases/download/${CARGO_WEB_VERSION}/cargo-web-x86_64-unknown-linux-gnu.gz"
mkdir -p ~/.cargo/bin
curl -L "${CARGO_WEB_URL}" | gzip -d > ~/.cargo/bin/cargo-web
chmod +x ~/.cargo/bin/cargo-web
- run: cd test_suite && cargo web test --target=asmjs-unknown-emscripten --nodejs
continue-on-error: true
- run: cd test_suite && cargo web test --target=wasm32-unknown-emscripten --nodejs
continue-on-error: true
- run: cargo generate-lockfile -Z minimal-versions
- run: cargo check --locked --workspace
clippy:
name: Clippy
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
timeout-minutes: 45
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@clippy
# The need for -Aredundant_field_names here is a Clippy bug.
# https://github.com/rust-lang/rust-clippy/issues/5356
- run: cd serde && cargo clippy --features rc,unstable -- -D clippy::all -A clippy::redundant_field_names
- run: cd serde_derive && cargo clippy -- -D clippy::all
- run: cd serde_test && cargo clippy -- -D clippy::all -A clippy::redundant_field_names
- run: cd test_suite && cargo clippy --tests --features unstable -- -D clippy::all -A clippy::redundant_field_names
- run: cd test_suite/no_std && cargo clippy -- -D clippy::all -A clippy::redundant_field_names
- run: cd serde && cargo clippy --features rc,unstable -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_derive && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_derive_internals && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd serde_test && cargo clippy -- -Dclippy::all -Dclippy::pedantic
- run: cd test_suite && cargo clippy --tests --features unstable -- -Dclippy::all -Dclippy::pedantic
- run: cd test_suite/no_std && cargo clippy -- -Dclippy::all -Dclippy::pedantic
miri:
name: Miri
runs-on: ubuntu-latest
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: dtolnay/rust-toolchain@miri
- run: cargo miri setup
- run: cd serde && cargo miri test --features derive,rc,unstable
env:
MIRIFLAGS: -Zmiri-strict-provenance
- run: cd test_suite && cargo miri test --features unstable
env:
MIRIFLAGS: -Zmiri-strict-provenance
outdated:
name: Outdated
runs-on: ubuntu-latest
if: github.event_name != 'pull_request'
timeout-minutes: 45
steps:
- uses: actions/checkout@v3
- uses: dtolnay/install@cargo-outdated
- run: cargo outdated --workspace --exit-code 1
+4 -10
View File
@@ -31,25 +31,19 @@ tests for you.
```sh
# Test all the example code in Serde documentation
cargo test
```
##### In the [`test_suite/deps`] directory
```sh
# This is a prerequisite for running the full test suite
cargo clean && cargo update && cargo build
cargo test --features derive
```
##### In the [`test_suite`] directory
```sh
# Run the full test suite, including tests of unstable functionality
cargo test --features unstable
cargo +nightly test --features unstable
```
Note that this test suite currently only supports running on a nightly compiler.
[`serde`]: https://github.com/serde-rs/serde/tree/master/serde
[`test_suite/deps`]: https://github.com/serde-rs/serde/tree/master/test_suite/deps
[`test_suite`]: https://github.com/serde-rs/serde/tree/master/test_suite
## Conduct
-25
View File
@@ -174,28 +174,3 @@ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+20 -17
View File
@@ -1,13 +1,13 @@
# Serde &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.13+]][Rust 1.13] [![serde_derive: rustc 1.31+]][Rust 1.31]
# Serde &emsp; [![Build Status]][actions] [![Latest Version]][crates.io] [![serde: rustc 1.19+]][Rust 1.19] [![serde_derive: rustc 1.56+]][Rust 1.56]
[Build Status]: https://img.shields.io/github/workflow/status/serde-rs/serde/CI/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
[Latest Version]: https://img.shields.io/crates/v/serde.svg
[crates.io]: https://crates.io/crates/serde
[serde: rustc 1.13+]: https://img.shields.io/badge/serde-rustc_1.13+-lightgray.svg
[serde_derive: rustc 1.31+]: https://img.shields.io/badge/serde_derive-rustc_1.31+-lightgray.svg
[Rust 1.13]: https://blog.rust-lang.org/2016/11/10/Rust-1.13.html
[Rust 1.31]: https://blog.rust-lang.org/2018/12/06/Rust-1.31-and-rust-2018.html
[serde: rustc 1.19+]: https://img.shields.io/badge/serde-rustc_1.19+-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.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.**
@@ -19,7 +19,7 @@ You may be looking for:
- [Data formats supported by Serde](https://serde.rs/#data-formats)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
- [Examples](https://serde.rs/examples.html)
- [API documentation](https://docs.serde.rs/serde/)
- [API documentation](https://docs.rs/serde)
- [Release notes](https://github.com/serde-rs/serde/releases)
## Serde in action
@@ -48,7 +48,7 @@ serde_json = "1.0"
<p></p>
```rust
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct Point {
@@ -77,17 +77,20 @@ fn main() {
Serde is one of the most widely used Rust libraries so any place that Rustaceans
congregate will be able to help you out. For chat, consider trying the
[#general] or [#beginners] channels of the unofficial community Discord, the
[#rust-usage] channel of the official Rust Project Discord, or the
[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag
on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned
weekly easy questions post, or the Rust [Discourse forum][discourse]. It's
acceptable to file a support issue in this repo but they tend not to get as many
eyes as any of the above and may get closed without a response after some time.
[#rust-questions] or [#rust-beginners] channels of the unofficial community
Discord (invite: <https://discord.gg/rust-lang-community>), the [#rust-usage] or
[#beginners] channels of the official Rust Project Discord (invite:
<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
[Discourse forum][discourse]. It's acceptable to file a support issue in this
repo but they tend not to get as many eyes as any of the above and may get
closed without a response after some time.
[#general]: https://discord.com/channels/273534239310479360/274215136414400513
[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281
[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
[/r/rust]: https://www.reddit.com/r/rust
+14 -11
View File
@@ -10,13 +10,13 @@ You may be looking for:
- [Data formats supported by Serde](https://serde.rs/#data-formats)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
- [Examples](https://serde.rs/examples.html)
- [API documentation](https://docs.serde.rs/serde/)
- [API documentation](https://docs.rs/serde)
- [Release notes](https://github.com/serde-rs/serde/releases)
## Serde in action
```rust
use serde::{Serialize, Deserialize};
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug)]
struct Point {
@@ -45,17 +45,20 @@ fn main() {
Serde is one of the most widely used Rust libraries so any place that Rustaceans
congregate will be able to help you out. For chat, consider trying the
[#general] or [#beginners] channels of the unofficial community Discord, the
[#rust-usage] channel of the official Rust Project Discord, or the
[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag
on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned
weekly easy questions post, or the Rust [Discourse forum][discourse]. It's
acceptable to file a support issue in this repo but they tend not to get as many
eyes as any of the above and may get closed without a response after some time.
[#rust-questions] or [#rust-beginners] channels of the unofficial community
Discord (invite: <https://discord.gg/rust-lang-community>, the [#rust-usage] or
[#beginners] channels of the official Rust Project Discord (invite:
<https://discord.gg/rust-lang>), or the [#general][zulip] stream in Zulip. For
asynchronous, consider the [\[rust\] tag on StackOverflow][stackoverflow], the
[/r/rust] subreddit which has a pinned weekly easy questions post, or the Rust
[Discourse forum][discourse]. It's acceptable to file a support issue in this
repo but they tend not to get as many eyes as any of the above and may get
closed without a response after some time.
[#general]: https://discord.com/channels/273534239310479360/274215136414400513
[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281
[#rust-questions]: https://discord.com/channels/273534239310479360/274215136414400513
[#rust-beginners]: https://discord.com/channels/273534239310479360/273541522815713281
[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
[#beginners]: https://discord.com/channels/442252698964721669/448238009733742612
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
[/r/rust]: https://www.reddit.com/r/rust
+1
View File
@@ -0,0 +1 @@
/serde_derive/serde_derive-x86_64-unknown-linux-gnu
+14
View File
@@ -0,0 +1,14 @@
[workspace]
members = ["bin", "proc-macro2"]
resolver = "2"
[patch.crates-io]
proc-macro2 = { path = "proc-macro2" }
[profile.precompiled]
inherits = "release"
codegen-units = 1
lto = true
opt-level = "z"
panic = "abort"
strip = true
+17
View File
@@ -0,0 +1,17 @@
[package]
name = "serde_derive"
version = "1.0.172"
authors = ["David Tolnay <dtolnay@gmail.com>"]
publish = false
[lib]
doctest = false
[[bin]]
name = "serde_derive"
path = "main.rs"
[dependencies]
proc-macro2 = "1"
quote = { version = "1", default-features = false }
syn = { version = "2.0.25", default-features = false, features = ["clone-impls", "derive", "parsing", "printing"] }
+4
View File
@@ -0,0 +1,4 @@
fn main() {
println!("cargo:rustc-cfg=precompiled");
println!("cargo:rustc-cfg=feature=\"deserialize_in_place\"");
}
+27
View File
@@ -0,0 +1,27 @@
extern crate proc_macro2;
use proc_macro2::watt;
use proc_macro2::watt::buffer::InputBuffer;
use std::io::{self, Read, Write};
use std::sync::atomic::Ordering;
fn main() {
let mut buf = Vec::new();
io::stdin().read_to_end(&mut buf).unwrap();
let mut buf = InputBuffer::new(&buf);
let derive = match buf.read_u8() {
0 => serde_derive::derive_serialize,
1 => serde_derive::derive_deserialize,
2 => {
serde_derive::DESERIALIZE_IN_PLACE.store(true, Ordering::Relaxed);
serde_derive::derive_deserialize
}
_ => unreachable!(),
};
let input = watt::load(&mut buf);
let output = derive(input);
let bytes = watt::linearize(output);
io::stdout().write_all(&bytes).unwrap();
}
+1
View File
@@ -0,0 +1 @@
../../serde_derive/src
+21
View File
@@ -0,0 +1,21 @@
#!/bin/bash
cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null
set -e -x
# TODO: Sanitize host filesystem paths. https://github.com/rust-lang/cargo/issues/12137
cargo +nightly build \
--manifest-path bin/Cargo.toml \
--bin serde_derive \
--profile precompiled \
-Z unstable-options \
-Z build-std=std,panic_abort \
-Z build-std-features=panic_immediate_abort \
--target x86_64-unknown-linux-musl \
--out-dir serde_derive
rm -f serde_derive/serde_derive-x86_64-unknown-linux-gnu
mv serde_derive/serde_derive{,-x86_64-unknown-linux-gnu}
#upx --best --lzma serde_derive/serde_derive-x86_64-unknown-linux-gnu
+8
View File
@@ -0,0 +1,8 @@
[package]
name = "proc-macro2"
version = "1.0.66"
edition = "2021"
publish = false
[dependencies]
proc-macro2 = { package = "proc-macro2-fallback", version = "1" }
+815
View File
@@ -0,0 +1,815 @@
#[doc(hidden)]
pub mod watt;
use crate::extra::DelimSpan;
use crate::watt::Identity;
use std::cmp::Ordering;
use std::fmt::{self, Debug, Display};
use std::hash::{Hash, Hasher};
use std::ops::RangeBounds;
use std::str::FromStr;
pub use proc_macro2::{Delimiter, Spacing};
#[derive(Copy, Clone)]
pub struct Span {
lo: u32,
hi: u32,
}
impl Span {
pub fn call_site() -> Self {
Span { lo: 0, hi: 0 }
}
pub fn join(&self, other: Self) -> Option<Self> {
Some(Span {
lo: self.lo,
hi: other.hi,
})
}
}
#[derive(Clone)]
pub enum TokenTree {
Group(Group),
Ident(Ident),
Punct(Punct),
Literal(Literal),
}
impl TokenTree {
pub fn span(&self) -> Span {
match self {
TokenTree::Group(group) => group.span(),
TokenTree::Ident(ident) => ident.span(),
TokenTree::Punct(punct) => punct.span(),
TokenTree::Literal(literal) => literal.span(),
}
}
pub fn set_span(&mut self, span: Span) {
match self {
TokenTree::Group(group) => group.set_span(span),
TokenTree::Ident(ident) => ident.set_span(span),
TokenTree::Punct(punct) => punct.set_span(span),
TokenTree::Literal(literal) => literal.set_span(span),
}
}
}
impl From<Group> for TokenTree {
fn from(group: Group) -> Self {
TokenTree::Group(group)
}
}
impl From<Ident> for TokenTree {
fn from(ident: Ident) -> Self {
TokenTree::Ident(ident)
}
}
impl From<Punct> for TokenTree {
fn from(punct: Punct) -> Self {
TokenTree::Punct(punct)
}
}
impl From<Literal> for TokenTree {
fn from(literal: Literal) -> Self {
TokenTree::Literal(literal)
}
}
impl Debug for TokenTree {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match self {
TokenTree::Group(group) => Debug::fmt(group, formatter),
TokenTree::Ident(ident) => {
let mut debug = formatter.debug_struct("Ident");
debug.field("sym", &format_args!("{}", ident));
debug.finish()
}
TokenTree::Punct(punct) => Debug::fmt(punct, formatter),
TokenTree::Literal(literal) => Debug::fmt(literal, formatter),
}
}
}
#[derive(Clone)]
pub struct Group {
delimiter: Delimiter,
stream: Vec<TokenTree>,
span: Span,
span_open: Span,
span_close: Span,
identity: u32,
}
impl Group {
pub fn new(delimiter: Delimiter, stream: TokenStream) -> Self {
Group {
delimiter,
stream: stream.content,
span: Span::call_site(),
span_open: Span::call_site(),
span_close: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn stream(&self) -> TokenStream {
TokenStream {
content: self.stream.clone(),
}
}
pub fn delimiter(&self) -> Delimiter {
self.delimiter
}
pub fn span(&self) -> Span {
self.span
}
pub fn span_open(&self) -> Span {
self.span_open
}
pub fn span_close(&self) -> Span {
self.span_close
}
pub fn delim_span(&self) -> DelimSpan {
DelimSpan {
join: self.span,
open: self.span_open,
close: self.span_close,
}
}
pub fn set_span(&mut self, span: Span) {
self.span = span;
self.identity |= Identity::RESPANNED;
}
}
impl Display for Group {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let (open, close) = match self.delimiter {
Delimiter::Parenthesis => ("(", ")"),
Delimiter::Brace => ("{ ", "}"),
Delimiter::Bracket => ("[", "]"),
Delimiter::None => ("", ""),
};
formatter.write_str(open)?;
display_tokens(&self.stream, formatter)?;
if self.delimiter == Delimiter::Brace && !self.stream.is_empty() {
formatter.write_str(" ")?;
}
formatter.write_str(close)?;
Ok(())
}
}
impl Debug for Group {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let mut debug = formatter.debug_struct("Group");
debug.field("delimiter", &self.delimiter);
debug.field("stream", &self.stream);
debug.finish()
}
}
#[derive(Clone)]
pub struct Ident {
fallback: proc_macro2::Ident,
span: Span,
identity: u32,
}
impl Ident {
pub fn new(string: &str, span: Span) -> Self {
Ident {
fallback: proc_macro2::Ident::new(string, proc_macro2::Span::call_site()),
span,
identity: Identity::NOVEL,
}
}
pub fn new_raw(string: &str, span: Span) -> Self {
Ident {
fallback: proc_macro2::Ident::new_raw(string, proc_macro2::Span::call_site()),
span,
identity: Identity::NOVEL,
}
}
pub fn span(&self) -> Span {
self.span
}
pub fn set_span(&mut self, span: Span) {
self.span = span;
self.identity |= Identity::RESPANNED;
}
}
impl Display for Ident {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.fallback, formatter)
}
}
impl Debug for Ident {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.fallback, formatter)
}
}
impl Eq for Ident {}
impl PartialEq for Ident {
fn eq(&self, other: &Self) -> bool {
PartialEq::eq(&self.fallback, &other.fallback)
}
}
impl<T> PartialEq<T> for Ident
where
T: ?Sized + AsRef<str>,
{
fn eq(&self, other: &T) -> bool {
PartialEq::eq(&self.fallback, other)
}
}
impl Ord for Ident {
fn cmp(&self, other: &Self) -> Ordering {
Ord::cmp(&self.fallback, &other.fallback)
}
}
impl PartialOrd for Ident {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
PartialOrd::partial_cmp(&self.fallback, &other.fallback)
}
}
impl Hash for Ident {
fn hash<H: Hasher>(&self, hasher: &mut H) {
Hash::hash(&self.fallback, hasher);
}
}
#[derive(Clone)]
pub struct Punct {
fallback: proc_macro2::Punct,
span: Span,
identity: u32,
}
impl Punct {
pub fn new(ch: char, spacing: Spacing) -> Self {
Punct {
fallback: proc_macro2::Punct::new(ch, spacing),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn as_char(&self) -> char {
self.fallback.as_char()
}
pub fn spacing(&self) -> Spacing {
self.fallback.spacing()
}
pub fn span(&self) -> Span {
self.span
}
pub fn set_span(&mut self, span: Span) {
self.span = span;
self.identity |= Identity::RESPANNED;
}
}
impl Display for Punct {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.fallback, formatter)
}
}
impl Debug for Punct {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.fallback, formatter)
}
}
#[derive(Clone)]
pub struct Literal {
fallback: proc_macro2::Literal,
span: Span,
identity: u32,
}
impl Literal {
pub fn u8_suffixed(n: u8) -> Self {
Literal {
fallback: proc_macro2::Literal::u8_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn u16_suffixed(n: u16) -> Self {
Literal {
fallback: proc_macro2::Literal::u16_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn u32_suffixed(n: u32) -> Self {
Literal {
fallback: proc_macro2::Literal::u32_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn u64_suffixed(n: u64) -> Self {
Literal {
fallback: proc_macro2::Literal::u64_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn u128_suffixed(n: u128) -> Self {
Literal {
fallback: proc_macro2::Literal::u128_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn usize_suffixed(n: usize) -> Self {
Literal {
fallback: proc_macro2::Literal::usize_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn i8_suffixed(n: i8) -> Self {
Literal {
fallback: proc_macro2::Literal::i8_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn i16_suffixed(n: i16) -> Self {
Literal {
fallback: proc_macro2::Literal::i16_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn i32_suffixed(n: i32) -> Self {
Literal {
fallback: proc_macro2::Literal::i32_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn i64_suffixed(n: i64) -> Self {
Literal {
fallback: proc_macro2::Literal::i64_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn i128_suffixed(n: i128) -> Self {
Literal {
fallback: proc_macro2::Literal::i128_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn isize_suffixed(n: isize) -> Self {
Literal {
fallback: proc_macro2::Literal::isize_suffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn u8_unsuffixed(n: u8) -> Self {
Literal {
fallback: proc_macro2::Literal::u8_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn u16_unsuffixed(n: u16) -> Self {
Literal {
fallback: proc_macro2::Literal::u16_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn u32_unsuffixed(n: u32) -> Self {
Literal {
fallback: proc_macro2::Literal::u32_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn u64_unsuffixed(n: u64) -> Self {
Literal {
fallback: proc_macro2::Literal::u64_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn u128_unsuffixed(n: u128) -> Self {
Literal {
fallback: proc_macro2::Literal::u128_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn usize_unsuffixed(n: usize) -> Self {
Literal {
fallback: proc_macro2::Literal::usize_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn i8_unsuffixed(n: i8) -> Self {
Literal {
fallback: proc_macro2::Literal::i8_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn i16_unsuffixed(n: i16) -> Self {
Literal {
fallback: proc_macro2::Literal::i16_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn i32_unsuffixed(n: i32) -> Self {
Literal {
fallback: proc_macro2::Literal::i32_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn i64_unsuffixed(n: i64) -> Self {
Literal {
fallback: proc_macro2::Literal::i64_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn i128_unsuffixed(n: i128) -> Self {
Literal {
fallback: proc_macro2::Literal::i128_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn isize_unsuffixed(n: isize) -> Self {
Literal {
fallback: proc_macro2::Literal::isize_unsuffixed(n),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn f64_unsuffixed(f: f64) -> Self {
Literal {
fallback: proc_macro2::Literal::f64_unsuffixed(f),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn f64_suffixed(f: f64) -> Self {
Literal {
fallback: proc_macro2::Literal::f64_suffixed(f),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn f32_unsuffixed(f: f32) -> Self {
Literal {
fallback: proc_macro2::Literal::f32_unsuffixed(f),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn f32_suffixed(f: f32) -> Self {
Literal {
fallback: proc_macro2::Literal::f32_suffixed(f),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn string(string: &str) -> Self {
Literal {
fallback: proc_macro2::Literal::string(string),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn character(ch: char) -> Self {
Literal {
fallback: proc_macro2::Literal::character(ch),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn byte_string(s: &[u8]) -> Self {
Literal {
fallback: proc_macro2::Literal::byte_string(s),
span: Span::call_site(),
identity: Identity::NOVEL,
}
}
pub fn span(&self) -> Span {
self.span
}
pub fn set_span(&mut self, span: Span) {
self.span = span;
self.identity |= Identity::RESPANNED;
}
pub fn subspan<R: RangeBounds<usize>>(&self, range: R) -> Option<Span> {
let _ = range;
None
}
}
impl FromStr for Literal {
type Err = LexError;
fn from_str(repr: &str) -> Result<Self, Self::Err> {
let fallback = match proc_macro2::Literal::from_str(repr) {
Ok(literal) => literal,
Err(error) => {
return Err(LexError {
fallback: error,
span: Span::call_site(),
});
}
};
Ok(Literal {
fallback,
span: Span::call_site(),
identity: Identity::NOVEL,
})
}
}
impl Display for Literal {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Display::fmt(&self.fallback, formatter)
}
}
impl Debug for Literal {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.fallback, formatter)
}
}
#[derive(Clone)]
pub struct TokenStream {
content: Vec<TokenTree>,
}
impl TokenStream {
pub fn new() -> Self {
TokenStream {
content: Vec::new(),
}
}
pub fn is_empty(&self) -> bool {
self.content.is_empty()
}
}
impl IntoIterator for TokenStream {
type Item = TokenTree;
type IntoIter = token_stream::IntoIter;
fn into_iter(self) -> Self::IntoIter {
token_stream::IntoIter {
iter: self.content.into_iter(),
}
}
}
impl Extend<TokenStream> for TokenStream {
fn extend<I: IntoIterator<Item = TokenStream>>(&mut self, streams: I) {
self.content.extend(streams.into_iter().flatten());
}
}
impl Extend<TokenTree> for TokenStream {
fn extend<I: IntoIterator<Item = TokenTree>>(&mut self, streams: I) {
self.content.extend(streams);
}
}
impl FromIterator<TokenStream> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenStream>>(streams: I) -> Self {
let content = streams.into_iter().flatten().collect();
TokenStream { content }
}
}
impl FromIterator<TokenTree> for TokenStream {
fn from_iter<I: IntoIterator<Item = TokenTree>>(streams: I) -> Self {
let content = streams.into_iter().collect();
TokenStream { content }
}
}
impl FromStr for TokenStream {
type Err = LexError;
fn from_str(string: &str) -> Result<Self, Self::Err> {
let fallback = match proc_macro2::TokenStream::from_str(string) {
Ok(token_stream) => token_stream,
Err(error) => {
return Err(LexError {
fallback: error,
span: Span::call_site(),
});
}
};
fn convert_token_stream(stream: proc_macro2::TokenStream) -> TokenStream {
TokenStream {
content: stream.into_iter().map(convert_token_tree).collect(),
}
}
fn convert_token_tree(token: proc_macro2::TokenTree) -> TokenTree {
match token {
proc_macro2::TokenTree::Group(group) => TokenTree::Group(Group::new(
group.delimiter(),
convert_token_stream(group.stream()),
)),
proc_macro2::TokenTree::Ident(ident) => TokenTree::Ident(Ident {
fallback: ident,
span: Span::call_site(),
identity: Identity::NOVEL,
}),
proc_macro2::TokenTree::Punct(punct) => TokenTree::Punct(Punct {
fallback: punct,
span: Span::call_site(),
identity: Identity::NOVEL,
}),
proc_macro2::TokenTree::Literal(literal) => TokenTree::Literal(Literal {
fallback: literal,
span: Span::call_site(),
identity: Identity::NOVEL,
}),
}
}
Ok(convert_token_stream(fallback))
}
}
fn display_tokens(tokens: &[TokenTree], formatter: &mut fmt::Formatter) -> fmt::Result {
let mut joint = false;
for (i, token) in tokens.iter().enumerate() {
if i != 0 && !joint {
write!(formatter, " ")?;
}
joint = false;
match token {
TokenTree::Group(group) => Display::fmt(group, formatter),
TokenTree::Ident(ident) => Display::fmt(ident, formatter),
TokenTree::Punct(punct) => {
joint = punct.spacing() == Spacing::Joint;
Display::fmt(punct, formatter)
}
TokenTree::Literal(literal) => Display::fmt(literal, formatter),
}?;
}
Ok(())
}
impl Display for TokenStream {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
display_tokens(&self.content, formatter)
}
}
impl Debug for TokenStream {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("TokenStream ")?;
formatter.debug_list().entries(&self.content).finish()
}
}
pub struct LexError {
fallback: proc_macro2::LexError,
span: Span,
}
impl LexError {
pub fn span(&self) -> Span {
self.span
}
}
impl Debug for LexError {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(&self.fallback, formatter)
}
}
pub mod token_stream {
use super::*;
#[derive(Clone)]
pub struct IntoIter {
pub(crate) iter: <Vec<TokenTree> as IntoIterator>::IntoIter,
}
impl Iterator for IntoIter {
type Item = TokenTree;
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.iter.size_hint()
}
}
}
pub mod extra {
use crate::Span;
#[derive(Copy, Clone)]
pub struct DelimSpan {
pub(crate) join: Span,
pub(crate) open: Span,
pub(crate) close: Span,
}
impl DelimSpan {
pub fn join(&self) -> Span {
self.join
}
pub fn open(&self) -> Span {
self.open
}
pub fn close(&self) -> Span {
self.close
}
}
}
@@ -0,0 +1,69 @@
use std::str;
pub struct OutputBuffer {
bytes: Vec<u8>,
}
impl OutputBuffer {
pub fn new() -> Self {
OutputBuffer { bytes: Vec::new() }
}
pub fn write_u8(&mut self, value: u8) {
self.bytes.push(value);
}
pub fn write_u16(&mut self, value: u16) {
self.bytes.extend_from_slice(&value.to_le_bytes());
}
pub fn write_u32(&mut self, value: u32) {
self.bytes.extend_from_slice(&value.to_le_bytes());
}
pub fn write_str(&mut self, value: &str) {
self.bytes.extend_from_slice(value.as_bytes());
}
pub fn into_bytes(self) -> Vec<u8> {
self.bytes
}
}
pub struct InputBuffer<'a> {
bytes: &'a [u8],
}
impl<'a> InputBuffer<'a> {
pub fn new(bytes: &'a [u8]) -> Self {
InputBuffer { bytes }
}
pub fn is_empty(&self) -> bool {
self.bytes.is_empty()
}
pub fn read_u8(&mut self) -> u8 {
let (first, rest) = self.bytes.split_first().unwrap();
self.bytes = rest;
*first
}
pub fn read_u16(&mut self) -> u16 {
let (value, rest) = self.bytes.split_at(2);
self.bytes = rest;
u16::from_le_bytes([value[0], value[1]])
}
pub fn read_u32(&mut self) -> u32 {
let (value, rest) = self.bytes.split_at(4);
self.bytes = rest;
u32::from_le_bytes([value[0], value[1], value[2], value[3]])
}
pub fn read_str(&mut self, len: usize) -> &'a str {
let (string, rest) = self.bytes.split_at(len);
self.bytes = rest;
str::from_utf8(string).unwrap()
}
}
@@ -0,0 +1,17 @@
pub enum Bytecode {}
impl Bytecode {
pub const GROUP_PARENTHESIS: u8 = 0;
pub const GROUP_BRACE: u8 = 1;
pub const GROUP_BRACKET: u8 = 2;
pub const GROUP_NONE: u8 = 3;
pub const IDENT: u8 = 4;
pub const PUNCT_ALONE: u8 = 5;
pub const PUNCT_JOINT: u8 = 6;
pub const LITERAL: u8 = 7;
pub const LOAD_GROUP: u8 = 8;
pub const LOAD_IDENT: u8 = 9;
pub const LOAD_PUNCT: u8 = 10;
pub const LOAD_LITERAL: u8 = 11;
pub const SET_SPAN: u8 = 12;
}
+203
View File
@@ -0,0 +1,203 @@
pub mod buffer;
pub mod bytecode;
use crate::watt::buffer::{InputBuffer, OutputBuffer};
use crate::watt::bytecode::Bytecode;
use crate::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
use std::str::FromStr;
pub enum Kind {
Group(Delimiter),
Ident,
Punct(Spacing),
Literal,
}
pub enum Identity {}
impl Identity {
pub const RESPANNED: u32 = 1 << 31;
pub const NOVEL: u32 = u32::MAX;
}
impl Span {
fn is_call_site(&self) -> bool {
self.lo == 0 && self.hi == 0
}
}
fn post_increment(counter: &mut u32) -> impl FnMut() -> u32 + '_ {
|| {
let value = *counter;
*counter += 1;
value
}
}
pub fn load(buf: &mut InputBuffer) -> TokenStream {
let mut span_counter = 1;
let mut next_span = post_increment(&mut span_counter);
let mut next_span = || {
let next = next_span();
Span { lo: next, hi: next }
};
let [mut group_counter, mut ident_counter, mut punct_counter, mut literal_counter] = [0; 4];
let mut next_group = post_increment(&mut group_counter);
let mut next_ident = post_increment(&mut ident_counter);
let mut next_punct = post_increment(&mut punct_counter);
let mut next_literal = post_increment(&mut literal_counter);
let mut trees = Vec::new();
while !buf.is_empty() {
match match buf.read_u8() {
Bytecode::GROUP_PARENTHESIS => Kind::Group(Delimiter::Parenthesis),
Bytecode::GROUP_BRACE => Kind::Group(Delimiter::Brace),
Bytecode::GROUP_BRACKET => Kind::Group(Delimiter::Bracket),
Bytecode::GROUP_NONE => Kind::Group(Delimiter::None),
Bytecode::IDENT => Kind::Ident,
Bytecode::PUNCT_ALONE => Kind::Punct(Spacing::Alone),
Bytecode::PUNCT_JOINT => Kind::Punct(Spacing::Joint),
Bytecode::LITERAL => Kind::Literal,
_ => unreachable!(),
} {
Kind::Group(delimiter) => {
let len = buf.read_u32();
let stream = trees.drain(trees.len() - len as usize..).collect();
trees.push(TokenTree::Group(Group {
delimiter,
stream,
span: next_span(),
span_open: next_span(),
span_close: next_span(),
identity: next_group(),
}));
}
Kind::Ident => {
let len = buf.read_u16();
let repr = buf.read_str(len as usize);
let ident = if let Some(repr) = repr.strip_prefix("r#") {
proc_macro2::Ident::new_raw(repr, proc_macro2::Span::call_site())
} else {
proc_macro2::Ident::new(repr, proc_macro2::Span::call_site())
};
trees.push(TokenTree::Ident(Ident {
fallback: ident,
span: next_span(),
identity: next_ident(),
}));
}
Kind::Punct(spacing) => {
let ch = buf.read_u8();
assert!(ch.is_ascii());
let punct = proc_macro2::Punct::new(ch as char, spacing);
trees.push(TokenTree::Punct(Punct {
fallback: punct,
span: next_span(),
identity: next_punct(),
}));
}
Kind::Literal => {
let len = buf.read_u16();
let repr = buf.read_str(len as usize);
let literal = proc_macro2::Literal::from_str(repr).unwrap();
trees.push(TokenTree::Literal(Literal {
fallback: literal,
span: next_span(),
identity: next_literal(),
}));
}
}
}
TokenStream { content: trees }
}
pub fn linearize(tokens: TokenStream) -> Vec<u8> {
let mut buf = OutputBuffer::new();
for token in &tokens.content {
linearize_token(token, &mut buf);
}
buf.into_bytes()
}
fn linearize_token(token: &TokenTree, buf: &mut OutputBuffer) {
let needs_span;
match token {
TokenTree::Group(group) => {
if group.identity < Identity::NOVEL {
buf.write_u8(Bytecode::LOAD_GROUP);
buf.write_u32(group.identity & !Identity::RESPANNED);
needs_span = group.identity >= Identity::RESPANNED;
} else {
let len = group.stream.len();
assert!(len <= u32::MAX as usize);
for token in &group.stream {
linearize_token(token, buf);
}
buf.write_u8(match group.delimiter {
Delimiter::Parenthesis => Bytecode::GROUP_PARENTHESIS,
Delimiter::Brace => Bytecode::GROUP_BRACE,
Delimiter::Bracket => Bytecode::GROUP_BRACKET,
Delimiter::None => Bytecode::GROUP_NONE,
});
buf.write_u32(len as u32);
needs_span = !group.span.is_call_site();
}
}
TokenTree::Ident(ident) => {
if ident.identity < Identity::NOVEL {
buf.write_u8(Bytecode::LOAD_IDENT);
buf.write_u32(ident.identity & !Identity::RESPANNED);
needs_span = ident.identity >= Identity::RESPANNED;
} else {
buf.write_u8(Bytecode::IDENT);
let repr = ident.to_string();
assert!(repr.len() <= u16::MAX as usize);
buf.write_u16(repr.len() as u16);
buf.write_str(&repr);
linearize_span(ident.span, buf);
needs_span = false;
}
}
TokenTree::Punct(punct) => {
if punct.identity < Identity::NOVEL {
buf.write_u8(Bytecode::LOAD_PUNCT);
buf.write_u32(punct.identity & !Identity::RESPANNED);
needs_span = punct.identity >= Identity::RESPANNED;
} else {
buf.write_u8(match punct.spacing() {
Spacing::Alone => Bytecode::PUNCT_ALONE,
Spacing::Joint => Bytecode::PUNCT_JOINT,
});
let ch = punct.as_char();
assert!(ch.is_ascii());
buf.write_u8(ch as u8);
needs_span = !punct.span.is_call_site();
}
}
TokenTree::Literal(literal) => {
if literal.identity < Identity::NOVEL {
buf.write_u8(Bytecode::LOAD_LITERAL);
buf.write_u32(literal.identity & !Identity::RESPANNED);
needs_span = literal.identity >= Identity::RESPANNED;
} else {
buf.write_u8(Bytecode::LITERAL);
let repr = literal.to_string();
assert!(repr.len() <= u16::MAX as usize);
buf.write_u16(repr.len() as u16);
buf.write_str(&repr);
needs_span = !literal.span.is_call_site();
}
}
}
if needs_span {
buf.write_u8(Bytecode::SET_SPAN);
linearize_span(token.span(), buf);
}
}
fn linearize_span(span: Span, buf: &mut OutputBuffer) {
buf.write_u32(span.lo);
buf.write_u32(span.hi);
}
+35
View File
@@ -0,0 +1,35 @@
[package]
name = "serde_derive"
version = "1.0.172"
authors = ["David Tolnay <dtolnay@gmail.com>"]
categories = ["no-std", "no-std::no-alloc"]
description = "Implementation of #[derive(Serialize, Deserialize)]"
documentation = "https://serde.rs/derive.html"
edition = "2015"
homepage = "https://serde.rs"
include = ["serde_derive-x86_64-unknown-linux-gnu", "src"]
keywords = ["serde", "serialization", "no_std", "derive"]
license = "MIT OR Apache-2.0"
readme = "crates-io.md"
repository = "https://github.com/serde-rs/serde"
rust-version = "1.56"
[features]
default = []
deserialize_in_place = []
[lib]
proc-macro = true
[target.'cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))'.dependencies]
proc-macro2 = "1"
quote = "1"
syn = "2.0.25"
[dev-dependencies]
serde = { version = "1", path = "../../serde" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
[workspace]
+1
View File
@@ -0,0 +1 @@
../../LICENSE-APACHE
+1
View File
@@ -0,0 +1 @@
../../LICENSE-MIT
+1
View File
@@ -0,0 +1 @@
../../README.md
+1
View File
@@ -0,0 +1 @@
../../crates-io.md
+1
View File
@@ -0,0 +1 @@
../../../serde_derive/src/bound.rs
+1
View File
@@ -0,0 +1 @@
../../proc-macro2/src/watt/buffer.rs
+1
View File
@@ -0,0 +1 @@
../../proc-macro2/src/watt/bytecode.rs
+1
View File
@@ -0,0 +1 @@
../../../serde_derive/src/de.rs
+1
View File
@@ -0,0 +1 @@
../../../serde_derive/src/dummy.rs
+1
View File
@@ -0,0 +1 @@
../../../serde_derive/src/fragment.rs
+1
View File
@@ -0,0 +1 @@
../../../serde_derive/src/internals/
+25
View File
@@ -0,0 +1,25 @@
//! This crate provides Serde's two derive macros.
//!
//! ```edition2021
//! # use serde_derive::{Deserialize, Serialize};
//! #
//! #[derive(Serialize, Deserialize)]
//! # struct S;
//! #
//! # fn main() {}
//! ```
//!
//! Please refer to [https://serde.rs/derive.html] for how to set this up.
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.172")]
#![allow(unknown_lints, bare_trait_objects)]
extern crate proc_macro;
#[cfg(not(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu")))]
include!("lib_from_source.rs");
#[cfg(all(target_arch = "x86_64", target_os = "linux", target_env = "gnu"))]
include!("lib_precompiled.rs");
@@ -0,0 +1,39 @@
#[macro_use]
extern crate quote;
#[macro_use]
extern crate syn;
extern crate proc_macro2;
mod internals;
use proc_macro::TokenStream;
use syn::DeriveInput;
#[macro_use]
mod bound;
#[macro_use]
mod fragment;
mod de;
mod dummy;
mod pretend;
mod ser;
mod this;
mod try;
#[proc_macro_derive(Serialize, attributes(serde))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput);
ser::expand_derive_serialize(&mut input)
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}
#[proc_macro_derive(Deserialize, attributes(serde))]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(input as DeriveInput);
de::expand_derive_deserialize(&mut input)
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}
@@ -0,0 +1,214 @@
mod buffer;
mod bytecode;
use crate::buffer::{InputBuffer, OutputBuffer};
use crate::bytecode::Bytecode;
use proc_macro::{Delimiter, Group, Ident, Literal, Punct, Spacing, Span, TokenStream, TokenTree};
use std::io::{Read, Write};
use std::iter::FromIterator;
use std::process::{Command, Stdio};
use std::str::FromStr;
#[proc_macro_derive(Serialize, attributes(serde))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
derive(0, input)
}
#[proc_macro_derive(Deserialize, attributes(serde))]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
derive(1 + cfg!(feature = "deserialize_in_place") as u8, input)
}
fn derive(select: u8, input: TokenStream) -> TokenStream {
let mut memory = TokenMemory::default();
let mut buf = OutputBuffer::new();
buf.write_u8(select);
memory.spans.push(Span::call_site());
for token in input {
memory.linearize_token(token, &mut buf);
}
let path = concat!(
env!("CARGO_MANIFEST_DIR"),
"/serde_derive-x86_64-unknown-linux-gnu",
);
let mut child = Command::new(path)
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.expect("failed to spawn process");
let mut stdin = child.stdin.take().unwrap();
let mut buf = buf.into_bytes();
stdin.write_all(&buf).unwrap();
drop(stdin);
let mut stdout = child.stdout.take().unwrap();
buf.clear();
stdout.read_to_end(&mut buf).unwrap();
let mut buf = InputBuffer::new(&buf);
memory.receive(&mut buf)
}
#[derive(Default)]
struct TokenMemory {
spans: Vec<Span>,
groups: Vec<Group>,
idents: Vec<Ident>,
puncts: Vec<Punct>,
literals: Vec<Literal>,
}
enum Kind {
Group(Delimiter),
Ident,
Punct(Spacing),
Literal,
}
impl TokenMemory {
// Depth-first post-order traversal.
fn linearize_token(&mut self, token: TokenTree, buf: &mut OutputBuffer) {
match token {
TokenTree::Group(group) => {
let mut len = 0usize;
for token in group.stream() {
self.linearize_token(token, buf);
len += 1;
}
assert!(len <= u32::MAX as usize);
buf.write_u8(match group.delimiter() {
Delimiter::Parenthesis => Bytecode::GROUP_PARENTHESIS,
Delimiter::Brace => Bytecode::GROUP_BRACE,
Delimiter::Bracket => Bytecode::GROUP_BRACKET,
Delimiter::None => Bytecode::GROUP_NONE,
});
buf.write_u32(len as u32);
self.spans
.extend([group.span(), group.span_open(), group.span_close()]);
self.groups.push(group);
}
TokenTree::Ident(ident) => {
buf.write_u8(Bytecode::IDENT);
let repr = ident.to_string();
assert!(repr.len() <= u16::MAX as usize);
buf.write_u16(repr.len() as u16);
buf.write_str(&repr);
self.spans.push(ident.span());
self.idents.push(ident);
}
TokenTree::Punct(punct) => {
buf.write_u8(match punct.spacing() {
Spacing::Alone => Bytecode::PUNCT_ALONE,
Spacing::Joint => Bytecode::PUNCT_JOINT,
});
let ch = punct.as_char();
assert!(ch.is_ascii());
buf.write_u8(ch as u8);
self.spans.push(punct.span());
self.puncts.push(punct);
}
TokenTree::Literal(literal) => {
buf.write_u8(Bytecode::LITERAL);
let repr = literal.to_string();
assert!(repr.len() <= u16::MAX as usize);
buf.write_u16(repr.len() as u16);
buf.write_str(&repr);
self.spans.push(literal.span());
self.literals.push(literal);
}
}
}
fn receive(&self, buf: &mut InputBuffer) -> TokenStream {
let mut trees = Vec::new();
while !buf.is_empty() {
match match buf.read_u8() {
Bytecode::GROUP_PARENTHESIS => Kind::Group(Delimiter::Parenthesis),
Bytecode::GROUP_BRACE => Kind::Group(Delimiter::Brace),
Bytecode::GROUP_BRACKET => Kind::Group(Delimiter::Bracket),
Bytecode::GROUP_NONE => Kind::Group(Delimiter::None),
Bytecode::IDENT => Kind::Ident,
Bytecode::PUNCT_ALONE => Kind::Punct(Spacing::Alone),
Bytecode::PUNCT_JOINT => Kind::Punct(Spacing::Joint),
Bytecode::LITERAL => Kind::Literal,
Bytecode::LOAD_GROUP => {
let identity = buf.read_u32();
let group = self.groups[identity as usize].clone();
trees.push(TokenTree::Group(group));
continue;
}
Bytecode::LOAD_IDENT => {
let identity = buf.read_u32();
let ident = self.idents[identity as usize].clone();
trees.push(TokenTree::Ident(ident));
continue;
}
Bytecode::LOAD_PUNCT => {
let identity = buf.read_u32();
let punct = self.puncts[identity as usize].clone();
trees.push(TokenTree::Punct(punct));
continue;
}
Bytecode::LOAD_LITERAL => {
let identity = buf.read_u32();
let literal = self.literals[identity as usize].clone();
trees.push(TokenTree::Literal(literal));
continue;
}
Bytecode::SET_SPAN => {
trees.last_mut().unwrap().set_span(self.read_span(buf));
continue;
}
_ => unreachable!(),
} {
Kind::Group(delimiter) => {
let len = buf.read_u32();
let stream = trees.drain(trees.len() - len as usize..).collect();
let group = Group::new(delimiter, stream);
trees.push(TokenTree::Group(group));
}
Kind::Ident => {
let len = buf.read_u16();
let repr = buf.read_str(len as usize);
let span = self.read_span(buf);
let ident = if let Some(repr) = repr.strip_prefix("r#") {
Ident::new_raw(repr, span)
} else {
Ident::new(repr, span)
};
trees.push(TokenTree::Ident(ident));
}
Kind::Punct(spacing) => {
let ch = buf.read_u8();
assert!(ch.is_ascii());
let punct = Punct::new(ch as char, spacing);
trees.push(TokenTree::Punct(punct));
}
Kind::Literal => {
let len = buf.read_u16();
let repr = buf.read_str(len as usize);
let literal = Literal::from_str(repr).unwrap();
trees.push(TokenTree::Literal(literal));
}
}
}
TokenStream::from_iter(trees)
}
fn read_span(&self, buf: &mut InputBuffer) -> Span {
let lo = buf.read_u32();
let hi = buf.read_u32();
let span = self.spans[lo as usize];
if lo == hi {
span
} else {
#[cfg(any())] // FIXME
return span.join(self.spans[hi as usize]).unwrap_or(span);
span
}
}
}
+1
View File
@@ -0,0 +1 @@
../../../serde_derive/src/pretend.rs
+1
View File
@@ -0,0 +1 @@
../../../serde_derive/src/ser.rs
+1
View File
@@ -0,0 +1 @@
../../../serde_derive/src/this.rs
+1
View File
@@ -0,0 +1 @@
../../../serde_derive/src/try.rs
+16 -12
View File
@@ -1,28 +1,32 @@
[package]
name = "serde"
version = "1.0.121" # remember to update html_root_url and serde_derive dependency
version = "1.0.172" # remember to update html_root_url and serde_derive dependency
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT OR Apache-2.0"
description = "A generic serialization/deserialization framework"
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde/"
keywords = ["serde", "serialization", "no_std"]
categories = ["encoding"]
readme = "crates-io.md"
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
build = "build.rs"
categories = ["encoding", "no-std", "no-std::no-alloc"]
description = "A generic serialization/deserialization framework"
documentation = "https://docs.rs/serde"
homepage = "https://serde.rs"
keywords = ["serde", "serialization", "no_std"]
license = "MIT OR Apache-2.0"
readme = "crates-io.md"
repository = "https://github.com/serde-rs/serde"
rust-version = "1.19"
[dependencies]
serde_derive = { version = "=1.0.121", optional = true, path = "../serde_derive" }
serde_derive = { version = "=1.0.172", optional = true, path = "../serde_derive" }
[dev-dependencies]
serde_derive = { version = "1.0", path = "../serde_derive" }
serde_derive = { version = "1", path = "../serde_derive" }
[lib]
doc-scrape-examples = false
[package.metadata.playground]
features = ["derive", "rc"]
[package.metadata.docs.rs]
features = ["derive"]
targets = ["x86_64-unknown-linux-gnu"]
+58 -33
View File
@@ -6,6 +6,8 @@ use std::str::{self, FromStr};
// opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script.
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let minor = match rustc_minor_version() {
Some(minor) => minor,
None => return,
@@ -17,84 +19,107 @@ fn main() {
// 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=ops_bound");
} else if minor >= 17 && cfg!(feature = "std") {
println!("cargo:rustc-cfg=collections_bound");
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=core_reverse");
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=de_boxed_c_str");
println!("cargo:rustc-cfg=de_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=de_rc_dst");
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=core_duration");
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 as Emscripten doesn't
// currently support integers larger than 64 bits.
if minor >= 26 && !emscripten {
println!("cargo:rustc-cfg=integer128");
// 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
if minor >= 27 {
println!("cargo:rustc-cfg=range_inclusive");
// 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=num_nonzero");
if minor < 28 {
println!("cargo:rustc-cfg=no_num_nonzero");
}
// TryFrom, Atomic types, and non-zero signed integers stabilized in Rust 1.34:
// TryFrom, Atomic types, non-zero signed integers, and SystemTime::checked_add
// stabilized in Rust 1.34:
// https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#tryfrom-and-tryinto
// https://blog.rust-lang.org/2019/04/11/Rust-1.34.0.html#library-stabilizations
if minor >= 34 {
println!("cargo:rustc-cfg=core_try_from");
println!("cargo:rustc-cfg=num_nonzero_signed");
if minor < 34 {
println!("cargo:rustc-cfg=no_core_try_from");
println!("cargo:rustc-cfg=no_num_nonzero_signed");
println!("cargo:rustc-cfg=no_systemtime_checked_add");
println!("cargo:rustc-cfg=no_relaxed_trait_bounds");
}
// Whitelist of archs that support std::sync::atomic module. Ideally we
// would use #[cfg(target_has_atomic = "...")] but it is not stable yet.
// Instead this is based on rustc's src/librustc_target/spec/*.rs.
// Current minimum supported version of serde_derive crate is Rust 1.56.
if minor < 56 {
println!("cargo:rustc-cfg=no_serde_derive");
}
// Support for #[cfg(target_has_atomic = "...")] stabilized in Rust 1.60.
if minor < 60 {
println!("cargo:rustc-cfg=no_target_has_atomic");
// Allowlist of archs that support std::sync::atomic module. This is
// based on rustc's compiler/rustc_target/src/spec/*.rs.
let has_atomic64 = target.starts_with("x86_64")
|| target.starts_with("i686")
|| target.starts_with("aarch64")
|| target.starts_with("powerpc64")
|| target.starts_with("sparc64")
|| target.starts_with("mips64el");
|| target.starts_with("mips64el")
|| target.starts_with("riscv64");
let has_atomic32 = has_atomic64 || emscripten;
if has_atomic64 {
println!("cargo:rustc-cfg=std_atomic64");
if minor < 34 || !has_atomic64 {
println!("cargo:rustc-cfg=no_std_atomic64");
}
if has_atomic32 {
println!("cargo:rustc-cfg=std_atomic");
if minor < 34 || !has_atomic32 {
println!("cargo:rustc-cfg=no_std_atomic");
}
}
// Support for core::ffi::CStr and alloc::ffi::CString stabilized in Rust 1.64.
// https://blog.rust-lang.org/2022/09/22/Rust-1.64.0.html#c-compatible-ffi-types-in-core-and-alloc
if minor < 64 {
println!("cargo:rustc-cfg=no_core_cstr");
}
}
fn rustc_minor_version() -> Option<u32> {
+30
View File
@@ -0,0 +1,30 @@
use lib::fmt::{self, Write};
use lib::str;
pub(super) struct Buf<'a> {
bytes: &'a mut [u8],
offset: usize,
}
impl<'a> Buf<'a> {
pub fn new(bytes: &'a mut [u8]) -> Self {
Buf { bytes, offset: 0 }
}
pub fn as_str(&self) -> &str {
let slice = &self.bytes[..self.offset];
unsafe { str::from_utf8_unchecked(slice) }
}
}
impl<'a> Write for Buf<'a> {
fn write_str(&mut self, s: &str) -> fmt::Result {
if self.offset + s.len() > self.bytes.len() {
Err(fmt::Error)
} else {
self.bytes[self.offset..self.offset + s.len()].copy_from_slice(s.as_bytes());
self.offset += s.len();
Ok(())
}
}
}
-260
View File
@@ -1,260 +0,0 @@
use lib::*;
macro_rules! int_to_int {
($dst:ident, $n:ident) => {
if $dst::min_value() as i64 <= $n as i64 && $n as i64 <= $dst::max_value() as i64 {
Some($n as $dst)
} else {
None
}
};
}
macro_rules! int_to_uint {
($dst:ident, $n:ident) => {
if 0 <= $n && $n as u64 <= $dst::max_value() as u64 {
Some($n as $dst)
} else {
None
}
};
}
macro_rules! uint_to {
($dst:ident, $n:ident) => {
if $n as u64 <= $dst::max_value() as u64 {
Some($n as $dst)
} else {
None
}
};
}
pub trait FromPrimitive: Sized {
fn from_i8(n: i8) -> Option<Self>;
fn from_i16(n: i16) -> Option<Self>;
fn from_i32(n: i32) -> Option<Self>;
fn from_i64(n: i64) -> Option<Self>;
fn from_u8(n: u8) -> Option<Self>;
fn from_u16(n: u16) -> Option<Self>;
fn from_u32(n: u32) -> Option<Self>;
fn from_u64(n: u64) -> Option<Self>;
}
macro_rules! impl_from_primitive_for_int {
($t:ident) => {
impl FromPrimitive for $t {
#[inline]
fn from_i8(n: i8) -> Option<Self> {
int_to_int!($t, n)
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
int_to_int!($t, n)
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
int_to_int!($t, n)
}
#[inline]
fn from_i64(n: i64) -> Option<Self> {
int_to_int!($t, n)
}
#[inline]
fn from_u8(n: u8) -> Option<Self> {
uint_to!($t, n)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
uint_to!($t, n)
}
#[inline]
fn from_u32(n: u32) -> Option<Self> {
uint_to!($t, n)
}
#[inline]
fn from_u64(n: u64) -> Option<Self> {
uint_to!($t, n)
}
}
};
}
macro_rules! impl_from_primitive_for_uint {
($t:ident) => {
impl FromPrimitive for $t {
#[inline]
fn from_i8(n: i8) -> Option<Self> {
int_to_uint!($t, n)
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
int_to_uint!($t, n)
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
int_to_uint!($t, n)
}
#[inline]
fn from_i64(n: i64) -> Option<Self> {
int_to_uint!($t, n)
}
#[inline]
fn from_u8(n: u8) -> Option<Self> {
uint_to!($t, n)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
uint_to!($t, n)
}
#[inline]
fn from_u32(n: u32) -> Option<Self> {
uint_to!($t, n)
}
#[inline]
fn from_u64(n: u64) -> Option<Self> {
uint_to!($t, n)
}
}
};
}
macro_rules! impl_from_primitive_for_float {
($t:ident) => {
impl FromPrimitive for $t {
#[inline]
fn from_i8(n: i8) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_i64(n: i64) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_u8(n: u8) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_u32(n: u32) -> Option<Self> {
Some(n as Self)
}
#[inline]
fn from_u64(n: u64) -> Option<Self> {
Some(n as Self)
}
}
};
}
impl_from_primitive_for_int!(isize);
impl_from_primitive_for_int!(i8);
impl_from_primitive_for_int!(i16);
impl_from_primitive_for_int!(i32);
impl_from_primitive_for_int!(i64);
impl_from_primitive_for_uint!(usize);
impl_from_primitive_for_uint!(u8);
impl_from_primitive_for_uint!(u16);
impl_from_primitive_for_uint!(u32);
impl_from_primitive_for_uint!(u64);
impl_from_primitive_for_float!(f32);
impl_from_primitive_for_float!(f64);
serde_if_integer128! {
impl FromPrimitive for i128 {
#[inline]
fn from_i8(n: i8) -> Option<Self> {
Some(n as i128)
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
Some(n as i128)
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
Some(n as i128)
}
#[inline]
fn from_i64(n: i64) -> Option<Self> {
Some(n as i128)
}
#[inline]
fn from_u8(n: u8) -> Option<Self> {
Some(n as i128)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
Some(n as i128)
}
#[inline]
fn from_u32(n: u32) -> Option<Self> {
Some(n as i128)
}
#[inline]
fn from_u64(n: u64) -> Option<Self> {
Some(n as i128)
}
}
impl FromPrimitive for u128 {
#[inline]
fn from_i8(n: i8) -> Option<Self> {
if n >= 0 {
Some(n as u128)
} else {
None
}
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
if n >= 0 {
Some(n as u128)
} else {
None
}
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
if n >= 0 {
Some(n as u128)
} else {
None
}
}
#[inline]
fn from_i64(n: i64) -> Option<Self> {
if n >= 0 {
Some(n as u128)
} else {
None
}
}
#[inline]
fn from_u8(n: u8) -> Option<Self> {
Some(n as u128)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
Some(n as u128)
}
#[inline]
fn from_u32(n: u32) -> Option<Self> {
Some(n as u128)
}
#[inline]
fn from_u64(n: u64) -> Option<Self> {
Some(n as u128)
}
}
}
+5 -6
View File
@@ -10,13 +10,12 @@ use de::{
/// any type, except that it does not store any information about the data that
/// gets deserialized.
///
/// ```edition2018
/// use std::fmt;
/// use std::marker::PhantomData;
///
/// ```edition2021
/// use serde::de::{
/// self, Deserialize, DeserializeSeed, Deserializer, IgnoredAny, SeqAccess, Visitor,
/// };
/// use std::fmt;
/// use std::marker::PhantomData;
///
/// /// A seed that can be used to deserialize only the `n`th element of a sequence
/// /// while efficiently discarding elements of any type before or after index `n`.
@@ -108,7 +107,7 @@ use de::{
/// # Ok(())
/// # }
/// ```
#[derive(Copy, Clone, Debug, Default)]
#[derive(Copy, Clone, Debug, Default, PartialEq)]
pub struct IgnoredAny;
impl<'de> Visitor<'de> for IgnoredAny {
@@ -228,7 +227,7 @@ impl<'de> Visitor<'de> for IgnoredAny {
where
A: EnumAccess<'de>,
{
data.variant::<IgnoredAny>()?.1.newtype_variant()
try!(data.variant::<IgnoredAny>()).1.newtype_variant()
}
}
+698 -274
View File
File diff suppressed because it is too large Load Diff
+73 -54
View File
@@ -30,7 +30,7 @@
//! # The Deserializer trait
//!
//! [`Deserializer`] implementations are provided by third-party crates, for
//! example [`serde_json`], [`serde_yaml`] and [`bincode`].
//! example [`serde_json`], [`serde_yaml`] and [`postcard`].
//!
//! A partial list of well-maintained formats is given on the [Serde
//! website][data formats].
@@ -104,7 +104,7 @@
//! [`Deserialize`]: ../trait.Deserialize.html
//! [`Deserializer`]: ../trait.Deserializer.html
//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
//! [`bincode`]: https://github.com/servo/bincode
//! [`postcard`]: https://github.com/jamesmunns/postcard
//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
//! [`serde_derive`]: https://crates.io/crates/serde_derive
//! [`serde_json`]: https://github.com/serde-rs/json
@@ -118,7 +118,8 @@ use lib::*;
pub mod value;
mod from_primitive;
#[cfg(not(no_integer128))]
mod format;
mod ignored_any;
mod impls;
mod utf8;
@@ -161,7 +162,7 @@ macro_rules! declare_error_trait {
///
/// The message should not be capitalized and should not end with a period.
///
/// ```edition2018
/// ```edition2021
/// # use std::str::FromStr;
/// #
/// # struct IpAddr;
@@ -306,7 +307,7 @@ declare_error_trait!(Error: Sized + Debug + Display);
/// This is used as an argument to the `invalid_type`, `invalid_value`, and
/// `invalid_length` methods of the `Error` trait to build error messages.
///
/// ```edition2018
/// ```edition2021
/// # use std::fmt;
/// #
/// # use serde::de::{self, Unexpected, Visitor};
@@ -393,7 +394,7 @@ pub enum Unexpected<'a> {
}
impl<'a> fmt::Display for Unexpected<'a> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
use self::Unexpected::*;
match *self {
Bool(b) => write!(formatter, "boolean `{}`", b),
@@ -431,10 +432,9 @@ impl<'a> fmt::Display for Unexpected<'a> {
/// Within the context of a `Visitor` implementation, the `Visitor` itself
/// (`&self`) is an implementation of this trait.
///
/// ```edition2018
/// # use std::fmt;
/// #
/// ```edition2021
/// # use serde::de::{self, Unexpected, Visitor};
/// # use std::fmt;
/// #
/// # struct Example;
/// #
@@ -456,7 +456,7 @@ impl<'a> fmt::Display for Unexpected<'a> {
///
/// Outside of a `Visitor`, `&"..."` can be used.
///
/// ```edition2018
/// ```edition2021
/// # use serde::de::{self, Unexpected};
/// #
/// # fn example<E>() -> Result<(), E>
@@ -464,7 +464,10 @@ impl<'a> fmt::Display for Unexpected<'a> {
/// # E: de::Error,
/// # {
/// # let v = true;
/// return Err(de::Error::invalid_type(Unexpected::Bool(v), &"a negative integer"));
/// return Err(de::Error::invalid_type(
/// Unexpected::Bool(v),
/// &"a negative integer",
/// ));
/// # }
/// ```
pub trait Expected {
@@ -500,8 +503,8 @@ impl<'a> Display for Expected + 'a {
/// by Serde.
///
/// Serde provides `Deserialize` implementations for many Rust primitive and
/// standard library types. The complete list is [here][de]. All of these can
/// be deserialized using Serde out of the box.
/// standard library types. The complete list is [here][crate::de]. All of these
/// can be deserialized using Serde out of the box.
///
/// Additionally, Serde provides a procedural macro called `serde_derive` to
/// automatically generate `Deserialize` implementations for structs and enums
@@ -517,7 +520,6 @@ impl<'a> Display for Expected + 'a {
/// `LinkedHashMap<K, V>` type that is deserializable by Serde because the crate
/// provides an implementation of `Deserialize` for it.
///
/// [de]: https://docs.serde.rs/serde/de/index.html
/// [derive]: https://serde.rs/derive.html
/// [impl-deserialize]: https://serde.rs/impl-deserialize.html
///
@@ -564,7 +566,7 @@ pub trait Deserialize<'de>: Sized {
D: Deserializer<'de>,
{
// Default implementation just delegates to `deserialize` impl.
*place = Deserialize::deserialize(deserializer)?;
*place = try!(Deserialize::deserialize(deserializer));
Ok(())
}
}
@@ -577,7 +579,7 @@ pub trait Deserialize<'de>: Sized {
/// from the input string, but a `from_reader` function may only deserialize
/// owned data.
///
/// ```edition2018
/// ```edition2021
/// # use serde::de::{Deserialize, DeserializeOwned};
/// # use std::io::{Read, Result};
/// #
@@ -616,7 +618,7 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
///
/// The canonical API for stateless deserialization looks like this:
///
/// ```edition2018
/// ```edition2021
/// # use serde::Deserialize;
/// #
/// # enum Error {}
@@ -630,7 +632,7 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
/// Adjusting an API like this to support stateful deserialization is a matter
/// of accepting a seed as input:
///
/// ```edition2018
/// ```edition2021
/// # use serde::de::DeserializeSeed;
/// #
/// # enum Error {}
@@ -663,12 +665,11 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
/// into it. This requires stateful deserialization using the `DeserializeSeed`
/// trait.
///
/// ```edition2018
/// ```edition2021
/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor};
/// use std::fmt;
/// use std::marker::PhantomData;
///
/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor};
///
/// // A DeserializeSeed implementation that uses stateful deserialization to
/// // append array elements onto the end of an existing vector. The preexisting
/// // state ("seed") in this case is the Vec<T>. The `deserialize` method of
@@ -707,6 +708,11 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
/// where
/// A: SeqAccess<'de>,
/// {
/// // Decrease the number of reallocations if there are many elements
/// if let Some(size_hint) = seq.size_hint() {
/// self.0.reserve(size_hint);
/// }
///
/// // Visit each element in the inner array and push it onto
/// // the existing vector.
/// while let Some(elem) = seq.next_element()? {
@@ -856,10 +862,10 @@ where
/// The `Deserializer` trait supports two entry point styles which enables
/// different kinds of deserialization.
///
/// 1. The `deserialize` method. Self-describing data formats like JSON are able
/// to look at the serialized data and tell what it represents. For example
/// the JSON deserializer may see an opening curly brace (`{`) and know that
/// it is seeing a map. If the data format supports
/// 1. The `deserialize_any` method. Self-describing data formats like JSON are
/// able to look at the serialized data and tell what it represents. For
/// example the JSON deserializer may see an opening curly brace (`{`) and
/// know that it is seeing a map. If the data format supports
/// `Deserializer::deserialize_any`, it will drive the Visitor using whatever
/// type it sees in the input. JSON uses this approach when deserializing
/// `serde_json::Value` which is an enum that can represent any JSON
@@ -868,7 +874,7 @@ where
/// `Deserializer::deserialize_any`.
///
/// 2. The various `deserialize_*` methods. Non-self-describing formats like
/// Bincode need to be told what is in the input in order to deserialize it.
/// Postcard need to be told what is in the input in order to deserialize it.
/// The `deserialize_*` methods are hints to the deserializer for how to
/// interpret the next piece of input. Non-self-describing formats are not
/// able to deserialize something like `serde_json::Value` which relies on
@@ -878,7 +884,7 @@ where
/// `Deserializer::deserialize_any` unless you need to be told by the
/// Deserializer what type is in the input. Know that relying on
/// `Deserializer::deserialize_any` means your data type will be able to
/// deserialize from self-describing formats only, ruling out Bincode and many
/// deserialize from self-describing formats only, ruling out Postcard and many
/// others.
///
/// [Serde data model]: https://serde.rs/data-model.html
@@ -909,7 +915,7 @@ pub trait Deserializer<'de>: Sized {
/// `Deserializer::deserialize_any` unless you need to be told by the
/// Deserializer what type is in the input. Know that relying on
/// `Deserializer::deserialize_any` means your data type will be able to
/// deserialize from self-describing formats only, ruling out Bincode and
/// deserialize from self-describing formats only, ruling out Postcard and
/// many others.
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
@@ -1008,7 +1014,7 @@ pub trait Deserializer<'de>: Sized {
/// `Deserializer`.
///
/// If the `Visitor` would benefit from taking ownership of `String` data,
/// indiciate this to the `Deserializer` by using `deserialize_string`
/// indicate this to the `Deserializer` by using `deserialize_string`
/// instead.
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
@@ -1150,10 +1156,10 @@ pub trait Deserializer<'de>: Sized {
/// Some types have a human-readable form that may be somewhat expensive to
/// construct, as well as a binary form that is compact and efficient.
/// Generally text-based formats like JSON and YAML will prefer to use the
/// human-readable one and binary formats like Bincode will prefer the
/// human-readable one and binary formats like Postcard will prefer the
/// compact one.
///
/// ```edition2018
/// ```edition2021
/// # use std::ops::Add;
/// # use std::str::FromStr;
/// #
@@ -1214,6 +1220,20 @@ pub trait Deserializer<'de>: Sized {
fn is_human_readable(&self) -> bool {
true
}
// Not public API.
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
#[doc(hidden)]
fn __deserialize_content<V>(
self,
_: ::actually_private::T,
visitor: V,
) -> Result<::private::de::Content<'de>, Self::Error>
where
V: Visitor<'de, Value = ::private::de::Content<'de>>,
{
self.deserialize_any(visitor)
}
}
////////////////////////////////////////////////////////////////////////////////
@@ -1230,10 +1250,9 @@ pub trait Deserializer<'de>: Sized {
///
/// # Example
///
/// ```edition2018
/// # use std::fmt;
/// #
/// ```edition2021
/// # use serde::de::{self, Unexpected, Visitor};
/// # use std::fmt;
/// #
/// /// A visitor that deserializes a long string - a string containing at least
/// /// some minimum number of bytes.
@@ -1271,7 +1290,7 @@ pub trait Visitor<'de>: Sized {
/// "an integer between 0 and 64". The message should not be capitalized and
/// should not end with a period.
///
/// ```edition2018
/// ```edition2021
/// # use std::fmt;
/// #
/// # struct S {
@@ -1353,8 +1372,10 @@ pub trait Visitor<'de>: Sized {
where
E: Error,
{
let _ = v;
Err(Error::invalid_type(Unexpected::Other("i128"), &self))
let mut buf = [0u8; 58];
let mut writer = format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as i128", v)).unwrap();
Err(Error::invalid_type(Unexpected::Other(writer.as_str()), &self))
}
}
@@ -1413,8 +1434,10 @@ pub trait Visitor<'de>: Sized {
where
E: Error,
{
let _ = v;
Err(Error::invalid_type(Unexpected::Other("u128"), &self))
let mut buf = [0u8; 57];
let mut writer = format::Buf::new(&mut buf);
fmt::Write::write_fmt(&mut writer, format_args!("integer `{}` as u128", v)).unwrap();
Err(Error::invalid_type(Unexpected::Other(writer.as_str()), &self))
}
}
@@ -1536,7 +1559,7 @@ pub trait Visitor<'de>: Sized {
/// `Deserializer`.
///
/// This enables zero-copy deserialization of bytes in some formats. For
/// example Bincode data containing bytes can be deserialized with zero
/// example Postcard data containing bytes can be deserialized with zero
/// copying into a `&'a [u8]` as long as the input data outlives `'a`.
///
/// The default implementation forwards to `visit_bytes`.
@@ -1715,7 +1738,7 @@ pub trait SeqAccess<'de> {
}
}
impl<'de, 'a, A> SeqAccess<'de> for &'a mut A
impl<'de, 'a, A: ?Sized> SeqAccess<'de> for &'a mut A
where
A: SeqAccess<'de>,
{
@@ -1868,7 +1891,7 @@ pub trait MapAccess<'de> {
}
}
impl<'de, 'a, A> MapAccess<'de> for &'a mut A
impl<'de, 'a, A: ?Sized> MapAccess<'de> for &'a mut A
where
A: MapAccess<'de>,
{
@@ -2012,7 +2035,7 @@ pub trait VariantAccess<'de>: Sized {
/// If the data contains a different type of variant, the following
/// `invalid_type` error should be constructed:
///
/// ```edition2018
/// ```edition2021
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
/// #
/// # struct X;
@@ -2052,7 +2075,7 @@ pub trait VariantAccess<'de>: Sized {
/// If the data contains a different type of variant, the following
/// `invalid_type` error should be constructed:
///
/// ```edition2018
/// ```edition2021
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
/// #
/// # struct X;
@@ -2108,7 +2131,7 @@ pub trait VariantAccess<'de>: Sized {
/// If the data contains a different type of variant, the following
/// `invalid_type` error should be constructed:
///
/// ```edition2018
/// ```edition2021
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
/// #
/// # struct X;
@@ -2125,11 +2148,7 @@ pub trait VariantAccess<'de>: Sized {
/// # T: DeserializeSeed<'de>,
/// # { unimplemented!() }
/// #
/// fn tuple_variant<V>(
/// self,
/// _len: usize,
/// _visitor: V,
/// ) -> Result<V::Value, Self::Error>
/// fn tuple_variant<V>(self, _len: usize, _visitor: V) -> Result<V::Value, Self::Error>
/// where
/// V: Visitor<'de>,
/// {
@@ -2155,7 +2174,7 @@ pub trait VariantAccess<'de>: Sized {
/// If the data contains a different type of variant, the following
/// `invalid_type` error should be constructed:
///
/// ```edition2018
/// ```edition2021
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
/// #
/// # struct X;
@@ -2215,10 +2234,10 @@ pub trait VariantAccess<'de>: Sized {
///
/// # Example
///
/// ```edition2018
/// ```edition2021
/// use serde::de::{value, Deserialize, IntoDeserializer};
/// use serde_derive::Deserialize;
/// use std::str::FromStr;
/// use serde::Deserialize;
/// use serde::de::{value, IntoDeserializer};
///
/// #[derive(Deserialize)]
/// enum Setting {
+19
View File
@@ -0,0 +1,19 @@
use de::{Deserialize, DeserializeSeed, Deserializer};
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
///
/// Wraps a mutable reference and calls deserialize_in_place on it.
pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
where
T: Deserialize<'de>,
{
type Value = ();
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize_in_place(deserializer, self.0)
}
}
+1 -1
View File
@@ -31,7 +31,7 @@ pub fn encode(c: char) -> Encode {
buf[3] = (code & 0x3F) as u8 | TAG_CONT;
0
};
Encode { buf: buf, pos: pos }
Encode { buf, pos }
}
pub struct Encode {
+218 -44
View File
@@ -1,10 +1,10 @@
//! Building blocks for deserializing basic values using the `IntoDeserializer`
//! trait.
//!
//! ```edition2018
//! ```edition2021
//! use serde::de::{value, Deserialize, IntoDeserializer};
//! use serde_derive::Deserialize;
//! use std::str::FromStr;
//! use serde::Deserialize;
//! use serde::de::{value, IntoDeserializer};
//!
//! #[derive(Deserialize)]
//! enum Setting {
@@ -24,7 +24,7 @@
use lib::*;
use self::private::{First, Second};
use __private::de::size_hint;
use __private::size_hint;
use de::{self, Deserializer, Expected, IntoDeserializer, SeqAccess, Visitor};
use ser;
@@ -48,7 +48,7 @@ macro_rules! impl_copy_clone {
/// A minimal representation of all possible errors that can occur using the
/// `IntoDeserializer` trait.
#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, PartialEq)]
pub struct Error {
err: ErrorImpl,
}
@@ -93,16 +93,25 @@ impl ser::Error for Error {
impl Display for Error {
#[cfg(any(feature = "std", feature = "alloc"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(&self.err)
}
#[cfg(not(any(feature = "std", feature = "alloc")))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("Serde deserialization error")
}
}
impl Debug for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
let mut debug = formatter.debug_tuple("Error");
#[cfg(any(feature = "std", feature = "alloc"))]
debug.field(&self.err);
debug.finish()
}
}
#[cfg(feature = "std")]
impl error::Error for Error {
fn description(&self) -> &str {
@@ -119,20 +128,26 @@ where
type Deserializer = UnitDeserializer<E>;
fn into_deserializer(self) -> UnitDeserializer<E> {
UnitDeserializer {
marker: PhantomData,
}
UnitDeserializer::new()
}
}
/// A deserializer holding a `()`.
#[derive(Debug)]
pub struct UnitDeserializer<E> {
marker: PhantomData<E>,
}
impl_copy_clone!(UnitDeserializer);
impl<E> UnitDeserializer<E> {
#[allow(missing_docs)]
pub fn new() -> Self {
UnitDeserializer {
marker: PhantomData,
}
}
}
impl<'de, E> de::Deserializer<'de> for UnitDeserializer<E>
where
E: de::Error,
@@ -160,6 +175,12 @@ where
}
}
impl<E> Debug for UnitDeserializer<E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.debug_struct("UnitDeserializer").finish()
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer that cannot be instantiated.
@@ -208,7 +229,6 @@ macro_rules! primitive_deserializer {
($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => {
#[doc = "A deserializer holding"]
#[doc = $doc]
#[derive(Debug)]
pub struct $name<E> {
value: $ty,
marker: PhantomData<E>
@@ -223,8 +243,15 @@ macro_rules! primitive_deserializer {
type Deserializer = $name<E>;
fn into_deserializer(self) -> $name<E> {
$name::new(self)
}
}
impl<E> $name<E> {
#[allow(missing_docs)]
pub fn new(value: $ty) -> Self {
$name {
value: self,
value,
marker: PhantomData,
}
}
@@ -249,6 +276,15 @@ macro_rules! primitive_deserializer {
visitor.$method(self.value $($cast)*)
}
}
impl<E> Debug for $name<E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.debug_struct(stringify!($name))
.field("value", &self.value)
.finish()
}
}
}
}
@@ -272,7 +308,6 @@ serde_if_integer128! {
}
/// A deserializer holding a `u32`.
#[derive(Debug)]
pub struct U32Deserializer<E> {
value: u32,
marker: PhantomData<E>,
@@ -287,8 +322,15 @@ where
type Deserializer = U32Deserializer<E>;
fn into_deserializer(self) -> U32Deserializer<E> {
U32Deserializer::new(self)
}
}
impl<E> U32Deserializer<E> {
#[allow(missing_docs)]
pub fn new(value: u32) -> Self {
U32Deserializer {
value: self,
value,
marker: PhantomData,
}
}
@@ -343,10 +385,18 @@ where
}
}
impl<E> Debug for U32Deserializer<E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.debug_struct("U32Deserializer")
.field("value", &self.value)
.finish()
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `&str`.
#[derive(Debug)]
pub struct StrDeserializer<'a, E> {
value: &'a str,
marker: PhantomData<E>,
@@ -361,8 +411,15 @@ where
type Deserializer = StrDeserializer<'a, E>;
fn into_deserializer(self) -> StrDeserializer<'a, E> {
StrDeserializer::new(self)
}
}
impl<'a, E> StrDeserializer<'a, E> {
#[allow(missing_docs)]
pub fn new(value: &'a str) -> Self {
StrDeserializer {
value: self,
value,
marker: PhantomData,
}
}
@@ -417,11 +474,19 @@ where
}
}
impl<'a, E> Debug for StrDeserializer<'a, E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.debug_struct("StrDeserializer")
.field("value", &self.value)
.finish()
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `&str` with a lifetime tied to another
/// deserializer.
#[derive(Debug)]
pub struct BorrowedStrDeserializer<'de, E> {
value: &'de str,
marker: PhantomData<E>,
@@ -433,7 +498,7 @@ impl<'de, E> BorrowedStrDeserializer<'de, E> {
/// Create a new borrowed deserializer from the given string.
pub fn new(value: &'de str) -> BorrowedStrDeserializer<'de, E> {
BorrowedStrDeserializer {
value: value,
value,
marker: PhantomData,
}
}
@@ -488,11 +553,19 @@ where
}
}
impl<'de, E> Debug for BorrowedStrDeserializer<'de, E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.debug_struct("BorrowedStrDeserializer")
.field("value", &self.value)
.finish()
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `String`.
#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Debug)]
pub struct StringDeserializer<E> {
value: String,
marker: PhantomData<E>,
@@ -516,8 +589,16 @@ where
type Deserializer = StringDeserializer<E>;
fn into_deserializer(self) -> StringDeserializer<E> {
StringDeserializer::new(self)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<E> StringDeserializer<E> {
#[allow(missing_docs)]
pub fn new(value: String) -> Self {
StringDeserializer {
value: self,
value,
marker: PhantomData,
}
}
@@ -559,7 +640,7 @@ where
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> de::EnumAccess<'de> for StringDeserializer<E>
impl<'de, E> de::EnumAccess<'de> for StringDeserializer<E>
where
E: de::Error,
{
@@ -574,11 +655,20 @@ where
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<E> Debug for StringDeserializer<E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.debug_struct("StringDeserializer")
.field("value", &self.value)
.finish()
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `Cow<str>`.
#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Debug)]
pub struct CowStrDeserializer<'a, E> {
value: Cow<'a, str>,
marker: PhantomData<E>,
@@ -602,8 +692,16 @@ where
type Deserializer = CowStrDeserializer<'a, E>;
fn into_deserializer(self) -> CowStrDeserializer<'a, E> {
CowStrDeserializer::new(self)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, E> CowStrDeserializer<'a, E> {
#[allow(missing_docs)]
pub fn new(value: Cow<'a, str>) -> Self {
CowStrDeserializer {
value: self,
value,
marker: PhantomData,
}
}
@@ -663,10 +761,19 @@ where
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, E> Debug for CowStrDeserializer<'a, E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.debug_struct("CowStrDeserializer")
.field("value", &self.value)
.finish()
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `&[u8]`. Always calls [`Visitor::visit_bytes`].
#[derive(Debug)]
pub struct BytesDeserializer<'a, E> {
value: &'a [u8],
marker: PhantomData<E>,
@@ -676,7 +783,7 @@ impl<'a, E> BytesDeserializer<'a, E> {
/// Create a new deserializer from the given bytes.
pub fn new(value: &'a [u8]) -> Self {
BytesDeserializer {
value: value,
value,
marker: PhantomData,
}
}
@@ -684,6 +791,17 @@ impl<'a, E> BytesDeserializer<'a, E> {
impl_copy_clone!(BytesDeserializer<'a>);
impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a [u8]
where
E: de::Error,
{
type Deserializer = BytesDeserializer<'a, E>;
fn into_deserializer(self) -> BytesDeserializer<'a, E> {
BytesDeserializer::new(self)
}
}
impl<'de, 'a, E> Deserializer<'de> for BytesDeserializer<'a, E>
where
E: de::Error,
@@ -704,9 +822,17 @@ where
}
}
impl<'a, E> Debug for BytesDeserializer<'a, E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.debug_struct("BytesDeserializer")
.field("value", &self.value)
.finish()
}
}
/// A deserializer holding a `&[u8]` with a lifetime tied to another
/// deserializer. Always calls [`Visitor::visit_borrowed_bytes`].
#[derive(Debug)]
pub struct BorrowedBytesDeserializer<'de, E> {
value: &'de [u8],
marker: PhantomData<E>,
@@ -716,7 +842,7 @@ impl<'de, E> BorrowedBytesDeserializer<'de, E> {
/// Create a new borrowed deserializer from the given borrowed bytes.
pub fn new(value: &'de [u8]) -> Self {
BorrowedBytesDeserializer {
value: value,
value,
marker: PhantomData,
}
}
@@ -744,10 +870,19 @@ where
}
}
impl<'de, E> Debug for BorrowedBytesDeserializer<'de, E> {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.debug_struct("BorrowedBytesDeserializer")
.field("value", &self.value)
.finish()
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer that iterates over a sequence.
#[derive(Clone, Debug)]
#[derive(Clone)]
pub struct SeqDeserializer<I, E> {
iter: iter::Fuse<I>,
count: usize,
@@ -852,6 +987,19 @@ impl Expected for ExpectedInSeq {
}
}
impl<I, E> Debug for SeqDeserializer<I, E>
where
I: Debug,
{
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter
.debug_struct("SeqDeserializer")
.field("iter", &self.iter)
.field("count", &self.count)
.finish()
}
}
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))]
@@ -905,7 +1053,7 @@ pub struct SeqAccessDeserializer<A> {
impl<A> SeqAccessDeserializer<A> {
/// Construct a new `SeqAccessDeserializer<A>`.
pub fn new(seq: A) -> Self {
SeqAccessDeserializer { seq: seq }
SeqAccessDeserializer { seq }
}
}
@@ -1147,7 +1295,6 @@ where
}
}
// Cannot #[derive(Debug)] because of the bound `Second<I::Item>: Debug`.
impl<'de, I, E> Debug for MapDeserializer<'de, I, E>
where
I: Iterator + Debug,
@@ -1160,8 +1307,6 @@ where
.field("iter", &self.iter)
.field("value", &self.value)
.field("count", &self.count)
.field("lifetime", &self.lifetime)
.field("error", &self.error)
.finish()
}
}
@@ -1309,7 +1454,7 @@ pub struct MapAccessDeserializer<A> {
impl<A> MapAccessDeserializer<A> {
/// Construct a new `MapAccessDeserializer<A>`.
pub fn new(map: A) -> Self {
MapAccessDeserializer { map: map }
MapAccessDeserializer { map }
}
}
@@ -1356,7 +1501,7 @@ where
where
T: de::DeserializeSeed<'de>,
{
match self.map.next_key_seed(seed)? {
match try!(self.map.next_key_seed(seed)) {
Some(key) => Ok((key, private::map_as_enum(self.map))),
None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")),
}
@@ -1365,12 +1510,46 @@ where
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding an `EnumAccess`.
#[derive(Clone, Debug)]
pub struct EnumAccessDeserializer<A> {
access: A,
}
impl<A> EnumAccessDeserializer<A> {
/// Construct a new `EnumAccessDeserializer<A>`.
pub fn new(access: A) -> Self {
EnumAccessDeserializer { access }
}
}
impl<'de, A> de::Deserializer<'de> for EnumAccessDeserializer<A>
where
A: de::EnumAccess<'de>,
{
type Error = A::Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_enum(self.access)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
}
////////////////////////////////////////////////////////////////////////////////
mod private {
use lib::*;
use de::{self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor};
#[derive(Clone, Debug)]
pub struct UnitOnly<E> {
marker: PhantomData<E>,
}
@@ -1429,13 +1608,12 @@ mod private {
}
}
#[derive(Clone, Debug)]
pub struct MapAsEnum<A> {
map: A,
}
pub fn map_as_enum<A>(map: A) -> MapAsEnum<A> {
MapAsEnum { map: map }
MapAsEnum { map }
}
impl<'de, A> VariantAccess<'de> for MapAsEnum<A>
@@ -1459,10 +1637,7 @@ mod private {
where
V: Visitor<'de>,
{
self.map.next_value_seed(SeedTupleVariant {
len: len,
visitor: visitor,
})
self.map.next_value_seed(SeedTupleVariant { len, visitor })
}
fn struct_variant<V>(
@@ -1473,8 +1648,7 @@ mod private {
where
V: Visitor<'de>,
{
self.map
.next_value_seed(SeedStructVariant { visitor: visitor })
self.map.next_value_seed(SeedStructVariant { visitor })
}
}
+6 -6
View File
@@ -9,8 +9,8 @@
/// or do not target platforms that lack 128-bit integers, do not need to
/// bother with this macro and may assume support for 128-bit integers.
///
/// ```edition2018
/// # use serde::__private::ser::Error;
/// ```edition2021
/// # use serde::__private::doc::Error;
/// #
/// # struct MySerializer;
/// #
@@ -50,7 +50,7 @@
/// When Serde is built with support for 128-bit integers, this macro expands
/// transparently into just the input tokens.
///
/// ```edition2018
/// ```edition2021
/// macro_rules! serde_if_integer128 {
/// ($($tt:tt)*) => {
/// $($tt)*
@@ -61,12 +61,12 @@
/// When built without support for 128-bit integers, this macro expands to
/// nothing.
///
/// ```edition2018
/// ```edition2021
/// macro_rules! serde_if_integer128 {
/// ($($tt:tt)*) => {};
/// }
/// ```
#[cfg(integer128)]
#[cfg(not(no_integer128))]
#[macro_export]
macro_rules! serde_if_integer128 {
($($tt:tt)*) => {
@@ -74,7 +74,7 @@ macro_rules! serde_if_integer128 {
};
}
#[cfg(not(integer128))]
#[cfg(no_integer128)]
#[macro_export]
#[doc(hidden)]
macro_rules! serde_if_integer128 {
+89 -33
View File
@@ -31,8 +31,7 @@
//! for Serde by the community.
//!
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//! used for IPC within the Servo rendering engine.
//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
//! - [CBOR], a Concise Binary Object Representation designed for small message
//! size without the need for version negotiation.
//! - [YAML], a self-proclaimed human-friendly configuration language that ain't
@@ -44,9 +43,10 @@
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//! definition.
//! - [JSON5], A superset of JSON including some productions from ES5.
//! - [Postcard], a no\_std and embedded-systems friendly compact binary format.
//! - [JSON5], a superset of JSON including some productions from ES5.
//! - [URL] query strings, in the x-www-form-urlencoded format.
//! - [Starlark], the format used for describing build targets by the Bazel and
//! Buck build systems. *(serialization only)*
//! - [Envy], a way to deserialize environment variables into Rust structs.
//! *(deserialization only)*
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
@@ -54,58 +54,66 @@
//! - [S-expressions], the textual representation of code and data used by the
//! Lisp language family.
//! - [D-Bus]'s binary wire format.
//! - [FlexBuffers], the schemaless cousin of Google's FlatBuffers zero-copy serialization format.
//! - [FlexBuffers], the schemaless cousin of Google's FlatBuffers zero-copy
//! serialization format.
//! - [Bencode], a simple binary format used in the BitTorrent protocol.
//! - [Token streams], for processing Rust procedural macro input.
//! *(deserialization only)*
//! - [DynamoDB Items], the format used by [rusoto_dynamodb] to transfer data to
//! and from DynamoDB.
//! - [Hjson], a syntax extension to JSON designed around human reading and
//! editing. *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/servo/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [Postcard]: https://github.com/jamesmunns/postcard
//! [CBOR]: https://github.com/enarx/ciborium
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [TOML]: https://docs.rs/toml
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [RON]: https://github.com/ron-rs/ron
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [BSON]: https://github.com/mongodb/bson-rust
//! [Avro]: https://docs.rs/apache-avro
//! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [Postcard]: https://github.com/jamesmunns/postcard
//! [URL]: https://docs.rs/serde_qs
//! [Starlark]: https://github.com/dtolnay/serde-starlark
//! [Envy]: https://github.com/softprops/envy
//! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html
//! [Cargo]: https://doc.rust-lang.org/cargo/reference/manifest.html
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html
//! [S-expressions]: https://github.com/rotty/lexpr-rs
//! [D-Bus]: https://docs.rs/zvariant
//! [FlexBuffers]: https://github.com/google/flatbuffers/tree/master/rust/flexbuffers
//! [Bencode]: https://github.com/P3KI/bendy
//! [Token streams]: https://github.com/oxidecomputer/serde_tokenstream
//! [DynamoDB Items]: https://docs.rs/serde_dynamo
//! [rusoto_dynamodb]: https://docs.rs/rusoto_dynamodb
//! [Hjson]: https://github.com/Canop/deser-hjson
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.121")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.172")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
// https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(never_type))]
#![cfg_attr(feature = "unstable", feature(error_in_core, never_type))]
#![allow(unknown_lints, bare_trait_objects, deprecated)]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy and clippy_pedantic lints
#![cfg_attr(
feature = "cargo-clippy",
allow(
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
unnested_or_patterns,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7768
semicolon_if_nothing_returned,
// not available in our oldest supported compiler
checked_conversions,
empty_enum,
redundant_field_names,
redundant_static_lifetimes,
type_repetition_in_bounds, // https://github.com/rust-lang/rust-clippy/issues/8772
// integer and float ser/de requires these sorts of casts
cast_possible_truncation,
cast_possible_wrap,
@@ -119,8 +127,12 @@
use_self,
zero_prefixed_literal,
// correctly used
derive_partial_eq_without_eq,
enum_glob_use,
explicit_auto_deref,
let_underscore_untyped,
map_err_ignore,
new_without_default,
result_unit_err,
wildcard_imports,
// not practical
@@ -138,7 +150,6 @@
)
)]
// Rustc lints.
#![forbid(unsafe_code)]
#![deny(missing_docs, unused_imports)]
////////////////////////////////////////////////////////////////////////////////
@@ -157,7 +168,7 @@ mod lib {
pub use std::*;
}
pub use self::core::{cmp, iter, mem, num, slice, str};
pub use self::core::{cmp, iter, mem, num, ptr, slice, str};
pub use self::core::{f32, f64};
pub use self::core::{i16, i32, i64, i8, isize};
pub use self::core::{u16, u32, u64, u8, usize};
@@ -169,7 +180,7 @@ mod lib {
pub use self::core::fmt::{self, Debug, Display};
pub use self::core::marker::{self, PhantomData};
pub use self::core::num::Wrapping;
pub use self::core::ops::Range;
pub use self::core::ops::{Range, RangeFrom, RangeTo};
pub use self::core::option::{self, Option};
pub use self::core::result::{self, Result};
@@ -208,13 +219,23 @@ mod lib {
#[cfg(feature = "std")]
pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
#[cfg(all(not(no_core_cstr), not(feature = "std")))]
pub use core::ffi::CStr;
#[cfg(feature = "std")]
pub use std::ffi::CStr;
#[cfg(all(not(no_core_cstr), feature = "alloc", not(feature = "std")))]
pub use alloc::ffi::CString;
#[cfg(feature = "std")]
pub use std::ffi::CString;
#[cfg(feature = "std")]
pub use std::{error, net};
#[cfg(feature = "std")]
pub use std::collections::{HashMap, HashSet};
#[cfg(feature = "std")]
pub use std::ffi::{CStr, CString, OsStr, OsString};
pub use std::ffi::{OsStr, OsString};
#[cfg(feature = "std")]
pub use std::hash::{BuildHasher, Hash};
#[cfg(feature = "std")]
@@ -226,30 +247,56 @@ mod lib {
#[cfg(feature = "std")]
pub use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(all(feature = "std", collections_bound))]
#[cfg(all(feature = "std", not(no_collections_bound), no_ops_bound))]
pub use std::collections::Bound;
#[cfg(core_reverse)]
#[cfg(not(no_core_reverse))]
pub use self::core::cmp::Reverse;
#[cfg(ops_bound)]
#[cfg(not(no_ops_bound))]
pub use self::core::ops::Bound;
#[cfg(range_inclusive)]
#[cfg(not(no_range_inclusive))]
pub use self::core::ops::RangeInclusive;
#[cfg(all(feature = "std", std_atomic))]
#[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic)))]
pub use std::sync::atomic::{
AtomicBool, AtomicI16, AtomicI32, AtomicI8, AtomicIsize, AtomicU16, AtomicU32, AtomicU8,
AtomicUsize, Ordering,
};
#[cfg(all(feature = "std", std_atomic64))]
#[cfg(all(feature = "std", no_target_has_atomic, not(no_std_atomic64)))]
pub use std::sync::atomic::{AtomicI64, AtomicU64};
#[cfg(any(core_duration, feature = "std"))]
#[cfg(all(feature = "std", not(no_target_has_atomic)))]
pub use std::sync::atomic::Ordering;
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "8"))]
pub use std::sync::atomic::{AtomicBool, AtomicI8, AtomicU8};
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "16"))]
pub use std::sync::atomic::{AtomicI16, AtomicU16};
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "32"))]
pub use std::sync::atomic::{AtomicI32, AtomicU32};
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "64"))]
pub use std::sync::atomic::{AtomicI64, AtomicU64};
#[cfg(all(feature = "std", not(no_target_has_atomic), target_has_atomic = "ptr"))]
pub use std::sync::atomic::{AtomicIsize, AtomicUsize};
#[cfg(any(feature = "std", not(no_core_duration)))]
pub use self::core::time::Duration;
}
// None of this crate's error handling needs the `From::from` error conversion
// performed implicitly by the `?` operator or the standard library's `try!`
// macro. This simplified macro gives a 5.5% improvement in compile time
// compared to standard `try!`, and 9% improvement compared to `?`.
macro_rules! try {
($expr:expr) => {
match $expr {
Ok(val) => val,
Err(err) => return Err(err),
}
};
}
////////////////////////////////////////////////////////////////////////////////
#[macro_use]
@@ -276,7 +323,10 @@ use self::__private as export;
#[allow(unused_imports)]
use self::__private as private;
#[cfg(not(feature = "std"))]
#[path = "de/seed.rs"]
mod seed;
#[cfg(not(any(feature = "std", feature = "unstable")))]
mod std_error;
// Re-export #[derive(Serialize, Deserialize)].
@@ -288,6 +338,12 @@ mod std_error;
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
/// Derive macro available if serde is built with `features = ["derive"]`.
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;
pub use serde_derive::{Deserialize, Serialize};
#[cfg(all(not(no_serde_derive), any(feature = "std", feature = "alloc")))]
mod actually_private {
pub struct T;
}
+4 -5
View File
@@ -11,7 +11,7 @@
/// input. This requires repetitive implementations of all the [`Deserializer`]
/// trait methods.
///
/// ```edition2018
/// ```edition2021
/// # use serde::forward_to_deserialize_any;
/// # use serde::de::{value, Deserializer, Visitor};
/// #
@@ -47,7 +47,7 @@
/// methods so that they forward directly to [`Deserializer::deserialize_any`].
/// You can choose which methods to forward.
///
/// ```edition2018
/// ```edition2021
/// # use serde::forward_to_deserialize_any;
/// # use serde::de::{value, Deserializer, Visitor};
/// #
@@ -78,11 +78,10 @@
/// called `V`. A different type parameter and a different lifetime can be
/// specified explicitly if necessary.
///
/// ```edition2018
/// # use std::marker::PhantomData;
/// #
/// ```edition2021
/// # use serde::forward_to_deserialize_any;
/// # use serde::de::{value, Deserializer, Visitor};
/// # use std::marker::PhantomData;
/// #
/// # struct MyDeserializer<V>(PhantomData<V>);
/// #
+249 -245
View File
@@ -1,10 +1,10 @@
use lib::*;
use de::value::{BorrowedBytesDeserializer, BytesDeserializer};
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
use de::{Deserialize, Deserializer, Error, IntoDeserializer, Visitor};
#[cfg(any(feature = "std", feature = "alloc"))]
use de::{MapAccess, Unexpected};
use de::{DeserializeSeed, MapAccess, Unexpected};
#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::content::{
@@ -13,6 +13,8 @@ pub use self::content::{
TagOrContentField, TagOrContentFieldVisitor, TaggedContentVisitor, UntaggedUnitVisitor,
};
pub use seed::InPlaceSeed;
/// If the missing field is of type `Option<T>` then treat is as `None`,
/// otherwise it is an error.
pub fn missing_field<'de, V, E>(field: &'static str) -> Result<V, E>
@@ -189,29 +191,6 @@ where
.map(From::from)
}
pub mod size_hint {
use lib::*;
pub fn from_bounds<I>(iter: &I) -> Option<usize>
where
I: Iterator,
{
helper(iter.size_hint())
}
#[inline]
pub fn cautious(hint: Option<usize>) -> usize {
cmp::min(hint.unwrap_or(0), 4096)
}
fn helper(bounds: (usize, Option<usize>)) -> Option<usize> {
match bounds {
(lower, Some(upper)) if lower == upper => Some(upper),
_ => None,
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
mod content {
// This module is private and nothing here should be used outside of
@@ -226,7 +205,8 @@ mod content {
use lib::*;
use super::size_hint;
use __private::size_hint;
use actually_private;
use de::{
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
MapAccess, SeqAccess, Unexpected, Visitor,
@@ -236,7 +216,7 @@ mod content {
/// deserializing untagged enums and internally tagged enums.
///
/// Not public API. Use serde-value instead.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub enum Content<'de> {
Bool(bool),
@@ -315,7 +295,7 @@ mod content {
// Untagged and internally tagged enums are only supported in
// self-describing formats.
let visitor = ContentVisitor { value: PhantomData };
deserializer.deserialize_any(visitor)
deserializer.__deserialize_content(actually_private::T, visitor)
}
}
@@ -494,7 +474,8 @@ mod content {
where
V: SeqAccess<'de>,
{
let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint()));
let mut vec =
Vec::<Content>::with_capacity(size_hint::cautious::<Content>(visitor.size_hint()));
while let Some(e) = try!(visitor.next_element()) {
vec.push(e);
}
@@ -505,7 +486,10 @@ mod content {
where
V: MapAccess<'de>,
{
let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint()));
let mut vec =
Vec::<(Content, Content)>::with_capacity(
size_hint::cautious::<(Content, Content)>(visitor.size_hint()),
);
while let Some(kv) = try!(visitor.next_entry()) {
vec.push(kv);
}
@@ -538,7 +522,7 @@ mod content {
impl<'de> TagOrContentVisitor<'de> {
fn new(name: &'static str) -> Self {
TagOrContentVisitor {
name: name,
name,
value: PhantomData,
}
}
@@ -817,52 +801,32 @@ mod content {
/// Used by generated code to deserialize an internally tagged enum.
///
/// Not public API.
pub struct TaggedContent<'de, T> {
pub tag: T,
pub content: Content<'de>,
}
/// Not public API.
pub struct TaggedContentVisitor<'de, T> {
pub struct TaggedContentVisitor<T> {
tag_name: &'static str,
value: PhantomData<TaggedContent<'de, T>>,
expecting: &'static str,
value: PhantomData<T>,
}
impl<'de, T> TaggedContentVisitor<'de, T> {
impl<T> TaggedContentVisitor<T> {
/// Visitor for the content of an internally tagged enum with the given
/// tag name.
pub fn new(name: &'static str) -> Self {
pub fn new(name: &'static str, expecting: &'static str) -> Self {
TaggedContentVisitor {
tag_name: name,
expecting,
value: PhantomData,
}
}
}
impl<'de, T> DeserializeSeed<'de> for TaggedContentVisitor<'de, T>
impl<'de, T> Visitor<'de> for TaggedContentVisitor<T>
where
T: Deserialize<'de>,
{
type Value = TaggedContent<'de, T>;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
// Internally tagged enums are only supported in self-describing
// formats.
deserializer.deserialize_any(self)
}
}
impl<'de, T> Visitor<'de> for TaggedContentVisitor<'de, T>
where
T: Deserialize<'de>,
{
type Value = TaggedContent<'de, T>;
type Value = (T, Content<'de>);
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
fmt.write_str("internally tagged enum")
fmt.write_str(self.expecting)
}
fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
@@ -876,10 +840,7 @@ mod content {
}
};
let rest = de::value::SeqAccessDeserializer::new(seq);
Ok(TaggedContent {
tag: tag,
content: try!(Content::deserialize(rest)),
})
Ok((tag, try!(Content::deserialize(rest))))
}
fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
@@ -887,7 +848,10 @@ mod content {
M: MapAccess<'de>,
{
let mut tag = None;
let mut vec = Vec::with_capacity(size_hint::cautious(map.size_hint()));
let mut vec = Vec::<(Content, Content)>::with_capacity(size_hint::cautious::<(
Content,
Content,
)>(map.size_hint()));
while let Some(k) = try!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
match k {
TagOrContent::Tag => {
@@ -904,10 +868,7 @@ mod content {
}
match tag {
None => Err(de::Error::missing_field(self.tag_name)),
Some(tag) => Ok(TaggedContent {
tag: tag,
content: Content::Map(vec),
}),
Some(tag) => Ok((tag, Content::Map(vec))),
}
}
}
@@ -933,7 +894,7 @@ mod content {
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(self)
deserializer.deserialize_identifier(self)
}
}
@@ -944,6 +905,20 @@ mod content {
write!(formatter, "{:?} or {:?}", self.tag, self.content)
}
fn visit_u64<E>(self, field_index: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
match field_index {
0 => Ok(TagOrContentField::Tag),
1 => Ok(TagOrContentField::Content),
_ => Err(de::Error::invalid_value(
Unexpected::Unsigned(field_index),
&self,
)),
}
}
fn visit_str<E>(self, field: &str) -> Result<Self::Value, E>
where
E: de::Error,
@@ -956,6 +931,19 @@ mod content {
Err(de::Error::invalid_value(Unexpected::Str(field), &self))
}
}
fn visit_bytes<E>(self, field: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
if field == self.tag.as_bytes() {
Ok(TagOrContentField::Tag)
} else if field == self.content.as_bytes() {
Ok(TagOrContentField::Content)
} else {
Err(de::Error::invalid_value(Unexpected::Bytes(field), &self))
}
}
}
/// Used by generated code to deserialize an adjacently tagged enum when
@@ -981,7 +969,7 @@ mod content {
where
D: Deserializer<'de>,
{
deserializer.deserialize_str(self)
deserializer.deserialize_identifier(self)
}
}
@@ -996,13 +984,31 @@ mod content {
)
}
fn visit_u64<E>(self, field_index: u64) -> Result<Self::Value, E>
where
E: de::Error,
{
match field_index {
0 => Ok(TagContentOtherField::Tag),
1 => Ok(TagContentOtherField::Content),
_ => Ok(TagContentOtherField::Other),
}
}
fn visit_str<E>(self, field: &str) -> Result<Self::Value, E>
where
E: de::Error,
{
if field == self.tag {
self.visit_bytes(field.as_bytes())
}
fn visit_bytes<E>(self, field: &[u8]) -> Result<Self::Value, E>
where
E: de::Error,
{
if field == self.tag.as_bytes() {
Ok(TagContentOtherField::Tag)
} else if field == self.content {
} else if field == self.content.as_bytes() {
Ok(TagContentOtherField::Content)
} else {
Ok(TagContentOtherField::Other)
@@ -1041,6 +1047,25 @@ mod content {
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_float<V>(self, visitor: V) -> Result<V::Value, E>
where
V: Visitor<'de>,
{
match self.content {
Content::F32(v) => visitor.visit_f32(v),
Content::F64(v) => visitor.visit_f64(v),
Content::U8(v) => visitor.visit_u8(v),
Content::U16(v) => visitor.visit_u16(v),
Content::U32(v) => visitor.visit_u32(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I8(v) => visitor.visit_i8(v),
Content::I16(v) => visitor.visit_i16(v),
Content::I32(v) => visitor.visit_i32(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
}
}
fn visit_content_seq<'de, V, E>(content: Vec<Content<'de>>, visitor: V) -> Result<V::Value, E>
@@ -1180,25 +1205,14 @@ mod content {
where
V: Visitor<'de>,
{
match self.content {
Content::F32(v) => visitor.visit_f32(v),
Content::F64(v) => visitor.visit_f64(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
self.deserialize_float(visitor)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::F64(v) => visitor.visit_f64(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
self.deserialize_float(visitor)
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@@ -1272,6 +1286,17 @@ mod content {
{
match self.content {
Content::Unit => visitor.visit_unit(),
// Allow deserializing newtype variant containing unit.
//
// #[derive(Deserialize)]
// #[serde(tag = "result")]
// enum Response<T> {
// Success(T),
// }
//
// We want {"result":"Success"} to deserialize into Response<()>.
Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
_ => Err(self.invalid_type(&visitor)),
}
}
@@ -1298,8 +1323,9 @@ mod content {
// }
//
// We want {"topic":"Info"} to deserialize even though
// ordinarily unit structs do not deserialize from empty map.
// ordinarily unit structs do not deserialize from empty map/seq.
Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
Content::Seq(ref v) if v.is_empty() => visitor.visit_unit(),
_ => self.deserialize_any(visitor),
}
}
@@ -1437,13 +1463,25 @@ mod content {
drop(self);
visitor.visit_unit()
}
fn __deserialize_content<V>(
self,
_: actually_private::T,
visitor: V,
) -> Result<Content<'de>, Self::Error>
where
V: Visitor<'de, Value = Content<'de>>,
{
let _ = visitor;
Ok(self.content)
}
}
impl<'de, E> ContentDeserializer<'de, E> {
/// private API, don't use
pub fn new(content: Content<'de>) -> Self {
ContentDeserializer {
content: content,
content,
err: PhantomData,
}
}
@@ -1464,8 +1502,8 @@ mod content {
{
pub fn new(variant: Content<'de>, value: Option<Content<'de>>) -> EnumDeserializer<'de, E> {
EnumDeserializer {
variant: variant,
value: value,
variant,
value,
err: PhantomData,
}
}
@@ -1752,6 +1790,25 @@ mod content {
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_float<V>(self, visitor: V) -> Result<V::Value, E>
where
V: Visitor<'de>,
{
match *self.content {
Content::F32(v) => visitor.visit_f32(v),
Content::F64(v) => visitor.visit_f64(v),
Content::U8(v) => visitor.visit_u8(v),
Content::U16(v) => visitor.visit_u16(v),
Content::U32(v) => visitor.visit_u32(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I8(v) => visitor.visit_i8(v),
Content::I16(v) => visitor.visit_i16(v),
Content::I32(v) => visitor.visit_i32(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
}
}
fn visit_content_seq_ref<'a, 'de, V, E>(
@@ -1777,7 +1834,7 @@ mod content {
V: Visitor<'de>,
E: de::Error,
{
let map = content.iter().map(|&(ref k, ref v)| {
let map = content.iter().map(|(k, v)| {
(
ContentRefDeserializer::new(k),
ContentRefDeserializer::new(v),
@@ -1899,25 +1956,14 @@ mod content {
where
V: Visitor<'de>,
{
match *self.content {
Content::F32(v) => visitor.visit_f32(v),
Content::F64(v) => visitor.visit_f64(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
self.deserialize_float(visitor)
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::F64(v) => visitor.visit_f64(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
self.deserialize_float(visitor)
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
@@ -2085,7 +2131,7 @@ mod content {
let (variant, value) = match *self.content {
Content::Map(ref value) => {
let mut iter = value.iter();
let &(ref variant, ref value) = match iter.next() {
let (variant, value) = match iter.next() {
Some(v) => v,
None => {
return Err(de::Error::invalid_value(
@@ -2113,8 +2159,8 @@ mod content {
};
visitor.visit_enum(EnumRefDeserializer {
variant: variant,
value: value,
variant,
value,
err: PhantomData,
})
}
@@ -2140,18 +2186,38 @@ mod content {
{
visitor.visit_unit()
}
fn __deserialize_content<V>(
self,
_: actually_private::T,
visitor: V,
) -> Result<Content<'de>, Self::Error>
where
V: Visitor<'de, Value = Content<'de>>,
{
let _ = visitor;
Ok(self.content.clone())
}
}
impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E> {
/// private API, don't use
pub fn new(content: &'a Content<'de>) -> Self {
ContentRefDeserializer {
content: content,
content,
err: PhantomData,
}
}
}
impl<'a, 'de: 'a, E> Copy for ContentRefDeserializer<'a, 'de, E> {}
impl<'a, 'de: 'a, E> Clone for ContentRefDeserializer<'a, 'de, E> {
fn clone(&self) -> Self {
*self
}
}
struct EnumRefDeserializer<'a, 'de: 'a, E>
where
E: de::Error,
@@ -2220,7 +2286,7 @@ mod content {
V: de::Visitor<'de>,
{
match self.value {
Some(&Content::Seq(ref v)) => {
Some(Content::Seq(v)) => {
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
}
Some(other) => Err(de::Error::invalid_type(
@@ -2243,10 +2309,10 @@ mod content {
V: de::Visitor<'de>,
{
match self.value {
Some(&Content::Map(ref v)) => {
Some(Content::Map(v)) => {
de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
}
Some(&Content::Seq(ref v)) => {
Some(Content::Seq(v)) => {
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
}
Some(other) => Err(de::Error::invalid_type(
@@ -2369,7 +2435,7 @@ mod content {
T: de::DeserializeSeed<'de>,
{
match self.iter.next() {
Some(&(ref key, ref value)) => {
Some((key, value)) => {
self.value = Some(value);
seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
}
@@ -2447,8 +2513,8 @@ mod content {
/// Not public API.
pub fn new(type_name: &'a str, variant_name: &'a str) -> Self {
InternallyTaggedUnitVisitor {
type_name: type_name,
variant_name: variant_name,
type_name,
variant_name,
}
}
}
@@ -2492,8 +2558,8 @@ mod content {
/// Not public API.
pub fn new(type_name: &'a str, variant_name: &'a str) -> Self {
UntaggedUnitVisitor {
type_name: type_name,
variant_name: variant_name,
type_name,
variant_name,
}
}
}
@@ -2539,26 +2605,21 @@ mod content {
// }
pub trait IdentifierDeserializer<'de, E: Error> {
type Deserializer: Deserializer<'de, Error = E>;
type BorrowedDeserializer: Deserializer<'de, Error = E>;
fn from(self) -> Self::Deserializer;
fn borrowed(self) -> Self::BorrowedDeserializer;
}
impl<'de, E> IdentifierDeserializer<'de, E> for u32
pub struct Borrowed<'de, T: 'de + ?Sized>(pub &'de T);
impl<'de, E> IdentifierDeserializer<'de, E> for u64
where
E: Error,
{
type Deserializer = <u32 as IntoDeserializer<'de, E>>::Deserializer;
type BorrowedDeserializer = <u32 as IntoDeserializer<'de, E>>::Deserializer;
type Deserializer = <u64 as IntoDeserializer<'de, E>>::Deserializer;
fn from(self) -> Self::Deserializer {
self.into_deserializer()
}
fn borrowed(self) -> Self::BorrowedDeserializer {
self.into_deserializer()
}
}
pub struct StrDeserializer<'a, E> {
@@ -2616,7 +2677,6 @@ where
E: Error,
{
type Deserializer = StrDeserializer<'a, E>;
type BorrowedDeserializer = BorrowedStrDeserializer<'a, E>;
fn from(self) -> Self::Deserializer {
StrDeserializer {
@@ -2624,10 +2684,17 @@ where
marker: PhantomData,
}
}
}
fn borrowed(self) -> Self::BorrowedDeserializer {
impl<'de, E> IdentifierDeserializer<'de, E> for Borrowed<'de, str>
where
E: Error,
{
type Deserializer = BorrowedStrDeserializer<'de, E>;
fn from(self) -> Self::Deserializer {
BorrowedStrDeserializer {
value: self,
value: self.0,
marker: PhantomData,
}
}
@@ -2638,32 +2705,20 @@ where
E: Error,
{
type Deserializer = BytesDeserializer<'a, E>;
type BorrowedDeserializer = BorrowedBytesDeserializer<'a, E>;
fn from(self) -> Self::Deserializer {
BytesDeserializer::new(self)
}
fn borrowed(self) -> Self::BorrowedDeserializer {
BorrowedBytesDeserializer::new(self)
}
}
/// A DeserializeSeed helper for implementing deserialize_in_place Visitors.
///
/// Wraps a mutable reference and calls deserialize_in_place on it.
pub struct InPlaceSeed<'a, T: 'a>(pub &'a mut T);
impl<'a, 'de, T> DeserializeSeed<'de> for InPlaceSeed<'a, T>
impl<'de, E> IdentifierDeserializer<'de, E> for Borrowed<'de, [u8]>
where
T: Deserialize<'de>,
E: Error,
{
type Value = ();
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize_in_place(deserializer, self.0)
type Deserializer = BorrowedBytesDeserializer<'de, E>;
fn from(self) -> Self::Deserializer {
BorrowedBytesDeserializer::new(self.0)
}
}
@@ -2685,7 +2740,7 @@ where
#[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! forward_to_deserialize_other {
($($func:ident ( $($arg:ty),* ))*) => {
($($func:ident ($($arg:ty),*))*) => {
$(
fn $func<V>(self, $(_: $arg,)* _visitor: V) -> Result<V::Value, Self::Error>
where
@@ -2708,11 +2763,7 @@ where
where
V: Visitor<'de>,
{
visitor.visit_map(FlatInternallyTaggedAccess {
iter: self.0.iter_mut(),
pending: None,
_marker: PhantomData,
})
self.deserialize_map(visitor)
}
fn deserialize_enum<V>(
@@ -2724,17 +2775,8 @@ where
where
V: Visitor<'de>,
{
for item in self.0.iter_mut() {
// items in the vector are nulled out when used. So we can only use
// an item if it's still filled in and if the field is one we care
// about.
let use_item = match *item {
None => false,
Some((ref c, _)) => c.as_str().map_or(false, |x| variants.contains(&x)),
};
if use_item {
let (key, value) = item.take().unwrap();
for entry in self.0 {
if let Some((key, value)) = flat_map_take_entry(entry, variants) {
return visitor.visit_enum(EnumDeserializer::new(key, Some(value)));
}
}
@@ -2749,7 +2791,11 @@ where
where
V: Visitor<'de>,
{
visitor.visit_map(FlatMapAccess::new(self.0.iter()))
visitor.visit_map(FlatMapAccess {
iter: self.0.iter(),
pending_content: None,
_marker: PhantomData,
})
}
fn deserialize_struct<V>(
@@ -2761,7 +2807,12 @@ where
where
V: Visitor<'de>,
{
visitor.visit_map(FlatStructAccess::new(self.0.iter_mut(), fields))
visitor.visit_map(FlatStructAccess {
iter: self.0.iter_mut(),
pending_content: None,
fields,
_marker: PhantomData,
})
}
fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
@@ -2788,6 +2839,13 @@ where
visitor.visit_unit()
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_unit()
}
forward_to_deserialize_other! {
deserialize_bool()
deserialize_i8()
@@ -2810,30 +2868,16 @@ where
deserialize_tuple(usize)
deserialize_tuple_struct(&'static str, usize)
deserialize_identifier()
deserialize_ignored_any()
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatMapAccess<'a, 'de: 'a, E> {
struct FlatMapAccess<'a, 'de: 'a, E> {
iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
pending_content: Option<&'a Content<'de>>,
_marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> FlatMapAccess<'a, 'de, E> {
fn new(
iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
) -> FlatMapAccess<'a, 'de, E> {
FlatMapAccess {
iter: iter,
pending_content: None,
_marker: PhantomData,
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> MapAccess<'de> for FlatMapAccess<'a, 'de, E>
where
@@ -2845,9 +2889,13 @@ where
where
T: DeserializeSeed<'de>,
{
while let Some(item) = self.iter.next() {
for item in &mut self.iter {
// Items in the vector are nulled out when used by a struct.
if let Some((ref key, ref content)) = *item {
// Do not take(), instead borrow this entry. The internally tagged
// enum does its own buffering so we can't tell whether this entry
// is going to be consumed. Borrowing here leaves the entry
// available for later flattened fields.
self.pending_content = Some(content);
return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
}
@@ -2867,28 +2915,13 @@ where
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatStructAccess<'a, 'de: 'a, E> {
struct FlatStructAccess<'a, 'de: 'a, E> {
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
pending_content: Option<Content<'de>>,
fields: &'static [&'static str],
_marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> FlatStructAccess<'a, 'de, E> {
fn new(
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
fields: &'static [&'static str],
) -> FlatStructAccess<'a, 'de, E> {
FlatStructAccess {
iter: iter,
pending_content: None,
fields: fields,
_marker: PhantomData,
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'a, 'de, E>
where
@@ -2900,17 +2933,8 @@ where
where
T: DeserializeSeed<'de>,
{
while let Some(item) = self.iter.next() {
// items in the vector are nulled out when used. So we can only use
// an item if it's still filled in and if the field is one we care
// about. In case we do not know which fields we want, we take them all.
let use_item = match *item {
None => false,
Some((ref c, _)) => c.as_str().map_or(false, |key| self.fields.contains(&key)),
};
if use_item {
let (key, content) = item.take().unwrap();
for entry in self.iter.by_ref() {
if let Some((key, content)) = flat_map_take_entry(entry, self.fields) {
self.pending_content = Some(content);
return seed.deserialize(ContentDeserializer::new(key)).map(Some);
}
@@ -2929,44 +2953,24 @@ where
}
}
/// Claims one key-value pair from a FlatMapDeserializer's field buffer if the
/// field name matches any of the recognized ones.
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatInternallyTaggedAccess<'a, 'de: 'a, E> {
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
pending: Option<&'a Content<'de>>,
_marker: PhantomData<E>,
}
fn flat_map_take_entry<'de>(
entry: &mut Option<(Content<'de>, Content<'de>)>,
recognized: &[&str],
) -> Option<(Content<'de>, Content<'de>)> {
// Entries in the FlatMapDeserializer buffer are nulled out as they get
// claimed for deserialization. We only use an entry if it is still present
// and if the field is one recognized by the current data structure.
let is_recognized = match entry {
None => false,
Some((k, _v)) => k.as_str().map_or(false, |name| recognized.contains(&name)),
};
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> MapAccess<'de> for FlatInternallyTaggedAccess<'a, 'de, E>
where
E: Error,
{
type Error = E;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
while let Some(item) = self.iter.next() {
if let Some((ref key, ref content)) = *item {
// Do not take(), instead borrow this entry. The internally tagged
// enum does its own buffering so we can't tell whether this entry
// is going to be consumed. Borrowing here leaves the entry
// available for later flattened fields.
self.pending = Some(content);
return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
}
}
Ok(None)
}
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeSeed<'de>,
{
match self.pending.take() {
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
None => panic!("value is missing"),
}
if is_recognized {
entry.take()
} else {
None
}
}
@@ -1,3 +1,35 @@
// Used only by Serde doc tests. Not public API.
use lib::*;
use ser;
#[doc(hidden)]
#[derive(Debug)]
pub struct Error;
impl ser::Error for Error {
fn custom<T>(_: T) -> Self
where
T: Display,
{
unimplemented!()
}
}
#[cfg(feature = "std")]
impl error::Error for Error {
fn description(&self) -> &str {
unimplemented!()
}
}
impl Display for Error {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
unimplemented!()
}
}
#[doc(hidden)]
#[macro_export]
macro_rules! __private_serialize {
@@ -10,19 +42,6 @@ macro_rules! __private_serialize {
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __private_deserialize {
() => {
trait Deserialize<'de>: Sized {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: $crate::Deserializer<'de>;
}
};
}
/// Used only by Serde doc tests. Not public API.
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __serialize_unimplemented {
+9 -3
View File
@@ -1,14 +1,20 @@
mod macros;
#[cfg(not(no_serde_derive))]
pub mod de;
#[cfg(not(no_serde_derive))]
pub mod ser;
pub mod size_hint;
// FIXME: #[cfg(doctest)] once https://github.com/rust-lang/rust/issues/67295 is fixed.
pub mod doc;
pub use lib::clone::Clone;
pub use lib::convert::{From, Into};
pub use lib::default::Default;
pub use lib::fmt::{self, Formatter};
pub use lib::marker::PhantomData;
pub use lib::option::Option::{self, None, Some};
pub use lib::ptr;
pub use lib::result::Result::{self, Err, Ok};
pub use self::string::from_utf8_lossy;
@@ -16,7 +22,7 @@ pub use self::string::from_utf8_lossy;
#[cfg(any(feature = "alloc", feature = "std"))]
pub use lib::{ToString, Vec};
#[cfg(core_try_from)]
#[cfg(not(no_core_try_from))]
pub use lib::convert::TryFrom;
mod string {
+22 -50
View File
@@ -27,10 +27,10 @@ where
T: Serialize,
{
value.serialize(TaggedSerializer {
type_ident: type_ident,
variant_ident: variant_ident,
tag: tag,
variant_name: variant_name,
type_ident,
variant_ident,
tag,
variant_name,
delegate: serializer,
})
}
@@ -51,7 +51,6 @@ enum Unsupported {
String,
ByteArray,
Optional,
Unit,
#[cfg(any(feature = "std", feature = "alloc"))]
UnitStruct,
Sequence,
@@ -70,7 +69,6 @@ impl Display for Unsupported {
Unsupported::String => formatter.write_str("a string"),
Unsupported::ByteArray => formatter.write_str("a byte array"),
Unsupported::Optional => formatter.write_str("an optional"),
Unsupported::Unit => formatter.write_str("unit"),
#[cfg(any(feature = "std", feature = "alloc"))]
Unsupported::UnitStruct => formatter.write_str("unit struct"),
Unsupported::Sequence => formatter.write_str("a sequence"),
@@ -184,7 +182,9 @@ where
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(self.bad_type(Unsupported::Unit))
let mut map = try!(self.delegate.serialize_map(Some(1)));
try!(map.serialize_entry(self.tag, self.variant_name));
map.end()
}
fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
@@ -335,33 +335,6 @@ where
}
}
/// Used only by Serde doc tests. Not public API.
#[doc(hidden)]
#[derive(Debug)]
pub struct Error;
impl ser::Error for Error {
fn custom<T>(_: T) -> Self
where
T: Display,
{
unimplemented!()
}
}
#[cfg(feature = "std")]
impl error::Error for Error {
fn description(&self) -> &str {
unimplemented!()
}
}
impl Display for Error {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
unimplemented!()
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
mod content {
use lib::*;
@@ -377,8 +350,8 @@ mod content {
impl<M> SerializeTupleVariantAsMapValue<M> {
pub fn new(map: M, name: &'static str, len: usize) -> Self {
SerializeTupleVariantAsMapValue {
map: map,
name: name,
map,
name,
fields: Vec::with_capacity(len),
}
}
@@ -417,8 +390,8 @@ mod content {
impl<M> SerializeStructVariantAsMapValue<M> {
pub fn new(map: M, name: &'static str, len: usize) -> Self {
SerializeStructVariantAsMapValue {
map: map,
name: name,
map,
name,
fields: Vec::with_capacity(len),
}
}
@@ -452,7 +425,6 @@ mod content {
}
}
#[derive(Debug)]
pub enum Content {
Bool(bool),
@@ -553,7 +525,7 @@ mod content {
Content::Map(ref entries) => {
use ser::SerializeMap;
let mut map = try!(serializer.serialize_map(Some(entries.len())));
for &(ref k, ref v) in entries {
for (k, v) in entries {
try!(map.serialize_entry(k, v));
}
map.end()
@@ -739,7 +711,7 @@ mod content {
len: usize,
) -> Result<Self::SerializeTupleStruct, E> {
Ok(SerializeTupleStruct {
name: name,
name,
fields: Vec::with_capacity(len),
error: PhantomData,
})
@@ -753,9 +725,9 @@ mod content {
len: usize,
) -> Result<Self::SerializeTupleVariant, E> {
Ok(SerializeTupleVariant {
name: name,
variant_index: variant_index,
variant: variant,
name,
variant_index,
variant,
fields: Vec::with_capacity(len),
error: PhantomData,
})
@@ -775,7 +747,7 @@ mod content {
len: usize,
) -> Result<Self::SerializeStruct, E> {
Ok(SerializeStruct {
name: name,
name,
fields: Vec::with_capacity(len),
error: PhantomData,
})
@@ -789,9 +761,9 @@ mod content {
len: usize,
) -> Result<Self::SerializeStructVariant, E> {
Ok(SerializeStructVariant {
name: name,
variant_index: variant_index,
variant: variant,
name,
variant_index,
variant,
fields: Vec::with_capacity(len),
error: PhantomData,
})
@@ -1301,8 +1273,8 @@ where
{
fn new(map: &'a mut M, name: &'static str) -> FlatMapSerializeStructVariantAsMapValue<'a, M> {
FlatMapSerializeStructVariantAsMapValue {
map: map,
name: name,
map,
name,
fields: Vec::new(),
}
}
+29
View File
@@ -0,0 +1,29 @@
use lib::*;
pub fn from_bounds<I>(iter: &I) -> Option<usize>
where
I: Iterator,
{
helper(iter.size_hint())
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub fn cautious<Element>(hint: Option<usize>) -> usize {
const MAX_PREALLOC_BYTES: usize = 1024 * 1024;
if mem::size_of::<Element>() == 0 {
0
} else {
cmp::min(
hint.unwrap_or(0),
MAX_PREALLOC_BYTES / mem::size_of::<Element>(),
)
}
}
fn helper(bounds: (usize, Option<usize>)) -> Option<usize> {
match bounds {
(lower, Some(upper)) if lower == upper => Some(upper),
_ => None,
}
}
+3 -2
View File
@@ -17,8 +17,9 @@ macro_rules! fmt_primitives {
};
}
/// ```edition2018
/// use serde::Serialize;
/// ```edition2021
/// use serde::ser::Serialize;
/// use serde_derive::Serialize;
/// use std::fmt::{self, Display};
///
/// #[derive(Serialize)]
+165 -30
View File
@@ -72,7 +72,7 @@ impl<'a> Serialize for fmt::Arguments<'a> {
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
#[cfg(any(feature = "std", not(no_core_cstr)))]
impl Serialize for CStr {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -83,7 +83,7 @@ impl Serialize for CStr {
}
}
#[cfg(feature = "std")]
#[cfg(any(feature = "std", all(not(no_core_cstr), feature = "alloc")))]
impl Serialize for CString {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -182,9 +182,27 @@ where
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg(all(any(feature = "std", feature = "alloc"), not(no_relaxed_trait_bounds)))]
macro_rules! seq_impl {
($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => {
($ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)*>) => {
impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
where
T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_seq(self)
}
}
}
}
#[cfg(all(any(feature = "std", feature = "alloc"), no_relaxed_trait_bounds))]
macro_rules! seq_impl {
($ty:ident <T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)*>) => {
impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
where
T: Serialize $(+ $tbound1 $(+ $tbound2)*)*,
@@ -239,7 +257,24 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(range_inclusive)]
impl<Idx> Serialize for RangeFrom<Idx>
where
Idx: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("RangeFrom", 1));
try!(state.serialize_field("start", &self.start));
state.end()
}
}
////////////////////////////////////////////////////////////////////////////////
#[cfg(not(no_range_inclusive))]
impl<Idx> Serialize for RangeInclusive<Idx>
where
Idx: Serialize,
@@ -258,7 +293,24 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(ops_bound, collections_bound))]
impl<Idx> Serialize for RangeTo<Idx>
where
Idx: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("RangeTo", 1));
try!(state.serialize_field("end", &self.end));
state.end()
}
}
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(not(no_ops_bound), all(feature = "std", not(no_collections_bound))))]
impl<T> Serialize for Bound<T>
where
T: Serialize,
@@ -347,9 +399,28 @@ tuple_impls! {
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg(all(any(feature = "std", feature = "alloc"), not(no_relaxed_trait_bounds)))]
macro_rules! map_impl {
($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => {
($ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)*>) => {
impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
where
K: Serialize,
V: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_map(self)
}
}
}
}
#[cfg(all(any(feature = "std", feature = "alloc"), no_relaxed_trait_bounds))]
macro_rules! map_impl {
($ty:ident <K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)*>) => {
impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
where
K: Serialize $(+ $kbound1 $(+ $kbound2)*)*,
@@ -465,9 +536,9 @@ where
////////////////////////////////////////////////////////////////////////////////
macro_rules! nonzero_integers {
( $( $T: ident, )+ ) => {
($($T:ident,)+) => {
$(
#[cfg(num_nonzero)]
#[cfg(not(no_num_nonzero))]
impl Serialize for num::$T {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -488,7 +559,7 @@ nonzero_integers! {
NonZeroUsize,
}
#[cfg(num_nonzero_signed)]
#[cfg(not(no_num_nonzero_signed))]
nonzero_integers! {
NonZeroI8,
NonZeroI16,
@@ -504,7 +575,7 @@ serde_if_integer128! {
NonZeroU128,
}
#[cfg(num_nonzero_signed)]
#[cfg(not(no_num_nonzero_signed))]
nonzero_integers! {
NonZeroI128,
}
@@ -522,7 +593,7 @@ where
}
}
impl<T> Serialize for RefCell<T>
impl<T: ?Sized> Serialize for RefCell<T>
where
T: Serialize,
{
@@ -538,7 +609,7 @@ where
}
#[cfg(feature = "std")]
impl<T> Serialize for Mutex<T>
impl<T: ?Sized> Serialize for Mutex<T>
where
T: Serialize,
{
@@ -554,7 +625,7 @@ where
}
#[cfg(feature = "std")]
impl<T> Serialize for RwLock<T>
impl<T: ?Sized> Serialize for RwLock<T>
where
T: Serialize,
{
@@ -591,7 +662,7 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(core_duration, feature = "std"))]
#[cfg(any(feature = "std", not(no_core_duration)))]
impl Serialize for Duration {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
@@ -614,9 +685,10 @@ impl Serialize for SystemTime {
S: Serializer,
{
use super::SerializeStruct;
let duration_since_epoch = self
.duration_since(UNIX_EPOCH)
.map_err(|_| S::Error::custom("SystemTime must be later than UNIX_EPOCH"))?;
let duration_since_epoch = match self.duration_since(UNIX_EPOCH) {
Ok(duration_since_epoch) => duration_since_epoch,
Err(_) => return Err(S::Error::custom("SystemTime must be later than UNIX_EPOCH")),
};
let mut state = try!(serializer.serialize_struct("SystemTime", 2));
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
@@ -674,6 +746,52 @@ impl Serialize for net::IpAddr {
}
}
#[cfg(feature = "std")]
const DEC_DIGITS_LUT: &[u8] = b"\
0001020304050607080910111213141516171819\
2021222324252627282930313233343536373839\
4041424344454647484950515253545556575859\
6061626364656667686970717273747576777879\
8081828384858687888990919293949596979899";
#[cfg(feature = "std")]
#[inline]
fn format_u8(mut n: u8, out: &mut [u8]) -> usize {
if n >= 100 {
let d1 = ((n % 100) << 1) as usize;
n /= 100;
out[0] = b'0' + n;
out[1] = DEC_DIGITS_LUT[d1];
out[2] = DEC_DIGITS_LUT[d1 + 1];
3
} else if n >= 10 {
let d1 = (n << 1) as usize;
out[0] = DEC_DIGITS_LUT[d1];
out[1] = DEC_DIGITS_LUT[d1 + 1];
2
} else {
out[0] = b'0' + n;
1
}
}
#[cfg(feature = "std")]
#[test]
fn test_format_u8() {
let mut i = 0u8;
loop {
let mut buf = [0u8; 3];
let written = format_u8(i, &mut buf);
assert_eq!(i.to_string().as_bytes(), &buf[..written]);
match i.checked_add(1) {
Some(next) => i = next,
None => break,
}
}
}
#[cfg(feature = "std")]
impl Serialize for net::Ipv4Addr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -683,7 +801,15 @@ impl Serialize for net::Ipv4Addr {
if serializer.is_human_readable() {
const MAX_LEN: usize = 15;
debug_assert_eq!(MAX_LEN, "101.102.103.104".len());
serialize_display_bounded_length!(self, MAX_LEN, serializer)
let mut buf = [b'.'; MAX_LEN];
let mut written = format_u8(self.octets()[0], &mut buf);
for oct in &self.octets()[1..] {
// Skip over delimiters that we initialized buf with
written += format_u8(*oct, &mut buf[written + 1..]) + 1;
}
// Safety: We've only written ASCII bytes to the buffer, so it is valid UTF-8
let buf = unsafe { str::from_utf8_unchecked(&buf[..written]) };
serializer.serialize_str(buf)
} else {
self.octets().serialize(serializer)
}
@@ -837,7 +963,7 @@ where
}
}
#[cfg(core_reverse)]
#[cfg(not(no_core_reverse))]
impl<T> Serialize for Reverse<T>
where
T: Serialize,
@@ -853,30 +979,39 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(all(feature = "std", std_atomic))]
#[cfg(all(feature = "std", not(no_std_atomic)))]
macro_rules! atomic_impl {
($($ty:ident)*) => {
($($ty:ident $size:expr)*) => {
$(
#[cfg(any(no_target_has_atomic, target_has_atomic = $size))]
impl Serialize for $ty {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.load(Ordering::SeqCst).serialize(serializer)
// Matches the atomic ordering used in libcore for the Debug impl
self.load(Ordering::Relaxed).serialize(serializer)
}
}
)*
}
}
#[cfg(all(feature = "std", std_atomic))]
#[cfg(all(feature = "std", not(no_std_atomic)))]
atomic_impl! {
AtomicBool
AtomicI8 AtomicI16 AtomicI32 AtomicIsize
AtomicU8 AtomicU16 AtomicU32 AtomicUsize
AtomicBool "8"
AtomicI8 "8"
AtomicI16 "16"
AtomicI32 "32"
AtomicIsize "ptr"
AtomicU8 "8"
AtomicU16 "16"
AtomicU32 "32"
AtomicUsize "ptr"
}
#[cfg(all(feature = "std", std_atomic64))]
#[cfg(all(feature = "std", not(no_std_atomic64)))]
atomic_impl! {
AtomicI64 AtomicU64
AtomicI64 "64"
AtomicU64 "64"
}
+2 -2
View File
@@ -15,9 +15,9 @@ use ser::{
/// [`SerializeTuple`], [`SerializeTupleStruct`], [`SerializeTupleVariant`],
/// [`SerializeMap`], [`SerializeStruct`], and [`SerializeStructVariant`].
///
/// ```edition2018
/// ```edition2021
/// # use serde::ser::{Serializer, Impossible};
/// # use serde::__private::ser::Error;
/// # use serde::__private::doc::Error;
/// #
/// # struct MySerializer;
/// #
+97 -77
View File
@@ -30,7 +30,7 @@
//! # The Serializer trait
//!
//! [`Serializer`] implementations are provided by third-party crates, for
//! example [`serde_json`], [`serde_yaml`] and [`bincode`].
//! example [`serde_json`], [`serde_yaml`] and [`postcard`].
//!
//! A partial list of well-maintained formats is given on the [Serde
//! website][data formats].
@@ -99,7 +99,7 @@
//! [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
//! [`Serialize`]: ../trait.Serialize.html
//! [`Serializer`]: ../trait.Serializer.html
//! [`bincode`]: https://github.com/servo/bincode
//! [`postcard`]: https://github.com/jamesmunns/postcard
//! [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
//! [`serde_derive`]: https://crates.io/crates/serde_derive
//! [`serde_json`]: https://github.com/serde-rs/json
@@ -115,10 +115,13 @@ mod impossible;
pub use self::impossible::Impossible;
#[cfg(all(feature = "unstable", not(feature = "std")))]
#[doc(inline)]
pub use core::error::Error as StdError;
#[cfg(feature = "std")]
#[doc(no_inline)]
pub use std::error::Error as StdError;
#[cfg(not(feature = "std"))]
#[cfg(not(any(feature = "std", feature = "unstable")))]
#[doc(no_inline)]
pub use std_error::Error as StdError;
@@ -146,7 +149,7 @@ macro_rules! declare_error_trait {
/// For example, a filesystem [`Path`] may refuse to serialize
/// itself if it contains invalid UTF-8 data.
///
/// ```edition2018
/// ```edition2021
/// # struct Path;
/// #
/// # impl Path {
@@ -191,8 +194,8 @@ declare_error_trait!(Error: Sized + Debug + Display);
/// by Serde.
///
/// Serde provides `Serialize` implementations for many Rust primitive and
/// standard library types. The complete list is [here][ser]. All of these can
/// be serialized using Serde out of the box.
/// standard library types. The complete list is [here][crate::ser]. All of
/// these can be serialized using Serde out of the box.
///
/// Additionally, Serde provides a procedural macro called [`serde_derive`] to
/// automatically generate `Serialize` implementations for structs and enums in
@@ -212,14 +215,13 @@ declare_error_trait!(Error: Sized + Debug + Display);
/// [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
/// [`serde_derive`]: https://crates.io/crates/serde_derive
/// [derive section of the manual]: https://serde.rs/derive.html
/// [ser]: https://docs.serde.rs/serde/ser/index.html
pub trait Serialize {
/// Serialize this value into the given Serde serializer.
///
/// See the [Implementing `Serialize`] section of the manual for more
/// information about how to implement this method.
///
/// ```edition2018
/// ```edition2021
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Person {
@@ -314,7 +316,7 @@ pub trait Serialize {
/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
///
/// Many Serde serializers produce text or binary data as output, for example
/// JSON or Bincode. This is not a requirement of the `Serializer` trait, and
/// JSON or Postcard. This is not a requirement of the `Serializer` trait, and
/// there are serializers that do not produce text or binary output. One example
/// is the `serde_json::value::Serializer` (distinct from the main `serde_json`
/// serializer) that produces a `serde_json::Value` data structure in memory as
@@ -386,7 +388,7 @@ pub trait Serializer: Sized {
/// Serialize a `bool` value.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -408,7 +410,7 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -430,7 +432,7 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -452,7 +454,7 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -470,7 +472,7 @@ pub trait Serializer: Sized {
/// Serialize an `i64` value.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -489,7 +491,7 @@ pub trait Serializer: Sized {
serde_if_integer128! {
/// Serialize an `i128` value.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -518,7 +520,7 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -540,7 +542,7 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -562,7 +564,7 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -580,7 +582,7 @@ pub trait Serializer: Sized {
/// Serialize a `u64` value.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -599,7 +601,7 @@ pub trait Serializer: Sized {
serde_if_integer128! {
/// Serialize a `u128` value.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -628,7 +630,7 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `f64` and
/// forward to `serialize_f64`.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -646,7 +648,7 @@ pub trait Serializer: Sized {
/// Serialize an `f64` value.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -667,7 +669,7 @@ pub trait Serializer: Sized {
/// If the format does not support characters, it is reasonable to serialize
/// it as a single element `str` or a `u32`.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -685,7 +687,7 @@ pub trait Serializer: Sized {
/// Serialize a `&str`.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -709,9 +711,9 @@ pub trait Serializer: Sized {
/// `serialize_seq`. If forwarded, the implementation looks usually just
/// like this:
///
/// ```edition2018
/// ```edition2021
/// # use serde::ser::{Serializer, SerializeSeq};
/// # use serde::__private::ser::Error;
/// # use serde::__private::doc::Error;
/// #
/// # struct MySerializer;
/// #
@@ -738,7 +740,7 @@ pub trait Serializer: Sized {
/// Serialize a [`None`] value.
///
/// ```edition2018
/// ```edition2021
/// # use serde::{Serialize, Serializer};
/// #
/// # enum Option<T> {
@@ -771,7 +773,7 @@ pub trait Serializer: Sized {
/// Serialize a [`Some(T)`] value.
///
/// ```edition2018
/// ```edition2021
/// # use serde::{Serialize, Serializer};
/// #
/// # enum Option<T> {
@@ -806,7 +808,7 @@ pub trait Serializer: Sized {
/// Serialize a `()` value.
///
/// ```edition2018
/// ```edition2021
/// # use serde::Serializer;
/// #
/// # serde::__private_serialize!();
@@ -826,7 +828,7 @@ pub trait Serializer: Sized {
///
/// A reasonable implementation would be to forward to `serialize_unit`.
///
/// ```edition2018
/// ```edition2021
/// use serde::{Serialize, Serializer};
///
/// struct Nothing;
@@ -848,7 +850,7 @@ pub trait Serializer: Sized {
/// this variant within the enum, and the `variant` is the name of the
/// variant.
///
/// ```edition2018
/// ```edition2021
/// use serde::{Serialize, Serializer};
///
/// enum E {
@@ -881,7 +883,7 @@ pub trait Serializer: Sized {
/// wrappers around the data they contain. A reasonable implementation would
/// be to forward to `value.serialize(self)`.
///
/// ```edition2018
/// ```edition2021
/// use serde::{Serialize, Serializer};
///
/// struct Millimeters(u8);
@@ -909,7 +911,7 @@ pub trait Serializer: Sized {
/// this variant within the enum, and the `variant` is the name of the
/// variant. The `value` is the data contained within this newtype variant.
///
/// ```edition2018
/// ```edition2021
/// use serde::{Serialize, Serializer};
///
/// enum E {
@@ -947,7 +949,7 @@ pub trait Serializer: Sized {
/// not be computable before the sequence is iterated. Some serializers only
/// support sequences whose length is known up front.
///
/// ```edition2018
/// ```edition2021
/// # use std::marker::PhantomData;
/// #
/// # struct Vec<T>(PhantomData<T>);
@@ -960,14 +962,14 @@ pub trait Serializer: Sized {
/// #
/// # impl<'a, T> IntoIterator for &'a Vec<T> {
/// # type Item = &'a T;
/// # type IntoIter = Box<Iterator<Item = &'a T>>;
/// # type IntoIter = Box<dyn Iterator<Item = &'a T>>;
/// #
/// # fn into_iter(self) -> Self::IntoIter {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::ser::{Serialize, Serializer, SerializeSeq};
/// use serde::ser::{Serialize, SerializeSeq, Serializer};
///
/// impl<T> Serialize for Vec<T>
/// where
@@ -992,8 +994,8 @@ pub trait Serializer: Sized {
/// This call must be followed by zero or more calls to `serialize_element`,
/// then a call to `end`.
///
/// ```edition2018
/// use serde::ser::{Serialize, Serializer, SerializeTuple};
/// ```edition2021
/// use serde::ser::{Serialize, SerializeTuple, Serializer};
///
/// # mod fool {
/// # trait Serialize {}
@@ -1022,7 +1024,7 @@ pub trait Serializer: Sized {
/// }
/// ```
///
/// ```edition2018
/// ```edition2021
/// use serde::ser::{Serialize, SerializeTuple, Serializer};
///
/// const VRAM_SIZE: usize = 386;
@@ -1050,7 +1052,7 @@ pub trait Serializer: Sized {
/// The `name` is the name of the tuple struct and the `len` is the number
/// of data fields that will be serialized.
///
/// ```edition2018
/// ```edition2021
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
///
/// struct Rgb(u8, u8, u8);
@@ -1082,7 +1084,7 @@ pub trait Serializer: Sized {
/// this variant within the enum, the `variant` is the name of the variant,
/// and the `len` is the number of data fields that will be serialized.
///
/// ```edition2018
/// ```edition2021
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
///
/// enum E {
@@ -1128,7 +1130,7 @@ pub trait Serializer: Sized {
/// be computable before the map is iterated. Some serializers only support
/// maps whose length is known up front.
///
/// ```edition2018
/// ```edition2021
/// # use std::marker::PhantomData;
/// #
/// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>);
@@ -1141,14 +1143,14 @@ pub trait Serializer: Sized {
/// #
/// # impl<'a, K, V> IntoIterator for &'a HashMap<K, V> {
/// # type Item = (&'a K, &'a V);
/// # type IntoIter = Box<Iterator<Item = (&'a K, &'a V)>>;
/// # type IntoIter = Box<dyn Iterator<Item = (&'a K, &'a V)>>;
/// #
/// # fn into_iter(self) -> Self::IntoIter {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::ser::{Serialize, Serializer, SerializeMap};
/// use serde::ser::{Serialize, SerializeMap, Serializer};
///
/// impl<K, V> Serialize for HashMap<K, V>
/// where
@@ -1176,7 +1178,7 @@ pub trait Serializer: Sized {
/// The `name` is the name of the struct and the `len` is the number of
/// data fields that will be serialized.
///
/// ```edition2018
/// ```edition2021
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Rgb {
@@ -1212,7 +1214,7 @@ pub trait Serializer: Sized {
/// this variant within the enum, the `variant` is the name of the variant,
/// and the `len` is the number of data fields that will be serialized.
///
/// ```edition2018
/// ```edition2021
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
///
/// enum E {
@@ -1254,7 +1256,7 @@ pub trait Serializer: Sized {
/// using [`serialize_seq`]. Implementors should not need to override this
/// method.
///
/// ```edition2018
/// ```edition2021
/// use serde::{Serialize, Serializer};
///
/// struct SecretlyOneHigher {
@@ -1279,9 +1281,20 @@ pub trait Serializer: Sized {
{
let iter = iter.into_iter();
let mut serializer = try!(self.serialize_seq(iterator_len_hint(&iter)));
for item in iter {
try!(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()
}
@@ -1291,7 +1304,7 @@ pub trait Serializer: Sized {
/// using [`serialize_map`]. Implementors should not need to override this
/// method.
///
/// ```edition2018
/// ```edition2021
/// use serde::{Serialize, Serializer};
/// use std::collections::BTreeSet;
///
@@ -1319,9 +1332,20 @@ pub trait Serializer: Sized {
{
let iter = iter.into_iter();
let mut serializer = try!(self.serialize_map(iterator_len_hint(&iter)));
for (key, value) in iter {
try!(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()
}
@@ -1331,7 +1355,7 @@ pub trait Serializer: Sized {
/// delegates to [`serialize_str`]. Serializers are encouraged to provide a
/// more efficient implementation if possible.
///
/// ```edition2018
/// ```edition2021
/// # struct DateTime;
/// #
/// # impl DateTime {
@@ -1346,9 +1370,7 @@ pub trait Serializer: Sized {
/// where
/// S: Serializer,
/// {
/// serializer.collect_str(&format_args!("{:?}{:?}",
/// self.naive_local(),
/// self.offset()))
/// serializer.collect_str(&format_args!("{:?}{:?}", self.naive_local(), self.offset()))
/// }
/// }
/// ```
@@ -1369,7 +1391,7 @@ pub trait Serializer: Sized {
/// of this method. If no more sensible behavior is possible, the
/// implementation is expected to return an error.
///
/// ```edition2018
/// ```edition2021
/// # struct DateTime;
/// #
/// # impl DateTime {
@@ -1384,9 +1406,7 @@ pub trait Serializer: Sized {
/// where
/// S: Serializer,
/// {
/// serializer.collect_str(&format_args!("{:?}{:?}",
/// self.naive_local(),
/// self.offset()))
/// serializer.collect_str(&format_args!("{:?}{:?}", self.naive_local(), self.offset()))
/// }
/// }
/// ```
@@ -1401,10 +1421,10 @@ pub trait Serializer: Sized {
/// Some types have a human-readable form that may be somewhat expensive to
/// construct, as well as a binary form that is compact and efficient.
/// Generally text-based formats like JSON and YAML will prefer to use the
/// human-readable one and binary formats like Bincode will prefer the
/// human-readable one and binary formats like Postcard will prefer the
/// compact one.
///
/// ```edition2018
/// ```edition2021
/// # use std::fmt::{self, Display};
/// #
/// # struct Timestamp;
@@ -1453,7 +1473,7 @@ pub trait Serializer: Sized {
///
/// # Example use
///
/// ```edition2018
/// ```edition2021
/// # use std::marker::PhantomData;
/// #
/// # struct Vec<T>(PhantomData<T>);
@@ -1466,13 +1486,13 @@ pub trait Serializer: Sized {
/// #
/// # impl<'a, T> IntoIterator for &'a Vec<T> {
/// # type Item = &'a T;
/// # type IntoIter = Box<Iterator<Item = &'a T>>;
/// # type IntoIter = Box<dyn Iterator<Item = &'a T>>;
/// # fn into_iter(self) -> Self::IntoIter {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::ser::{Serialize, Serializer, SerializeSeq};
/// use serde::ser::{Serialize, SerializeSeq, Serializer};
///
/// impl<T> Serialize for Vec<T>
/// where
@@ -1517,8 +1537,8 @@ pub trait SerializeSeq {
///
/// # Example use
///
/// ```edition2018
/// use serde::ser::{Serialize, Serializer, SerializeTuple};
/// ```edition2021
/// use serde::ser::{Serialize, SerializeTuple, Serializer};
///
/// # mod fool {
/// # trait Serialize {}
@@ -1547,7 +1567,7 @@ pub trait SerializeSeq {
/// }
/// ```
///
/// ```edition2018
/// ```edition2021
/// # use std::marker::PhantomData;
/// #
/// # struct Array<T>(PhantomData<T>);
@@ -1560,13 +1580,13 @@ pub trait SerializeSeq {
/// #
/// # impl<'a, T> IntoIterator for &'a Array<T> {
/// # type Item = &'a T;
/// # type IntoIter = Box<Iterator<Item = &'a T>>;
/// # type IntoIter = Box<dyn Iterator<Item = &'a T>>;
/// # fn into_iter(self) -> Self::IntoIter {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::ser::{Serialize, Serializer, SerializeTuple};
/// use serde::ser::{Serialize, SerializeTuple, Serializer};
///
/// # mod fool {
/// # trait Serialize {}
@@ -1617,7 +1637,7 @@ pub trait SerializeTuple {
///
/// # Example use
///
/// ```edition2018
/// ```edition2021
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
///
/// struct Rgb(u8, u8, u8);
@@ -1662,7 +1682,7 @@ pub trait SerializeTupleStruct {
///
/// # Example use
///
/// ```edition2018
/// ```edition2021
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
///
/// enum E {
@@ -1720,7 +1740,7 @@ pub trait SerializeTupleVariant {
///
/// # Example use
///
/// ```edition2018
/// ```edition2021
/// # use std::marker::PhantomData;
/// #
/// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>);
@@ -1733,14 +1753,14 @@ pub trait SerializeTupleVariant {
/// #
/// # impl<'a, K, V> IntoIterator for &'a HashMap<K, V> {
/// # type Item = (&'a K, &'a V);
/// # type IntoIter = Box<Iterator<Item = (&'a K, &'a V)>>;
/// # type IntoIter = Box<dyn Iterator<Item = (&'a K, &'a V)>>;
/// #
/// # fn into_iter(self) -> Self::IntoIter {
/// # unimplemented!()
/// # }
/// # }
/// #
/// use serde::ser::{Serialize, Serializer, SerializeMap};
/// use serde::ser::{Serialize, SerializeMap, Serializer};
///
/// impl<K, V> Serialize for HashMap<K, V>
/// where
@@ -1831,7 +1851,7 @@ pub trait SerializeMap {
///
/// # Example use
///
/// ```edition2018
/// ```edition2021
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Rgb {
@@ -1891,7 +1911,7 @@ pub trait SerializeStruct {
///
/// # Example use
///
/// ```edition2018
/// ```edition2021
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
///
/// enum E {
+3 -3
View File
@@ -9,7 +9,7 @@ use lib::{Debug, Display};
/// generally provide their error types with a `std::error::Error` impl
/// directly:
///
/// ```edition2018
/// ```edition2021
/// #[derive(Debug)]
/// struct MySerError {...}
///
@@ -29,7 +29,7 @@ use lib::{Debug, Display};
/// std = ["serde/std"]
/// ```
///
/// ```edition2018
/// ```edition2021
/// #[cfg(feature = "std")]
/// impl std::error::Error for MySerError {}
/// ```
@@ -37,7 +37,7 @@ use lib::{Debug, Display};
/// ... or else provide the std Error impl unconditionally via Serde's
/// re-export:
///
/// ```edition2018
/// ```edition2021
/// impl serde::ser::StdError for MySerError {}
/// ```
pub trait Error: Debug + Display {
+9 -8
View File
@@ -1,15 +1,16 @@
[package]
name = "serde_derive"
version = "1.0.121" # remember to update html_root_url
version = "1.0.172" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT OR Apache-2.0"
categories = ["no-std", "no-std::no-alloc"]
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://serde.rs/derive.html"
keywords = ["serde", "serialization", "no_std"]
homepage = "https://serde.rs"
keywords = ["serde", "serialization", "no_std", "derive"]
license = "MIT OR Apache-2.0"
readme = "crates-io.md"
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
repository = "https://github.com/serde-rs/serde"
rust-version = "1.56"
[features]
default = []
@@ -22,10 +23,10 @@ proc-macro = true
[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "1.0.58", features = ["visit"] }
syn = "2.0.25"
[dev-dependencies]
serde = { version = "1.0", path = "../serde" }
serde = { version = "1", path = "../serde" }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
-30
View File
@@ -1,30 +0,0 @@
use std::env;
use std::process::Command;
use std::str;
// The rustc-cfg strings below are *not* public API. Please let us know by
// opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script.
fn main() {
let minor = match rustc_minor_version() {
Some(minor) => minor,
None => return,
};
// Underscore const names stabilized in Rust 1.37:
// https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#using-unnamed-const-items-for-macros
if minor >= 37 {
println!("cargo:rustc-cfg=underscore_consts");
}
}
fn rustc_minor_version() -> Option<u32> {
let rustc = env::var_os("RUSTC")?;
let output = Command::new(rustc).arg("--version").output().ok()?;
let version = str::from_utf8(&output.stdout).ok()?;
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
}
pieces.next()?.parse().ok()
}
+106 -9
View File
@@ -2,7 +2,6 @@ use std::collections::HashSet;
use syn;
use syn::punctuated::{Pair, Punctuated};
use syn::visit::{self, Visit};
use internals::ast::{Container, Data};
use internals::{attr, ungroup};
@@ -50,8 +49,8 @@ pub fn with_where_predicates_from_fields(
let predicates = cont
.data
.all_fields()
.flat_map(|field| from_field(&field.attrs))
.flat_map(|predicates| predicates.to_vec());
.filter_map(|field| from_field(&field.attrs))
.flat_map(<[syn::WherePredicate]>::to_vec);
let mut generics = generics.clone();
generics.make_where_clause().predicates.extend(predicates);
@@ -72,8 +71,8 @@ pub fn with_where_predicates_from_variants(
let predicates = variants
.iter()
.flat_map(|variant| from_variant(&variant.attrs))
.flat_map(|predicates| predicates.to_vec());
.filter_map(|variant| from_variant(&variant.attrs))
.flat_map(<[syn::WherePredicate]>::to_vec);
let mut generics = generics.clone();
generics.make_where_clause().predicates.extend(predicates);
@@ -112,7 +111,8 @@ pub fn with_bound(
// parameters.
associated_type_usage: Vec<&'ast syn::TypePath>,
}
impl<'ast> Visit<'ast> for FindTyParams<'ast> {
impl<'ast> FindTyParams<'ast> {
fn visit_field(&mut self, field: &'ast syn::Field) {
if let syn::Type::Path(ty) = ungroup(&field.ty) {
if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() {
@@ -138,7 +138,104 @@ pub fn with_bound(
self.relevant_type_params.insert(id.clone());
}
}
visit::visit_path(self, path);
for segment in &path.segments {
self.visit_path_segment(segment);
}
}
// Everything below is simply traversing the syntax tree.
fn visit_type(&mut self, ty: &'ast syn::Type) {
match ty {
syn::Type::Array(ty) => self.visit_type(&ty.elem),
syn::Type::BareFn(ty) => {
for arg in &ty.inputs {
self.visit_type(&arg.ty);
}
self.visit_return_type(&ty.output);
}
syn::Type::Group(ty) => self.visit_type(&ty.elem),
syn::Type::ImplTrait(ty) => {
for bound in &ty.bounds {
self.visit_type_param_bound(bound);
}
}
syn::Type::Macro(ty) => self.visit_macro(&ty.mac),
syn::Type::Paren(ty) => self.visit_type(&ty.elem),
syn::Type::Path(ty) => {
if let Some(qself) = &ty.qself {
self.visit_type(&qself.ty);
}
self.visit_path(&ty.path);
}
syn::Type::Ptr(ty) => self.visit_type(&ty.elem),
syn::Type::Reference(ty) => self.visit_type(&ty.elem),
syn::Type::Slice(ty) => self.visit_type(&ty.elem),
syn::Type::TraitObject(ty) => {
for bound in &ty.bounds {
self.visit_type_param_bound(bound);
}
}
syn::Type::Tuple(ty) => {
for elem in &ty.elems {
self.visit_type(elem);
}
}
syn::Type::Infer(_) | syn::Type::Never(_) | syn::Type::Verbatim(_) => {}
#[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
_ => {}
}
}
fn visit_path_segment(&mut self, segment: &'ast syn::PathSegment) {
self.visit_path_arguments(&segment.arguments);
}
fn visit_path_arguments(&mut self, arguments: &'ast syn::PathArguments) {
match arguments {
syn::PathArguments::None => {}
syn::PathArguments::AngleBracketed(arguments) => {
for arg in &arguments.args {
match arg {
syn::GenericArgument::Type(arg) => self.visit_type(arg),
syn::GenericArgument::AssocType(arg) => self.visit_type(&arg.ty),
syn::GenericArgument::Lifetime(_)
| syn::GenericArgument::Const(_)
| syn::GenericArgument::AssocConst(_)
| syn::GenericArgument::Constraint(_) => {}
#[cfg_attr(
all(test, exhaustive),
deny(non_exhaustive_omitted_patterns)
)]
_ => {}
}
}
}
syn::PathArguments::Parenthesized(arguments) => {
for argument in &arguments.inputs {
self.visit_type(argument);
}
self.visit_return_type(&arguments.output);
}
}
}
fn visit_return_type(&mut self, return_type: &'ast syn::ReturnType) {
match return_type {
syn::ReturnType::Default => {}
syn::ReturnType::Type(_, output) => self.visit_type(output),
}
}
fn visit_type_param_bound(&mut self, bound: &'ast syn::TypeParamBound) {
match bound {
syn::TypeParamBound::Trait(bound) => self.visit_path(&bound.path),
syn::TypeParamBound::Lifetime(_) | syn::TypeParamBound::Verbatim(_) => {}
#[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
_ => {}
}
}
// Type parameter should not be considered used by a macro path.
@@ -162,7 +259,7 @@ pub fn with_bound(
};
match &cont.data {
Data::Enum(variants) => {
for variant in variants.iter() {
for variant in variants {
let relevant_fields = variant
.fields
.iter()
@@ -245,7 +342,7 @@ pub fn with_self_bound(
pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Generics {
let bound = syn::Lifetime::new(lifetime, Span::call_site());
let def = syn::LifetimeDef {
let def = syn::LifetimeParam {
attrs: Vec::new(),
lifetime: bound.clone(),
colon_token: None,
+541 -412
View File
File diff suppressed because it is too large Load Diff
+4 -24
View File
@@ -1,29 +1,17 @@
use proc_macro2::{Ident, TokenStream};
use quote::format_ident;
use proc_macro2::TokenStream;
use syn;
use try;
pub fn wrap_in_const(
serde_path: Option<&syn::Path>,
trait_: &str,
ty: &Ident,
code: TokenStream,
) -> TokenStream {
pub fn wrap_in_const(serde_path: Option<&syn::Path>, code: TokenStream) -> TokenStream {
let try_replacement = try::replacement();
let dummy_const = if cfg!(underscore_consts) {
format_ident!("_")
} else {
format_ident!("_IMPL_{}_FOR_{}", trait_, unraw(ty))
};
let use_serde = match serde_path {
Some(path) => quote! {
use #path as _serde;
},
None => quote! {
#[allow(rust_2018_idioms, clippy::useless_attribute)]
#[allow(unused_extern_crates, clippy::useless_attribute)]
extern crate serde as _serde;
},
};
@@ -31,18 +19,10 @@ pub fn wrap_in_const(
quote! {
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
const _: () = {
#use_serde
#try_replacement
#code
};
}
}
#[allow(deprecated)]
fn unraw(ident: &Ident) -> String {
// str::trim_start_matches was added in 1.30, trim_left_matches deprecated
// in 1.33. We currently support rustc back to 1.15 so we need to continue
// to use the deprecated one.
ident.to_string().trim_left_matches("r#").to_owned()
}
+16 -3
View File
@@ -23,7 +23,7 @@ pub struct Container<'a> {
/// The fields of a struct or enum.
///
/// Analagous to `syn::Data`.
/// Analogous to `syn::Data`.
pub enum Data<'a> {
Enum(Vec<Variant<'a>>),
Struct(Style, Vec<Field<'a>>),
@@ -140,7 +140,7 @@ fn enum_from_ast<'a>(
variants: &'a Punctuated<syn::Variant, Token![,]>,
container_default: &attr::Default,
) -> Vec<Variant<'a>> {
variants
let variants: Vec<Variant> = variants
.iter()
.map(|variant| {
let attrs = attr::Variant::from_ast(cx, variant);
@@ -154,7 +154,20 @@ fn enum_from_ast<'a>(
original: variant,
}
})
.collect()
.collect();
let index_of_last_tagged_variant = variants
.iter()
.rposition(|variant| !variant.attrs.untagged());
if let Some(index_of_last_tagged_variant) = index_of_last_tagged_variant {
for variant in &variants[..index_of_last_tagged_variant] {
if variant.attrs.untagged() {
cx.error_spanned_by(&variant.ident, "all variants with the #[serde(untagged)] attribute must be placed at the end of the enum");
}
}
}
variants
}
fn struct_from_ast<'a>(
File diff suppressed because it is too large Load Diff
+42 -19
View File
@@ -5,7 +5,7 @@
#[allow(deprecated, unused_imports)]
use std::ascii::AsciiExt;
use std::str::FromStr;
use std::fmt::{self, Debug, Display};
use self::RenameRule::*;
@@ -17,7 +17,7 @@ pub enum RenameRule {
/// Rename direct children to "lowercase" style.
LowerCase,
/// Rename direct children to "UPPERCASE" style.
UPPERCASE,
UpperCase,
/// Rename direct children to "PascalCase" style, as typically used for
/// enum variants.
PascalCase,
@@ -35,13 +35,35 @@ pub enum RenameRule {
ScreamingKebabCase,
}
static RENAME_RULES: &[(&str, RenameRule)] = &[
("lowercase", LowerCase),
("UPPERCASE", UpperCase),
("PascalCase", PascalCase),
("camelCase", CamelCase),
("snake_case", SnakeCase),
("SCREAMING_SNAKE_CASE", ScreamingSnakeCase),
("kebab-case", KebabCase),
("SCREAMING-KEBAB-CASE", ScreamingKebabCase),
];
impl RenameRule {
pub fn from_str(rename_all_str: &str) -> Result<Self, ParseError> {
for (name, rule) in RENAME_RULES {
if rename_all_str == *name {
return Ok(*rule);
}
}
Err(ParseError {
unknown: rename_all_str,
})
}
/// Apply a renaming rule to an enum variant, returning the version expected in the source.
pub fn apply_to_variant(&self, variant: &str) -> String {
match *self {
None | PascalCase => variant.to_owned(),
LowerCase => variant.to_ascii_lowercase(),
UPPERCASE => variant.to_ascii_uppercase(),
UpperCase => variant.to_ascii_uppercase(),
CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..],
SnakeCase => {
let mut snake = String::new();
@@ -65,7 +87,7 @@ impl RenameRule {
pub fn apply_to_field(&self, field: &str) -> String {
match *self {
None | LowerCase | SnakeCase => field.to_owned(),
UPPERCASE => field.to_ascii_uppercase(),
UpperCase => field.to_ascii_uppercase(),
PascalCase => {
let mut pascal = String::new();
let mut capitalize = true;
@@ -92,21 +114,22 @@ impl RenameRule {
}
}
impl FromStr for RenameRule {
type Err = ();
pub struct ParseError<'a> {
unknown: &'a str,
}
fn from_str(rename_all_str: &str) -> Result<Self, Self::Err> {
match rename_all_str {
"lowercase" => Ok(LowerCase),
"UPPERCASE" => Ok(UPPERCASE),
"PascalCase" => Ok(PascalCase),
"camelCase" => Ok(CamelCase),
"snake_case" => Ok(SnakeCase),
"SCREAMING_SNAKE_CASE" => Ok(ScreamingSnakeCase),
"kebab-case" => Ok(KebabCase),
"SCREAMING-KEBAB-CASE" => Ok(ScreamingKebabCase),
_ => Err(()),
impl<'a> Display for ParseError<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.write_str("unknown rename rule `rename_all = ")?;
Debug::fmt(self.unknown, f)?;
f.write_str("`, expected one of ")?;
for (i, (name, _rule)) in RENAME_RULES.iter().enumerate() {
if i > 0 {
f.write_str(", ")?;
}
Debug::fmt(name, f)?;
}
Ok(())
}
}
@@ -131,7 +154,7 @@ fn rename_variants() {
] {
assert_eq!(None.apply_to_variant(original), original);
assert_eq!(LowerCase.apply_to_variant(original), lower);
assert_eq!(UPPERCASE.apply_to_variant(original), upper);
assert_eq!(UpperCase.apply_to_variant(original), upper);
assert_eq!(PascalCase.apply_to_variant(original), original);
assert_eq!(CamelCase.apply_to_variant(original), camel);
assert_eq!(SnakeCase.apply_to_variant(original), snake);
@@ -163,7 +186,7 @@ fn rename_fields() {
("z42", "Z42", "Z42", "z42", "Z42", "z42", "Z42"),
] {
assert_eq!(None.apply_to_field(original), original);
assert_eq!(UPPERCASE.apply_to_field(original), upper);
assert_eq!(UpperCase.apply_to_field(original), upper);
assert_eq!(PascalCase.apply_to_field(original), pascal);
assert_eq!(CamelCase.apply_to_field(original), camel);
assert_eq!(SnakeCase.apply_to_field(original), original);
+47 -29
View File
@@ -3,9 +3,10 @@ use internals::attr::{Identifier, TagType};
use internals::{ungroup, Ctxt, Derive};
use syn::{Member, Type};
/// Cross-cutting checks that require looking at more than a single attrs
/// object. Simpler checks should happen when parsing and building the attrs.
// Cross-cutting checks that require looking at more than a single attrs object.
// Simpler checks should happen when parsing and building the attrs.
pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
check_remote_generic(cx, cont);
check_getter(cx, cont);
check_flatten(cx, cont);
check_identifier(cx, cont);
@@ -16,8 +17,30 @@ pub fn check(cx: &Ctxt, cont: &mut Container, derive: Derive) {
check_from_and_try_from(cx, cont);
}
/// Getters are only allowed inside structs (not enums) with the `remote`
/// attribute.
// Remote derive definition type must have either all of the generics of the
// remote type:
//
// #[serde(remote = "Generic")]
// struct Generic<T> {…}
//
// or none of them, i.e. defining impls for one concrete instantiation of the
// remote type only:
//
// #[serde(remote = "Generic<T>")]
// struct ConcreteDef {…}
//
fn check_remote_generic(cx: &Ctxt, cont: &Container) {
if let Some(remote) = cont.attrs.remote() {
let local_has_generic = !cont.generics.params.is_empty();
let remote_has_generic = !remote.segments.last().unwrap().arguments.is_none();
if local_has_generic && remote_has_generic {
cx.error_spanned_by(remote, "remove generic parameters from this path");
}
}
}
// Getters are only allowed inside structs (not enums) with the `remote`
// attribute.
fn check_getter(cx: &Ctxt, cont: &Container) {
match cont.data {
Data::Enum(_) => {
@@ -39,7 +62,7 @@ fn check_getter(cx: &Ctxt, cont: &Container) {
}
}
/// Flattening has some restrictions we can test.
// Flattening has some restrictions we can test.
fn check_flatten(cx: &Ctxt, cont: &Container) {
match &cont.data {
Data::Enum(variants) => {
@@ -78,18 +101,16 @@ fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
}
}
/// The `other` attribute must be used at most once and it must be the last
/// variant of an enum.
///
/// Inside a `variant_identifier` all variants must be unit variants. Inside a
/// `field_identifier` all but possibly one variant must be unit variants. The
/// last variant may be a newtype variant which is an implicit "other" case.
// The `other` attribute must be used at most once and it must be the last
// variant of an enum.
//
// Inside a `variant_identifier` all variants must be unit variants. Inside a
// `field_identifier` all but possibly one variant must be unit variants. The
// last variant may be a newtype variant which is an implicit "other" case.
fn check_identifier(cx: &Ctxt, cont: &Container) {
let variants = match &cont.data {
Data::Enum(variants) => variants,
Data::Struct(_, _) => {
return;
}
Data::Struct(_, _) => return,
};
for (i, variant) in variants.iter().enumerate() {
@@ -166,17 +187,15 @@ fn check_identifier(cx: &Ctxt, cont: &Container) {
}
}
/// Skip-(de)serializing attributes are not allowed on variants marked
/// (de)serialize_with.
// Skip-(de)serializing attributes are not allowed on variants marked
// (de)serialize_with.
fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
let variants = match &cont.data {
Data::Enum(variants) => variants,
Data::Struct(_, _) => {
return;
}
Data::Struct(_, _) => return,
};
for variant in variants.iter() {
for variant in variants {
if variant.attrs.serialize_with().is_some() {
if variant.attrs.skip_serializing() {
cx.error_spanned_by(
@@ -241,10 +260,9 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
}
}
/// The tag of an internally-tagged struct variant must not be
/// the same as either one of its fields, as this would result in
/// duplicate keys in the serialized output and/or ambiguity in
/// the to-be-deserialized input.
// The tag of an internally-tagged struct variant must not be the same as either
// one of its fields, as this would result in duplicate keys in the serialized
// output and/or ambiguity in the to-be-deserialized input.
fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
let variants = match &cont.data {
Data::Enum(variants) => variants,
@@ -260,7 +278,7 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
cx.error_spanned_by(
cont.original,
format!("variant field name `{}` conflicts with internal tag", tag),
)
);
};
for variant in variants {
@@ -290,8 +308,8 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
}
}
/// In the case of adjacently-tagged enums, the type and the
/// contents tag must differ, for the same reason.
// In the case of adjacently-tagged enums, the type and the contents tag must
// differ, for the same reason.
fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
let (type_tag, content_tag) = match cont.attrs.tag() {
TagType::Adjacent { tag, content } => (tag, content),
@@ -309,7 +327,7 @@ fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
}
}
/// Enums and unit structs cannot be transparent.
// Enums and unit structs cannot be transparent.
fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
if !cont.attrs.transparent() {
return;
@@ -396,7 +414,7 @@ fn member_message(member: &Member) -> String {
}
fn allow_transparent(field: &Field, derive: Derive) -> bool {
if let Type::Path(ty) = ungroup(&field.ty) {
if let Type::Path(ty) = ungroup(field.ty) {
if let Some(seg) = ty.path.segments.last() {
if seg.ident == "PhantomData" {
return false;
+12 -5
View File
@@ -44,12 +44,19 @@ impl Ctxt {
}
/// Consume this object, producing a formatted error string if there are errors.
pub fn check(self) -> Result<(), Vec<syn::Error>> {
let errors = self.errors.borrow_mut().take().unwrap();
match errors.len() {
0 => Ok(()),
_ => Err(errors),
pub fn check(self) -> syn::Result<()> {
let mut errors = self.errors.borrow_mut().take().unwrap().into_iter();
let mut combined = match errors.next() {
Some(first) => first,
None => return Ok(()),
};
for rest in errors {
combined.combine(rest);
}
Err(combined)
}
}
+4
View File
@@ -4,8 +4,12 @@ pub mod attr;
mod ctxt;
pub use self::ctxt::Ctxt;
mod receiver;
pub use self::receiver::replace_receiver;
mod case;
mod check;
mod respan;
mod symbol;
use syn::Type;
+292
View File
@@ -0,0 +1,292 @@
use internals::respan::respan;
use proc_macro2::Span;
use quote::ToTokens;
use std::mem;
use syn::punctuated::Punctuated;
use syn::{
parse_quote, Data, DeriveInput, Expr, ExprPath, GenericArgument, GenericParam, Generics, Macro,
Path, PathArguments, QSelf, ReturnType, Type, TypeParamBound, TypePath, WherePredicate,
};
pub fn replace_receiver(input: &mut DeriveInput) {
let self_ty = {
let ident = &input.ident;
let ty_generics = input.generics.split_for_impl().1;
parse_quote!(#ident #ty_generics)
};
let mut visitor = ReplaceReceiver(&self_ty);
visitor.visit_generics_mut(&mut input.generics);
visitor.visit_data_mut(&mut input.data);
}
struct ReplaceReceiver<'a>(&'a TypePath);
impl ReplaceReceiver<'_> {
fn self_ty(&self, span: Span) -> TypePath {
let tokens = self.0.to_token_stream();
let respanned = respan(tokens, span);
syn::parse2(respanned).unwrap()
}
fn self_to_qself(&self, qself: &mut Option<QSelf>, path: &mut Path) {
if path.leading_colon.is_some() || path.segments[0].ident != "Self" {
return;
}
if path.segments.len() == 1 {
self.self_to_expr_path(path);
return;
}
let span = path.segments[0].ident.span();
*qself = Some(QSelf {
lt_token: Token![<](span),
ty: Box::new(Type::Path(self.self_ty(span))),
position: 0,
as_token: None,
gt_token: Token![>](span),
});
path.leading_colon = Some(**path.segments.pairs().next().unwrap().punct().unwrap());
let segments = mem::replace(&mut path.segments, Punctuated::new());
path.segments = segments.into_pairs().skip(1).collect();
}
fn self_to_expr_path(&self, path: &mut Path) {
let self_ty = self.self_ty(path.segments[0].ident.span());
let variant = mem::replace(path, self_ty.path);
for segment in &mut path.segments {
if let PathArguments::AngleBracketed(bracketed) = &mut segment.arguments {
if bracketed.colon2_token.is_none() && !bracketed.args.is_empty() {
bracketed.colon2_token = Some(<Token![::]>::default());
}
}
}
if variant.segments.len() > 1 {
path.segments.push_punct(<Token![::]>::default());
path.segments.extend(variant.segments.into_pairs().skip(1));
}
}
}
impl ReplaceReceiver<'_> {
// `Self` -> `Receiver`
fn visit_type_mut(&mut self, ty: &mut Type) {
let span = if let Type::Path(node) = ty {
if node.qself.is_none() && node.path.is_ident("Self") {
node.path.segments[0].ident.span()
} else {
self.visit_type_path_mut(node);
return;
}
} else {
self.visit_type_mut_impl(ty);
return;
};
*ty = self.self_ty(span).into();
}
// `Self::Assoc` -> `<Receiver>::Assoc`
fn visit_type_path_mut(&mut self, ty: &mut TypePath) {
if ty.qself.is_none() {
self.self_to_qself(&mut ty.qself, &mut ty.path);
}
self.visit_type_path_mut_impl(ty);
}
// `Self::method` -> `<Receiver>::method`
fn visit_expr_path_mut(&mut self, expr: &mut ExprPath) {
if expr.qself.is_none() {
self.self_to_qself(&mut expr.qself, &mut expr.path);
}
self.visit_expr_path_mut_impl(expr);
}
// Everything below is simply traversing the syntax tree.
fn visit_type_mut_impl(&mut self, ty: &mut Type) {
match ty {
Type::Array(ty) => {
self.visit_type_mut(&mut ty.elem);
self.visit_expr_mut(&mut ty.len);
}
Type::BareFn(ty) => {
for arg in &mut ty.inputs {
self.visit_type_mut(&mut arg.ty);
}
self.visit_return_type_mut(&mut ty.output);
}
Type::Group(ty) => self.visit_type_mut(&mut ty.elem),
Type::ImplTrait(ty) => {
for bound in &mut ty.bounds {
self.visit_type_param_bound_mut(bound);
}
}
Type::Macro(ty) => self.visit_macro_mut(&mut ty.mac),
Type::Paren(ty) => self.visit_type_mut(&mut ty.elem),
Type::Path(ty) => {
if let Some(qself) = &mut ty.qself {
self.visit_type_mut(&mut qself.ty);
}
self.visit_path_mut(&mut ty.path);
}
Type::Ptr(ty) => self.visit_type_mut(&mut ty.elem),
Type::Reference(ty) => self.visit_type_mut(&mut ty.elem),
Type::Slice(ty) => self.visit_type_mut(&mut ty.elem),
Type::TraitObject(ty) => {
for bound in &mut ty.bounds {
self.visit_type_param_bound_mut(bound);
}
}
Type::Tuple(ty) => {
for elem in &mut ty.elems {
self.visit_type_mut(elem);
}
}
Type::Infer(_) | Type::Never(_) | Type::Verbatim(_) => {}
#[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
_ => {}
}
}
fn visit_type_path_mut_impl(&mut self, ty: &mut TypePath) {
if let Some(qself) = &mut ty.qself {
self.visit_type_mut(&mut qself.ty);
}
self.visit_path_mut(&mut ty.path);
}
fn visit_expr_path_mut_impl(&mut self, expr: &mut ExprPath) {
if let Some(qself) = &mut expr.qself {
self.visit_type_mut(&mut qself.ty);
}
self.visit_path_mut(&mut expr.path);
}
fn visit_path_mut(&mut self, path: &mut Path) {
for segment in &mut path.segments {
self.visit_path_arguments_mut(&mut segment.arguments);
}
}
fn visit_path_arguments_mut(&mut self, arguments: &mut PathArguments) {
match arguments {
PathArguments::None => {}
PathArguments::AngleBracketed(arguments) => {
for arg in &mut arguments.args {
match arg {
GenericArgument::Type(arg) => self.visit_type_mut(arg),
GenericArgument::AssocType(arg) => self.visit_type_mut(&mut arg.ty),
GenericArgument::Lifetime(_)
| GenericArgument::Const(_)
| GenericArgument::AssocConst(_)
| GenericArgument::Constraint(_) => {}
#[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
_ => {}
}
}
}
PathArguments::Parenthesized(arguments) => {
for argument in &mut arguments.inputs {
self.visit_type_mut(argument);
}
self.visit_return_type_mut(&mut arguments.output);
}
}
}
fn visit_return_type_mut(&mut self, return_type: &mut ReturnType) {
match return_type {
ReturnType::Default => {}
ReturnType::Type(_, output) => self.visit_type_mut(output),
}
}
fn visit_type_param_bound_mut(&mut self, bound: &mut TypeParamBound) {
match bound {
TypeParamBound::Trait(bound) => self.visit_path_mut(&mut bound.path),
TypeParamBound::Lifetime(_) | TypeParamBound::Verbatim(_) => {}
#[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
_ => {}
}
}
fn visit_generics_mut(&mut self, generics: &mut Generics) {
for param in &mut generics.params {
match param {
GenericParam::Type(param) => {
for bound in &mut param.bounds {
self.visit_type_param_bound_mut(bound);
}
}
GenericParam::Lifetime(_) | GenericParam::Const(_) => {}
}
}
if let Some(where_clause) = &mut generics.where_clause {
for predicate in &mut where_clause.predicates {
match predicate {
WherePredicate::Type(predicate) => {
self.visit_type_mut(&mut predicate.bounded_ty);
for bound in &mut predicate.bounds {
self.visit_type_param_bound_mut(bound);
}
}
WherePredicate::Lifetime(_) => {}
#[cfg_attr(all(test, exhaustive), deny(non_exhaustive_omitted_patterns))]
_ => {}
}
}
}
}
fn visit_data_mut(&mut self, data: &mut Data) {
match data {
Data::Struct(data) => {
for field in &mut data.fields {
self.visit_type_mut(&mut field.ty);
}
}
Data::Enum(data) => {
for variant in &mut data.variants {
for field in &mut variant.fields {
self.visit_type_mut(&mut field.ty);
}
}
}
Data::Union(_) => {}
}
}
fn visit_expr_mut(&mut self, expr: &mut Expr) {
match expr {
Expr::Binary(expr) => {
self.visit_expr_mut(&mut expr.left);
self.visit_expr_mut(&mut expr.right);
}
Expr::Call(expr) => {
self.visit_expr_mut(&mut expr.func);
for arg in &mut expr.args {
self.visit_expr_mut(arg);
}
}
Expr::Cast(expr) => {
self.visit_expr_mut(&mut expr.expr);
self.visit_type_mut(&mut expr.ty);
}
Expr::Field(expr) => self.visit_expr_mut(&mut expr.base),
Expr::Index(expr) => {
self.visit_expr_mut(&mut expr.expr);
self.visit_expr_mut(&mut expr.index);
}
Expr::Paren(expr) => self.visit_expr_mut(&mut expr.expr),
Expr::Path(expr) => self.visit_expr_path_mut(expr),
Expr::Unary(expr) => self.visit_expr_mut(&mut expr.expr),
_ => {}
}
}
fn visit_macro_mut(&mut self, _mac: &mut Macro) {}
}
+16
View File
@@ -0,0 +1,16 @@
use proc_macro2::{Group, Span, TokenStream, TokenTree};
pub(crate) fn respan(stream: TokenStream, span: Span) -> TokenStream {
stream
.into_iter()
.map(|token| respan_token(token, span))
.collect()
}
fn respan_token(mut token: TokenTree, span: Span) -> TokenTree {
if let TokenTree::Group(g) = &mut token {
*g = Group::new(g.delimiter(), respan(g.stream(), span));
}
token.set_span(span);
token
}
+2
View File
@@ -13,6 +13,7 @@ pub const DEFAULT: Symbol = Symbol("default");
pub const DENY_UNKNOWN_FIELDS: Symbol = Symbol("deny_unknown_fields");
pub const DESERIALIZE: Symbol = Symbol("deserialize");
pub const DESERIALIZE_WITH: Symbol = Symbol("deserialize_with");
pub const EXPECTING: Symbol = Symbol("expecting");
pub const FIELD_IDENTIFIER: Symbol = Symbol("field_identifier");
pub const FLATTEN: Symbol = Symbol("flatten");
pub const FROM: Symbol = Symbol("from");
@@ -22,6 +23,7 @@ pub const OTHER: Symbol = Symbol("other");
pub const REMOTE: Symbol = Symbol("remote");
pub const RENAME: Symbol = Symbol("rename");
pub const RENAME_ALL: Symbol = Symbol("rename_all");
pub const REPR: Symbol = Symbol("repr");
pub const SERDE: Symbol = Symbol("serde");
pub const SERIALIZE: Symbol = Symbol("serialize");
pub const SERIALIZE_WITH: Symbol = Symbol("serialize_with");
+44 -18
View File
@@ -1,7 +1,7 @@
//! This crate provides Serde's two derive macros.
//!
//! ```edition2018
//! # use serde_derive::{Serialize, Deserialize};
//! ```edition2021
//! # use serde_derive::{Deserialize, Serialize};
//! #
//! #[derive(Serialize, Deserialize)]
//! # struct S;
@@ -13,13 +13,19 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.121")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.172")]
#![allow(unknown_lints, bare_trait_objects)]
#![deny(clippy::all, clippy::pedantic)]
// Ignored clippy lints
#![allow(
// clippy false positive: https://github.com/rust-lang/rust-clippy/issues/7054
clippy::branches_sharing_code,
clippy::cognitive_complexity,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7575
clippy::collapsible_match,
clippy::derive_partial_eq_without_eq,
clippy::enum_variant_names,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6797
clippy::manual_map,
clippy::match_like_matches_macro,
clippy::needless_pass_by_value,
clippy::too_many_arguments,
@@ -35,11 +41,14 @@
clippy::checked_conversions,
clippy::doc_markdown,
clippy::enum_glob_use,
clippy::filter_map,
clippy::indexing_slicing,
clippy::items_after_statements,
clippy::let_underscore_untyped,
clippy::manual_assert,
clippy::map_err_ignore,
clippy::match_same_arms,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
clippy::match_wildcard_for_single_variants,
clippy::module_name_repetitions,
clippy::must_use_candidate,
clippy::option_if_let_else,
@@ -48,21 +57,29 @@
clippy::struct_excessive_bools,
clippy::too_many_lines,
clippy::unseparated_literal_suffix,
clippy::unused_self,
clippy::use_self,
clippy::wildcard_imports
)]
#![cfg_attr(all(test, exhaustive), feature(non_exhaustive_omitted_patterns_lint))]
#[macro_use]
extern crate quote;
#[macro_use]
extern crate syn;
#[cfg(not(precompiled))]
extern crate proc_macro;
extern crate proc_macro2;
#[cfg(precompiled)]
extern crate proc_macro2 as proc_macro;
mod internals;
use proc_macro::TokenStream;
#[cfg(precompiled)]
use std::sync::atomic::AtomicBool;
use syn::DeriveInput;
#[macro_use]
@@ -74,25 +91,34 @@ mod de;
mod dummy;
mod pretend;
mod ser;
mod this;
mod try;
#[proc_macro_derive(Serialize, attributes(serde))]
#[cfg(precompiled)]
macro_rules! parse_macro_input {
($tokenstream:ident as $ty:ty) => {
match syn::parse2::<$ty>($tokenstream) {
Ok(data) => data,
Err(err) => return err.to_compile_error(),
}
};
}
#[cfg(precompiled)]
pub static DESERIALIZE_IN_PLACE: AtomicBool = AtomicBool::new(false);
#[cfg_attr(not(precompiled), proc_macro_derive(Serialize, attributes(serde)))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
ser::expand_derive_serialize(&input)
.unwrap_or_else(to_compile_errors)
let mut input = parse_macro_input!(input as DeriveInput);
ser::expand_derive_serialize(&mut input)
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}
#[proc_macro_derive(Deserialize, attributes(serde))]
#[cfg_attr(not(precompiled), proc_macro_derive(Deserialize, attributes(serde)))]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput);
de::expand_derive_deserialize(&input)
.unwrap_or_else(to_compile_errors)
let mut input = parse_macro_input!(input as DeriveInput);
de::expand_derive_deserialize(&mut input)
.unwrap_or_else(syn::Error::into_compile_error)
.into()
}
fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream {
let compile_errors = errors.iter().map(syn::Error::to_compile_error);
quote!(#(#compile_errors)*)
}
+88 -42
View File
@@ -1,7 +1,7 @@
use proc_macro2::{Span, TokenStream};
use syn::Ident;
use proc_macro2::TokenStream;
use quote::format_ident;
use internals::ast::{Container, Data, Field, Style};
use internals::ast::{Container, Data, Field, Style, Variant};
// Suppress dead_code warnings that would otherwise appear when using a remote
// derive. Other than this pretend code, a struct annotated with remote derive
@@ -20,8 +20,8 @@ use internals::ast::{Container, Data, Field, Style};
// 8 | enum EnumDef { V }
// | ^
//
pub fn pretend_used(cont: &Container) -> TokenStream {
let pretend_fields = pretend_fields_used(cont);
pub fn pretend_used(cont: &Container, is_packed: bool) -> TokenStream {
let pretend_fields = pretend_fields_used(cont, is_packed);
let pretend_variants = pretend_variants_used(cont);
quote! {
@@ -32,49 +32,102 @@ pub fn pretend_used(cont: &Container) -> TokenStream {
// For structs with named fields, expands to:
//
// match None::<&T> {
// Some(T { a: __v0, b: __v1 }) => {}
// _ => {}
// }
//
// For packed structs on sufficiently new rustc, expands to:
//
// match None::<&T> {
// Some(__v @ T { a: _, b: _ }) => {
// let _ = addr_of!(__v.a);
// let _ = addr_of!(__v.b);
// }
// _ => {}
// }
//
// For packed structs on older rustc, we assume Sized and !Drop, and expand to:
//
// match None::<T> {
// Some(T { a: ref __v0, b: ref __v1 }) => {}
// Some(T { a: __v0, b: __v1 }) => {}
// _ => {}
// }
//
// For enums, expands to the following but only including struct variants:
//
// match None::<T> {
// Some(T::A { a: ref __v0 }) => {}
// Some(T::B { b: ref __v0 }) => {}
// match None::<&T> {
// Some(T::A { a: __v0 }) => {}
// Some(T::B { b: __v0 }) => {}
// _ => {}
// }
//
// The `ref` is important in case the user has written a Drop impl on their
// type. Rust does not allow destructuring a struct or enum that has a Drop
// impl.
fn pretend_fields_used(cont: &Container) -> TokenStream {
fn pretend_fields_used(cont: &Container, is_packed: bool) -> TokenStream {
match &cont.data {
Data::Enum(variants) => pretend_fields_used_enum(cont, variants),
Data::Struct(Style::Struct, fields) => {
if is_packed {
pretend_fields_used_struct_packed(cont, fields)
} else {
pretend_fields_used_struct(cont, fields)
}
}
Data::Struct(_, _) => quote!(),
}
}
fn pretend_fields_used_struct(cont: &Container, fields: &[Field]) -> TokenStream {
let type_ident = &cont.ident;
let (_, ty_generics, _) = cont.generics.split_for_impl();
let patterns = match &cont.data {
Data::Enum(variants) => variants
.iter()
.filter_map(|variant| match variant.style {
Style::Struct => {
let variant_ident = &variant.ident;
let pat = struct_pattern(&variant.fields);
Some(quote!(#type_ident::#variant_ident #pat))
}
_ => None,
})
.collect::<Vec<_>>(),
Data::Struct(Style::Struct, fields) => {
let pat = struct_pattern(fields);
vec![quote!(#type_ident #pat)]
}
Data::Struct(_, _) => {
return quote!();
}
};
let members = fields.iter().map(|field| &field.member);
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
quote! {
match _serde::__private::None::<#type_ident #ty_generics> {
match _serde::__private::None::<&#type_ident #ty_generics> {
_serde::__private::Some(#type_ident { #(#members: #placeholders),* }) => {}
_ => {}
}
}
}
fn pretend_fields_used_struct_packed(cont: &Container, fields: &[Field]) -> TokenStream {
let type_ident = &cont.ident;
let (_, ty_generics, _) = cont.generics.split_for_impl();
let members = fields.iter().map(|field| &field.member).collect::<Vec<_>>();
quote! {
match _serde::__private::None::<&#type_ident #ty_generics> {
_serde::__private::Some(__v @ #type_ident { #(#members: _),* }) => {
#(
let _ = _serde::__private::ptr::addr_of!(__v.#members);
)*
}
_ => {}
}
}
}
fn pretend_fields_used_enum(cont: &Container, variants: &[Variant]) -> TokenStream {
let type_ident = &cont.ident;
let (_, ty_generics, _) = cont.generics.split_for_impl();
let patterns = variants
.iter()
.filter_map(|variant| match variant.style {
Style::Struct => {
let variant_ident = &variant.ident;
let members = variant.fields.iter().map(|field| &field.member);
let placeholders = (0usize..).map(|i| format_ident!("__v{}", i));
Some(quote!(#type_ident::#variant_ident { #(#members: #placeholders),* }))
}
_ => None,
})
.collect::<Vec<_>>();
quote! {
match _serde::__private::None::<&#type_ident #ty_generics> {
#(
_serde::__private::Some(#patterns) => {}
)*
@@ -107,7 +160,7 @@ fn pretend_variants_used(cont: &Container) -> TokenStream {
let cases = variants.iter().map(|variant| {
let variant_ident = &variant.ident;
let placeholders = &(0..variant.fields.len())
.map(|i| Ident::new(&format!("__v{}", i), Span::call_site()))
.map(|i| format_ident!("__v{}", i))
.collect::<Vec<_>>();
let pat = match variant.style {
@@ -131,10 +184,3 @@ fn pretend_variants_used(cont: &Container) -> TokenStream {
quote!(#(#cases)*)
}
fn struct_pattern(fields: &[Field]) -> TokenStream {
let members = fields.iter().map(|field| &field.member);
let placeholders =
(0..fields.len()).map(|i| Ident::new(&format!("__v{}", i), Span::call_site()));
quote!({ #(#members: ref #placeholders),* })
}
+48 -41
View File
@@ -6,10 +6,13 @@ use bound;
use dummy;
use fragment::{Fragment, Match, Stmts};
use internals::ast::{Container, Data, Field, Style, Variant};
use internals::{attr, Ctxt, Derive};
use internals::{attr, replace_receiver, Ctxt, Derive};
use pretend;
use this;
pub fn expand_derive_serialize(input: &mut syn::DeriveInput) -> syn::Result<TokenStream> {
replace_receiver(input);
pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
let ctxt = Ctxt::new();
let cont = match Container::from_ast(&ctxt, input, Derive::Serialize) {
Some(cont) => cont,
@@ -26,7 +29,7 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis;
let used = pretend::pretend_used(&cont);
let used = pretend::pretend_used(&cont, params.is_packed);
quote! {
impl #impl_generics #ident #ty_generics #where_clause {
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::__private::Result<__S::Ok, __S::Error>
@@ -54,8 +57,6 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
Ok(dummy::wrap_in_const(
cont.attrs.custom_serde_path(),
"SERIALIZE",
ident,
impl_block,
))
}
@@ -78,9 +79,13 @@ struct Parameters {
self_var: Ident,
/// Path to the type the impl is for. Either a single `Ident` for local
/// types or `some::remote::Ident` for remote types. Does not include
/// generic parameters.
this: syn::Path,
/// types (does not include generic parameters) or `some::remote::Path` for
/// remote types.
this_type: syn::Path,
/// Same as `this_type` but using `::<T>` for generic parameters for use in
/// expression position.
this_value: syn::Path,
/// Generics including any explicit and inferred bounds for the impl.
generics: syn::Generics,
@@ -101,18 +106,15 @@ impl Parameters {
Ident::new("self", Span::call_site())
};
let this = match cont.attrs.remote() {
Some(remote) => remote.clone(),
None => cont.ident.clone().into(),
};
let this_type = this::this_type(cont);
let this_value = this::this_value(cont);
let is_packed = cont.attrs.is_packed();
let generics = build_generics(cont);
Parameters {
self_var,
this,
this_type,
this_value,
generics,
is_remote,
is_packed,
@@ -122,7 +124,7 @@ impl Parameters {
/// Type name to use in error messages and `&'static str` arguments to
/// various Serializer methods.
fn type_name(&self) -> String {
self.this.segments.last().unwrap().ident.to_string()
self.this_type.segments.last().unwrap().ident.to_string()
}
}
@@ -423,7 +425,7 @@ fn serialize_variant(
variant_index: u32,
cattrs: &attr::Container,
) -> TokenStream {
let this = &params.this;
let this_value = &params.this_value;
let variant_ident = &variant.ident;
if variant.attrs.skip_serializing() {
@@ -441,47 +443,49 @@ fn serialize_variant(
Style::Struct => quote!({ .. }),
};
quote! {
#this::#variant_ident #fields_pat => #skipped_err,
#this_value::#variant_ident #fields_pat => #skipped_err,
}
} else {
// variant wasn't skipped
let case = match variant.style {
Style::Unit => {
quote! {
#this::#variant_ident
#this_value::#variant_ident
}
}
Style::Newtype => {
quote! {
#this::#variant_ident(ref __field0)
#this_value::#variant_ident(ref __field0)
}
}
Style::Tuple => {
let field_names = (0..variant.fields.len())
.map(|i| Ident::new(&format!("__field{}", i), Span::call_site()));
quote! {
#this::#variant_ident(#(ref #field_names),*)
#this_value::#variant_ident(#(ref #field_names),*)
}
}
Style::Struct => {
let members = variant.fields.iter().map(|f| &f.member);
quote! {
#this::#variant_ident { #(ref #members),* }
#this_value::#variant_ident { #(ref #members),* }
}
}
};
let body = Match(match cattrs.tag() {
attr::TagType::External => {
let body = Match(match (cattrs.tag(), variant.attrs.untagged()) {
(attr::TagType::External, false) => {
serialize_externally_tagged_variant(params, variant, variant_index, cattrs)
}
attr::TagType::Internal { tag } => {
(attr::TagType::Internal { tag }, false) => {
serialize_internally_tagged_variant(params, variant, cattrs, tag)
}
attr::TagType::Adjacent { tag, content } => {
(attr::TagType::Adjacent { tag, content }, false) => {
serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content)
}
attr::TagType::None => serialize_untagged_variant(params, variant, cattrs),
(attr::TagType::None, _) | (_, true) => {
serialize_untagged_variant(params, variant, cattrs)
}
});
quote! {
@@ -636,7 +640,7 @@ fn serialize_adjacently_tagged_variant(
tag: &str,
content: &str,
) -> Fragment {
let this = &params.this;
let this_type = &params.this_type;
let type_name = cattrs.name().serialize_name();
let variant_name = variant.attrs.name().serialize_name();
@@ -713,9 +717,10 @@ fn serialize_adjacently_tagged_variant(
let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
quote_block! {
#[doc(hidden)]
struct __AdjacentlyTagged #wrapper_generics #where_clause {
data: (#(&'__a #fields_ty,)*),
phantom: _serde::__private::PhantomData<#this #ty_generics>,
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
}
impl #wrapper_impl_generics _serde::Serialize for __AdjacentlyTagged #wrapper_ty_generics #where_clause {
@@ -737,7 +742,7 @@ fn serialize_adjacently_tagged_variant(
try!(_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #content, &__AdjacentlyTagged {
data: (#(#fields_ident,)*),
phantom: _serde::__private::PhantomData::<#this #ty_generics>,
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
}));
_serde::ser::SerializeStruct::end(__struct)
}
@@ -862,8 +867,8 @@ enum StructVariant<'a> {
Untagged,
}
fn serialize_struct_variant<'a>(
context: StructVariant<'a>,
fn serialize_struct_variant(
context: StructVariant,
params: &Parameters,
fields: &[Field],
name: &str,
@@ -946,8 +951,8 @@ fn serialize_struct_variant<'a>(
}
}
fn serialize_struct_variant_with_flatten<'a>(
context: StructVariant<'a>,
fn serialize_struct_variant_with_flatten(
context: StructVariant,
params: &Parameters,
fields: &[Field],
name: &str,
@@ -967,7 +972,7 @@ fn serialize_struct_variant_with_flatten<'a>(
variant_index,
variant_name,
} => {
let this = &params.this;
let this_type = &params.this_type;
let fields_ty = fields.iter().map(|f| &f.ty);
let members = &fields.iter().map(|f| &f.member).collect::<Vec<_>>();
@@ -976,9 +981,10 @@ fn serialize_struct_variant_with_flatten<'a>(
let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
quote_block! {
#[doc(hidden)]
struct __EnumFlatten #wrapper_generics #where_clause {
data: (#(&'__a #fields_ty,)*),
phantom: _serde::__private::PhantomData<#this #ty_generics>,
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
}
impl #wrapper_impl_generics _serde::Serialize for __EnumFlatten #wrapper_ty_generics #where_clause {
@@ -1002,7 +1008,7 @@ fn serialize_struct_variant_with_flatten<'a>(
#variant_name,
&__EnumFlatten {
data: (#(#members,)*),
phantom: _serde::__private::PhantomData::<#this #ty_generics>,
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
})
}
}
@@ -1095,7 +1101,7 @@ fn serialize_struct_visitor(
let mut field_expr = if is_enum {
quote!(#member)
} else {
get_member(params, field, &member)
get_member(params, field, member)
};
let key_expr = field.attrs.name().serialize_name();
@@ -1188,7 +1194,7 @@ fn wrap_serialize_with(
field_tys: &[&syn::Type],
field_exprs: &[TokenStream],
) -> TokenStream {
let this = &params.this;
let this_type = &params.this_type;
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
let wrapper_generics = if field_exprs.is_empty() {
@@ -1206,9 +1212,10 @@ fn wrap_serialize_with(
});
quote!({
#[doc(hidden)]
struct __SerializeWith #wrapper_impl_generics #where_clause {
values: (#(&'__a #field_tys, )*),
phantom: _serde::__private::PhantomData<#this #ty_generics>,
phantom: _serde::__private::PhantomData<#this_type #ty_generics>,
}
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
@@ -1222,7 +1229,7 @@ fn wrap_serialize_with(
&__SerializeWith {
values: (#(#field_exprs, )*),
phantom: _serde::__private::PhantomData::<#this #ty_generics>,
phantom: _serde::__private::PhantomData::<#this_type #ty_generics>,
}
})
}
+32
View File
@@ -0,0 +1,32 @@
use internals::ast::Container;
use syn::{Path, PathArguments, Token};
pub fn this_type(cont: &Container) -> Path {
if let Some(remote) = cont.attrs.remote() {
let mut this = remote.clone();
for segment in &mut this.segments {
if let PathArguments::AngleBracketed(arguments) = &mut segment.arguments {
arguments.colon2_token = None;
}
}
this
} else {
Path::from(cont.ident.clone())
}
}
pub fn this_value(cont: &Container) -> Path {
if let Some(remote) = cont.attrs.remote() {
let mut this = remote.clone();
for segment in &mut this.segments {
if let PathArguments::AngleBracketed(arguments) = &mut segment.arguments {
if arguments.colon2_token.is_none() {
arguments.colon2_token = Some(Token![::](arguments.lt_token.span));
}
}
}
this
} else {
Path::from(cont.ident.clone())
}
}
+7 -6
View File
@@ -1,14 +1,15 @@
[package]
name = "serde_derive_internals"
version = "0.25.0" # remember to update html_root_url
version = "0.28.0" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT OR Apache-2.0"
description = "AST representation used by Serde derive macros. Unstable."
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.rs/serde_derive_internals"
exclude = ["build.rs"]
homepage = "https://serde.rs"
keywords = ["serde", "serialization"]
include = ["lib.rs", "src/**/*.rs", "LICENSE-APACHE", "LICENSE-MIT"]
license = "MIT OR Apache-2.0"
repository = "https://github.com/serde-rs/serde"
rust-version = "1.56"
[lib]
path = "lib.rs"
@@ -16,7 +17,7 @@ path = "lib.rs"
[dependencies]
proc-macro2 = "1.0"
quote = "1.0"
syn = { version = "1.0.33", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] }
syn = { version = "2.0.25", default-features = false, features = ["clone-impls", "derive", "parsing", "printing"] }
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
+15
View File
@@ -0,0 +1,15 @@
use std::path::Path;
fn main() {
println!("cargo:rerun-if-changed=build.rs");
println!("cargo:rerun-if-changed=src/mod.rs");
// Sometimes on Windows the git checkout does not correctly wire up the
// symlink from serde_derive_internals/src to serde_derive/src/internals.
// When this happens we'll just build based on relative paths within the git
// repo.
let mod_behind_symlink = Path::new("src/mod.rs");
if !mod_behind_symlink.exists() {
println!("cargo:rustc-cfg=serde_build_from_git");
}
}
+39 -14
View File
@@ -1,17 +1,41 @@
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.25.0")]
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.28.0")]
#![allow(unknown_lints, bare_trait_objects)]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(
feature = "cargo-clippy",
allow(
cognitive_complexity,
redundant_field_names,
result_unit_err,
trivially_copy_pass_by_ref,
wildcard_in_or_patterns,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
unnested_or_patterns,
)
// Ignored clippy lints
#![allow(
clippy::cognitive_complexity,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/7575
clippy::collapsible_match,
clippy::derive_partial_eq_without_eq,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6797
clippy::manual_map,
clippy::missing_panics_doc,
clippy::redundant_field_names,
clippy::result_unit_err,
clippy::should_implement_trait,
clippy::trivially_copy_pass_by_ref,
clippy::wildcard_in_or_patterns,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
clippy::unnested_or_patterns,
)]
// Ignored clippy_pedantic lints
#![allow(
clippy::doc_markdown,
clippy::enum_glob_use,
clippy::items_after_statements,
clippy::let_underscore_untyped,
clippy::manual_assert,
clippy::match_same_arms,
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/6984
clippy::match_wildcard_for_single_variants,
clippy::missing_errors_doc,
clippy::module_name_repetitions,
clippy::must_use_candidate,
clippy::similar_names,
clippy::single_match_else,
clippy::struct_excessive_bools,
clippy::too_many_lines,
clippy::unused_self,
clippy::wildcard_imports
)]
#[macro_use]
@@ -20,7 +44,8 @@ extern crate syn;
extern crate proc_macro2;
extern crate quote;
#[path = "src/mod.rs"]
#[cfg_attr(serde_build_from_git, path = "../serde_derive/src/internals/mod.rs")]
#[cfg_attr(not(serde_build_from_git), path = "src/mod.rs")]
mod internals;
pub use internals::*;
+13 -8
View File
@@ -1,22 +1,27 @@
[package]
name = "serde_test"
version = "1.0.121" # remember to update html_root_url
version = "1.0.172" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT OR Apache-2.0"
build = "build.rs"
categories = ["development-tools::testing"]
description = "Token De/Serializer for testing De/Serialize implementations"
documentation = "https://docs.rs/serde_test"
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde_test/"
keywords = ["serde", "serialization"]
keywords = ["serde", "serialization", "testing", "dev-dependencies"]
license = "MIT OR Apache-2.0"
readme = "crates-io.md"
include = ["src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
repository = "https://github.com/serde-rs/serde"
rust-version = "1.19"
[dependencies]
serde = { version = "1.0.60", path = "../serde" }
[dev-dependencies]
serde = { version = "1.0", path = "../serde" }
serde_derive = { version = "1.0", path = "../serde_derive" }
serde = { version = "1", path = "../serde", features = ["rc"] }
serde_derive = { version = "1", path = "../serde_derive" }
[lib]
doc-scrape-examples = false
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]
+50
View File
@@ -0,0 +1,50 @@
use std::env;
use std::process::Command;
use std::str::{self, FromStr};
// The rustc-cfg strings below are *not* public API. Please let us know by
// opening a GitHub issue if your build environment requires some way to enable
// these cfgs other than by executing our build script.
fn main() {
println!("cargo:rerun-if-changed=build.rs");
let minor = match rustc_minor_version() {
Some(minor) => minor,
None => return,
};
// #[track_caller] stabilized in Rust 1.46:
// https://blog.rust-lang.org/2020/08/27/Rust-1.46.0.html#track_caller
if minor < 46 {
println!("cargo:rustc-cfg=no_track_caller");
}
}
fn rustc_minor_version() -> Option<u32> {
let rustc = match env::var_os("RUSTC") {
Some(rustc) => rustc,
None => return None,
};
let output = match Command::new(rustc).arg("--version").output() {
Ok(output) => output,
Err(_) => return None,
};
let version = match str::from_utf8(&output.stdout) {
Ok(version) => version,
Err(_) => return None,
};
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return None;
}
let next = match pieces.next() {
Some(next) => next,
None => return None,
};
u32::from_str(next).ok()
}
+61 -42
View File
@@ -8,8 +8,8 @@ use std::fmt::Debug;
/// Runs both `assert_ser_tokens` and `assert_de_tokens`.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
@@ -19,15 +19,19 @@ use std::fmt::Debug;
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_tokens(&s, &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ]);
/// assert_tokens(
/// &s,
/// &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ],
/// );
/// ```
#[cfg_attr(not(no_track_caller), track_caller)]
pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token])
where
T: Serialize + Deserialize<'de> + PartialEq + Debug,
@@ -38,8 +42,8 @@ where
/// Asserts that `value` serializes to the given `tokens`.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_ser_tokens, Token};
/// #
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
@@ -49,16 +53,20 @@ where
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_ser_tokens(&s, &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ]);
/// assert_ser_tokens(
/// &s,
/// &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ],
/// );
/// ```
pub fn assert_ser_tokens<T>(value: &T, tokens: &[Token])
#[cfg_attr(not(no_track_caller), track_caller)]
pub fn assert_ser_tokens<T: ?Sized>(value: &T, tokens: &[Token])
where
T: Serialize,
{
@@ -76,23 +84,24 @@ where
/// Asserts that `value` serializes to the given `tokens`, and then yields
/// `error`.
///
/// ```edition2018
/// ```edition2021
/// use serde_derive::Serialize;
/// use serde_test::{assert_ser_tokens_error, Token};
/// use std::sync::{Arc, Mutex};
/// use std::thread;
///
/// use serde::Serialize;
/// use serde_test::{assert_ser_tokens_error, Token};
///
/// #[derive(Serialize)]
/// struct Example {
/// lock: Arc<Mutex<u32>>,
/// }
///
/// fn main() {
/// let example = Example { lock: Arc::new(Mutex::new(0)) };
/// let example = Example {
/// lock: Arc::new(Mutex::new(0)),
/// };
/// let lock = example.lock.clone();
///
/// let _ = thread::spawn(move || {
/// let thread = thread::spawn(move || {
/// // This thread will acquire the mutex first, unwrapping the result
/// // of `lock` because the lock has not been poisoned.
/// let _guard = lock.lock().unwrap();
@@ -100,17 +109,22 @@ where
/// // This panic while holding the lock (`_guard` is in scope) will
/// // poison the mutex.
/// panic!()
/// }).join();
/// });
/// thread.join();
///
/// let expected = &[
/// Token::Struct { name: "Example", len: 1 },
/// Token::Struct {
/// name: "Example",
/// len: 1,
/// },
/// Token::Str("lock"),
/// ];
/// let error = "lock poison error while serializing";
/// assert_ser_tokens_error(&example, expected, error);
/// }
/// ```
pub fn assert_ser_tokens_error<T>(value: &T, tokens: &[Token], error: &str)
#[cfg_attr(not(no_track_caller), track_caller)]
pub fn assert_ser_tokens_error<T: ?Sized>(value: &T, tokens: &[Token], error: &str)
where
T: Serialize,
{
@@ -127,8 +141,8 @@ where
/// Asserts that the given `tokens` deserialize into `value`.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_de_tokens, Token};
/// #
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
@@ -138,15 +152,19 @@ where
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_de_tokens(&s, &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ]);
/// assert_de_tokens(
/// &s,
/// &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ],
/// );
/// ```
#[cfg_attr(not(no_track_caller), track_caller)]
pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
where
T: Deserialize<'de> + PartialEq + Debug,
@@ -180,8 +198,8 @@ where
/// Asserts that the given `tokens` yield `error` when deserializing.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_de_tokens_error, Token};
/// #
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
@@ -199,6 +217,7 @@ where
/// "unknown field `x`, expected `a` or `b`",
/// );
/// ```
#[cfg_attr(not(no_track_caller), track_caller)]
pub fn assert_de_tokens_error<'de, T>(tokens: &'de [Token], error: &str)
where
T: Deserialize<'de>,
+12 -1
View File
@@ -14,7 +14,7 @@ pub struct Compact<T: ?Sized>(T);
/// Trait to determine whether a value is represented in human-readable or
/// compact form.
///
/// ```edition2018
/// ```edition2021
/// use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// use serde_test::{assert_tokens, Configure, Token};
///
@@ -777,6 +777,17 @@ macro_rules! impl_deserializer {
{
self.0.next_value_seed($wrapper(seed))
}
fn next_entry_seed<K, V>(
&mut self,
kseed: K,
vseed: V,
) -> Result<Option<(K::Value, V::Value)>, D::Error>
where
K: DeserializeSeed<'de>,
V: DeserializeSeed<'de>,
{
self.0.next_entry_seed($wrapper(kseed), $wrapper(vseed))
}
fn size_hint(&self) -> Option<usize> {
self.0.size_hint()
}
+105 -91
View File
@@ -12,32 +12,29 @@ pub struct Deserializer<'de> {
tokens: &'de [Token],
}
macro_rules! assert_next_token {
($de:expr, $expected:expr) => {
match $de.next_token_opt() {
Some(token) if token == $expected => {}
Some(other) => panic!(
"expected Token::{} but deserialization wants Token::{}",
other, $expected
),
None => panic!(
"end of tokens but deserialization wants Token::{}",
$expected
),
}
};
fn assert_next_token(de: &mut Deserializer, expected: Token) -> Result<(), Error> {
match de.next_token_opt() {
Some(token) if token == expected => Ok(()),
Some(other) => Err(de::Error::custom(format!(
"expected Token::{} but deserialization wants Token::{}",
other, expected,
))),
None => Err(de::Error::custom(format!(
"end of tokens but deserialization wants Token::{}",
expected,
))),
}
}
macro_rules! unexpected {
($token:expr) => {
panic!("deserialization did not expect this token: {}", $token)
};
fn unexpected(token: Token) -> Error {
de::Error::custom(format!(
"deserialization did not expect this token: {}",
token,
))
}
macro_rules! end_of_tokens {
() => {
panic!("ran out of tokens to deserialize")
};
fn end_of_tokens() -> Error {
de::Error::custom("ran out of tokens to deserialize")
}
impl<'de> Deserializer<'de> {
@@ -49,11 +46,8 @@ impl<'de> Deserializer<'de> {
self.tokens.first().cloned()
}
fn peek_token(&self) -> Token {
match self.peek_token_opt() {
Some(token) => token,
None => end_of_tokens!(),
}
fn peek_token(&self) -> Result<Token, Error> {
self.peek_token_opt().ok_or_else(end_of_tokens)
}
pub fn next_token_opt(&mut self) -> Option<Token> {
@@ -66,14 +60,10 @@ impl<'de> Deserializer<'de> {
}
}
fn next_token(&mut self) -> Token {
match self.tokens.split_first() {
Some((&first, rest)) => {
self.tokens = rest;
first
}
None => end_of_tokens!(),
}
fn next_token(&mut self) -> Result<Token, Error> {
let (&first, rest) = self.tokens.split_first().ok_or_else(end_of_tokens)?;
self.tokens = rest;
Ok(first)
}
pub fn remaining(&self) -> usize {
@@ -94,7 +84,7 @@ impl<'de> Deserializer<'de> {
len: len,
end: end,
})?;
assert_next_token!(self, end);
assert_next_token(self, end)?;
Ok(value)
}
@@ -112,7 +102,7 @@ impl<'de> Deserializer<'de> {
len: len,
end: end,
})?;
assert_next_token!(self, end);
assert_next_token(self, end)?;
Ok(value)
}
}
@@ -129,7 +119,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: Visitor<'de>,
{
let token = self.next_token();
let token = self.next_token()?;
match token {
Token::Bool(v) => visitor.visit_bool(v),
Token::I8(v) => visitor.visit_i8(v),
@@ -161,22 +151,50 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
Token::Map { len } => self.visit_map(len, Token::MapEnd, visitor),
Token::Struct { len, .. } => self.visit_map(Some(len), Token::StructEnd, visitor),
Token::Enum { .. } => {
let variant = self.next_token();
let next = self.peek_token();
let variant = self.next_token()?;
let next = self.peek_token()?;
match (variant, next) {
(Token::Str(variant), Token::Unit) => {
self.next_token();
self.next_token()?;
visitor.visit_str(variant)
}
(Token::BorrowedStr(variant), Token::Unit) => {
self.next_token()?;
visitor.visit_borrowed_str(variant)
}
(Token::String(variant), Token::Unit) => {
self.next_token()?;
visitor.visit_string(variant.to_string())
}
(Token::Bytes(variant), Token::Unit) => {
self.next_token();
self.next_token()?;
visitor.visit_bytes(variant)
}
(Token::BorrowedBytes(variant), Token::Unit) => {
self.next_token()?;
visitor.visit_borrowed_bytes(variant)
}
(Token::ByteBuf(variant), Token::Unit) => {
self.next_token()?;
visitor.visit_byte_buf(variant.to_vec())
}
(Token::U8(variant), Token::Unit) => {
self.next_token()?;
visitor.visit_u8(variant)
}
(Token::U16(variant), Token::Unit) => {
self.next_token()?;
visitor.visit_u16(variant)
}
(Token::U32(variant), Token::Unit) => {
self.next_token();
self.next_token()?;
visitor.visit_u32(variant)
}
(variant, Token::Unit) => unexpected!(variant),
(Token::U64(variant), Token::Unit) => {
self.next_token()?;
visitor.visit_u64(variant)
}
(variant, Token::Unit) => Err(unexpected(variant)),
(variant, _) => {
visitor.visit_map(EnumMapVisitor::new(self, variant, EnumFormat::Any))
}
@@ -204,9 +222,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
| Token::MapEnd
| Token::StructEnd
| Token::TupleVariantEnd
| Token::StructVariantEnd => {
unexpected!(token);
}
| Token::StructVariantEnd => Err(unexpected(token)),
}
}
@@ -214,13 +230,13 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: Visitor<'de>,
{
match self.peek_token() {
match self.peek_token()? {
Token::Unit | Token::None => {
self.next_token();
self.next_token()?;
visitor.visit_none()
}
Token::Some => {
self.next_token();
self.next_token()?;
visitor.visit_some(self)
}
_ => self.deserialize_any(visitor),
@@ -236,9 +252,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: Visitor<'de>,
{
match self.peek_token() {
match self.peek_token()? {
Token::Enum { name: n } if name == n => {
self.next_token();
self.next_token()?;
visitor.visit_enum(DeserializerEnumVisitor { de: self })
}
@@ -250,9 +266,7 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
{
visitor.visit_enum(DeserializerEnumVisitor { de: self })
}
_ => {
unexpected!(self.next_token());
}
_ => self.deserialize_any(visitor),
}
}
@@ -260,9 +274,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: Visitor<'de>,
{
match self.peek_token() {
match self.peek_token()? {
Token::UnitStruct { .. } => {
assert_next_token!(self, Token::UnitStruct { name: name });
assert_next_token(self, Token::UnitStruct { name: name })?;
visitor.visit_unit()
}
_ => self.deserialize_any(visitor),
@@ -277,9 +291,9 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: Visitor<'de>,
{
match self.peek_token() {
match self.peek_token()? {
Token::NewtypeStruct { .. } => {
assert_next_token!(self, Token::NewtypeStruct { name: name });
assert_next_token(self, Token::NewtypeStruct { name: name })?;
visitor.visit_newtype_struct(self)
}
_ => self.deserialize_any(visitor),
@@ -290,21 +304,21 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: Visitor<'de>,
{
match self.peek_token() {
match self.peek_token()? {
Token::Unit | Token::UnitStruct { .. } => {
self.next_token();
self.next_token()?;
visitor.visit_unit()
}
Token::Seq { .. } => {
self.next_token();
self.next_token()?;
self.visit_seq(Some(len), Token::SeqEnd, visitor)
}
Token::Tuple { .. } => {
self.next_token();
self.next_token()?;
self.visit_seq(Some(len), Token::TupleEnd, visitor)
}
Token::TupleStruct { .. } => {
self.next_token();
self.next_token()?;
self.visit_seq(Some(len), Token::TupleStructEnd, visitor)
}
_ => self.deserialize_any(visitor),
@@ -320,25 +334,25 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: Visitor<'de>,
{
match self.peek_token() {
match self.peek_token()? {
Token::Unit => {
self.next_token();
self.next_token()?;
visitor.visit_unit()
}
Token::UnitStruct { .. } => {
assert_next_token!(self, Token::UnitStruct { name: name });
assert_next_token(self, Token::UnitStruct { name: name })?;
visitor.visit_unit()
}
Token::Seq { .. } => {
self.next_token();
self.next_token()?;
self.visit_seq(Some(len), Token::SeqEnd, visitor)
}
Token::Tuple { .. } => {
self.next_token();
self.next_token()?;
self.visit_seq(Some(len), Token::TupleEnd, visitor)
}
Token::TupleStruct { len: n, .. } => {
assert_next_token!(self, Token::TupleStruct { name: name, len: n });
assert_next_token(self, Token::TupleStruct { name: name, len: n })?;
self.visit_seq(Some(len), Token::TupleStructEnd, visitor)
}
_ => self.deserialize_any(visitor),
@@ -354,13 +368,13 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
where
V: Visitor<'de>,
{
match self.peek_token() {
match self.peek_token()? {
Token::Struct { len: n, .. } => {
assert_next_token!(self, Token::Struct { name: name, len: n });
assert_next_token(self, Token::Struct { name: name, len: n })?;
self.visit_map(Some(fields.len()), Token::StructEnd, visitor)
}
Token::Map { .. } => {
self.next_token();
self.next_token()?;
self.visit_map(Some(fields.len()), Token::MapEnd, visitor)
}
_ => self.deserialize_any(visitor),
@@ -450,7 +464,7 @@ impl<'de, 'a> EnumAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
where
V: DeserializeSeed<'de>,
{
match self.de.peek_token() {
match self.de.peek_token()? {
Token::UnitVariant { variant: v, .. }
| Token::NewtypeVariant { variant: v, .. }
| Token::TupleVariant { variant: v, .. }
@@ -471,9 +485,9 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
type Error = Error;
fn unit_variant(self) -> Result<(), Error> {
match self.de.peek_token() {
match self.de.peek_token()? {
Token::UnitVariant { .. } => {
self.de.next_token();
self.de.next_token()?;
Ok(())
}
_ => Deserialize::deserialize(self.de),
@@ -484,9 +498,9 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
where
T: DeserializeSeed<'de>,
{
match self.de.peek_token() {
match self.de.peek_token()? {
Token::NewtypeVariant { .. } => {
self.de.next_token();
self.de.next_token()?;
seed.deserialize(self.de)
}
_ => seed.deserialize(self.de),
@@ -497,26 +511,26 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
where
V: Visitor<'de>,
{
match self.de.peek_token() {
match self.de.peek_token()? {
Token::TupleVariant { len: enum_len, .. } => {
let token = self.de.next_token();
let token = self.de.next_token()?;
if len == enum_len {
self.de
.visit_seq(Some(len), Token::TupleVariantEnd, visitor)
} else {
unexpected!(token);
Err(unexpected(token))
}
}
Token::Seq {
len: Some(enum_len),
} => {
let token = self.de.next_token();
let token = self.de.next_token()?;
if len == enum_len {
self.de.visit_seq(Some(len), Token::SeqEnd, visitor)
} else {
unexpected!(token);
Err(unexpected(token))
}
}
_ => de::Deserializer::deserialize_any(self.de, visitor),
@@ -531,27 +545,27 @@ impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
where
V: Visitor<'de>,
{
match self.de.peek_token() {
match self.de.peek_token()? {
Token::StructVariant { len: enum_len, .. } => {
let token = self.de.next_token();
let token = self.de.next_token()?;
if fields.len() == enum_len {
self.de
.visit_map(Some(fields.len()), Token::StructVariantEnd, visitor)
} else {
unexpected!(token);
Err(unexpected(token))
}
}
Token::Map {
len: Some(enum_len),
} => {
let token = self.de.next_token();
let token = self.de.next_token()?;
if fields.len() == enum_len {
self.de
.visit_map(Some(fields.len()), Token::MapEnd, visitor)
} else {
unexpected!(token);
Err(unexpected(token))
}
}
_ => de::Deserializer::deserialize_any(self.de, visitor),
@@ -596,7 +610,7 @@ impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> {
.deserialize(BytesDeserializer { value: variant })
.map(Some),
Some(Token::U32(variant)) => seed.deserialize(variant.into_deserializer()).map(Some),
Some(other) => unexpected!(other),
Some(other) => Err(unexpected(other)),
None => Ok(None),
}
}
@@ -615,7 +629,7 @@ impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> {
};
seed.deserialize(SeqAccessDeserializer::new(visitor))?
};
assert_next_token!(self.de, Token::TupleVariantEnd);
assert_next_token(self.de, Token::TupleVariantEnd)?;
Ok(value)
}
EnumFormat::Map => {
@@ -627,7 +641,7 @@ impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> {
};
seed.deserialize(MapAccessDeserializer::new(visitor))?
};
assert_next_token!(self.de, Token::StructVariantEnd);
assert_next_token(self.de, Token::StructVariantEnd)?;
Ok(value)
}
EnumFormat::Any => seed.deserialize(&mut *self.de),
+32 -31
View File
@@ -1,8 +1,8 @@
//! This crate provides a convenient concise way to write unit tests for
//! implementations of [`Serialize`] and [`Deserialize`].
//!
//! [`Serialize`]: https://docs.serde.rs/serde/ser/trait.Serialize.html
//! [`Deserialize`]: https://docs.serde.rs/serde/de/trait.Deserialize.html
//! [`Serialize`]: serde::ser::Serialize
//! [`Deserialize`]: serde::de::Deserialize
//!
//! The `Serialize` impl for a value can be characterized by the sequence of
//! [`Serializer`] calls that are made in the course of serializing the value,
@@ -14,21 +14,17 @@
//! test both directions. There are also functions to test expected failure
//! conditions.
//!
//! [`Serializer`]: https://docs.serde.rs/serde/ser/trait.Serializer.html
//! [`Token`]: https://docs.serde.rs/serde_test/enum.Token.html
//! [`assert_ser_tokens`]: https://docs.serde.rs/serde_test/fn.assert_ser_tokens.html
//! [`assert_de_tokens`]: https://docs.serde.rs/serde_test/fn.assert_de_tokens.html
//! [`assert_tokens`]: https://docs.serde.rs/serde_test/fn.assert_tokens.html
//! [`Serializer`]: serde::ser::Serializer
//!
//! Here is an example from the [`linked-hash-map`] crate.
//!
//! [`linked-hash-map`]: https://github.com/contain-rs/linked-hash-map
//!
//! ```edition2018
//! ```edition2021
//! # const IGNORE: &str = stringify! {
//! use linked_hash_map::LinkedHashMap;
//! # };
//! use serde_test::{Token, assert_tokens};
//! use serde_test::{assert_tokens, Token};
//!
//! # use std::fmt;
//! # use std::marker::PhantomData;
@@ -110,10 +106,13 @@
//! fn test_ser_de_empty() {
//! let map = LinkedHashMap::<char, u32>::new();
//!
//! assert_tokens(&map, &[
//! Token::Map { len: Some(0) },
//! Token::MapEnd,
//! ]);
//! assert_tokens(
//! &map,
//! &[
//! Token::Map { len: Some(0) },
//! Token::MapEnd,
//! ],
//! );
//! }
//!
//! #[test]
@@ -124,18 +123,19 @@
//! map.insert('a', 10);
//! map.insert('c', 30);
//!
//! assert_tokens(&map, &[
//! Token::Map { len: Some(3) },
//! Token::Char('b'),
//! Token::I32(20),
//!
//! Token::Char('a'),
//! Token::I32(10),
//!
//! Token::Char('c'),
//! Token::I32(30),
//! Token::MapEnd,
//! ]);
//! assert_tokens(
//! &map,
//! &[
//! Token::Map { len: Some(3) },
//! Token::Char('b'),
//! Token::I32(20),
//! Token::Char('a'),
//! Token::I32(10),
//! Token::Char('c'),
//! Token::I32(30),
//! Token::MapEnd,
//! ],
//! );
//! }
//! #
//! # fn main() {
@@ -144,20 +144,25 @@
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.121")]
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.172")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Ignored clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp, needless_doctest_main))]
// Ignored clippy_pedantic lints
#![cfg_attr(
feature = "cargo-clippy",
allow(
cloned_instead_of_copied,
doc_link_with_quotes, // https://github.com/rust-lang/rust-clippy/issues/8961
empty_line_after_outer_attr,
manual_assert,
missing_docs_in_private_items,
missing_panics_doc,
module_name_repetitions,
must_use_candidate,
redundant_field_names,
too_many_lines,
type_repetition_in_bounds, // https://github.com/rust-lang/rust-clippy/issues/8772
use_debug,
use_self
)
@@ -181,7 +186,3 @@ pub use assert::{
pub use token::Token;
pub use configure::{Compact, Configure, Readable};
// Not public API.
#[doc(hidden)]
pub use de::Deserializer;
+18 -20
View File
@@ -32,18 +32,18 @@ impl<'a> Serializer<'a> {
}
macro_rules! assert_next_token {
($ser:expr, $expected:ident) => {
assert_next_token!($ser, stringify!($expected), Token::$expected, true);
};
($ser:expr, $expected:ident($v:expr)) => {
($ser:expr, $actual:ident) => {{
assert_next_token!($ser, stringify!($actual), Token::$actual, true);
}};
($ser:expr, $actual:ident($v:expr)) => {{
assert_next_token!(
$ser,
format_args!(concat!(stringify!($expected), "({:?})"), $v),
Token::$expected(v),
format_args!(concat!(stringify!($actual), "({:?})"), $v),
Token::$actual(v),
v == $v
);
};
($ser:expr, $expected:ident { $($k:ident),* }) => {
}};
($ser:expr, $actual:ident { $($k:ident),* }) => {{
let compare = ($($k,)*);
let field_format = || {
use std::fmt::Write;
@@ -55,22 +55,20 @@ macro_rules! assert_next_token {
};
assert_next_token!(
$ser,
format_args!(concat!(stringify!($expected), " {{ {}}}"), field_format()),
Token::$expected { $($k),* },
format_args!(concat!(stringify!($actual), " {{ {}}}"), field_format()),
Token::$actual { $($k),* },
($($k,)*) == compare
);
};
($ser:expr, $expected:expr, $pat:pat, $guard:expr) => {
}};
($ser:expr, $actual:expr, $pat:pat, $guard:expr) => {
match $ser.next_token() {
Some($pat) if $guard => {}
Some(other) => {
panic!("expected Token::{} but serialized as {}",
$expected, other);
}
None => {
panic!("expected Token::{} after end of serialized tokens",
$expected);
}
Some(expected) => return Err(ser::Error::custom(
format!("expected Token::{} but serialized as {}", expected, $actual)
)),
None => return Err(ser::Error::custom(
format!("expected end of tokens, but {} was serialized", $actual)
)),
}
};
}
+167 -125
View File
@@ -4,7 +4,7 @@ use std::fmt::{self, Debug, Display};
pub enum Token {
/// A serialized `bool`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&true, &[Token::Bool(true)]);
@@ -13,7 +13,7 @@ pub enum Token {
/// A serialized `i8`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i8, &[Token::I8(0)]);
@@ -22,7 +22,7 @@ pub enum Token {
/// A serialized `i16`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i16, &[Token::I16(0)]);
@@ -31,7 +31,7 @@ pub enum Token {
/// A serialized `i32`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i32, &[Token::I32(0)]);
@@ -40,7 +40,7 @@ pub enum Token {
/// A serialized `i64`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i64, &[Token::I64(0)]);
@@ -49,7 +49,7 @@ pub enum Token {
/// A serialized `u8`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u8, &[Token::U8(0)]);
@@ -58,7 +58,7 @@ pub enum Token {
/// A serialized `u16`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u16, &[Token::U16(0)]);
@@ -67,7 +67,7 @@ pub enum Token {
/// A serialized `u32`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u32, &[Token::U32(0)]);
@@ -76,7 +76,7 @@ pub enum Token {
/// A serialized `u64`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u64, &[Token::U64(0)]);
@@ -85,7 +85,7 @@ pub enum Token {
/// A serialized `f32`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0f32, &[Token::F32(0.0)]);
@@ -94,7 +94,7 @@ pub enum Token {
/// A serialized `f64`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0f64, &[Token::F64(0.0)]);
@@ -103,7 +103,7 @@ pub enum Token {
/// A serialized `char`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&'\n', &[Token::Char('\n')]);
@@ -112,7 +112,7 @@ pub enum Token {
/// A serialized `str`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let s = String::from("transient");
@@ -122,7 +122,7 @@ pub enum Token {
/// A borrowed `str`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let s: &str = "borrowed";
@@ -132,7 +132,7 @@ pub enum Token {
/// A serialized `String`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let s = String::from("owned");
@@ -151,7 +151,7 @@ pub enum Token {
/// A serialized `Option<T>` containing none.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let opt = None::<char>;
@@ -163,20 +163,17 @@ pub enum Token {
///
/// The tokens of the value follow after this header.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let opt = Some('c');
/// assert_tokens(&opt, &[
/// Token::Some,
/// Token::Char('c'),
/// ]);
/// assert_tokens(&opt, &[Token::Some, Token::Char('c')]);
/// ```
Some,
/// A serialized `()`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&(), &[Token::Unit]);
@@ -185,8 +182,8 @@ pub enum Token {
/// A serialized unit struct of the given name.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
@@ -200,8 +197,8 @@ pub enum Token {
/// A unit variant of an enum.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
@@ -211,7 +208,13 @@ pub enum Token {
/// }
///
/// let a = E::A;
/// assert_tokens(&a, &[Token::UnitVariant { name: "E", variant: "A" }]);
/// assert_tokens(
/// &a,
/// &[Token::UnitVariant {
/// name: "E",
/// variant: "A",
/// }],
/// );
/// # }
/// ```
UnitVariant {
@@ -223,8 +226,8 @@ pub enum Token {
///
/// After this header is the value contained in the newtype struct.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
@@ -232,10 +235,10 @@ pub enum Token {
/// struct N(String);
///
/// let n = N("newtype".to_owned());
/// assert_tokens(&n, &[
/// Token::NewtypeStruct { name: "N" },
/// Token::String("newtype"),
/// ]);
/// assert_tokens(
/// &n,
/// &[Token::NewtypeStruct { name: "N" }, Token::String("newtype")],
/// );
/// # }
/// ```
NewtypeStruct { name: &'static str },
@@ -244,8 +247,8 @@ pub enum Token {
///
/// After this header is the value contained in the newtype variant.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
@@ -255,10 +258,16 @@ pub enum Token {
/// }
///
/// let b = E::B(0);
/// assert_tokens(&b, &[
/// Token::NewtypeVariant { name: "E", variant: "B" },
/// Token::U8(0),
/// ]);
/// assert_tokens(
/// &b,
/// &[
/// Token::NewtypeVariant {
/// name: "E",
/// variant: "B",
/// },
/// Token::U8(0),
/// ],
/// );
/// # }
/// ```
NewtypeVariant {
@@ -271,17 +280,20 @@ pub enum Token {
/// After this header are the elements of the sequence, followed by
/// `SeqEnd`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let vec = vec!['a', 'b', 'c'];
/// assert_tokens(&vec, &[
/// Token::Seq { len: Some(3) },
/// Token::Char('a'),
/// Token::Char('b'),
/// Token::Char('c'),
/// Token::SeqEnd,
/// ]);
/// assert_tokens(
/// &vec,
/// &[
/// Token::Seq { len: Some(3) },
/// Token::Char('a'),
/// Token::Char('b'),
/// Token::Char('c'),
/// Token::SeqEnd,
/// ],
/// );
/// ```
Seq { len: Option<usize> },
@@ -292,16 +304,19 @@ pub enum Token {
///
/// After this header are the elements of the tuple, followed by `TupleEnd`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// let tuple = ('a', 100);
/// assert_tokens(&tuple, &[
/// Token::Tuple { len: 2 },
/// Token::Char('a'),
/// Token::I32(100),
/// Token::TupleEnd,
/// ]);
/// assert_tokens(
/// &tuple,
/// &[
/// Token::Tuple { len: 2 },
/// Token::Char('a'),
/// Token::I32(100),
/// Token::TupleEnd,
/// ],
/// );
/// ```
Tuple { len: usize },
@@ -313,8 +328,8 @@ pub enum Token {
/// After this header are the fields of the tuple struct, followed by
/// `TupleStructEnd`.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
@@ -322,12 +337,15 @@ pub enum Token {
/// struct T(u8, u8);
///
/// let t = T(0, 0);
/// assert_tokens(&t, &[
/// Token::TupleStruct { name: "T", len: 2 },
/// Token::U8(0),
/// Token::U8(0),
/// Token::TupleStructEnd,
/// ]);
/// assert_tokens(
/// &t,
/// &[
/// Token::TupleStruct { name: "T", len: 2 },
/// Token::U8(0),
/// Token::U8(0),
/// Token::TupleStructEnd,
/// ],
/// );
/// # }
/// ```
TupleStruct { name: &'static str, len: usize },
@@ -340,8 +358,8 @@ pub enum Token {
/// After this header are the fields of the tuple variant, followed by
/// `TupleVariantEnd`.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
@@ -351,12 +369,19 @@ pub enum Token {
/// }
///
/// let c = E::C(0, 0);
/// assert_tokens(&c, &[
/// Token::TupleVariant { name: "E", variant: "C", len: 2 },
/// Token::U8(0),
/// Token::U8(0),
/// Token::TupleVariantEnd,
/// ]);
/// assert_tokens(
/// &c,
/// &[
/// Token::TupleVariant {
/// name: "E",
/// variant: "C",
/// len: 2,
/// },
/// Token::U8(0),
/// Token::U8(0),
/// Token::TupleVariantEnd,
/// ],
/// );
/// # }
/// ```
TupleVariant {
@@ -372,7 +397,7 @@ pub enum Token {
///
/// After this header are the entries of the map, followed by `MapEnd`.
///
/// ```edition2018
/// ```edition2021
/// # use serde_test::{assert_tokens, Token};
/// #
/// use std::collections::BTreeMap;
@@ -381,14 +406,17 @@ pub enum Token {
/// map.insert('A', 65);
/// map.insert('Z', 90);
///
/// assert_tokens(&map, &[
/// Token::Map { len: Some(2) },
/// Token::Char('A'),
/// Token::I32(65),
/// Token::Char('Z'),
/// Token::I32(90),
/// Token::MapEnd,
/// ]);
/// assert_tokens(
/// &map,
/// &[
/// Token::Map { len: Some(2) },
/// Token::Char('A'),
/// Token::I32(65),
/// Token::Char('Z'),
/// Token::I32(90),
/// Token::MapEnd,
/// ],
/// );
/// ```
Map { len: Option<usize> },
@@ -399,8 +427,8 @@ pub enum Token {
///
/// After this header are the fields of the struct, followed by `StructEnd`.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
@@ -411,14 +439,17 @@ pub enum Token {
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_tokens(&s, &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ]);
/// assert_tokens(
/// &s,
/// &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ],
/// );
/// # }
/// ```
Struct { name: &'static str, len: usize },
@@ -431,8 +462,8 @@ pub enum Token {
/// After this header are the fields of the struct variant, followed by
/// `StructVariantEnd`.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
@@ -442,12 +473,19 @@ pub enum Token {
/// }
///
/// let d = E::D { d: 0 };
/// assert_tokens(&d, &[
/// Token::StructVariant { name: "E", variant: "D", len: 1 },
/// Token::Str("d"),
/// Token::U8(0),
/// Token::StructVariantEnd,
/// ]);
/// assert_tokens(
/// &d,
/// &[
/// Token::StructVariant {
/// name: "E",
/// variant: "D",
/// len: 1,
/// },
/// Token::Str("d"),
/// Token::U8(0),
/// Token::StructVariantEnd,
/// ],
/// );
/// # }
/// ```
StructVariant {
@@ -461,8 +499,8 @@ pub enum Token {
/// The header to an enum of the given name.
///
/// ```edition2018
/// # use serde::{Serialize, Deserialize};
/// ```edition2021
/// # use serde_derive::{Deserialize, Serialize};
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
@@ -475,38 +513,42 @@ pub enum Token {
/// }
///
/// let a = E::A;
/// assert_tokens(&a, &[
/// Token::Enum { name: "E" },
/// Token::Str("A"),
/// Token::Unit,
/// ]);
/// assert_tokens(
/// &a,
/// &[Token::Enum { name: "E" }, Token::Str("A"), Token::Unit],
/// );
///
/// let b = E::B(0);
/// assert_tokens(&b, &[
/// Token::Enum { name: "E" },
/// Token::Str("B"),
/// Token::U8(0),
/// ]);
/// assert_tokens(
/// &b,
/// &[Token::Enum { name: "E" }, Token::Str("B"), Token::U8(0)],
/// );
///
/// let c = E::C(0, 0);
/// assert_tokens(&c, &[
/// Token::Enum { name: "E" },
/// Token::Str("C"),
/// Token::Seq { len: Some(2) },
/// Token::U8(0),
/// Token::U8(0),
/// Token::SeqEnd,
/// ]);
/// assert_tokens(
/// &c,
/// &[
/// Token::Enum { name: "E" },
/// Token::Str("C"),
/// Token::Seq { len: Some(2) },
/// Token::U8(0),
/// Token::U8(0),
/// Token::SeqEnd,
/// ],
/// );
///
/// let d = E::D { d: 0 };
/// assert_tokens(&d, &[
/// Token::Enum { name: "E" },
/// Token::Str("D"),
/// Token::Map { len: Some(1) },
/// Token::Str("d"),
/// Token::U8(0),
/// Token::MapEnd,
/// ]);
/// assert_tokens(
/// &d,
/// &[
/// Token::Enum { name: "E" },
/// Token::Str("D"),
/// Token::Map { len: Some(1) },
/// Token::Str("d"),
/// Token::U8(0),
/// Token::MapEnd,
/// ],
/// );
/// # }
/// ```
Enum { name: &'static str },
+3 -8
View File
@@ -4,23 +4,18 @@ version = "0.0.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
edition = "2018"
publish = false
build = "build.rs"
[features]
expandtest = []
unstable = ["serde/unstable"]
[dependencies]
serde = { path = "../serde" }
[build-dependencies]
toolchain_find = "0.1"
[dev-dependencies]
automod = "1.0.1"
fnv = "1.0"
macrotest = "=1.0.0"
rustversion = "1.0"
serde = { path = "../serde", features = ["rc", "derive"] }
serde = { path = "../serde", features = ["rc"] }
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
serde_test = { path = "../serde_test" }
trybuild = { version = "1.0.19", features = ["diff"] }
trybuild = { version = "1.0.66", features = ["diff"] }
-29
View File
@@ -1,29 +0,0 @@
use std::process::{Command, ExitStatus, Stdio};
fn has_cargo_expand() -> bool {
let cargo_expand = if cfg!(windows) {
"cargo-expand.exe"
} else {
"cargo-expand"
};
Command::new(cargo_expand)
.arg("--version")
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.as_ref()
.map(ExitStatus::success)
.unwrap_or(false)
}
fn has_rustfmt() -> bool {
toolchain_find::find_installed_component("rustfmt").is_some()
}
fn main() {
if cfg!(feature = "expandtest") && has_cargo_expand() && has_rustfmt() {
println!("cargo:rustc-cfg=expandtest");
}
}
+3 -1
View File
@@ -1,11 +1,13 @@
[package]
name = "serde_derive_tests_no_std"
version = "0.0.0"
authors = ["David Tolnay <dtolnay@gmail.com>"]
edition = "2018"
publish = false
[dependencies]
libc = { version = "0.2", default-features = false }
serde = { path = "../../serde", default-features = false, features = ["derive"] }
serde = { path = "../../serde", default-features = false }
serde_derive = { path = "../../serde_derive" }
[workspace]
+1 -1
View File
@@ -19,7 +19,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
//////////////////////////////////////////////////////////////////////////////
use serde::{Serialize, Deserialize};
use serde_derive::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
struct Unit;
+2
View File
@@ -1,5 +1,7 @@
#[cfg_attr(target_os = "emscripten", ignore)]
#[rustversion::attr(not(nightly), ignore)]
#[cfg_attr(miri, ignore)]
#[allow(unused_attributes)]
#[test]
fn ui() {
let t = trybuild::TestCases::new();
File diff suppressed because it is too large Load Diff
-13
View File
@@ -1,13 +0,0 @@
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
enum DeEnum<B, C, D> {
Unit,
Seq(i8, B, C, D),
Map { a: i8, b: B, c: C, d: D },
// Make sure we can support more than one variant.
_Unit2,
_Seq2(i8, B, C, D),
_Map2 { a: i8, b: B, c: C, d: D },
}
@@ -1,416 +0,0 @@
use serde::{Deserialize, Serialize};
trait AssociatedType {
type X;
}
impl AssociatedType for i32 {
type X = i32;
}
struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
phantom: PhantomData<T>,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
#[allow(rust_2018_idioms, clippy::useless_attribute)]
extern crate serde as _serde;
#[automatically_derived]
impl<T: AssociatedType<X = i32>> _serde::Serialize for DefaultTyParam<T> {
fn serialize<__S>(
&self,
__serializer: __S,
) -> _serde::__private::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
{
let mut __serde_state = match _serde::Serializer::serialize_struct(
__serializer,
"DefaultTyParam",
false as usize + 1,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
match _serde::ser::SerializeStruct::serialize_field(
&mut __serde_state,
"phantom",
&self.phantom,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
_serde::ser::SerializeStruct::end(__serde_state)
}
}
};
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
#[allow(rust_2018_idioms, clippy::useless_attribute)]
extern crate serde as _serde;
#[automatically_derived]
impl<'de, T: AssociatedType<X = i32>> _serde::Deserialize<'de> for DefaultTyParam<T> {
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"phantom" => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"phantom" => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de, T: AssociatedType<X = i32>> {
marker: _serde::__private::PhantomData<DefaultTyParam<T>>,
lifetime: _serde::__private::PhantomData<&'de ()>,
}
impl<'de, T: AssociatedType<X = i32>> _serde::de::Visitor<'de> for __Visitor<'de, T> {
type Value = DefaultTyParam<T>;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter, "struct DefaultTyParam")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<PhantomData<T>>(
&mut __seq,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
_serde::__private::Some(__value) => __value,
_serde::__private::None => {
return _serde::__private::Err(_serde::de::Error::invalid_length(
0usize,
&"struct DefaultTyParam with 1 element",
));
}
};
_serde::__private::Ok(DefaultTyParam { phantom: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::__private::Option<PhantomData<T>> =
_serde::__private::None;
while let _serde::__private::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::__private::Option::is_some(&__field0) {
return _serde::__private::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"phantom",
),
);
}
__field0 = _serde::__private::Some(
match _serde::de::MapAccess::next_value::<PhantomData<T>>(
&mut __map,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::__private::Some(__field0) => __field0,
_serde::__private::None => {
match _serde::__private::de::missing_field("phantom") {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
}
}
};
_serde::__private::Ok(DefaultTyParam { phantom: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["phantom"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"DefaultTyParam",
FIELDS,
__Visitor {
marker: _serde::__private::PhantomData::<DefaultTyParam<T>>,
lifetime: _serde::__private::PhantomData,
},
)
}
fn deserialize_in_place<__D>(
__deserializer: __D,
__place: &mut Self,
) -> _serde::__private::Result<(), __D::Error>
where
__D: _serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"phantom" => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"phantom" => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de, 'place, T: AssociatedType<X = i32> + 'place> {
place: &'place mut DefaultTyParam<T>,
lifetime: _serde::__private::PhantomData<&'de ()>,
}
impl<'de, 'place, T: AssociatedType<X = i32> + 'place> _serde::de::Visitor<'de>
for __Visitor<'de, 'place, T>
{
type Value = ();
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter, "struct DefaultTyParam")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
&mut __seq,
_serde::__private::de::InPlaceSeed(&mut self.place.phantom),
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
return _serde::__private::Err(_serde::de::Error::invalid_length(
0usize,
&"struct DefaultTyParam with 1 element",
));
}
_serde::__private::Ok(())
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: bool = false;
while let _serde::__private::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if __field0 {
return _serde::__private::Err(
<__A::Error as _serde::de::Error>::duplicate_field(
"phantom",
),
);
}
match _serde::de::MapAccess::next_value_seed(
&mut __map,
_serde::__private::de::InPlaceSeed(&mut self.place.phantom),
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
__field0 = true;
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
}
}
}
if !__field0 {
self.place.phantom = match _serde::__private::de::missing_field("phantom") {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
};
_serde::__private::Ok(())
}
}
const FIELDS: &'static [&'static str] = &["phantom"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"DefaultTyParam",
FIELDS,
__Visitor {
place: __place,
lifetime: _serde::__private::PhantomData,
},
)
}
}
};
@@ -1,14 +0,0 @@
use serde::{Deserialize, Serialize};
trait AssociatedType {
type X;
}
impl AssociatedType for i32 {
type X = i32;
}
#[derive(Serialize, Deserialize)]
struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
phantom: PhantomData<T>,
}
@@ -1,595 +0,0 @@
use serde::{Deserialize, Serialize};
pub enum GenericEnum<T, U> {
Unit,
NewType(T),
Seq(T, U),
Map { x: T, y: U },
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
#[allow(rust_2018_idioms, clippy::useless_attribute)]
extern crate serde as _serde;
#[automatically_derived]
impl<T, U> _serde::Serialize for GenericEnum<T, U>
where
T: _serde::Serialize,
U: _serde::Serialize,
{
fn serialize<__S>(
&self,
__serializer: __S,
) -> _serde::__private::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
{
match *self {
GenericEnum::Unit => _serde::Serializer::serialize_unit_variant(
__serializer,
"GenericEnum",
0u32,
"Unit",
),
GenericEnum::NewType(ref __field0) => {
_serde::Serializer::serialize_newtype_variant(
__serializer,
"GenericEnum",
1u32,
"NewType",
__field0,
)
}
GenericEnum::Seq(ref __field0, ref __field1) => {
let mut __serde_state = match _serde::Serializer::serialize_tuple_variant(
__serializer,
"GenericEnum",
2u32,
"Seq",
0 + 1 + 1,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
match _serde::ser::SerializeTupleVariant::serialize_field(
&mut __serde_state,
__field0,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
match _serde::ser::SerializeTupleVariant::serialize_field(
&mut __serde_state,
__field1,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
_serde::ser::SerializeTupleVariant::end(__serde_state)
}
GenericEnum::Map { ref x, ref y } => {
let mut __serde_state = match _serde::Serializer::serialize_struct_variant(
__serializer,
"GenericEnum",
3u32,
"Map",
0 + 1 + 1,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
match _serde::ser::SerializeStructVariant::serialize_field(
&mut __serde_state,
"x",
x,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
match _serde::ser::SerializeStructVariant::serialize_field(
&mut __serde_state,
"y",
y,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
_serde::ser::SerializeStructVariant::end(__serde_state)
}
}
}
}
};
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
#[allow(rust_2018_idioms, clippy::useless_attribute)]
extern crate serde as _serde;
#[automatically_derived]
impl<'de, T, U> _serde::Deserialize<'de> for GenericEnum<T, U>
where
T: _serde::Deserialize<'de>,
U: _serde::Deserialize<'de>,
{
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__field1,
__field2,
__field3,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter, "variant identifier")
}
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::__private::Ok(__Field::__field0),
1u64 => _serde::__private::Ok(__Field::__field1),
2u64 => _serde::__private::Ok(__Field::__field2),
3u64 => _serde::__private::Ok(__Field::__field3),
_ => _serde::__private::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"variant index 0 <= i < 4",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"Unit" => _serde::__private::Ok(__Field::__field0),
"NewType" => _serde::__private::Ok(__Field::__field1),
"Seq" => _serde::__private::Ok(__Field::__field2),
"Map" => _serde::__private::Ok(__Field::__field3),
_ => _serde::__private::Err(_serde::de::Error::unknown_variant(
__value, VARIANTS,
)),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"Unit" => _serde::__private::Ok(__Field::__field0),
b"NewType" => _serde::__private::Ok(__Field::__field1),
b"Seq" => _serde::__private::Ok(__Field::__field2),
b"Map" => _serde::__private::Ok(__Field::__field3),
_ => {
let __value = &_serde::__private::from_utf8_lossy(__value);
_serde::__private::Err(_serde::de::Error::unknown_variant(
__value, VARIANTS,
))
}
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de, T, U>
where
T: _serde::Deserialize<'de>,
U: _serde::Deserialize<'de>,
{
marker: _serde::__private::PhantomData<GenericEnum<T, U>>,
lifetime: _serde::__private::PhantomData<&'de ()>,
}
impl<'de, T, U> _serde::de::Visitor<'de> for __Visitor<'de, T, U>
where
T: _serde::Deserialize<'de>,
U: _serde::Deserialize<'de>,
{
type Value = GenericEnum<T, U>;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter, "enum GenericEnum")
}
fn visit_enum<__A>(
self,
__data: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::EnumAccess<'de>,
{
match match _serde::de::EnumAccess::variant(__data) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
(__Field::__field0, __variant) => {
match _serde::de::VariantAccess::unit_variant(__variant) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
_serde::__private::Ok(GenericEnum::Unit)
}
(__Field::__field1, __variant) => _serde::__private::Result::map(
_serde::de::VariantAccess::newtype_variant::<T>(__variant),
GenericEnum::NewType,
),
(__Field::__field2, __variant) => {
struct __Visitor<'de, T, U>
where
T: _serde::Deserialize<'de>,
U: _serde::Deserialize<'de>,
{
marker: _serde::__private::PhantomData<GenericEnum<T, U>>,
lifetime: _serde::__private::PhantomData<&'de ()>,
}
impl<'de, T, U> _serde::de::Visitor<'de> for __Visitor<'de, T, U>
where
T: _serde::Deserialize<'de>,
U: _serde::Deserialize<'de>,
{
type Value = GenericEnum<T, U>;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result
{
_serde::__private::Formatter::write_str(
__formatter,
"tuple variant GenericEnum::Seq",
)
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<
T,
>(
&mut __seq
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
_serde::__private::Some(__value) => __value,
_serde::__private::None => {
return _serde :: __private :: Err (_serde :: de :: Error :: invalid_length (0usize , & "tuple variant GenericEnum::Seq with 2 elements")) ;
}
};
let __field1 = match match _serde::de::SeqAccess::next_element::<
U,
>(
&mut __seq
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
_serde::__private::Some(__value) => __value,
_serde::__private::None => {
return _serde :: __private :: Err (_serde :: de :: Error :: invalid_length (1usize , & "tuple variant GenericEnum::Seq with 2 elements")) ;
}
};
_serde::__private::Ok(GenericEnum::Seq(__field0, __field1))
}
}
_serde::de::VariantAccess::tuple_variant(
__variant,
2usize,
__Visitor {
marker: _serde::__private::PhantomData::<GenericEnum<T, U>>,
lifetime: _serde::__private::PhantomData,
},
)
}
(__Field::__field3, __variant) => {
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__field1,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result
{
_serde::__private::Formatter::write_str(
__formatter,
"field identifier",
)
}
fn visit_u64<__E>(
self,
__value: u64,
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::__private::Ok(__Field::__field0),
1u64 => _serde::__private::Ok(__Field::__field1),
_ => _serde::__private::Err(
_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 2",
),
),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"x" => _serde::__private::Ok(__Field::__field0),
"y" => _serde::__private::Ok(__Field::__field1),
_ => _serde::__private::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"x" => _serde::__private::Ok(__Field::__field0),
b"y" => _serde::__private::Ok(__Field::__field1),
_ => _serde::__private::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(
__deserializer,
__FieldVisitor,
)
}
}
struct __Visitor<'de, T, U>
where
T: _serde::Deserialize<'de>,
U: _serde::Deserialize<'de>,
{
marker: _serde::__private::PhantomData<GenericEnum<T, U>>,
lifetime: _serde::__private::PhantomData<&'de ()>,
}
impl<'de, T, U> _serde::de::Visitor<'de> for __Visitor<'de, T, U>
where
T: _serde::Deserialize<'de>,
U: _serde::Deserialize<'de>,
{
type Value = GenericEnum<T, U>;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result
{
_serde::__private::Formatter::write_str(
__formatter,
"struct variant GenericEnum::Map",
)
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<
T,
>(
&mut __seq
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
_serde::__private::Some(__value) => __value,
_serde::__private::None => {
return _serde :: __private :: Err (_serde :: de :: Error :: invalid_length (0usize , & "struct variant GenericEnum::Map with 2 elements")) ;
}
};
let __field1 = match match _serde::de::SeqAccess::next_element::<
U,
>(
&mut __seq
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
_serde::__private::Some(__value) => __value,
_serde::__private::None => {
return _serde :: __private :: Err (_serde :: de :: Error :: invalid_length (1usize , & "struct variant GenericEnum::Map with 2 elements")) ;
}
};
_serde::__private::Ok(GenericEnum::Map {
x: __field0,
y: __field1,
})
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::__private::Option<T> =
_serde::__private::None;
let mut __field1: _serde::__private::Option<U> =
_serde::__private::None;
while let _serde::__private::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map)
{
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::__private::Option::is_some(&__field0) {
return _serde :: __private :: Err (< __A :: Error as _serde :: de :: Error > :: duplicate_field ("x")) ;
}
__field0 = _serde::__private::Some(
match _serde::de::MapAccess::next_value::<T>(
&mut __map,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
},
);
}
__Field::__field1 => {
if _serde::__private::Option::is_some(&__field1) {
return _serde :: __private :: Err (< __A :: Error as _serde :: de :: Error > :: duplicate_field ("y")) ;
}
__field1 = _serde::__private::Some(
match _serde::de::MapAccess::next_value::<U>(
&mut __map,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(
&mut __map
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::__private::Some(__field0) => __field0,
_serde::__private::None => {
match _serde::__private::de::missing_field("x") {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
}
}
};
let __field1 = match __field1 {
_serde::__private::Some(__field1) => __field1,
_serde::__private::None => {
match _serde::__private::de::missing_field("y") {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
}
}
};
_serde::__private::Ok(GenericEnum::Map {
x: __field0,
y: __field1,
})
}
}
const FIELDS: &'static [&'static str] = &["x", "y"];
_serde::de::VariantAccess::struct_variant(
__variant,
FIELDS,
__Visitor {
marker: _serde::__private::PhantomData::<GenericEnum<T, U>>,
lifetime: _serde::__private::PhantomData,
},
)
}
}
}
}
const VARIANTS: &'static [&'static str] = &["Unit", "NewType", "Seq", "Map"];
_serde::Deserializer::deserialize_enum(
__deserializer,
"GenericEnum",
VARIANTS,
__Visitor {
marker: _serde::__private::PhantomData::<GenericEnum<T, U>>,
lifetime: _serde::__private::PhantomData,
},
)
}
}
};
-9
View File
@@ -1,9 +0,0 @@
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize)]
pub enum GenericEnum<T, U> {
Unit,
NewType(T),
Seq(T, U),
Map { x: T, y: U },
}
@@ -1,600 +0,0 @@
use serde::{Deserialize, Serialize};
pub struct GenericStruct<T> {
x: T,
}
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
#[allow(rust_2018_idioms, clippy::useless_attribute)]
extern crate serde as _serde;
#[automatically_derived]
impl<T> _serde::Serialize for GenericStruct<T>
where
T: _serde::Serialize,
{
fn serialize<__S>(
&self,
__serializer: __S,
) -> _serde::__private::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
{
let mut __serde_state = match _serde::Serializer::serialize_struct(
__serializer,
"GenericStruct",
false as usize + 1,
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
match _serde::ser::SerializeStruct::serialize_field(&mut __serde_state, "x", &self.x) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
_serde::ser::SerializeStruct::end(__serde_state)
}
}
};
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
#[allow(rust_2018_idioms, clippy::useless_attribute)]
extern crate serde as _serde;
#[automatically_derived]
impl<'de, T> _serde::Deserialize<'de> for GenericStruct<T>
where
T: _serde::Deserialize<'de>,
{
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"x" => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"x" => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de, T>
where
T: _serde::Deserialize<'de>,
{
marker: _serde::__private::PhantomData<GenericStruct<T>>,
lifetime: _serde::__private::PhantomData<&'de ()>,
}
impl<'de, T> _serde::de::Visitor<'de> for __Visitor<'de, T>
where
T: _serde::Deserialize<'de>,
{
type Value = GenericStruct<T>;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter, "struct GenericStruct")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<T>(&mut __seq)
{
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
_serde::__private::Some(__value) => __value,
_serde::__private::None => {
return _serde::__private::Err(_serde::de::Error::invalid_length(
0usize,
&"struct GenericStruct with 1 element",
));
}
};
_serde::__private::Ok(GenericStruct { x: __field0 })
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: _serde::__private::Option<T> = _serde::__private::None;
while let _serde::__private::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if _serde::__private::Option::is_some(&__field0) {
return _serde::__private::Err(
<__A::Error as _serde::de::Error>::duplicate_field("x"),
);
}
__field0 = _serde::__private::Some(
match _serde::de::MapAccess::next_value::<T>(&mut __map) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
},
);
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
}
}
}
let __field0 = match __field0 {
_serde::__private::Some(__field0) => __field0,
_serde::__private::None => {
match _serde::__private::de::missing_field("x") {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
}
}
};
_serde::__private::Ok(GenericStruct { x: __field0 })
}
}
const FIELDS: &'static [&'static str] = &["x"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"GenericStruct",
FIELDS,
__Visitor {
marker: _serde::__private::PhantomData::<GenericStruct<T>>,
lifetime: _serde::__private::PhantomData,
},
)
}
fn deserialize_in_place<__D>(
__deserializer: __D,
__place: &mut Self,
) -> _serde::__private::Result<(), __D::Error>
where
__D: _serde::Deserializer<'de>,
{
#[allow(non_camel_case_types)]
enum __Field {
__field0,
__ignore,
}
struct __FieldVisitor;
impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
type Value = __Field;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter, "field identifier")
}
fn visit_u64<__E>(self, __value: u64) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
0u64 => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value),
&"field index 0 <= i < 1",
)),
}
}
fn visit_str<__E>(
self,
__value: &str,
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
"x" => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Ok(__Field::__ignore),
}
}
fn visit_bytes<__E>(
self,
__value: &[u8],
) -> _serde::__private::Result<Self::Value, __E>
where
__E: _serde::de::Error,
{
match __value {
b"x" => _serde::__private::Ok(__Field::__field0),
_ => _serde::__private::Ok(__Field::__ignore),
}
}
}
impl<'de> _serde::Deserialize<'de> for __Field {
#[inline]
fn deserialize<__D>(
__deserializer: __D,
) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
_serde::Deserializer::deserialize_identifier(__deserializer, __FieldVisitor)
}
}
struct __Visitor<'de, 'place, T: 'place>
where
T: _serde::Deserialize<'de>,
{
place: &'place mut GenericStruct<T>,
lifetime: _serde::__private::PhantomData<&'de ()>,
}
impl<'de, 'place, T: 'place> _serde::de::Visitor<'de> for __Visitor<'de, 'place, T>
where
T: _serde::Deserialize<'de>,
{
type Value = ();
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(__formatter, "struct GenericStruct")
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
&mut __seq,
_serde::__private::de::InPlaceSeed(&mut self.place.x),
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
return _serde::__private::Err(_serde::de::Error::invalid_length(
0usize,
&"struct GenericStruct with 1 element",
));
}
_serde::__private::Ok(())
}
#[inline]
fn visit_map<__A>(
self,
mut __map: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::MapAccess<'de>,
{
let mut __field0: bool = false;
while let _serde::__private::Some(__key) =
match _serde::de::MapAccess::next_key::<__Field>(&mut __map) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
}
{
match __key {
__Field::__field0 => {
if __field0 {
return _serde::__private::Err(
<__A::Error as _serde::de::Error>::duplicate_field("x"),
);
}
match _serde::de::MapAccess::next_value_seed(
&mut __map,
_serde::__private::de::InPlaceSeed(&mut self.place.x),
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
__field0 = true;
}
_ => {
let _ = match _serde::de::MapAccess::next_value::<
_serde::de::IgnoredAny,
>(&mut __map)
{
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
}
}
}
if !__field0 {
self.place.x = match _serde::__private::de::missing_field("x") {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
};
_serde::__private::Ok(())
}
}
const FIELDS: &'static [&'static str] = &["x"];
_serde::Deserializer::deserialize_struct(
__deserializer,
"GenericStruct",
FIELDS,
__Visitor {
place: __place,
lifetime: _serde::__private::PhantomData,
},
)
}
}
};
pub struct GenericNewTypeStruct<T>(T);
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
#[allow(rust_2018_idioms, clippy::useless_attribute)]
extern crate serde as _serde;
#[automatically_derived]
impl<T> _serde::Serialize for GenericNewTypeStruct<T>
where
T: _serde::Serialize,
{
fn serialize<__S>(
&self,
__serializer: __S,
) -> _serde::__private::Result<__S::Ok, __S::Error>
where
__S: _serde::Serializer,
{
_serde::Serializer::serialize_newtype_struct(
__serializer,
"GenericNewTypeStruct",
&self.0,
)
}
}
};
#[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const _: () = {
#[allow(rust_2018_idioms, clippy::useless_attribute)]
extern crate serde as _serde;
#[automatically_derived]
impl<'de, T> _serde::Deserialize<'de> for GenericNewTypeStruct<T>
where
T: _serde::Deserialize<'de>,
{
fn deserialize<__D>(__deserializer: __D) -> _serde::__private::Result<Self, __D::Error>
where
__D: _serde::Deserializer<'de>,
{
struct __Visitor<'de, T>
where
T: _serde::Deserialize<'de>,
{
marker: _serde::__private::PhantomData<GenericNewTypeStruct<T>>,
lifetime: _serde::__private::PhantomData<&'de ()>,
}
impl<'de, T> _serde::de::Visitor<'de> for __Visitor<'de, T>
where
T: _serde::Deserialize<'de>,
{
type Value = GenericNewTypeStruct<T>;
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(
__formatter,
"tuple struct GenericNewTypeStruct",
)
}
#[inline]
fn visit_newtype_struct<__E>(
self,
__e: __E,
) -> _serde::__private::Result<Self::Value, __E::Error>
where
__E: _serde::Deserializer<'de>,
{
let __field0: T = match <T as _serde::Deserialize>::deserialize(__e) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
};
_serde::__private::Ok(GenericNewTypeStruct(__field0))
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
let __field0 = match match _serde::de::SeqAccess::next_element::<T>(&mut __seq)
{
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
_serde::__private::Some(__value) => __value,
_serde::__private::None => {
return _serde::__private::Err(_serde::de::Error::invalid_length(
0usize,
&"tuple struct GenericNewTypeStruct with 1 element",
));
}
};
_serde::__private::Ok(GenericNewTypeStruct(__field0))
}
}
_serde::Deserializer::deserialize_newtype_struct(
__deserializer,
"GenericNewTypeStruct",
__Visitor {
marker: _serde::__private::PhantomData::<GenericNewTypeStruct<T>>,
lifetime: _serde::__private::PhantomData,
},
)
}
fn deserialize_in_place<__D>(
__deserializer: __D,
__place: &mut Self,
) -> _serde::__private::Result<(), __D::Error>
where
__D: _serde::Deserializer<'de>,
{
struct __Visitor<'de, 'place, T: 'place>
where
T: _serde::Deserialize<'de>,
{
place: &'place mut GenericNewTypeStruct<T>,
lifetime: _serde::__private::PhantomData<&'de ()>,
}
impl<'de, 'place, T: 'place> _serde::de::Visitor<'de> for __Visitor<'de, 'place, T>
where
T: _serde::Deserialize<'de>,
{
type Value = ();
fn expecting(
&self,
__formatter: &mut _serde::__private::Formatter,
) -> _serde::__private::fmt::Result {
_serde::__private::Formatter::write_str(
__formatter,
"tuple struct GenericNewTypeStruct",
)
}
#[inline]
fn visit_newtype_struct<__E>(
self,
__e: __E,
) -> _serde::__private::Result<Self::Value, __E::Error>
where
__E: _serde::Deserializer<'de>,
{
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
}
#[inline]
fn visit_seq<__A>(
self,
mut __seq: __A,
) -> _serde::__private::Result<Self::Value, __A::Error>
where
__A: _serde::de::SeqAccess<'de>,
{
if let _serde::__private::None = match _serde::de::SeqAccess::next_element_seed(
&mut __seq,
_serde::__private::de::InPlaceSeed(&mut self.place.0),
) {
_serde::__private::Ok(__val) => __val,
_serde::__private::Err(__err) => {
return _serde::__private::Err(__err);
}
} {
return _serde::__private::Err(_serde::de::Error::invalid_length(
0usize,
&"tuple struct GenericNewTypeStruct with 1 element",
));
}
_serde::__private::Ok(())
}
}
_serde::Deserializer::deserialize_newtype_struct(
__deserializer,
"GenericNewTypeStruct",
__Visitor {
place: __place,
lifetime: _serde::__private::PhantomData,
},
)
}
}
};

Some files were not shown because too many files have changed in this diff Show More