Compare commits

...

186 Commits

Author SHA1 Message Date
David Tolnay e1edb0282a Release 1.0.81 2018-12-07 18:30:35 -08:00
David Tolnay 5484f69164 Merge pull request #1438 from daboross/fix-untagged-enum-integer-variant-encoding
Accept integers variant encoding in Content
2018-12-07 18:17:53 -08:00
David Ross cf1e0825c1 Support only u8 for enum identifiers within Content. 2018-12-05 17:01:48 -08:00
David Ross 86faa44915 Support only u8,u32 for enum variant identifiers in Content.
u8 correctly supports msgpack-rust, and u32 supports bincode and
presumably all other similar binary formats.
2018-12-05 15:59:47 -08:00
David Ross a0b23cbf02 Accept integers variant encoding in Content
This allows ContentDeserializer and ContentRefDeserializer to
deserialize unsigned integers in deserialize_identifier, and
furthermore allows enums inside untagged enums to be correctly decoded
in formats which encode the enum variant as an integer.

Fixes https://github.com/serde-rs/serde/issues/1437.
2018-12-04 19:40:27 -08:00
David Tolnay e8ffb22c0d Merge pull request #1424 from hcpl/spanned-error-messages
Use more spans for error messages
2018-12-01 23:16:49 -08:00
David Tolnay 4d04ae0111 Sync links from serde.rs website 2018-12-01 13:01:48 -08:00
hcpl 14a3da9b16 Improve UI test coverage
With this commit I believe I've covered all `compile_error!`-based
errors.
2018-11-30 03:07:31 +02:00
hcpl 034db9f20f Improve overall quality of compile_error! errors
Also updates UI tests.
2018-11-30 02:51:49 +02:00
hcpl 8f3f073017 Use more spans for error messages 2018-11-25 16:44:41 +02:00
David Tolnay 58b3af4c29 Copyright/license headers
The following changes are included:

- Delete per-file license notices at the top of each file.
- Delete the first paragraph of LICENSE-MIT (an inaccurate
  pseudo-copyright line), leaving only the text of the MIT license.

Nothing about the license of Serde code has changed, only our
understanding of how to correctly communicate that license has changed.

This mirrors an equivalent change being applied in the rust-lang/rust
repository.
2018-11-24 15:53:09 -08:00
David Tolnay 4821d09a48 Move all compile-fail tests to ui tests
The update-references.sh script makes these much easier to update in
bulk compared to compile-fail tests.
2018-11-24 15:43:19 -08:00
David Tolnay b3d9d51b51 Simplify compiletest setup 2018-11-24 15:35:49 -08:00
David Tolnay 6b33abb179 Set up Travis build names 2018-11-24 15:12:48 -08:00
David Tolnay a043b2a763 Point serde_derive_internals documentation to docs.rs 2018-11-21 14:22:33 -08:00
David Tolnay 0c3d4a8a37 Release serde_derive_internals 0.24.0 2018-11-21 14:17:55 -08:00
David Tolnay 9afc5fef11 Format with rustfmt 1.0.0-nightly 2018-11-21 01:13:17 -08:00
David Tolnay a8a54c0568 Remove 1.26-dev docs.rs workaround
They are now building with 1.31.0-nightly.
2018-11-11 12:13:25 -08:00
David Tolnay 451ee2d78e Clean up calls to into_iter per into_iter_on_ref lint 2018-11-10 20:10:37 -08:00
David Tolnay 820107d15e Move emscripten CI to allow_failures
Not sure what is going on with this failure that just started happening with no
code change on our end. Wait and see if it goes away.

On asmjs-unknown-emscripten:

    Assertion failed: compiled without a main, but one is present. if you added
    it from JS, use Module["onRuntimeInitialized"]

    undefined:109
        throw ex;
        ^

    abort("Assertion failed: compiled without a main, but one is present. if you
    added it from JS, use Module[\"onRuntimeInitialized\"]") at Error

On wasm32-unknown-emscripten:

    Assertion failed: compiled without a main, but one is present. if you added
    it from JS, use Module["onRuntimeInitialized"]

    failed to asynchronously prepare wasm: abort("Assertion failed: compiled
    without a main, but one is present. if you added it from JS, use
    Module[\"onRuntimeInitialized\"]") at Error
2018-11-10 20:06:18 -08:00
David Tolnay a51f831ae4 Drop nightly dependency of compiletest 2018-10-27 23:59:48 -07:00
David Tolnay 1b45e5766a Release 1.0.80 2018-10-14 03:08:53 -07:00
David Tolnay 59c8951341 Merge pull request #1411 from dtolnay/vec
Optimize Vec::deserialize_in_place to deserialize elements in place
2018-10-14 03:08:04 -07:00
David Tolnay aca61b5dda Optimize Vec::deserialize_in_place to deserialize elements in place 2018-10-14 02:51:24 -07:00
David Tolnay 908affd24f Remove unused code in seq and map impls 2018-10-14 02:31:56 -07:00
David Tolnay f878d2ebd5 Do not require clippy for a green build 2018-10-06 21:26:25 -07:00
David Tolnay 778e516270 Feature panic_handler has been stabilized 2018-10-06 21:12:14 -07:00
David Tolnay 6d58492ad0 Fix links to redirected derive documentation 2018-10-03 23:14:49 -07:00
David Tolnay fecfabb168 Merge pull request #1399 from derekdreery/more_docs
Some docs
2018-09-30 08:16:24 -07:00
Richard Dodd 80765eb453 Make suggested changes 2018-09-30 15:17:47 +01:00
Richard Dodd f1073dca04 Make the recommended changed from code review. 2018-09-30 12:34:52 +01:00
Richard Dodd da65fe5a52 Some docs 2018-09-29 15:06:23 +01:00
David Tolnay 3f0f739e17 Merge pull request #1391 from dtolnay/ci
Move CI commands into travis.yml and appveyor.yml
2018-09-15 17:00:27 -07:00
David Tolnay 5023e2ad52 Fix escaping issues in emscripten CI commands 2018-09-15 16:37:46 -07:00
David Tolnay 810cde1c84 Split travis builds into individual steps 2018-09-15 16:15:59 -07:00
David Tolnay 9436efb80e Move CI commands into travis.yml and appveyor.yml 2018-09-15 16:04:57 -07:00
David Tolnay 48230890c5 Merge pull request #1390 from dtolnay/asmjs
Run test suite on asmjs
2018-09-15 15:50:11 -07:00
David Tolnay f1e8dcf38e Run test suite on asmjs 2018-09-15 15:25:55 -07:00
David Tolnay 2cf10a6003 Remove separate proc-macro2/nightly build
This feature is automatically enabled on sufficiently new compilers.
2018-09-15 15:25:19 -07:00
David Tolnay 23a53d8008 Remove unused proc-macro2 dependency in test suite 2018-09-15 15:12:47 -07:00
David Tolnay 9956589ed5 Release 1.0.79 2018-09-15 14:40:38 -07:00
David Tolnay 81a3f66d78 Ignore unseparated_literal_suffix pedantic lint 2018-09-11 23:08:13 -07:00
David Tolnay a8247bc619 Sort the ignored lints in serde_derive 2018-09-11 23:08:00 -07:00
David Tolnay 66a9ccb10e Ignore renamed_and_removed_lints lint
The recommended replacement involving clippy::all has not been
stabilized yet.
2018-09-11 23:05:33 -07:00
David Tolnay 53fe1b328e Format with rustfmt 0.99.4 2018-09-11 23:00:08 -07:00
David Tolnay 2753ec757b Merge pull request #1382 from roblabla/serde-other
Implement #[serde(other)] on enum variant
2018-09-11 22:59:30 -07:00
roblabla dcd2232f69 Enforce unit struct for #[serde(other)] 2018-09-11 17:12:37 +00:00
roblabla 0156f1355a Remove obsolete compile-fail test 2018-09-10 17:15:22 +00:00
roblabla 61bf901048 Fix for rust 1.15 2018-09-10 17:12:33 +00:00
roblabla 7870b58356 Add tests for serde(other) in enum 2018-09-10 16:25:02 +00:00
roblabla 8cc7e6aa90 Implement #serde(other) on enum variant 2018-09-10 15:12:15 +00:00
David Tolnay 7b50388fef Release 1.0.78 2018-09-08 17:10:41 -07:00
David Tolnay e704990322 Merge pull request #1380 from dtolnay/f
Fix panic deserializing flattened any after flattened struct
2018-09-08 17:10:01 -07:00
David Tolnay 2a4b8ce42d Fix panic deserializing flattened any after flattened struct 2018-09-08 16:55:34 -07:00
David Tolnay 108cca687c Release 1.0.77 2018-09-06 21:36:27 -07:00
David Tolnay bca8c115c7 Merge pull request #1372 from dtolnay/syn
Update to syn 0.15
2018-09-06 21:34:14 -07:00
David Tolnay b49bd52a53 Use parse_macro_input to report parse errors 2018-09-06 21:16:12 -07:00
David Tolnay 27bd640812 Update to syn 0.15 2018-09-06 21:16:08 -07:00
David Tolnay 8d5cda8464 Merge pull request #1376 from dreid/fix-internally-tagged-enum-deserialization-with-unknown-fields
Fix internally tagged enum deserialization with unknown fields
2018-09-06 21:10:41 -07:00
David Reid 389b9b5fe7 Add a test for an internally tagged unit enum flattened with a second internally tagged unit enum. 2018-09-06 14:55:10 -07:00
David Reid 27478b6f71 Internally tagged unit enum variants should ignore unknown fields. 2018-09-06 14:29:49 -07:00
David Tolnay 480f858fc3 Update panic_handler attribute name changed in nightly 2018-09-03 08:24:27 -07:00
David Tolnay 7d752c5a60 Merge pull request #1373 from dtolnay/emscripten
Add Emscripten build in Travis
2018-09-02 13:56:41 -07:00
David Tolnay 33b7841300 Skip asmjs 2018-09-02 13:21:36 -07:00
David Tolnay 2244b92eb0 Nvm install in .travis.yml
The one in travis.sh was failing:

    ./travis.sh: line 56: nvm: command not found
    The command "./travis.sh" exited with 127.
2018-09-02 12:45:12 -07:00
David Tolnay d0464fbff7 Add Emscripten build in Travis 2018-09-02 12:34:13 -07:00
David Tolnay 98eddf9b29 Update to syn 0.15-rc1 2018-09-01 23:03:59 -07:00
David Tolnay d23a40c1bb Format with rustfmt 0.99.2 2018-09-01 23:03:41 -07:00
David Tolnay 55cecace29 Release 1.0.76 2018-09-01 15:25:53 -07:00
David Tolnay 3da0deaa50 Merge pull request #1371 from hcpl/nonzero_u128
Add support for `NonZeroU128`
2018-09-01 15:25:10 -07:00
hcpl 585550a5be Add support for NonZeroU128 2018-09-02 00:34:56 +03:00
David Tolnay 5b7b8abf9f Move some compile-fail errors based on proc-macro2 update 2018-08-28 20:35:49 -07:00
David Tolnay 2aab0ce2f6 Release 1.0.75 2018-08-24 23:03:04 -04:00
David Tolnay a157c56d7d Merge pull request #1367 from Eh2406/master
update a deb for minimal-versions
2018-08-24 23:02:02 -04:00
Eh2406 6c45593ee4 update a deb for minimal-versions 2018-08-24 22:50:17 -04:00
David Tolnay 1175d54fb7 Stabilize raw_identifiers 2018-08-24 19:49:13 -04:00
David Tolnay cfdbbee845 Release 1.0.74 2018-08-23 18:29:16 -04:00
David Tolnay c1583bf2b8 Merge pull request #1365 from koute/master
Disable i128 integers on Emscripten targets
2018-08-23 18:28:51 -04:00
Jan Bujak 7385b50249 Disable i128 integers on Emscripten targets 2018-08-24 00:02:40 +02:00
David Tolnay db6aaf5110 Release 1.0.73 2018-08-22 21:47:15 -04:00
David Tolnay c4a4501d71 Merge pull request #1363 from dtolnay/raw
Trim the r# from raw identifiers in user-facing strings
2018-08-22 21:46:31 -04:00
David Tolnay a3ae14d090 Test raw identifiers 2018-08-22 21:09:37 -04:00
David Tolnay dc4bb0bf08 Trim the r# from raw identifiers in user-facing strings 2018-08-22 20:50:29 -04:00
David Tolnay c69a3e083f Merge pull request #1360 from Pratyush/master
Update travis.sh to also test `--no-default-features --features "rc alloc"`
2018-08-20 21:38:55 -04:00
Pratyush Mishra c790bd2a69 Update travis.sh 2018-08-20 18:30:43 -07:00
David Tolnay 60cbbacdb3 Release 1.0.72 2018-08-20 21:02:03 -04:00
David Tolnay befc7edc17 Merge pull request #1359 from Pratyush/master
Fix compilation under `rc` feature
2018-08-20 21:00:47 -04:00
Pratyush Mishra 3897ccb3f9 Fix compilation under rc feature 2018-08-20 14:35:48 -07:00
David Tolnay 11c5fd78ad Abbreviate and touch up some attribute parsing comments 2018-08-14 22:37:59 -07:00
David Tolnay cbfdba3826 Use rustfmt to wrap and format comments 2018-08-14 22:32:27 -07:00
David Tolnay 5985b7edaf Format with rustfmt 0.99.2 2018-08-14 19:59:20 -07:00
David Tolnay d28a0e66c8 Fix old reference to serde_codegen 2018-08-12 10:54:59 -07:00
David Tolnay 0ca4db1616 Move untagged borrow test case into codegen tests 2018-08-12 10:54:29 -07:00
David Tolnay 72b3438dfc Merge pull request #1338 from toidiu/ak-untagged-enum
test borrowing untagged enum
2018-08-12 10:49:15 -07:00
David Tolnay c7051ac748 Update links to a renamed manual chapter 2018-08-12 10:48:20 -07:00
David Tolnay a065db9838 Add AppVeyor badge to rest of crates 2018-08-07 00:15:12 -07:00
David Tolnay 24c4df7831 Release 1.0.71 2018-08-06 23:55:55 -07:00
David Tolnay a077ae039e Merge pull request #1349 from dtolnay/range
Share some code between the Range and RangeInclusive impls
2018-08-06 23:30:03 -07:00
David Tolnay 20b34d3b43 Share some code between the Range and RangeInclusive impls 2018-08-06 23:16:47 -07:00
David Tolnay b5451d1905 Merge pull request #1348 from dtolnay/range
Provide ops::Range impls whether or not std is used
2018-08-06 23:04:26 -07:00
David Tolnay e26960f7f8 Remove useless run-pass test
When originally added, this test used to contain a `#![plugin(clippy)]`.
This was removed at some point along the way, at which point this test
no longer tests anything. It prints:

    warning: unknown lint: `identity_op`
     --> src/main.rs:1:9
      |
    1 | #![deny(identity_op)]
      |         ^^^^^^^^^^^
      |
      = note: #[warn(unknown_lints)] on by default

which is swallowed and ignored by compiletest.

Nowadays Clippy handles warnings inside of macro expanded code
intelligently and this is something they would be responsible for
testing.
2018-08-06 22:57:46 -07:00
David Tolnay 228b5a4a63 Provide ops::Range impls whether or not std is used 2018-08-06 22:49:09 -07:00
David Tolnay 28db9d4989 Format with rustfmt 0.99.1 2018-08-06 22:40:28 -07:00
David Tolnay 5fff0d936d Merge pull request #1347 from c410-f3r/master
Implement Serialize and Deserialize for RangeInclusive
2018-08-06 22:36:12 -07:00
Caio 8eb195edf0 Fix tests 2018-08-05 17:38:41 -03:00
Caio 8b2e6baf78 Implement Serialize and Deserialize for RangeInclusive 2018-08-05 10:45:50 -03:00
toidiu 3ca0597a7e test borrowing untagged enum 2018-07-12 17:12:27 -04:00
David Tolnay 4e54aaf796 Format with rustfmt 0.8.2 2018-07-08 19:02:44 -07:00
David Tolnay 4cddcbe194 Release 1.0.70 2018-07-06 20:21:26 -07:00
David Tolnay 54b6798ef6 Merge pull request #1336 from dtolnay/collections
Update path to alloc::collections for nightly-2018-07-07
2018-07-06 20:19:59 -07:00
David Tolnay 229a9d90ba Update path to alloc::collections for nightly-2018-07-07 2018-07-06 20:04:23 -07:00
David Tolnay 3bcd568c86 Release 1.0.69 2018-06-30 23:40:28 -07:00
David Tolnay dc56077aac Local inner macros 2018-06-30 23:38:14 -07:00
David Tolnay 46bd36e17c Link to issue picker 2018-06-30 10:30:14 -07:00
David Tolnay 5dee9118c7 Factor out the getting help links 2018-06-30 10:29:36 -07:00
David Tolnay a916aa9420 Release 1.0.68 2018-06-28 09:31:12 -07:00
David Tolnay d9c63d0784 Merge pull request #1324 from jechase/suppress_2018_warning
Suppress 'extern crate' warning for rust 2018
2018-06-28 09:30:40 -07:00
Josh Chase 41dcb969e8 Shut clippy up 2018-06-28 11:12:27 -04:00
Josh Chase 6dbaea34ba Suppress 'extern crate' warning for rust 2018 2018-06-28 10:51:57 -04:00
David Tolnay ce17301b8b Release 1.0.67 2018-06-27 00:18:03 -07:00
David Tolnay b0e78c6be4 Format with rustfmt 0.8.2 2018-06-27 00:16:06 -07:00
David Tolnay 898f65fa46 Merge pull request #1323 from dtolnay/format-args
Implement Serialize for core::fmt::Arguments
2018-06-27 00:15:55 -07:00
David Tolnay 84e384196d Implement Serialize for core::fmt::Arguments 2018-06-26 23:58:16 -07:00
David Tolnay d827b101d9 Resolve default_trait_access lint 2018-06-26 23:58:02 -07:00
David Tolnay c45ab6b304 Ignore indexing_slicing pedantic lint 2018-06-26 23:56:39 -07:00
David Tolnay cc9d85b293 Work around unused_imports rustdoc bug 2018-06-26 23:54:32 -07:00
David Tolnay 02493d83be Ignore indexing_slicing pedantic lint 2018-06-26 23:39:26 -07:00
David Tolnay a1280c672a Switch no-std panic to #[panic_implementation] 2018-06-04 10:13:29 -07:00
David Tolnay a740f76772 Update no-std panic signature for nightly-2018-06-03 2018-06-03 23:15:16 -07:00
David Tolnay a887db398b Release 1.0.66 2018-06-03 11:45:20 -07:00
Oliver Schneider e1ae3c71f3 Merge pull request #1304 from dtolnay/ci
CI builders for all versions mentioned in the build script
2018-06-03 10:44:32 +02:00
David Tolnay d094209774 CI builders for all versions mentioned in the build script
This should prevent accidentally inserting something under one of these
cfgs that is available only on a newer rustc. For example if something
is changed in the Duration serialization, but that change works only on
a recent rustc, our test suite will not have caught it before.
2018-06-03 01:26:58 -07:00
David Tolnay 485a64aaf9 Visitor for types that parse from a string 2018-06-03 01:19:46 -07:00
David Tolnay 3e57cd5917 Merge pull request #1303 from dtolnay/duration
Support Duration in no-std mode on new compilers
2018-06-03 01:05:39 -07:00
David Tolnay b6c4cfec37 Support Duration in no-std mode on new compilers 2018-06-03 00:55:58 -07:00
David Tolnay 94853752a1 Stabilize some unstable tests in test suite 2018-06-03 00:31:20 -07:00
David Tolnay bd366f675e Merge pull request #1302 from dtolnay/never
Implement traits for `!`
2018-06-03 00:30:19 -07:00
David Tolnay 22b1af7eb3 Test never_type 2018-06-03 00:22:11 -07:00
David Tolnay fd6178cad6 IntoDeserializer for ! 2018-06-03 00:12:02 -07:00
David Tolnay 338fb67853 Implement traits for ! 2018-06-03 00:02:29 -07:00
David Tolnay 0a71fe329c Format the compile-test sources with rustfmt 0.8.2 2018-06-02 22:30:55 -07:00
David Tolnay a4acc83282 Place compile-fail expected errors on their own line 2018-06-02 22:28:05 -07:00
David Tolnay 57de28744c These match-expressions are implementing unwrap_or_else 2018-06-02 22:09:04 -07:00
David Tolnay 6d31ec521b Remove leftover import from compile_error change 2018-06-02 22:01:45 -07:00
David Tolnay 7ad3d17e59 Merge pull request #1297 from adamcrume/master
Use compile_error! instead of panicking
2018-06-02 22:00:24 -07:00
Adam Crume 05e931b9a5 Update tests and use quote! macro 2018-06-02 21:11:42 -07:00
David Tolnay 2db2b53bbf Release 1.0.65 2018-06-01 13:00:58 -07:00
David Tolnay d5ec3efe49 Merge pull request #1299 from dtolnay/flattenmap
Allow multiple flattened maps to see the same fields
2018-06-01 13:00:45 -07:00
David Tolnay 71fc318474 Merge pull request #1300 from dtolnay/refcell
Use try_borrow for serializing RefCell
2018-06-01 12:58:03 -07:00
David Tolnay 5ee2fc0562 Allow multiple flattened maps to see the same fields
Before this change, flattening anything after a flattened map was
nonsensical because the later flattened field would always observe no
input fields.

    #[derive(Deserialize)]
    struct S {
        #[serde(flatten)]
        map: Map<K, V>,
        #[serde(flatten)]
        other: Other, // always empty
    }

This change makes a flattened map not consume any of the input fields,
leaving them available to later flattened fields in the same struct. The
new behavior is useful when two flattened fields that both use
deserialize_map care about disjoint subsets of the fields in the input.

    #[derive(Deserialize)]
    struct S {
        // Looks at fields with a "player1_" prefix.
        #[serde(flatten, with = "prefix_player1")]
        player1: Player,
        // Looks at fields with a "player2_" prefix.
        #[serde(flatten, with = "prefix_player2")]
        player2: Player,
    }
2018-06-01 12:50:23 -07:00
David Tolnay ca53daf697 Fix RefCell serialize impl to work with no-std 2018-06-01 12:47:10 -07:00
Konrad Borowski c3b9ee314b Use try_borrow for serializing RefCell 2018-06-01 09:09:40 +02:00
Adam Crume 993710eb16 Use compile_error! instead of panicking
Fixes #1168
2018-05-31 19:57:23 -07:00
David Tolnay dbaf2893e3 Release 1.0.64 2018-05-30 00:17:45 -07:00
David Tolnay 34a7108b73 Second attempt at workaround for docs.rs compiler 2018-05-30 00:17:02 -07:00
David Tolnay db2bafd3f3 Revert "Work around docs.rs using an old 1.26-dev compiler"
This reverts commit c81bab18ad.
2018-05-30 00:13:20 -07:00
David Tolnay 1b6fbf1023 Release 1.0.63 2018-05-28 20:12:08 -07:00
David Tolnay c81bab18ad Work around docs.rs using an old 1.26-dev compiler 2018-05-28 19:58:27 -07:00
David Tolnay a39199e9f7 Reword Avro blurb
- Emphasize the association with Apache Hadoop,

- Rephrase "schematized data" because that term returns not many Google
  results, doesn't seem widely recognized.
2018-05-27 19:39:50 -07:00
David Tolnay b0ad1e56e8 Move Avro above deserialization-only formats 2018-05-27 19:31:05 -07:00
David Tolnay ab53448bc3 Merge pull request #1260 from flavray/master
Add Avro to the list of supported data formats
2018-05-27 19:29:19 -07:00
David Tolnay c50c9d8862 Simplify readme as rendered on crates.io 2018-05-27 19:18:30 -07:00
David Tolnay cc4f289758 Link from readme to new playground 2018-05-27 19:07:46 -07:00
David Tolnay a2a9041549 Fix warning about unresolved [u8] and [T] links 2018-05-27 14:35:55 -07:00
David Tolnay a65950acca Link to more complete explanation of the data model 2018-05-27 14:11:02 -07:00
David Tolnay 0fbf4d0c5d Link to example data format from trait rustdocs 2018-05-27 14:05:50 -07:00
David Tolnay 983bf8c090 Release 1.0.62 2018-05-26 18:59:03 -07:00
David Tolnay f2afa89ff1 Explain the pattern for optional Serde derives 2018-05-26 17:59:53 -07:00
David Tolnay 8b4f9c47c4 Build script rustc-cfg strings are not public API 2018-05-26 17:23:09 -07:00
David Tolnay 06d8a44f18 Move unimportant code out of build script main 2018-05-26 17:18:14 -07:00
David Tolnay fffdceca95 Link to "Understanding deserializer lifetimes" 2018-05-26 17:08:46 -07:00
David Tolnay 794b769e6b Merge pull request #1288 from dtolnay/copy
Implement Copy for value deserializers of primitive types
2018-05-26 16:05:12 -07:00
David Tolnay 927ec7d38e Implement Copy for value deserializers of primitive types 2018-05-26 15:56:57 -07:00
David Tolnay cd0b2d312c Merge pull request #1286 from dtolnay/into128
Implement IntoDeserializer for i128 and u128
2018-05-26 15:36:46 -07:00
David Tolnay ea118e11a0 Test the 128-bit IntoDeserializer impls 2018-05-26 15:21:37 -07:00
David Tolnay 0ff4882cab Implement IntoDeserializer for i128 and u128 2018-05-26 15:15:07 -07:00
David Tolnay 7407d71417 Release 1.0.61 2018-05-26 10:38:18 -07:00
David Tolnay 9faa11fd9a Update list of impls to show NonZero* stable 2018-05-26 10:37:08 -07:00
David Tolnay 5310bd87ae Remove unneeded core import
This was previously used by the unstable nonzero impls.

    #[cfg(feature = "unstable")]
    use core::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize};
2018-05-26 10:37:06 -07:00
David Tolnay 99091d5925 Merge pull request #1285 from dtolnay/rcdst
Stabilize impls for dynamically sized Rc / Arc
2018-05-26 10:36:52 -07:00
David Tolnay 320a059e4b Stabilize impls for dynamically sized Rc / Arc 2018-05-26 10:06:29 -07:00
David Tolnay 8a596951bf Merge pull request #1284 from serde-rs/boxcstr
Stabilize Deserialize for Box<CStr>
2018-05-26 10:06:14 -07:00
David Tolnay 350406e827 Merge pull request #1283 from serde-rs/dep
Specify serde version required by serde_test
2018-05-26 09:53:47 -07:00
David Tolnay 7ec3cac7d6 Stabilize Deserialize for Box<CStr> 2018-05-26 09:48:50 -07:00
David Tolnay ad47bd132b Specify serde version required by serde_test 2018-05-26 09:42:31 -07:00
Flavien Raynaud 38d4f0e06c Add Avro to the list of supported data formats 2018-05-16 16:22:25 +01:00
322 changed files with 4340 additions and 2691 deletions
+90 -13
View File
@@ -1,18 +1,95 @@
sudo: false
language: rust
cache: cargo
# run builds for all the trains (and more)
rust:
- 1.13.0
- 1.15.0
- stable
- beta
- nightly
matrix:
include:
- rust: nightly
env: CLIPPY=true
- rust: stable
script:
- cd "${TRAVIS_BUILD_DIR}/serde"
- cargo build --features rc
- cargo build --no-default-features
- cd "${TRAVIS_BUILD_DIR}/serde_test"
- cargo build
- cargo test
script: ./travis.sh
- rust: beta
script:
- cd "${TRAVIS_BUILD_DIR}/serde"
- cargo build --features rc
- cd "${TRAVIS_BUILD_DIR}/test_suite"
- cargo test
- rust: nightly
script:
- cd "${TRAVIS_BUILD_DIR}/serde"
- cargo build
- cargo build --no-default-features
- cargo build --no-default-features --features alloc
- cargo build --no-default-features --features rc,alloc
- cargo test --features rc,unstable
- cd "${TRAVIS_BUILD_DIR}/test_suite/deps"
- cargo build
- cd "${TRAVIS_BUILD_DIR}/test_suite"
- cargo test --features unstable
- cd "${TRAVIS_BUILD_DIR}/test_suite/no_std"
- cargo build
- rust: 1.13.0
script:
- cd "${TRAVIS_BUILD_DIR}/serde"
- cargo build --features rc
- cargo build --no-default-features
- cd "${TRAVIS_BUILD_DIR}/serde_test"
- cargo build
- rust: 1.15.0
script:
- cd "${TRAVIS_BUILD_DIR}/serde_derive"
- cargo build
- rust: 1.20.0
- rust: 1.21.0
- rust: 1.25.0
- rust: 1.26.0
- rust: nightly
name: Clippy
script:
- rustup component add clippy-preview || travis_terminate 0
- cargo clippy -- -Dclippy
- cd "${TRAVIS_BUILD_DIR}/serde"
- cargo clippy --features rc,unstable -- -Dclippy
- cd "${TRAVIS_BUILD_DIR}/serde_derive"
- cargo clippy -- -Dclippy
- cd "${TRAVIS_BUILD_DIR}/serde_test"
- cargo clippy -- -Dclippy
- cd "${TRAVIS_BUILD_DIR}/test_suite"
- cargo clippy --features unstable -- -Dclippy
- cd "${TRAVIS_BUILD_DIR}/test_suite/no_std"
- cargo clippy -- -Dclippy
- rust: nightly
name: Emscripten
script:
- 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"
- nvm install 9
- mkdir -p ~/.cargo/bin
- curl -L "${CARGO_WEB_URL}" | gzip -d > ~/.cargo/bin/cargo-web
- chmod +x ~/.cargo/bin/cargo-web
- cd "${TRAVIS_BUILD_DIR}/test_suite"
- cargo web test --target=asmjs-unknown-emscripten --nodejs
- cargo web test --target=wasm32-unknown-emscripten --nodejs
allow_failures:
- rust: nightly
name: Clippy
- rust: nightly
name: Emscripten
script:
- cd "${TRAVIS_BUILD_DIR}/serde"
- cargo build --no-default-features
- cargo build
-2
View File
@@ -1,5 +1,3 @@
Copyright (c) 2014 The Rust Project Developers
Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the
+9 -8
View File
@@ -15,7 +15,7 @@ You may be looking for:
- [An overview of Serde](https://serde.rs/)
- [Data formats supported by Serde](https://serde.rs/#data-formats)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
- [Examples](https://serde.rs/examples.html)
- [API documentation](https://docs.serde.rs/serde/)
- [Release notes](https://github.com/serde-rs/serde/releases)
@@ -25,7 +25,7 @@ You may be looking for:
<details>
<summary>
Click to show Cargo.toml.
<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
<a href="https://play.rust-lang.org/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
</summary>
```toml
@@ -79,12 +79,13 @@ fn main() {
## Getting help
Serde developers live in the #serde channel on
[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a
good resource with generally faster response time but less specific knowledge
about Serde. If IRC is not your thing or you don't get a good response, we are
happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new)
as well.
Serde developers live in the #serde channel on [`irc.mozilla.org`][irc]. The
\#rust channel is also a good resource with generally faster response time but
less specific knowledge about Serde. If IRC is not your thing or you don't get a
good response, we are happy to respond to [GitHub issues][issues] as well.
[irc]: https://wiki.mozilla.org/IRC
[issues]: https://github.com/serde-rs/serde/issues/new/choose
## License
+26 -2
View File
@@ -13,5 +13,29 @@ install:
build: false
test_script:
- sh -c 'PATH=`rustc --print sysroot`/bin:$PATH ./travis.sh'
for:
- matrix:
only:
- APPVEYOR_RUST_CHANNEL: stable
test_script:
- cd %APPVEYOR_BUILD_FOLDER%\serde
- cargo build --features rc
- cargo build --no-default-features
- cd %APPVEYOR_BUILD_FOLDER%\serde_test
- cargo build
- cargo test
- matrix:
only:
- APPVEYOR_RUST_CHANNEL: nightly
test_script:
- cd %APPVEYOR_BUILD_FOLDER%\serde
- cargo build
- cargo build --no-default-features
- cargo build --no-default-features --features alloc
- cargo build --no-default-features --features rc,alloc
- cargo test --features rc,unstable
- cd %APPVEYOR_BUILD_FOLDER%\test_suite\deps
- cargo build
- cd %APPVEYOR_BUILD_FOLDER%\test_suite
- cargo test --features unstable
+56
View File
@@ -0,0 +1,56 @@
<!-- Serde readme rendered on crates.io -->
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
---
You may be looking for:
- [An overview of Serde](https://serde.rs/)
- [Data formats supported by Serde](https://serde.rs/#data-formats)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/derive.html)
- [Examples](https://serde.rs/examples.html)
- [API documentation](https://docs.serde.rs/serde/)
- [Release notes](https://github.com/serde-rs/serde/releases)
## Serde in action
```rust
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
// Convert the Point to a JSON string.
let serialized = serde_json::to_string(&point).unwrap();
// Prints serialized = {"x":1,"y":2}
println!("serialized = {}", serialized);
// Convert the JSON string back to a Point.
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
// Prints deserialized = Point { x: 1, y: 2 }
println!("deserialized = {:?}", deserialized);
}
```
## Getting help
Serde developers live in the #serde channel on [`irc.mozilla.org`][irc]. The
\#rust channel is also a good resource with generally faster response time but
less specific knowledge about Serde. If IRC is not your thing or you don't get a
good response, we are happy to respond to [GitHub issues][issues] as well.
[irc]: https://wiki.mozilla.org/IRC
[issues]: https://github.com/serde-rs/serde/issues/new/choose
+26 -10
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.60" # remember to update html_root_url
version = "1.0.81" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
@@ -9,8 +9,8 @@ repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde/"
keywords = ["serde", "serialization", "no_std"]
categories = ["encoding"]
readme = "README.md"
include = ["Cargo.toml", "build.rs", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
readme = "crates-io.md"
include = ["Cargo.toml", "build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
build = "build.rs"
[badges]
@@ -29,14 +29,30 @@ serde_derive = { version = "1.0", path = "../serde_derive" }
[features]
default = ["std"]
# Re-export the derive(Serialize, Deserialize) macros. This is specifically
# intended for library crates that provide optional Serde impls behind a Cargo
# cfg of their own. All other crates should depend on serde_derive directly.
# Re-export the derive(Serialize, Deserialize) macros. This is intended for
# library crates that provide optional Serde impls behind a Cargo cfg of their
# own.
#
# Mainly this is a workaround for limitations associated with
# rust-lang/cargo#1286 in which a library crate cannot use one "serde" cfg in
# Cargo to enable dependencies on both serde and serde_derive crates.
#
# The recommended way to provide optional Serde support that requires derive is
# as follows. In particular, please do not name your library's Serde feature
# anything other than "serde".
#
# [dependencies]
# serde = { version = "1.0", optional = true, features = ["derive"] }
#
# Within the library, these optional Serde derives would be written like this.
#
# #[cfg(feature = "serde")]
# #[macro_use]
# extern crate serde;
#
# #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
# struct ...
#
# Please refer to the long comment above the line `pub use serde_derive::*` in
# src/lib.rs before enabling this feature. If you think you need this feature
# and your use case does not precisely match the one described in the comment,
# please open an issue to let us know about your use case.
derive = ["serde_derive"]
# Provide impls for common standard library types like Vec<T> and HashMap<K, V>.
+61 -23
View File
@@ -2,46 +2,84 @@ 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() {
let rustc = match env::var_os("RUSTC") {
Some(rustc) => rustc,
let minor = match rustc_minor_version() {
Some(minor) => minor,
None => return,
};
let output = match Command::new(rustc).arg("--version").output() {
Ok(output) => output,
Err(_) => return,
};
let target = env::var("TARGET").unwrap();
let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
let version = match str::from_utf8(&output.stdout) {
Ok(version) => version,
Err(_) => return,
};
let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") {
return;
// CString::into_boxed_c_str stabilized in Rust 1.20:
// https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
if minor >= 20 {
println!("cargo:rustc-cfg=de_boxed_c_str");
}
let next = match pieces.next() {
Some(next) => next,
None => return,
};
// 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");
}
let minor = match u32::from_str(next) {
Ok(minor) => minor,
Err(_) => return,
};
// 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");
}
// 128-bit integers stabilized in Rust 1.26:
// https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
if minor >= 26 {
//
// Disabled on Emscripten targets as Emscripten doesn't
// currently support integers larger than 64 bits.
if minor >= 26 && !emscripten {
println!("cargo:rustc-cfg=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");
}
// Non-zero integers stabilized in Rust 1.28:
// https://github.com/rust-lang/rust/pull/50808
if minor >= 28 {
println!("cargo:rustc-cfg=num_nonzero");
}
}
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()
}
+1
View File
@@ -0,0 +1 @@
../crates-io.md
-8
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
macro_rules! int_to_int {
+8 -10
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
@@ -20,7 +12,9 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// use std::fmt;
/// use std::marker::PhantomData;
///
/// use serde::de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess, IgnoredAny};
/// use serde::de::{
/// self, Deserialize, DeserializeSeed, Deserializer, IgnoredAny, SeqAccess, Visitor,
/// };
///
/// /// A seed that can be used to deserialize only the `n`th element of a sequence
/// /// while efficiently discarding elements of any type before or after index `n`.
@@ -51,7 +45,11 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// type Value = T;
///
/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// write!(formatter, "a sequence in which we care about element {}", self.n)
/// write!(
/// formatter,
/// "a sequence in which we care about element {}",
/// self.n
/// )
/// }
///
/// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+366 -182
View File
@@ -1,18 +1,10 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
use de::{
Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor,
};
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg(any(core_duration, feature = "std", feature = "alloc"))]
use de::MapAccess;
use de::from_primitive::FromPrimitive;
@@ -49,6 +41,16 @@ impl<'de> Deserialize<'de> for () {
}
}
#[cfg(feature = "unstable")]
impl<'de> Deserialize<'de> for ! {
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Err(Error::custom("cannot deserialize `!`"))
}
}
////////////////////////////////////////////////////////////////////////////////
struct BoolVisitor;
@@ -573,7 +575,7 @@ macro_rules! forwarded_impl {
}
}
#[cfg(all(feature = "std", feature = "unstable"))]
#[cfg(all(feature = "std", de_boxed_c_str))]
forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
////////////////////////////////////////////////////////////////////////////////
@@ -686,7 +688,6 @@ macro_rules! seq_impl {
(
$ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
$access:ident,
$ctor:expr,
$clear:expr,
$with_capacity:expr,
$reserve:expr,
@@ -783,7 +784,6 @@ fn nop_reserve<T>(_seq: T, _n: usize) {}
seq_impl!(
BinaryHeap<T: Ord>,
seq,
BinaryHeap::new(),
BinaryHeap::clear,
BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
BinaryHeap::reserve,
@@ -793,7 +793,6 @@ seq_impl!(
seq_impl!(
BTreeSet<T: Eq + Ord>,
seq,
BTreeSet::new(),
BTreeSet::clear,
BTreeSet::new(),
nop_reserve,
@@ -803,7 +802,6 @@ seq_impl!(
seq_impl!(
LinkedList<T>,
seq,
LinkedList::new(),
LinkedList::clear,
LinkedList::new(),
nop_reserve,
@@ -814,28 +812,15 @@ seq_impl!(
seq_impl!(
HashSet<T: Eq + Hash, S: BuildHasher + Default>,
seq,
HashSet::with_hasher(S::default()),
HashSet::clear,
HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
HashSet::reserve,
HashSet::insert);
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
Vec<T>,
seq,
Vec::new(),
Vec::clear,
Vec::with_capacity(size_hint::cautious(seq.size_hint())),
Vec::reserve,
Vec::push
);
#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
VecDeque<T>,
seq,
VecDeque::new(),
VecDeque::clear,
VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
VecDeque::reserve,
@@ -844,6 +829,99 @@ seq_impl!(
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, T> Deserialize<'de> for Vec<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct VecVisitor<T> {
marker: PhantomData<T>,
}
impl<'de, T> Visitor<'de> for VecVisitor<T>
where
T: Deserialize<'de>,
{
type Value = Vec<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut values = Vec::with_capacity(size_hint::cautious(seq.size_hint()));
while let Some(value) = try!(seq.next_element()) {
values.push(value);
}
Ok(values)
}
}
let visitor = VecVisitor {
marker: PhantomData,
};
deserializer.deserialize_seq(visitor)
}
fn deserialize_in_place<D>(deserializer: D, place: &mut Self) -> Result<(), D::Error>
where
D: Deserializer<'de>,
{
struct VecInPlaceVisitor<'a, T: 'a>(&'a mut Vec<T>);
impl<'a, 'de, T> Visitor<'de> for VecInPlaceVisitor<'a, T>
where
T: Deserialize<'de>,
{
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a sequence")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let hint = size_hint::cautious(seq.size_hint());
if let Some(additional) = hint.checked_sub(self.0.len()) {
self.0.reserve(additional);
}
for i in 0..self.0.len() {
let next = {
let next_place = InPlaceSeed(&mut self.0[i]);
try!(seq.next_element_seed(next_place))
};
if next.is_none() {
self.0.truncate(i);
return Ok(());
}
}
while let Some(value) = try!(seq.next_element()) {
self.0.push(value);
}
Ok(())
}
}
deserializer.deserialize_seq(VecInPlaceVisitor(place))
}
}
////////////////////////////////////////////////////////////////////////////////
struct ArrayVisitor<A> {
marker: PhantomData<A>,
}
@@ -1103,7 +1181,6 @@ macro_rules! map_impl {
(
$ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
$access:ident,
$ctor:expr,
$with_capacity:expr
) => {
impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty<K, V $(, $typaram)*>
@@ -1158,29 +1235,43 @@ macro_rules! map_impl {
map_impl!(
BTreeMap<K: Ord, V>,
map,
BTreeMap::new(),
BTreeMap::new());
#[cfg(feature = "std")]
map_impl!(
HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
map,
HashMap::with_hasher(S::default()),
HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
macro_rules! parse_ip_impl {
($ty:ty; $size:expr) => {
($expecting:tt $ty:ty; $size:tt) => {
impl<'de> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = try!(String::deserialize(deserializer));
s.parse().map_err(Error::custom)
struct IpAddrVisitor;
impl<'de> Visitor<'de> for IpAddrVisitor {
type Value = $ty;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str($expecting)
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
s.parse().map_err(Error::custom)
}
}
deserializer.deserialize_str(IpAddrVisitor)
} else {
<[u8; $size]>::deserialize(deserializer).map(<$ty>::from)
}
@@ -1308,11 +1399,27 @@ impl<'de> Deserialize<'de> for net::IpAddr {
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = try!(String::deserialize(deserializer));
s.parse().map_err(Error::custom)
struct IpAddrVisitor;
impl<'de> Visitor<'de> for IpAddrVisitor {
type Value = net::IpAddr;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("IP address")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
s.parse().map_err(Error::custom)
}
}
deserializer.deserialize_str(IpAddrVisitor)
} else {
use lib::net::IpAddr;
deserialize_enum!{
deserialize_enum! {
IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
"`V4` or `V6`",
deserializer
@@ -1322,22 +1429,38 @@ impl<'de> Deserialize<'de> for net::IpAddr {
}
#[cfg(feature = "std")]
parse_ip_impl!(net::Ipv4Addr; 4);
parse_ip_impl!("IPv4 address" net::Ipv4Addr; 4);
#[cfg(feature = "std")]
parse_ip_impl!(net::Ipv6Addr; 16);
parse_ip_impl!("IPv6 address" net::Ipv6Addr; 16);
#[cfg(feature = "std")]
macro_rules! parse_socket_impl {
($ty:ty, $new:expr) => {
($expecting:tt $ty:ty, $new:expr) => {
impl<'de> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = try!(String::deserialize(deserializer));
s.parse().map_err(Error::custom)
struct SocketAddrVisitor;
impl<'de> Visitor<'de> for SocketAddrVisitor {
type Value = $ty;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str($expecting)
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
s.parse().map_err(Error::custom)
}
}
deserializer.deserialize_str(SocketAddrVisitor)
} else {
<(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port))
}
@@ -1353,11 +1476,27 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = try!(String::deserialize(deserializer));
s.parse().map_err(Error::custom)
struct SocketAddrVisitor;
impl<'de> Visitor<'de> for SocketAddrVisitor {
type Value = net::SocketAddr;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("socket address")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
s.parse().map_err(Error::custom)
}
}
deserializer.deserialize_str(SocketAddrVisitor)
} else {
use lib::net::SocketAddr;
deserialize_enum!{
deserialize_enum! {
SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
"`V4` or `V6`",
deserializer
@@ -1367,10 +1506,10 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
}
#[cfg(feature = "std")]
parse_socket_impl!(net::SocketAddrV4, net::SocketAddrV4::new);
parse_socket_impl!("IPv4 socket address" net::SocketAddrV4, net::SocketAddrV4::new);
#[cfg(feature = "std")]
parse_socket_impl!(net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(
parse_socket_impl!("IPv6 socket address" net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(
ip, port, 0, 0
));
@@ -1457,7 +1596,7 @@ impl<'de> Deserialize<'de> for PathBuf {
// #[derive(Deserialize)]
// #[serde(variant_identifier)]
#[cfg(all(feature = "std", any(unix, windows)))]
variant_identifier!{
variant_identifier! {
OsStringKind (Unix; b"Unix"; 0, Windows; b"Windows"; 1)
"`Unix` or `Windows`",
OSSTR_VARIANTS
@@ -1528,7 +1667,11 @@ forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice);
#[cfg(any(feature = "std", feature = "alloc"))]
forwarded_impl!((), Box<str>, String::into_boxed_str);
#[cfg(all(not(feature = "unstable"), feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg(all(
not(de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1540,7 +1683,11 @@ forwarded_impl! {
(T), Arc<T>, Arc::new
}
#[cfg(all(not(feature = "unstable"), feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg(all(
not(de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1607,7 +1754,7 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
macro_rules! box_forwarded_impl {
(
$(#[doc = $doc:tt])*
@@ -1628,7 +1775,7 @@ macro_rules! box_forwarded_impl {
};
}
#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1640,7 +1787,7 @@ box_forwarded_impl! {
Rc
}
#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1684,7 +1831,7 @@ forwarded_impl!((T), RwLock<T>, RwLock::new);
// secs: u64,
// nanos: u32,
// }
#[cfg(feature = "std")]
#[cfg(any(core_duration, feature = "std"))]
impl<'de> Deserialize<'de> for Duration {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1732,7 +1879,7 @@ impl<'de> Deserialize<'de> for Duration {
b"secs" => Ok(Field::Secs),
b"nanos" => Ok(Field::Nanos),
_ => {
let value = String::from_utf8_lossy(value);
let value = ::export::from_utf8_lossy(value);
Err(Error::unknown_field(&value, FIELDS))
}
}
@@ -1950,8 +2097,7 @@ impl<'de> Deserialize<'de> for SystemTime {
// start: u64,
// end: u32,
// }
#[cfg(feature = "std")]
impl<'de, Idx> Deserialize<'de> for ops::Range<Idx>
impl<'de, Idx> Deserialize<'de> for Range<Idx>
where
Idx: Deserialize<'de>,
{
@@ -1959,134 +2105,165 @@ where
where
D: Deserializer<'de>,
{
// If this were outside of the serde crate, it would just use:
//
// #[derive(Deserialize)]
// #[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Start,
End,
};
impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`start` or `end`")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"start" => Ok(Field::Start),
"end" => Ok(Field::End),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"start" => Ok(Field::Start),
b"end" => Ok(Field::End),
_ => {
let value = String::from_utf8_lossy(value);
Err(Error::unknown_field(&value, FIELDS))
}
}
}
}
deserializer.deserialize_identifier(FieldVisitor)
}
}
struct RangeVisitor<Idx> {
phantom: PhantomData<Idx>,
}
impl<'de, Idx> Visitor<'de> for RangeVisitor<Idx>
where
Idx: Deserialize<'de>,
{
type Value = ops::Range<Idx>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Range")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let start: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
};
let end: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(1, &self));
}
};
Ok(start..end)
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut start: Option<Idx> = None;
let mut end: Option<Idx> = None;
while let Some(key) = try!(map.next_key()) {
match key {
Field::Start => {
if start.is_some() {
return Err(<A::Error as Error>::duplicate_field("start"));
}
start = Some(try!(map.next_value()));
}
Field::End => {
if end.is_some() {
return Err(<A::Error as Error>::duplicate_field("end"));
}
end = Some(try!(map.next_value()));
}
}
}
let start = match start {
Some(start) => start,
None => return Err(<A::Error as Error>::missing_field("start")),
};
let end = match end {
Some(end) => end,
None => return Err(<A::Error as Error>::missing_field("end")),
};
Ok(start..end)
}
}
const FIELDS: &'static [&'static str] = &["start", "end"];
deserializer.deserialize_struct(
let (start, end) = deserializer.deserialize_struct(
"Range",
FIELDS,
RangeVisitor {
range::FIELDS,
range::RangeVisitor {
expecting: "struct Range",
phantom: PhantomData,
},
)
)?;
Ok(start..end)
}
}
#[cfg(range_inclusive)]
impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx>
where
Idx: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let (start, end) = deserializer.deserialize_struct(
"RangeInclusive",
range::FIELDS,
range::RangeVisitor {
expecting: "struct RangeInclusive",
phantom: PhantomData,
},
)?;
Ok(RangeInclusive::new(start, end))
}
}
mod range {
use lib::*;
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
pub const FIELDS: &'static [&'static str] = &["start", "end"];
// If this were outside of the serde crate, it would just use:
//
// #[derive(Deserialize)]
// #[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Start,
End,
}
impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`start` or `end`")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"start" => Ok(Field::Start),
"end" => Ok(Field::End),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"start" => Ok(Field::Start),
b"end" => Ok(Field::End),
_ => {
let value = ::export::from_utf8_lossy(value);
Err(Error::unknown_field(&value, FIELDS))
}
}
}
}
deserializer.deserialize_identifier(FieldVisitor)
}
}
pub struct RangeVisitor<Idx> {
pub expecting: &'static str,
pub phantom: PhantomData<Idx>,
}
impl<'de, Idx> Visitor<'de> for RangeVisitor<Idx>
where
Idx: Deserialize<'de>,
{
type Value = (Idx, Idx);
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(self.expecting)
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let start: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
};
let end: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(1, &self));
}
};
Ok((start, end))
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut start: Option<Idx> = None;
let mut end: Option<Idx> = None;
while let Some(key) = try!(map.next_key()) {
match key {
Field::Start => {
if start.is_some() {
return Err(<A::Error as Error>::duplicate_field("start"));
}
start = Some(try!(map.next_value()));
}
Field::End => {
if end.is_some() {
return Err(<A::Error as Error>::duplicate_field("end"));
}
end = Some(try!(map.next_value()));
}
}
}
let start = match start {
Some(start) => start,
None => return Err(<A::Error as Error>::missing_field("start")),
};
let end = match end {
Some(end) => end,
None => return Err(<A::Error as Error>::missing_field("end")),
};
Ok((start, end))
}
}
}
@@ -2118,10 +2295,17 @@ nonzero_integers! {
NonZeroU16,
NonZeroU32,
NonZeroU64,
// FIXME: https://github.com/serde-rs/serde/issues/1136 NonZeroU128,
NonZeroUsize,
}
// Currently 128-bit integers do not work on Emscripten targets so we need an
// additional `#[cfg]`
serde_if_integer128! {
nonzero_integers! {
NonZeroU128,
}
}
////////////////////////////////////////////////////////////////////////////////
impl<'de, T, E> Deserialize<'de> for Result<T, E>
+169 -49
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Generic data structure deserialization framework.
//!
//! The two most important traits in this module are [`Deserialize`] and
@@ -24,8 +16,7 @@
//!
//! Additionally, Serde provides a procedural macro called [`serde_derive`] to
//! automatically generate [`Deserialize`] implementations for structs and enums
//! in your program. See the [codegen section of the manual] for how to use
//! this.
//! in your program. See the [derive section of the manual] for how to use this.
//!
//! In rare cases it may be necessary to implement [`Deserialize`] manually for
//! some type in your program. See the [Implementing `Deserialize`] section of
@@ -57,7 +48,7 @@
//! - f32, f64
//! - char
//! - **Compound types**:
//! - [T; 0] through [T; 32]
//! - \[T; 0\] through \[T; 32\]
//! - tuples up to size 16
//! - **Common standard library types**:
//! - String
@@ -66,7 +57,7 @@
//! - PhantomData\<T\>
//! - **Wrapper types**:
//! - Box\<T\>
//! - Box\<[T]\>
//! - Box\<\[T\]\>
//! - Box\<str\>
//! - Rc\<T\>
//! - Arc\<T\>
@@ -86,7 +77,7 @@
//! - Vec\<T\>
//! - **Zero-copy types**:
//! - &str
//! - &[u8]
//! - &\[u8\]
//! - **FFI types**:
//! - CString
//! - Box\<CStr\>
@@ -97,7 +88,9 @@
//! - Path
//! - PathBuf
//! - Range\<T\>
//! - num::NonZero* (unstable)
//! - RangeInclusive\<T\>
//! - num::NonZero*
//! - `!` *(unstable)*
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
@@ -115,7 +108,7 @@
//! [`serde_derive`]: https://crates.io/crates/serde_derive
//! [`serde_json`]: https://github.com/serde-rs/json
//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml
//! [codegen section of the manual]: https://serde.rs/codegen.html
//! [derive section of the manual]: https://serde.rs/derive.html
//! [data formats]: https://serde.rs/#data-formats
use lib::*;
@@ -148,6 +141,13 @@ macro_rules! declare_error_trait {
///
/// Most deserializers should only need to provide the `Error::custom` method
/// and inherit the default behavior for the other methods.
///
/// # Example implementation
///
/// The [example data format] presented on the website shows an error
/// type appropriate for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait Error: Sized $(+ $($supertrait)::+)* {
/// Raised when there is general error when deserializing a type.
///
@@ -489,7 +489,7 @@ impl<'a> Display for Expected + 'a {
///
/// Additionally, Serde provides a procedural macro called `serde_derive` to
/// automatically generate `Deserialize` implementations for structs and enums
/// in your program. See the [codegen section of the manual][codegen] for how to
/// in your program. See the [derive section of the manual][derive] for how to
/// use this.
///
/// In rare cases it may be necessary to implement `Deserialize` manually for
@@ -502,8 +502,16 @@ impl<'a> Display for Expected + 'a {
/// provides an implementation of `Deserialize` for it.
///
/// [de]: https://docs.serde.rs/serde/de/index.html
/// [codegen]: https://serde.rs/codegen.html
/// [derive]: https://serde.rs/derive.html
/// [impl-deserialize]: https://serde.rs/impl-deserialize.html
///
/// # Lifetime
///
/// The `'de` lifetime of this trait is the lifetime of data that may be
/// borrowed by `Self` when deserialized. See the page [Understanding
/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
pub trait Deserialize<'de>: Sized {
/// Deserialize this value from the given Serde deserializer.
///
@@ -568,12 +576,16 @@ pub trait Deserialize<'de>: Sized {
/// T: DeserializeOwned;
/// # }
/// ```
///
/// # Lifetime
///
/// The relationship between `Deserialize` and `DeserializeOwned` in trait
/// bounds is explained in more detail on the page [Understanding deserializer
/// lifetimes].
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
impl<T> DeserializeOwned for T
where
T: for<'de> Deserialize<'de>,
{
}
impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
/// `DeserializeSeed` is the stateful form of the `Deserialize` trait. If you
/// ever find yourself looking for a way to pass data into a `Deserialize` impl,
@@ -618,6 +630,14 @@ where
/// seed can be appeased by passing `std::marker::PhantomData` as a seed in the
/// case of stateless deserialization.
///
/// # Lifetime
///
/// The `'de` lifetime of this trait is the lifetime of data that may be
/// borrowed by `Self::Value` when deserialized. See the page [Understanding
/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example
///
/// Suppose we have JSON that looks like `[[1, 2], [3, 4, 5], [6]]` and we need
@@ -631,7 +651,7 @@ where
/// use std::fmt;
/// use std::marker::PhantomData;
///
/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess};
/// 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
@@ -756,10 +776,10 @@ where
/// A **data format** that can deserialize any data structure supported by
/// Serde.
///
/// The role of this trait is to define the deserialization half of the Serde
/// data model, which is a way to categorize every Rust data type into one of 29
/// possible types. Each method of the `Serializer` trait corresponds to one of
/// the types of the data model.
/// The role of this trait is to define the deserialization half of the [Serde
/// data model], which is a way to categorize every Rust data type into one of
/// 29 possible types. Each method of the `Serializer` trait corresponds to one
/// of the types of the data model.
///
/// Implementations of `Deserialize` map themselves into this data model by
/// passing to the `Deserializer` a `Visitor` implementation that can receive
@@ -777,17 +797,17 @@ where
/// - UTF-8 bytes with a length and no null terminator.
/// - When serializing, all strings are handled equally. When deserializing,
/// there are three flavors of strings: transient, owned, and borrowed.
/// - **byte array** - [u8]
/// - Similar to strings, during deserialization byte arrays can be transient,
/// owned, or borrowed.
/// - **byte array** - \[u8\]
/// - Similar to strings, during deserialization byte arrays can be
/// transient, owned, or borrowed.
/// - **option**
/// - Either none or some value.
/// - **unit**
/// - The type of `()` in Rust. It represents an anonymous value containing no
/// data.
/// - The type of `()` in Rust. It represents an anonymous value containing
/// no data.
/// - **unit_struct**
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named value
/// containing no data.
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named
/// value containing no data.
/// - **unit_variant**
/// - For example the `E::A` and `E::B` in `enum E { A, B }`.
/// - **newtype_struct**
@@ -795,14 +815,15 @@ where
/// - **newtype_variant**
/// - For example the `E::N` in `enum E { N(u8) }`.
/// - **seq**
/// - A variably sized heterogeneous sequence of values, for example `Vec<T>` or
/// `HashSet<T>`. When serializing, the length may or may not be known before
/// iterating through all the data. When deserializing, the length is determined
/// by looking at the serialized data.
/// - A variably sized heterogeneous sequence of values, for example `Vec<T>`
/// or `HashSet<T>`. When serializing, the length may or may not be known
/// before iterating through all the data. When deserializing, the length
/// is determined by looking at the serialized data.
/// - **tuple**
/// - A statically sized heterogeneous sequence of values for which the length
/// will be known at deserialization time without looking at the serialized
/// data, for example `(u8,)` or `(String, u64, Vec<T>)` or `[u64; 10]`.
/// - A statically sized heterogeneous sequence of values for which the
/// length will be known at deserialization time without looking at the
/// serialized data, for example `(u8,)` or `(String, u64, Vec<T>)` or
/// `[u64; 10]`.
/// - **tuple_struct**
/// - A named tuple, for example `struct Rgb(u8, u8, u8)`.
/// - **tuple_variant**
@@ -810,9 +831,9 @@ where
/// - **map**
/// - A heterogeneous key-value pairing, for example `BTreeMap<K, V>`.
/// - **struct**
/// - A heterogeneous key-value pairing in which the keys are strings and will be
/// known at deserialization time without looking at the serialized data, for
/// example `struct S { r: u8, g: u8, b: u8 }`.
/// - A heterogeneous key-value pairing in which the keys are strings and
/// will be known at deserialization time without looking at the serialized
/// data, for example `struct S { r: u8, g: u8, b: u8 }`.
/// - **struct_variant**
/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
///
@@ -827,7 +848,8 @@ where
/// type it sees in the input. JSON uses this approach when deserializing
/// `serde_json::Value` which is an enum that can represent any JSON
/// document. Without knowing what is in a JSON document, we can deserialize
/// it to `serde_json::Value` by going through `Deserializer::deserialize_any`.
/// it to `serde_json::Value` by going through
/// `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.
@@ -837,10 +859,28 @@ where
/// `Deserializer::deserialize_any`.
///
/// When implementing `Deserialize`, you should avoid relying on
/// `Deserializer::deserialize_any` unless you need to be told by the Deserializer
/// what type is in the input. Know that relying on `Deserializer::deserialize_any`
/// means your data type will be able to deserialize from self-describing
/// formats only, ruling out Bincode and many others.
/// `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
/// others.
///
/// [Serde data model]: https://serde.rs/data-model.html
///
/// # Lifetime
///
/// The `'de` lifetime of this trait is the lifetime of data that may be
/// borrowed from the input when deserializing. See the page [Understanding
/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example implementation
///
/// The [example data format] presented on the website contains example code for
/// a basic JSON `Deserializer`.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait Deserializer<'de>: Sized {
/// The error type that can be returned if some error occurs during
/// deserialization.
@@ -1164,6 +1204,16 @@ pub trait Deserializer<'de>: Sized {
/// This trait represents a visitor that walks through a deserializer.
///
/// # Lifetime
///
/// The `'de` lifetime of this trait is the requirement for lifetime of data
/// that may be borrowed by `Self::Value`. See the page [Understanding
/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example
///
/// ```rust
/// # use std::fmt;
/// #
@@ -1600,6 +1650,21 @@ pub trait Visitor<'de>: Sized {
///
/// This is a trait that a `Deserializer` passes to a `Visitor` implementation,
/// which deserializes each item in a sequence.
///
/// # Lifetime
///
/// The `'de` lifetime of this trait is the lifetime of data that may be
/// borrowed by deserialized sequence elements. See the page [Understanding
/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SeqAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SeqAccess<'de> {
/// The error type that can be returned if some error occurs during
/// deserialization.
@@ -1667,6 +1732,21 @@ where
/// Provides a `Visitor` access to each entry of a map in the input.
///
/// This is a trait that a `Deserializer` passes to a `Visitor` implementation.
///
/// # Lifetime
///
/// The `'de` lifetime of this trait is the lifetime of data that may be
/// borrowed by deserialized map entries. See the page [Understanding
/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `MapAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait MapAccess<'de> {
/// The error type that can be returned if some error occurs during
/// deserialization.
@@ -1844,6 +1924,21 @@ where
///
/// `EnumAccess` is created by the `Deserializer` and passed to the
/// `Visitor` in order to identify which variant of an enum to deserialize.
///
/// # Lifetime
///
/// The `'de` lifetime of this trait is the lifetime of data that may be
/// borrowed by the deserialized enum variant. See the page [Understanding
/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `EnumAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait EnumAccess<'de>: Sized {
/// The error type that can be returned if some error occurs during
/// deserialization.
@@ -1876,6 +1971,21 @@ pub trait EnumAccess<'de>: Sized {
/// `VariantAccess` is a visitor that is created by the `Deserializer` and
/// passed to the `Deserialize` to deserialize the content of a particular enum
/// variant.
///
/// # Lifetime
///
/// The `'de` lifetime of this trait is the lifetime of data that may be
/// borrowed by the deserialized enum variant. See the page [Understanding
/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `VariantAccess` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait VariantAccess<'de>: Sized {
/// The error type that can be returned if some error occurs during
/// deserialization. Must match the error type of our `EnumAccess`.
@@ -2079,6 +2189,16 @@ pub trait VariantAccess<'de>: Sized {
/// Converts an existing value into a `Deserializer` from which other values can
/// be deserialized.
///
/// # Lifetime
///
/// The `'de` lifetime of this trait is the lifetime of data that may be
/// borrowed from the resulting `Deserializer`. See the page [Understanding
/// deserializer lifetimes] for a more detailed explanation of these lifetimes.
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
///
/// # Example
///
/// ```rust
/// #[macro_use]
/// extern crate serde_derive;
-8
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
const TAG_CONT: u8 = 0b1000_0000;
+103 -16
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Building blocks for deserializing basic values using the `IntoDeserializer`
//! trait.
//!
@@ -44,6 +36,22 @@ use ser;
////////////////////////////////////////////////////////////////////////////////
// For structs that contain a PhantomData. We do not want the trait
// bound `E: Clone` inferred by derive(Clone).
macro_rules! impl_copy_clone {
($ty:ident $(<$lifetime:tt>)*) => {
impl<$($lifetime,)* E> Copy for $ty<$($lifetime,)* E> {}
impl<$($lifetime,)* E> Clone for $ty<$($lifetime,)* E> {
fn clone(&self) -> Self {
*self
}
}
};
}
////////////////////////////////////////////////////////////////////////////////
/// A minimal representation of all possible errors that can occur using the
/// `IntoDeserializer` trait.
#[derive(Clone, Debug, PartialEq)]
@@ -124,11 +132,13 @@ where
}
/// A deserializer holding a `()`.
#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct UnitDeserializer<E> {
marker: PhantomData<E>,
}
impl_copy_clone!(UnitDeserializer);
impl<'de, E> de::Deserializer<'de> for UnitDeserializer<E>
where
E: de::Error,
@@ -158,16 +168,60 @@ where
////////////////////////////////////////////////////////////////////////////////
/// A deserializer that cannot be instantiated.
#[cfg(feature = "unstable")]
pub struct NeverDeserializer<E> {
never: !,
marker: PhantomData<E>,
}
#[cfg(feature = "unstable")]
impl<'de, E> IntoDeserializer<'de, E> for !
where
E: de::Error,
{
type Deserializer = NeverDeserializer<E>;
fn into_deserializer(self) -> Self::Deserializer {
self
}
}
#[cfg(feature = "unstable")]
impl<'de, E> de::Deserializer<'de> for NeverDeserializer<E>
where
E: de::Error,
{
type Error = E;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.never
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
}
////////////////////////////////////////////////////////////////////////////////
macro_rules! primitive_deserializer {
($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => {
#[doc = "A deserializer holding"]
#[doc = $doc]
#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct $name<E> {
value: $ty,
marker: PhantomData<E>
}
impl_copy_clone!($name);
impl<'de, E> IntoDeserializer<'de, E> for $ty
where
E: de::Error,
@@ -218,13 +272,20 @@ primitive_deserializer!(f32, "an `f32`.", F32Deserializer, visit_f32);
primitive_deserializer!(f64, "an `f64`.", F64Deserializer, visit_f64);
primitive_deserializer!(char, "a `char`.", CharDeserializer, visit_char);
serde_if_integer128! {
primitive_deserializer!(i128, "an `i128`.", I128Deserializer, visit_i128);
primitive_deserializer!(u128, "a `u128`.", U128Deserializer, visit_u128);
}
/// A deserializer holding a `u32`.
#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct U32Deserializer<E> {
value: u32,
marker: PhantomData<E>,
}
impl_copy_clone!(U32Deserializer);
impl<'de, E> IntoDeserializer<'de, E> for u32
where
E: de::Error,
@@ -291,12 +352,14 @@ where
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `&str`.
#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct StrDeserializer<'a, E> {
value: &'a str,
marker: PhantomData<E>,
}
impl_copy_clone!(StrDeserializer<'de>);
impl<'de, 'a, E> IntoDeserializer<'de, E> for &'a str
where
E: de::Error,
@@ -364,12 +427,14 @@ where
/// A deserializer holding a `&str` with a lifetime tied to another
/// deserializer.
#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct BorrowedStrDeserializer<'de, E> {
value: &'de str,
marker: PhantomData<E>,
}
impl_copy_clone!(BorrowedStrDeserializer<'de>);
impl<'de, E> BorrowedStrDeserializer<'de, E> {
/// Create a new borrowed deserializer from the given string.
pub fn new(value: &'de str) -> BorrowedStrDeserializer<'de, E> {
@@ -433,12 +498,22 @@ where
/// A deserializer holding a `String`.
#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct StringDeserializer<E> {
value: String,
marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<E> Clone for StringDeserializer<E> {
fn clone(&self) -> Self {
StringDeserializer {
value: self.value.clone(),
marker: PhantomData,
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, E> IntoDeserializer<'de, E> for String
where
@@ -509,12 +584,22 @@ where
/// A deserializer holding a `Cow<str>`.
#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct CowStrDeserializer<'a, E> {
value: Cow<'a, str>,
marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, E> Clone for CowStrDeserializer<'a, E> {
fn clone(&self) -> Self {
CowStrDeserializer {
value: self.value.clone(),
marker: PhantomData,
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str>
where
@@ -588,12 +673,14 @@ where
/// A deserializer holding a `&[u8]` with a lifetime tied to another
/// deserializer.
#[derive(Clone, Debug)]
#[derive(Debug)]
pub struct BorrowedBytesDeserializer<'de, E> {
value: &'de [u8],
marker: PhantomData<E>,
}
impl_copy_clone!(BorrowedBytesDeserializer<'de>);
impl<'de, E> BorrowedBytesDeserializer<'de, E> {
/// Create a new borrowed deserializer from the given byte slice.
pub fn new(value: &'de [u8]) -> BorrowedBytesDeserializer<'de, E> {
-8
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub use lib::clone::Clone;
pub use lib::convert::{From, Into};
pub use lib::default::Default;
+41 -29
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
@@ -50,15 +42,17 @@
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [RON], a Rusty Object Notation.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema
//! definition.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [JSON5], A superset of JSON including some productions from ES5.
//! - [URL], the x-www-form-urlencoded format.
//! - [XML], the flexible machine-friendly W3C standard.
//! *(deserialization only)*
//! - [Envy], a way to deserialize environment variables into Rust structs.
//! *(deserialization only)*
//! - [Redis], deserialize values from Redis when using [redis-rs].
//! *(deserialization only)*
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
//! Rust structs. *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
@@ -67,34 +61,44 @@
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [RON]: https://github.com/ron-rs/ron
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-rs
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [URL]: https://github.com/nox/serde_urlencoded
//! [XML]: https://github.com/RReverser/serde-xml-rs
//! [Envy]: https://github.com/softprops/envy
//! [Redis]: https://github.com/OneSignal/serde-redis
//! [Envy Store]: https://github.com/softprops/envy-store
//! [Cargo]: http://doc.crates.io/manifest.html
//! [redis-rs]: https://crates.io/crates/redis
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.60")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.81")]
// 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(specialization))]
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(
feature = "cargo-clippy",
allow(
cast_lossless, const_static_lifetime, doc_markdown, linkedlist, needless_pass_by_value,
redundant_field_names, type_complexity, unreadable_literal, zero_prefixed_literal
cast_lossless,
const_static_lifetime,
doc_markdown,
linkedlist,
needless_pass_by_value,
redundant_field_names,
type_complexity,
unreadable_literal,
zero_prefixed_literal
)
)]
// Whitelisted clippy_pedantic lints
@@ -115,6 +119,7 @@
stutter,
use_self,
// not practical
indexing_slicing,
many_single_char_names,
missing_docs_in_private_items,
similar_names,
@@ -123,16 +128,16 @@
use_debug,
))]
// Blacklisted Rust lints.
#![deny(missing_docs, unused_imports)]
//
// Compiler bug involving unused_imports:
// https://github.com/rust-lang/rust/issues/51661
#![deny(missing_docs, /*unused_imports*/)]
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(all(feature = "unstable", feature = "std"))]
extern crate core;
/// A facade around all the types we need from the `std`, `core`, and `alloc`
/// crates. This avoids elaborate import wrangling having to happen in every
/// module.
@@ -144,7 +149,7 @@ mod lib {
pub use std::*;
}
pub use self::core::{cmp, iter, mem, num, ops, slice, str};
pub use self::core::{cmp, iter, mem, num, 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};
@@ -155,6 +160,7 @@ mod lib {
pub use self::core::default::{self, Default};
pub use self::core::fmt::{self, Debug, Display};
pub use self::core::marker::{self, PhantomData};
pub use self::core::ops::Range;
pub use self::core::option::{self, Option};
pub use self::core::result::{self, Result};
@@ -184,12 +190,12 @@ mod lib {
pub use std::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::arc::{Arc, Weak as ArcWeak};
pub use alloc::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
#[cfg(feature = "std")]
pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
@@ -211,7 +217,13 @@ mod lib {
#[cfg(feature = "std")]
pub use std::sync::{Mutex, RwLock};
#[cfg(feature = "std")]
pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
pub use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(any(core_duration, feature = "std"))]
pub use self::core::time::Duration;
#[cfg(range_inclusive)]
pub use self::core::ops::RangeInclusive;
}
////////////////////////////////////////////////////////////////////////////////
+2 -10
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Super explicit first paragraph because this shows up at the top level and
// trips up people who are just looking for basic Serialize / Deserialize
// documentation.
@@ -128,7 +120,7 @@
/// [`Deserializer`]: trait.Deserializer.html
/// [`Visitor`]: de/trait.Visitor.html
/// [`Deserializer::deserialize_any`]: trait.Deserializer.html#tymethod.deserialize_any
#[macro_export]
#[macro_export(local_inner_macros)]
macro_rules! forward_to_deserialize_any {
(<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => {
$(forward_to_deserialize_any_helper!{$func<$lifetime, $visitor>})*
@@ -157,7 +149,7 @@ macro_rules! forward_to_deserialize_any_method {
}
#[doc(hidden)]
#[macro_export]
#[macro_export(local_inner_macros)]
macro_rules! forward_to_deserialize_any_helper {
(bool<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_bool<$l, $v>()}
+83 -43
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
@@ -231,8 +223,8 @@ mod content {
use super::size_hint;
use de::{
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess,
SeqAccess, Unexpected, Visitor,
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
MapAccess, SeqAccess, Unexpected, Visitor,
};
/// Used from generated code to buffer the contents of the Deserializer when
@@ -832,8 +824,8 @@ mod content {
}
impl<'de, T> TaggedContentVisitor<'de, T> {
/// Visitor for the content of an internally tagged enum with the given tag
/// name.
/// Visitor for the content of an internally tagged enum with the given
/// tag name.
pub fn new(name: &'static str) -> Self {
TaggedContentVisitor {
tag_name: name,
@@ -1075,8 +1067,8 @@ mod content {
Ok(value)
}
/// Used when deserializing an internally tagged enum because the content will
/// be used exactly once.
/// Used when deserializing an internally tagged enum because the content
/// will be used exactly once.
impl<'de, E> Deserializer<'de> for ContentDeserializer<'de, E>
where
E: de::Error,
@@ -1427,6 +1419,7 @@ mod content {
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(v) => visitor.visit_byte_buf(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::U8(v) => visitor.visit_u8(v),
_ => Err(self.invalid_type(&visitor)),
}
}
@@ -1763,7 +1756,7 @@ mod content {
V: Visitor<'de>,
E: de::Error,
{
let seq = content.into_iter().map(ContentRefDeserializer::new);
let seq = content.iter().map(ContentRefDeserializer::new);
let mut seq_visitor = de::value::SeqDeserializer::new(seq);
let value = try!(visitor.visit_seq(&mut seq_visitor));
try!(seq_visitor.end());
@@ -1778,7 +1771,7 @@ mod content {
V: Visitor<'de>,
E: de::Error,
{
let map = content.into_iter().map(|&(ref k, ref v)| {
let map = content.iter().map(|&(ref k, ref v)| {
(
ContentRefDeserializer::new(k),
ContentRefDeserializer::new(v),
@@ -1790,8 +1783,8 @@ mod content {
Ok(value)
}
/// Used when deserializing an untagged enum because the content may need to be
/// used more than once.
/// Used when deserializing an untagged enum because the content may need
/// to be used more than once.
impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2085,7 +2078,7 @@ mod content {
{
let (variant, value) = match *self.content {
Content::Map(ref value) => {
let mut iter = value.into_iter();
let mut iter = value.iter();
let &(ref variant, ref value) = match iter.next() {
Some(v) => v,
None => {
@@ -2129,6 +2122,7 @@ mod content {
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(ref v) => visitor.visit_bytes(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::U8(v) => visitor.visit_u8(v),
_ => Err(self.invalid_type(&visitor)),
}
}
@@ -2272,9 +2266,9 @@ mod content {
where
E: de::Error,
{
fn new(vec: &'a [Content<'de>]) -> Self {
fn new(slice: &'a [Content<'de>]) -> Self {
SeqRefDeserializer {
iter: vec.into_iter(),
iter: slice.iter(),
err: PhantomData,
}
}
@@ -2350,7 +2344,7 @@ mod content {
{
fn new(map: &'a [(Content<'de>, Content<'de>)]) -> Self {
MapRefDeserializer {
iter: map.into_iter(),
iter: map.iter(),
value: None,
err: PhantomData,
}
@@ -2470,10 +2464,11 @@ mod content {
Ok(())
}
fn visit_map<M>(self, _: M) -> Result<(), M::Error>
fn visit_map<M>(self, mut access: M) -> Result<(), M::Error>
where
M: MapAccess<'de>,
{
while let Some(_) = try!(access.next_entry::<IgnoredAny, IgnoredAny>()) {}
Ok(())
}
}
@@ -2723,7 +2718,7 @@ where
where
V: Visitor<'de>,
{
visitor.visit_map(FlatMapAccess::new(self.0.iter_mut(), None))
visitor.visit_map(FlatMapAccess::new(self.0.iter()))
}
fn deserialize_struct<V>(
@@ -2735,7 +2730,7 @@ where
where
V: Visitor<'de>,
{
visitor.visit_map(FlatMapAccess::new(self.0.iter_mut(), Some(fields)))
visitor.visit_map(FlatStructAccess::new(self.0.iter_mut(), fields))
}
fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
@@ -2784,22 +2779,19 @@ where
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatMapAccess<'a, 'de: 'a, E> {
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
pending_content: Option<Content<'de>>,
fields: Option<&'static [&'static str]>,
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::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
fields: Option<&'static [&'static str]>,
iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
) -> FlatMapAccess<'a, 'de, E> {
FlatMapAccess {
iter: iter,
pending_content: None,
fields: fields,
_marker: PhantomData,
}
}
@@ -2812,6 +2804,61 @@ where
{
type Error = E;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
while let Some(item) = self.iter.next() {
// Items in the vector are nulled out when used by a struct.
if let Some((ref key, ref content)) = *item {
self.pending_content = Some(content);
return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
}
}
Ok(None)
}
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeSeed<'de>,
{
match self.pending_content.take() {
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
None => Err(Error::custom("value is missing")),
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatStructAccess<'a, 'de: 'a, E> {
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
pending_content: Option<Content<'de>>,
fields: &'static [&'static str],
_marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> FlatStructAccess<'a, 'de, E> {
fn new(
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
fields: &'static [&'static str],
) -> FlatStructAccess<'a, 'de, E> {
FlatStructAccess {
iter: iter,
pending_content: None,
fields: fields,
_marker: PhantomData,
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'a, 'de, E>
where
E: Error,
{
type Error = E;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
@@ -2822,13 +2869,7 @@ where
// 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(self.fields.is_none(), |key| {
match self.fields {
None => true,
Some(fields) if fields.contains(&key) => true,
_ => false,
}
}),
Some((ref c, _)) => c.as_str().map_or(false, |key| self.fields.contains(&key)),
};
if use_item {
@@ -2869,18 +2910,17 @@ where
where
T: DeserializeSeed<'de>,
{
match self.iter.next() {
Some(item) => {
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.
let (ref key, ref content) = *item.as_ref().unwrap();
self.pending = Some(content);
seed.deserialize(ContentRefDeserializer::new(key)).map(Some)
return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
}
None => Ok(None),
}
Ok(None)
}
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
+2 -10
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[doc(hidden)]
#[macro_export]
macro_rules! __private_serialize {
@@ -32,7 +24,7 @@ macro_rules! __private_deserialize {
/// Used only by Serde doc tests. Not public API.
#[doc(hidden)]
#[macro_export]
#[macro_export(local_inner_macros)]
macro_rules! __serialize_unimplemented {
($($func:ident)*) => {
$(
@@ -52,7 +44,7 @@ macro_rules! __serialize_unimplemented_method {
}
#[doc(hidden)]
#[macro_export]
#[macro_export(local_inner_macros)]
macro_rules! __serialize_unimplemented_helper {
(bool) => {
__serialize_unimplemented_method!(serialize_bool(bool) -> Ok);
-8
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod macros;
pub mod de;
+9 -20
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
@@ -409,10 +401,9 @@ mod content {
}
fn end(mut self) -> Result<M::Ok, M::Error> {
try!(
self.map
.serialize_value(&Content::TupleStruct(self.name, self.fields))
);
try!(self
.map
.serialize_value(&Content::TupleStruct(self.name, self.fields)));
self.map.end()
}
}
@@ -454,10 +445,9 @@ mod content {
}
fn end(mut self) -> Result<M::Ok, M::Error> {
try!(
self.map
.serialize_value(&Content::Struct(self.name, self.fields))
);
try!(self
.map
.serialize_value(&Content::Struct(self.name, self.fields)));
self.map.end()
}
}
@@ -1328,10 +1318,9 @@ where
}
fn end(self) -> Result<(), Self::Error> {
try!(
self.map
.serialize_value(&Content::Struct(self.name, self.fields))
);
try!(self
.map
.serialize_value(&Content::Struct(self.name, self.fields)));
Ok(())
}
}
+53 -17
View File
@@ -1,17 +1,6 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
use ser::{Serialize, SerializeTuple, Serializer};
#[cfg(feature = "std")]
use ser::Error;
use ser::{Error, Serialize, SerializeTuple, Serializer};
////////////////////////////////////////////////////////////////////////////////
@@ -72,6 +61,15 @@ impl Serialize for String {
}
}
impl<'a> Serialize for fmt::Arguments<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_str(self)
}
}
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
@@ -221,8 +219,7 @@ seq_impl!(VecDeque<T>);
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl<Idx> Serialize for ops::Range<Idx>
impl<Idx> Serialize for Range<Idx>
where
Idx: Serialize,
{
@@ -240,6 +237,25 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(range_inclusive)]
impl<Idx> Serialize for RangeInclusive<Idx>
where
Idx: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("RangeInclusive", 2));
try!(state.serialize_field("start", &self.start()));
try!(state.serialize_field("end", &self.end()));
state.end()
}
}
////////////////////////////////////////////////////////////////////////////////
impl Serialize for () {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -250,6 +266,16 @@ impl Serialize for () {
}
}
#[cfg(feature = "unstable")]
impl Serialize for ! {
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
*self
}
}
////////////////////////////////////////////////////////////////////////////////
macro_rules! tuple_impls {
@@ -435,10 +461,17 @@ nonzero_integers! {
NonZeroU16,
NonZeroU32,
NonZeroU64,
// FIXME: https://github.com/serde-rs/serde/issues/1136 NonZeroU128,
NonZeroUsize,
}
// Currently 128-bit integers do not work on Emscripten targets so we need an
// additional `#[cfg]`
serde_if_integer128! {
nonzero_integers! {
NonZeroU128,
}
}
impl<T> Serialize for Cell<T>
where
T: Serialize + Copy,
@@ -459,7 +492,10 @@ where
where
S: Serializer,
{
self.borrow().serialize(serializer)
match self.try_borrow() {
Ok(value) => value.serialize(serializer),
Err(_) => Err(S::Error::custom("already mutably borrowed")),
}
}
}
@@ -517,7 +553,7 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
#[cfg(any(core_duration, feature = "std"))]
impl Serialize for Duration {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
-8
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! This module contains `Impossible` serializer and its implementations.
use lib::*;
+133 -52
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Generic data structure serialization framework.
//!
//! The two most important traits in this module are [`Serialize`] and
@@ -24,8 +16,7 @@
//!
//! Additionally, Serde provides a procedural macro called [`serde_derive`] to
//! automatically generate [`Serialize`] implementations for structs and enums
//! in your program. See the [codegen section of the manual] for how to use
//! this.
//! in your program. See the [derive section of the manual] for how to use this.
//!
//! In rare cases it may be necessary to implement [`Serialize`] manually for
//! some type in your program. See the [Implementing `Serialize`] section of the
@@ -55,8 +46,8 @@
//! - str
//! - &T and &mut T
//! - **Compound types**:
//! - [T]
//! - [T; 0] through [T; 32]
//! - \[T\]
//! - \[T; 0\] through \[T; 32\]
//! - tuples up to size 16
//! - **Common standard library types**:
//! - String
@@ -92,7 +83,9 @@
//! - Path
//! - PathBuf
//! - Range\<T\>
//! - num::NonZero* (unstable)
//! - RangeInclusive\<T\>
//! - num::NonZero*
//! - `!` *(unstable)*
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
@@ -110,7 +103,7 @@
//! [`serde_derive`]: https://crates.io/crates/serde_derive
//! [`serde_json`]: https://github.com/serde-rs/json
//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml
//! [codegen section of the manual]: https://serde.rs/codegen.html
//! [derive section of the manual]: https://serde.rs/derive.html
//! [data formats]: https://serde.rs/#data-formats
use lib::*;
@@ -127,6 +120,13 @@ macro_rules! declare_error_trait {
/// Trait used by `Serialize` implementations to generically construct
/// errors belonging to the `Serializer` against which they are
/// currently running.
///
/// # Example implementation
///
/// The [example data format] presented on the website shows an error
/// type appropriate for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait Error: Sized $(+ $($supertrait)::+)* {
/// Used when a [`Serialize`] implementation encounters any error
/// while serializing a type.
@@ -187,7 +187,7 @@ declare_error_trait!(Error: Sized + Debug + Display);
///
/// Additionally, Serde provides a procedural macro called [`serde_derive`] to
/// automatically generate `Serialize` implementations for structs and enums in
/// your program. See the [codegen section of the manual] for how to use this.
/// your program. See the [derive section of the manual] for how to use this.
///
/// In rare cases it may be necessary to implement `Serialize` manually for some
/// type in your program. See the [Implementing `Serialize`] section of the
@@ -202,7 +202,7 @@ declare_error_trait!(Error: Sized + Debug + Display);
/// [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
/// [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
/// [`serde_derive`]: https://crates.io/crates/serde_derive
/// [codegen section of the manual]: https://serde.rs/codegen.html
/// [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.
@@ -211,7 +211,7 @@ pub trait Serialize {
/// information about how to implement this method.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStruct};
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Person {
/// name: String,
@@ -244,10 +244,10 @@ pub trait Serialize {
/// A **data format** that can serialize any data structure supported by Serde.
///
/// The role of this trait is to define the serialization half of the Serde data
/// model, which is a way to categorize every Rust data structure into one of 29
/// possible types. Each method of the `Serializer` trait corresponds to one of
/// the types of the data model.
/// The role of this trait is to define the serialization half of the [Serde
/// data model], which is a way to categorize every Rust data structure into one
/// of 29 possible types. Each method of the `Serializer` trait corresponds to
/// one of the types of the data model.
///
/// Implementations of `Serialize` map themselves into this data model by
/// invoking exactly one of the `Serializer` methods.
@@ -264,17 +264,17 @@ pub trait Serialize {
/// - UTF-8 bytes with a length and no null terminator.
/// - When serializing, all strings are handled equally. When deserializing,
/// there are three flavors of strings: transient, owned, and borrowed.
/// - **byte array** - [u8]
/// - Similar to strings, during deserialization byte arrays can be transient,
/// owned, or borrowed.
/// - **byte array** - \[u8\]
/// - Similar to strings, during deserialization byte arrays can be
/// transient, owned, or borrowed.
/// - **option**
/// - Either none or some value.
/// - **unit**
/// - The type of `()` in Rust. It represents an anonymous value containing no
/// data.
/// - The type of `()` in Rust. It represents an anonymous value containing
/// no data.
/// - **unit_struct**
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named value
/// containing no data.
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named
/// value containing no data.
/// - **unit_variant**
/// - For example the `E::A` and `E::B` in `enum E { A, B }`.
/// - **newtype_struct**
@@ -282,14 +282,15 @@ pub trait Serialize {
/// - **newtype_variant**
/// - For example the `E::N` in `enum E { N(u8) }`.
/// - **seq**
/// - A variably sized heterogeneous sequence of values, for example `Vec<T>` or
/// `HashSet<T>`. When serializing, the length may or may not be known before
/// iterating through all the data. When deserializing, the length is determined
/// by looking at the serialized data.
/// - A variably sized heterogeneous sequence of values, for example
/// `Vec<T>` or `HashSet<T>`. When serializing, the length may or may not
/// be known before iterating through all the data. When deserializing,
/// the length is determined by looking at the serialized data.
/// - **tuple**
/// - A statically sized heterogeneous sequence of values for which the length
/// will be known at deserialization time without looking at the serialized
/// data, for example `(u8,)` or `(String, u64, Vec<T>)` or `[u64; 10]`.
/// - A statically sized heterogeneous sequence of values for which the
/// length will be known at deserialization time without looking at the
/// serialized data, for example `(u8,)` or `(String, u64, Vec<T>)` or
/// `[u64; 10]`.
/// - **tuple_struct**
/// - A named tuple, for example `struct Rgb(u8, u8, u8)`.
/// - **tuple_variant**
@@ -297,9 +298,9 @@ pub trait Serialize {
/// - **map**
/// - A heterogeneous key-value pairing, for example `BTreeMap<K, V>`.
/// - **struct**
/// - A heterogeneous key-value pairing in which the keys are strings and will be
/// known at deserialization time without looking at the serialized data, for
/// example `struct S { r: u8, g: u8, b: u8 }`.
/// - A heterogeneous key-value pairing in which the keys are strings and
/// will be known at deserialization time without looking at the
/// serialized data, for example `struct S { r: u8, g: u8, b: u8 }`.
/// - **struct_variant**
/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
///
@@ -309,6 +310,15 @@ pub trait Serialize {
/// is the `serde_json::value::Serializer` (distinct from the main `serde_json`
/// serializer) that produces a `serde_json::Value` data structure in memory as
/// output.
///
/// [Serde data model]: https://serde.rs/data-model.html
///
/// # Example implementation
///
/// The [example data format] presented on the website contains example code for
/// a basic JSON `Serializer`.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait Serializer: Sized {
/// The output type produced by this `Serializer` during successful
/// serialization. Most serializers that produce text or binary output
@@ -1093,7 +1103,7 @@ pub trait Serializer: Sized {
/// ```
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTuple};
/// use serde::ser::{Serialize, SerializeTuple, Serializer};
///
/// const VRAM_SIZE: usize = 386;
/// struct Vram([u16; VRAM_SIZE]);
@@ -1121,7 +1131,7 @@ pub trait Serializer: Sized {
/// of data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleStruct};
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
///
/// struct Rgb(u8, u8, u8);
///
@@ -1153,7 +1163,7 @@ pub trait Serializer: Sized {
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleVariant};
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
///
/// enum E {
/// T(u8, u8),
@@ -1247,7 +1257,7 @@ pub trait Serializer: Sized {
/// data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStruct};
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Rgb {
/// r: u8,
@@ -1283,10 +1293,10 @@ pub trait Serializer: Sized {
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
///
/// enum E {
/// S { r: u8, g: u8, b: u8 }
/// S { r: u8, g: u8, b: u8 },
/// }
///
/// impl Serialize for E {
@@ -1295,7 +1305,11 @@ pub trait Serializer: Sized {
/// S: Serializer,
/// {
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// E::S {
/// ref r,
/// ref g,
/// ref b,
/// } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
@@ -1358,8 +1372,8 @@ pub trait Serializer: Sized {
/// method.
///
/// ```rust
/// use std::collections::BTreeSet;
/// use serde::{Serialize, Serializer};
/// use std::collections::BTreeSet;
///
/// struct MapToUnit {
/// keys: BTreeSet<i32>,
@@ -1520,6 +1534,8 @@ pub trait Serializer: Sized {
/// Returned from `Serializer::serialize_seq`.
///
/// # Example use
///
/// ```rust
/// # use std::marker::PhantomData;
/// #
@@ -1557,6 +1573,13 @@ pub trait Serializer: Sized {
/// }
/// }
/// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeSeq` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeSeq {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1575,6 +1598,8 @@ pub trait SerializeSeq {
/// Returned from `Serializer::serialize_tuple`.
///
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTuple};
///
@@ -1648,6 +1673,13 @@ pub trait SerializeSeq {
/// }
/// }
/// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeTuple` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeTuple {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1666,8 +1698,10 @@ pub trait SerializeTuple {
/// Returned from `Serializer::serialize_tuple_struct`.
///
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleStruct};
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
///
/// struct Rgb(u8, u8, u8);
///
@@ -1684,6 +1718,13 @@ pub trait SerializeTuple {
/// }
/// }
/// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeTupleStruct` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeTupleStruct {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1702,8 +1743,10 @@ pub trait SerializeTupleStruct {
/// Returned from `Serializer::serialize_tuple_variant`.
///
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleVariant};
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
///
/// enum E {
/// T(u8, u8),
@@ -1733,6 +1776,13 @@ pub trait SerializeTupleStruct {
/// }
/// }
/// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeTupleVariant` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeTupleVariant {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1751,6 +1801,8 @@ pub trait SerializeTupleVariant {
/// Returned from `Serializer::serialize_map`.
///
/// # Example use
///
/// ```rust
/// # use std::marker::PhantomData;
/// #
@@ -1790,6 +1842,13 @@ pub trait SerializeTupleVariant {
/// }
/// }
/// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeMap` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeMap {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1853,8 +1912,10 @@ pub trait SerializeMap {
/// Returned from `Serializer::serialize_struct`.
///
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStruct};
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Rgb {
/// r: u8,
@@ -1875,6 +1936,13 @@ pub trait SerializeMap {
/// }
/// }
/// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeStruct` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeStruct {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
@@ -1904,11 +1972,13 @@ pub trait SerializeStruct {
/// Returned from `Serializer::serialize_struct_variant`.
///
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
///
/// enum E {
/// S { r: u8, g: u8, b: u8 }
/// S { r: u8, g: u8, b: u8 },
/// }
///
/// impl Serialize for E {
@@ -1917,7 +1987,11 @@ pub trait SerializeStruct {
/// S: Serializer,
/// {
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// E::S {
/// ref r,
/// ref g,
/// ref b,
/// } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
@@ -1928,6 +2002,13 @@ pub trait SerializeStruct {
/// }
/// }
/// ```
///
/// # Example implementation
///
/// The [example data format] presented on the website demonstrates an
/// implementation of `SerializeStructVariant` for a basic JSON data format.
///
/// [example data format]: https://serde.rs/data-format.html
pub trait SerializeStructVariant {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
+7 -6
View File
@@ -1,18 +1,19 @@
[package]
name = "serde_derive"
version = "1.0.60" # remember to update html_root_url
version = "1.0.81" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://serde.rs/codegen.html"
documentation = "https://serde.rs/derive.html"
keywords = ["serde", "serialization", "no_std"]
readme = "README.md"
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
readme = "crates-io.md"
include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[badges]
travis-ci = { repository = "serde-rs/serde" }
appveyor = { repository = "serde-rs/serde" }
[features]
default = []
@@ -24,8 +25,8 @@ proc-macro = true
[dependencies]
proc-macro2 = "0.4"
quote = "0.6"
syn = { version = "0.14", features = ["visit"] }
quote = "0.6.3"
syn = { version = "0.15.22", features = ["visit"] }
[dev-dependencies]
serde = { version = "1.0", path = "../serde" }
+1
View File
@@ -0,0 +1 @@
../crates-io.md
+26 -28
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::collections::HashSet;
use syn;
@@ -46,7 +38,7 @@ pub fn with_where_predicates(
generics
.make_where_clause()
.predicates
.extend(predicates.into_iter().cloned());
.extend(predicates.iter().cloned());
generics
}
@@ -91,7 +83,8 @@ pub fn with_where_predicates_from_variants(
// Puts the given bound on any generic type parameters that are used in fields
// for which filter returns true.
//
// For example, the following struct needs the bound `A: Serialize, B: Serialize`.
// For example, the following struct needs the bound `A: Serialize, B:
// Serialize`.
//
// struct S<'b, A, B: 'b, C> {
// a: A,
@@ -168,15 +161,17 @@ pub fn with_bound(
associated_type_usage: Vec::new(),
};
match cont.data {
Data::Enum(ref variants) => for variant in variants.iter() {
let relevant_fields = variant
.fields
.iter()
.filter(|field| filter(&field.attrs, Some(&variant.attrs)));
for field in relevant_fields {
visitor.visit_field(field.original);
Data::Enum(ref variants) => {
for variant in variants.iter() {
let relevant_fields = variant
.fields
.iter()
.filter(|field| filter(&field.attrs, Some(&variant.attrs)));
for field in relevant_fields {
visitor.visit_field(field.original);
}
}
},
}
Data::Struct(_, ref fields) => {
for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
visitor.visit_field(field.original);
@@ -200,15 +195,16 @@ pub fn with_bound(
lifetimes: None,
// the type parameter that is being bounded e.g. T
bounded_ty: syn::Type::Path(bounded_ty),
colon_token: Default::default(),
colon_token: <Token![:]>::default(),
// the bound e.g. Serialize
bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound {
paren_token: None,
modifier: syn::TraitBoundModifier::None,
lifetimes: None,
path: bound.clone(),
})].into_iter()
.collect(),
})]
.into_iter()
.collect(),
})
});
@@ -233,15 +229,16 @@ pub fn with_self_bound(
lifetimes: None,
// the type that is being bounded e.g. MyStruct<'a, T>
bounded_ty: type_of_item(cont),
colon_token: Default::default(),
colon_token: <Token![:]>::default(),
// the bound e.g. Default
bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound {
paren_token: None,
modifier: syn::TraitBoundModifier::None,
lifetimes: None,
path: bound.clone(),
})].into_iter()
.collect(),
})]
.into_iter()
.collect(),
}));
generics
}
@@ -289,7 +286,7 @@ fn type_of_item(cont: &Container) -> syn::Type {
arguments: syn::PathArguments::AngleBracketed(
syn::AngleBracketedGenericArguments {
colon2_token: None,
lt_token: Default::default(),
lt_token: <Token![<]>::default(),
args: cont
.generics
.params
@@ -309,11 +306,12 @@ fn type_of_item(cont: &Container) -> syn::Type {
}
})
.collect(),
gt_token: Default::default(),
gt_token: <Token![>]>::default(),
},
),
}].into_iter()
.collect(),
}]
.into_iter()
.collect(),
},
})
}
+67 -31
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use proc_macro2::{Literal, Span, TokenStream};
use quote::ToTokens;
use syn::punctuated::Punctuated;
@@ -21,17 +13,21 @@ use try;
use std::collections::BTreeSet;
pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream, String> {
pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
let ctxt = Ctxt::new();
let cont = Container::from_ast(&ctxt, input, Derive::Deserialize);
let cont = match Container::from_ast(&ctxt, input, Derive::Deserialize) {
Some(cont) => cont,
None => return Err(ctxt.check().unwrap_err()),
};
precondition(&ctxt, &cont);
try!(ctxt.check());
let ident = &cont.ident;
let params = Parameters::new(&cont);
let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
let suffix = ident.to_string().trim_left_matches("r#").to_owned();
let dummy_const = Ident::new(
&format!("_IMPL_DESERIALIZE_FOR_{}", ident),
&format!("_IMPL_DESERIALIZE_FOR_{}", suffix),
Span::call_site(),
);
let body = Stmts(deserialize_body(&cont, &params));
@@ -73,6 +69,9 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
#[allow(unknown_lints)]
#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
#[allow(rust_2018_idioms)]
extern crate serde as _serde;
#try_replacement
#impl_block
@@ -90,7 +89,7 @@ fn precondition_sized(cx: &Ctxt, cont: &Container) {
if let Data::Struct(_, ref fields) = cont.data {
if let Some(last) = fields.last() {
if let syn::Type::Slice(_) = *last.ty {
cx.error("cannot deserialize a dynamically sized struct");
cx.error_spanned_by(cont.original, "cannot deserialize a dynamically sized struct");
}
}
}
@@ -100,7 +99,10 @@ fn precondition_no_de_lifetime(cx: &Ctxt, cont: &Container) {
if let BorrowedLifetimes::Borrowed(_) = borrowed_lifetimes(cont) {
for param in cont.generics.lifetimes() {
if param.lifetime.to_string() == "'de" {
cx.error("cannot deserialize when there is a lifetime parameter called 'de");
cx.error_spanned_by(
&param.lifetime,
"cannot deserialize when there is a lifetime parameter called 'de",
);
return;
}
}
@@ -201,7 +203,9 @@ fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generi
// All other fields may need a `T: Deserialize` bound where T is the type of the
// field.
fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
!field.skip_deserializing() && field.deserialize_with().is_none() && field.de_bound().is_none()
!field.skip_deserializing()
&& field.deserialize_with().is_none()
&& field.de_bound().is_none()
&& variant.map_or(true, |variant| {
!variant.skip_deserializing()
&& variant.deserialize_with().is_none()
@@ -359,7 +363,10 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
let path = match transparent_field.attrs.deserialize_with() {
Some(path) => quote!(#path),
None => quote!(_serde::Deserialize::deserialize),
None => {
let span = transparent_field.original.span();
quote_spanned!(span=> _serde::Deserialize::deserialize)
},
};
let assign = fields.iter().map(|field| {
@@ -799,8 +806,10 @@ fn deserialize_newtype_struct(
let value = match field.attrs.deserialize_with() {
None => {
let span = field.original.span();
let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
quote! {
try!(<#field_ty as _serde::Deserialize>::deserialize(__e))
try!(#func(__e))
}
}
Some(path) => {
@@ -832,7 +841,8 @@ fn deserialize_newtype_struct(
#[cfg(feature = "deserialize_in_place")]
fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> TokenStream {
// We do not generate deserialize_in_place if every field has a deserialize_with.
// We do not generate deserialize_in_place if every field has a
// deserialize_with.
assert!(field.attrs.deserialize_with().is_none());
let delife = params.borrowed.de_lifetime();
@@ -936,8 +946,8 @@ fn deserialize_struct(
quote!(mut __seq)
};
// untagged struct variants do not get a visit_seq method. The same applies to structs that
// only have a map representation.
// untagged struct variants do not get a visit_seq method. The same applies to
// structs that only have a map representation.
let visit_seq = match *untagged {
Untagged::No if !cattrs.has_flatten() => Some(quote! {
#[inline]
@@ -1150,6 +1160,10 @@ fn deserialize_externally_tagged_enum(
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
.collect();
let other_idx = variants
.iter()
.position(|ref variant| variant.attrs.other());
let variants_stmt = {
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
quote! {
@@ -1161,6 +1175,7 @@ fn deserialize_externally_tagged_enum(
&variant_names_idents,
cattrs,
true,
other_idx,
));
// Match arms to extract a variant from a string
@@ -1248,6 +1263,10 @@ fn deserialize_internally_tagged_enum(
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
.collect();
let other_idx = variants
.iter()
.position(|ref variant| variant.attrs.other());
let variants_stmt = {
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
quote! {
@@ -1259,6 +1278,7 @@ fn deserialize_internally_tagged_enum(
&variant_names_idents,
cattrs,
true,
other_idx,
));
// Match arms to extract a variant from a string
@@ -1317,6 +1337,10 @@ fn deserialize_adjacently_tagged_enum(
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)))
.collect();
let other_idx = variants
.iter()
.position(|ref variant| variant.attrs.other());
let variants_stmt = {
let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
quote! {
@@ -1328,6 +1352,7 @@ fn deserialize_adjacently_tagged_enum(
&variant_names_idents,
cattrs,
true,
other_idx,
));
let variant_arms: &Vec<_> = &variants
@@ -1789,10 +1814,10 @@ fn deserialize_externally_tagged_newtype_variant(
match field.attrs.deserialize_with() {
None => {
let field_ty = field.ty;
let span = field.original.span();
let func = quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>);
quote_expr! {
_serde::export::Result::map(
_serde::de::VariantAccess::newtype_variant::<#field_ty>(__variant),
#this::#variant_ident)
_serde::export::Result::map(#func(__variant), #this::#variant_ident)
}
}
Some(path) => {
@@ -1817,10 +1842,10 @@ fn deserialize_untagged_newtype_variant(
let field_ty = field.ty;
match field.attrs.deserialize_with() {
None => {
let span = field.original.span();
let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
quote_expr! {
_serde::export::Result::map(
<#field_ty as _serde::Deserialize>::deserialize(#deserializer),
#this::#variant_ident)
_serde::export::Result::map(#func(#deserializer), #this::#variant_ident)
}
}
Some(path) => {
@@ -1836,6 +1861,7 @@ fn deserialize_generated_identifier(
fields: &[(String, Ident)],
cattrs: &attr::Container,
is_variant: bool,
other_idx: Option<usize>,
) -> Fragment {
let this = quote!(__Field);
let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect();
@@ -1844,6 +1870,10 @@ fn deserialize_generated_identifier(
let ignore_variant = quote!(__other(_serde::private::de::Content<'de>),);
let fallthrough = quote!(_serde::export::Ok(__Field::__other(__value)));
(Some(ignore_variant), Some(fallthrough))
} else if let Some(other_idx) = other_idx {
let ignore_variant = fields[other_idx].1.clone();
let fallthrough = quote!(_serde::export::Ok(__Field::#ignore_variant));
(None, Some(fallthrough))
} else if is_variant || cattrs.deny_unknown_fields() {
(None, None)
} else {
@@ -2267,7 +2297,7 @@ fn deserialize_struct_as_struct_visitor(
}
};
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false);
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
let visit_map = deserialize_map(struct_path, params, fields, cattrs);
@@ -2287,7 +2317,7 @@ fn deserialize_struct_as_map_visitor(
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)))
.collect();
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false);
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
let visit_map = deserialize_map(struct_path, params, fields, cattrs);
@@ -2422,7 +2452,10 @@ fn deserialize_map(
.map(|&(field, ref name)| {
let field_ty = field.ty;
let func = match field.attrs.deserialize_with() {
None => quote!(_serde::de::Deserialize::deserialize),
None => {
let span = field.original.span();
quote_spanned!(span=> _serde::de::Deserialize::deserialize)
},
Some(path) => quote!(#path),
};
quote! {
@@ -2522,7 +2555,7 @@ fn deserialize_struct_as_struct_in_place_visitor(
}
};
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false);
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
let visit_map = deserialize_map_in_place(params, fields, cattrs);
@@ -2544,7 +2577,8 @@ fn deserialize_map_in_place(
.map(|(i, field)| (field, field_i(i)))
.collect();
// For deserialize_in_place, declare booleans for each field that will be deserialized.
// For deserialize_in_place, declare booleans for each field that will be
// deserialized.
let let_flags = fields_names
.iter()
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
@@ -2773,7 +2807,9 @@ fn wrap_deserialize_variant_with(
fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
match *field.attrs.default() {
attr::Default::Default => {
return quote_expr!(_serde::export::Default::default());
let span = field.original.span();
let func = quote_spanned!(span=> _serde::export::Default::default);
return quote_expr!(#func());
}
attr::Default::Path(ref path) => {
return quote_expr!(#path());
-8
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use proc_macro2::TokenStream;
use quote::ToTokens;
use syn::token;
+41 -21
View File
@@ -1,10 +1,4 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! A Serde ast, parsed from the Syn ast and ready to generate Rust code.
use internals::attr;
use internals::check;
@@ -12,25 +6,39 @@ use internals::{Ctxt, Derive};
use syn;
use syn::punctuated::Punctuated;
/// A source data structure annotated with `#[derive(Serialize)]` and/or `#[derive(Deserialize)]`,
/// parsed into an internal representation.
pub struct Container<'a> {
/// The struct or enum name (without generics).
pub ident: syn::Ident,
/// Attributes on the structure, parsed for Serde.
pub attrs: attr::Container,
/// The contents of the struct or enum.
pub data: Data<'a>,
/// Any generics on the struct or enum.
pub generics: &'a syn::Generics,
/// Original input.
pub original: &'a syn::DeriveInput,
}
/// The fields of a struct or enum.
///
/// Analagous to `syn::Data`.
pub enum Data<'a> {
Enum(Vec<Variant<'a>>),
Struct(Style, Vec<Field<'a>>),
}
/// A variant of an enum.
pub struct Variant<'a> {
pub ident: syn::Ident,
pub attrs: attr::Variant,
pub style: Style,
pub fields: Vec<Field<'a>>,
pub original: &'a syn::Variant,
}
/// A field of a struct.
pub struct Field<'a> {
pub member: syn::Member,
pub attrs: attr::Field,
@@ -40,14 +48,19 @@ pub struct Field<'a> {
#[derive(Copy, Clone)]
pub enum Style {
/// Named fields.
Struct,
/// Many unnamed fields.
Tuple,
/// One unnamed field.
Newtype,
/// No fields.
Unit,
}
impl<'a> Container<'a> {
pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput, derive: Derive) -> Container<'a> {
/// Convert the raw Syn ast into a parsed container object, collecting errors in `cx`.
pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput, derive: Derive) -> Option<Container<'a>> {
let mut attrs = attr::Container::from_ast(cx, item);
let mut data = match item.data {
@@ -59,27 +72,32 @@ impl<'a> Container<'a> {
Data::Struct(style, fields)
}
syn::Data::Union(_) => {
panic!("Serde does not support derive for unions");
cx.error_spanned_by(item, "Serde does not support derive for unions");
return None;
}
};
let mut has_flatten = false;
match data {
Data::Enum(ref mut variants) => for variant in variants {
variant.attrs.rename_by_rule(attrs.rename_all());
for field in &mut variant.fields {
Data::Enum(ref mut variants) => {
for variant in variants {
variant.attrs.rename_by_rule(attrs.rename_all());
for field in &mut variant.fields {
if field.attrs.flatten() {
has_flatten = true;
}
field.attrs.rename_by_rule(variant.attrs.rename_all());
}
}
}
Data::Struct(_, ref mut fields) => {
for field in fields {
if field.attrs.flatten() {
has_flatten = true;
}
field.attrs.rename_by_rule(variant.attrs.rename_all());
field.attrs.rename_by_rule(attrs.rename_all());
}
},
Data::Struct(_, ref mut fields) => for field in fields {
if field.attrs.flatten() {
has_flatten = true;
}
field.attrs.rename_by_rule(attrs.rename_all());
},
}
}
if has_flatten {
@@ -91,9 +109,10 @@ impl<'a> Container<'a> {
attrs: attrs,
data: data,
generics: &item.generics,
original: item,
};
check::check(cx, &mut item, derive);
item
Some(item)
}
}
@@ -128,6 +147,7 @@ fn enum_from_ast<'a>(
attrs: attrs,
style: style,
fields: fields,
original: variant,
}
})
.collect()
File diff suppressed because it is too large Load Diff
+11 -10
View File
@@ -1,10 +1,5 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Code to convert the Rust-styled field/variant (e.g. `my_field`, `MyType`) to the
//! case of the source (e.g. `my-field`, `MY_FIELD`).
// See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
#[allow(deprecated, unused_imports)]
@@ -14,6 +9,7 @@ use std::str::FromStr;
use self::RenameRule::*;
/// The different possible ways to change case of fields in a struct, or variants in an enum.
#[derive(PartialEq)]
pub enum RenameRule {
/// Don't apply a default rename rule.
@@ -22,13 +18,16 @@ pub enum RenameRule {
LowerCase,
/// Rename direct children to "UPPERCASE" style.
UPPERCASE,
/// Rename direct children to "PascalCase" style, as typically used for enum variants.
/// Rename direct children to "PascalCase" style, as typically used for
/// enum variants.
PascalCase,
/// Rename direct children to "camelCase" style.
CamelCase,
/// Rename direct children to "snake_case" style, as commonly used for fields.
/// Rename direct children to "snake_case" style, as commonly used for
/// fields.
SnakeCase,
/// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly used for constants.
/// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly
/// used for constants.
ScreamingSnakeCase,
/// Rename direct children to "kebab-case" style.
KebabCase,
@@ -37,6 +36,7 @@ pub enum RenameRule {
}
impl RenameRule {
/// 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(),
@@ -61,6 +61,7 @@ impl RenameRule {
}
}
/// Apply a renaming rule to a struct field, returning the version expected in the source.
pub fn apply_to_field(&self, field: &str) -> String {
match *self {
None | LowerCase | SnakeCase => field.to_owned(),
+104 -54
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use internals::ast::{Container, Data, Field, Style};
use internals::attr::{EnumTag, Identifier};
use internals::{Ctxt, Derive};
@@ -29,12 +21,16 @@ fn check_getter(cx: &Ctxt, cont: &Container) {
match cont.data {
Data::Enum(_) => {
if cont.data.has_getter() {
cx.error("#[serde(getter = \"...\")] is not allowed in an enum");
cx.error_spanned_by(
cont.original,
"#[serde(getter = \"...\")] is not allowed in an enum",
);
}
}
Data::Struct(_, _) => {
if cont.data.has_getter() && cont.attrs.remote().is_none() {
cx.error(
cx.error_spanned_by(
cont.original,
"#[serde(getter = \"...\")] can only be used in structs \
that have #[serde(remote = \"...\")]",
);
@@ -67,33 +63,42 @@ fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
}
match style {
Style::Tuple => {
cx.error("#[serde(flatten)] cannot be used on tuple structs");
cx.error_spanned_by(
field.original,
"#[serde(flatten)] cannot be used on tuple structs",
);
}
Style::Newtype => {
cx.error("#[serde(flatten)] cannot be used on newtype structs");
cx.error_spanned_by(
field.original,
"#[serde(flatten)] cannot be used on newtype structs",
);
}
_ => {}
}
if field.attrs.skip_serializing() {
cx.error(
"#[serde(flatten] can not be combined with \
cx.error_spanned_by(
field.original,
"#[serde(flatten)] can not be combined with \
#[serde(skip_serializing)]",
);
} else if field.attrs.skip_serializing_if().is_some() {
cx.error(
"#[serde(flatten] can not be combined with \
cx.error_spanned_by(
field.original,
"#[serde(flatten)] can not be combined with \
#[serde(skip_serializing_if = \"...\")]",
);
} else if field.attrs.skip_deserializing() {
cx.error(
"#[serde(flatten] can not be combined with \
cx.error_spanned_by(
field.original,
"#[serde(flatten)] can not be combined with \
#[serde(skip_deserializing)]",
);
}
}
/// The `other` attribute must be used at most once and it must be the last
/// variant of an enum that has the `field_identifier` attribute.
/// 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
@@ -111,43 +116,70 @@ fn check_identifier(cx: &Ctxt, cont: &Container) {
variant.style,
cont.attrs.identifier(),
variant.attrs.other(),
cont.attrs.tag(),
) {
// The `other` attribute may only be used in a field_identifier.
(_, Identifier::Variant, true) | (_, Identifier::No, true) => {
cx.error("#[serde(other)] may only be used inside a field_identifier");
// The `other` attribute may not be used in a variant_identifier.
(_, Identifier::Variant, true, _) => {
cx.error_spanned_by(
variant.original,
"#[serde(other)] may not be used on a variant identifier",
);
}
// Variant with `other` attribute cannot appear in untagged enum
(_, Identifier::No, true, &EnumTag::None) => {
cx.error_spanned_by(
variant.original,
"#[serde(other)] cannot appear on untagged enum",
);
}
// Variant with `other` attribute must be the last one.
(Style::Unit, Identifier::Field, true) => {
(Style::Unit, Identifier::Field, true, _) | (Style::Unit, Identifier::No, true, _) => {
if i < variants.len() - 1 {
cx.error("#[serde(other)] must be the last variant");
cx.error_spanned_by(
variant.original,
"#[serde(other)] must be on the last variant",
);
}
}
// Variant with `other` attribute must be a unit variant.
(_, Identifier::Field, true) => {
cx.error("#[serde(other)] must be on a unit variant");
(_, Identifier::Field, true, _) | (_, Identifier::No, true, _) => {
cx.error_spanned_by(
variant.original,
"#[serde(other)] must be on a unit variant",
);
}
// Any sort of variant is allowed if this is not an identifier.
(_, Identifier::No, false) => {}
(_, Identifier::No, false, _) => {}
// Unit variant without `other` attribute is always fine.
(Style::Unit, _, false) => {}
(Style::Unit, _, false, _) => {}
// The last field is allowed to be a newtype catch-all.
(Style::Newtype, Identifier::Field, false) => {
(Style::Newtype, Identifier::Field, false, _) => {
if i < variants.len() - 1 {
cx.error(format!("`{}` must be the last variant", variant.ident));
cx.error_spanned_by(
variant.original,
format!("`{}` must be the last variant", variant.ident),
);
}
}
(_, Identifier::Field, false) => {
cx.error("field_identifier may only contain unit variants");
(_, Identifier::Field, false, _) => {
cx.error_spanned_by(
variant.original,
"#[serde(field_identifier)] may only contain unit variants",
);
}
(_, Identifier::Variant, false) => {
cx.error("variant_identifier may only contain unit variants");
(_, Identifier::Variant, false, _) => {
cx.error_spanned_by(
variant.original,
"#[serde(variant_identifier)] may only contain unit variants",
);
}
}
}
@@ -166,7 +198,7 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
for variant in variants.iter() {
if variant.attrs.serialize_with().is_some() {
if variant.attrs.skip_serializing() {
cx.error(format!(
cx.error_spanned_by(variant.original, format!(
"variant `{}` cannot have both #[serde(serialize_with)] and \
#[serde(skip_serializing)]",
variant.ident
@@ -177,7 +209,7 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
let member = member_message(&field.member);
if field.attrs.skip_serializing() {
cx.error(format!(
cx.error_spanned_by(variant.original, format!(
"variant `{}` cannot have both #[serde(serialize_with)] and \
a field {} marked with #[serde(skip_serializing)]",
variant.ident, member
@@ -185,7 +217,7 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
}
if field.attrs.skip_serializing_if().is_some() {
cx.error(format!(
cx.error_spanned_by(variant.original, format!(
"variant `{}` cannot have both #[serde(serialize_with)] and \
a field {} marked with #[serde(skip_serializing_if)]",
variant.ident, member
@@ -196,7 +228,7 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
if variant.attrs.deserialize_with().is_some() {
if variant.attrs.skip_deserializing() {
cx.error(format!(
cx.error_spanned_by(variant.original, format!(
"variant `{}` cannot have both #[serde(deserialize_with)] and \
#[serde(skip_deserializing)]",
variant.ident
@@ -207,7 +239,7 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
if field.attrs.skip_deserializing() {
let member = member_message(&field.member);
cx.error(format!(
cx.error_spanned_by(variant.original, format!(
"variant `{}` cannot have both #[serde(deserialize_with)] \
and a field {} marked with #[serde(skip_deserializing)]",
variant.ident, member
@@ -233,10 +265,10 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
EnumTag::External | EnumTag::Adjacent { .. } | EnumTag::None => return,
};
let diagnose_conflict = || {
let message = format!("variant field name `{}` conflicts with internal tag", tag);
cx.error(message);
};
let diagnose_conflict = || cx.error_spanned_by(
cont.original,
format!("variant field name `{}` conflicts with internal tag", tag),
);
for variant in variants {
match variant.style {
@@ -271,11 +303,10 @@ fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
};
if type_tag == content_tag {
let message = format!(
cx.error_spanned_by(cont.original, format!(
"enum tags `{}` for type and content conflict with each other",
type_tag
);
cx.error(message);
));
}
}
@@ -286,20 +317,32 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
}
if cont.attrs.type_from().is_some() {
cx.error("#[serde(transparent)] is not allowed with #[serde(from = \"...\")]");
cx.error_spanned_by(
cont.original,
"#[serde(transparent)] is not allowed with #[serde(from = \"...\")]",
);
}
if cont.attrs.type_into().is_some() {
cx.error("#[serde(transparent)] is not allowed with #[serde(into = \"...\")]");
cx.error_spanned_by(
cont.original,
"#[serde(transparent)] is not allowed with #[serde(into = \"...\")]",
);
}
let fields = match cont.data {
Data::Enum(_) => {
cx.error("#[serde(transparent)] is not allowed on an enum");
cx.error_spanned_by(
cont.original,
"#[serde(transparent)] is not allowed on an enum",
);
return;
}
Data::Struct(Style::Unit, _) => {
cx.error("#[serde(transparent)] is not allowed on a unit struct");
cx.error_spanned_by(
cont.original,
"#[serde(transparent)] is not allowed on a unit struct",
);
return;
}
Data::Struct(_, ref mut fields) => fields,
@@ -310,7 +353,8 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
for field in fields {
if allow_transparent(field, derive) {
if transparent_field.is_some() {
cx.error(
cx.error_spanned_by(
cont.original,
"#[serde(transparent)] requires struct to have at most one transparent field",
);
return;
@@ -323,10 +367,16 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
Some(transparent_field) => transparent_field.attrs.mark_transparent(),
None => match derive {
Derive::Serialize => {
cx.error("#[serde(transparent)] requires at least one field that is not skipped");
cx.error_spanned_by(
cont.original,
"#[serde(transparent)] requires at least one field that is not skipped",
);
}
Derive::Deserialize => {
cx.error("#[serde(transparent)] requires at least one field that is neither skipped nor has a default");
cx.error_spanned_by(
cont.original,
"#[serde(transparent)] requires at least one field that is neither skipped nor has a default",
);
}
},
}
@@ -335,7 +385,7 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
fn member_message(member: &Member) -> String {
match *member {
Member::Named(ref ident) => format!("`{}`", ident),
Member::Unnamed(ref i) => i.index.to_string(),
Member::Unnamed(ref i) => format!("#{}", i.index),
}
}
+23 -22
View File
@@ -1,48 +1,49 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use quote::ToTokens;
use std::cell::RefCell;
use std::fmt::Display;
use std::thread;
use syn;
/// A type to collect errors together and format them.
///
/// Dropping this object will cause a panic. It must be consumed using `check`.
///
/// References can be shared since this type uses run-time exclusive mut checking.
#[derive(Default)]
pub struct Ctxt {
errors: RefCell<Option<Vec<String>>>,
// The contents will be set to `None` during checking. This is so that checking can be
// enforced.
errors: RefCell<Option<Vec<syn::Error>>>,
}
impl Ctxt {
/// Create a new context object.
///
/// This object contains no errors, but will still trigger a panic if it is not `check`ed.
pub fn new() -> Self {
Ctxt {
errors: RefCell::new(Some(Vec::new())),
}
}
pub fn error<T: Display>(&self, msg: T) {
/// Add an error to the context object with a tokenenizable object.
///
/// The object is used for spanning in error messages.
pub fn error_spanned_by<A: ToTokens, T: Display>(&self, obj: A, msg: T) {
self.errors
.borrow_mut()
.as_mut()
.unwrap()
.push(msg.to_string());
// Curb monomorphization from generating too many identical methods.
.push(syn::Error::new_spanned(obj.into_token_stream(), msg));
}
pub fn check(self) -> Result<(), String> {
let mut errors = self.errors.borrow_mut().take().unwrap();
/// 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(()),
1 => Err(errors.pop().unwrap()),
n => {
let mut msg = format!("{} errors:", n);
for err in errors {
msg.push_str("\n\t# ");
msg.push_str(&err);
}
Err(msg)
}
_ => Err(errors),
}
}
}
-8
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub mod ast;
pub mod attr;
+33 -23
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! This crate provides Serde's two derive macros.
//!
//! ```rust
@@ -22,22 +14,37 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.60")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.81")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(
feature = "cargo-clippy",
allow(
enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding,
cyclomatic_complexity
cyclomatic_complexity,
enum_variant_names,
needless_pass_by_value,
redundant_field_names,
too_many_arguments,
used_underscore_binding,
)
)]
// Whitelisted clippy_pedantic lints
#![cfg_attr(
feature = "cargo-clippy",
allow(
items_after_statements, doc_markdown, stutter, similar_names, use_self, single_match_else,
enum_glob_use, match_same_arms, filter_map, cast_possible_truncation
cast_possible_truncation,
doc_markdown,
enum_glob_use,
filter_map,
indexing_slicing,
items_after_statements,
match_same_arms,
similar_names,
single_match_else,
stutter,
unseparated_literal_suffix,
use_self,
)
)]
// The `quote!` macro requires deep recursion.
@@ -68,18 +75,21 @@ mod try;
#[proc_macro_derive(Serialize, attributes(serde))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
let input: DeriveInput = syn::parse(input).unwrap();
match ser::expand_derive_serialize(&input) {
Ok(expanded) => expanded.into(),
Err(msg) => panic!(msg),
}
let input = parse_macro_input!(input as DeriveInput);
ser::expand_derive_serialize(&input)
.unwrap_or_else(to_compile_errors)
.into()
}
#[proc_macro_derive(Deserialize, attributes(serde))]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
let input: DeriveInput = syn::parse(input).unwrap();
match de::expand_derive_deserialize(&input) {
Ok(expanded) => expanded.into(),
Err(msg) => panic!(msg),
}
let input = parse_macro_input!(input as DeriveInput);
de::expand_derive_deserialize(&input)
.unwrap_or_else(to_compile_errors)
.into()
}
fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream {
let compile_errors = errors.iter().map(syn::Error::to_compile_error);
quote!(#(#compile_errors)*)
}
+36 -20
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use proc_macro2::{Span, TokenStream};
use syn::spanned::Spanned;
use syn::{self, Ident, Index, Member};
@@ -17,16 +9,23 @@ use internals::{attr, Ctxt, Derive};
use pretend;
use try;
pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream, String> {
pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream, Vec<syn::Error>> {
let ctxt = Ctxt::new();
let cont = Container::from_ast(&ctxt, input, Derive::Serialize);
let cont = match Container::from_ast(&ctxt, input, Derive::Serialize) {
Some(cont) => cont,
None => return Err(ctxt.check().unwrap_err()),
};
precondition(&ctxt, &cont);
try!(ctxt.check());
let ident = &cont.ident;
let params = Parameters::new(&cont);
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
let dummy_const = Ident::new(&format!("_IMPL_SERIALIZE_FOR_{}", ident), Span::call_site());
let suffix = ident.to_string().trim_left_matches("r#").to_owned();
let dummy_const = Ident::new(
&format!("_IMPL_SERIALIZE_FOR_{}", suffix),
Span::call_site(),
);
let body = Stmts(serialize_body(&cont, &params));
let impl_block = if let Some(remote) = cont.attrs.remote() {
@@ -61,6 +60,9 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
#[allow(unknown_lints)]
#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
#[allow(rust_2018_idioms)]
extern crate serde as _serde;
#try_replacement
#impl_block
@@ -73,10 +75,10 @@ fn precondition(cx: &Ctxt, cont: &Container) {
match cont.attrs.identifier() {
attr::Identifier::No => {}
attr::Identifier::Field => {
cx.error("field identifiers cannot be serialized");
cx.error_spanned_by(cont.original, "field identifiers cannot be serialized");
}
attr::Identifier::Variant => {
cx.error("variant identifiers cannot be serialized");
cx.error_spanned_by(cont.original, "variant identifiers cannot be serialized");
}
}
}
@@ -157,7 +159,9 @@ fn build_generics(cont: &Container) -> syn::Generics {
// attribute specify their own bound so we do not generate one. All other fields
// may need a `T: Serialize` bound where T is the type of the field.
fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
!field.skip_serializing() && field.serialize_with().is_none() && field.ser_bound().is_none()
!field.skip_serializing()
&& field.serialize_with().is_none()
&& field.ser_bound().is_none()
&& variant.map_or(true, |variant| {
!variant.skip_serializing()
&& variant.serialize_with().is_none()
@@ -199,7 +203,10 @@ fn serialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
let path = match transparent_field.attrs.serialize_with() {
Some(path) => quote!(#path),
None => quote!(_serde::Serialize::serialize),
None => {
let span = transparent_field.original.span();
quote_spanned!(span=> _serde::Serialize::serialize)
},
};
quote_block! {
@@ -504,8 +511,10 @@ fn serialize_externally_tagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
}
let span = field.original.span();
let func = quote_spanned!(span=> _serde::Serializer::serialize_newtype_variant);
quote_expr! {
_serde::Serializer::serialize_newtype_variant(
#func(
__serializer,
#type_name,
#variant_index,
@@ -578,8 +587,10 @@ fn serialize_internally_tagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
}
let span = field.original.span();
let func = quote_spanned!(span=> _serde::private::ser::serialize_tagged_newtype);
quote_expr! {
_serde::private::ser::serialize_tagged_newtype(
#func(
__serializer,
#enum_ident_str,
#variant_ident_str,
@@ -636,12 +647,14 @@ fn serialize_adjacently_tagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
}
let span = field.original.span();
let func = quote_spanned!(span=> _serde::ser::SerializeStruct::serialize_field);
return quote_block! {
let mut __struct = try!(_serde::Serializer::serialize_struct(
__serializer, #type_name, 2));
try!(_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name));
try!(_serde::ser::SerializeStruct::serialize_field(
try!(#func(
&mut __struct, #content, #field_expr));
_serde::ser::SerializeStruct::end(__struct)
};
@@ -737,8 +750,10 @@ fn serialize_untagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
}
let span = field.original.span();
let func = quote_spanned!(span=> _serde::Serialize::serialize);
quote_expr! {
_serde::Serialize::serialize(#field_expr, __serializer)
#func(#field_expr, __serializer)
}
}
Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
@@ -1078,8 +1093,9 @@ fn serialize_struct_visitor(
let span = field.original.span();
let ser = if field.attrs.flatten() {
let func = quote_spanned!(span=> _serde::Serialize::serialize);
quote! {
try!(_serde::Serialize::serialize(&#field_expr, _serde::private::ser::FlatMapSerializer(&mut __serde_state)));
try!(#func(&#field_expr, _serde::private::ser::FlatMapSerializer(&mut __serde_state)));
}
} else {
let func = struct_trait.serialize_field(span);
+5 -5
View File
@@ -1,22 +1,22 @@
[package]
name = "serde_derive_internals"
version = "0.23.1" # remember to update html_root_url
version = "0.24.1" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "AST representation used by Serde derive macros. Unstable."
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde_derive_internals/"
documentation = "https://docs.rs/serde_derive_internals"
keywords = ["serde", "serialization"]
readme = "README.md"
include = ["Cargo.toml", "lib.rs", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
include = ["Cargo.toml", "lib.rs", "src/**/*.rs", "LICENSE-APACHE", "LICENSE-MIT"]
[lib]
path = "lib.rs"
[dependencies]
proc-macro2 = "0.4"
syn = { version = "0.14", default-features = false, features = ["derive", "parsing", "clone-impls"] }
syn = { version = "0.15", default-features = false, features = ["derive", "parsing", "clone-impls"] }
[badges]
travis-ci = { repository = "serde-rs/serde" }
appveyor = { repository = "serde-rs/serde" }
-1
View File
@@ -1 +0,0 @@
../README.md
+8 -10
View File
@@ -1,15 +1,13 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.23.1")]
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.24.1")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(
feature = "cargo-clippy",
allow(cyclomatic_complexity, doc_markdown, match_same_arms, redundant_field_names)
allow(
cyclomatic_complexity,
doc_markdown,
match_same_arms,
redundant_field_names
)
)]
#[macro_use]
+6 -5
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_test"
version = "1.0.60" # remember to update html_root_url
version = "1.0.81" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations"
@@ -8,15 +8,16 @@ homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde_test/"
keywords = ["serde", "serialization"]
readme = "README.md"
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
readme = "crates-io.md"
include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[dependencies]
serde = { version = "1.0.16", path = "../serde" }
serde = { version = "1.0.60", path = "../serde" }
[dev-dependencies]
serde = { version = "1.0.16", path = "../serde", features = ["rc"] }
serde = { version = "1.0", path = "../serde", features = ["rc"] }
serde_derive = { version = "1.0", path = "../serde_derive" }
[badges]
travis-ci = { repository = "serde-rs/serde" }
appveyor = { repository = "serde-rs/serde" }
+1
View File
@@ -0,0 +1 @@
../crates-io.md
+2 -9
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::{Deserialize, Serialize};
use de::Deserializer;
@@ -95,7 +87,8 @@ where
}
}
/// Asserts that `value` serializes to the given `tokens`, and then yields `error`.
/// Asserts that `value` serializes to the given `tokens`, and then yields
/// `error`.
///
/// ```rust
/// # #[macro_use]
+3 -8
View File
@@ -19,7 +19,7 @@ pub struct Compact<T: ?Sized>(T);
/// extern crate serde_test;
///
/// use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// use serde_test::{Configure, Token, assert_tokens};
/// use serde_test::{assert_tokens, Configure, Token};
///
/// #[derive(Debug, PartialEq)]
/// struct Example(u8, u8);
@@ -67,12 +67,7 @@ pub struct Compact<T: ?Sized>(T);
/// Token::TupleEnd,
/// ],
/// );
/// assert_tokens(
/// &Example(1, 0).readable(),
/// &[
/// Token::Str("1.0"),
/// ],
/// );
/// assert_tokens(&Example(1, 0).readable(), &[Token::Str("1.0")]);
/// }
/// ```
pub trait Configure {
@@ -205,7 +200,7 @@ macro_rules! impl_serializer {
$is_human_readable
}
forward_serialize_methods!{
forward_serialize_methods! {
serialize_bool bool,
serialize_i8 i8,
serialize_i16 i16,
+2 -9
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer};
use serde::de::{
self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess,
@@ -253,7 +245,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
Token::UnitVariant { name: n, .. }
| Token::NewtypeVariant { name: n, .. }
| Token::TupleVariant { name: n, .. }
| Token::StructVariant { name: n, .. } if name == n =>
| Token::StructVariant { name: n, .. }
if name == n =>
{
visitor.visit_enum(DeserializerEnumVisitor { de: self })
}
-8
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::error;
use std::fmt::{self, Display};
+8 -11
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! This crate provides a convenient concise way to write unit tests for
//! implementations of [`Serialize`] and [`Deserialize`].
//!
@@ -161,7 +153,8 @@
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.60")]
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.81")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
@@ -169,8 +162,12 @@
#![cfg_attr(
feature = "cargo-clippy",
allow(
empty_line_after_outer_attr, missing_docs_in_private_items, redundant_field_names, stutter,
use_debug, use_self
empty_line_after_outer_attr,
missing_docs_in_private_items,
redundant_field_names,
stutter,
use_debug,
use_self
)
)]
+2 -9
View File
@@ -1,17 +1,10 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::{ser, Serialize};
use error::Error;
use token::Token;
/// A `Serializer` that ensures that a value serializes to a given list of tokens.
/// A `Serializer` that ensures that a value serializes to a given list of
/// tokens.
#[derive(Debug)]
pub struct Serializer<'a> {
tokens: &'a [Token],
-8
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::fmt::{self, Debug, Display};
#[derive(Copy, Clone, PartialEq, Debug)]
+1 -2
View File
@@ -9,11 +9,10 @@ unstable = ["serde/unstable", "compiletest_rs"]
[dev-dependencies]
fnv = "1.0"
proc-macro2 = "0.4"
rustc-serialize = "0.3.16"
serde = { path = "../serde", features = ["rc"] }
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
serde_test = { path = "../serde_test" }
[dependencies]
compiletest_rs = { version = "0.3", optional = true }
compiletest_rs = { version = "0.3", optional = true, features = ["stable"] }
-8
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(/*=============================================]
#![=== Serde test suite requires a nightly compiler. ===]
#![====================================================*/)]
+2 -15
View File
@@ -1,11 +1,3 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(lang_items, start)]
#![no_std]
@@ -20,13 +12,8 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
pub extern "C" fn rust_eh_personality() {}
#[lang = "panic_fmt"]
#[no_mangle]
pub extern "C" fn rust_begin_panic(
_msg: core::fmt::Arguments,
_file: &'static str,
_line: u32,
) -> ! {
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
@@ -1,18 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
struct Test<'a> {
#[serde(borrow = "zzz")] //~^^ HELP: failed to parse borrowed lifetimes: "zzz"
s: &'a str,
}
fn main() {}
@@ -1,18 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
struct Test<'a> {
#[serde(borrow = "'a + 'a")] //~^^ HELP: duplicate borrowed lifetime `'a`
s: &'a str,
}
fn main() {}
@@ -1,21 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)]
struct Str<'a>(&'a str);
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
enum Test<'a> {
#[serde(borrow)] //~^^ HELP: duplicate serde attribute `borrow`
S(#[serde(borrow)] Str<'a>)
}
fn main() {}
@@ -1,18 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
struct Test<'a> {
#[serde(borrow = "")] //~^^ HELP: at least one lifetime must be borrowed
s: &'a str,
}
fn main() {}
@@ -1,18 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
struct Test {
#[serde(borrow)] //~^^ HELP: field `s` has no lifetimes to borrow
s: String,
}
fn main() {}
@@ -1,21 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)]
struct Str<'a>(&'a str);
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
enum Test<'a> {
#[serde(borrow)] //~^^ HELP: #[serde(borrow)] may only be used on newtype variants
S { s: Str<'a> }
}
fn main() {}
@@ -1,18 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
struct Test<'a> {
#[serde(borrow = "'b")] //~^^ HELP: field `s` does not have lifetime 'b
s: &'a str,
}
fn main() {}
@@ -1,20 +0,0 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(tag = "conflict", content = "conflict")]
//~^^ HELP: enum tags `conflict` for type and content conflict with each other
enum E {
A,
B,
}
fn main() {}
@@ -1,16 +0,0 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: #[serde(flatten)] cannot be used on newtype structs
struct Foo(#[serde(flatten)] HashMap<String, String>);
fn main() {}
@@ -1,24 +0,0 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: #[serde(flatten] can not be combined with #[serde(skip_deserializing)]
struct Foo {
#[serde(flatten, skip_deserializing)]
other: Other,
}
#[derive(Deserialize)]
struct Other {
x: u32
}
fn main() {}
@@ -1,24 +0,0 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: #[serde(flatten] can not be combined with #[serde(skip_serializing_if = "...")]
struct Foo {
#[serde(flatten, skip_serializing_if="Option::is_none")]
other: Option<Other>,
}
#[derive(Serialize)]
struct Other {
x: u32
}
fn main() {}
@@ -1,24 +0,0 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: #[serde(flatten] can not be combined with #[serde(skip_serializing)]
struct Foo {
#[serde(flatten, skip_serializing)]
other: Other,
}
#[derive(Serialize)]
struct Other {
x: u32
}
fn main() {}
@@ -1,16 +0,0 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: #[serde(flatten)] cannot be used on tuple structs
struct Foo(u32, #[serde(flatten)] HashMap<String, String>);
fn main() {}
@@ -1,22 +0,0 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(tag = "conflict")]
//~^^ HELP: variant field name `conflict` conflicts with internal tag
enum E {
A {
#[serde(rename = "conflict")]
x: (),
},
}
fn main() {}
@@ -1,16 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(default)] //~^ HELP: #[serde(default)] can only be used on structs
enum E {
S { f: u8 },
}
@@ -1,16 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(default)] //~^ HELP: #[serde(default)] can only be used on structs
struct T(u8, u8);
fn main() { }
@@ -1,18 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
struct S {
#[serde(rename="x", serialize="y")] //~^^ HELP: unknown serde field attribute `serialize`
x: (),
}
fn main() {}
@@ -1,19 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
struct S {
#[serde(rename="x")]
#[serde(rename(deserialize="y"))] //~^^^ HELP: duplicate serde attribute `rename`
x: (),
}
fn main() {}
@@ -1,18 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
struct S {
#[serde(rename(serialize="x"), rename(serialize="y"))] //~^^ HELP: duplicate serde attribute `rename`
x: (),
}
fn main() {}
@@ -1,19 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
struct S {
#[serde(rename(serialize="x"))]
#[serde(rename="y")] //~^^^ HELP: duplicate serde attribute `rename`
x: (),
}
fn main() {}
@@ -1,18 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
struct S {
#[serde(rename(serialize="x", serialize="y"))] //~^^ HELP: duplicate serde attribute `rename`
x: (),
}
fn main() {}
@@ -1,19 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
struct S {
#[serde(rename(serialize="x"))]
#[serde(rename(serialize="y"))] //~^^^ HELP: duplicate serde attribute `rename`
x: (),
}
fn main() {}
@@ -1,18 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
struct S {
#[serde(with = "w", serialize_with = "s")] //~^^ HELP: duplicate serde attribute `serialize_with`
x: (),
}
fn main() {}
@@ -1,18 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(tag = "type")] //~^ HELP: #[serde(tag = "...")] cannot be used with tuple variants
enum E {
Tuple(u8, u8),
}
fn main() {}
@@ -1,16 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(tag = "type")] //~^ HELP: #[serde(tag = "...")] can only be used on enums
struct S;
fn main() {}
@@ -1,20 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(untagged)]
#[serde(tag = "type")] //~^^ HELP: enum cannot be both untagged and internally tagged
enum E {
A(u8),
B(String),
}
fn main() {}
@@ -1,16 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(untagged)] //~^ HELP: #[serde(untagged)] can only be used on enums
struct S;
fn main() {}
@@ -1,19 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(field_identifier, variant_identifier)] //~^ HELP: `field_identifier` and `variant_identifier` cannot both be set
enum F {
A,
B,
}
fn main() {}
@@ -1,16 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(field_identifier)]
struct S; //~^^ HELP: `field_identifier` can only be used on an enum
fn main() {}
@@ -1,19 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(field_identifier)]
enum F {
A,
B(u8, u8), //~^^^^ HELP: field_identifier may only contain unit variants
}
fn main() {}
@@ -1,20 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(field_identifier)]
enum F {
A,
Other(String), //~^^^^ HELP: `Other` must be the last variant
B,
}
fn main() {}
@@ -1,19 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
enum F {
A,
#[serde(other)] //~^^^ HELP: #[serde(other)] may only be used inside a field_identifier
B,
}
fn main() {}
@@ -1,20 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(field_identifier)]
enum F {
A,
#[serde(other)] //~^^^^ HELP: #[serde(other)] must be on a unit variant
Other(u8, u8),
}
fn main() {}
@@ -1,21 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(field_identifier)]
enum F {
A,
#[serde(other)] //~^^^^ HELP: #[serde(other)] must be the last variant
Other,
B,
}
fn main() {}
@@ -1,19 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(field_identifier)] //~^ HELP: field identifiers cannot be serialized
enum F {
A,
B,
}
fn main() {}
@@ -1,16 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(variant_identifier)]
struct S; //~^^ HELP: `variant_identifier` can only be used on an enum
fn main() {}
@@ -1,19 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(variant_identifier)]
enum F {
A,
B(u8, u8), //~^^^^ HELP: variant_identifier may only contain unit variants
}
fn main() {}
@@ -1,15 +0,0 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
struct S<'de> {
s: &'de str, //~^^ HELP: cannot deserialize when there is a lifetime parameter called 'de
}
@@ -1,16 +0,0 @@
// Copyright 2018 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
struct S {
string: String,
slice: [u8], //~^^^ HELP: cannot deserialize a dynamically sized struct
}
@@ -1,25 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
mod remote {
pub struct S {
a: u8,
}
}
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(remote = "remote::S")]
struct S {
#[serde(getter = "~~~")] //~^^^ HELP: failed to parse path: "~~~"
a: u8,
}
fn main() {}
@@ -1,24 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
mod remote {
pub struct S {
a: u8,
}
}
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(remote = "~~~")] //~^ HELP: failed to parse path: "~~~"
struct S {
a: u8,
}
fn main() {}
@@ -1,27 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
mod remote {
pub enum E {
A { a: u8 }
}
}
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(remote = "remote::E")]
pub enum E {
A {
#[serde(getter = "get_a")] //~^^^^ HELP: #[serde(getter = "...")] is not allowed in an enum
a: u8,
}
}
fn main() {}
@@ -1,25 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
mod remote {
pub struct S {
pub a: u8,
pub b: u8,
}
}
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::S")]
struct S {
a: u8, //~^^^ ERROR: missing field `b` in initializer of `remote::S`
}
fn main() {}
@@ -1,24 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
struct S {
#[serde(getter = "S::get")] //~^^ HELP: #[serde(getter = "...")] can only be used in structs that have #[serde(remote = "...")]
a: u8,
}
impl S {
fn get(&self) -> u8 {
self.a
}
}
fn main() {}
@@ -1,25 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
mod remote {
pub struct S {
pub a: u8,
}
}
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::S")]
struct S {
//~^^^ ERROR: struct `remote::S` has no field named `b`
b: u8, //~^^^^ ERROR: no field `b` on type `&remote::S`
}
fn main() {}
@@ -1,20 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
mod remote {
pub struct S(pub u16);
}
#[derive(Deserialize)] //~ ERROR: mismatched types
#[serde(remote = "remote::S")]
struct S(u8); //~^^ expected u16, found u8
fn main() {}
@@ -1,31 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
mod remote {
pub struct S {
a: u8,
}
impl S {
pub fn get(&self) -> u16 {
self.a as u16
}
}
}
#[derive(Serialize)] //~ ERROR: mismatched types
#[serde(remote = "remote::S")]
struct S {
#[serde(getter = "remote::S::get")]
a: u8, //~^^^^ expected u8, found u16
}
fn main() {}
@@ -1,24 +0,0 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[macro_use]
extern crate serde_derive;
mod remote {
pub struct S {
pub a: u16,
}
}
#[derive(Serialize)] //~ ERROR: mismatched types
#[serde(remote = "remote::S")]
struct S {
a: u8, //~^^^ expected u8, found u16
}
fn main() {}

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