Compare commits

...

67 Commits

Author SHA1 Message Date
David Tolnay cd0412bddc Release 1.0.92 2019-05-31 13:44:01 -07:00
David Tolnay e42262f0f5 Provide ToString for re-export by serde::export 2019-05-31 13:42:22 -07:00
David Tolnay 0a3eeab273 Merge pull request #1543 from jplatte/alloc-de-compile-fix
Fix a compile error in derive(Deserialize) with no_std + alloc
2019-05-31 13:41:07 -07:00
Jonas Platte e4e110e28f Fix a compile error in derive(Deserialize) with no_std + alloc 2019-05-31 22:16:40 +02:00
David Tolnay 0726623389 Ignore bare_trait_objects lint to support old compilers 2019-05-31 11:34:18 -07:00
David Tolnay fd9d334d01 Smaller format for license section 2019-05-18 17:35:47 -07:00
David Tolnay 840eb14121 Merge pull request #1528 from est31/no_variable_names
Don't use variable names
2019-05-17 08:57:14 -07:00
est31 8fef196ee4 Don't use variable names
They aren't needed. This makes the macro a bit simpler
2019-05-17 16:50:41 +02:00
David Tolnay 9c756f1ec0 Disable ui tests on emscripten
These hit a strange error in our Emscripten builder in Travis as well as
locally through cargo web:

    ERROR: failed to execute cargo: Resource temporarily unavailable (os error 11)
2019-05-12 00:28:22 -07:00
David Tolnay 6dd2b4607f Switch to SPDX 2.1 license expression 2019-05-09 15:21:20 -07:00
David Tolnay 1e9ae88f53 Work around "failed to select a version for serde_test_suite"
Without this:

    error: failed to select a version for `serde_test_suite`.
        ... required by package `serde_test_suite-tests v0.0.0`
    versions that meet the requirements `= 0.0.0` are: 0.0.0

    the package `serde_test_suite-tests` depends on `serde_test_suite`, with features: `serde` but `serde_test_suite` does not have these features.

    failed to select a version for `serde_test_suite` which could resolve this conflict

Seems like a Cargo bug -- I will minimize and report.
2019-05-06 22:53:38 -07:00
David Tolnay 5cc3902ab9 Release 1.0.91 2019-05-06 16:27:04 -07:00
David Tolnay c8e09e2d6d Merge pull request #1522 from dtolnay/enum
Support deserializing enum out of MapAccessDeserializer
2019-05-06 16:26:43 -07:00
David Tolnay e2a2ba116c Remove old instructions intended for compiletest 2019-05-06 16:17:30 -07:00
David Tolnay 0a9d24a218 Support deserializing enum out of MapAccessDeserializer 2019-05-06 16:11:28 -07:00
David Tolnay c222183669 Merge pull request #1521 from serde-rs/trybuild
Switch ui tests to trybuild
2019-05-06 10:44:25 -07:00
David Tolnay 140f9beee7 Switch ui tests to trybuild 2019-05-06 10:25:47 -07:00
David Tolnay 28ce892617 Disable compiletest in appveyor
error[E0464]: multiple matching crates for `serde`
      --> $DIR/wrong_getter.rs:15:10
       |
    15 | #[derive(Serialize)]
       |          ^^^^^^^^^
       |
       = note: candidates:
               crate `serde`: /?/C:/projects/serde/test_suite/deps/target/debug/deps/libserde-a1a28acc73b0edde.rlib
               crate `serde`: /?/C:/Users/appveyor/.
2019-04-22 23:18:21 -07:00
David Tolnay 1e6d3ff99b Merge pull request #1512 from dtolnay/off
Temporarily disable compiletest testing in CI
2019-04-22 23:05:54 -07:00
David Tolnay fba1b92cbf Temporarily disable compiletest testing in CI
The nightly compiler just added a dependency on serde so libserde ends
up in the sysroot, breaking crate resolution inside of compiletest. We
will need to figure out how else to run these tests.

    error[E0464]: multiple matching crates for `serde`
      --> $DIR/wrong_ser.rs:9:10
       |
     9 | #[derive(Serialize)]
       |          ^^^^^^^^^
       |
       = note: candidates:
               crate `serde`: /rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libserde-2b75907288aa7c40.rlib
               crate `serde`: /serde/test_suite/deps/target/debug/deps/libserde-33e0a319242344ce.rlib
2019-04-22 22:42:36 -07:00
David Tolnay ce1686379d Update test suite to nightly-2019-04-20 2019-04-19 22:54:59 -07:00
David Tolnay 79a20e9e33 Resolve option_map_unwrap_or_else lint 2019-04-10 22:57:47 -07:00
David Tolnay e9cd73f78e Remove link to hjson
This project has still not been updated to Serde 1.0.
2019-04-08 10:39:55 -07:00
David Tolnay 0be7f36d51 Release 1.0.90 2019-04-03 09:41:38 -07:00
David Tolnay 4c6cb6e359 Match on serde_path to handle Some(path) and None
I find this a bit easier to follow than map + unwrap_or_else.
2019-04-03 09:40:25 -07:00
David Tolnay 82bde8d166 Format with rustfmt 2019-03-27 2019-04-03 09:40:12 -07:00
David Tolnay 465392b618 Merge pull request #1499 from sgrif/sg-custom-serde-path
Allow `#[serde(crate = "...")]` to override `extern crate serde`
2019-04-03 09:32:07 -07:00
David Tolnay f3c6b9f05a Simplify signature of Container::serde_path 2019-04-03 09:18:45 -07:00
David Tolnay 2f1945eaf2 Refer directly to serde_path in Deserialize impl
This makes it not a breaking change if we later want to eliminate
the `use #serde_path as _serde;` line.
2019-04-03 09:16:21 -07:00
Sean Griffin b4d8a55b2a Change serde_path to crate
Also changed the generated code to have at least one thing refer to the
path directly, rather than via `use` -- This shows that the impl *can*
work without `use`, but doesn't actually do all the work to remove the
`use` lines unless we decide we need this feature to work on the 2015
edition
2019-03-28 11:42:50 -06:00
Sean Griffin 0e6ce8fa50 Fix for Rust 1.15 2019-03-20 14:31:49 -06:00
Sean Griffin a295c38ba3 Allow #[serde(serde_path = "...")] to override extern crate serde
This is intended to be used by other crates which provide their own proc
macros and use serde internally. Today there's no consistent way to put
`#[derive(Deserialize)]` on a struct that consistently works, since
crates may be using either `features = ["derive"]` or relying on
`serde_derive` separately.

Even if we assume that everyone is using `features = ["derive"]`,
without this commit, any crate which generates
`#[derive(serde::Deserialize)]` forces its consumers to put `serde` in
their `Cargo.toml`, even if they aren't otherwise using serde for
anything.

Examples of crates which suffer from this in the real world are
tower-web and swirl.

With this feature, it's expected that these crates would have `pub
extern crate serde;` in some accessible path, and add
`#[serde(serde_path = "that_crate::wherever::serde")]` anywhere they
place serde's derives. Those crates would also have to derive
`that_crate::whatever::serde::Deserialize`, or `use` the macros
explicitly beforehand.

The test for this is a little funky, as it's testing this in a way that
is not the intended use case, or even one we want to support. It has its
own module which re-exports all of serde, but defines its own
`Serialize` and `Deserialize` traits. We then test that we generated
impls for those traits, instead of serde's. The only other way to test
this would be to create a new test crate which does not depend on serde,
but instead depends on `serde_derive` and a third crate which publicly
re-exports serde. This feels like way too much overhead for a single
test case, hence the funky test given.

I didn't see anywhere in this repo to document this attribute, so I
assume the docs will have to be done as a separate PR to a separate
repo.

Fixes #1487
2019-03-18 15:20:19 -06:00
David Tolnay 295730ba1e Clippy cyclomatic complexity lint has been renamed 2019-03-09 16:36:51 -08:00
David Tolnay ac0d8f61c5 Use non-preview name of Clippy rustup component 2019-03-01 23:11:06 -08:00
David Tolnay b811588fa0 Release 1.0.89 2019-02-28 17:09:10 -08:00
David Tolnay 5fcdf0ff2b Sort version-conditional imports at the bottom 2019-02-28 16:53:13 -08:00
David Tolnay 650b723da3 Format with rustfmt 2019-02-14 2019-02-28 16:40:54 -08:00
David Tolnay 97920be33a Merge pull request #1486 from vorot93/reverse
impl Serialize and Deserialize for core::cmp::Reverse
2019-02-28 16:39:54 -08:00
David Tolnay 58bbaa9e80 Refer to Option through serde::export in generated code 2019-02-28 16:36:17 -08:00
David Tolnay 94f152730c Merge pull request #1492 from thomaseizinger/1491-clippy-warning
Don't generate code with redundant closures
2019-02-28 16:35:59 -08:00
David Tolnay 535e3d4372 Mention rc feature in list of trait impls in documentation 2019-02-28 01:13:36 -08:00
Thomas Eizinger 2ea43c8986 Don't generate code with redundant closures
Fixes #1491.
2019-02-28 17:30:21 +11:00
Artem Vorotnikov 71fe2a5534 Reverse impls available for Rust >=1.19 2019-02-20 12:56:35 +03:00
Artem Vorotnikov f3ffcfd61e impl Serialize and Deserialize for core::cmp::Reverse 2019-02-20 04:32:55 +03:00
David Tolnay bf27b28554 Simplify running update-references.sh 2019-02-17 10:58:46 -08:00
David Tolnay 344602d27e Make array ser impls macro better fit rustfmt style 2019-02-16 15:22:53 -08:00
David Tolnay 64c483cf80 Release 1.0.88 2019-02-15 19:55:50 -08:00
David Tolnay 19091aacc7 Fix mistaken double negative in flatten error message 2019-02-15 18:56:31 -08:00
David Tolnay ef9028d798 Remove conflict between flatten and skip 2019-02-15 18:39:15 -08:00
David Tolnay 1668cd19d3 Eliminate try!(..).value to improve rustfmt'd code
Rustfmt bails out on the original code, leaving it all on one line.
2019-02-13 09:13:50 -08:00
David Tolnay 134f268cee Release 1.0.87 2019-02-04 07:08:41 +01:00
David Tolnay c473633676 Format with rustfmt 2018-12-10 2019-02-04 00:39:32 +01:00
David Tolnay 6a3a82007c Merge pull request #1474 from jwillbold/master
Fixed #1468, flattened struct fields made structs ignore their tag
2019-02-03 15:37:44 -08:00
Johannes Willbold 1d6ef76cfb Fixed #1468, flattened struct fields made structs ignore their tag 2019-02-03 02:09:37 +01:00
David Tolnay c8e3959435 Release 1.0.86 2019-02-01 21:07:19 -08:00
David Tolnay 796f412a1e Document that Bound<T> impls exist 2019-02-01 21:07:18 -08:00
David Tolnay fa854a2108 Format with rustfmt 2018-12-10 2019-02-01 21:04:08 -08:00
David Tolnay 3a097ff2d2 Deserialize Bound::Unbounded as unit variant 2019-02-01 21:04:07 -08:00
David Tolnay 8463bfc1e5 Remove as yet unrequested range impls 2019-02-01 21:04:06 -08:00
David Tolnay 7a72b4c624 Merge pull request #1466 from 0nkery/master
Impl Serialize/Deserialize for std::ops::{Bound, RangeFrom, RangeTo, RangeToInclusive}
2019-02-01 21:03:55 -08:00
David Tolnay 670c179417 Re-enable deny unused_imports 2019-02-01 17:56:52 -08:00
David Tolnay 1b1d868837 Combine the two clippy lists 2019-02-01 17:56:31 -08:00
David Tolnay d9704d02bb Remove clippy lints that are no longer triggering 2019-02-01 17:53:14 -08:00
David Tolnay 1349548367 Fix indentation of cfg that isn't formatted by rustfmt 2019-02-01 17:48:14 -08:00
Dmitry Shlagoff 18b1604fc8 Fix compatibility issues with syntax and Bound 2019-01-30 00:41:03 +07:00
Dmitry Shlagoff 0def7da5a8 Impl Ser/De for RangeFrom, RangeTo, RangeToInclusive 2019-01-29 20:29:14 +07:00
Dmitry Shlagoff 4bb45c8252 Impl Serialize for Bound<T> 2019-01-29 15:20:27 +07:00
133 changed files with 762 additions and 637 deletions
+2 -4
View File
@@ -26,10 +26,8 @@ matrix:
- 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 derive,rc,unstable - cargo test --features derive,rc,unstable
- cd "${TRAVIS_BUILD_DIR}/test_suite/deps"
- cargo build
- cd "${TRAVIS_BUILD_DIR}/test_suite" - cd "${TRAVIS_BUILD_DIR}/test_suite"
- cargo test --features compiletest,unstable - cargo test --features unstable
- cd "${TRAVIS_BUILD_DIR}/test_suite/no_std" - cd "${TRAVIS_BUILD_DIR}/test_suite/no_std"
- cargo build - cargo build
@@ -54,7 +52,7 @@ matrix:
- rust: nightly - rust: nightly
name: Clippy name: Clippy
script: script:
- rustup component add clippy-preview || travis_terminate 0 - rustup component add clippy || travis_terminate 0
- cargo clippy -- -D clippy::all - cargo clippy -- -D clippy::all
- cd "${TRAVIS_BUILD_DIR}/serde" - cd "${TRAVIS_BUILD_DIR}/serde"
- cargo clippy --features rc,unstable -- -D clippy::all - cargo clippy --features rc,unstable -- -D clippy::all
+9 -9
View File
@@ -81,19 +81,19 @@ good response, we are happy to respond to [GitHub issues][issues] as well.
[irc]: https://wiki.mozilla.org/IRC [irc]: https://wiki.mozilla.org/IRC
[issues]: https://github.com/serde-rs/serde/issues/new/choose [issues]: https://github.com/serde-rs/serde/issues/new/choose
## License <br>
Serde is licensed under either of #### License
* Apache License, Version 2.0, ([LICENSE-APACHE](LICENSE-APACHE) or <sup>
http://www.apache.org/licenses/LICENSE-2.0) Licensed under either of <a href="LICENSE-APACHE">Apache License, Version
* MIT license ([LICENSE-MIT](LICENSE-MIT) or 2.0</a> or <a href="LICENSE-MIT">MIT license</a> at your option.
http://opensource.org/licenses/MIT) </sup>
at your option. <br>
### Contribution
<sub>
Unless you explicitly state otherwise, any contribution intentionally submitted Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be for inclusion in Serde by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions. dual licensed as above, without any additional terms or conditions.
</sub>
+1 -3
View File
@@ -35,7 +35,5 @@ for:
- 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 derive,rc,unstable - cargo test --features derive,rc,unstable
- cd %APPVEYOR_BUILD_FOLDER%\test_suite\deps
- cargo build
- cd %APPVEYOR_BUILD_FOLDER%\test_suite - cd %APPVEYOR_BUILD_FOLDER%\test_suite
- cargo test --features compiletest,unstable - cargo test --features unstable
+2 -2
View File
@@ -1,8 +1,8 @@
[package] [package]
name = "serde" name = "serde"
version = "1.0.85" # remember to update html_root_url version = "1.0.92" # 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 OR Apache-2.0"
description = "A generic serialization/deserialization framework" description = "A generic serialization/deserialization framework"
homepage = "https://serde.rs" homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde" repository = "https://github.com/serde-rs/serde"
+15
View File
@@ -14,6 +14,21 @@ fn main() {
let target = env::var("TARGET").unwrap(); let target = env::var("TARGET").unwrap();
let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten"; let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
// std::collections::Bound was stabilized in Rust 1.17
// but it was moved to core::ops later in Rust 1.26:
// https://doc.rust-lang.org/core/ops/enum.Bound.html
if minor >= 26 {
println!("cargo:rustc-cfg=ops_bound");
} else if minor >= 17 && cfg!(feature = "std") {
println!("cargo:rustc-cfg=collections_bound");
}
// core::cmp::Reverse stabilized in Rust 1.19:
// https://doc.rust-lang.org/stable/core/cmp/struct.Reverse.html
if minor >= 19 {
println!("cargo:rustc-cfg=core_reverse");
}
// CString::into_boxed_c_str stabilized in Rust 1.20: // CString::into_boxed_c_str stabilized in Rust 1.20:
// https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str // https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
if minor >= 20 { if minor >= 20 {
+151 -39
View File
@@ -578,6 +578,9 @@ macro_rules! forwarded_impl {
#[cfg(all(feature = "std", de_boxed_c_str))] #[cfg(all(feature = "std", de_boxed_c_str))]
forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str); forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
#[cfg(core_reverse)]
forwarded_impl!((T), Reverse<T>, Reverse);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
struct OptionVisitor<T> { struct OptionVisitor<T> {
@@ -962,7 +965,7 @@ impl<'de, T> Deserialize<'de> for [T; 0] {
} }
macro_rules! array_impls { macro_rules! array_impls {
($($len:expr => ($($n:tt $name:ident)+))+) => { ($($len:expr => ($($n:tt)+))+) => {
$( $(
impl<'de, T> Visitor<'de> for ArrayVisitor<[T; $len]> impl<'de, T> Visitor<'de> for ArrayVisitor<[T; $len]>
where where
@@ -979,14 +982,12 @@ macro_rules! array_impls {
where where
A: SeqAccess<'de>, A: SeqAccess<'de>,
{ {
$( Ok([$(
let $name = match try!(seq.next_element()) { match try!(seq.next_element()) {
Some(val) => val, Some(val) => val,
None => return Err(Error::invalid_length($n, &self)), None => return Err(Error::invalid_length($n, &self)),
}; }
)+ ),+])
Ok([$($name),+])
} }
} }
@@ -1042,38 +1043,38 @@ macro_rules! array_impls {
} }
array_impls! { array_impls! {
1 => (0 a) 1 => (0)
2 => (0 a 1 b) 2 => (0 1)
3 => (0 a 1 b 2 c) 3 => (0 1 2)
4 => (0 a 1 b 2 c 3 d) 4 => (0 1 2 3)
5 => (0 a 1 b 2 c 3 d 4 e) 5 => (0 1 2 3 4)
6 => (0 a 1 b 2 c 3 d 4 e 5 f) 6 => (0 1 2 3 4 5)
7 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g) 7 => (0 1 2 3 4 5 6)
8 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h) 8 => (0 1 2 3 4 5 6 7)
9 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i) 9 => (0 1 2 3 4 5 6 7 8)
10 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j) 10 => (0 1 2 3 4 5 6 7 8 9)
11 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k) 11 => (0 1 2 3 4 5 6 7 8 9 10)
12 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l) 12 => (0 1 2 3 4 5 6 7 8 9 10 11)
13 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m) 13 => (0 1 2 3 4 5 6 7 8 9 10 11 12)
14 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n) 14 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13)
15 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o) 15 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14)
16 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p) 16 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15)
17 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q) 17 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16)
18 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r) 18 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17)
19 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s) 19 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18)
20 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t) 20 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
21 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u) 21 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20)
22 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v) 22 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21)
23 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w) 23 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22)
24 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x) 24 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23)
25 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y) 25 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24)
26 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z) 26 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25)
27 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa) 27 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26)
28 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab) 28 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27)
29 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac) 29 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28)
30 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad) 30 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29)
31 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad 30 ae) 31 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30)
32 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad 30 ae 31 af) 32 => (0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31)
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -2269,6 +2270,117 @@ mod range {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(ops_bound, collections_bound))]
impl<'de, T> Deserialize<'de> for Bound<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
enum Field {
Unbounded,
Included,
Excluded,
}
impl<'de> Deserialize<'de> for Field {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`Unbounded`, `Included` or `Excluded`")
}
fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
where
E: Error,
{
match value {
0 => Ok(Field::Unbounded),
1 => Ok(Field::Included),
2 => Ok(Field::Excluded),
_ => Err(Error::invalid_value(
Unexpected::Unsigned(value as u64),
&self,
)),
}
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"Unbounded" => Ok(Field::Unbounded),
"Included" => Ok(Field::Included),
"Excluded" => Ok(Field::Excluded),
_ => Err(Error::unknown_variant(value, VARIANTS)),
}
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"Unbounded" => Ok(Field::Unbounded),
b"Included" => Ok(Field::Included),
b"Excluded" => Ok(Field::Excluded),
_ => match str::from_utf8(value) {
Ok(value) => Err(Error::unknown_variant(value, VARIANTS)),
Err(_) => {
Err(Error::invalid_value(Unexpected::Bytes(value), &self))
}
},
}
}
}
deserializer.deserialize_identifier(FieldVisitor)
}
}
struct BoundVisitor<T>(PhantomData<Bound<T>>);
impl<'de, T> Visitor<'de> for BoundVisitor<T>
where
T: Deserialize<'de>,
{
type Value = Bound<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("enum Bound")
}
fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
where
A: EnumAccess<'de>,
{
match try!(data.variant()) {
(Field::Unbounded, v) => v.unit_variant().map(|()| Bound::Unbounded),
(Field::Included, v) => v.newtype_variant().map(Bound::Included),
(Field::Excluded, v) => v.newtype_variant().map(Bound::Excluded),
}
}
}
const VARIANTS: &'static [&'static str] = &["Unbounded", "Included", "Excluded"];
deserializer.deserialize_enum("Bound", VARIANTS, BoundVisitor(PhantomData))
}
}
////////////////////////////////////////////////////////////////////////////////
macro_rules! nonzero_integers { macro_rules! nonzero_integers {
( $( $T: ident, )+ ) => { ( $( $T: ident, )+ ) => {
$( $(
+3 -2
View File
@@ -59,13 +59,13 @@
//! - Box\<T\> //! - Box\<T\>
//! - Box\<\[T\]\> //! - Box\<\[T\]\>
//! - Box\<str\> //! - Box\<str\>
//! - Rc\<T\>
//! - Arc\<T\>
//! - Cow\<'a, T\> //! - Cow\<'a, T\>
//! - Cell\<T\> //! - Cell\<T\>
//! - RefCell\<T\> //! - RefCell\<T\>
//! - Mutex\<T\> //! - Mutex\<T\>
//! - RwLock\<T\> //! - RwLock\<T\>
//! - Rc\<T\>&emsp;*(if* features = ["rc"] *is enabled)*
//! - Arc\<T\>&emsp;*(if* features = ["rc"] *is enabled)*
//! - **Collection types**: //! - **Collection types**:
//! - BTreeMap\<K, V\> //! - BTreeMap\<K, V\>
//! - BTreeSet\<T\> //! - BTreeSet\<T\>
@@ -89,6 +89,7 @@
//! - PathBuf //! - PathBuf
//! - Range\<T\> //! - Range\<T\>
//! - RangeInclusive\<T\> //! - RangeInclusive\<T\>
//! - Bound\<T\>
//! - num::NonZero* //! - num::NonZero*
//! - `!` *(unstable)* //! - `!` *(unstable)*
//! - **Net types**: //! - **Net types**:
+118 -2
View File
@@ -1287,10 +1287,40 @@ where
visitor.visit_map(self.map) visitor.visit_map(self.map)
} }
fn deserialize_enum<V>(
self,
_name: &str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_enum(self)
}
forward_to_deserialize_any! { forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any tuple_struct map struct identifier ignored_any
}
}
impl<'de, A> de::EnumAccess<'de> for MapAccessDeserializer<A>
where
A: de::MapAccess<'de>,
{
type Error = A::Error;
type Variant = private::MapAsEnum<A>;
fn variant_seed<T>(mut self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
where
T: de::DeserializeSeed<'de>,
{
match self.map.next_key_seed(seed)? {
Some(key) => Ok((key, private::map_as_enum(self.map))),
None => Err(de::Error::invalid_type(de::Unexpected::Map, &"enum")),
}
} }
} }
@@ -1299,7 +1329,7 @@ where
mod private { mod private {
use lib::*; use lib::*;
use de::{self, Unexpected}; use de::{self, DeserializeSeed, Deserializer, MapAccess, Unexpected, VariantAccess, Visitor};
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct UnitOnly<E> { pub struct UnitOnly<E> {
@@ -1360,6 +1390,92 @@ mod private {
} }
} }
#[derive(Clone, Debug)]
pub struct MapAsEnum<A> {
map: A,
}
pub fn map_as_enum<A>(map: A) -> MapAsEnum<A> {
MapAsEnum { map: map }
}
impl<'de, A> VariantAccess<'de> for MapAsEnum<A>
where
A: MapAccess<'de>,
{
type Error = A::Error;
fn unit_variant(mut self) -> Result<(), Self::Error> {
self.map.next_value()
}
fn newtype_variant_seed<T>(mut self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeSeed<'de>,
{
self.map.next_value_seed(seed)
}
fn tuple_variant<V>(mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.map.next_value_seed(SeedTupleVariant {
len: len,
visitor: visitor,
})
}
fn struct_variant<V>(
mut self,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.map
.next_value_seed(SeedStructVariant { visitor: visitor })
}
}
struct SeedTupleVariant<V> {
len: usize,
visitor: V,
}
impl<'de, V> DeserializeSeed<'de> for SeedTupleVariant<V>
where
V: Visitor<'de>,
{
type Value = V::Value;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_tuple(self.len, self.visitor)
}
}
struct SeedStructVariant<V> {
visitor: V,
}
impl<'de, V> DeserializeSeed<'de> for SeedStructVariant<V>
where
V: Visitor<'de>,
{
type Value = V::Value;
fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_map(self.visitor)
}
}
/// Avoid having to restate the generic types on `MapDeserializer`. The /// Avoid having to restate the generic types on `MapDeserializer`. The
/// `Iterator::Item` contains enough information to figure out K and V. /// `Iterator::Item` contains enough information to figure out K and V.
pub trait Pair { pub trait Pair {
+1 -1
View File
@@ -9,7 +9,7 @@ pub use lib::result::Result::{self, Err, Ok};
pub use self::string::from_utf8_lossy; pub use self::string::from_utf8_lossy;
#[cfg(any(feature = "alloc", feature = "std"))] #[cfg(any(feature = "alloc", feature = "std"))]
pub use lib::Vec; pub use lib::{ToString, Vec};
mod string { mod string {
use lib::*; use lib::*;
+35 -44
View File
@@ -46,7 +46,6 @@
//! - [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. //! - [JSON5], A superset of JSON including some productions from ES5.
//! - [URL], the x-www-form-urlencoded format. //! - [URL], the x-www-form-urlencoded format.
//! - [Envy], a way to deserialize environment variables into Rust structs. //! - [Envy], a way to deserialize environment variables into Rust structs.
@@ -64,7 +63,6 @@
//! [RON]: https://github.com/ron-rs/ron //! [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 //! [JSON5]: https://github.com/callum-oakley/json5-rs
//! [URL]: https://github.com/nox/serde_urlencoded //! [URL]: https://github.com/nox/serde_urlencoded
//! [Envy]: https://github.com/softprops/envy //! [Envy]: https://github.com/softprops/envy
@@ -75,7 +73,7 @@
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here. // Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.85")] #![doc(html_root_url = "https://docs.rs/serde/1.0.92")]
// 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
@@ -84,54 +82,38 @@
// https://github.com/serde-rs/serde/issues/812 // https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization, never_type))] #![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![cfg_attr(feature = "alloc", feature(alloc))] #![cfg_attr(feature = "alloc", feature(alloc))]
#![allow(unknown_lints, bare_trait_objects)]
#![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))]
// Ignored clippy lints // Ignored clippy and clippy_pedantic lints
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
allow( allow(
cast_lossless, // not available in our oldest supported compiler
const_static_lifetime, const_static_lifetime,
doc_markdown, empty_enum,
linkedlist,
needless_pass_by_value,
redundant_field_names, redundant_field_names,
// integer and float ser/de requires these sorts of casts
cast_possible_truncation,
cast_possible_wrap,
cast_precision_loss,
cast_sign_loss,
// things are often more readable this way
cast_lossless,
module_name_repetitions,
single_match_else,
type_complexity, type_complexity,
unreadable_literal, use_self,
zero_prefixed_literal zero_prefixed_literal,
// not practical
needless_pass_by_value,
similar_names,
// preference
doc_markdown,
) )
)] )]
// Ignored clippy_pedantic lints // Rustc lints.
#![cfg_attr(feature = "cargo-clippy", allow( #![deny(missing_docs, unused_imports)]
// integer and float ser/de requires these sorts of casts
cast_possible_truncation,
cast_possible_wrap,
cast_precision_loss,
cast_sign_loss,
// simplifies some macros
invalid_upcast_comparisons,
// things are often more readable this way
decimal_literal_representation,
module_name_repetitions,
option_unwrap_used,
result_unwrap_used,
shadow_reuse,
single_match_else,
use_self,
// not practical
indexing_slicing,
many_single_char_names,
missing_docs_in_private_items,
similar_names,
// alternative is not stable
empty_enum,
use_debug,
))]
// Blacklisted Rust lints.
//
// Compiler bug involving unused_imports:
// https://github.com/rust-lang/rust/issues/51661
#![deny(missing_docs, /*unused_imports*/)]
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -172,7 +154,7 @@ mod lib {
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::string::{String, ToString}; pub use alloc::string::{String, ToString};
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::string::String; pub use std::string::{String, ToString};
#[cfg(all(feature = "alloc", not(feature = "std")))] #[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::vec::Vec; pub use alloc::vec::Vec;
@@ -219,11 +201,20 @@ mod lib {
#[cfg(feature = "std")] #[cfg(feature = "std")]
pub use std::time::{SystemTime, UNIX_EPOCH}; pub use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(any(core_duration, feature = "std"))] #[cfg(all(feature = "std", collections_bound))]
pub use self::core::time::Duration; pub use std::collections::Bound;
#[cfg(core_reverse)]
pub use self::core::cmp::Reverse;
#[cfg(ops_bound)]
pub use self::core::ops::Bound;
#[cfg(range_inclusive)] #[cfg(range_inclusive)]
pub use self::core::ops::RangeInclusive; pub use self::core::ops::RangeInclusive;
#[cfg(any(core_duration, feature = "std"))]
pub use self::core::time::Duration;
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
+1 -1
View File
@@ -2709,7 +2709,7 @@ where
} }
Err(Error::custom(format_args!( Err(Error::custom(format_args!(
"no variant of enum {} not found in flattened data", "no variant of enum {} found in flattened data",
name name
))) )))
} }
+43 -4
View File
@@ -160,10 +160,12 @@ macro_rules! array_impls {
} }
} }
array_impls!(01 02 03 04 05 06 07 08 09 10 array_impls! {
11 12 13 14 15 16 17 18 19 20 01 02 03 04 05 06 07 08 09 10
21 22 23 24 25 26 27 28 29 30 11 12 13 14 15 16 17 18 19 20
31 32); 21 22 23 24 25 26 27 28 29 30
31 32
}
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@@ -256,6 +258,29 @@ where
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
#[cfg(any(ops_bound, collections_bound))]
impl<T> Serialize for Bound<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match *self {
Bound::Unbounded => serializer.serialize_unit_variant("Bound", 0, "Unbounded"),
Bound::Included(ref value) => {
serializer.serialize_newtype_variant("Bound", 1, "Included", value)
}
Bound::Excluded(ref value) => {
serializer.serialize_newtype_variant("Bound", 2, "Excluded", value)
}
}
}
}
////////////////////////////////////////////////////////////////////////////////
impl Serialize for () { impl Serialize for () {
#[inline] #[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -799,3 +824,17 @@ where
self.0.serialize(serializer) self.0.serialize(serializer)
} }
} }
#[cfg(core_reverse)]
impl<T> Serialize for Reverse<T>
where
T: Serialize,
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(serializer)
}
}
+3 -2
View File
@@ -56,13 +56,13 @@
//! - PhantomData\<T\> //! - PhantomData\<T\>
//! - **Wrapper types**: //! - **Wrapper types**:
//! - Box\<T\> //! - Box\<T\>
//! - Rc\<T\>
//! - Arc\<T\>
//! - Cow\<'a, T\> //! - Cow\<'a, T\>
//! - Cell\<T\> //! - Cell\<T\>
//! - RefCell\<T\> //! - RefCell\<T\>
//! - Mutex\<T\> //! - Mutex\<T\>
//! - RwLock\<T\> //! - RwLock\<T\>
//! - Rc\<T\>&emsp;*(if* features = ["rc"] *is enabled)*
//! - Arc\<T\>&emsp;*(if* features = ["rc"] *is enabled)*
//! - **Collection types**: //! - **Collection types**:
//! - BTreeMap\<K, V\> //! - BTreeMap\<K, V\>
//! - BTreeSet\<T\> //! - BTreeSet\<T\>
@@ -84,6 +84,7 @@
//! - PathBuf //! - PathBuf
//! - Range\<T\> //! - Range\<T\>
//! - RangeInclusive\<T\> //! - RangeInclusive\<T\>
//! - Bound\<T\>
//! - num::NonZero* //! - num::NonZero*
//! - `!` *(unstable)* //! - `!` *(unstable)*
//! - **Net types**: //! - **Net types**:
+2 -2
View File
@@ -1,8 +1,8 @@
[package] [package]
name = "serde_derive" name = "serde_derive"
version = "1.0.85" # remember to update html_root_url version = "1.0.92" # 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 OR Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]" description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
homepage = "https://serde.rs" homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde" repository = "https://github.com/serde-rs/serde"
+49 -15
View File
@@ -27,15 +27,16 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream
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 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();
let serde = cont.attrs.serde_path();
let impl_block = if let Some(remote) = cont.attrs.remote() { let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis; let vis = &input.vis;
let used = pretend::pretend_used(&cont); let used = pretend::pretend_used(&cont);
quote! { quote! {
impl #de_impl_generics #ident #ty_generics #where_clause { impl #de_impl_generics #ident #ty_generics #where_clause {
#vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error> #vis fn deserialize<__D>(__deserializer: __D) -> #serde::export::Result<#remote #ty_generics, __D::Error>
where where
__D: _serde::Deserializer<#delife>, __D: #serde::Deserializer<#delife>,
{ {
#used #used
#body #body
@@ -47,10 +48,10 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream
quote! { quote! {
#[automatically_derived] #[automatically_derived]
impl #de_impl_generics _serde::Deserialize<#delife> for #ident #ty_generics #where_clause { impl #de_impl_generics #serde::Deserialize<#delife> for #ident #ty_generics #where_clause {
fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error> fn deserialize<__D>(__deserializer: __D) -> #serde::export::Result<Self, __D::Error>
where where
__D: _serde::Deserializer<#delife>, __D: #serde::Deserializer<#delife>,
{ {
#body #body
} }
@@ -60,7 +61,12 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream
} }
}; };
Ok(dummy::wrap_in_const("DESERIALIZE", ident, impl_block)) Ok(dummy::wrap_in_const(
cont.attrs.custom_serde_path(),
"DESERIALIZE",
ident,
impl_block,
))
} }
fn precondition(cx: &Ctxt, cont: &Container) { fn precondition(cx: &Ctxt, cont: &Container) {
@@ -1149,7 +1155,11 @@ fn prepare_enum_variant_enum(
.enumerate() .enumerate()
.filter(|&(_, variant)| !variant.attrs.skip_deserializing()) .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
.map(|(i, variant)| { .map(|(i, variant)| {
(variant.attrs.name().deserialize_name(), field_i(i), variant.attrs.aliases()) (
variant.attrs.name().deserialize_name(),
field_i(i),
variant.attrs.aliases(),
)
}) })
.collect(); .collect();
@@ -2049,7 +2059,7 @@ fn deserialize_identifier(
) = if collect_other_fields { ) = if collect_other_fields {
( (
Some(quote! { Some(quote! {
let __value = _serde::private::de::Content::String(__value.to_string()); let __value = _serde::private::de::Content::String(_serde::export::ToString::to_string(__value));
}), }),
Some(quote! { Some(quote! {
let __value = _serde::private::de::Content::Str(__value); let __value = _serde::private::de::Content::Str(__value);
@@ -2275,7 +2285,11 @@ fn deserialize_struct_as_struct_visitor(
.enumerate() .enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing()) .filter(|&(_, field)| !field.attrs.skip_deserializing())
.map(|(i, field)| { .map(|(i, field)| {
(field.attrs.name().deserialize_name(), field_i(i), field.attrs.aliases()) (
field.attrs.name().deserialize_name(),
field_i(i),
field.attrs.aliases(),
)
}) })
.collect(); .collect();
@@ -2304,7 +2318,11 @@ fn deserialize_struct_as_map_visitor(
.enumerate() .enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten()) .filter(|&(_, field)| !field.attrs.skip_deserializing() && !field.attrs.flatten())
.map(|(i, field)| { .map(|(i, field)| {
(field.attrs.name().deserialize_name(), field_i(i), field.attrs.aliases()) (
field.attrs.name().deserialize_name(),
field_i(i),
field.attrs.aliases(),
)
}) })
.collect(); .collect();
@@ -2372,7 +2390,12 @@ fn deserialize_map(
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
try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) {
_serde::export::Ok(__wrapper) => __wrapper.value,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
}) })
} }
}; };
@@ -2439,7 +2462,7 @@ fn deserialize_map(
let extract_collected = fields_names let extract_collected = fields_names
.iter() .iter()
.filter(|&&(field, _)| field.attrs.flatten()) .filter(|&&(field, _)| field.attrs.flatten() && !field.attrs.skip_deserializing())
.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() {
@@ -2459,7 +2482,9 @@ fn deserialize_map(
let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() { let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() {
Some(quote! { Some(quote! {
if let _serde::export::Some(_serde::export::Some((__key, _))) = __collect.into_iter().filter(|x| x.is_some()).next() { if let _serde::export::Some(_serde::export::Some((__key, _))) =
__collect.into_iter().filter(_serde::export::Option::is_some).next()
{
if let _serde::export::Some(__key) = __key.as_str() { if let _serde::export::Some(__key) = __key.as_str() {
return _serde::export::Err( return _serde::export::Err(
_serde::de::Error::custom(format_args!("unknown field `{}`", &__key))); _serde::de::Error::custom(format_args!("unknown field `{}`", &__key)));
@@ -2537,7 +2562,11 @@ fn deserialize_struct_as_struct_in_place_visitor(
.enumerate() .enumerate()
.filter(|&(_, field)| !field.attrs.skip_deserializing()) .filter(|&(_, field)| !field.attrs.skip_deserializing())
.map(|(i, field)| { .map(|(i, field)| {
(field.attrs.name().deserialize_name(), field_i(i), field.attrs.aliases()) (
field.attrs.name().deserialize_name(),
field_i(i),
field.attrs.aliases(),
)
}) })
.collect(); .collect();
@@ -2599,7 +2628,12 @@ fn deserialize_map_in_place(
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
self.place.#member = try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value self.place.#member = match _serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map) {
_serde::export::Ok(__wrapper) => __wrapper.value,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
};
}) })
} }
}; };
+19 -4
View File
@@ -1,8 +1,14 @@
use proc_macro2::{Ident, Span, TokenStream}; use proc_macro2::{Ident, Span, TokenStream};
use syn;
use try; use try;
pub fn wrap_in_const(trait_: &str, ty: &Ident, code: TokenStream) -> TokenStream { pub fn wrap_in_const(
serde_path: Option<&syn::Path>,
trait_: &str,
ty: &Ident,
code: TokenStream,
) -> TokenStream {
let try_replacement = try::replacement(); let try_replacement = try::replacement();
let dummy_const = Ident::new( let dummy_const = Ident::new(
@@ -10,13 +16,22 @@ pub fn wrap_in_const(trait_: &str, ty: &Ident, code: TokenStream) -> TokenStream
Span::call_site(), Span::call_site(),
); );
quote! { let use_serde = match serde_path {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)] Some(path) => quote! {
const #dummy_const: () = { use #path as _serde;
},
None => quote! {
#[allow(unknown_lints)] #[allow(unknown_lints)]
#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))] #[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
#[allow(rust_2018_idioms)] #[allow(rust_2018_idioms)]
extern crate serde as _serde; extern crate serde as _serde;
},
};
quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
#use_serde
#try_replacement #try_replacement
#code #code
}; };
+24 -2
View File
@@ -1,6 +1,7 @@
use internals::Ctxt; use internals::Ctxt;
use proc_macro2::{Group, Span, TokenStream, TokenTree}; use proc_macro2::{Group, Span, TokenStream, TokenTree};
use quote::ToTokens; use quote::ToTokens;
use std::borrow::Cow;
use std::collections::BTreeSet; use std::collections::BTreeSet;
use std::str::FromStr; use std::str::FromStr;
use syn; use syn;
@@ -116,8 +117,10 @@ impl<'c, T> VecAttr<'c, T> {
fn at_most_one(mut self) -> Result<Option<T>, ()> { fn at_most_one(mut self) -> Result<Option<T>, ()> {
if self.values.len() > 1 { if self.values.len() > 1 {
let dup_token = self.first_dup_tokens; let dup_token = self.first_dup_tokens;
self.cx self.cx.error_spanned_by(
.error_spanned_by(dup_token, format!("duplicate serde attribute `{}`", self.name)); dup_token,
format!("duplicate serde attribute `{}`", self.name),
);
Err(()) Err(())
} else { } else {
Ok(self.values.pop()) Ok(self.values.pop())
@@ -216,6 +219,7 @@ pub struct Container {
remote: Option<syn::Path>, remote: Option<syn::Path>,
identifier: Identifier, identifier: Identifier,
has_flatten: bool, has_flatten: bool,
serde_path: Option<syn::Path>,
} }
/// Styles of representing an enum. /// Styles of representing an enum.
@@ -296,6 +300,7 @@ impl Container {
let mut remote = Attr::none(cx, "remote"); let mut remote = Attr::none(cx, "remote");
let mut field_identifier = BoolAttr::none(cx, "field_identifier"); let mut field_identifier = BoolAttr::none(cx, "field_identifier");
let mut variant_identifier = BoolAttr::none(cx, "variant_identifier"); let mut variant_identifier = BoolAttr::none(cx, "variant_identifier");
let mut serde_path = Attr::none(cx, "crate");
for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) { for meta_items in item.attrs.iter().filter_map(get_serde_meta_items) {
for meta_item in meta_items { for meta_item in meta_items {
@@ -580,6 +585,13 @@ impl Container {
variant_identifier.set_true(word); variant_identifier.set_true(word);
} }
// Parse `#[serde(crate = "foo")]`
Meta(NameValue(ref m)) if m.ident == "crate" => {
if let Ok(path) = parse_lit_into_path(cx, &m.ident, &m.lit) {
serde_path.set(&m.ident, path)
}
}
Meta(ref meta_item) => { Meta(ref meta_item) => {
cx.error_spanned_by( cx.error_spanned_by(
meta_item.name(), meta_item.name(),
@@ -611,6 +623,7 @@ impl Container {
remote: remote.get(), remote: remote.get(),
identifier: decide_identifier(cx, item, field_identifier, variant_identifier), identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
has_flatten: false, has_flatten: false,
serde_path: serde_path.get(),
} }
} }
@@ -669,6 +682,15 @@ impl Container {
pub fn mark_has_flatten(&mut self) { pub fn mark_has_flatten(&mut self) {
self.has_flatten = true; self.has_flatten = true;
} }
pub fn custom_serde_path(&self) -> Option<&syn::Path> {
self.serde_path.as_ref()
}
pub fn serde_path(&self) -> Cow<syn::Path> {
self.custom_serde_path()
.map_or_else(|| Cow::Owned(parse_quote!(_serde)), Cow::Borrowed)
}
} }
fn decide_tag( fn decide_tag(
-19
View File
@@ -76,25 +76,6 @@ fn check_flatten_field(cx: &Ctxt, style: Style, field: &Field) {
} }
_ => {} _ => {}
} }
if field.attrs.skip_serializing() {
cx.error_spanned_by(
field.original,
"#[serde(flatten)] can not be combined with \
#[serde(skip_serializing)]",
);
} else if field.attrs.skip_serializing_if().is_some() {
cx.error_spanned_by(
field.original,
"#[serde(flatten)] can not be combined with \
#[serde(skip_serializing_if = \"...\")]",
);
} else if field.attrs.skip_deserializing() {
cx.error_spanned_by(
field.original,
"#[serde(flatten)] can not be combined with \
#[serde(skip_deserializing)]",
);
}
} }
/// The `other` attribute must be used at most once and it must be the last /// The `other` attribute must be used at most once and it must be the last
+3 -2
View File
@@ -13,14 +13,15 @@
//! //!
//! [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.85")] #![doc(html_root_url = "https://docs.rs/serde_derive/1.0.92")]
#![allow(unknown_lints, bare_trait_objects)]
#![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))]
// Ignored clippy lints // Ignored clippy lints
#![cfg_attr( #![cfg_attr(
feature = "cargo-clippy", feature = "cargo-clippy",
allow( allow(
cyclomatic_complexity, cognitive_complexity,
enum_variant_names, enum_variant_names,
needless_pass_by_value, needless_pass_by_value,
redundant_field_names, redundant_field_names,
+40 -25
View File
@@ -22,15 +22,16 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
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 body = Stmts(serialize_body(&cont, &params)); let body = Stmts(serialize_body(&cont, &params));
let serde = cont.attrs.serde_path();
let impl_block = if let Some(remote) = cont.attrs.remote() { let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis; let vis = &input.vis;
let used = pretend::pretend_used(&cont); let used = pretend::pretend_used(&cont);
quote! { quote! {
impl #impl_generics #ident #ty_generics #where_clause { impl #impl_generics #ident #ty_generics #where_clause {
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> #serde::export::Result<__S::Ok, __S::Error>
where where
__S: _serde::Serializer, __S: #serde::Serializer,
{ {
#used #used
#body #body
@@ -40,10 +41,10 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
} else { } else {
quote! { quote! {
#[automatically_derived] #[automatically_derived]
impl #impl_generics _serde::Serialize for #ident #ty_generics #where_clause { impl #impl_generics #serde::Serialize for #ident #ty_generics #where_clause {
fn serialize<__S>(&self, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error> fn serialize<__S>(&self, __serializer: __S) -> #serde::export::Result<__S::Ok, __S::Error>
where where
__S: _serde::Serializer, __S: #serde::Serializer,
{ {
#body #body
} }
@@ -51,7 +52,12 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
} }
}; };
Ok(dummy::wrap_in_const("SERIALIZE", ident, impl_block)) Ok(dummy::wrap_in_const(
cont.attrs.custom_serde_path(),
"SERIALIZE",
ident,
impl_block,
))
} }
fn precondition(cx: &Ctxt, cont: &Container) { fn precondition(cx: &Ctxt, cont: &Container) {
@@ -289,37 +295,38 @@ fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Contai
} }
} }
fn serialize_struct_tag_field(cattrs: &attr::Container, struct_trait: &StructTrait) -> TokenStream {
match *cattrs.tag() {
attr::TagType::Internal { ref tag } => {
let type_name = cattrs.name().serialize_name();
let func = struct_trait.serialize_field(Span::call_site());
quote! {
try!(#func(&mut __serde_state, #tag, #type_name));
}
}
_ => quote! {},
}
}
fn serialize_struct_as_struct( fn serialize_struct_as_struct(
params: &Parameters, params: &Parameters,
fields: &[Field], fields: &[Field],
cattrs: &attr::Container, cattrs: &attr::Container,
) -> Fragment { ) -> Fragment {
let mut serialize_fields = let 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() { let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeStruct);
attr::TagType::Internal { ref tag } => { let tag_field_exists = !tag_field.is_empty();
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() || additional_field_count > 0); let let_mut = mut_if(serialized_fields.peek().is_some() || tag_field_exists);
let len = serialized_fields let len = serialized_fields
.map(|field| match field.attrs.skip_serializing_if() { .map(|field| match field.attrs.skip_serializing_if() {
@@ -330,12 +337,13 @@ fn serialize_struct_as_struct(
} }
}) })
.fold( .fold(
quote!(#additional_field_count), quote!(#tag_field_exists as usize),
|sum, expr| quote!(#sum + #expr), |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));
#tag_field
#(#serialize_fields)* #(#serialize_fields)*
_serde::ser::SerializeStruct::end(__serde_state) _serde::ser::SerializeStruct::end(__serde_state)
} }
@@ -349,12 +357,15 @@ fn serialize_struct_as_map(
let serialize_fields = let serialize_fields =
serialize_struct_visitor(fields, params, false, &StructTrait::SerializeMap); serialize_struct_visitor(fields, params, false, &StructTrait::SerializeMap);
let tag_field = serialize_struct_tag_field(cattrs, &StructTrait::SerializeMap);
let tag_field_exists = !tag_field.is_empty();
let mut serialized_fields = fields 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() || tag_field_exists);
let len = if cattrs.has_flatten() { let len = if cattrs.has_flatten() {
quote!(_serde::export::None) quote!(_serde::export::None)
@@ -367,12 +378,16 @@ fn serialize_struct_as_map(
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!(#tag_field_exists as usize),
|sum, expr| quote!(#sum + #expr),
);
quote!(_serde::export::Some(#len)) quote!(_serde::export::Some(#len))
}; };
quote_block! { quote_block! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(__serializer, #len)); let #let_mut __serde_state = try!(_serde::Serializer::serialize_map(__serializer, #len));
#tag_field
#(#serialize_fields)* #(#serialize_fields)*
_serde::ser::SerializeMap::end(__serde_state) _serde::ser::SerializeMap::end(__serde_state)
} }
+1 -1
View File
@@ -2,7 +2,7 @@
name = "serde_derive_internals" name = "serde_derive_internals"
version = "0.24.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 OR 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"
+2 -1
View File
@@ -1,9 +1,10 @@
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.24.1")] #![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.24.1")]
#![allow(unknown_lints, bare_trait_objects)]
#![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, cognitive_complexity,
redundant_field_names, redundant_field_names,
trivially_copy_pass_by_ref trivially_copy_pass_by_ref
) )
+2 -2
View File
@@ -1,8 +1,8 @@
[package] [package]
name = "serde_test" name = "serde_test"
version = "1.0.85" # remember to update html_root_url version = "1.0.92" # 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 OR Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations" description = "Token De/Serializer for testing De/Serialize implementations"
homepage = "https://serde.rs" homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde" repository = "https://github.com/serde-rs/serde"
+1 -1
View File
@@ -144,7 +144,7 @@
//! # } //! # }
//! ``` //! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.85")] #![doc(html_root_url = "https://docs.rs/serde_test/1.0.92")]
#![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))]
// Ignored clippy lints // Ignored clippy lints
+5 -4
View File
@@ -7,14 +7,15 @@ publish = false
[features] [features]
unstable = ["serde/unstable"] unstable = ["serde/unstable"]
compiletest = ["compiletest_rs"]
[dependencies]
serde = { path = "../serde" }
[dev-dependencies] [dev-dependencies]
fnv = "1.0" fnv = "1.0"
rustc-serialize = "0.3.16" rustc-serialize = "0.3.16"
select-rustc = "0.1"
serde = { path = "../serde", features = ["rc", "derive"] } 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" }
trybuild = "1.0"
[dependencies]
compiletest_rs = { version = "0.3", optional = true, features = ["stable"] }
-11
View File
@@ -1,11 +0,0 @@
[package]
name = "serde_test_suite_deps"
version = "0.0.0"
authors = ["David Tolnay <dtolnay@gmail.com>"]
publish = false
[workspace]
[dependencies]
serde = { path = "../../serde" }
serde_derive = { path = "../../serde_derive" }
-3
View File
@@ -1,3 +0,0 @@
#![feature(/*=============================================]
#![=== Serde test suite requires a nightly compiler. ===]
#![====================================================*/)]
+4 -17
View File
@@ -1,20 +1,7 @@
#![cfg(feature = "compiletest")] #[cfg(not(target_os = "emscripten"))]
#[rustc::attr(not(nightly), ignore)]
use compiletest_rs as compiletest;
#[test] #[test]
fn ui() { fn ui() {
compiletest::run_tests(&compiletest::Config { let t = trybuild::TestCases::new();
mode: compiletest::common::Mode::Ui, t.compile_fail("tests/ui/**/*.rs");
src_base: std::path::PathBuf::from("tests/ui"),
target_rustcflags: Some(String::from(
"\
--edition=2018 \
-L deps/target/debug/deps \
-Z unstable-options \
--extern serde_derive \
",
)),
..Default::default()
});
} }
+18 -20
View File
@@ -574,7 +574,11 @@ fn test_rename_struct() {
); );
assert_de_tokens( assert_de_tokens(
&AliasStruct { a1: 1, a2: 2, a4: 3 }, &AliasStruct {
a1: 1,
a2: 2,
a4: 3,
},
&[ &[
Token::Struct { Token::Struct {
name: "AliasStruct", name: "AliasStruct",
@@ -591,7 +595,11 @@ fn test_rename_struct() {
); );
assert_de_tokens( assert_de_tokens(
&AliasStruct { a1: 1, a2: 2, a4: 3 }, &AliasStruct {
a1: 1,
a2: 2,
a4: 3,
},
&[ &[
Token::Struct { Token::Struct {
name: "AliasStruct", name: "AliasStruct",
@@ -665,7 +673,7 @@ enum AliasEnum {
b: i8, b: i8,
#[serde(alias = "e", rename = "f")] #[serde(alias = "e", rename = "f")]
d: i8, d: i8,
} },
} }
#[test] #[test]
@@ -756,11 +764,7 @@ fn test_rename_enum() {
); );
assert_de_tokens( assert_de_tokens(
&AliasEnum::SailorMoon { &AliasEnum::SailorMoon { a: 0, b: 1, d: 2 },
a: 0,
b: 1,
d: 2,
},
&[ &[
Token::StructVariant { Token::StructVariant {
name: "AliasEnum", name: "AliasEnum",
@@ -778,11 +782,7 @@ fn test_rename_enum() {
); );
assert_de_tokens( assert_de_tokens(
&AliasEnum::SailorMoon { &AliasEnum::SailorMoon { a: 0, b: 1, d: 2 },
a: 0,
b: 1,
d: 2,
},
&[ &[
Token::StructVariant { Token::StructVariant {
name: "AliasEnum", name: "AliasEnum",
@@ -803,13 +803,11 @@ fn test_rename_enum() {
#[test] #[test]
fn test_unknown_field_rename_enum() { fn test_unknown_field_rename_enum() {
assert_de_tokens_error::<AliasEnum>( assert_de_tokens_error::<AliasEnum>(
&[ &[Token::StructVariant {
Token::StructVariant { name: "AliasEnum",
name: "AliasEnum", variant: "SailorMoon",
variant: "SailorMoon", len: 3,
len: 3, }],
},
],
"unknown variant `SailorMoon`, expected `sailor_moon`", "unknown variant `SailorMoon`, expected `sailor_moon`",
); );
+18
View File
@@ -6,6 +6,7 @@ use std::default::Default;
use std::ffi::{CStr, CString, OsString}; use std::ffi::{CStr, CString, OsString};
use std::net; use std::net;
use std::num::Wrapping; use std::num::Wrapping;
use std::ops::Bound;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::rc::{Rc, Weak as RcWeak}; use std::rc::{Rc, Weak as RcWeak};
use std::sync::{Arc, Weak as ArcWeak}; use std::sync::{Arc, Weak as ArcWeak};
@@ -836,6 +837,23 @@ declare_tests! {
Token::SeqEnd, Token::SeqEnd,
], ],
} }
test_bound {
Bound::Unbounded::<()> => &[
Token::Enum { name: "Bound" },
Token::Str("Unbounded"),
Token::Unit,
],
Bound::Included(0) => &[
Token::Enum { name: "Bound" },
Token::Str("Included"),
Token::U8(0),
],
Bound::Excluded(0) => &[
Token::Enum { name: "Bound" },
Token::Str("Excluded"),
Token::U8(0),
],
}
test_path { test_path {
Path::new("/usr/local/lib") => &[ Path::new("/usr/local/lib") => &[
Token::BorrowedStr("/usr/local/lib"), Token::BorrowedStr("/usr/local/lib"),
+27 -1
View File
@@ -265,7 +265,7 @@ fn test_gen() {
#[cfg(feature = "unstable")] #[cfg(feature = "unstable")]
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct NonAsciiIdents { struct NonAsciiIdents {
σ: f64, σ: f64,
} }
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
@@ -522,6 +522,13 @@ fn test_gen() {
} }
assert::<FlattenWith>(); assert::<FlattenWith>();
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct FlattenDenyUnknown<T> {
#[serde(flatten)]
t: T,
}
#[derive(Serialize, Deserialize)] #[derive(Serialize, Deserialize)]
struct StaticStrStruct<'a> { struct StaticStrStruct<'a> {
a: &'a str, a: &'a str,
@@ -665,6 +672,25 @@ fn test_gen() {
ty: &'a str, ty: &'a str,
id: String, id: String,
} }
#[derive(Serialize, Deserialize)]
struct FlattenSkipSerializing<T> {
#[serde(flatten, skip_serializing)]
#[allow(dead_code)]
flat: T,
}
#[derive(Serialize, Deserialize)]
struct FlattenSkipSerializingIf<T> {
#[serde(flatten, skip_serializing_if = "StdOption::is_none")]
flat: StdOption<T>,
}
#[derive(Serialize, Deserialize)]
struct FlattenSkipDeserializing<T> {
#[serde(flatten, skip_deserializing)]
flat: T,
}
} }
////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////
+42
View File
@@ -1424,6 +1424,48 @@ fn test_internally_tagged_braced_struct_with_zero_fields() {
); );
} }
#[test]
fn test_internally_tagged_struct_with_flattened_field() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "tag_struct")]
pub struct Struct {
#[serde(flatten)]
pub flat: Enum,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "tag_enum", content = "content")]
pub enum Enum {
A(u64),
}
assert_tokens(
&Struct { flat: Enum::A(0) },
&[
Token::Map { len: None },
Token::Str("tag_struct"),
Token::Str("Struct"),
Token::Str("tag_enum"),
Token::Str("A"),
Token::Str("content"),
Token::U64(0),
Token::MapEnd,
],
);
assert_de_tokens(
&Struct { flat: Enum::A(0) },
&[
Token::Map { len: None },
Token::Str("tag_enum"),
Token::Str("A"),
Token::Str("content"),
Token::U64(0),
Token::MapEnd,
],
);
}
#[test] #[test]
fn test_enum_in_untagged_enum() { fn test_enum_in_untagged_enum() {
#[derive(Debug, PartialEq, Serialize, Deserialize)] #[derive(Debug, PartialEq, Serialize, Deserialize)]
+18
View File
@@ -6,6 +6,7 @@ use std::ffi::CString;
use std::mem; use std::mem;
use std::net; use std::net;
use std::num::Wrapping; use std::num::Wrapping;
use std::ops::Bound;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::rc::{Rc, Weak as RcWeak}; use std::rc::{Rc, Weak as RcWeak};
use std::sync::{Arc, Weak as ArcWeak}; use std::sync::{Arc, Weak as ArcWeak};
@@ -375,6 +376,23 @@ declare_tests! {
Token::StructEnd, Token::StructEnd,
], ],
} }
test_bound {
Bound::Unbounded::<()> => &[
Token::Enum { name: "Bound" },
Token::Str("Unbounded"),
Token::Unit,
],
Bound::Included(0u8) => &[
Token::Enum { name: "Bound" },
Token::Str("Included"),
Token::U8(0),
],
Bound::Excluded(0u8) => &[
Token::Enum { name: "Bound" },
Token::Str("Excluded"),
Token::U8(0),
],
}
test_path { test_path {
Path::new("/usr/local/lib") => &[ Path::new("/usr/local/lib") => &[
Token::Str("/usr/local/lib"), Token::Str("/usr/local/lib"),
+40
View File
@@ -0,0 +1,40 @@
#[test]
fn test_gen_custom_serde() {
#[derive(serde::Serialize, serde::Deserialize)]
#[serde(crate = "fake_serde")]
struct Foo;
// Would be overlapping if serde::Serialize were implemented
impl AssertNotSerdeSerialize for Foo {}
// Would be overlapping if serde::Deserialize were implemented
impl<'a> AssertNotSerdeDeserialize<'a> for Foo {}
fake_serde::assert::<Foo>();
}
mod fake_serde {
pub use serde::*;
pub fn assert<T>()
where
T: Serialize,
T: for<'a> Deserialize<'a>,
{
}
pub trait Serialize {
fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error>;
}
pub trait Deserialize<'a>: Sized {
fn deserialize<D: Deserializer<'a>>(deserializer: D) -> Result<Self, D::Error>;
}
}
trait AssertNotSerdeSerialize {}
impl<T: serde::Serialize> AssertNotSerdeSerialize for T {}
trait AssertNotSerdeDeserialize<'a> {}
impl<'a, T: serde::Deserialize<'a>> AssertNotSerdeDeserialize<'a> for T {}
+62 -2
View File
@@ -1,5 +1,8 @@
use serde::de::{value, IntoDeserializer}; use serde::de::value::{self, MapAccessDeserializer};
use serde::Deserialize; use serde::de::{IntoDeserializer, MapAccess, Visitor};
use serde::{Deserialize, Deserializer};
use serde_test::{assert_de_tokens, Token};
use std::fmt;
#[test] #[test]
fn test_u32_to_enum() { fn test_u32_to_enum() {
@@ -32,3 +35,60 @@ fn test_integer128() {
// i128 to i128 // i128 to i128
assert_eq!(1i128, i128::deserialize(de_i128).unwrap()); assert_eq!(1i128, i128::deserialize(de_i128).unwrap());
} }
#[test]
fn test_map_access_to_enum() {
#[derive(PartialEq, Debug)]
struct Potential(PotentialKind);
#[derive(PartialEq, Debug, Deserialize)]
enum PotentialKind {
Airebo(Airebo),
}
#[derive(PartialEq, Debug, Deserialize)]
struct Airebo {
lj_sigma: f64,
}
impl<'de> Deserialize<'de> for Potential {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct PotentialVisitor;
impl<'de> Visitor<'de> for PotentialVisitor {
type Value = Potential;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "a map")
}
fn visit_map<A>(self, map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
Deserialize::deserialize(MapAccessDeserializer::new(map)).map(Potential)
}
}
deserializer.deserialize_any(PotentialVisitor)
}
}
let expected = Potential(PotentialKind::Airebo(Airebo { lj_sigma: 14.0 }));
assert_de_tokens(
&expected,
&[
Token::Map { len: Some(1) },
Token::Str("Airebo"),
Token::Map { len: Some(1) },
Token::Str("lj_sigma"),
Token::F64(14.0),
Token::MapEnd,
Token::MapEnd,
],
);
}
@@ -3,6 +3,3 @@ error: failed to parse borrowed lifetimes: "zzz"
| |
5 | #[serde(borrow = "zzz")] 5 | #[serde(borrow = "zzz")]
| ^^^^^ | ^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: duplicate borrowed lifetime `'a`
| |
5 | #[serde(borrow = "'a + 'a")] 5 | #[serde(borrow = "'a + 'a")]
| ^^^^^^^^^ | ^^^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: duplicate serde attribute `borrow`
| |
8 | #[serde(borrow)] 8 | #[serde(borrow)]
| ^^^^^^ | ^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: at least one lifetime must be borrowed
| |
5 | #[serde(borrow = "")] 5 | #[serde(borrow = "")]
| ^^ | ^^
error: aborting due to previous error
@@ -4,6 +4,3 @@ error: field `s` has no lifetimes to borrow
5 | / #[serde(borrow)] 5 | / #[serde(borrow)]
6 | | s: String, 6 | | s: String,
| |_____________^ | |_____________^
error: aborting due to previous error
@@ -4,6 +4,3 @@ error: #[serde(borrow)] may only be used on newtype variants
8 | / #[serde(borrow)] 8 | / #[serde(borrow)]
9 | | S { s: Str<'a> }, 9 | | S { s: Str<'a> },
| |____________________^ | |____________________^
error: aborting due to previous error
@@ -4,6 +4,3 @@ error: field `s` does not have lifetime 'b
5 | / #[serde(borrow = "'b")] 5 | / #[serde(borrow = "'b")]
6 | | s: &'a str, 6 | | s: &'a str,
| |______________^ | |______________^
error: aborting due to previous error
@@ -7,6 +7,3 @@ error: enum tags `conflict` for type and content conflict with each other
7 | | B, 7 | | B,
8 | | } 8 | | }
| |_^ | |_^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(flatten)] cannot be used on newtype structs
| |
6 | struct Foo(#[serde(flatten)] HashMap<String, String>); 6 | struct Foo(#[serde(flatten)] HashMap<String, String>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
@@ -1,14 +0,0 @@
use serde_derive::Deserialize;
#[derive(Deserialize)]
struct Foo {
#[serde(flatten, skip_deserializing)]
other: Other,
}
#[derive(Deserialize)]
struct Other {
x: u32,
}
fn main() {}
@@ -1,9 +0,0 @@
error: #[serde(flatten)] can not be combined with #[serde(skip_deserializing)]
--> $DIR/flatten-skip-deserializing.rs:5:5
|
5 | / #[serde(flatten, skip_deserializing)]
6 | | other: Other,
| |________________^
error: aborting due to previous error
@@ -1,14 +0,0 @@
use serde_derive::Serialize;
#[derive(Serialize)]
struct Foo {
#[serde(flatten, skip_serializing_if = "Option::is_none")]
other: Option<Other>,
}
#[derive(Serialize)]
struct Other {
x: u32,
}
fn main() {}
@@ -1,9 +0,0 @@
error: #[serde(flatten)] can not be combined with #[serde(skip_serializing_if = "...")]
--> $DIR/flatten-skip-serializing-if.rs:5:5
|
5 | / #[serde(flatten, skip_serializing_if = "Option::is_none")]
6 | | other: Option<Other>,
| |________________________^
error: aborting due to previous error
@@ -1,14 +0,0 @@
use serde_derive::Serialize;
#[derive(Serialize)]
struct Foo {
#[serde(flatten, skip_serializing)]
other: Other,
}
#[derive(Serialize)]
struct Other {
x: u32,
}
fn main() {}
@@ -1,9 +0,0 @@
error: #[serde(flatten)] can not be combined with #[serde(skip_serializing)]
--> $DIR/flatten-skip-serializing.rs:5:5
|
5 | / #[serde(flatten, skip_serializing)]
6 | | other: Other,
| |________________^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(flatten)] cannot be used on tuple structs
| |
6 | struct Foo(u32, #[serde(flatten)] HashMap<String, String>); 6 | struct Foo(u32, #[serde(flatten)] HashMap<String, String>);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
@@ -9,6 +9,3 @@ error: variant field name `conflict` conflicts with internal tag
9 | | }, 9 | | },
10 | | } 10 | | }
| |_^ | |_^
error: aborting due to previous error
@@ -9,6 +9,3 @@ error: variant field name `conflict` conflicts with internal tag
9 | | }, 9 | | },
10 | | } 10 | | }
| |_^ | |_^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(default)] can only be used on structs with named fields
| |
5 | enum E { 5 | enum E {
| ^^^^ | ^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(default = "...")] can only be used on structs with named fields
| |
5 | enum E { 5 | enum E {
| ^^^^ | ^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(default)] can only be used on structs with named fields
| |
5 | struct T(u8, u8); 5 | struct T(u8, u8);
| ^^^^^^^^ | ^^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(default = "...")] can only be used on structs with named fields
| |
5 | struct T(u8, u8); 5 | struct T(u8, u8);
| ^^^^^^^^ | ^^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: unknown serde field attribute `serialize`
| |
5 | #[serde(rename = "x", serialize = "y")] 5 | #[serde(rename = "x", serialize = "y")]
| ^^^^^^^^^ | ^^^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: duplicate serde attribute `rename`
| |
5 | #[serde(rename(serialize = "x"), rename(serialize = "y"))] 5 | #[serde(rename(serialize = "x"), rename(serialize = "y"))]
| ^^^^^^ | ^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: duplicate serde attribute `rename`
| |
6 | #[serde(rename = "y")] 6 | #[serde(rename = "y")]
| ^^^^^^ | ^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: duplicate serde attribute `rename`
| |
5 | #[serde(rename(serialize = "x", serialize = "y"))] 5 | #[serde(rename(serialize = "x", serialize = "y"))]
| ^^^^^^^^^ | ^^^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: duplicate serde attribute `rename`
| |
6 | #[serde(rename(serialize = "y"))] 6 | #[serde(rename(serialize = "y"))]
| ^^^^^^ | ^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: duplicate serde attribute `serialize_with`
| |
5 | #[serde(with = "w", serialize_with = "s")] 5 | #[serde(with = "w", serialize_with = "s")]
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(tag = "...", content = "...")] must be used together
| |
4 | #[serde(content = "c")] 4 | #[serde(content = "c")]
| ^^^^^^^ | ^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(tag = "...")] cannot be used with tuple variants
| |
6 | Tuple(u8, u8), 6 | Tuple(u8, u8),
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: aborting due to previous error
@@ -15,6 +15,3 @@ error: untagged enum cannot have #[serde(tag = "...", content = "...")]
| |
5 | #[serde(tag = "t", content = "c")] 5 | #[serde(tag = "t", content = "c")]
| ^^^^^^^ | ^^^^^^^
error: aborting due to 3 previous errors
@@ -9,6 +9,3 @@ error: untagged enum cannot have #[serde(content = "...")]
| |
5 | #[serde(content = "c")] 5 | #[serde(content = "c")]
| ^^^^^^^ | ^^^^^^^
error: aborting due to 2 previous errors
@@ -9,6 +9,3 @@ error: enum cannot be both untagged and internally tagged
| |
5 | #[serde(tag = "type")] 5 | #[serde(tag = "type")]
| ^^^ | ^^^
error: aborting due to 2 previous errors
@@ -3,6 +3,3 @@ error: #[serde(untagged)] can only be used on enums
| |
5 | struct S; 5 | struct S;
| ^^^^^^ | ^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: expected serde rename attribute to be a string: `rename = "..."`
| |
5 | #[serde(rename = true)] 5 | #[serde(rename = true)]
| ^^^^ | ^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: expected serde rename attribute to be a string: `rename = "..."`
| |
5 | #[serde(rename = b'a')] 5 | #[serde(rename = b'a')]
| ^^^^ | ^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: expected serde rename attribute to be a string: `rename = "..."`
| |
5 | #[serde(rename = b"byte string")] 5 | #[serde(rename = b"byte string")]
| ^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: expected serde rename attribute to be a string: `rename = "..."`
| |
5 | #[serde(rename = 'a')] 5 | #[serde(rename = 'a')]
| ^^^ | ^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: expected serde rename attribute to be a string: `rename = "..."`
| |
5 | #[serde(rename = 3.14)] 5 | #[serde(rename = 3.14)]
| ^^^^ | ^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: expected serde rename attribute to be a string: `rename = "..."`
| |
5 | #[serde(rename = 100)] 5 | #[serde(rename = 100)]
| ^^^ | ^^^
error: aborting due to previous error
@@ -9,6 +9,3 @@ error: #[serde(field_identifier)] and #[serde(variant_identifier)] cannot both b
| |
4 | #[serde(field_identifier, variant_identifier)] 4 | #[serde(field_identifier, variant_identifier)]
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
error: aborting due to 2 previous errors
@@ -3,6 +3,3 @@ error: #[serde(field_identifier)] can only be used on an enum
| |
5 | struct S; 5 | struct S;
| ^^^^^^ | ^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(field_identifier)] may only contain unit variants
| |
7 | B(u8, u8), 7 | B(u8, u8),
| ^^^^^^^^^ | ^^^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: `Other` must be the last variant
| |
7 | Other(String), 7 | Other(String),
| ^^^^^^^^^^^^^ | ^^^^^^^^^^^^^
error: aborting due to previous error
@@ -4,6 +4,3 @@ error: #[serde(other)] must be on a unit variant
7 | / #[serde(other)] 7 | / #[serde(other)]
8 | | Other(u8, u8), 8 | | Other(u8, u8),
| |_________________^ | |_________________^
error: aborting due to previous error
@@ -4,6 +4,3 @@ error: #[serde(other)] must be on the last variant
7 | / #[serde(other)] 7 | / #[serde(other)]
8 | | Other, 8 | | Other,
| |_________^ | |_________^
error: aborting due to previous error
@@ -4,6 +4,3 @@ error: #[serde(other)] cannot appear on untagged enum
6 | / #[serde(other)] 6 | / #[serde(other)]
7 | | Other, 7 | | Other,
| |_________^ | |_________^
error: aborting due to previous error
@@ -4,6 +4,3 @@ error: #[serde(other)] may not be used on a variant identifier
6 | / #[serde(other)] 6 | / #[serde(other)]
7 | | Other, 7 | | Other,
| |_________^ | |_________^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(variant_identifier)] can only be used on an enum
| |
5 | struct S; 5 | struct S;
| ^^^^^^ | ^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: #[serde(variant_identifier)] may only contain unit variants
| |
7 | B(u8, u8), 7 | B(u8, u8),
| ^^^^^^^^^ | ^^^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: malformed bound attribute, expected `bound(serialize = ..., deserialize =
| |
5 | #[serde(bound(unknown))] 5 | #[serde(bound(unknown))]
| ^^^^^^^ | ^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: malformed rename attribute, expected `rename(serialize = ..., deserialize
| |
5 | #[serde(rename(unknown))] 5 | #[serde(rename(unknown))]
| ^^^^^^^ | ^^^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: cannot deserialize when there is a lifetime parameter called 'de
| |
4 | struct S<'de> { 4 | struct S<'de> {
| ^^^ | ^^^
error: aborting due to previous error
@@ -6,6 +6,3 @@ error: cannot deserialize a dynamically sized struct
6 | | slice: [u8], 6 | | slice: [u8],
7 | | } 7 | | }
| |_^ | |_^
error: aborting due to previous error
@@ -7,6 +7,3 @@ error: field identifiers cannot be serialized
7 | | B, 7 | | B,
8 | | } 8 | | }
| |_^ | |_^
error: aborting due to previous error
@@ -7,6 +7,3 @@ error: variant identifiers cannot be serialized
7 | | B, 7 | | B,
8 | | } 8 | | }
| |_^ | |_^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: failed to parse path: "~~~"
| |
12 | #[serde(getter = "~~~")] 12 | #[serde(getter = "~~~")]
| ^^^^^ | ^^^^^
error: aborting due to previous error
@@ -3,6 +3,3 @@ error: failed to parse path: "~~~"
| |
10 | #[serde(remote = "~~~")] 10 | #[serde(remote = "~~~")]
| ^^^^^ | ^^^^^
error: aborting due to previous error
@@ -9,6 +9,3 @@ error: #[serde(getter = "...")] is not allowed in an enum
15 | | }, 15 | | },
16 | | } 16 | | }
| |_^ | |_^
error: aborting due to previous error
@@ -4,6 +4,4 @@ error[E0063]: missing field `b` in initializer of `remote::S`
11 | #[serde(remote = "remote::S")] 11 | #[serde(remote = "remote::S")]
| ^^^^^^^^^^^ missing `b` | ^^^^^^^^^^^ missing `b`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0063`. For more information about this error, try `rustc --explain E0063`.
@@ -6,6 +6,3 @@ error: #[serde(getter = "...")] can only be used in structs that have #[serde(re
6 | | a: u8, 6 | | a: u8,
7 | | } 7 | | }
| |_^ | |_^
error: aborting due to previous error
@@ -10,7 +10,5 @@ error[E0560]: struct `remote::S` has no field named `b`
12 | b: u8, 12 | b: u8,
| ^ help: a field with a similar name exists: `a` | ^ help: a field with a similar name exists: `a`
error: aborting due to 2 previous errors Some errors have detailed explanations: E0560, E0609.
Some errors occurred: E0560, E0609.
For more information about an error, try `rustc --explain E0560`. For more information about an error, try `rustc --explain E0560`.
@@ -3,11 +3,5 @@ error[E0308]: mismatched types
| |
7 | #[derive(Deserialize)] 7 | #[derive(Deserialize)]
| ^^^^^^^^^^^ expected u16, found u8 | ^^^^^^^^^^^ expected u16, found u8
help: you can cast an `u8` to `u16`, which will zero-extend the source value
|
7 | #[derive(Deserialize.into())]
| ^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`. For more information about this error, try `rustc --explain E0308`.
@@ -7,6 +7,4 @@ error[E0308]: mismatched types
= note: expected type `&u8` = note: expected type `&u8`
found type `&u16` found type `&u16`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`. For more information about this error, try `rustc --explain E0308`.
@@ -7,6 +7,4 @@ error[E0308]: mismatched types
= note: expected type `&u8` = note: expected type `&u8`
found type `&u16` found type `&u16`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0308`. For more information about this error, try `rustc --explain E0308`.

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