Compare commits

...

85 Commits

Author SHA1 Message Date
David Tolnay bb99b31eb0 Release 1.0.85 2019-01-18 22:36:49 -08:00
David Tolnay 84397183f3 Fix spelling of alises -> aliases 2019-01-18 22:34:23 -08:00
David Tolnay aeae265777 Simpler way to get single element from vector 2019-01-18 22:33:43 -08:00
David Tolnay a9c5df5da1 Remove unused Clone on attr::Attr 2019-01-18 22:31:25 -08:00
David Tolnay 96576c4de9 Merge pull request #1458 from Lymia/master
Implements alias annotation and allow multiple deserialization renames.
2019-01-18 22:29:57 -08:00
David Tolnay 9ec68e5829 Re-export is no longer just for optional serde cfg 2019-01-18 00:48:05 -08:00
David Tolnay face857d5e Update crates.io readme to 2018 edition 2019-01-18 00:44:17 -08:00
David Tolnay 85a1cc9b4f Merge pull request #1460 from dtolnay/readme
Replace serde_derive with features = ["derive"] in readme
2019-01-18 00:43:25 -08:00
David Tolnay 630501b93d Replace serde_derive with features = ["derive"] in readme 2019-01-18 00:30:01 -08:00
Lymia Aluysia 8bbc2995ca Fix clippy lint in serde_derive 2019-01-15 11:35:26 -06:00
Lymia Aluysia 7d3872df57 Fix compilation on Rust 1.15.x 2019-01-15 11:29:55 -06:00
Lymia Aluysia 1ed228b92b Implements alias annotation and allow multiple deserialization renames. 2019-01-15 11:15:01 -06:00
David Tolnay b605cd1bb9 Make compiletest setup consistent with serde_json 2019-01-12 16:22:23 -08:00
David Tolnay fea4e8e5b6 Release 1.0.84 2018-12-31 23:45:34 -05:00
David Tolnay 1df8b5785b Test with same features in Travis and AppVeyor 2018-12-31 23:31:49 -05:00
David Tolnay 981a75d7c9 Enable extra features in playground 2018-12-31 23:28:10 -05:00
David Tolnay 11cc7014b3 Set all doc tests to 2018 edition 2018-12-31 23:22:13 -05:00
David Tolnay 0b667c88fa Remove unneeded main functions in doc tests
These used to be needed because `#[macro_use] extern crate serde`
couldn't go inside of rustdoc's implicit main function.
2018-12-31 23:22:12 -05:00
David Tolnay 054ab1adaf Update serde documentation to 2018 edition 2018-12-31 23:22:11 -05:00
David Tolnay f1f8386f2e Update serde_derive_internals ignored lints 2018-12-31 22:53:09 -05:00
David Tolnay ba8c3970b0 Use tool lint naming in clippy invocation 2018-12-31 22:51:38 -05:00
David Tolnay 2f36b26a5c Clarify that these lints are ignored 2018-12-31 22:49:38 -05:00
David Tolnay 9b4edb3a1d Address match_ref_pats lint in serde_derive 2018-12-31 22:47:48 -05:00
David Tolnay b8adc5ffa2 Update name of stutter lint in serde_derive 2018-12-31 22:47:18 -05:00
David Tolnay bd90cafda7 Ignore trivially_copy_pass_by_ref lint in serde_derive 2018-12-31 22:47:03 -05:00
David Tolnay 6d43a08a1d Remove dev-dependencies features from serde_test
Apparently Cargo is applying these features to the non-dev dependency on
serde as well. Concluded by running `cargo clean && cargo build` and
observing that serde_derive was getting built.
2018-12-31 22:43:15 -05:00
David Tolnay e71b8598ae Update serde_test examples to 2018 edition 2018-12-31 22:41:23 -05:00
David Tolnay 95d0f437e3 Update ui tests to nightly 2019-01-01 2018-12-31 22:09:07 -05:00
David Tolnay c95ee3968a Format with rustfmt 2018-12-10 2018-12-31 22:09:06 -05:00
David Tolnay c22dd4ada5 Suppress trivially_copy_pass_by_ref lint on fn is_zero 2018-12-31 22:09:05 -05:00
David Tolnay 727a40fc5a Update test suite to use tool attrs 2018-12-31 21:59:40 -05:00
David Tolnay ce84a5f1d3 Update name of deprecated stutter lint 2018-12-31 21:59:39 -05:00
David Tolnay e6fda1c410 Fix clippy command to run against test suite 2018-12-31 21:56:10 -05:00
David Tolnay 294dccc5be Update test suite to 2018 edition 2018-12-31 21:53:37 -05:00
David Tolnay da346a8878 Replace try! macro in test suite 2018-12-31 21:46:14 -05:00
David Tolnay c5ccb995ad Update no_std test to 2018 edition 2018-12-31 21:42:22 -05:00
David Tolnay 05ab569a80 Update ui tests to 2018 edition 2018-12-31 21:38:13 -05:00
David Tolnay ab3f4971f0 Move compiletest out of the unstable feature flag 2018-12-31 21:28:39 -05:00
David Tolnay 47e238aa13 Add missing imports in ui tests
There is a new fallback as of nightly-2018-12-29 that makes these emit a
new error unrelated to Serde.
2018-12-29 00:19:29 -05:00
David Tolnay e49b6c708b Add main function to ui tests without main
These emit a new error not relevant to Serde as of nightly-2018-12-29.
2018-12-29 00:18:55 -05:00
David Tolnay eb7250792b Format with rustfmt 2018-12-10 2018-12-28 12:19:32 -05:00
David Tolnay 7e5066b878 Merge pull request #1450 from motu42/master
Bug fix to support the tag attribute on braced structs with zero fields
2018-12-27 21:48:14 -05:00
Johannes Willbold 889e17816f Bug fix for #1449
Modified serialize_struct_as_struct.
Added test test_internally_tagged_braced_struct_with_zero_fields
2018-12-28 02:50:24 +01:00
David Tolnay b1b9702daf Release 1.0.83 2018-12-27 19:53:48 -05:00
David Tolnay 32728d2f1d Format with rustfmt 2018-12-10 2018-12-27 19:52:26 -05:00
David Tolnay 807a097387 Fix spelling in ui test name 2018-12-27 19:51:53 -05:00
David Tolnay 794ee15386 Merge pull request #1448 from motu42/master
Allow #[serde(tag="...")] on structs
2018-12-27 19:47:28 -05:00
Johannes Willbold 2359417804 Added ui tests, Limited serde(tag = "...") to structs with named field
Added ui test struct-representation/internally-tagged-unit
Added ui test struct-representation/internally-tagged-tuple
    
Limited the serde(tag = "...") to enums and structs with named field
2018-12-28 01:29:33 +01:00
David Tolnay 7950f3cdc5 Format with rustfmt 2018-12-10 2018-12-27 15:35:43 -05:00
David Tolnay b87f8f35ee Merge pull request 1447 from vincascm/master 2018-12-27 15:29:16 -05:00
Johannes Willbold 9e53405f43 Fix for rustc 1.15.0 2018-12-27 21:21:46 +01:00
David Tolnay c6c1d8fa86 Work around deprecation of str::trim_left_matches 2018-12-27 15:20:32 -05:00
Johannes Willbold 8aa5c2b45d Removed deprected ui/enum-representation/internally-tagged-struct test 2018-12-27 20:53:08 +01:00
Johannes Willbold 414fd694c0 Allowed serde(tag="...") on structs
Added test test_internally_tagged_struct
Renamed EnumTag to TagType as it now also used for structs 
Modified serialize_struct_as_struct
2018-12-27 20:18:36 +01:00
vinoca 7e82809592 Fix tests fail since modify Container attributes rename_all 2018-12-20 14:30:23 +08:00
vinoca 0dae5db30e Support Container attributes rename_all only for Serialize or Deserialize 2018-12-19 09:46:52 +08:00
David Tolnay 5c24f0f0f3 Clean up some indentation that isn't visible to rustfmt 2018-12-10 22:31:39 -08:00
David Tolnay c2591e9b39 Release 1.0.82 2018-12-10 22:25:27 -08:00
David Tolnay 8ce0dee6da Fix missing dependency on quote in serde_derive_internals 2018-12-10 22:15:46 -08:00
David Tolnay 16daba8ea9 Format with rustfmt 2018-11-30 2018-12-10 22:09:34 -08:00
David Tolnay 8b4074ee77 Tests for tuple default attribute 2018-12-10 22:09:33 -08:00
David Tolnay 85fbd8793a Support default attr in deserialize_seq_in_place 2018-12-10 22:09:31 -08:00
David Tolnay 65705e2091 Merge pull request #1442 from tcr/master
Adds support for the default attr to tuple variants in enums.
2018-12-10 22:09:21 -08:00
Tim Ryan 385a385c62 Adds support for the default attr to tuple variants in enums. 2018-12-11 00:02:50 -05:00
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
324 changed files with 3701 additions and 3028 deletions
+14 -12
View File
@@ -9,7 +9,7 @@ matrix:
- cargo build --no-default-features - cargo build --no-default-features
- cd "${TRAVIS_BUILD_DIR}/serde_test" - cd "${TRAVIS_BUILD_DIR}/serde_test"
- cargo build - cargo build
- cargo test - cargo test --features serde/derive,serde/rc
- rust: beta - rust: beta
script: script:
@@ -25,11 +25,11 @@ matrix:
- cargo build --no-default-features - cargo build --no-default-features
- cargo build --no-default-features --features alloc - cargo build --no-default-features --features alloc
- cargo build --no-default-features --features rc,alloc - cargo build --no-default-features --features rc,alloc
- cargo test --features rc,unstable - cargo test --features derive,rc,unstable
- cd "${TRAVIS_BUILD_DIR}/test_suite/deps" - cd "${TRAVIS_BUILD_DIR}/test_suite/deps"
- cargo build - cargo build
- cd "${TRAVIS_BUILD_DIR}/test_suite" - cd "${TRAVIS_BUILD_DIR}/test_suite"
- cargo test --features unstable - cargo test --features compiletest,unstable
- cd "${TRAVIS_BUILD_DIR}/test_suite/no_std" - cd "${TRAVIS_BUILD_DIR}/test_suite/no_std"
- cargo build - cargo build
@@ -52,23 +52,23 @@ matrix:
- rust: 1.26.0 - rust: 1.26.0
- rust: nightly - rust: nightly
env: CLIPPY name: Clippy
script: script:
- rustup component add clippy-preview || travis_terminate 0 - rustup component add clippy-preview || travis_terminate 0
- cargo clippy -- -Dclippy - cargo clippy -- -D clippy::all
- cd "${TRAVIS_BUILD_DIR}/serde" - cd "${TRAVIS_BUILD_DIR}/serde"
- cargo clippy --features rc,unstable -- -Dclippy - cargo clippy --features rc,unstable -- -D clippy::all
- cd "${TRAVIS_BUILD_DIR}/serde_derive" - cd "${TRAVIS_BUILD_DIR}/serde_derive"
- cargo clippy -- -Dclippy - cargo clippy -- -D clippy::all
- cd "${TRAVIS_BUILD_DIR}/serde_test" - cd "${TRAVIS_BUILD_DIR}/serde_test"
- cargo clippy -- -Dclippy - cargo clippy -- -D clippy::all
- cd "${TRAVIS_BUILD_DIR}/test_suite" - cd "${TRAVIS_BUILD_DIR}/test_suite"
- cargo clippy --features unstable -- -Dclippy - cargo clippy --tests --features unstable -- -D clippy::all
- cd "${TRAVIS_BUILD_DIR}/test_suite/no_std" - cd "${TRAVIS_BUILD_DIR}/test_suite/no_std"
- cargo clippy -- -Dclippy - cargo clippy -- -D clippy::all
- rust: nightly - rust: nightly
env: EMSCRIPTEN name: Emscripten
script: script:
- CARGO_WEB_RELEASE=$(curl -L -s -H Accept:application/json https://github.com/koute/cargo-web/releases/latest) - 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_VERSION=$(echo "${CARGO_WEB_RELEASE}" | jq -r .tag_name)
@@ -85,7 +85,9 @@ matrix:
allow_failures: allow_failures:
- rust: nightly - rust: nightly
env: CLIPPY name: Clippy
- rust: nightly
name: Emscripten
script: script:
- cd "${TRAVIS_BUILD_DIR}/serde" - cd "${TRAVIS_BUILD_DIR}/serde"
-2
View File
@@ -1,5 +1,3 @@
Copyright (c) 2014 The Rust Project Developers
Permission is hereby granted, free of charge, to any Permission is hereby granted, free of charge, to any
person obtaining a copy of this software and associated person obtaining a copy of this software and associated
documentation files (the "Software"), to deal in the documentation files (the "Software"), to deal in the
+6 -12
View File
@@ -25,19 +25,17 @@ You may be looking for:
<details> <details>
<summary> <summary>
Click to show Cargo.toml. Click to show Cargo.toml.
<a href="https://play.rust-lang.org/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a> <a href="https://play.rust-lang.org/?edition=2018&gist=72755f28f99afc95e01d63174b28c1f5" target="_blank">Run this code in the playground.</a>
</summary> </summary>
```toml ```toml
[dependencies] [dependencies]
# The core APIs, including the Serialize and Deserialize traits. Always # The core APIs, including the Serialize and Deserialize traits. Always
# required when using Serde. # required when using Serde. The "derive" feature is only required when
serde = "1.0" # using #[derive(Serialize, Deserialize)] to make Serde work with structs
# and enums defined in your crate.
# Support for #[derive(Serialize, Deserialize)]. Required if you want Serde serde = { version = "1.0", features = ["derive"] }
# to work for structs and enums defined in your crate.
serde_derive = "1.0"
# Each data format lives in its own crate; the sample code below uses JSON # Each data format lives in its own crate; the sample code below uses JSON
# but you may be using a different one. # but you may be using a different one.
@@ -48,11 +46,7 @@ serde_json = "1.0"
<p></p> <p></p>
```rust ```rust
#[macro_use] use serde::{Serialize, Deserialize};
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
struct Point { struct Point {
+3 -3
View File
@@ -23,7 +23,7 @@ for:
- cargo build --no-default-features - cargo build --no-default-features
- cd %APPVEYOR_BUILD_FOLDER%\serde_test - cd %APPVEYOR_BUILD_FOLDER%\serde_test
- cargo build - cargo build
- cargo test - cargo test --features serde/derive,serde/rc
- matrix: - matrix:
only: only:
@@ -34,8 +34,8 @@ for:
- cargo build --no-default-features - cargo build --no-default-features
- cargo build --no-default-features --features alloc - cargo build --no-default-features --features alloc
- cargo build --no-default-features --features rc,alloc - cargo build --no-default-features --features rc,alloc
- cargo test --features rc,unstable - cargo test --features derive,rc,unstable
- cd %APPVEYOR_BUILD_FOLDER%\test_suite\deps - cd %APPVEYOR_BUILD_FOLDER%\test_suite\deps
- cargo build - cargo build
- cd %APPVEYOR_BUILD_FOLDER%\test_suite - cd %APPVEYOR_BUILD_FOLDER%\test_suite
- cargo test --features unstable - cargo test --features compiletest,unstable
+1 -5
View File
@@ -16,11 +16,7 @@ You may be looking for:
## Serde in action ## Serde in action
```rust ```rust
#[macro_use] use serde::{Serialize, Deserialize};
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)] #[derive(Serialize, Deserialize, Debug)]
struct Point { struct Point {
+5 -25
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.80" # remember to update html_root_url version = "1.0.85" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
@@ -23,36 +23,16 @@ serde_derive = { version = "1.0", optional = true, path = "../serde_derive" }
[dev-dependencies] [dev-dependencies]
serde_derive = { version = "1.0", path = "../serde_derive" } serde_derive = { version = "1.0", path = "../serde_derive" }
[package.metadata.playground]
features = ["derive", "rc"]
### FEATURES ################################################################# ### FEATURES #################################################################
[features] [features]
default = ["std"] default = ["std"]
# Re-export the derive(Serialize, Deserialize) macros. This is intended for # Provide derive(Serialize, Deserialize) macros.
# 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 ...
#
derive = ["serde_derive"] derive = ["serde_derive"]
# Provide impls for common standard library types like Vec<T> and HashMap<K, V>. # Provide impls for common standard library types like Vec<T> and HashMap<K, V>.
-5
View File
@@ -71,11 +71,6 @@ fn rustc_minor_version() -> Option<u32> {
Err(_) => return None, Err(_) => return None,
}; };
// Temporary workaround to support the old 1.26-dev compiler on docs.rs.
if version.contains("0eb87c9bf") {
return Some(25);
}
let mut pieces = version.split('.'); let mut pieces = version.split('.');
if pieces.next() != Some("rustc 1") { if pieces.next() != Some("rustc 1") {
return None; return None;
-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::*; use lib::*;
macro_rules! int_to_int { macro_rules! int_to_int {
+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.
use lib::*; use lib::*;
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor}; use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
@@ -16,7 +8,7 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// any type, except that it does not store any information about the data that /// any type, except that it does not store any information about the data that
/// gets deserialized. /// gets deserialized.
/// ///
/// ```rust /// ```edition2018
/// use std::fmt; /// use std::fmt;
/// use std::marker::PhantomData; /// use std::marker::PhantomData;
/// ///
@@ -29,7 +21,7 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// /// /// ///
/// /// For example to deserialize only the element at index 3: /// /// For example to deserialize only the element at index 3:
/// /// /// ///
/// /// ```rust /// /// ```
/// /// NthElement::new(3).deserialize(deserializer) /// /// NthElement::new(3).deserialize(deserializer)
/// /// ``` /// /// ```
/// pub struct NthElement<T> { /// pub struct NthElement<T> {
+9 -27
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 lib::*;
use de::{ use de::{
@@ -874,7 +866,9 @@ where
} }
} }
let visitor = VecVisitor { marker: PhantomData }; let visitor = VecVisitor {
marker: PhantomData,
};
deserializer.deserialize_seq(visitor) deserializer.deserialize_seq(visitor)
} }
@@ -1425,7 +1419,7 @@ impl<'de> Deserialize<'de> for net::IpAddr {
deserializer.deserialize_str(IpAddrVisitor) deserializer.deserialize_str(IpAddrVisitor)
} else { } else {
use lib::net::IpAddr; use lib::net::IpAddr;
deserialize_enum!{ deserialize_enum! {
IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1) IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
"`V4` or `V6`", "`V4` or `V6`",
deserializer deserializer
@@ -1502,7 +1496,7 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
deserializer.deserialize_str(SocketAddrVisitor) deserializer.deserialize_str(SocketAddrVisitor)
} else { } else {
use lib::net::SocketAddr; use lib::net::SocketAddr;
deserialize_enum!{ deserialize_enum! {
SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1) SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
"`V4` or `V6`", "`V4` or `V6`",
deserializer deserializer
@@ -1602,7 +1596,7 @@ impl<'de> Deserialize<'de> for PathBuf {
// #[derive(Deserialize)] // #[derive(Deserialize)]
// #[serde(variant_identifier)] // #[serde(variant_identifier)]
#[cfg(all(feature = "std", any(unix, windows)))] #[cfg(all(feature = "std", any(unix, windows)))]
variant_identifier!{ variant_identifier! {
OsStringKind (Unix; b"Unix"; 0, Windows; b"Windows"; 1) OsStringKind (Unix; b"Unix"; 0, Windows; b"Windows"; 1)
"`Unix` or `Windows`", "`Unix` or `Windows`",
OSSTR_VARIANTS OSSTR_VARIANTS
@@ -1760,11 +1754,7 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(all( #[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
))]
macro_rules! box_forwarded_impl { macro_rules! box_forwarded_impl {
( (
$(#[doc = $doc:tt])* $(#[doc = $doc:tt])*
@@ -1785,11 +1775,7 @@ macro_rules! box_forwarded_impl {
}; };
} }
#[cfg(all( #[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
))]
box_forwarded_impl! { box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde. /// This impl requires the [`"rc"`] Cargo feature of Serde.
/// ///
@@ -1801,11 +1787,7 @@ box_forwarded_impl! {
Rc Rc
} }
#[cfg(all( #[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
))]
box_forwarded_impl! { box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde. /// This impl requires the [`"rc"`] Cargo feature of Serde.
/// ///
+37 -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.
//! Generic data structure deserialization framework. //! Generic data structure deserialization framework.
//! //!
//! The two most important traits in this module are [`Deserialize`] and //! The two most important traits in this module are [`Deserialize`] and
@@ -161,7 +153,7 @@ macro_rules! declare_error_trait {
/// ///
/// The message should not be capitalized and should not end with a period. /// The message should not be capitalized and should not end with a period.
/// ///
/// ```rust /// ```edition2018
/// # use std::str::FromStr; /// # use std::str::FromStr;
/// # /// #
/// # struct IpAddr; /// # struct IpAddr;
@@ -181,7 +173,7 @@ macro_rules! declare_error_trait {
/// where /// where
/// D: Deserializer<'de>, /// D: Deserializer<'de>,
/// { /// {
/// let s = try!(String::deserialize(deserializer)); /// let s = String::deserialize(deserializer)?;
/// s.parse().map_err(de::Error::custom) /// s.parse().map_err(de::Error::custom)
/// } /// }
/// } /// }
@@ -245,12 +237,16 @@ macro_rules! declare_error_trait {
#[cold] #[cold]
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self { fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() { if expected.is_empty() {
Error::custom(format_args!("unknown variant `{}`, there are no variants", Error::custom(format_args!(
variant)) "unknown variant `{}`, there are no variants",
variant
))
} else { } else {
Error::custom(format_args!("unknown variant `{}`, expected {}", Error::custom(format_args!(
variant, "unknown variant `{}`, expected {}",
OneOf { names: expected })) variant,
OneOf { names: expected }
))
} }
} }
@@ -259,12 +255,16 @@ macro_rules! declare_error_trait {
#[cold] #[cold]
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self { fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() { if expected.is_empty() {
Error::custom(format_args!("unknown field `{}`, there are no fields", Error::custom(format_args!(
field)) "unknown field `{}`, there are no fields",
field
))
} else { } else {
Error::custom(format_args!("unknown field `{}`, expected {}", Error::custom(format_args!(
field, "unknown field `{}`, expected {}",
OneOf { names: expected })) field,
OneOf { names: expected }
))
} }
} }
@@ -298,7 +298,7 @@ declare_error_trait!(Error: Sized + Debug + Display);
/// This is used as an argument to the `invalid_type`, `invalid_value`, and /// This is used as an argument to the `invalid_type`, `invalid_value`, and
/// `invalid_length` methods of the `Error` trait to build error messages. /// `invalid_length` methods of the `Error` trait to build error messages.
/// ///
/// ```rust /// ```edition2018
/// # use std::fmt; /// # use std::fmt;
/// # /// #
/// # use serde::de::{self, Unexpected, Visitor}; /// # use serde::de::{self, Unexpected, Visitor};
@@ -423,7 +423,7 @@ impl<'a> fmt::Display for Unexpected<'a> {
/// Within the context of a `Visitor` implementation, the `Visitor` itself /// Within the context of a `Visitor` implementation, the `Visitor` itself
/// (`&self`) is an implementation of this trait. /// (`&self`) is an implementation of this trait.
/// ///
/// ```rust /// ```edition2018
/// # use std::fmt; /// # use std::fmt;
/// # /// #
/// # use serde::de::{self, Unexpected, Visitor}; /// # use serde::de::{self, Unexpected, Visitor};
@@ -448,7 +448,7 @@ impl<'a> fmt::Display for Unexpected<'a> {
/// ///
/// Outside of a `Visitor`, `&"..."` can be used. /// Outside of a `Visitor`, `&"..."` can be used.
/// ///
/// ```rust /// ```edition2018
/// # use serde::de::{self, Unexpected}; /// # use serde::de::{self, Unexpected};
/// # /// #
/// # fn example<E>() -> Result<(), E> /// # fn example<E>() -> Result<(), E>
@@ -569,7 +569,7 @@ pub trait Deserialize<'de>: Sized {
/// from the input string, but a `from_reader` function may only deserialize /// from the input string, but a `from_reader` function may only deserialize
/// owned data. /// owned data.
/// ///
/// ```rust /// ```edition2018
/// # use serde::de::{Deserialize, DeserializeOwned}; /// # use serde::de::{Deserialize, DeserializeOwned};
/// # use std::io::{Read, Result}; /// # use std::io::{Read, Result};
/// # /// #
@@ -608,7 +608,7 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
/// ///
/// The canonical API for stateless deserialization looks like this: /// The canonical API for stateless deserialization looks like this:
/// ///
/// ```rust /// ```edition2018
/// # use serde::Deserialize; /// # use serde::Deserialize;
/// # /// #
/// # enum Error {} /// # enum Error {}
@@ -622,7 +622,7 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
/// Adjusting an API like this to support stateful deserialization is a matter /// Adjusting an API like this to support stateful deserialization is a matter
/// of accepting a seed as input: /// of accepting a seed as input:
/// ///
/// ```rust /// ```edition2018
/// # use serde::de::DeserializeSeed; /// # use serde::de::DeserializeSeed;
/// # /// #
/// # enum Error {} /// # enum Error {}
@@ -655,7 +655,7 @@ impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
/// into it. This requires stateful deserialization using the `DeserializeSeed` /// into it. This requires stateful deserialization using the `DeserializeSeed`
/// trait. /// trait.
/// ///
/// ```rust /// ```edition2018
/// use std::fmt; /// use std::fmt;
/// use std::marker::PhantomData; /// use std::marker::PhantomData;
/// ///
@@ -1145,7 +1145,7 @@ pub trait Deserializer<'de>: Sized {
/// human-readable one and binary formats like Bincode will prefer the /// human-readable one and binary formats like Bincode will prefer the
/// compact one. /// compact one.
/// ///
/// ``` /// ```edition2018
/// # use std::ops::Add; /// # use std::ops::Add;
/// # use std::str::FromStr; /// # use std::str::FromStr;
/// # /// #
@@ -1222,7 +1222,7 @@ pub trait Deserializer<'de>: Sized {
/// ///
/// # Example /// # Example
/// ///
/// ```rust /// ```edition2018
/// # use std::fmt; /// # use std::fmt;
/// # /// #
/// # use serde::de::{self, Unexpected, Visitor}; /// # use serde::de::{self, Unexpected, Visitor};
@@ -1263,7 +1263,7 @@ pub trait Visitor<'de>: Sized {
/// "an integer between 0 and 64". The message should not be capitalized and /// "an integer between 0 and 64". The message should not be capitalized and
/// should not end with a period. /// should not end with a period.
/// ///
/// ```rust /// ```edition2018
/// # use std::fmt; /// # use std::fmt;
/// # /// #
/// # struct S { /// # struct S {
@@ -2004,7 +2004,7 @@ pub trait VariantAccess<'de>: Sized {
/// If the data contains a different type of variant, the following /// If the data contains a different type of variant, the following
/// `invalid_type` error should be constructed: /// `invalid_type` error should be constructed:
/// ///
/// ```rust /// ```edition2018
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
/// # /// #
/// # struct X; /// # struct X;
@@ -2044,7 +2044,7 @@ pub trait VariantAccess<'de>: Sized {
/// If the data contains a different type of variant, the following /// If the data contains a different type of variant, the following
/// `invalid_type` error should be constructed: /// `invalid_type` error should be constructed:
/// ///
/// ```rust /// ```edition2018
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
/// # /// #
/// # struct X; /// # struct X;
@@ -2100,7 +2100,7 @@ pub trait VariantAccess<'de>: Sized {
/// If the data contains a different type of variant, the following /// If the data contains a different type of variant, the following
/// `invalid_type` error should be constructed: /// `invalid_type` error should be constructed:
/// ///
/// ```rust /// ```edition2018
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
/// # /// #
/// # struct X; /// # struct X;
@@ -2147,7 +2147,7 @@ pub trait VariantAccess<'de>: Sized {
/// If the data contains a different type of variant, the following /// If the data contains a different type of variant, the following
/// `invalid_type` error should be constructed: /// `invalid_type` error should be constructed:
/// ///
/// ```rust /// ```edition2018
/// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected}; /// # use serde::de::{self, value, DeserializeSeed, Visitor, VariantAccess, Unexpected};
/// # /// #
/// # struct X; /// # struct X;
@@ -2207,14 +2207,10 @@ pub trait VariantAccess<'de>: Sized {
/// ///
/// # Example /// # Example
/// ///
/// ```rust /// ```edition2018
/// #[macro_use]
/// extern crate serde_derive;
///
/// extern crate serde;
///
/// use std::str::FromStr; /// use std::str::FromStr;
/// use serde::de::{value, Deserialize, IntoDeserializer}; /// use serde::Deserialize;
/// use serde::de::{value, IntoDeserializer};
/// ///
/// #[derive(Deserialize)] /// #[derive(Deserialize)]
/// enum Setting { /// enum Setting {
@@ -2229,8 +2225,6 @@ pub trait VariantAccess<'de>: Sized {
/// Self::deserialize(s.into_deserializer()) /// Self::deserialize(s.into_deserializer())
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
pub trait IntoDeserializer<'de, E: Error = value::Error> { pub trait IntoDeserializer<'de, E: Error = value::Error> {
/// The type of the deserializer being converted into. /// The type of the deserializer being converted into.
-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::*; use lib::*;
const TAG_CONT: u8 = 0b1000_0000; const TAG_CONT: u8 = 0b1000_0000;
+3 -17
View File
@@ -1,22 +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.
//! Building blocks for deserializing basic values using the `IntoDeserializer` //! Building blocks for deserializing basic values using the `IntoDeserializer`
//! trait. //! trait.
//! //!
//! ```rust //! ```edition2018
//! #[macro_use]
//! extern crate serde_derive;
//!
//! extern crate serde;
//!
//! use std::str::FromStr; //! use std::str::FromStr;
//! use serde::de::{value, Deserialize, IntoDeserializer}; //! use serde::Deserialize;
//! use serde::de::{value, IntoDeserializer};
//! //!
//! #[derive(Deserialize)] //! #[derive(Deserialize)]
//! enum Setting { //! enum Setting {
@@ -31,8 +19,6 @@
//! Self::deserialize(s.into_deserializer()) //! Self::deserialize(s.into_deserializer())
//! } //! }
//! } //! }
//! #
//! # fn main() {}
//! ``` //! ```
use lib::*; use lib::*;
-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::clone::Clone;
pub use lib::convert::{From, Into}; pub use lib::convert::{From, Into};
pub use lib::default::Default; pub use lib::default::Default;
+6 -10
View File
@@ -9,14 +9,12 @@
/// do not need to bother with this macro and may assume support for 128-bit /// do not need to bother with this macro and may assume support for 128-bit
/// integers. /// integers.
/// ///
/// ```rust /// ```edition2018
/// #[macro_use]
/// extern crate serde;
///
/// use serde::Serializer;
/// # use serde::private::ser::Error; /// # use serde::private::ser::Error;
/// # /// #
/// # struct MySerializer; /// # struct MySerializer;
/// #
/// use serde::{serde_if_integer128, Serializer};
/// ///
/// impl Serializer for MySerializer { /// impl Serializer for MySerializer {
/// type Ok = (); /// type Ok = ();
@@ -41,20 +39,18 @@
/// } /// }
/// } /// }
/// # /// #
/// # __serialize_unimplemented! { /// # serde::__serialize_unimplemented! {
/// # bool i8 i16 i32 u8 u16 u32 u64 f32 f64 char str bytes none some /// # bool i8 i16 i32 u8 u16 u32 u64 f32 f64 char str bytes none some
/// # unit unit_struct unit_variant newtype_struct newtype_variant seq /// # unit unit_struct unit_variant newtype_struct newtype_variant seq
/// # tuple tuple_struct tuple_variant map struct struct_variant /// # tuple tuple_struct tuple_variant map struct struct_variant
/// # } /// # }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
/// ///
/// When Serde is built with support for 128-bit integers, this macro expands /// When Serde is built with support for 128-bit integers, this macro expands
/// transparently into just the input tokens. /// transparently into just the input tokens.
/// ///
/// ```rust /// ```edition2018
/// macro_rules! serde_if_integer128 { /// macro_rules! serde_if_integer128 {
/// ($($tt:tt)*) => { /// ($($tt:tt)*) => {
/// $($tt)* /// $($tt)*
@@ -65,7 +61,7 @@
/// When built without support for 128-bit integers, this macro expands to /// When built without support for 128-bit integers, this macro expands to
/// nothing. /// nothing.
/// ///
/// ```rust /// ```edition2018
/// macro_rules! serde_if_integer128 { /// macro_rules! serde_if_integer128 {
/// ($($tt:tt)*) => {}; /// ($($tt:tt)*) => {};
/// } /// }
+14 -55
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
//! //!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data //! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
@@ -50,17 +42,17 @@
//! - [MessagePack], an efficient binary format that resembles a compact JSON. //! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo]. //! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world. //! - [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. //! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [Avro], a binary format used within Apache Hadoop, with support for schema //! - [Avro], a binary format used within Apache Hadoop, with support for schema
//! definition. //! 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. //! - [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. //! - [Envy], a way to deserialize environment variables into Rust structs.
//! *(deserialization only)* //! *(deserialization only)*
//! - [Redis], deserialize values from Redis when using [redis-rs]. //! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
//! *(deserialization only)* //! Rust structs. *(deserialization only)*
//! //!
//! [JSON]: https://github.com/serde-rs/json //! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode //! [Bincode]: https://github.com/TyOverby/bincode
@@ -69,20 +61,21 @@
//! [MessagePack]: https://github.com/3Hren/msgpack-rust //! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs //! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle //! [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 //! [BSON]: https://github.com/zonyitoo/bson-rs
//! [Avro]: https://github.com/flavray/avro-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 //! [URL]: https://github.com/nox/serde_urlencoded
//! [XML]: https://github.com/RReverser/serde-xml-rs
//! [Envy]: https://github.com/softprops/envy //! [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 //! [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. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.80")] #![doc(html_root_url = "https://docs.rs/serde/1.0.85")]
// Support using Serde without the standard library! // Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and // Unstable functionality only if the user asks for it. For tracking and
@@ -93,7 +86,7 @@
#![cfg_attr(feature = "alloc", feature(alloc))] #![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints // Ignored clippy lints
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
allow( allow(
@@ -108,7 +101,7 @@
zero_prefixed_literal zero_prefixed_literal
) )
)] )]
// Whitelisted clippy_pedantic lints // Ignored clippy_pedantic lints
#![cfg_attr(feature = "cargo-clippy", allow( #![cfg_attr(feature = "cargo-clippy", allow(
// integer and float ser/de requires these sorts of casts // integer and float ser/de requires these sorts of casts
cast_possible_truncation, cast_possible_truncation,
@@ -119,11 +112,11 @@
invalid_upcast_comparisons, invalid_upcast_comparisons,
// things are often more readable this way // things are often more readable this way
decimal_literal_representation, decimal_literal_representation,
module_name_repetitions,
option_unwrap_used, option_unwrap_used,
result_unwrap_used, result_unwrap_used,
shadow_reuse, shadow_reuse,
single_match_else, single_match_else,
stutter,
use_self, use_self,
// not practical // not practical
indexing_slicing, indexing_slicing,
@@ -259,40 +252,6 @@ pub mod private;
// Re-export #[derive(Serialize, Deserialize)]. // Re-export #[derive(Serialize, Deserialize)].
// //
// This is a workaround for https://github.com/rust-lang/cargo/issues/1286.
// Without this re-export, crates that put Serde derives behind a cfg_attr would
// need to use some silly feature name that depends on both serde and
// serde_derive.
//
// [features]
// serde-impls = ["serde", "serde_derive"]
//
// [dependencies]
// serde = { version = "1.0", optional = true }
// serde_derive = { version = "1.0", optional = true }
//
// # Used like this:
// # #[cfg(feature = "serde-impls")]
// # #[macro_use]
// # extern crate serde_derive;
// #
// # #[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
// # struct S { /* ... */ }
//
// The re-exported derives allow crates to use "serde" as the name of their
// Serde feature which is more intuitive.
//
// [dependencies]
// serde = { version = "1.0", optional = true, features = ["derive"] }
//
// # Used like this:
// # #[cfg(feature = "serde")]
// # #[macro_use]
// # extern crate serde;
// #
// # #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
// # struct S { /* ... */ }
//
// The reason re-exporting is not enabled by default is that disabling it would // The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They // be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std. // would need to disable default features and then explicitly re-enable std.
+6 -26
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 // Super explicit first paragraph because this shows up at the top level and
// trips up people who are just looking for basic Serialize / Deserialize // trips up people who are just looking for basic Serialize / Deserialize
// documentation. // documentation.
@@ -19,10 +11,8 @@
/// input. This requires repetitive implementations of all the [`Deserializer`] /// input. This requires repetitive implementations of all the [`Deserializer`]
/// trait methods. /// trait methods.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::forward_to_deserialize_any;
/// # extern crate serde;
/// #
/// # use serde::de::{value, Deserializer, Visitor}; /// # use serde::de::{value, Deserializer, Visitor};
/// # /// #
/// # struct MyDeserializer; /// # struct MyDeserializer;
@@ -51,18 +41,14 @@
/// # tuple_struct map struct enum identifier ignored_any /// # tuple_struct map struct enum identifier ignored_any
/// # } /// # }
/// # } /// # }
/// #
/// # fn main() {}
/// ``` /// ```
/// ///
/// The `forward_to_deserialize_any!` macro implements these simple forwarding /// The `forward_to_deserialize_any!` macro implements these simple forwarding
/// methods so that they forward directly to [`Deserializer::deserialize_any`]. /// methods so that they forward directly to [`Deserializer::deserialize_any`].
/// You can choose which methods to forward. /// You can choose which methods to forward.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::forward_to_deserialize_any;
/// # extern crate serde;
/// #
/// # use serde::de::{value, Deserializer, Visitor}; /// # use serde::de::{value, Deserializer, Visitor};
/// # /// #
/// # struct MyDeserializer; /// # struct MyDeserializer;
@@ -85,8 +71,6 @@
/// tuple_struct map struct enum identifier ignored_any /// tuple_struct map struct enum identifier ignored_any
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
/// ///
/// The macro assumes the convention that your `Deserializer` lifetime parameter /// The macro assumes the convention that your `Deserializer` lifetime parameter
@@ -94,12 +78,10 @@
/// called `V`. A different type parameter and a different lifetime can be /// called `V`. A different type parameter and a different lifetime can be
/// specified explicitly if necessary. /// specified explicitly if necessary.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use std::marker::PhantomData; /// # use std::marker::PhantomData;
/// # /// #
/// # use serde::forward_to_deserialize_any;
/// # use serde::de::{value, Deserializer, Visitor}; /// # use serde::de::{value, Deserializer, Visitor};
/// # /// #
/// # struct MyDeserializer<V>(PhantomData<V>); /// # struct MyDeserializer<V>(PhantomData<V>);
@@ -121,8 +103,6 @@
/// tuple_struct map struct enum identifier ignored_any /// tuple_struct map struct enum identifier ignored_any
/// } /// }
/// # } /// # }
/// #
/// # fn main() {}
/// ``` /// ```
/// ///
/// [`Deserializer`]: trait.Deserializer.html /// [`Deserializer`]: trait.Deserializer.html
+8 -14
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 lib::*;
use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor}; use de::{Deserialize, DeserializeSeed, Deserializer, Error, IntoDeserializer, Visitor};
@@ -1427,6 +1419,7 @@ mod content {
Content::Str(v) => visitor.visit_borrowed_str(v), Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(v) => visitor.visit_byte_buf(v), Content::ByteBuf(v) => visitor.visit_byte_buf(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v), Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::U8(v) => visitor.visit_u8(v),
_ => Err(self.invalid_type(&visitor)), _ => Err(self.invalid_type(&visitor)),
} }
} }
@@ -1763,7 +1756,7 @@ mod content {
V: Visitor<'de>, V: Visitor<'de>,
E: de::Error, 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 mut seq_visitor = de::value::SeqDeserializer::new(seq);
let value = try!(visitor.visit_seq(&mut seq_visitor)); let value = try!(visitor.visit_seq(&mut seq_visitor));
try!(seq_visitor.end()); try!(seq_visitor.end());
@@ -1778,7 +1771,7 @@ mod content {
V: Visitor<'de>, V: Visitor<'de>,
E: de::Error, 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(k),
ContentRefDeserializer::new(v), ContentRefDeserializer::new(v),
@@ -2085,7 +2078,7 @@ mod content {
{ {
let (variant, value) = match *self.content { let (variant, value) = match *self.content {
Content::Map(ref value) => { Content::Map(ref value) => {
let mut iter = value.into_iter(); let mut iter = value.iter();
let &(ref variant, ref value) = match iter.next() { let &(ref variant, ref value) = match iter.next() {
Some(v) => v, Some(v) => v,
None => { None => {
@@ -2129,6 +2122,7 @@ mod content {
Content::Str(v) => visitor.visit_borrowed_str(v), Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(ref v) => visitor.visit_bytes(v), Content::ByteBuf(ref v) => visitor.visit_bytes(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v), Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::U8(v) => visitor.visit_u8(v),
_ => Err(self.invalid_type(&visitor)), _ => Err(self.invalid_type(&visitor)),
} }
} }
@@ -2272,9 +2266,9 @@ mod content {
where where
E: de::Error, E: de::Error,
{ {
fn new(vec: &'a [Content<'de>]) -> Self { fn new(slice: &'a [Content<'de>]) -> Self {
SeqRefDeserializer { SeqRefDeserializer {
iter: vec.into_iter(), iter: slice.iter(),
err: PhantomData, err: PhantomData,
} }
} }
@@ -2350,7 +2344,7 @@ mod content {
{ {
fn new(map: &'a [(Content<'de>, Content<'de>)]) -> Self { fn new(map: &'a [(Content<'de>, Content<'de>)]) -> Self {
MapRefDeserializer { MapRefDeserializer {
iter: map.into_iter(), iter: map.iter(),
value: None, value: None,
err: PhantomData, err: PhantomData,
} }
-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.
#[doc(hidden)] #[doc(hidden)]
#[macro_export] #[macro_export]
macro_rules! __private_serialize { macro_rules! __private_serialize {
-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; mod macros;
pub mod de; 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 lib::*;
use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer}; use ser::{self, Impossible, Serialize, SerializeMap, SerializeStruct, Serializer};
@@ -409,10 +401,9 @@ mod content {
} }
fn end(mut self) -> Result<M::Ok, M::Error> { fn end(mut self) -> Result<M::Ok, M::Error> {
try!( try!(self
self.map .map
.serialize_value(&Content::TupleStruct(self.name, self.fields)) .serialize_value(&Content::TupleStruct(self.name, self.fields)));
);
self.map.end() self.map.end()
} }
} }
@@ -454,10 +445,9 @@ mod content {
} }
fn end(mut self) -> Result<M::Ok, M::Error> { fn end(mut self) -> Result<M::Ok, M::Error> {
try!( try!(self
self.map .map
.serialize_value(&Content::Struct(self.name, self.fields)) .serialize_value(&Content::Struct(self.name, self.fields)));
);
self.map.end() self.map.end()
} }
} }
@@ -1328,10 +1318,9 @@ where
} }
fn end(self) -> Result<(), Self::Error> { fn end(self) -> Result<(), Self::Error> {
try!( try!(self
self.map .map
.serialize_value(&Content::Struct(self.name, self.fields)) .serialize_value(&Content::Struct(self.name, self.fields)));
);
Ok(()) 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.
use lib::*; use lib::*;
use ser::{Error, Serialize, SerializeTuple, Serializer}; use ser::{Error, Serialize, SerializeTuple, Serializer};
+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.
//! This module contains `Impossible` serializer and its implementations. //! This module contains `Impossible` serializer and its implementations.
use lib::*; use lib::*;
@@ -23,10 +15,7 @@ use ser::{
/// [`SerializeTuple`], [`SerializeTupleStruct`], [`SerializeTupleVariant`], /// [`SerializeTuple`], [`SerializeTupleStruct`], [`SerializeTupleVariant`],
/// [`SerializeMap`], [`SerializeStruct`], and [`SerializeStructVariant`]. /// [`SerializeMap`], [`SerializeStruct`], and [`SerializeStructVariant`].
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::ser::{Serializer, Impossible}; /// # use serde::ser::{Serializer, Impossible};
/// # use serde::private::ser::Error; /// # use serde::private::ser::Error;
/// # /// #
@@ -52,14 +41,12 @@ use ser::{
/// } /// }
/// ///
/// /* other Serializer methods */ /// /* other Serializer methods */
/// # __serialize_unimplemented! { /// # serde::__serialize_unimplemented! {
/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str bytes none some /// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str bytes none some
/// # unit unit_struct unit_variant newtype_struct newtype_variant /// # unit unit_struct unit_variant newtype_struct newtype_variant
/// # tuple tuple_struct tuple_variant map struct struct_variant /// # tuple tuple_struct tuple_variant map struct struct_variant
/// # } /// # }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
/// ///
/// [`Serializer`]: trait.Serializer.html /// [`Serializer`]: trait.Serializer.html
+65 -162
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. //! Generic data structure serialization framework.
//! //!
//! The two most important traits in this module are [`Serialize`] and //! The two most important traits in this module are [`Serialize`] and
@@ -145,7 +137,7 @@ macro_rules! declare_error_trait {
/// For example, a filesystem [`Path`] may refuse to serialize /// For example, a filesystem [`Path`] may refuse to serialize
/// itself if it contains invalid UTF-8 data. /// itself if it contains invalid UTF-8 data.
/// ///
/// ```rust /// ```edition2018
/// # struct Path; /// # struct Path;
/// # /// #
/// # impl Path { /// # impl Path {
@@ -218,7 +210,7 @@ pub trait Serialize {
/// See the [Implementing `Serialize`] section of the manual for more /// See the [Implementing `Serialize`] section of the manual for more
/// information about how to implement this method. /// information about how to implement this method.
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, SerializeStruct, Serializer}; /// use serde::ser::{Serialize, SerializeStruct, Serializer};
/// ///
/// struct Person { /// struct Person {
@@ -385,13 +377,10 @@ pub trait Serializer: Sized {
/// Serialize a `bool` value. /// Serialize a `bool` value.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for bool { /// impl Serialize for bool {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -401,8 +390,6 @@ pub trait Serializer: Sized {
/// serializer.serialize_bool(*self) /// serializer.serialize_bool(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>; fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;
@@ -412,13 +399,10 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `i64` and /// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`. /// forward to `serialize_i64`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for i8 { /// impl Serialize for i8 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -428,8 +412,6 @@ pub trait Serializer: Sized {
/// serializer.serialize_i8(*self) /// serializer.serialize_i8(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>; fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>;
@@ -439,13 +421,10 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `i64` and /// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`. /// forward to `serialize_i64`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for i16 { /// impl Serialize for i16 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -455,8 +434,6 @@ pub trait Serializer: Sized {
/// serializer.serialize_i16(*self) /// serializer.serialize_i16(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>; fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>;
@@ -466,13 +443,10 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `i64` and /// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`. /// forward to `serialize_i64`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for i32 { /// impl Serialize for i32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -482,20 +456,15 @@ pub trait Serializer: Sized {
/// serializer.serialize_i32(*self) /// serializer.serialize_i32(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>; fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>;
/// Serialize an `i64` value. /// Serialize an `i64` value.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for i64 { /// impl Serialize for i64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -505,21 +474,16 @@ pub trait Serializer: Sized {
/// serializer.serialize_i64(*self) /// serializer.serialize_i64(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>; fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>;
serde_if_integer128! { serde_if_integer128! {
/// Serialize an `i128` value. /// Serialize an `i128` value.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for i128 { /// impl Serialize for i128 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -529,8 +493,6 @@ pub trait Serializer: Sized {
/// serializer.serialize_i128(*self) /// serializer.serialize_i128(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
/// ///
/// This method is available only on Rust compiler versions >=1.26. The /// This method is available only on Rust compiler versions >=1.26. The
@@ -547,13 +509,10 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `u64` and /// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`. /// forward to `serialize_u64`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for u8 { /// impl Serialize for u8 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -563,8 +522,6 @@ pub trait Serializer: Sized {
/// serializer.serialize_u8(*self) /// serializer.serialize_u8(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>; fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>;
@@ -574,13 +531,10 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `u64` and /// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`. /// forward to `serialize_u64`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for u16 { /// impl Serialize for u16 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -590,8 +544,6 @@ pub trait Serializer: Sized {
/// serializer.serialize_u16(*self) /// serializer.serialize_u16(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>; fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>;
@@ -601,13 +553,10 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `u64` and /// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`. /// forward to `serialize_u64`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for u32 { /// impl Serialize for u32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -617,20 +566,15 @@ pub trait Serializer: Sized {
/// serializer.serialize_u32(*self) /// serializer.serialize_u32(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>; fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>;
/// Serialize a `u64` value. /// Serialize a `u64` value.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for u64 { /// impl Serialize for u64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -640,21 +584,16 @@ pub trait Serializer: Sized {
/// serializer.serialize_u64(*self) /// serializer.serialize_u64(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>; fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>;
serde_if_integer128! { serde_if_integer128! {
/// Serialize a `u128` value. /// Serialize a `u128` value.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for u128 { /// impl Serialize for u128 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -664,8 +603,6 @@ pub trait Serializer: Sized {
/// serializer.serialize_u128(*self) /// serializer.serialize_u128(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
/// ///
/// This method is available only on Rust compiler versions >=1.26. The /// This method is available only on Rust compiler versions >=1.26. The
@@ -682,13 +619,10 @@ pub trait Serializer: Sized {
/// reasonable implementation would be to cast the value to `f64` and /// reasonable implementation would be to cast the value to `f64` and
/// forward to `serialize_f64`. /// forward to `serialize_f64`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for f32 { /// impl Serialize for f32 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -698,20 +632,15 @@ pub trait Serializer: Sized {
/// serializer.serialize_f32(*self) /// serializer.serialize_f32(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>; fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>;
/// Serialize an `f64` value. /// Serialize an `f64` value.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for f64 { /// impl Serialize for f64 {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -721,8 +650,6 @@ pub trait Serializer: Sized {
/// serializer.serialize_f64(*self) /// serializer.serialize_f64(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>; fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>;
@@ -731,13 +658,10 @@ pub trait Serializer: Sized {
/// If the format does not support characters, it is reasonable to serialize /// If the format does not support characters, it is reasonable to serialize
/// it as a single element `str` or a `u32`. /// it as a single element `str` or a `u32`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for char { /// impl Serialize for char {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -747,20 +671,15 @@ pub trait Serializer: Sized {
/// serializer.serialize_char(*self) /// serializer.serialize_char(*self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>; fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>;
/// Serialize a `&str`. /// Serialize a `&str`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for str { /// impl Serialize for str {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -770,8 +689,6 @@ pub trait Serializer: Sized {
/// serializer.serialize_str(self) /// serializer.serialize_str(self)
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error>; fn serialize_str(self, v: &str) -> Result<Self::Ok, Self::Error>;
@@ -783,10 +700,7 @@ pub trait Serializer: Sized {
/// `serialize_seq`. If forwarded, the implementation looks usually just /// `serialize_seq`. If forwarded, the implementation looks usually just
/// like this: /// like this:
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::ser::{Serializer, SerializeSeq}; /// # use serde::ser::{Serializer, SerializeSeq};
/// # use serde::private::ser::Error; /// # use serde::private::ser::Error;
/// # /// #
@@ -804,22 +718,18 @@ pub trait Serializer: Sized {
/// seq.end() /// seq.end()
/// } /// }
/// # /// #
/// # __serialize_unimplemented! { /// # serde::__serialize_unimplemented! {
/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str none some /// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str none some
/// # unit unit_struct unit_variant newtype_struct newtype_variant /// # unit unit_struct unit_variant newtype_struct newtype_variant
/// # seq tuple tuple_struct tuple_variant map struct struct_variant /// # seq tuple tuple_struct tuple_variant map struct struct_variant
/// # } /// # }
/// # } /// # }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error>; fn serialize_bytes(self, v: &[u8]) -> Result<Self::Ok, Self::Error>;
/// Serialize a [`None`] value. /// Serialize a [`None`] value.
/// ///
/// ```rust /// ```edition2018
/// # extern crate serde;
/// #
/// # use serde::{Serialize, Serializer}; /// # use serde::{Serialize, Serializer};
/// # /// #
/// # enum Option<T> { /// # enum Option<T> {
@@ -827,7 +737,7 @@ pub trait Serializer: Sized {
/// # None, /// # None,
/// # } /// # }
/// # /// #
/// # use Option::{Some, None}; /// # use self::Option::{Some, None};
/// # /// #
/// impl<T> Serialize for Option<T> /// impl<T> Serialize for Option<T>
/// where /// where
@@ -852,9 +762,7 @@ pub trait Serializer: Sized {
/// Serialize a [`Some(T)`] value. /// Serialize a [`Some(T)`] value.
/// ///
/// ```rust /// ```edition2018
/// # extern crate serde;
/// #
/// # use serde::{Serialize, Serializer}; /// # use serde::{Serialize, Serializer};
/// # /// #
/// # enum Option<T> { /// # enum Option<T> {
@@ -862,7 +770,7 @@ pub trait Serializer: Sized {
/// # None, /// # None,
/// # } /// # }
/// # /// #
/// # use Option::{Some, None}; /// # use self::Option::{Some, None};
/// # /// #
/// impl<T> Serialize for Option<T> /// impl<T> Serialize for Option<T>
/// where /// where
@@ -889,13 +797,10 @@ pub trait Serializer: Sized {
/// Serialize a `()` value. /// Serialize a `()` value.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::Serializer; /// # use serde::Serializer;
/// # /// #
/// # __private_serialize!(); /// # serde::__private_serialize!();
/// # /// #
/// impl Serialize for () { /// impl Serialize for () {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -905,8 +810,6 @@ pub trait Serializer: Sized {
/// serializer.serialize_unit() /// serializer.serialize_unit()
/// } /// }
/// } /// }
/// #
/// # fn main() {}
/// ``` /// ```
fn serialize_unit(self) -> Result<Self::Ok, Self::Error>; fn serialize_unit(self) -> Result<Self::Ok, Self::Error>;
@@ -914,7 +817,7 @@ pub trait Serializer: Sized {
/// ///
/// A reasonable implementation would be to forward to `serialize_unit`. /// A reasonable implementation would be to forward to `serialize_unit`.
/// ///
/// ```rust /// ```edition2018
/// use serde::{Serialize, Serializer}; /// use serde::{Serialize, Serializer};
/// ///
/// struct Nothing; /// struct Nothing;
@@ -936,7 +839,7 @@ pub trait Serializer: Sized {
/// this variant within the enum, and the `variant` is the name of the /// this variant within the enum, and the `variant` is the name of the
/// variant. /// variant.
/// ///
/// ```rust /// ```edition2018
/// use serde::{Serialize, Serializer}; /// use serde::{Serialize, Serializer};
/// ///
/// enum E { /// enum E {
@@ -969,7 +872,7 @@ pub trait Serializer: Sized {
/// wrappers around the data they contain. A reasonable implementation would /// wrappers around the data they contain. A reasonable implementation would
/// be to forward to `value.serialize(self)`. /// be to forward to `value.serialize(self)`.
/// ///
/// ```rust /// ```edition2018
/// use serde::{Serialize, Serializer}; /// use serde::{Serialize, Serializer};
/// ///
/// struct Millimeters(u8); /// struct Millimeters(u8);
@@ -997,7 +900,7 @@ pub trait Serializer: Sized {
/// this variant within the enum, and the `variant` is the name of the /// this variant within the enum, and the `variant` is the name of the
/// variant. The `value` is the data contained within this newtype variant. /// variant. The `value` is the data contained within this newtype variant.
/// ///
/// ```rust /// ```edition2018
/// use serde::{Serialize, Serializer}; /// use serde::{Serialize, Serializer};
/// ///
/// enum E { /// enum E {
@@ -1035,7 +938,7 @@ pub trait Serializer: Sized {
/// not be computable before the sequence is iterated. Some serializers only /// not be computable before the sequence is iterated. Some serializers only
/// support sequences whose length is known up front. /// support sequences whose length is known up front.
/// ///
/// ```rust /// ```edition2018
/// # use std::marker::PhantomData; /// # use std::marker::PhantomData;
/// # /// #
/// # struct Vec<T>(PhantomData<T>); /// # struct Vec<T>(PhantomData<T>);
@@ -1080,7 +983,7 @@ pub trait Serializer: Sized {
/// This call must be followed by zero or more calls to `serialize_element`, /// This call must be followed by zero or more calls to `serialize_element`,
/// then a call to `end`. /// then a call to `end`.
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, Serializer, SerializeTuple}; /// use serde::ser::{Serialize, Serializer, SerializeTuple};
/// ///
/// # mod fool { /// # mod fool {
@@ -1110,7 +1013,7 @@ pub trait Serializer: Sized {
/// } /// }
/// ``` /// ```
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, SerializeTuple, Serializer}; /// use serde::ser::{Serialize, SerializeTuple, Serializer};
/// ///
/// const VRAM_SIZE: usize = 386; /// const VRAM_SIZE: usize = 386;
@@ -1138,7 +1041,7 @@ pub trait Serializer: Sized {
/// The `name` is the name of the tuple struct and the `len` is the number /// The `name` is the name of the tuple struct and the `len` is the number
/// of data fields that will be serialized. /// of data fields that will be serialized.
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer}; /// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
/// ///
/// struct Rgb(u8, u8, u8); /// struct Rgb(u8, u8, u8);
@@ -1170,7 +1073,7 @@ pub trait Serializer: Sized {
/// this variant within the enum, the `variant` is the name of the variant, /// this variant within the enum, the `variant` is the name of the variant,
/// and the `len` is the number of data fields that will be serialized. /// and the `len` is the number of data fields that will be serialized.
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer}; /// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
/// ///
/// enum E { /// enum E {
@@ -1216,7 +1119,7 @@ pub trait Serializer: Sized {
/// be computable before the map is iterated. Some serializers only support /// be computable before the map is iterated. Some serializers only support
/// maps whose length is known up front. /// maps whose length is known up front.
/// ///
/// ```rust /// ```edition2018
/// # use std::marker::PhantomData; /// # use std::marker::PhantomData;
/// # /// #
/// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>); /// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>);
@@ -1264,7 +1167,7 @@ pub trait Serializer: Sized {
/// The `name` is the name of the struct and the `len` is the number of /// The `name` is the name of the struct and the `len` is the number of
/// data fields that will be serialized. /// data fields that will be serialized.
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, SerializeStruct, Serializer}; /// use serde::ser::{Serialize, SerializeStruct, Serializer};
/// ///
/// struct Rgb { /// struct Rgb {
@@ -1300,7 +1203,7 @@ pub trait Serializer: Sized {
/// this variant within the enum, the `variant` is the name of the variant, /// this variant within the enum, the `variant` is the name of the variant,
/// and the `len` is the number of data fields that will be serialized. /// and the `len` is the number of data fields that will be serialized.
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer}; /// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
/// ///
/// enum E { /// enum E {
@@ -1342,7 +1245,7 @@ pub trait Serializer: Sized {
/// using [`serialize_seq`]. Implementors should not need to override this /// using [`serialize_seq`]. Implementors should not need to override this
/// method. /// method.
/// ///
/// ```rust /// ```edition2018
/// use serde::{Serialize, Serializer}; /// use serde::{Serialize, Serializer};
/// ///
/// struct SecretlyOneHigher { /// struct SecretlyOneHigher {
@@ -1379,7 +1282,7 @@ pub trait Serializer: Sized {
/// using [`serialize_map`]. Implementors should not need to override this /// using [`serialize_map`]. Implementors should not need to override this
/// method. /// method.
/// ///
/// ```rust /// ```edition2018
/// use serde::{Serialize, Serializer}; /// use serde::{Serialize, Serializer};
/// use std::collections::BTreeSet; /// use std::collections::BTreeSet;
/// ///
@@ -1419,7 +1322,7 @@ pub trait Serializer: Sized {
/// delegates to [`serialize_str`]. Serializers are encouraged to provide a /// delegates to [`serialize_str`]. Serializers are encouraged to provide a
/// more efficient implementation if possible. /// more efficient implementation if possible.
/// ///
/// ```rust /// ```edition2018
/// # struct DateTime; /// # struct DateTime;
/// # /// #
/// # impl DateTime { /// # impl DateTime {
@@ -1460,7 +1363,7 @@ pub trait Serializer: Sized {
/// of this method. If no more sensible behavior is possible, the /// of this method. If no more sensible behavior is possible, the
/// implementation is expected to return an error. /// implementation is expected to return an error.
/// ///
/// ```rust /// ```edition2018
/// # struct DateTime; /// # struct DateTime;
/// # /// #
/// # impl DateTime { /// # impl DateTime {
@@ -1495,7 +1398,7 @@ pub trait Serializer: Sized {
/// human-readable one and binary formats like Bincode will prefer the /// human-readable one and binary formats like Bincode will prefer the
/// compact one. /// compact one.
/// ///
/// ``` /// ```edition2018
/// # use std::fmt::{self, Display}; /// # use std::fmt::{self, Display};
/// # /// #
/// # struct Timestamp; /// # struct Timestamp;
@@ -1544,7 +1447,7 @@ pub trait Serializer: Sized {
/// ///
/// # Example use /// # Example use
/// ///
/// ```rust /// ```edition2018
/// # use std::marker::PhantomData; /// # use std::marker::PhantomData;
/// # /// #
/// # struct Vec<T>(PhantomData<T>); /// # struct Vec<T>(PhantomData<T>);
@@ -1608,7 +1511,7 @@ pub trait SerializeSeq {
/// ///
/// # Example use /// # Example use
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, Serializer, SerializeTuple}; /// use serde::ser::{Serialize, Serializer, SerializeTuple};
/// ///
/// # mod fool { /// # mod fool {
@@ -1638,7 +1541,7 @@ pub trait SerializeSeq {
/// } /// }
/// ``` /// ```
/// ///
/// ```rust /// ```edition2018
/// # use std::marker::PhantomData; /// # use std::marker::PhantomData;
/// # /// #
/// # struct Array<T>(PhantomData<T>); /// # struct Array<T>(PhantomData<T>);
@@ -1708,7 +1611,7 @@ pub trait SerializeTuple {
/// ///
/// # Example use /// # Example use
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer}; /// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
/// ///
/// struct Rgb(u8, u8, u8); /// struct Rgb(u8, u8, u8);
@@ -1753,7 +1656,7 @@ pub trait SerializeTupleStruct {
/// ///
/// # Example use /// # Example use
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer}; /// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
/// ///
/// enum E { /// enum E {
@@ -1811,7 +1714,7 @@ pub trait SerializeTupleVariant {
/// ///
/// # Example use /// # Example use
/// ///
/// ```rust /// ```edition2018
/// # use std::marker::PhantomData; /// # use std::marker::PhantomData;
/// # /// #
/// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>); /// # struct HashMap<K, V>(PhantomData<K>, PhantomData<V>);
@@ -1922,7 +1825,7 @@ pub trait SerializeMap {
/// ///
/// # Example use /// # Example use
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, SerializeStruct, Serializer}; /// use serde::ser::{Serialize, SerializeStruct, Serializer};
/// ///
/// struct Rgb { /// struct Rgb {
@@ -1982,7 +1885,7 @@ pub trait SerializeStruct {
/// ///
/// # Example use /// # Example use
/// ///
/// ```rust /// ```edition2018
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer}; /// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
/// ///
/// enum E { /// enum E {
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.80" # remember to update html_root_url version = "1.0.85" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -26,7 +26,7 @@ proc-macro = true
[dependencies] [dependencies]
proc-macro2 = "0.4" proc-macro2 = "0.4"
quote = "0.6.3" quote = "0.6.3"
syn = { version = "0.15", features = ["visit"] } syn = { version = "0.15.22", features = ["visit"] }
[dev-dependencies] [dev-dependencies]
serde = { version = "1.0", path = "../serde" } serde = { version = "1.0", path = "../serde" }
+25 -24
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 std::collections::HashSet;
use syn; use syn;
@@ -32,7 +24,8 @@ pub fn without_defaults(generics: &syn::Generics) -> syn::Generics {
..param.clone() ..param.clone()
}), }),
_ => param.clone(), _ => param.clone(),
}).collect(), })
.collect(),
..generics.clone() ..generics.clone()
} }
} }
@@ -45,7 +38,7 @@ pub fn with_where_predicates(
generics generics
.make_where_clause() .make_where_clause()
.predicates .predicates
.extend(predicates.into_iter().cloned()); .extend(predicates.iter().cloned());
generics generics
} }
@@ -168,15 +161,17 @@ pub fn with_bound(
associated_type_usage: Vec::new(), associated_type_usage: Vec::new(),
}; };
match cont.data { match cont.data {
Data::Enum(ref variants) => for variant in variants.iter() { Data::Enum(ref variants) => {
let relevant_fields = variant for variant in variants.iter() {
.fields let relevant_fields = variant
.iter() .fields
.filter(|field| filter(&field.attrs, Some(&variant.attrs))); .iter()
for field in relevant_fields { .filter(|field| filter(&field.attrs, Some(&variant.attrs)));
visitor.visit_field(field.original); for field in relevant_fields {
visitor.visit_field(field.original);
}
} }
}, }
Data::Struct(_, ref fields) => { Data::Struct(_, ref fields) => {
for field in fields.iter().filter(|field| filter(&field.attrs, None)) { for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
visitor.visit_field(field.original); visitor.visit_field(field.original);
@@ -193,7 +188,8 @@ pub fn with_bound(
.map(|id| syn::TypePath { .map(|id| syn::TypePath {
qself: None, qself: None,
path: id.into(), path: id.into(),
}).chain(associated_type_usage.into_iter().cloned()) })
.chain(associated_type_usage.into_iter().cloned())
.map(|bounded_ty| { .map(|bounded_ty| {
syn::WherePredicate::Type(syn::PredicateType { syn::WherePredicate::Type(syn::PredicateType {
lifetimes: None, lifetimes: None,
@@ -206,7 +202,8 @@ pub fn with_bound(
modifier: syn::TraitBoundModifier::None, modifier: syn::TraitBoundModifier::None,
lifetimes: None, lifetimes: None,
path: bound.clone(), path: bound.clone(),
})].into_iter() })]
.into_iter()
.collect(), .collect(),
}) })
}); });
@@ -239,7 +236,8 @@ pub fn with_self_bound(
modifier: syn::TraitBoundModifier::None, modifier: syn::TraitBoundModifier::None,
lifetimes: None, lifetimes: None,
path: bound.clone(), path: bound.clone(),
})].into_iter() })]
.into_iter()
.collect(), .collect(),
})); }));
generics generics
@@ -269,7 +267,8 @@ pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Gen
syn::GenericParam::Const(_) => {} syn::GenericParam::Const(_) => {}
} }
param param
})).collect(); }))
.collect();
syn::Generics { syn::Generics {
params: params, params: params,
@@ -305,11 +304,13 @@ fn type_of_item(cont: &Container) -> syn::Type {
syn::GenericParam::Const(_) => { syn::GenericParam::Const(_) => {
panic!("Serde does not support const generics yet"); panic!("Serde does not support const generics yet");
} }
}).collect(), })
.collect(),
gt_token: <Token![>]>::default(), gt_token: <Token![>]>::default(),
}, },
), ),
}].into_iter() }]
.into_iter()
.collect(), .collect(),
}, },
}) })
+166 -163
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 proc_macro2::{Literal, Span, TokenStream};
use quote::ToTokens; use quote::ToTokens;
use syn::punctuated::Punctuated; use syn::punctuated::Punctuated;
@@ -13,28 +5,26 @@ use syn::spanned::Spanned;
use syn::{self, Ident, Index, Member}; use syn::{self, Ident, Index, Member};
use bound; use bound;
use dummy;
use fragment::{Expr, Fragment, Match, Stmts}; use fragment::{Expr, Fragment, Match, Stmts};
use internals::ast::{Container, Data, Field, Style, Variant}; use internals::ast::{Container, Data, Field, Style, Variant};
use internals::{attr, Ctxt, Derive}; use internals::{attr, Ctxt, Derive};
use pretend; use pretend;
use try;
use std::collections::BTreeSet; 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 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); precondition(&ctxt, &cont);
try!(ctxt.check()); try!(ctxt.check());
let ident = &cont.ident; let ident = &cont.ident;
let params = Parameters::new(&cont); let params = Parameters::new(&cont);
let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params); 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_{}", suffix),
Span::call_site(),
);
let body = Stmts(deserialize_body(&cont, &params)); let body = Stmts(deserialize_body(&cont, &params));
let delife = params.borrowed.de_lifetime(); let delife = params.borrowed.de_lifetime();
@@ -70,19 +60,7 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream
} }
}; };
let try_replacement = try::replacement(); Ok(dummy::wrap_in_const("DESERIALIZE", ident, impl_block))
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
};
};
Ok(generated)
} }
fn precondition(cx: &Ctxt, cont: &Container) { fn precondition(cx: &Ctxt, cont: &Container) {
@@ -94,7 +72,10 @@ fn precondition_sized(cx: &Ctxt, cont: &Container) {
if let Data::Struct(_, ref fields) = cont.data { if let Data::Struct(_, ref fields) = cont.data {
if let Some(last) = fields.last() { if let Some(last) = fields.last() {
if let syn::Type::Slice(_) = *last.ty { 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",
);
} }
} }
} }
@@ -104,7 +85,10 @@ fn precondition_no_de_lifetime(cx: &Ctxt, cont: &Container) {
if let BorrowedLifetimes::Borrowed(_) = borrowed_lifetimes(cont) { if let BorrowedLifetimes::Borrowed(_) = borrowed_lifetimes(cont) {
for param in cont.generics.lifetimes() { for param in cont.generics.lifetimes() {
if param.lifetime.to_string() == "'de" { 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; return;
} }
} }
@@ -365,7 +349,10 @@ fn deserialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
let path = match transparent_field.attrs.deserialize_with() { let path = match transparent_field.attrs.deserialize_with() {
Some(path) => quote!(#path), 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| { let assign = fields.iter().map(|field| {
@@ -660,11 +647,18 @@ fn deserialize_seq(
}) })
} }
}; };
let value_if_none = match *field.attrs.default() {
attr::Default::Default => quote!(_serde::export::Default::default()),
attr::Default::Path(ref path) => quote!(#path()),
attr::Default::None => quote!(
return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
),
};
let assign = quote! { let assign = quote! {
let #var = match #visit { let #var = match #visit {
_serde::export::Some(__value) => __value, _serde::export::Some(__value) => __value,
_serde::export::None => { _serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting)); #value_if_none
} }
}; };
}; };
@@ -739,8 +733,16 @@ fn deserialize_seq_in_place(
self.place.#member = #default; self.place.#member = #default;
} }
} else { } else {
let return_invalid_length = quote! { let value_if_none = match *field.attrs.default() {
return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting)); attr::Default::Default => quote!(
self.place.#member = _serde::export::Default::default();
),
attr::Default::Path(ref path) => quote!(
self.place.#member = #path();
),
attr::Default::None => quote!(
return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
),
}; };
let write = match field.attrs.deserialize_with() { let write = match field.attrs.deserialize_with() {
None => { None => {
@@ -748,23 +750,23 @@ fn deserialize_seq_in_place(
if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq, if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
_serde::private::de::InPlaceSeed(&mut self.place.#member))) _serde::private::de::InPlaceSeed(&mut self.place.#member)))
{ {
#return_invalid_length #value_if_none
} }
} }
} }
Some(path) => { Some(path) => {
let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path); let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
quote!({ quote!({
#wrapper #wrapper
match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) { match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
_serde::export::Some(__wrap) => { _serde::export::Some(__wrap) => {
self.place.#member = __wrap.value; self.place.#member = __wrap.value;
}
_serde::export::None => {
#return_invalid_length
}
} }
}) _serde::export::None => {
#value_if_none
}
}
})
} }
}; };
index_in_seq += 1; index_in_seq += 1;
@@ -805,8 +807,10 @@ fn deserialize_newtype_struct(
let value = match field.attrs.deserialize_with() { let value = match field.attrs.deserialize_with() {
None => { None => {
let span = field.original.span();
let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
quote! { quote! {
try!(<#field_ty as _serde::Deserialize>::deserialize(__e)) try!(#func(__e))
} }
} }
Some(path) => { Some(path) => {
@@ -1124,18 +1128,52 @@ fn deserialize_enum(
cattrs: &attr::Container, cattrs: &attr::Container,
) -> Fragment { ) -> Fragment {
match *cattrs.tag() { match *cattrs.tag() {
attr::EnumTag::External => deserialize_externally_tagged_enum(params, variants, cattrs), attr::TagType::External => deserialize_externally_tagged_enum(params, variants, cattrs),
attr::EnumTag::Internal { ref tag } => { attr::TagType::Internal { ref tag } => {
deserialize_internally_tagged_enum(params, variants, cattrs, tag) deserialize_internally_tagged_enum(params, variants, cattrs, tag)
} }
attr::EnumTag::Adjacent { attr::TagType::Adjacent {
ref tag, ref tag,
ref content, ref content,
} => deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content), } => deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content),
attr::EnumTag::None => deserialize_untagged_enum(params, variants, cattrs), attr::TagType::None => deserialize_untagged_enum(params, variants, cattrs),
} }
} }
fn prepare_enum_variant_enum(
variants: &[Variant],
cattrs: &attr::Container,
) -> (TokenStream, Stmts) {
let variant_names_idents: Vec<_> = variants
.iter()
.enumerate()
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
.map(|(i, variant)| {
(variant.attrs.name().deserialize_name(), field_i(i), variant.attrs.aliases())
})
.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! {
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
}
};
let variant_visitor = Stmts(deserialize_generated_identifier(
&variant_names_idents,
cattrs,
true,
other_idx,
));
(variants_stmt, variant_visitor)
}
fn deserialize_externally_tagged_enum( fn deserialize_externally_tagged_enum(
params: &Parameters, params: &Parameters,
variants: &[Variant], variants: &[Variant],
@@ -1147,33 +1185,9 @@ fn deserialize_externally_tagged_enum(
let delife = params.borrowed.de_lifetime(); let delife = params.borrowed.de_lifetime();
let type_name = cattrs.name().deserialize_name(); let type_name = cattrs.name().deserialize_name();
let expecting = format!("enum {}", params.type_name()); let expecting = format!("enum {}", params.type_name());
let variant_names_idents: Vec<_> = variants let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
.iter()
.enumerate()
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
.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! {
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
}
};
let variant_visitor = Stmts(deserialize_generated_identifier(
&variant_names_idents,
cattrs,
true,
other_idx,
));
// Match arms to extract a variant from a string // Match arms to extract a variant from a string
let variant_arms = variants let variant_arms = variants
@@ -1239,11 +1253,15 @@ fn deserialize_externally_tagged_enum(
#variants_stmt #variants_stmt
_serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS, _serde::Deserializer::deserialize_enum(
__Visitor { __deserializer,
marker: _serde::export::PhantomData::<#this #ty_generics>, #type_name,
lifetime: _serde::export::PhantomData, VARIANTS,
}) __Visitor {
marker: _serde::export::PhantomData::<#this #ty_generics>,
lifetime: _serde::export::PhantomData,
},
)
} }
} }
@@ -1253,30 +1271,7 @@ fn deserialize_internally_tagged_enum(
cattrs: &attr::Container, cattrs: &attr::Container,
tag: &str, tag: &str,
) -> Fragment { ) -> Fragment {
let variant_names_idents: Vec<_> = variants let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
.iter()
.enumerate()
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
.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! {
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
}
};
let variant_visitor = Stmts(deserialize_generated_identifier(
&variant_names_idents,
cattrs,
true,
other_idx,
));
// Match arms to extract a variant from a string // Match arms to extract a variant from a string
let variant_arms = variants let variant_arms = variants
@@ -1327,30 +1322,7 @@ fn deserialize_adjacently_tagged_enum(
split_with_de_lifetime(params); split_with_de_lifetime(params);
let delife = params.borrowed.de_lifetime(); let delife = params.borrowed.de_lifetime();
let variant_names_idents: Vec<_> = variants let (variants_stmt, variant_visitor) = prepare_enum_variant_enum(variants, cattrs);
.iter()
.enumerate()
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
.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! {
const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
}
};
let variant_visitor = Stmts(deserialize_generated_identifier(
&variant_names_idents,
cattrs,
true,
other_idx,
));
let variant_arms: &Vec<_> = &variants let variant_arms: &Vec<_> = &variants
.iter() .iter()
@@ -1369,7 +1341,8 @@ fn deserialize_adjacently_tagged_enum(
quote! { quote! {
__Field::#variant_index => #block __Field::#variant_index => #block
} }
}).collect(); })
.collect();
let expecting = format!("adjacently tagged enum {}", params.type_name()); let expecting = format!("adjacently tagged enum {}", params.type_name());
let type_name = cattrs.name().deserialize_name(); let type_name = cattrs.name().deserialize_name();
@@ -1593,12 +1566,14 @@ fn deserialize_adjacently_tagged_enum(
match try!(_serde::de::SeqAccess::next_element(&mut __seq)) { match try!(_serde::de::SeqAccess::next_element(&mut __seq)) {
_serde::export::Some(__field) => { _serde::export::Some(__field) => {
// Visit the second element - the content. // Visit the second element - the content.
match try!(_serde::de::SeqAccess::next_element_seed(&mut __seq, match try!(_serde::de::SeqAccess::next_element_seed(
__Seed { &mut __seq,
field: __field, __Seed {
marker: _serde::export::PhantomData, field: __field,
lifetime: _serde::export::PhantomData, marker: _serde::export::PhantomData,
})) { lifetime: _serde::export::PhantomData,
},
)) {
_serde::export::Some(__ret) => _serde::export::Ok(__ret), _serde::export::Some(__ret) => _serde::export::Ok(__ret),
// There is no second element. // There is no second element.
_serde::export::None => { _serde::export::None => {
@@ -1615,11 +1590,15 @@ fn deserialize_adjacently_tagged_enum(
} }
const FIELDS: &'static [&'static str] = &[#tag, #content]; const FIELDS: &'static [&'static str] = &[#tag, #content];
_serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, _serde::Deserializer::deserialize_struct(
__deserializer,
#type_name,
FIELDS,
__Visitor { __Visitor {
marker: _serde::export::PhantomData::<#this #ty_generics>, marker: _serde::export::PhantomData::<#this #ty_generics>,
lifetime: _serde::export::PhantomData, lifetime: _serde::export::PhantomData,
}) },
)
} }
} }
@@ -1810,10 +1789,11 @@ fn deserialize_externally_tagged_newtype_variant(
match field.attrs.deserialize_with() { match field.attrs.deserialize_with() {
None => { None => {
let field_ty = field.ty; let field_ty = field.ty;
let span = field.original.span();
let func =
quote_spanned!(span=> _serde::de::VariantAccess::newtype_variant::<#field_ty>);
quote_expr! { quote_expr! {
_serde::export::Result::map( _serde::export::Result::map(#func(__variant), #this::#variant_ident)
_serde::de::VariantAccess::newtype_variant::<#field_ty>(__variant),
#this::#variant_ident)
} }
} }
Some(path) => { Some(path) => {
@@ -1838,10 +1818,10 @@ fn deserialize_untagged_newtype_variant(
let field_ty = field.ty; let field_ty = field.ty;
match field.attrs.deserialize_with() { match field.attrs.deserialize_with() {
None => { None => {
let span = field.original.span();
let func = quote_spanned!(span=> <#field_ty as _serde::Deserialize>::deserialize);
quote_expr! { quote_expr! {
_serde::export::Result::map( _serde::export::Result::map(#func(#deserializer), #this::#variant_ident)
<#field_ty as _serde::Deserialize>::deserialize(#deserializer),
#this::#variant_ident)
} }
} }
Some(path) => { Some(path) => {
@@ -1854,13 +1834,13 @@ fn deserialize_untagged_newtype_variant(
} }
fn deserialize_generated_identifier( fn deserialize_generated_identifier(
fields: &[(String, Ident)], fields: &[(String, Ident, Vec<String>)],
cattrs: &attr::Container, cattrs: &attr::Container,
is_variant: bool, is_variant: bool,
other_idx: Option<usize>, other_idx: Option<usize>,
) -> Fragment { ) -> Fragment {
let this = quote!(__Field); let this = quote!(__Field);
let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident)| ident).collect(); let field_idents: &Vec<_> = &fields.iter().map(|&(_, ref ident, _)| ident).collect();
let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() { let (ignore_variant, fallthrough) = if !is_variant && cattrs.has_flatten() {
let ignore_variant = quote!(__other(_serde::private::de::Content<'de>),); let ignore_variant = quote!(__other(_serde::private::de::Content<'de>),);
@@ -1961,10 +1941,12 @@ fn deserialize_custom_identifier(
( (
variant.attrs.name().deserialize_name(), variant.attrs.name().deserialize_name(),
variant.ident.clone(), variant.ident.clone(),
variant.attrs.aliases(),
) )
}).collect(); })
.collect();
let names = names_idents.iter().map(|&(ref name, _)| name); let names = names_idents.iter().map(|&(ref name, _, _)| name);
let names_const = if fallthrough.is_some() { let names_const = if fallthrough.is_some() {
None None
@@ -2015,24 +1997,33 @@ fn deserialize_custom_identifier(
fn deserialize_identifier( fn deserialize_identifier(
this: &TokenStream, this: &TokenStream,
fields: &[(String, Ident)], fields: &[(String, Ident, Vec<String>)],
is_variant: bool, is_variant: bool,
fallthrough: Option<TokenStream>, fallthrough: Option<TokenStream>,
collect_other_fields: bool, collect_other_fields: bool,
) -> Fragment { ) -> Fragment {
let field_strs = fields.iter().map(|&(ref name, _)| name); let mut flat_fields = Vec::new();
let field_borrowed_strs = fields.iter().map(|&(ref name, _)| name); for &(_, ref ident, ref aliases) in fields {
let field_bytes = fields flat_fields.extend(aliases.iter().map(|alias| (alias, ident)))
}
let field_strs = flat_fields.iter().map(|&(ref name, _)| name);
let field_borrowed_strs = flat_fields.iter().map(|&(ref name, _)| name);
let field_bytes = flat_fields
.iter() .iter()
.map(|&(ref name, _)| Literal::byte_string(name.as_bytes())); .map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
let field_borrowed_bytes = fields let field_borrowed_bytes = flat_fields
.iter() .iter()
.map(|&(ref name, _)| Literal::byte_string(name.as_bytes())); .map(|&(ref name, _)| Literal::byte_string(name.as_bytes()));
let constructors: &Vec<_> = &fields let constructors: &Vec<_> = &flat_fields
.iter() .iter()
.map(|&(_, ref ident)| quote!(#this::#ident)) .map(|&(_, ref ident)| quote!(#this::#ident))
.collect(); .collect();
let main_constructors: &Vec<_> = &fields
.iter()
.map(|&(_, ref ident, _)| quote!(#this::#ident))
.collect();
let expecting = if is_variant { let expecting = if is_variant {
"variant identifier" "variant identifier"
@@ -2220,11 +2211,12 @@ fn deserialize_identifier(
{ {
match __value { match __value {
#( #(
#variant_indices => _serde::export::Ok(#constructors), #variant_indices => _serde::export::Ok(#main_constructors),
)* )*
_ => _serde::export::Err(_serde::de::Error::invalid_value( _ => _serde::export::Err(_serde::de::Error::invalid_value(
_serde::de::Unexpected::Unsigned(__value), _serde::de::Unexpected::Unsigned(__value),
&#fallthrough_msg)) &#fallthrough_msg,
))
} }
} }
} }
@@ -2282,11 +2274,13 @@ fn deserialize_struct_as_struct_visitor(
.iter() .iter()
.enumerate() .enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing()) .filter(|&(_, field)| !field.attrs.skip_deserializing())
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i))) .map(|(i, field)| {
(field.attrs.name().deserialize_name(), field_i(i), field.attrs.aliases())
})
.collect(); .collect();
let fields_stmt = { let fields_stmt = {
let field_names = field_names_idents.iter().map(|&(ref name, _)| name); let field_names = field_names_idents.iter().map(|&(ref name, _, _)| name);
quote_block! { quote_block! {
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
} }
@@ -2309,7 +2303,9 @@ fn deserialize_struct_as_map_visitor(
.iter() .iter()
.enumerate() .enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) .filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i))) .map(|(i, field)| {
(field.attrs.name().deserialize_name(), field_i(i), field.attrs.aliases())
})
.collect(); .collect();
let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None); let field_visitor = deserialize_generated_identifier(&field_names_idents, cattrs, false, None);
@@ -2447,7 +2443,10 @@ fn deserialize_map(
.map(|&(field, ref name)| { .map(|&(field, ref name)| {
let field_ty = field.ty; let field_ty = field.ty;
let func = match field.attrs.deserialize_with() { 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), Some(path) => quote!(#path),
}; };
quote! { quote! {
@@ -2537,11 +2536,13 @@ fn deserialize_struct_as_struct_in_place_visitor(
.iter() .iter()
.enumerate() .enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing()) .filter(|&(_, field)| !field.attrs.skip_deserializing())
.map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i))) .map(|(i, field)| {
(field.attrs.name().deserialize_name(), field_i(i), field.attrs.aliases())
})
.collect(); .collect();
let fields_stmt = { let fields_stmt = {
let field_names = field_names_idents.iter().map(|&(ref name, _)| name); let field_names = field_names_idents.iter().map(|&(ref name, _, _)| name);
quote_block! { quote_block! {
const FIELDS: &'static [&'static str] = &[ #(#field_names),* ]; const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
} }
@@ -2799,7 +2800,9 @@ fn wrap_deserialize_variant_with(
fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment { fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
match *field.attrs.default() { match *field.attrs.default() {
attr::Default::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) => { attr::Default::Path(ref path) => {
return quote_expr!(#path()); return quote_expr!(#path());
+32
View File
@@ -0,0 +1,32 @@
use proc_macro2::{Ident, Span, TokenStream};
use try;
pub fn wrap_in_const(trait_: &str, ty: &Ident, code: TokenStream) -> TokenStream {
let try_replacement = try::replacement();
let dummy_const = Ident::new(
&format!("_IMPL_{}_FOR_{}", trait_, unraw(ty)),
Span::call_site(),
);
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
#code
};
}
}
#[allow(deprecated)]
fn unraw(ident: &Ident) -> String {
// str::trim_start_matches was added in 1.30, trim_left_matches deprecated
// in 1.33. We currently support rustc back to 1.15 so we need to continue
// to use the deprecated one.
ident.to_string().trim_left_matches("r#").to_owned()
}
-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 proc_macro2::TokenStream;
use quote::ToTokens; use quote::ToTokens;
use syn::token; use syn::token;
+34 -24
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.
//! A Serde ast, parsed from the Syn ast and ready to generate Rust code. //! A Serde ast, parsed from the Syn ast and ready to generate Rust code.
use internals::attr; use internals::attr;
@@ -25,6 +17,8 @@ pub struct Container<'a> {
pub data: Data<'a>, pub data: Data<'a>,
/// Any generics on the struct or enum. /// Any generics on the struct or enum.
pub generics: &'a syn::Generics, pub generics: &'a syn::Generics,
/// Original input.
pub original: &'a syn::DeriveInput,
} }
/// The fields of a struct or enum. /// The fields of a struct or enum.
@@ -41,6 +35,7 @@ pub struct Variant<'a> {
pub attrs: attr::Variant, pub attrs: attr::Variant,
pub style: Style, pub style: Style,
pub fields: Vec<Field<'a>>, pub fields: Vec<Field<'a>>,
pub original: &'a syn::Variant,
} }
/// A field of a struct. /// A field of a struct.
@@ -65,7 +60,11 @@ pub enum Style {
impl<'a> Container<'a> { impl<'a> Container<'a> {
/// Convert the raw Syn ast into a parsed container object, collecting errors in `cx`. /// 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) -> Container<'a> { 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 attrs = attr::Container::from_ast(cx, item);
let mut data = match item.data { let mut data = match item.data {
@@ -77,27 +76,34 @@ impl<'a> Container<'a> {
Data::Struct(style, fields) Data::Struct(style, fields)
} }
syn::Data::Union(_) => { 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; let mut has_flatten = false;
match data { match data {
Data::Enum(ref mut variants) => for variant in variants { Data::Enum(ref mut variants) => {
variant.attrs.rename_by_rule(attrs.rename_all()); for variant in variants {
for field in &mut variant.fields { variant.attrs.rename_by_rules(attrs.rename_all_rules());
for field in &mut variant.fields {
if field.attrs.flatten() {
has_flatten = true;
}
field
.attrs
.rename_by_rules(variant.attrs.rename_all_rules());
}
}
}
Data::Struct(_, ref mut fields) => {
for field in fields {
if field.attrs.flatten() { if field.attrs.flatten() {
has_flatten = true; has_flatten = true;
} }
field.attrs.rename_by_rule(variant.attrs.rename_all()); field.attrs.rename_by_rules(attrs.rename_all_rules());
} }
}, }
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 { if has_flatten {
@@ -109,9 +115,10 @@ impl<'a> Container<'a> {
attrs: attrs, attrs: attrs,
data: data, data: data,
generics: &item.generics, generics: &item.generics,
original: item,
}; };
check::check(cx, &mut item, derive); check::check(cx, &mut item, derive);
item Some(item)
} }
} }
@@ -146,8 +153,10 @@ fn enum_from_ast<'a>(
attrs: attrs, attrs: attrs,
style: style, style: style,
fields: fields, fields: fields,
original: variant,
} }
}).collect() })
.collect()
} }
fn struct_from_ast<'a>( fn struct_from_ast<'a>(
@@ -190,5 +199,6 @@ fn fields_from_ast<'a>(
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default), attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
ty: &field.ty, ty: &field.ty,
original: field, original: field,
}).collect() })
.collect()
} }
File diff suppressed because it is too large Load Diff
+1 -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.
//! Code to convert the Rust-styled field/variant (e.g. `my_field`, `MyType`) to the //! 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`). //! case of the source (e.g. `my-field`, `MY_FIELD`).
@@ -18,7 +10,7 @@ use std::str::FromStr;
use self::RenameRule::*; use self::RenameRule::*;
/// The different possible ways to change case of fields in a struct, or variants in an enum. /// The different possible ways to change case of fields in a struct, or variants in an enum.
#[derive(PartialEq)] #[derive(Copy, Clone, PartialEq)]
pub enum RenameRule { pub enum RenameRule {
/// Don't apply a default rename rule. /// Don't apply a default rename rule.
None, None,
+142 -72
View File
@@ -1,13 +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.
use internals::ast::{Container, Data, Field, Style}; use internals::ast::{Container, Data, Field, Style};
use internals::attr::{EnumTag, Identifier}; use internals::attr::{Identifier, TagType};
use internals::{Ctxt, Derive}; use internals::{Ctxt, Derive};
use syn::{Member, Type}; use syn::{Member, Type};
@@ -29,12 +21,16 @@ fn check_getter(cx: &Ctxt, cont: &Container) {
match cont.data { match cont.data {
Data::Enum(_) => { Data::Enum(_) => {
if cont.data.has_getter() { 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(_, _) => { Data::Struct(_, _) => {
if cont.data.has_getter() && cont.attrs.remote().is_none() { 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 \ "#[serde(getter = \"...\")] can only be used in structs \
that have #[serde(remote = \"...\")]", that have #[serde(remote = \"...\")]",
); );
@@ -67,26 +63,35 @@ fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
} }
match style { match style {
Style::Tuple => { 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 => { 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() { if field.attrs.skip_serializing() {
cx.error( cx.error_spanned_by(
"#[serde(flatten] can not be combined with \ field.original,
"#[serde(flatten)] can not be combined with \
#[serde(skip_serializing)]", #[serde(skip_serializing)]",
); );
} else if field.attrs.skip_serializing_if().is_some() { } else if field.attrs.skip_serializing_if().is_some() {
cx.error( cx.error_spanned_by(
"#[serde(flatten] can not be combined with \ field.original,
"#[serde(flatten)] can not be combined with \
#[serde(skip_serializing_if = \"...\")]", #[serde(skip_serializing_if = \"...\")]",
); );
} else if field.attrs.skip_deserializing() { } else if field.attrs.skip_deserializing() {
cx.error( cx.error_spanned_by(
"#[serde(flatten] can not be combined with \ field.original,
"#[serde(flatten)] can not be combined with \
#[serde(skip_deserializing)]", #[serde(skip_deserializing)]",
); );
} }
@@ -115,24 +120,36 @@ fn check_identifier(cx: &Ctxt, cont: &Container) {
) { ) {
// The `other` attribute may not be used in a variant_identifier. // The `other` attribute may not be used in a variant_identifier.
(_, Identifier::Variant, true, _) => { (_, Identifier::Variant, true, _) => {
cx.error("#[serde(other)] may not be used on a variant_identifier"); 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 // Variant with `other` attribute cannot appear in untagged enum
(_, Identifier::No, true, &EnumTag::None) => { (_, Identifier::No, true, &TagType::None) => {
cx.error("#[serde(other)] cannot appear on untagged enum"); cx.error_spanned_by(
variant.original,
"#[serde(other)] cannot appear on untagged enum",
);
} }
// Variant with `other` attribute must be the last one. // Variant with `other` attribute must be the last one.
(Style::Unit, Identifier::Field, true, _) | (Style::Unit, Identifier::No, true, _) => { (Style::Unit, Identifier::Field, true, _) | (Style::Unit, Identifier::No, true, _) => {
if i < variants.len() - 1 { 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. // Variant with `other` attribute must be a unit variant.
(_, Identifier::Field, true, _) | (_, Identifier::No, true, _) => { (_, Identifier::Field, true, _) | (_, Identifier::No, true, _) => {
cx.error("#[serde(other)] must be on a unit variant"); 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. // Any sort of variant is allowed if this is not an identifier.
@@ -144,16 +161,25 @@ fn check_identifier(cx: &Ctxt, cont: &Container) {
// The last field is allowed to be a newtype catch-all. // 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 { 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, _) => { (_, Identifier::Field, false, _) => {
cx.error("field_identifier may only contain unit variants"); cx.error_spanned_by(
variant.original,
"#[serde(field_identifier)] may only contain unit variants",
);
} }
(_, Identifier::Variant, false, _) => { (_, Identifier::Variant, false, _) => {
cx.error("variant_identifier may only contain unit variants"); cx.error_spanned_by(
variant.original,
"#[serde(variant_identifier)] may only contain unit variants",
);
} }
} }
} }
@@ -172,52 +198,67 @@ fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
for variant in variants.iter() { for variant in variants.iter() {
if variant.attrs.serialize_with().is_some() { if variant.attrs.serialize_with().is_some() {
if variant.attrs.skip_serializing() { if variant.attrs.skip_serializing() {
cx.error(format!( cx.error_spanned_by(
"variant `{}` cannot have both #[serde(serialize_with)] and \ variant.original,
#[serde(skip_serializing)]", format!(
variant.ident "variant `{}` cannot have both #[serde(serialize_with)] and \
)); #[serde(skip_serializing)]",
variant.ident
),
);
} }
for field in &variant.fields { for field in &variant.fields {
let member = member_message(&field.member); let member = member_message(&field.member);
if field.attrs.skip_serializing() { if field.attrs.skip_serializing() {
cx.error(format!( cx.error_spanned_by(
"variant `{}` cannot have both #[serde(serialize_with)] and \ variant.original,
a field {} marked with #[serde(skip_serializing)]", format!(
variant.ident, member "variant `{}` cannot have both #[serde(serialize_with)] and \
)); a field {} marked with #[serde(skip_serializing)]",
variant.ident, member
),
);
} }
if field.attrs.skip_serializing_if().is_some() { if field.attrs.skip_serializing_if().is_some() {
cx.error(format!( cx.error_spanned_by(
"variant `{}` cannot have both #[serde(serialize_with)] and \ variant.original,
a field {} marked with #[serde(skip_serializing_if)]", format!(
variant.ident, member "variant `{}` cannot have both #[serde(serialize_with)] and \
)); a field {} marked with #[serde(skip_serializing_if)]",
variant.ident, member
),
);
} }
} }
} }
if variant.attrs.deserialize_with().is_some() { if variant.attrs.deserialize_with().is_some() {
if variant.attrs.skip_deserializing() { if variant.attrs.skip_deserializing() {
cx.error(format!( cx.error_spanned_by(
"variant `{}` cannot have both #[serde(deserialize_with)] and \ variant.original,
#[serde(skip_deserializing)]", format!(
variant.ident "variant `{}` cannot have both #[serde(deserialize_with)] and \
)); #[serde(skip_deserializing)]",
variant.ident
),
);
} }
for field in &variant.fields { for field in &variant.fields {
if field.attrs.skip_deserializing() { if field.attrs.skip_deserializing() {
let member = member_message(&field.member); let member = member_message(&field.member);
cx.error(format!( cx.error_spanned_by(
"variant `{}` cannot have both #[serde(deserialize_with)] \ variant.original,
and a field {} marked with #[serde(skip_deserializing)]", format!(
variant.ident, member "variant `{}` cannot have both #[serde(deserialize_with)] \
)); and a field {} marked with #[serde(skip_deserializing)]",
variant.ident, member
),
);
} }
} }
} }
@@ -235,13 +276,15 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
}; };
let tag = match *cont.attrs.tag() { let tag = match *cont.attrs.tag() {
EnumTag::Internal { ref tag } => tag.as_str(), TagType::Internal { ref tag } => tag.as_str(),
EnumTag::External | EnumTag::Adjacent { .. } | EnumTag::None => return, TagType::External | TagType::Adjacent { .. } | TagType::None => return,
}; };
let diagnose_conflict = || { let diagnose_conflict = || {
let message = format!("variant field name `{}` conflicts with internal tag", tag); cx.error_spanned_by(
cx.error(message); cont.original,
format!("variant field name `{}` conflicts with internal tag", tag),
)
}; };
for variant in variants { for variant in variants {
@@ -252,12 +295,18 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
let check_de = !field.attrs.skip_deserializing(); let check_de = !field.attrs.skip_deserializing();
let name = field.attrs.name(); let name = field.attrs.name();
let ser_name = name.serialize_name(); let ser_name = name.serialize_name();
let de_name = name.deserialize_name();
if check_ser && ser_name == tag || check_de && de_name == tag { if check_ser && ser_name == tag {
diagnose_conflict(); diagnose_conflict();
return; return;
} }
for de_name in field.attrs.aliases() {
if check_de && de_name == tag {
diagnose_conflict();
return;
}
}
} }
} }
Style::Unit | Style::Newtype | Style::Tuple => {} Style::Unit | Style::Newtype | Style::Tuple => {}
@@ -269,19 +318,21 @@ fn check_internal_tag_field_name_conflict(cx: &Ctxt, cont: &Container) {
/// contents tag must differ, for the same reason. /// contents tag must differ, for the same reason.
fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) { fn check_adjacent_tag_conflict(cx: &Ctxt, cont: &Container) {
let (type_tag, content_tag) = match *cont.attrs.tag() { let (type_tag, content_tag) = match *cont.attrs.tag() {
EnumTag::Adjacent { TagType::Adjacent {
ref tag, ref tag,
ref content, ref content,
} => (tag, content), } => (tag, content),
EnumTag::Internal { .. } | EnumTag::External | EnumTag::None => return, TagType::Internal { .. } | TagType::External | TagType::None => return,
}; };
if type_tag == content_tag { if type_tag == content_tag {
let message = format!( cx.error_spanned_by(
"enum tags `{}` for type and content conflict with each other", cont.original,
type_tag format!(
"enum tags `{}` for type and content conflict with each other",
type_tag
),
); );
cx.error(message);
} }
} }
@@ -292,20 +343,32 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
} }
if cont.attrs.type_from().is_some() { 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() { 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 { let fields = match cont.data {
Data::Enum(_) => { 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; return;
} }
Data::Struct(Style::Unit, _) => { 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; return;
} }
Data::Struct(_, ref mut fields) => fields, Data::Struct(_, ref mut fields) => fields,
@@ -316,7 +379,8 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
for field in fields { for field in fields {
if allow_transparent(field, derive) { if allow_transparent(field, derive) {
if transparent_field.is_some() { if transparent_field.is_some() {
cx.error( cx.error_spanned_by(
cont.original,
"#[serde(transparent)] requires struct to have at most one transparent field", "#[serde(transparent)] requires struct to have at most one transparent field",
); );
return; return;
@@ -329,10 +393,16 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
Some(transparent_field) => transparent_field.attrs.mark_transparent(), Some(transparent_field) => transparent_field.attrs.mark_transparent(),
None => match derive { None => match derive {
Derive::Serialize => { 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 => { 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",
);
} }
}, },
} }
@@ -341,7 +411,7 @@ fn check_transparent(cx: &Ctxt, cont: &mut Container, derive: Derive) {
fn member_message(member: &Member) -> String { fn member_message(member: &Member) -> String {
match *member { match *member {
Member::Named(ref ident) => format!("`{}`", ident), Member::Named(ref ident) => format!("`{}`", ident),
Member::Unnamed(ref i) => i.index.to_string(), Member::Unnamed(ref i) => format!("#{}", i.index),
} }
} }
+12 -23
View File
@@ -1,14 +1,8 @@
// Copyright 2017 Serde Developers use quote::ToTokens;
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::cell::RefCell; use std::cell::RefCell;
use std::fmt::Display; use std::fmt::Display;
use std::thread; use std::thread;
use syn;
/// A type to collect errors together and format them. /// A type to collect errors together and format them.
/// ///
@@ -19,7 +13,7 @@ use std::thread;
pub struct Ctxt { pub struct Ctxt {
// The contents will be set to `None` during checking. This is so that checking can be // The contents will be set to `None` during checking. This is so that checking can be
// enforced. // enforced.
errors: RefCell<Option<Vec<String>>>, errors: RefCell<Option<Vec<syn::Error>>>,
} }
impl Ctxt { impl Ctxt {
@@ -32,29 +26,24 @@ impl Ctxt {
} }
} }
/// Add an error to the context object. /// Add an error to the context object with a tokenenizable object.
pub fn error<T: Display>(&self, msg: T) { ///
/// 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 self.errors
.borrow_mut() .borrow_mut()
.as_mut() .as_mut()
.unwrap() .unwrap()
.push(msg.to_string()); // Curb monomorphization from generating too many identical methods.
.push(syn::Error::new_spanned(obj.into_token_stream(), msg));
} }
/// Consume this object, producing a formatted error string if there are errors. /// Consume this object, producing a formatted error string if there are errors.
pub fn check(self) -> Result<(), String> { pub fn check(self) -> Result<(), Vec<syn::Error>> {
let mut errors = self.errors.borrow_mut().take().unwrap(); let errors = self.errors.borrow_mut().take().unwrap();
match errors.len() { match errors.len() {
0 => Ok(()), 0 => Ok(()),
1 => Err(errors.pop().unwrap()), _ => Err(errors),
n => {
let mut msg = format!("{} errors:", n);
for err in errors {
msg.push_str("\n\t# ");
msg.push_str(&err);
}
Err(msg)
}
} }
} }
} }
-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 ast;
pub mod attr; pub mod attr;
+13 -21
View File
@@ -1,16 +1,7 @@
// 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. //! This crate provides Serde's two derive macros.
//! //!
//! ```rust //! ```edition2018
//! # #[macro_use] //! # use serde_derive::{Serialize, Deserialize};
//! # extern crate serde_derive;
//! # //! #
//! #[derive(Serialize, Deserialize)] //! #[derive(Serialize, Deserialize)]
//! # struct S; //! # struct S;
@@ -22,10 +13,10 @@
//! //!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html //! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.80")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.85")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints // Ignored clippy lints
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
allow( allow(
@@ -34,10 +25,11 @@
needless_pass_by_value, needless_pass_by_value,
redundant_field_names, redundant_field_names,
too_many_arguments, too_many_arguments,
trivially_copy_pass_by_ref,
used_underscore_binding, used_underscore_binding,
) )
)] )]
// Whitelisted clippy_pedantic lints // Ignored clippy_pedantic lints
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
allow( allow(
@@ -48,9 +40,9 @@
indexing_slicing, indexing_slicing,
items_after_statements, items_after_statements,
match_same_arms, match_same_arms,
module_name_repetitions,
similar_names, similar_names,
single_match_else, single_match_else,
stutter,
unseparated_literal_suffix, unseparated_literal_suffix,
use_self, use_self,
) )
@@ -77,6 +69,7 @@ mod bound;
mod fragment; mod fragment;
mod de; mod de;
mod dummy;
mod pretend; mod pretend;
mod ser; mod ser;
mod try; mod try;
@@ -85,7 +78,7 @@ mod try;
pub fn derive_serialize(input: TokenStream) -> TokenStream { pub fn derive_serialize(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);
ser::expand_derive_serialize(&input) ser::expand_derive_serialize(&input)
.unwrap_or_else(compile_error) .unwrap_or_else(to_compile_errors)
.into() .into()
} }
@@ -93,12 +86,11 @@ pub fn derive_serialize(input: TokenStream) -> TokenStream {
pub fn derive_deserialize(input: TokenStream) -> TokenStream { pub fn derive_deserialize(input: TokenStream) -> TokenStream {
let input = parse_macro_input!(input as DeriveInput); let input = parse_macro_input!(input as DeriveInput);
de::expand_derive_deserialize(&input) de::expand_derive_deserialize(&input)
.unwrap_or_else(compile_error) .unwrap_or_else(to_compile_errors)
.into() .into()
} }
fn compile_error(message: String) -> proc_macro2::TokenStream { fn to_compile_errors(errors: Vec<syn::Error>) -> proc_macro2::TokenStream {
quote! { let compile_errors = errors.iter().map(syn::Error::to_compile_error);
compile_error!(#message); quote!(#(#compile_errors)*)
}
} }
+2 -1
View File
@@ -62,7 +62,8 @@ fn pretend_fields_used(cont: &Container) -> TokenStream {
Some(quote!(#type_ident::#variant_ident #pat)) Some(quote!(#type_ident::#variant_ident #pat))
} }
_ => None, _ => None,
}).collect::<Vec<_>>(), })
.collect::<Vec<_>>(),
Data::Struct(Style::Struct, ref fields) => { Data::Struct(Style::Struct, ref fields) => {
let pat = struct_pattern(fields); let pat = struct_pattern(fields);
vec![quote!(#type_ident #pat)] vec![quote!(#type_ident #pat)]
+67 -51
View File
@@ -1,36 +1,26 @@
// 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 proc_macro2::{Span, TokenStream};
use syn::spanned::Spanned; use syn::spanned::Spanned;
use syn::{self, Ident, Index, Member}; use syn::{self, Ident, Index, Member};
use bound; use bound;
use dummy;
use fragment::{Fragment, Match, Stmts}; use fragment::{Fragment, Match, Stmts};
use internals::ast::{Container, Data, Field, Style, Variant}; use internals::ast::{Container, Data, Field, Style, Variant};
use internals::{attr, Ctxt, Derive}; use internals::{attr, Ctxt, Derive};
use pretend; 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 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); precondition(&ctxt, &cont);
try!(ctxt.check()); try!(ctxt.check());
let ident = &cont.ident; let ident = &cont.ident;
let params = Parameters::new(&cont); let params = Parameters::new(&cont);
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl(); let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
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 body = Stmts(serialize_body(&cont, &params));
let impl_block = if let Some(remote) = cont.attrs.remote() { let impl_block = if let Some(remote) = cont.attrs.remote() {
@@ -61,29 +51,17 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
} }
}; };
let try_replacement = try::replacement(); Ok(dummy::wrap_in_const("SERIALIZE", ident, impl_block))
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
};
};
Ok(generated)
} }
fn precondition(cx: &Ctxt, cont: &Container) { fn precondition(cx: &Ctxt, cont: &Container) {
match cont.attrs.identifier() { match cont.attrs.identifier() {
attr::Identifier::No => {} attr::Identifier::No => {}
attr::Identifier::Field => { attr::Identifier::Field => {
cx.error("field identifiers cannot be serialized"); cx.error_spanned_by(cont.original, "field identifiers cannot be serialized");
} }
attr::Identifier::Variant => { attr::Identifier::Variant => {
cx.error("variant identifiers cannot be serialized"); cx.error_spanned_by(cont.original, "variant identifiers cannot be serialized");
} }
} }
} }
@@ -208,7 +186,10 @@ fn serialize_transparent(cont: &Container, params: &Parameters) -> Fragment {
let path = match transparent_field.attrs.serialize_with() { let path = match transparent_field.attrs.serialize_with() {
Some(path) => quote!(#path), Some(path) => quote!(#path),
None => quote!(_serde::Serialize::serialize), None => {
let span = transparent_field.original.span();
quote_spanned!(span=> _serde::Serialize::serialize)
}
}; };
quote_block! { quote_block! {
@@ -288,7 +269,8 @@ fn serialize_tuple_struct(
let field_expr = get_member(params, field, &Member::Unnamed(index)); let field_expr = get_member(params, field, &Member::Unnamed(index));
quote!(if #path(#field_expr) { 0 } else { 1 }) quote!(if #path(#field_expr) { 0 } else { 1 })
} }
}).fold(quote!(0), |sum, expr| quote!(#sum + #expr)); })
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
quote_block! { quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len)); let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len));
@@ -312,17 +294,32 @@ fn serialize_struct_as_struct(
fields: &[Field], fields: &[Field],
cattrs: &attr::Container, cattrs: &attr::Container,
) -> Fragment { ) -> Fragment {
let serialize_fields = let mut serialize_fields =
serialize_struct_visitor(fields, params, false, &StructTrait::SerializeStruct); serialize_struct_visitor(fields, params, false, &StructTrait::SerializeStruct);
let type_name = cattrs.name().serialize_name(); let type_name = cattrs.name().serialize_name();
let additional_field_count: usize = match *cattrs.tag() {
attr::TagType::Internal { ref tag } => {
let func = StructTrait::SerializeStruct.serialize_field(Span::call_site());
serialize_fields.insert(
0,
quote! {
try!(#func(&mut __serde_state, #tag, #type_name));
},
);
1
}
_ => 0,
};
let mut serialized_fields = fields let mut serialized_fields = fields
.iter() .iter()
.filter(|&field| !field.attrs.skip_serializing()) .filter(|&field| !field.attrs.skip_serializing())
.peekable(); .peekable();
let let_mut = mut_if(serialized_fields.peek().is_some()); let let_mut = mut_if(serialized_fields.peek().is_some() || additional_field_count > 0);
let len = serialized_fields let len = serialized_fields
.map(|field| match field.attrs.skip_serializing_if() { .map(|field| match field.attrs.skip_serializing_if() {
@@ -331,7 +328,11 @@ fn serialize_struct_as_struct(
let field_expr = get_member(params, field, &field.member); let field_expr = get_member(params, field, &field.member);
quote!(if #path(#field_expr) { 0 } else { 1 }) quote!(if #path(#field_expr) { 0 } else { 1 })
} }
}).fold(quote!(0), |sum, expr| quote!(#sum + #expr)); })
.fold(
quote!(#additional_field_count),
|sum, expr| quote!(#sum + #expr),
);
quote_block! { quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len)); let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len));
@@ -365,7 +366,8 @@ fn serialize_struct_as_map(
let field_expr = get_member(params, field, &field.member); let field_expr = get_member(params, field, &field.member);
quote!(if #path(#field_expr) { 0 } else { 1 }) quote!(if #path(#field_expr) { 0 } else { 1 })
} }
}).fold(quote!(0), |sum, expr| quote!(#sum + #expr)); })
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
quote!(_serde::export::Some(#len)) quote!(_serde::export::Some(#len))
}; };
@@ -386,7 +388,8 @@ fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Cont
.enumerate() .enumerate()
.map(|(variant_index, variant)| { .map(|(variant_index, variant)| {
serialize_variant(params, variant, variant_index as u32, cattrs) serialize_variant(params, variant, variant_index as u32, cattrs)
}).collect(); })
.collect();
quote_expr! { quote_expr! {
match *#self_var { match *#self_var {
@@ -450,17 +453,17 @@ fn serialize_variant(
}; };
let body = Match(match *cattrs.tag() { let body = Match(match *cattrs.tag() {
attr::EnumTag::External => { attr::TagType::External => {
serialize_externally_tagged_variant(params, variant, variant_index, cattrs) serialize_externally_tagged_variant(params, variant, variant_index, cattrs)
} }
attr::EnumTag::Internal { ref tag } => { attr::TagType::Internal { ref tag } => {
serialize_internally_tagged_variant(params, variant, cattrs, tag) serialize_internally_tagged_variant(params, variant, cattrs, tag)
} }
attr::EnumTag::Adjacent { attr::TagType::Adjacent {
ref tag, ref tag,
ref content, ref content,
} => serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content), } => serialize_adjacently_tagged_variant(params, variant, cattrs, tag, content),
attr::EnumTag::None => serialize_untagged_variant(params, variant, cattrs), attr::TagType::None => serialize_untagged_variant(params, variant, cattrs),
}); });
quote! { quote! {
@@ -509,8 +512,10 @@ fn serialize_externally_tagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); 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! { quote_expr! {
_serde::Serializer::serialize_newtype_variant( #func(
__serializer, __serializer,
#type_name, #type_name,
#variant_index, #variant_index,
@@ -583,8 +588,10 @@ fn serialize_internally_tagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); 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! { quote_expr! {
_serde::private::ser::serialize_tagged_newtype( #func(
__serializer, __serializer,
#enum_ident_str, #enum_ident_str,
#variant_ident_str, #variant_ident_str,
@@ -641,12 +648,14 @@ fn serialize_adjacently_tagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); 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! { return quote_block! {
let mut __struct = try!(_serde::Serializer::serialize_struct( let mut __struct = try!(_serde::Serializer::serialize_struct(
__serializer, #type_name, 2)); __serializer, #type_name, 2));
try!(_serde::ser::SerializeStruct::serialize_field( try!(_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name)); &mut __struct, #tag, #variant_name));
try!(_serde::ser::SerializeStruct::serialize_field( try!(#func(
&mut __struct, #content, #field_expr)); &mut __struct, #content, #field_expr));
_serde::ser::SerializeStruct::end(__struct) _serde::ser::SerializeStruct::end(__struct)
}; };
@@ -742,8 +751,10 @@ fn serialize_untagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr); 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! { quote_expr! {
_serde::Serialize::serialize(#field_expr, __serializer) #func(#field_expr, __serializer)
} }
} }
Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields), Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
@@ -790,7 +801,8 @@ fn serialize_tuple_variant(
let field_expr = Ident::new(&format!("__field{}", i), Span::call_site()); let field_expr = Ident::new(&format!("__field{}", i), Span::call_site());
quote!(if #path(#field_expr) { 0 } else { 1 }) quote!(if #path(#field_expr) { 0 } else { 1 })
} }
}).fold(quote!(0), |sum, expr| quote!(#sum + #expr)); })
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
match context { match context {
TupleVariant::ExternallyTagged { TupleVariant::ExternallyTagged {
@@ -867,7 +879,8 @@ fn serialize_struct_variant<'a>(
Some(path) => quote!(if #path(#member) { 0 } else { 1 }), Some(path) => quote!(if #path(#member) { 0 } else { 1 }),
None => quote!(1), None => quote!(1),
} }
}).fold(quote!(0), |sum, expr| quote!(#sum + #expr)); })
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
match context { match context {
StructVariant::ExternallyTagged { StructVariant::ExternallyTagged {
@@ -1046,7 +1059,8 @@ fn serialize_tuple_struct_visitor(
None => ser, None => ser,
Some(skip) => quote!(if !#skip { #ser }), Some(skip) => quote!(if !#skip { #ser }),
} }
}).collect() })
.collect()
} }
fn serialize_struct_visitor( fn serialize_struct_visitor(
@@ -1080,8 +1094,9 @@ fn serialize_struct_visitor(
let span = field.original.span(); let span = field.original.span();
let ser = if field.attrs.flatten() { let ser = if field.attrs.flatten() {
let func = quote_spanned!(span=> _serde::Serialize::serialize);
quote! { 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 { } else {
let func = struct_trait.serialize_field(span); let func = struct_trait.serialize_field(span);
@@ -1140,7 +1155,8 @@ fn wrap_serialize_variant_with(
} }
}; };
quote!(#id) quote!(#id)
}).collect(); })
.collect();
wrap_serialize_with( wrap_serialize_with(
params, params,
serialize_with, serialize_with,
+5 -5
View File
@@ -1,22 +1,22 @@
[package] [package]
name = "serde_derive_internals" 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>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "AST representation used by Serde derive macros. Unstable." description = "AST representation used by Serde derive macros. Unstable."
homepage = "https://serde.rs" homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde" 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"] keywords = ["serde", "serialization"]
readme = "crates-io.md" include = ["Cargo.toml", "lib.rs", "src/**/*.rs", "LICENSE-APACHE", "LICENSE-MIT"]
include = ["Cargo.toml", "lib.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[lib] [lib]
path = "lib.rs" path = "lib.rs"
[dependencies] [dependencies]
proc-macro2 = "0.4" proc-macro2 = "0.4"
syn = { version = "0.15", default-features = false, features = ["derive", "parsing", "clone-impls"] } quote = "0.6.3"
syn = { version = "0.15", default-features = false, features = ["derive", "parsing", "printing", "clone-impls"] }
[badges] [badges]
travis-ci = { repository = "serde-rs/serde" } travis-ci = { repository = "serde-rs/serde" }
-1
View File
@@ -1 +0,0 @@
../README.md
-1
View File
@@ -1 +0,0 @@
../crates-io.md
+4 -12
View File
@@ -1,20 +1,11 @@
// Copyright 2017 Serde Developers #![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.24.1")]
//
// 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")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
allow( allow(
cyclomatic_complexity, cyclomatic_complexity,
doc_markdown, redundant_field_names,
match_same_arms, trivially_copy_pass_by_ref
redundant_field_names
) )
)] )]
@@ -22,6 +13,7 @@
extern crate syn; extern crate syn;
extern crate proc_macro2; extern crate proc_macro2;
extern crate quote;
#[path = "src/mod.rs"] #[path = "src/mod.rs"]
mod internals; mod internals;
+2 -2
View File
@@ -1,6 +1,6 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "1.0.80" # remember to update html_root_url version = "1.0.85" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0" license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations" description = "Token De/Serializer for testing De/Serialize implementations"
@@ -15,7 +15,7 @@ include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-AP
serde = { version = "1.0.60", path = "../serde" } serde = { version = "1.0.60", path = "../serde" }
[dev-dependencies] [dev-dependencies]
serde = { version = "1.0", path = "../serde", features = ["rc"] } serde = { version = "1.0", path = "../serde" }
serde_derive = { version = "1.0", path = "../serde_derive" } serde_derive = { version = "1.0", path = "../serde_derive" }
[badges] [badges]
+28 -60
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 serde::{Deserialize, Serialize};
use de::Deserializer; use de::Deserializer;
@@ -16,13 +8,8 @@ use std::fmt::Debug;
/// Runs both `assert_ser_tokens` and `assert_de_tokens`. /// Runs both `assert_ser_tokens` and `assert_de_tokens`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -53,13 +40,8 @@ where
/// Asserts that `value` serializes to the given `tokens`. /// Asserts that `value` serializes to the given `tokens`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_ser_tokens, Token}; /// # use serde_test::{assert_ser_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -98,16 +80,11 @@ where
/// Asserts that `value` serializes to the given `tokens`, and then yields /// Asserts that `value` serializes to the given `tokens`, and then yields
/// `error`. /// `error`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde_test;
/// #
/// # fn main() {
/// use std::sync::{Arc, Mutex}; /// use std::sync::{Arc, Mutex};
/// use std::thread; /// use std::thread;
/// ///
/// use serde::Serialize;
/// use serde_test::{assert_ser_tokens_error, Token}; /// use serde_test::{assert_ser_tokens_error, Token};
/// ///
/// #[derive(Serialize)] /// #[derive(Serialize)]
@@ -115,26 +92,27 @@ where
/// lock: Arc<Mutex<u32>>, /// lock: Arc<Mutex<u32>>,
/// } /// }
/// ///
/// let example = Example { lock: Arc::new(Mutex::new(0)) }; /// fn main() {
/// let lock = example.lock.clone(); /// let example = Example { lock: Arc::new(Mutex::new(0)) };
/// let lock = example.lock.clone();
/// ///
/// let _ = thread::spawn(move || { /// let _ = thread::spawn(move || {
/// // This thread will acquire the mutex first, unwrapping the result /// // This thread will acquire the mutex first, unwrapping the result
/// // of `lock` because the lock has not been poisoned. /// // of `lock` because the lock has not been poisoned.
/// let _guard = lock.lock().unwrap(); /// let _guard = lock.lock().unwrap();
/// ///
/// // This panic while holding the lock (`_guard` is in scope) will /// // This panic while holding the lock (`_guard` is in scope) will
/// // poison the mutex. /// // poison the mutex.
/// panic!() /// panic!()
/// }).join(); /// }).join();
/// ///
/// let expected = &[ /// let expected = &[
/// Token::Struct { name: "Example", len: 1 }, /// Token::Struct { name: "Example", len: 1 },
/// Token::Str("lock"), /// Token::Str("lock"),
/// ]; /// ];
/// let error = "lock poison error while serializing"; /// let error = "lock poison error while serializing";
/// assert_ser_tokens_error(&example, expected, error); /// assert_ser_tokens_error(&example, expected, error);
/// # } /// }
/// ``` /// ```
pub fn assert_ser_tokens_error<T>(value: &T, tokens: &[Token], error: &str) pub fn assert_ser_tokens_error<T>(value: &T, tokens: &[Token], error: &str)
where where
@@ -153,13 +131,8 @@ where
/// Asserts that the given `tokens` deserialize into `value`. /// Asserts that the given `tokens` deserialize into `value`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_de_tokens, Token}; /// # use serde_test::{assert_de_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -213,13 +186,8 @@ where
/// Asserts that the given `tokens` yield `error` when deserializing. /// Asserts that the given `tokens` yield `error` when deserializing.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_de_tokens_error, Token}; /// # use serde_test::{assert_de_tokens_error, Token};
/// # /// #
/// # fn main() { /// # fn main() {
+2 -5
View File
@@ -14,10 +14,7 @@ pub struct Compact<T: ?Sized>(T);
/// Trait to determine whether a value is represented in human-readable or /// Trait to determine whether a value is represented in human-readable or
/// compact form. /// compact form.
/// ///
/// ``` /// ```edition2018
/// extern crate serde;
/// extern crate serde_test;
///
/// use serde::{Deserialize, Deserializer, Serialize, Serializer}; /// use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// use serde_test::{assert_tokens, Configure, Token}; /// use serde_test::{assert_tokens, Configure, Token};
/// ///
@@ -200,7 +197,7 @@ macro_rules! impl_serializer {
$is_human_readable $is_human_readable
} }
forward_serialize_methods!{ forward_serialize_methods! {
serialize_bool bool, serialize_bool bool,
serialize_i8 i8, serialize_i8 i8,
serialize_i16 i16, serialize_i16 i16,
-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 serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer}; use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer};
use serde::de::{ use serde::de::{
self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess, self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess, SeqAccess,
-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::error;
use std::fmt::{self, Display}; use std::fmt::{self, Display};
+7 -24
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 //! This crate provides a convenient concise way to write unit tests for
//! implementations of [`Serialize`] and [`Deserialize`]. //! implementations of [`Serialize`] and [`Deserialize`].
//! //!
@@ -32,19 +24,10 @@
//! //!
//! [`linked-hash-map`]: https://github.com/contain-rs/linked-hash-map //! [`linked-hash-map`]: https://github.com/contain-rs/linked-hash-map
//! //!
//! ```rust //! ```edition2018
//! # extern crate serde; //! # const IGNORE: &str = stringify! {
//! #
//! # macro_rules! ignore {
//! # ($($tt:tt)+) => {}
//! # }
//! #
//! # ignore! {
//! extern crate linked_hash_map;
//! use linked_hash_map::LinkedHashMap; //! use linked_hash_map::LinkedHashMap;
//! # } //! # };
//!
//! extern crate serde_test;
//! use serde_test::{Token, assert_tokens}; //! use serde_test::{Token, assert_tokens};
//! //!
//! # use std::fmt; //! # use std::fmt;
@@ -161,19 +144,19 @@
//! # } //! # }
//! ``` //! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.80")] #![doc(html_root_url = "https://docs.rs/serde_test/1.0.85")]
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))] #![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))] #![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints // Ignored clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))] #![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
// Whitelisted clippy_pedantic lints // Ignored clippy_pedantic lints
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
allow( allow(
empty_line_after_outer_attr, empty_line_after_outer_attr,
missing_docs_in_private_items, missing_docs_in_private_items,
module_name_repetitions,
redundant_field_names, redundant_field_names,
stutter,
use_debug, use_debug,
use_self use_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 serde::{ser, Serialize}; use serde::{ser, Serialize};
use error::Error; use error::Error;
+39 -92
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 std::fmt::{self, Debug, Display}; use std::fmt::{self, Debug, Display};
#[derive(Copy, Clone, PartialEq, Debug)] #[derive(Copy, Clone, PartialEq, Debug)]
pub enum Token { pub enum Token {
/// A serialized `bool`. /// A serialized `bool`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&true, &[Token::Bool(true)]); /// assert_tokens(&true, &[Token::Bool(true)]);
@@ -21,7 +13,7 @@ pub enum Token {
/// A serialized `i8`. /// A serialized `i8`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&0i8, &[Token::I8(0)]); /// assert_tokens(&0i8, &[Token::I8(0)]);
@@ -30,7 +22,7 @@ pub enum Token {
/// A serialized `i16`. /// A serialized `i16`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&0i16, &[Token::I16(0)]); /// assert_tokens(&0i16, &[Token::I16(0)]);
@@ -39,7 +31,7 @@ pub enum Token {
/// A serialized `i32`. /// A serialized `i32`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&0i32, &[Token::I32(0)]); /// assert_tokens(&0i32, &[Token::I32(0)]);
@@ -48,7 +40,7 @@ pub enum Token {
/// A serialized `i64`. /// A serialized `i64`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&0i64, &[Token::I64(0)]); /// assert_tokens(&0i64, &[Token::I64(0)]);
@@ -57,7 +49,7 @@ pub enum Token {
/// A serialized `u8`. /// A serialized `u8`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&0u8, &[Token::U8(0)]); /// assert_tokens(&0u8, &[Token::U8(0)]);
@@ -66,7 +58,7 @@ pub enum Token {
/// A serialized `u16`. /// A serialized `u16`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&0u16, &[Token::U16(0)]); /// assert_tokens(&0u16, &[Token::U16(0)]);
@@ -75,7 +67,7 @@ pub enum Token {
/// A serialized `u32`. /// A serialized `u32`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&0u32, &[Token::U32(0)]); /// assert_tokens(&0u32, &[Token::U32(0)]);
@@ -84,7 +76,7 @@ pub enum Token {
/// A serialized `u64`. /// A serialized `u64`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&0u64, &[Token::U64(0)]); /// assert_tokens(&0u64, &[Token::U64(0)]);
@@ -93,7 +85,7 @@ pub enum Token {
/// A serialized `f32`. /// A serialized `f32`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&0f32, &[Token::F32(0.0)]); /// assert_tokens(&0f32, &[Token::F32(0.0)]);
@@ -102,7 +94,7 @@ pub enum Token {
/// A serialized `f64`. /// A serialized `f64`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&0f64, &[Token::F64(0.0)]); /// assert_tokens(&0f64, &[Token::F64(0.0)]);
@@ -111,7 +103,7 @@ pub enum Token {
/// A serialized `char`. /// A serialized `char`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&'\n', &[Token::Char('\n')]); /// assert_tokens(&'\n', &[Token::Char('\n')]);
@@ -120,7 +112,7 @@ pub enum Token {
/// A serialized `str`. /// A serialized `str`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// let s = String::from("transient"); /// let s = String::from("transient");
@@ -130,7 +122,7 @@ pub enum Token {
/// A borrowed `str`. /// A borrowed `str`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// let s: &str = "borrowed"; /// let s: &str = "borrowed";
@@ -140,7 +132,7 @@ pub enum Token {
/// A serialized `String`. /// A serialized `String`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// let s = String::from("owned"); /// let s = String::from("owned");
@@ -159,7 +151,7 @@ pub enum Token {
/// A serialized `Option<T>` containing none. /// A serialized `Option<T>` containing none.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// let opt = None::<char>; /// let opt = None::<char>;
@@ -171,7 +163,7 @@ pub enum Token {
/// ///
/// The tokens of the value follow after this header. /// The tokens of the value follow after this header.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// let opt = Some('c'); /// let opt = Some('c');
@@ -184,7 +176,7 @@ pub enum Token {
/// A serialized `()`. /// A serialized `()`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// assert_tokens(&(), &[Token::Unit]); /// assert_tokens(&(), &[Token::Unit]);
@@ -193,13 +185,8 @@ pub enum Token {
/// A serialized unit struct of the given name. /// A serialized unit struct of the given name.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -213,13 +200,8 @@ pub enum Token {
/// A unit variant of an enum. /// A unit variant of an enum.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -241,13 +223,8 @@ pub enum Token {
/// ///
/// After this header is the value contained in the newtype struct. /// After this header is the value contained in the newtype struct.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -267,13 +244,8 @@ pub enum Token {
/// ///
/// After this header is the value contained in the newtype variant. /// After this header is the value contained in the newtype variant.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -299,7 +271,7 @@ pub enum Token {
/// After this header are the elements of the sequence, followed by /// After this header are the elements of the sequence, followed by
/// `SeqEnd`. /// `SeqEnd`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// let vec = vec!['a', 'b', 'c']; /// let vec = vec!['a', 'b', 'c'];
@@ -320,7 +292,7 @@ pub enum Token {
/// ///
/// After this header are the elements of the tuple, followed by `TupleEnd`. /// After this header are the elements of the tuple, followed by `TupleEnd`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// let tuple = ('a', 100); /// let tuple = ('a', 100);
@@ -341,13 +313,8 @@ pub enum Token {
/// After this header are the fields of the tuple struct, followed by /// After this header are the fields of the tuple struct, followed by
/// `TupleStructEnd`. /// `TupleStructEnd`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -373,13 +340,8 @@ pub enum Token {
/// After this header are the fields of the tuple variant, followed by /// After this header are the fields of the tuple variant, followed by
/// `TupleVariantEnd`. /// `TupleVariantEnd`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -410,7 +372,7 @@ pub enum Token {
/// ///
/// After this header are the entries of the map, followed by `MapEnd`. /// After this header are the entries of the map, followed by `MapEnd`.
/// ///
/// ```rust /// ```edition2018
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// use std::collections::BTreeMap; /// use std::collections::BTreeMap;
@@ -437,13 +399,8 @@ pub enum Token {
/// ///
/// After this header are the fields of the struct, followed by `StructEnd`. /// After this header are the fields of the struct, followed by `StructEnd`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -474,13 +431,8 @@ pub enum Token {
/// After this header are the fields of the struct variant, followed by /// After this header are the fields of the struct variant, followed by
/// `StructVariantEnd`. /// `StructVariantEnd`.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
@@ -509,13 +461,8 @@ pub enum Token {
/// The header to an enum of the given name. /// The header to an enum of the given name.
/// ///
/// ```rust /// ```edition2018
/// # #[macro_use] /// # use serde::{Serialize, Deserialize};
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token}; /// # use serde_test::{assert_tokens, Token};
/// # /// #
/// # fn main() { /// # fn main() {
+5 -3
View File
@@ -2,17 +2,19 @@
name = "serde_test_suite" name = "serde_test_suite"
version = "0.0.0" version = "0.0.0"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"] authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
edition = "2018"
publish = false publish = false
[features] [features]
unstable = ["serde/unstable", "compiletest_rs"] unstable = ["serde/unstable"]
compiletest = ["compiletest_rs"]
[dev-dependencies] [dev-dependencies]
fnv = "1.0" fnv = "1.0"
rustc-serialize = "0.3.16" rustc-serialize = "0.3.16"
serde = { path = "../serde", features = ["rc"] } serde = { path = "../serde", features = ["rc", "derive"] }
serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] } serde_derive = { path = "../serde_derive", features = ["deserialize_in_place"] }
serde_test = { path = "../serde_test" } serde_test = { path = "../serde_test" }
[dependencies] [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(/*=============================================] #![feature(/*=============================================]
#![=== Serde test suite requires a nightly compiler. ===] #![=== Serde test suite requires a nightly compiler. ===]
#![====================================================*/)] #![====================================================*/)]
+2 -2
View File
@@ -1,11 +1,11 @@
[package] [package]
name = "serde_derive_tests_no_std" name = "serde_derive_tests_no_std"
version = "0.0.0" version = "0.0.0"
edition = "2018"
publish = false publish = false
[dependencies] [dependencies]
libc = { version = "0.2", default-features = false } libc = { version = "0.2", default-features = false }
serde = { path = "../../serde", default-features = false } serde = { path = "../../serde", default-features = false, features = ["derive"] }
serde_derive = { path = "../../serde_derive" }
[workspace] [workspace]
+1 -12
View File
@@ -1,16 +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.
#![feature(lang_items, start)] #![feature(lang_items, start)]
#![no_std] #![no_std]
extern crate libc;
#[start] #[start]
fn start(_argc: isize, _argv: *const *const u8) -> isize { fn start(_argc: isize, _argv: *const *const u8) -> isize {
0 0
@@ -29,8 +19,7 @@ fn panic(_info: &core::panic::PanicInfo) -> ! {
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
#[macro_use] use serde::{Serialize, Deserialize};
extern crate serde_derive;
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct Unit; struct Unit;
+1 -1
View File
@@ -22,7 +22,7 @@ impl<'de> Visitor<'de> for ByteBufVisitor {
V: SeqAccess<'de>, V: SeqAccess<'de>,
{ {
let mut values = Vec::new(); let mut values = Vec::new();
while let Some(value) = try!(visitor.next_element()) { while let Some(value) = visitor.next_element()? {
values.push(value); values.push(value);
} }
Ok(values) Ok(values)
@@ -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)]
struct Test<'a> {
#[serde(borrow = "zzz")]
//~^^^ ERROR: failed to parse borrowed lifetimes: "zzz"
s: &'a str,
}
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)]
struct Test<'a> {
#[serde(borrow = "'a + 'a")]
//~^^^ ERROR: duplicate borrowed lifetime `'a`
s: &'a str,
}
fn main() {}
@@ -1,22 +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)]
enum Test<'a> {
#[serde(borrow)]
//~^^^ ERROR: duplicate serde attribute `borrow`
S(#[serde(borrow)] Str<'a>),
}
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)]
struct Test<'a> {
#[serde(borrow = "")]
//~^^^ ERROR: at least one lifetime must be borrowed
s: &'a str,
}
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)]
struct Test {
#[serde(borrow)]
//~^^^ ERROR: field `s` has no lifetimes to borrow
s: String,
}
fn main() {}
@@ -1,22 +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)]
enum Test<'a> {
#[serde(borrow)]
//~^^^ ERROR: #[serde(borrow)] may only be used on newtype variants
S { s: Str<'a> },
}
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)]
struct Test<'a> {
#[serde(borrow = "'b")]
//~^^^ ERROR: 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)]
#[serde(tag = "conflict", content = "conflict")]
//~^^ ERROR: 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)]
struct Foo(#[serde(flatten)] HashMap<String, String>);
//~^^ ERROR: #[serde(flatten)] cannot be used on newtype structs
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)]
struct Foo {
#[serde(flatten, skip_deserializing)]
//~^^^ ERROR: #[serde(flatten] can not be combined with #[serde(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)]
struct Foo {
#[serde(flatten, skip_serializing_if = "Option::is_none")]
//~^^^ ERROR: #[serde(flatten] can not be combined with #[serde(skip_serializing_if = "...")]
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)]
struct Foo {
#[serde(flatten, skip_serializing)]
//~^^^ ERROR: #[serde(flatten] can not be combined with #[serde(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)]
struct Foo(u32, #[serde(flatten)] HashMap<String, String>);
//~^^ ERROR: #[serde(flatten)] cannot be used on tuple structs
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)]
#[serde(tag = "conflict")]
//~^^ ERROR: variant field name `conflict` conflicts with internal tag
enum E {
A {
#[serde(rename = "conflict")]
x: (),
},
}
fn main() {}
@@ -1,17 +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)]
#[serde(default)]
//~^^ ERROR: #[serde(default)] can only be used on structs
enum E {
S { f: u8 },
}
@@ -1,17 +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)]
#[serde(default)]
//~^^ ERROR: #[serde(default)] can only be used on structs
struct T(u8, u8);
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)]
struct S {
#[serde(rename = "x", serialize = "y")]
//~^^^ ERROR: unknown serde field attribute `serialize`
x: (),
}
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)]
struct S {
#[serde(rename = "x")]
#[serde(rename(deserialize = "y"))]
//~^^^^ ERROR: 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)]
struct S {
#[serde(rename(serialize = "x"), rename(serialize = "y"))]
//~^^^ ERROR: duplicate serde attribute `rename`
x: (),
}
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)]
struct S {
#[serde(rename(serialize = "x"))]
#[serde(rename = "y")]
//~^^^^ ERROR: 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)]
struct S {
#[serde(rename(serialize = "x", serialize = "y"))]
//~^^^ ERROR: duplicate serde attribute `rename`
x: (),
}
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)]
struct S {
#[serde(rename(serialize = "x"))]
#[serde(rename(serialize = "y"))]
//~^^^^ ERROR: 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)]
struct S {
#[serde(with = "w", serialize_with = "s")]
//~^^^ ERROR: duplicate serde attribute `serialize_with`
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)]
#[serde(tag = "type")]
//~^^ ERROR: #[serde(tag = "...")] cannot be used with tuple variants
enum E {
Tuple(u8, u8),
}
fn main() {}
@@ -1,17 +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)]
#[serde(tag = "type")]
//~^^ ERROR: #[serde(tag = "...")] can only be used on enums
struct S;
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(Serialize)]
#[serde(untagged)]
#[serde(tag = "type")]
//~^^^ ERROR: enum cannot be both untagged and internally tagged
enum E {
A(u8),
B(String),
}
fn main() {}
@@ -1,17 +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)]
#[serde(untagged)]
//~^^ ERROR: #[serde(untagged)] 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(Deserialize)]
#[serde(field_identifier, variant_identifier)]
//~^^ ERROR: `field_identifier` and `variant_identifier` cannot both be set
enum F {
A,
B,
}
fn main() {}
@@ -1,17 +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)]
#[serde(field_identifier)]
//~^^ ERROR: `field_identifier` can only be used on an enum
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(Deserialize)]
#[serde(field_identifier)]
enum F {
A,
B(u8, u8),
//~^^^^^ ERROR: field_identifier may only contain unit variants
}
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)]
#[serde(field_identifier)]
enum F {
A,
Other(String),
//~^^^^^ ERROR: `Other` must be the last variant
B,
}
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)]
#[serde(field_identifier)]
enum F {
A,
#[serde(other)]
//~^^^^^ ERROR: #[serde(other)] must be on a unit variant
Other(u8, u8),
}
fn main() {}
@@ -1,22 +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)]
#[serde(field_identifier)]
enum F {
A,
#[serde(other)]
//~^^^^^ ERROR: #[serde(other)] must be the last variant
Other,
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(Serialize)]
#[serde(field_identifier)]
//~^^ ERROR: field identifiers cannot be serialized
enum F {
A,
B,
}
fn main() {}
@@ -1,17 +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)]
#[serde(variant_identifier)]
//~^^ ERROR: `variant_identifier` can only be used on an enum
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(Deserialize)]
#[serde(variant_identifier)]
enum F {
A,
B(u8, u8),
//~^^^^^ ERROR: variant_identifier may only contain unit variants
}
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(Deserialize)]
struct S<'de> {
//~^^ ERROR: cannot deserialize when there is a lifetime parameter called 'de
s: &'de str,
}
@@ -1,17 +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)]
struct S {
string: String,
slice: [u8],
//~^^^^ ERROR: cannot deserialize a dynamically sized struct
}
@@ -1,26 +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)]
#[serde(remote = "remote::S")]
struct S {
#[serde(getter = "~~~")]
//~^^^^ ERROR: failed to parse path: "~~~"
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 {
a: u8,
}
}
#[derive(Serialize)]
#[serde(remote = "~~~")]
//~^^ ERROR: failed to parse path: "~~~"
struct S {
a: u8,
}
fn main() {}
@@ -1,28 +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)]
#[serde(remote = "remote::E")]
pub enum E {
A {
#[serde(getter = "get_a")]
//~^^^^^ ERROR: #[serde(getter = "...")] is not allowed in an enum
a: u8,
},
}
fn main() {}
@@ -1,26 +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,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;
#[derive(Serialize)]
struct S {
#[serde(getter = "S::get")]
//~^^^ ERROR: #[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,26 +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 {
b: u8,
//~^ ERROR: struct `remote::S` has no field named `b`
//~^^ ERROR: no field `b` on type `&remote::S`
}
fn main() {}
@@ -1,22 +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)]
#[serde(remote = "remote::S")]
struct S(u8);
//~^^^ ERROR: mismatched types
//~^^^^ expected u16, found u8
fn main() {}

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