Compare commits

...

102 Commits

Author SHA1 Message Date
David Tolnay 108cca687c Release 1.0.77 2018-09-06 21:36:27 -07:00
David Tolnay bca8c115c7 Merge pull request #1372 from dtolnay/syn
Update to syn 0.15
2018-09-06 21:34:14 -07:00
David Tolnay b49bd52a53 Use parse_macro_input to report parse errors 2018-09-06 21:16:12 -07:00
David Tolnay 27bd640812 Update to syn 0.15 2018-09-06 21:16:08 -07:00
David Tolnay 8d5cda8464 Merge pull request #1376 from dreid/fix-internally-tagged-enum-deserialization-with-unknown-fields
Fix internally tagged enum deserialization with unknown fields
2018-09-06 21:10:41 -07:00
David Reid 389b9b5fe7 Add a test for an internally tagged unit enum flattened with a second internally tagged unit enum. 2018-09-06 14:55:10 -07:00
David Reid 27478b6f71 Internally tagged unit enum variants should ignore unknown fields. 2018-09-06 14:29:49 -07:00
David Tolnay 480f858fc3 Update panic_handler attribute name changed in nightly 2018-09-03 08:24:27 -07:00
David Tolnay 7d752c5a60 Merge pull request #1373 from dtolnay/emscripten
Add Emscripten build in Travis
2018-09-02 13:56:41 -07:00
David Tolnay 33b7841300 Skip asmjs 2018-09-02 13:21:36 -07:00
David Tolnay 2244b92eb0 Nvm install in .travis.yml
The one in travis.sh was failing:

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

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

which is swallowed and ignored by compiletest.

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

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

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

    #[derive(Deserialize)]
    struct S {
        // Looks at fields with a "player1_" prefix.
        #[serde(flatten, with = "prefix_player1")]
        player1: Player,
        // Looks at fields with a "player2_" prefix.
        #[serde(flatten, with = "prefix_player2")]
        player2: Player,
    }
2018-06-01 12:50:23 -07:00
David Tolnay ca53daf697 Fix RefCell serialize impl to work with no-std 2018-06-01 12:47:10 -07:00
Konrad Borowski c3b9ee314b Use try_borrow for serializing RefCell 2018-06-01 09:09:40 +02:00
Adam Crume 993710eb16 Use compile_error! instead of panicking
Fixes #1168
2018-05-31 19:57:23 -07:00
David Tolnay dbaf2893e3 Release 1.0.64 2018-05-30 00:17:45 -07:00
David Tolnay 34a7108b73 Second attempt at workaround for docs.rs compiler 2018-05-30 00:17:02 -07:00
David Tolnay db2bafd3f3 Revert "Work around docs.rs using an old 1.26-dev compiler"
This reverts commit c81bab18ad.
2018-05-30 00:13:20 -07:00
111 changed files with 1310 additions and 651 deletions
+9 -2
View File
@@ -4,15 +4,22 @@ cache: cargo
# run builds for all the trains (and more)
rust:
- 1.13.0
- 1.15.0
- stable
- beta
- nightly
- 1.13.0
- 1.15.0
- 1.20.0
- 1.21.0
- 1.25.0
- 1.26.0
matrix:
include:
- rust: nightly
env: CLIPPY=true
- rust: nightly
env: EMSCRIPTEN=true
script: nvm install 9 && ./travis.sh
script: ./travis.sh
+7 -6
View File
@@ -79,12 +79,13 @@ fn main() {
## Getting help
Serde developers live in the #serde channel on
[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a
good resource with generally faster response time but less specific knowledge
about Serde. If IRC is not your thing or you don't get a good response, we are
happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new)
as well.
Serde developers live in the #serde channel on [`irc.mozilla.org`][irc]. The
\#rust channel is also a good resource with generally faster response time but
less specific knowledge about Serde. If IRC is not your thing or you don't get a
good response, we are happy to respond to [GitHub issues][issues] as well.
[irc]: https://wiki.mozilla.org/IRC
[issues]: https://github.com/serde-rs/serde/issues/new/choose
## License
+7 -6
View File
@@ -47,9 +47,10 @@ fn main() {
## Getting help
Serde developers live in the #serde channel on
[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a
good resource with generally faster response time but less specific knowledge
about Serde. If IRC is not your thing or you don't get a good response, we are
happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new)
as well.
Serde developers live in the #serde channel on [`irc.mozilla.org`][irc]. The
\#rust channel is also a good resource with generally faster response time but
less specific knowledge about Serde. If IRC is not your thing or you don't get a
good response, we are happy to respond to [GitHub issues][issues] as well.
[irc]: https://wiki.mozilla.org/IRC
[issues]: https://github.com/serde-rs/serde/issues/new/choose
+1 -6
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.63" # remember to update html_root_url
version = "1.0.77" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
@@ -23,11 +23,6 @@ serde_derive = { version = "1.0", optional = true, path = "../serde_derive" }
[dev-dependencies]
serde_derive = { version = "1.0", path = "../serde_derive" }
[package.metadata.docs.rs]
# Temporary cfg to work around docs.rs using an old 1.26-dev compiler.
rustc-args = ["--cfg", "serde_docs_rs"]
rustdoc-args = ["--cfg", "serde_docs_rs"]
### FEATURES #################################################################
+24 -1
View File
@@ -11,6 +11,9 @@ fn main() {
None => return,
};
let target = env::var("TARGET").unwrap();
let emscripten = target == "asmjs-unknown-emscripten" || target == "wasm32-unknown-emscripten";
// CString::into_boxed_c_str stabilized in Rust 1.20:
// https://doc.rust-lang.org/std/ffi/struct.CString.html#method.into_boxed_c_str
if minor >= 20 {
@@ -24,12 +27,27 @@ fn main() {
println!("cargo:rustc-cfg=de_rc_dst");
}
// Duration available in core since Rust 1.25:
// https://blog.rust-lang.org/2018/03/29/Rust-1.25.html#library-stabilizations
if minor >= 25 {
println!("cargo:rustc-cfg=core_duration");
}
// 128-bit integers stabilized in Rust 1.26:
// https://blog.rust-lang.org/2018/05/10/Rust-1.26.html
if minor >= 26 {
//
// Disabled on Emscripten targets as Emscripten doesn't
// currently support integers larger than 64 bits.
if minor >= 26 && !emscripten {
println!("cargo:rustc-cfg=integer128");
}
// Inclusive ranges methods stabilized in Rust 1.27:
// https://github.com/rust-lang/rust/pull/50758
if minor >= 27 {
println!("cargo:rustc-cfg=range_inclusive");
}
// Non-zero integers stabilized in Rust 1.28:
// https://github.com/rust-lang/rust/pull/50808
if minor >= 28 {
@@ -53,6 +71,11 @@ fn rustc_minor_version() -> Option<u32> {
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('.');
if pieces.next() != Some("rustc 1") {
return None;
+8 -2
View File
@@ -20,7 +20,9 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// use std::fmt;
/// use std::marker::PhantomData;
///
/// use serde::de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess, IgnoredAny};
/// use serde::de::{
/// self, Deserialize, DeserializeSeed, Deserializer, IgnoredAny, SeqAccess, Visitor,
/// };
///
/// /// A seed that can be used to deserialize only the `n`th element of a sequence
/// /// while efficiently discarding elements of any type before or after index `n`.
@@ -51,7 +53,11 @@ use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
/// type Value = T;
///
/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// write!(formatter, "a sequence in which we care about element {}", self.n)
/// write!(
/// formatter,
/// "a sequence in which we care about element {}",
/// self.n
/// )
/// }
///
/// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
+281 -150
View File
@@ -12,7 +12,7 @@ use de::{
Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess, Visitor,
};
#[cfg(any(feature = "std", feature = "alloc"))]
#[cfg(any(core_duration, feature = "std", feature = "alloc"))]
use de::MapAccess;
use de::from_primitive::FromPrimitive;
@@ -49,6 +49,16 @@ impl<'de> Deserialize<'de> for () {
}
}
#[cfg(feature = "unstable")]
impl<'de> Deserialize<'de> for ! {
fn deserialize<D>(_deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Err(Error::custom("cannot deserialize `!`"))
}
}
////////////////////////////////////////////////////////////////////////////////
struct BoolVisitor;
@@ -1172,15 +1182,31 @@ map_impl!(
#[cfg(feature = "std")]
macro_rules! parse_ip_impl {
($ty:ty; $size:expr) => {
($expecting:tt $ty:ty; $size:tt) => {
impl<'de> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = try!(String::deserialize(deserializer));
s.parse().map_err(Error::custom)
struct IpAddrVisitor;
impl<'de> Visitor<'de> for IpAddrVisitor {
type Value = $ty;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str($expecting)
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
s.parse().map_err(Error::custom)
}
}
deserializer.deserialize_str(IpAddrVisitor)
} else {
<[u8; $size]>::deserialize(deserializer).map(<$ty>::from)
}
@@ -1308,8 +1334,24 @@ impl<'de> Deserialize<'de> for net::IpAddr {
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = try!(String::deserialize(deserializer));
s.parse().map_err(Error::custom)
struct IpAddrVisitor;
impl<'de> Visitor<'de> for IpAddrVisitor {
type Value = net::IpAddr;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("IP address")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
s.parse().map_err(Error::custom)
}
}
deserializer.deserialize_str(IpAddrVisitor)
} else {
use lib::net::IpAddr;
deserialize_enum!{
@@ -1322,22 +1364,38 @@ impl<'de> Deserialize<'de> for net::IpAddr {
}
#[cfg(feature = "std")]
parse_ip_impl!(net::Ipv4Addr; 4);
parse_ip_impl!("IPv4 address" net::Ipv4Addr; 4);
#[cfg(feature = "std")]
parse_ip_impl!(net::Ipv6Addr; 16);
parse_ip_impl!("IPv6 address" net::Ipv6Addr; 16);
#[cfg(feature = "std")]
macro_rules! parse_socket_impl {
($ty:ty, $new:expr) => {
($expecting:tt $ty:ty, $new:expr) => {
impl<'de> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = try!(String::deserialize(deserializer));
s.parse().map_err(Error::custom)
struct SocketAddrVisitor;
impl<'de> Visitor<'de> for SocketAddrVisitor {
type Value = $ty;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str($expecting)
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
s.parse().map_err(Error::custom)
}
}
deserializer.deserialize_str(SocketAddrVisitor)
} else {
<(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port))
}
@@ -1353,8 +1411,24 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
D: Deserializer<'de>,
{
if deserializer.is_human_readable() {
let s = try!(String::deserialize(deserializer));
s.parse().map_err(Error::custom)
struct SocketAddrVisitor;
impl<'de> Visitor<'de> for SocketAddrVisitor {
type Value = net::SocketAddr;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("socket address")
}
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
s.parse().map_err(Error::custom)
}
}
deserializer.deserialize_str(SocketAddrVisitor)
} else {
use lib::net::SocketAddr;
deserialize_enum!{
@@ -1367,10 +1441,10 @@ impl<'de> Deserialize<'de> for net::SocketAddr {
}
#[cfg(feature = "std")]
parse_socket_impl!(net::SocketAddrV4, net::SocketAddrV4::new);
parse_socket_impl!("IPv4 socket address" net::SocketAddrV4, net::SocketAddrV4::new);
#[cfg(feature = "std")]
parse_socket_impl!(net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(
parse_socket_impl!("IPv6 socket address" net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(
ip, port, 0, 0
));
@@ -1528,7 +1602,11 @@ forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice);
#[cfg(any(feature = "std", feature = "alloc"))]
forwarded_impl!((), Box<str>, String::into_boxed_str);
#[cfg(all(not(de_rc_dst), feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg(all(
not(de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1540,7 +1618,11 @@ forwarded_impl! {
(T), Arc<T>, Arc::new
}
#[cfg(all(not(de_rc_dst), feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg(all(
not(de_rc_dst),
feature = "rc",
any(feature = "std", feature = "alloc")
))]
forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1607,7 +1689,11 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg(all(
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
))]
macro_rules! box_forwarded_impl {
(
$(#[doc = $doc:tt])*
@@ -1628,7 +1714,11 @@ macro_rules! box_forwarded_impl {
};
}
#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg(all(
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
))]
box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1640,7 +1730,11 @@ box_forwarded_impl! {
Rc
}
#[cfg(all(de_rc_dst, feature = "rc", any(feature = "std", feature = "alloc")))]
#[cfg(all(
de_rc_dst,
feature = "rc",
any(feature = "std", feature = "alloc")
))]
box_forwarded_impl! {
/// This impl requires the [`"rc"`] Cargo feature of Serde.
///
@@ -1684,7 +1778,7 @@ forwarded_impl!((T), RwLock<T>, RwLock::new);
// secs: u64,
// nanos: u32,
// }
#[cfg(feature = "std")]
#[cfg(any(core_duration, feature = "std"))]
impl<'de> Deserialize<'de> for Duration {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
@@ -1732,7 +1826,7 @@ impl<'de> Deserialize<'de> for Duration {
b"secs" => Ok(Field::Secs),
b"nanos" => Ok(Field::Nanos),
_ => {
let value = String::from_utf8_lossy(value);
let value = ::export::from_utf8_lossy(value);
Err(Error::unknown_field(&value, FIELDS))
}
}
@@ -1950,8 +2044,7 @@ impl<'de> Deserialize<'de> for SystemTime {
// start: u64,
// end: u32,
// }
#[cfg(feature = "std")]
impl<'de, Idx> Deserialize<'de> for ops::Range<Idx>
impl<'de, Idx> Deserialize<'de> for Range<Idx>
where
Idx: Deserialize<'de>,
{
@@ -1959,134 +2052,165 @@ where
where
D: Deserializer<'de>,
{
// If this were outside of the serde crate, it would just use:
//
// #[derive(Deserialize)]
// #[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Start,
End,
};
impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`start` or `end`")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"start" => Ok(Field::Start),
"end" => Ok(Field::End),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"start" => Ok(Field::Start),
b"end" => Ok(Field::End),
_ => {
let value = String::from_utf8_lossy(value);
Err(Error::unknown_field(&value, FIELDS))
}
}
}
}
deserializer.deserialize_identifier(FieldVisitor)
}
}
struct RangeVisitor<Idx> {
phantom: PhantomData<Idx>,
}
impl<'de, Idx> Visitor<'de> for RangeVisitor<Idx>
where
Idx: Deserialize<'de>,
{
type Value = ops::Range<Idx>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("struct Range")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let start: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
};
let end: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(1, &self));
}
};
Ok(start..end)
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut start: Option<Idx> = None;
let mut end: Option<Idx> = None;
while let Some(key) = try!(map.next_key()) {
match key {
Field::Start => {
if start.is_some() {
return Err(<A::Error as Error>::duplicate_field("start"));
}
start = Some(try!(map.next_value()));
}
Field::End => {
if end.is_some() {
return Err(<A::Error as Error>::duplicate_field("end"));
}
end = Some(try!(map.next_value()));
}
}
}
let start = match start {
Some(start) => start,
None => return Err(<A::Error as Error>::missing_field("start")),
};
let end = match end {
Some(end) => end,
None => return Err(<A::Error as Error>::missing_field("end")),
};
Ok(start..end)
}
}
const FIELDS: &'static [&'static str] = &["start", "end"];
deserializer.deserialize_struct(
let (start, end) = deserializer.deserialize_struct(
"Range",
FIELDS,
RangeVisitor {
range::FIELDS,
range::RangeVisitor {
expecting: "struct Range",
phantom: PhantomData,
},
)
)?;
Ok(start..end)
}
}
#[cfg(range_inclusive)]
impl<'de, Idx> Deserialize<'de> for RangeInclusive<Idx>
where
Idx: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let (start, end) = deserializer.deserialize_struct(
"RangeInclusive",
range::FIELDS,
range::RangeVisitor {
expecting: "struct RangeInclusive",
phantom: PhantomData,
},
)?;
Ok(RangeInclusive::new(start, end))
}
}
mod range {
use lib::*;
use de::{Deserialize, Deserializer, Error, MapAccess, SeqAccess, Visitor};
pub const FIELDS: &'static [&'static str] = &["start", "end"];
// If this were outside of the serde crate, it would just use:
//
// #[derive(Deserialize)]
// #[serde(field_identifier, rename_all = "lowercase")]
enum Field {
Start,
End,
}
impl<'de> Deserialize<'de> for Field {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct FieldVisitor;
impl<'de> Visitor<'de> for FieldVisitor {
type Value = Field;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("`start` or `end`")
}
fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
where
E: Error,
{
match value {
"start" => Ok(Field::Start),
"end" => Ok(Field::End),
_ => Err(Error::unknown_field(value, FIELDS)),
}
}
fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
match value {
b"start" => Ok(Field::Start),
b"end" => Ok(Field::End),
_ => {
let value = ::export::from_utf8_lossy(value);
Err(Error::unknown_field(&value, FIELDS))
}
}
}
}
deserializer.deserialize_identifier(FieldVisitor)
}
}
pub struct RangeVisitor<Idx> {
pub expecting: &'static str,
pub phantom: PhantomData<Idx>,
}
impl<'de, Idx> Visitor<'de> for RangeVisitor<Idx>
where
Idx: Deserialize<'de>,
{
type Value = (Idx, Idx);
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(self.expecting)
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let start: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(0, &self));
}
};
let end: Idx = match try!(seq.next_element()) {
Some(value) => value,
None => {
return Err(Error::invalid_length(1, &self));
}
};
Ok((start, end))
}
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
let mut start: Option<Idx> = None;
let mut end: Option<Idx> = None;
while let Some(key) = try!(map.next_key()) {
match key {
Field::Start => {
if start.is_some() {
return Err(<A::Error as Error>::duplicate_field("start"));
}
start = Some(try!(map.next_value()));
}
Field::End => {
if end.is_some() {
return Err(<A::Error as Error>::duplicate_field("end"));
}
end = Some(try!(map.next_value()));
}
}
}
let start = match start {
Some(start) => start,
None => return Err(<A::Error as Error>::missing_field("start")),
};
let end = match end {
Some(end) => end,
None => return Err(<A::Error as Error>::missing_field("end")),
};
Ok((start, end))
}
}
}
@@ -2118,10 +2242,17 @@ nonzero_integers! {
NonZeroU16,
NonZeroU32,
NonZeroU64,
// FIXME: https://github.com/serde-rs/serde/issues/1136 NonZeroU128,
NonZeroUsize,
}
// Currently 128-bit integers do not work on Emscripten targets so we need an
// additional `#[cfg]`
serde_if_integer128! {
nonzero_integers! {
NonZeroU128,
}
}
////////////////////////////////////////////////////////////////////////////////
impl<'de, T, E> Deserialize<'de> for Result<T, E>
+32 -32
View File
@@ -24,8 +24,7 @@
//!
//! Additionally, Serde provides a procedural macro called [`serde_derive`] to
//! automatically generate [`Deserialize`] implementations for structs and enums
//! in your program. See the [codegen section of the manual] for how to use
//! this.
//! in your program. See the [derive section of the manual] for how to use this.
//!
//! In rare cases it may be necessary to implement [`Deserialize`] manually for
//! some type in your program. See the [Implementing `Deserialize`] section of
@@ -97,7 +96,9 @@
//! - Path
//! - PathBuf
//! - Range\<T\>
//! - RangeInclusive\<T\>
//! - num::NonZero*
//! - `!` *(unstable)*
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
@@ -115,7 +116,7 @@
//! [`serde_derive`]: https://crates.io/crates/serde_derive
//! [`serde_json`]: https://github.com/serde-rs/json
//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml
//! [codegen section of the manual]: https://serde.rs/codegen.html
//! [derive section of the manual]: https://serde.rs/derive.html
//! [data formats]: https://serde.rs/#data-formats
use lib::*;
@@ -496,7 +497,7 @@ impl<'a> Display for Expected + 'a {
///
/// Additionally, Serde provides a procedural macro called `serde_derive` to
/// automatically generate `Deserialize` implementations for structs and enums
/// in your program. See the [codegen section of the manual][codegen] for how to
/// in your program. See the [derive section of the manual][derive] for how to
/// use this.
///
/// In rare cases it may be necessary to implement `Deserialize` manually for
@@ -509,7 +510,7 @@ impl<'a> Display for Expected + 'a {
/// provides an implementation of `Deserialize` for it.
///
/// [de]: https://docs.serde.rs/serde/de/index.html
/// [codegen]: https://serde.rs/codegen.html
/// [derive]: https://serde.rs/derive.html
/// [impl-deserialize]: https://serde.rs/impl-deserialize.html
///
/// # Lifetime
@@ -592,11 +593,7 @@ pub trait Deserialize<'de>: Sized {
///
/// [Understanding deserializer lifetimes]: https://serde.rs/lifetimes.html
pub trait DeserializeOwned: for<'de> Deserialize<'de> {}
impl<T> DeserializeOwned for T
where
T: for<'de> Deserialize<'de>,
{
}
impl<T> DeserializeOwned for T where T: for<'de> Deserialize<'de> {}
/// `DeserializeSeed` is the stateful form of the `Deserialize` trait. If you
/// ever find yourself looking for a way to pass data into a `Deserialize` impl,
@@ -662,7 +659,7 @@ where
/// use std::fmt;
/// use std::marker::PhantomData;
///
/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess};
/// use serde::de::{Deserialize, DeserializeSeed, Deserializer, SeqAccess, Visitor};
///
/// // A DeserializeSeed implementation that uses stateful deserialization to
/// // append array elements onto the end of an existing vector. The preexisting
@@ -809,16 +806,16 @@ where
/// - When serializing, all strings are handled equally. When deserializing,
/// there are three flavors of strings: transient, owned, and borrowed.
/// - **byte array** - \[u8\]
/// - Similar to strings, during deserialization byte arrays can be transient,
/// owned, or borrowed.
/// - Similar to strings, during deserialization byte arrays can be
/// transient, owned, or borrowed.
/// - **option**
/// - Either none or some value.
/// - **unit**
/// - The type of `()` in Rust. It represents an anonymous value containing no
/// data.
/// - The type of `()` in Rust. It represents an anonymous value containing
/// no data.
/// - **unit_struct**
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named value
/// containing no data.
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named
/// value containing no data.
/// - **unit_variant**
/// - For example the `E::A` and `E::B` in `enum E { A, B }`.
/// - **newtype_struct**
@@ -826,14 +823,15 @@ where
/// - **newtype_variant**
/// - For example the `E::N` in `enum E { N(u8) }`.
/// - **seq**
/// - A variably sized heterogeneous sequence of values, for example `Vec<T>` or
/// `HashSet<T>`. When serializing, the length may or may not be known before
/// iterating through all the data. When deserializing, the length is determined
/// by looking at the serialized data.
/// - A variably sized heterogeneous sequence of values, for example `Vec<T>`
/// or `HashSet<T>`. When serializing, the length may or may not be known
/// before iterating through all the data. When deserializing, the length
/// is determined by looking at the serialized data.
/// - **tuple**
/// - A statically sized heterogeneous sequence of values for which the length
/// will be known at deserialization time without looking at the serialized
/// data, for example `(u8,)` or `(String, u64, Vec<T>)` or `[u64; 10]`.
/// - A statically sized heterogeneous sequence of values for which the
/// length will be known at deserialization time without looking at the
/// serialized data, for example `(u8,)` or `(String, u64, Vec<T>)` or
/// `[u64; 10]`.
/// - **tuple_struct**
/// - A named tuple, for example `struct Rgb(u8, u8, u8)`.
/// - **tuple_variant**
@@ -841,9 +839,9 @@ where
/// - **map**
/// - A heterogeneous key-value pairing, for example `BTreeMap<K, V>`.
/// - **struct**
/// - A heterogeneous key-value pairing in which the keys are strings and will be
/// known at deserialization time without looking at the serialized data, for
/// example `struct S { r: u8, g: u8, b: u8 }`.
/// - A heterogeneous key-value pairing in which the keys are strings and
/// will be known at deserialization time without looking at the serialized
/// data, for example `struct S { r: u8, g: u8, b: u8 }`.
/// - **struct_variant**
/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
///
@@ -858,7 +856,8 @@ where
/// type it sees in the input. JSON uses this approach when deserializing
/// `serde_json::Value` which is an enum that can represent any JSON
/// document. Without knowing what is in a JSON document, we can deserialize
/// it to `serde_json::Value` by going through `Deserializer::deserialize_any`.
/// it to `serde_json::Value` by going through
/// `Deserializer::deserialize_any`.
///
/// 2. The various `deserialize_*` methods. Non-self-describing formats like
/// Bincode need to be told what is in the input in order to deserialize it.
@@ -868,10 +867,11 @@ where
/// `Deserializer::deserialize_any`.
///
/// When implementing `Deserialize`, you should avoid relying on
/// `Deserializer::deserialize_any` unless you need to be told by the Deserializer
/// what type is in the input. Know that relying on `Deserializer::deserialize_any`
/// means your data type will be able to deserialize from self-describing
/// formats only, ruling out Bincode and many others.
/// `Deserializer::deserialize_any` unless you need to be told by the
/// Deserializer what type is in the input. Know that relying on
/// `Deserializer::deserialize_any` means your data type will be able to
/// deserialize from self-describing formats only, ruling out Bincode and many
/// others.
///
/// [Serde data model]: https://serde.rs/data-model.html
///
+42
View File
@@ -176,6 +176,48 @@ where
////////////////////////////////////////////////////////////////////////////////
/// A deserializer that cannot be instantiated.
#[cfg(feature = "unstable")]
pub struct NeverDeserializer<E> {
never: !,
marker: PhantomData<E>,
}
#[cfg(feature = "unstable")]
impl<'de, E> IntoDeserializer<'de, E> for !
where
E: de::Error,
{
type Deserializer = NeverDeserializer<E>;
fn into_deserializer(self) -> Self::Deserializer {
self
}
}
#[cfg(feature = "unstable")]
impl<'de, E> de::Deserializer<'de> for NeverDeserializer<E>
where
E: de::Error,
{
type Error = E;
fn deserialize_any<V>(self, _visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
self.never
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
bytes byte_buf option unit unit_struct newtype_struct seq tuple
tuple_struct map struct enum identifier ignored_any
}
}
////////////////////////////////////////////////////////////////////////////////
macro_rules! primitive_deserializer {
($ty:ty, $doc:tt, $name:ident, $method:ident $($cast:tt)*) => {
#[doc = "A deserializer holding"]
+2 -2
View File
@@ -70,7 +70,7 @@
/// ($($tt:tt)*) => {};
/// }
/// ```
#[cfg(all(integer128, not(serde_docs_rs)))]
#[cfg(integer128)]
#[macro_export]
macro_rules! serde_if_integer128 {
($($tt:tt)*) => {
@@ -78,7 +78,7 @@ macro_rules! serde_if_integer128 {
};
}
#[cfg(any(not(integer128), serde_docs_rs))]
#[cfg(not(integer128))]
#[macro_export]
#[doc(hidden)]
macro_rules! serde_if_integer128 {
+27 -9
View File
@@ -82,22 +82,29 @@
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.63")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.77")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
// https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(specialization))]
#![cfg_attr(feature = "unstable", feature(specialization, never_type))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(
feature = "cargo-clippy",
allow(
cast_lossless, const_static_lifetime, doc_markdown, linkedlist, needless_pass_by_value,
redundant_field_names, type_complexity, unreadable_literal, zero_prefixed_literal
cast_lossless,
const_static_lifetime,
doc_markdown,
linkedlist,
needless_pass_by_value,
redundant_field_names,
type_complexity,
unreadable_literal,
zero_prefixed_literal
)
)]
// Whitelisted clippy_pedantic lints
@@ -118,6 +125,7 @@
stutter,
use_self,
// not practical
indexing_slicing,
many_single_char_names,
missing_docs_in_private_items,
similar_names,
@@ -126,7 +134,10 @@
use_debug,
))]
// Blacklisted Rust lints.
#![deny(missing_docs, unused_imports)]
//
// Compiler bug involving unused_imports:
// https://github.com/rust-lang/rust/issues/51661
#![deny(missing_docs, /*unused_imports*/)]
////////////////////////////////////////////////////////////////////////////////
@@ -144,7 +155,7 @@ mod lib {
pub use std::*;
}
pub use self::core::{cmp, iter, mem, num, ops, slice, str};
pub use self::core::{cmp, iter, mem, num, slice, str};
pub use self::core::{f32, f64};
pub use self::core::{i16, i32, i64, i8, isize};
pub use self::core::{u16, u32, u64, u8, usize};
@@ -155,6 +166,7 @@ mod lib {
pub use self::core::default::{self, Default};
pub use self::core::fmt::{self, Debug, Display};
pub use self::core::marker::{self, PhantomData};
pub use self::core::ops::Range;
pub use self::core::option::{self, Option};
pub use self::core::result::{self, Result};
@@ -184,12 +196,12 @@ mod lib {
pub use std::rc::{Rc, Weak as RcWeak};
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::arc::{Arc, Weak as ArcWeak};
pub use alloc::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::sync::{Arc, Weak as ArcWeak};
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
pub use alloc::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
#[cfg(feature = "std")]
pub use std::collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque};
@@ -211,7 +223,13 @@ mod lib {
#[cfg(feature = "std")]
pub use std::sync::{Mutex, RwLock};
#[cfg(feature = "std")]
pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
pub use std::time::{SystemTime, UNIX_EPOCH};
#[cfg(any(core_duration, feature = "std"))]
pub use self::core::time::Duration;
#[cfg(range_inclusive)]
pub use self::core::ops::RangeInclusive;
}
////////////////////////////////////////////////////////////////////////////////
+2 -2
View File
@@ -128,7 +128,7 @@
/// [`Deserializer`]: trait.Deserializer.html
/// [`Visitor`]: de/trait.Visitor.html
/// [`Deserializer::deserialize_any`]: trait.Deserializer.html#tymethod.deserialize_any
#[macro_export]
#[macro_export(local_inner_macros)]
macro_rules! forward_to_deserialize_any {
(<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => {
$(forward_to_deserialize_any_helper!{$func<$lifetime, $visitor>})*
@@ -157,7 +157,7 @@ macro_rules! forward_to_deserialize_any_method {
}
#[doc(hidden)]
#[macro_export]
#[macro_export(local_inner_macros)]
macro_rules! forward_to_deserialize_any_helper {
(bool<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_bool<$l, $v>()}
+71 -24
View File
@@ -231,8 +231,8 @@ mod content {
use super::size_hint;
use de::{
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess,
SeqAccess, Unexpected, Visitor,
self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, IgnoredAny,
MapAccess, SeqAccess, Unexpected, Visitor,
};
/// Used from generated code to buffer the contents of the Deserializer when
@@ -832,8 +832,8 @@ mod content {
}
impl<'de, T> TaggedContentVisitor<'de, T> {
/// Visitor for the content of an internally tagged enum with the given tag
/// name.
/// Visitor for the content of an internally tagged enum with the given
/// tag name.
pub fn new(name: &'static str) -> Self {
TaggedContentVisitor {
tag_name: name,
@@ -1075,8 +1075,8 @@ mod content {
Ok(value)
}
/// Used when deserializing an internally tagged enum because the content will
/// be used exactly once.
/// Used when deserializing an internally tagged enum because the content
/// will be used exactly once.
impl<'de, E> Deserializer<'de> for ContentDeserializer<'de, E>
where
E: de::Error,
@@ -1790,8 +1790,8 @@ mod content {
Ok(value)
}
/// Used when deserializing an untagged enum because the content may need to be
/// used more than once.
/// Used when deserializing an untagged enum because the content may need
/// to be used more than once.
impl<'de, 'a, E> Deserializer<'de> for ContentRefDeserializer<'a, 'de, E>
where
E: de::Error,
@@ -2470,10 +2470,11 @@ mod content {
Ok(())
}
fn visit_map<M>(self, _: M) -> Result<(), M::Error>
fn visit_map<M>(self, mut access: M) -> Result<(), M::Error>
where
M: MapAccess<'de>,
{
while let Some(_) = try!(access.next_entry::<IgnoredAny, IgnoredAny>()) {}
Ok(())
}
}
@@ -2723,7 +2724,7 @@ where
where
V: Visitor<'de>,
{
visitor.visit_map(FlatMapAccess::new(self.0.iter_mut(), None))
visitor.visit_map(FlatMapAccess::new(self.0.iter()))
}
fn deserialize_struct<V>(
@@ -2735,7 +2736,7 @@ where
where
V: Visitor<'de>,
{
visitor.visit_map(FlatMapAccess::new(self.0.iter_mut(), Some(fields)))
visitor.visit_map(FlatStructAccess::new(self.0.iter_mut(), fields))
}
fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
@@ -2784,22 +2785,19 @@ where
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatMapAccess<'a, 'de: 'a, E> {
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
pending_content: Option<Content<'de>>,
fields: Option<&'static [&'static str]>,
iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
pending_content: Option<&'a Content<'de>>,
_marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> FlatMapAccess<'a, 'de, E> {
fn new(
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
fields: Option<&'static [&'static str]>,
iter: slice::Iter<'a, Option<(Content<'de>, Content<'de>)>>,
) -> FlatMapAccess<'a, 'de, E> {
FlatMapAccess {
iter: iter,
pending_content: None,
fields: fields,
_marker: PhantomData,
}
}
@@ -2812,6 +2810,61 @@ where
{
type Error = E;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
{
while let Some(item) = self.iter.next() {
// Items in the vector are nulled out when used by a struct.
if let Some((ref key, ref content)) = *item {
self.pending_content = Some(content);
return seed.deserialize(ContentRefDeserializer::new(key)).map(Some);
}
}
Ok(None)
}
fn next_value_seed<T>(&mut self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeSeed<'de>,
{
match self.pending_content.take() {
Some(value) => seed.deserialize(ContentRefDeserializer::new(value)),
None => Err(Error::custom("value is missing")),
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
pub struct FlatStructAccess<'a, 'de: 'a, E> {
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
pending_content: Option<Content<'de>>,
fields: &'static [&'static str],
_marker: PhantomData<E>,
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> FlatStructAccess<'a, 'de, E> {
fn new(
iter: slice::IterMut<'a, Option<(Content<'de>, Content<'de>)>>,
fields: &'static [&'static str],
) -> FlatStructAccess<'a, 'de, E> {
FlatStructAccess {
iter: iter,
pending_content: None,
fields: fields,
_marker: PhantomData,
}
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<'a, 'de, E> MapAccess<'de> for FlatStructAccess<'a, 'de, E>
where
E: Error,
{
type Error = E;
fn next_key_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>,
@@ -2822,13 +2875,7 @@ where
// about. In case we do not know which fields we want, we take them all.
let use_item = match *item {
None => false,
Some((ref c, _)) => c.as_str().map_or(self.fields.is_none(), |key| {
match self.fields {
None => true,
Some(fields) if fields.contains(&key) => true,
_ => false,
}
}),
Some((ref c, _)) => c.as_str().map_or(false, |key| self.fields.contains(&key)),
};
if use_item {
+2 -2
View File
@@ -32,7 +32,7 @@ macro_rules! __private_deserialize {
/// Used only by Serde doc tests. Not public API.
#[doc(hidden)]
#[macro_export]
#[macro_export(local_inner_macros)]
macro_rules! __serialize_unimplemented {
($($func:ident)*) => {
$(
@@ -52,7 +52,7 @@ macro_rules! __serialize_unimplemented_method {
}
#[doc(hidden)]
#[macro_export]
#[macro_export(local_inner_macros)]
macro_rules! __serialize_unimplemented_helper {
(bool) => {
__serialize_unimplemented_method!(serialize_bool(bool) -> Ok);
+53 -9
View File
@@ -8,10 +8,7 @@
use lib::*;
use ser::{Serialize, SerializeTuple, Serializer};
#[cfg(feature = "std")]
use ser::Error;
use ser::{Error, Serialize, SerializeTuple, Serializer};
////////////////////////////////////////////////////////////////////////////////
@@ -72,6 +69,15 @@ impl Serialize for String {
}
}
impl<'a> Serialize for fmt::Arguments<'a> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_str(self)
}
}
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
@@ -221,8 +227,7 @@ seq_impl!(VecDeque<T>);
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl<Idx> Serialize for ops::Range<Idx>
impl<Idx> Serialize for Range<Idx>
where
Idx: Serialize,
{
@@ -240,6 +245,25 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(range_inclusive)]
impl<Idx> Serialize for RangeInclusive<Idx>
where
Idx: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("RangeInclusive", 2));
try!(state.serialize_field("start", &self.start()));
try!(state.serialize_field("end", &self.end()));
state.end()
}
}
////////////////////////////////////////////////////////////////////////////////
impl Serialize for () {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -250,6 +274,16 @@ impl Serialize for () {
}
}
#[cfg(feature = "unstable")]
impl Serialize for ! {
fn serialize<S>(&self, _serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
*self
}
}
////////////////////////////////////////////////////////////////////////////////
macro_rules! tuple_impls {
@@ -435,10 +469,17 @@ nonzero_integers! {
NonZeroU16,
NonZeroU32,
NonZeroU64,
// FIXME: https://github.com/serde-rs/serde/issues/1136 NonZeroU128,
NonZeroUsize,
}
// Currently 128-bit integers do not work on Emscripten targets so we need an
// additional `#[cfg]`
serde_if_integer128! {
nonzero_integers! {
NonZeroU128,
}
}
impl<T> Serialize for Cell<T>
where
T: Serialize + Copy,
@@ -459,7 +500,10 @@ where
where
S: Serializer,
{
self.borrow().serialize(serializer)
match self.try_borrow() {
Ok(value) => value.serialize(serializer),
Err(_) => Err(S::Error::custom("already mutably borrowed")),
}
}
}
@@ -517,7 +561,7 @@ where
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
#[cfg(any(core_duration, feature = "std"))]
impl Serialize for Duration {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
+46 -36
View File
@@ -24,8 +24,7 @@
//!
//! Additionally, Serde provides a procedural macro called [`serde_derive`] to
//! automatically generate [`Serialize`] implementations for structs and enums
//! in your program. See the [codegen section of the manual] for how to use
//! this.
//! in your program. See the [derive section of the manual] for how to use this.
//!
//! In rare cases it may be necessary to implement [`Serialize`] manually for
//! some type in your program. See the [Implementing `Serialize`] section of the
@@ -92,7 +91,9 @@
//! - Path
//! - PathBuf
//! - Range\<T\>
//! - RangeInclusive\<T\>
//! - num::NonZero*
//! - `!` *(unstable)*
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
@@ -110,7 +111,7 @@
//! [`serde_derive`]: https://crates.io/crates/serde_derive
//! [`serde_json`]: https://github.com/serde-rs/json
//! [`serde_yaml`]: https://github.com/dtolnay/serde-yaml
//! [codegen section of the manual]: https://serde.rs/codegen.html
//! [derive section of the manual]: https://serde.rs/derive.html
//! [data formats]: https://serde.rs/#data-formats
use lib::*;
@@ -194,7 +195,7 @@ declare_error_trait!(Error: Sized + Debug + Display);
///
/// Additionally, Serde provides a procedural macro called [`serde_derive`] to
/// automatically generate `Serialize` implementations for structs and enums in
/// your program. See the [codegen section of the manual] for how to use this.
/// your program. See the [derive section of the manual] for how to use this.
///
/// In rare cases it may be necessary to implement `Serialize` manually for some
/// type in your program. See the [Implementing `Serialize`] section of the
@@ -209,7 +210,7 @@ declare_error_trait!(Error: Sized + Debug + Display);
/// [`LinkedHashMap<K, V>`]: https://docs.rs/linked-hash-map/*/linked_hash_map/struct.LinkedHashMap.html
/// [`linked-hash-map`]: https://crates.io/crates/linked-hash-map
/// [`serde_derive`]: https://crates.io/crates/serde_derive
/// [codegen section of the manual]: https://serde.rs/codegen.html
/// [derive section of the manual]: https://serde.rs/derive.html
/// [ser]: https://docs.serde.rs/serde/ser/index.html
pub trait Serialize {
/// Serialize this value into the given Serde serializer.
@@ -218,7 +219,7 @@ pub trait Serialize {
/// information about how to implement this method.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStruct};
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Person {
/// name: String,
@@ -272,16 +273,16 @@ pub trait Serialize {
/// - When serializing, all strings are handled equally. When deserializing,
/// there are three flavors of strings: transient, owned, and borrowed.
/// - **byte array** - \[u8\]
/// - Similar to strings, during deserialization byte arrays can be transient,
/// owned, or borrowed.
/// - Similar to strings, during deserialization byte arrays can be
/// transient, owned, or borrowed.
/// - **option**
/// - Either none or some value.
/// - **unit**
/// - The type of `()` in Rust. It represents an anonymous value containing no
/// data.
/// - The type of `()` in Rust. It represents an anonymous value containing
/// no data.
/// - **unit_struct**
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named value
/// containing no data.
/// - For example `struct Unit` or `PhantomData<T>`. It represents a named
/// value containing no data.
/// - **unit_variant**
/// - For example the `E::A` and `E::B` in `enum E { A, B }`.
/// - **newtype_struct**
@@ -289,14 +290,15 @@ pub trait Serialize {
/// - **newtype_variant**
/// - For example the `E::N` in `enum E { N(u8) }`.
/// - **seq**
/// - A variably sized heterogeneous sequence of values, for example `Vec<T>` or
/// `HashSet<T>`. When serializing, the length may or may not be known before
/// iterating through all the data. When deserializing, the length is determined
/// by looking at the serialized data.
/// - A variably sized heterogeneous sequence of values, for example
/// `Vec<T>` or `HashSet<T>`. When serializing, the length may or may not
/// be known before iterating through all the data. When deserializing,
/// the length is determined by looking at the serialized data.
/// - **tuple**
/// - A statically sized heterogeneous sequence of values for which the length
/// will be known at deserialization time without looking at the serialized
/// data, for example `(u8,)` or `(String, u64, Vec<T>)` or `[u64; 10]`.
/// - A statically sized heterogeneous sequence of values for which the
/// length will be known at deserialization time without looking at the
/// serialized data, for example `(u8,)` or `(String, u64, Vec<T>)` or
/// `[u64; 10]`.
/// - **tuple_struct**
/// - A named tuple, for example `struct Rgb(u8, u8, u8)`.
/// - **tuple_variant**
@@ -304,9 +306,9 @@ pub trait Serialize {
/// - **map**
/// - A heterogeneous key-value pairing, for example `BTreeMap<K, V>`.
/// - **struct**
/// - A heterogeneous key-value pairing in which the keys are strings and will be
/// known at deserialization time without looking at the serialized data, for
/// example `struct S { r: u8, g: u8, b: u8 }`.
/// - A heterogeneous key-value pairing in which the keys are strings and
/// will be known at deserialization time without looking at the
/// serialized data, for example `struct S { r: u8, g: u8, b: u8 }`.
/// - **struct_variant**
/// - For example the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`.
///
@@ -1109,7 +1111,7 @@ pub trait Serializer: Sized {
/// ```
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTuple};
/// use serde::ser::{Serialize, SerializeTuple, Serializer};
///
/// const VRAM_SIZE: usize = 386;
/// struct Vram([u16; VRAM_SIZE]);
@@ -1137,7 +1139,7 @@ pub trait Serializer: Sized {
/// of data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleStruct};
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
///
/// struct Rgb(u8, u8, u8);
///
@@ -1169,7 +1171,7 @@ pub trait Serializer: Sized {
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleVariant};
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
///
/// enum E {
/// T(u8, u8),
@@ -1263,7 +1265,7 @@ pub trait Serializer: Sized {
/// data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStruct};
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Rgb {
/// r: u8,
@@ -1299,10 +1301,10 @@ pub trait Serializer: Sized {
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
///
/// enum E {
/// S { r: u8, g: u8, b: u8 }
/// S { r: u8, g: u8, b: u8 },
/// }
///
/// impl Serialize for E {
@@ -1311,7 +1313,11 @@ pub trait Serializer: Sized {
/// S: Serializer,
/// {
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// E::S {
/// ref r,
/// ref g,
/// ref b,
/// } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
@@ -1374,8 +1380,8 @@ pub trait Serializer: Sized {
/// method.
///
/// ```rust
/// use std::collections::BTreeSet;
/// use serde::{Serialize, Serializer};
/// use std::collections::BTreeSet;
///
/// struct MapToUnit {
/// keys: BTreeSet<i32>,
@@ -1703,7 +1709,7 @@ pub trait SerializeTuple {
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleStruct};
/// use serde::ser::{Serialize, SerializeTupleStruct, Serializer};
///
/// struct Rgb(u8, u8, u8);
///
@@ -1748,7 +1754,7 @@ pub trait SerializeTupleStruct {
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeTupleVariant};
/// use serde::ser::{Serialize, SerializeTupleVariant, Serializer};
///
/// enum E {
/// T(u8, u8),
@@ -1917,7 +1923,7 @@ pub trait SerializeMap {
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStruct};
/// use serde::ser::{Serialize, SerializeStruct, Serializer};
///
/// struct Rgb {
/// r: u8,
@@ -1977,10 +1983,10 @@ pub trait SerializeStruct {
/// # Example use
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
/// use serde::ser::{Serialize, SerializeStructVariant, Serializer};
///
/// enum E {
/// S { r: u8, g: u8, b: u8 }
/// S { r: u8, g: u8, b: u8 },
/// }
///
/// impl Serialize for E {
@@ -1989,7 +1995,11 @@ pub trait SerializeStruct {
/// S: Serializer,
/// {
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// E::S {
/// ref r,
/// ref g,
/// ref b,
/// } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
+4 -3
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.63" # remember to update html_root_url
version = "1.0.77" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -13,6 +13,7 @@ include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-AP
[badges]
travis-ci = { repository = "serde-rs/serde" }
appveyor = { repository = "serde-rs/serde" }
[features]
default = []
@@ -24,8 +25,8 @@ proc-macro = true
[dependencies]
proc-macro2 = "0.4"
quote = "0.6"
syn = { version = "0.14", features = ["visit"] }
quote = "0.6.3"
syn = { version = "0.15", features = ["visit"] }
[dev-dependencies]
serde = { version = "1.0", path = "../serde" }
+13 -16
View File
@@ -32,8 +32,7 @@ pub fn without_defaults(generics: &syn::Generics) -> syn::Generics {
..param.clone()
}),
_ => param.clone(),
})
.collect(),
}).collect(),
..generics.clone()
}
}
@@ -91,7 +90,8 @@ pub fn with_where_predicates_from_variants(
// Puts the given bound on any generic type parameters that are used in fields
// for which filter returns true.
//
// For example, the following struct needs the bound `A: Serialize, B: Serialize`.
// For example, the following struct needs the bound `A: Serialize, B:
// Serialize`.
//
// struct S<'b, A, B: 'b, C> {
// a: A,
@@ -193,14 +193,13 @@ pub fn with_bound(
.map(|id| syn::TypePath {
qself: None,
path: id.into(),
})
.chain(associated_type_usage.into_iter().cloned())
}).chain(associated_type_usage.into_iter().cloned())
.map(|bounded_ty| {
syn::WherePredicate::Type(syn::PredicateType {
lifetimes: None,
// the type parameter that is being bounded e.g. T
bounded_ty: syn::Type::Path(bounded_ty),
colon_token: Default::default(),
colon_token: <Token![:]>::default(),
// the bound e.g. Serialize
bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound {
paren_token: None,
@@ -208,7 +207,7 @@ pub fn with_bound(
lifetimes: None,
path: bound.clone(),
})].into_iter()
.collect(),
.collect(),
})
});
@@ -233,7 +232,7 @@ pub fn with_self_bound(
lifetimes: None,
// the type that is being bounded e.g. MyStruct<'a, T>
bounded_ty: type_of_item(cont),
colon_token: Default::default(),
colon_token: <Token![:]>::default(),
// the bound e.g. Default
bounds: vec![syn::TypeParamBound::Trait(syn::TraitBound {
paren_token: None,
@@ -241,7 +240,7 @@ pub fn with_self_bound(
lifetimes: None,
path: bound.clone(),
})].into_iter()
.collect(),
.collect(),
}));
generics
}
@@ -270,8 +269,7 @@ pub fn with_lifetime_bound(generics: &syn::Generics, lifetime: &str) -> syn::Gen
syn::GenericParam::Const(_) => {}
}
param
}))
.collect();
})).collect();
syn::Generics {
params: params,
@@ -289,7 +287,7 @@ fn type_of_item(cont: &Container) -> syn::Type {
arguments: syn::PathArguments::AngleBracketed(
syn::AngleBracketedGenericArguments {
colon2_token: None,
lt_token: Default::default(),
lt_token: <Token![<]>::default(),
args: cont
.generics
.params
@@ -307,13 +305,12 @@ fn type_of_item(cont: &Container) -> syn::Type {
syn::GenericParam::Const(_) => {
panic!("Serde does not support const generics yet");
}
})
.collect(),
gt_token: Default::default(),
}).collect(),
gt_token: <Token![>]>::default(),
},
),
}].into_iter()
.collect(),
.collect(),
},
})
}
+16 -10
View File
@@ -30,8 +30,9 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream
let ident = &cont.ident;
let params = Parameters::new(&cont);
let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(&params);
let suffix = ident.to_string().trim_left_matches("r#").to_owned();
let dummy_const = Ident::new(
&format!("_IMPL_DESERIALIZE_FOR_{}", ident),
&format!("_IMPL_DESERIALIZE_FOR_{}", suffix),
Span::call_site(),
);
let body = Stmts(deserialize_body(&cont, &params));
@@ -73,6 +74,9 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<TokenStream
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
#[allow(unknown_lints)]
#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
#[allow(rust_2018_idioms)]
extern crate serde as _serde;
#try_replacement
#impl_block
@@ -201,7 +205,9 @@ fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generi
// All other fields may need a `T: Deserialize` bound where T is the type of the
// field.
fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
!field.skip_deserializing() && field.deserialize_with().is_none() && field.de_bound().is_none()
!field.skip_deserializing()
&& field.deserialize_with().is_none()
&& field.de_bound().is_none()
&& variant.map_or(true, |variant| {
!variant.skip_deserializing()
&& variant.deserialize_with().is_none()
@@ -832,7 +838,8 @@ fn deserialize_newtype_struct(
#[cfg(feature = "deserialize_in_place")]
fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> TokenStream {
// We do not generate deserialize_in_place if every field has a deserialize_with.
// We do not generate deserialize_in_place if every field has a
// deserialize_with.
assert!(field.attrs.deserialize_with().is_none());
let delife = params.borrowed.de_lifetime();
@@ -936,8 +943,8 @@ fn deserialize_struct(
quote!(mut __seq)
};
// untagged struct variants do not get a visit_seq method. The same applies to structs that
// only have a map representation.
// untagged struct variants do not get a visit_seq method. The same applies to
// structs that only have a map representation.
let visit_seq = match *untagged {
Untagged::No if !cattrs.has_flatten() => Some(quote! {
#[inline]
@@ -1347,8 +1354,7 @@ fn deserialize_adjacently_tagged_enum(
quote! {
__Field::#variant_index => #block
}
})
.collect();
}).collect();
let expecting = format!("adjacently tagged enum {}", params.type_name());
let type_name = cattrs.name().deserialize_name();
@@ -1936,8 +1942,7 @@ fn deserialize_custom_identifier(
variant.attrs.name().deserialize_name(),
variant.ident.clone(),
)
})
.collect();
}).collect();
let names = names_idents.iter().map(|&(ref name, _)| name);
@@ -2544,7 +2549,8 @@ fn deserialize_map_in_place(
.map(|(i, field)| (field, field_i(i)))
.collect();
// For deserialize_in_place, declare booleans for each field that will be deserialized.
// For deserialize_in_place, declare booleans for each field that will be
// deserialized.
let let_flags = fields_names
.iter()
.filter(|&&(field, _)| !field.attrs.skip_deserializing())
+2 -4
View File
@@ -129,8 +129,7 @@ fn enum_from_ast<'a>(
style: style,
fields: fields,
}
})
.collect()
}).collect()
}
fn struct_from_ast<'a>(
@@ -173,6 +172,5 @@ fn fields_from_ast<'a>(
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
ty: &field.ty,
original: field,
})
.collect()
}).collect()
}
+28 -24
View File
@@ -11,8 +11,8 @@ use proc_macro2::{Group, Span, TokenStream, TokenTree};
use std::collections::BTreeSet;
use std::str::FromStr;
use syn;
use syn::parse::{self, Parse, ParseStream};
use syn::punctuated::Punctuated;
use syn::synom::{ParseError, Synom};
use syn::Ident;
use syn::Meta::{List, NameValue, Word};
use syn::NestedMeta::{Literal, Meta};
@@ -90,6 +90,10 @@ pub struct Name {
deserialize: String,
}
fn unraw(ident: &Ident) -> String {
ident.to_string().trim_left_matches("r#").to_owned()
}
impl Name {
/// Return the container name for the container when serializing.
pub fn serialize_name(&self) -> String {
@@ -272,7 +276,7 @@ impl Container {
}
}
// Parse `#[serde(bound = "D: Serialize")]`
// Parse `#[serde(bound = "T: SomeBound")]`
Meta(NameValue(ref m)) if m.ident == "bound" => {
if let Ok(where_predicates) =
parse_lit_into_where(cx, &m.ident, &m.ident, &m.lit)
@@ -282,7 +286,7 @@ impl Container {
}
}
// Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
// Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
Meta(List(ref m)) if m.ident == "bound" => {
if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
ser_bound.set_opt(ser);
@@ -380,8 +384,8 @@ impl Container {
Container {
name: Name {
serialize: ser_name.get().unwrap_or_else(|| item.ident.to_string()),
deserialize: de_name.get().unwrap_or_else(|| item.ident.to_string()),
serialize: ser_name.get().unwrap_or_else(|| unraw(&item.ident)),
deserialize: de_name.get().unwrap_or_else(|| unraw(&item.ident)),
},
transparent: transparent.get(),
deny_unknown_fields: deny_unknown_fields.get(),
@@ -617,7 +621,7 @@ impl Variant {
other.set_true();
}
// Parse `#[serde(bound = "D: Serialize")]`
// Parse `#[serde(bound = "T: SomeBound")]`
Meta(NameValue(ref m)) if m.ident == "bound" => {
if let Ok(where_predicates) =
parse_lit_into_where(cx, &m.ident, &m.ident, &m.lit)
@@ -627,7 +631,7 @@ impl Variant {
}
}
// Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
// Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
Meta(List(ref m)) if m.ident == "bound" => {
if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
ser_bound.set_opt(ser);
@@ -697,8 +701,8 @@ impl Variant {
let de_renamed = de_name.is_some();
Variant {
name: Name {
serialize: ser_name.unwrap_or_else(|| variant.ident.to_string()),
deserialize: de_name.unwrap_or_else(|| variant.ident.to_string()),
serialize: ser_name.unwrap_or_else(|| unraw(&variant.ident)),
deserialize: de_name.unwrap_or_else(|| unraw(&variant.ident)),
},
ser_renamed: ser_renamed,
de_renamed: de_renamed,
@@ -822,7 +826,7 @@ impl Field {
let mut flatten = BoolAttr::none(cx, "flatten");
let ident = match field.ident {
Some(ref ident) => ident.to_string(),
Some(ref ident) => unraw(ident),
None => index.to_string(),
};
@@ -921,7 +925,7 @@ impl Field {
}
}
// Parse `#[serde(bound = "D: Serialize")]`
// Parse `#[serde(bound = "T: SomeBound")]`
Meta(NameValue(ref m)) if m.ident == "bound" => {
if let Ok(where_predicates) =
parse_lit_into_where(cx, &m.ident, &m.ident, &m.lit)
@@ -931,7 +935,7 @@ impl Field {
}
}
// Parse `#[serde(bound(serialize = "D: Serialize", deserialize = "D: Deserialize"))]`
// Parse `#[serde(bound(serialize = "...", deserialize = "..."))]`
Meta(List(ref m)) if m.ident == "bound" => {
if let Ok((ser, de)) = get_where_predicates(cx, &m.nested) {
ser_bound.set_opt(ser);
@@ -989,9 +993,9 @@ impl Field {
}
}
// Is skip_deserializing, initialize the field to Default::default() unless a different
// default is specified by `#[serde(default = "...")]` on ourselves or our container (e.g.
// the struct we are in).
// Is skip_deserializing, initialize the field to Default::default() unless a
// different default is specified by `#[serde(default = "...")]` on
// ourselves or our container (e.g. the struct we are in).
if let Default::None = *container_default {
if skip_deserializing.0.value.is_some() {
default.set_if_none(Default::Default);
@@ -1296,11 +1300,10 @@ fn parse_lit_into_lifetimes(
struct BorrowedLifetimes(Punctuated<syn::Lifetime, Token![+]>);
impl Synom for BorrowedLifetimes {
named!(parse -> Self, map!(
call!(Punctuated::parse_separated_nonempty),
BorrowedLifetimes
));
impl Parse for BorrowedLifetimes {
fn parse(input: ParseStream) -> parse::Result<Self> {
Punctuated::parse_separated_nonempty(input).map(BorrowedLifetimes)
}
}
if let Ok(BorrowedLifetimes(lifetimes)) = parse_lit_str(string) {
@@ -1509,7 +1512,8 @@ fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
syn::GenericArgument::Binding(ref binding) => {
collect_lifetimes(&binding.ty, out);
}
syn::GenericArgument::Const(_) => {}
syn::GenericArgument::Constraint(_)
| syn::GenericArgument::Const(_) => {}
}
}
}
@@ -1531,15 +1535,15 @@ fn collect_lifetimes(ty: &syn::Type, out: &mut BTreeSet<syn::Lifetime>) {
}
}
fn parse_lit_str<T>(s: &syn::LitStr) -> Result<T, ParseError>
fn parse_lit_str<T>(s: &syn::LitStr) -> parse::Result<T>
where
T: Synom,
T: Parse,
{
let tokens = try!(spanned_tokens(s));
syn::parse2(tokens)
}
fn spanned_tokens(s: &syn::LitStr) -> Result<TokenStream, ParseError> {
fn spanned_tokens(s: &syn::LitStr) -> parse::Result<TokenStream> {
let stream = try!(syn::parse_str(&s.value()));
Ok(respan_token_stream(stream, s.span()))
}
+6 -3
View File
@@ -22,13 +22,16 @@ pub enum RenameRule {
LowerCase,
/// Rename direct children to "UPPERCASE" style.
UPPERCASE,
/// Rename direct children to "PascalCase" style, as typically used for enum variants.
/// Rename direct children to "PascalCase" style, as typically used for
/// enum variants.
PascalCase,
/// Rename direct children to "camelCase" style.
CamelCase,
/// Rename direct children to "snake_case" style, as commonly used for fields.
/// Rename direct children to "snake_case" style, as commonly used for
/// fields.
SnakeCase,
/// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly used for constants.
/// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly
/// used for constants.
ScreamingSnakeCase,
/// Rename direct children to "kebab-case" style.
KebabCase,
+31 -14
View File
@@ -22,22 +22,35 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.63")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.77")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(
feature = "cargo-clippy",
allow(
enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding,
cyclomatic_complexity
enum_variant_names,
redundant_field_names,
too_many_arguments,
used_underscore_binding,
cyclomatic_complexity,
needless_pass_by_value
)
)]
// Whitelisted clippy_pedantic lints
#![cfg_attr(
feature = "cargo-clippy",
allow(
items_after_statements, doc_markdown, stutter, similar_names, use_self, single_match_else,
enum_glob_use, match_same_arms, filter_map, cast_possible_truncation
items_after_statements,
doc_markdown,
stutter,
similar_names,
use_self,
single_match_else,
enum_glob_use,
match_same_arms,
filter_map,
cast_possible_truncation,
indexing_slicing,
)
)]
// The `quote!` macro requires deep recursion.
@@ -68,18 +81,22 @@ mod try;
#[proc_macro_derive(Serialize, attributes(serde))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
let input: DeriveInput = syn::parse(input).unwrap();
match ser::expand_derive_serialize(&input) {
Ok(expanded) => expanded.into(),
Err(msg) => panic!(msg),
}
let input = parse_macro_input!(input as DeriveInput);
ser::expand_derive_serialize(&input)
.unwrap_or_else(compile_error)
.into()
}
#[proc_macro_derive(Deserialize, attributes(serde))]
pub fn derive_deserialize(input: TokenStream) -> TokenStream {
let input: DeriveInput = syn::parse(input).unwrap();
match de::expand_derive_deserialize(&input) {
Ok(expanded) => expanded.into(),
Err(msg) => panic!(msg),
let input = parse_macro_input!(input as DeriveInput);
de::expand_derive_deserialize(&input)
.unwrap_or_else(compile_error)
.into()
}
fn compile_error(message: String) -> proc_macro2::TokenStream {
quote! {
compile_error!(#message);
}
}
+1 -2
View File
@@ -62,8 +62,7 @@ fn pretend_fields_used(cont: &Container) -> TokenStream {
Some(quote!(#type_ident::#variant_ident #pat))
}
_ => None,
})
.collect::<Vec<_>>(),
}).collect::<Vec<_>>(),
Data::Struct(Style::Struct, ref fields) => {
let pat = struct_pattern(fields);
vec![quote!(#type_ident #pat)]
+19 -18
View File
@@ -26,7 +26,11 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
let ident = &cont.ident;
let params = Parameters::new(&cont);
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
let dummy_const = Ident::new(&format!("_IMPL_SERIALIZE_FOR_{}", ident), Span::call_site());
let suffix = ident.to_string().trim_left_matches("r#").to_owned();
let dummy_const = Ident::new(
&format!("_IMPL_SERIALIZE_FOR_{}", suffix),
Span::call_site(),
);
let body = Stmts(serialize_body(&cont, &params));
let impl_block = if let Some(remote) = cont.attrs.remote() {
@@ -61,6 +65,9 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<TokenStream,
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
#[allow(unknown_lints)]
#[cfg_attr(feature = "cargo-clippy", allow(useless_attribute))]
#[allow(rust_2018_idioms)]
extern crate serde as _serde;
#try_replacement
#impl_block
@@ -157,7 +164,9 @@ fn build_generics(cont: &Container) -> syn::Generics {
// attribute specify their own bound so we do not generate one. All other fields
// may need a `T: Serialize` bound where T is the type of the field.
fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
!field.skip_serializing() && field.serialize_with().is_none() && field.ser_bound().is_none()
!field.skip_serializing()
&& field.serialize_with().is_none()
&& field.ser_bound().is_none()
&& variant.map_or(true, |variant| {
!variant.skip_serializing()
&& variant.serialize_with().is_none()
@@ -279,8 +288,7 @@ fn serialize_tuple_struct(
let field_expr = get_member(params, field, &Member::Unnamed(index));
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! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_tuple_struct(__serializer, #type_name, #len));
@@ -323,8 +331,7 @@ fn serialize_struct_as_struct(
let field_expr = get_member(params, field, &field.member);
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! {
let #let_mut __serde_state = try!(_serde::Serializer::serialize_struct(__serializer, #type_name, #len));
@@ -358,8 +365,7 @@ fn serialize_struct_as_map(
let field_expr = get_member(params, field, &field.member);
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))
};
@@ -380,8 +386,7 @@ fn serialize_enum(params: &Parameters, variants: &[Variant], cattrs: &attr::Cont
.enumerate()
.map(|(variant_index, variant)| {
serialize_variant(params, variant, variant_index as u32, cattrs)
})
.collect();
}).collect();
quote_expr! {
match *#self_var {
@@ -785,8 +790,7 @@ fn serialize_tuple_variant(
let field_expr = Ident::new(&format!("__field{}", i), Span::call_site());
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 {
TupleVariant::ExternallyTagged {
@@ -863,8 +867,7 @@ fn serialize_struct_variant<'a>(
Some(path) => quote!(if #path(#member) { 0 } else { 1 }),
None => quote!(1),
}
})
.fold(quote!(0), |sum, expr| quote!(#sum + #expr));
}).fold(quote!(0), |sum, expr| quote!(#sum + #expr));
match context {
StructVariant::ExternallyTagged {
@@ -1043,8 +1046,7 @@ fn serialize_tuple_struct_visitor(
None => ser,
Some(skip) => quote!(if !#skip { #ser }),
}
})
.collect()
}).collect()
}
fn serialize_struct_visitor(
@@ -1138,8 +1140,7 @@ fn wrap_serialize_variant_with(
}
};
quote!(#id)
})
.collect();
}).collect();
wrap_serialize_with(
params,
serialize_with,
+2 -1
View File
@@ -16,7 +16,8 @@ path = "lib.rs"
[dependencies]
proc-macro2 = "0.4"
syn = { version = "0.14", default-features = false, features = ["derive", "parsing", "clone-impls"] }
syn = { version = "0.15", default-features = false, features = ["derive", "parsing", "clone-impls"] }
[badges]
travis-ci = { repository = "serde-rs/serde" }
appveyor = { repository = "serde-rs/serde" }
+6 -1
View File
@@ -9,7 +9,12 @@
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.23.1")]
#![cfg_attr(
feature = "cargo-clippy",
allow(cyclomatic_complexity, doc_markdown, match_same_arms, redundant_field_names)
allow(
cyclomatic_complexity,
doc_markdown,
match_same_arms,
redundant_field_names
)
)]
#[macro_use]
+2 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_test"
version = "1.0.63" # remember to update html_root_url
version = "1.0.77" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations"
@@ -20,3 +20,4 @@ serde_derive = { version = "1.0", path = "../serde_derive" }
[badges]
travis-ci = { repository = "serde-rs/serde" }
appveyor = { repository = "serde-rs/serde" }
+2 -1
View File
@@ -95,7 +95,8 @@ where
}
}
/// Asserts that `value` serializes to the given `tokens`, and then yields `error`.
/// Asserts that `value` serializes to the given `tokens`, and then yields
/// `error`.
///
/// ```rust
/// # #[macro_use]
+2 -7
View File
@@ -19,7 +19,7 @@ pub struct Compact<T: ?Sized>(T);
/// extern crate serde_test;
///
/// use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// use serde_test::{Configure, Token, assert_tokens};
/// use serde_test::{assert_tokens, Configure, Token};
///
/// #[derive(Debug, PartialEq)]
/// struct Example(u8, u8);
@@ -67,12 +67,7 @@ pub struct Compact<T: ?Sized>(T);
/// Token::TupleEnd,
/// ],
/// );
/// assert_tokens(
/// &Example(1, 0).readable(),
/// &[
/// Token::Str("1.0"),
/// ],
/// );
/// assert_tokens(&Example(1, 0).readable(), &[Token::Str("1.0")]);
/// }
/// ```
pub trait Configure {
+2 -1
View File
@@ -253,7 +253,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
Token::UnitVariant { name: n, .. }
| Token::NewtypeVariant { name: n, .. }
| Token::TupleVariant { name: n, .. }
| Token::StructVariant { name: n, .. } if name == n =>
| Token::StructVariant { name: n, .. }
if name == n =>
{
visitor.visit_enum(DeserializerEnumVisitor { de: self })
}
+7 -3
View File
@@ -161,7 +161,7 @@
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.63")]
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.77")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
@@ -169,8 +169,12 @@
#![cfg_attr(
feature = "cargo-clippy",
allow(
empty_line_after_outer_attr, missing_docs_in_private_items, redundant_field_names, stutter,
use_debug, use_self
empty_line_after_outer_attr,
missing_docs_in_private_items,
redundant_field_names,
stutter,
use_debug,
use_self
)
)]
+2 -1
View File
@@ -11,7 +11,8 @@ use serde::{ser, Serialize};
use error::Error;
use token::Token;
/// A `Serializer` that ensures that a value serializes to a given list of tokens.
/// A `Serializer` that ensures that a value serializes to a given list of
/// tokens.
#[derive(Debug)]
pub struct Serializer<'a> {
tokens: &'a [Token],
+3 -8
View File
@@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![feature(lang_items, start)]
#![feature(lang_items, start, panic_handler)]
#![no_std]
extern crate libc;
@@ -20,13 +20,8 @@ fn start(_argc: isize, _argv: *const *const u8) -> isize {
#[no_mangle]
pub extern "C" fn rust_eh_personality() {}
#[lang = "panic_fmt"]
#[no_mangle]
pub extern "C" fn rust_begin_panic(
_msg: core::fmt::Arguments,
_file: &'static str,
_line: u32,
) -> ! {
#[panic_handler]
fn panic(_info: &core::panic::PanicInfo) -> ! {
unsafe {
libc::abort();
}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
struct Test<'a> {
#[serde(borrow = "zzz")] //~^^ HELP: failed to parse borrowed lifetimes: "zzz"
#[serde(borrow = "zzz")]
//~^^^ ERROR: failed to parse borrowed lifetimes: "zzz"
s: &'a str,
}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
struct Test<'a> {
#[serde(borrow = "'a + 'a")] //~^^ HELP: duplicate borrowed lifetime `'a`
#[serde(borrow = "'a + 'a")]
//~^^^ ERROR: duplicate borrowed lifetime `'a`
s: &'a str,
}
@@ -12,10 +12,11 @@ extern crate serde_derive;
#[derive(Deserialize)]
struct Str<'a>(&'a str);
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
enum Test<'a> {
#[serde(borrow)] //~^^ HELP: duplicate serde attribute `borrow`
S(#[serde(borrow)] Str<'a>)
#[serde(borrow)]
//~^^^ ERROR: duplicate serde attribute `borrow`
S(#[serde(borrow)] Str<'a>),
}
fn main() {}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
struct Test<'a> {
#[serde(borrow = "")] //~^^ HELP: at least one lifetime must be borrowed
#[serde(borrow = "")]
//~^^^ ERROR: at least one lifetime must be borrowed
s: &'a str,
}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
struct Test {
#[serde(borrow)] //~^^ HELP: field `s` has no lifetimes to borrow
#[serde(borrow)]
//~^^^ ERROR: field `s` has no lifetimes to borrow
s: String,
}
@@ -12,10 +12,11 @@ extern crate serde_derive;
#[derive(Deserialize)]
struct Str<'a>(&'a str);
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
enum Test<'a> {
#[serde(borrow)] //~^^ HELP: #[serde(borrow)] may only be used on newtype variants
S { s: Str<'a> }
#[serde(borrow)]
//~^^^ ERROR: #[serde(borrow)] may only be used on newtype variants
S { s: Str<'a> },
}
fn main() {}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
struct Test<'a> {
#[serde(borrow = "'b")] //~^^ HELP: field `s` does not have lifetime 'b
#[serde(borrow = "'b")]
//~^^^ ERROR: field `s` does not have lifetime 'b
s: &'a str,
}
@@ -9,9 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
#[serde(tag = "conflict", content = "conflict")]
//~^^ HELP: enum tags `conflict` for type and content conflict with each other
//~^^ ERROR: enum tags `conflict` for type and content conflict with each other
enum E {
A,
B,
@@ -9,8 +9,8 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: #[serde(flatten)] cannot be used on newtype structs
#[derive(Serialize)]
struct Foo(#[serde(flatten)] HashMap<String, String>);
//~^^ ERROR: #[serde(flatten)] cannot be used on newtype structs
fn main() {}
@@ -9,16 +9,16 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: #[serde(flatten] can not be combined with #[serde(skip_deserializing)]
#[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
x: u32,
}
fn main() {}
@@ -9,16 +9,16 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: #[serde(flatten] can not be combined with #[serde(skip_serializing_if = "...")]
#[derive(Serialize)]
struct Foo {
#[serde(flatten, skip_serializing_if="Option::is_none")]
#[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
x: u32,
}
fn main() {}
@@ -9,16 +9,16 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: #[serde(flatten] can not be combined with #[serde(skip_serializing)]
#[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
x: u32,
}
fn main() {}
@@ -9,8 +9,8 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: #[serde(flatten)] cannot be used on tuple structs
#[derive(Serialize)]
struct Foo(u32, #[serde(flatten)] HashMap<String, String>);
//~^^ ERROR: #[serde(flatten)] cannot be used on tuple structs
fn main() {}
@@ -9,9 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
#[serde(tag = "conflict")]
//~^^ HELP: variant field name `conflict` conflicts with internal tag
//~^^ ERROR: variant field name `conflict` conflicts with internal tag
enum E {
A {
#[serde(rename = "conflict")]
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(default)] //~^ HELP: #[serde(default)] can only be used on structs
#[derive(Deserialize)]
#[serde(default)]
//~^^ ERROR: #[serde(default)] can only be used on structs
enum E {
S { f: u8 },
}
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(default)] //~^ HELP: #[serde(default)] can only be used on structs
#[derive(Deserialize)]
#[serde(default)]
//~^^ ERROR: #[serde(default)] can only be used on structs
struct T(u8, u8);
fn main() { }
fn main() {}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
struct S {
#[serde(rename="x", serialize="y")] //~^^ HELP: unknown serde field attribute `serialize`
#[serde(rename = "x", serialize = "y")]
//~^^^ ERROR: unknown serde field attribute `serialize`
x: (),
}
@@ -9,10 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
struct S {
#[serde(rename="x")]
#[serde(rename(deserialize="y"))] //~^^^ HELP: duplicate serde attribute `rename`
#[serde(rename = "x")]
#[serde(rename(deserialize = "y"))]
//~^^^^ ERROR: duplicate serde attribute `rename`
x: (),
}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
struct S {
#[serde(rename(serialize="x"), rename(serialize="y"))] //~^^ HELP: duplicate serde attribute `rename`
#[serde(rename(serialize = "x"), rename(serialize = "y"))]
//~^^^ ERROR: duplicate serde attribute `rename`
x: (),
}
@@ -9,10 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
struct S {
#[serde(rename(serialize="x"))]
#[serde(rename="y")] //~^^^ HELP: duplicate serde attribute `rename`
#[serde(rename(serialize = "x"))]
#[serde(rename = "y")]
//~^^^^ ERROR: duplicate serde attribute `rename`
x: (),
}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
struct S {
#[serde(rename(serialize="x", serialize="y"))] //~^^ HELP: duplicate serde attribute `rename`
#[serde(rename(serialize = "x", serialize = "y"))]
//~^^^ ERROR: duplicate serde attribute `rename`
x: (),
}
@@ -9,10 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
struct S {
#[serde(rename(serialize="x"))]
#[serde(rename(serialize="y"))] //~^^^ HELP: duplicate serde attribute `rename`
#[serde(rename(serialize = "x"))]
#[serde(rename(serialize = "y"))]
//~^^^^ ERROR: duplicate serde attribute `rename`
x: (),
}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
struct S {
#[serde(with = "w", serialize_with = "s")] //~^^ HELP: duplicate serde attribute `serialize_with`
#[serde(with = "w", serialize_with = "s")]
//~^^^ ERROR: duplicate serde attribute `serialize_with`
x: (),
}
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(tag = "type")] //~^ HELP: #[serde(tag = "...")] cannot be used with tuple variants
#[derive(Serialize)]
#[serde(tag = "type")]
//~^^ ERROR: #[serde(tag = "...")] cannot be used with tuple variants
enum E {
Tuple(u8, u8),
}
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(tag = "type")] //~^ HELP: #[serde(tag = "...")] can only be used on enums
#[derive(Serialize)]
#[serde(tag = "type")]
//~^^ ERROR: #[serde(tag = "...")] can only be used on enums
struct S;
fn main() {}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
#[serde(untagged)]
#[serde(tag = "type")] //~^^ HELP: enum cannot be both untagged and internally tagged
#[serde(tag = "type")]
//~^^^ ERROR: enum cannot be both untagged and internally tagged
enum E {
A(u8),
B(String),
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(untagged)] //~^ HELP: #[serde(untagged)] can only be used on enums
#[derive(Serialize)]
#[serde(untagged)]
//~^^ ERROR: #[serde(untagged)] can only be used on enums
struct S;
fn main() {}
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(field_identifier, variant_identifier)] //~^ HELP: `field_identifier` and `variant_identifier` cannot both be set
#[derive(Deserialize)]
#[serde(field_identifier, variant_identifier)]
//~^^ ERROR: `field_identifier` and `variant_identifier` cannot both be set
enum F {
A,
B,
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
#[serde(field_identifier)]
struct S; //~^^ HELP: `field_identifier` can only be used on an enum
//~^^ ERROR: `field_identifier` can only be used on an enum
struct S;
fn main() {}
@@ -9,11 +9,12 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
#[serde(field_identifier)]
enum F {
A,
B(u8, u8), //~^^^^ HELP: field_identifier may only contain unit variants
B(u8, u8),
//~^^^^^ ERROR: field_identifier may only contain unit variants
}
fn main() {}
@@ -9,11 +9,12 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
#[serde(field_identifier)]
enum F {
A,
Other(String), //~^^^^ HELP: `Other` must be the last variant
Other(String),
//~^^^^^ ERROR: `Other` must be the last variant
B,
}
@@ -9,10 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
enum F {
A,
#[serde(other)] //~^^^ HELP: #[serde(other)] may only be used inside a field_identifier
#[serde(other)]
//~^^^^ ERROR: #[serde(other)] may only be used inside a field_identifier
B,
}
@@ -9,11 +9,12 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
#[serde(field_identifier)]
enum F {
A,
#[serde(other)] //~^^^^ HELP: #[serde(other)] must be on a unit variant
#[serde(other)]
//~^^^^^ ERROR: #[serde(other)] must be on a unit variant
Other(u8, u8),
}
@@ -9,11 +9,12 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
#[serde(field_identifier)]
enum F {
A,
#[serde(other)] //~^^^^ HELP: #[serde(other)] must be the last variant
#[serde(other)]
//~^^^^^ ERROR: #[serde(other)] must be the last variant
Other,
B,
}
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(field_identifier)] //~^ HELP: field identifiers cannot be serialized
#[derive(Serialize)]
#[serde(field_identifier)]
//~^^ ERROR: field identifiers cannot be serialized
enum F {
A,
B,
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
#[serde(variant_identifier)]
struct S; //~^^ HELP: `variant_identifier` can only be used on an enum
//~^^ ERROR: `variant_identifier` can only be used on an enum
struct S;
fn main() {}
@@ -9,11 +9,12 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
#[serde(variant_identifier)]
enum F {
A,
B(u8, u8), //~^^^^ HELP: variant_identifier may only contain unit variants
B(u8, u8),
//~^^^^^ ERROR: variant_identifier may only contain unit variants
}
fn main() {}
@@ -9,7 +9,8 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
struct S<'de> {
s: &'de str, //~^^ HELP: cannot deserialize when there is a lifetime parameter called 'de
//~^^ ERROR: cannot deserialize when there is a lifetime parameter called 'de
s: &'de str,
}
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
struct S {
string: String,
slice: [u8], //~^^^ HELP: cannot deserialize a dynamically sized struct
slice: [u8],
//~^^^^ ERROR: cannot deserialize a dynamically sized struct
}
@@ -15,10 +15,11 @@ mod remote {
}
}
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
#[serde(remote = "remote::S")]
struct S {
#[serde(getter = "~~~")] //~^^^ HELP: failed to parse path: "~~~"
#[serde(getter = "~~~")]
//~^^^^ ERROR: failed to parse path: "~~~"
a: u8,
}
@@ -15,8 +15,9 @@ mod remote {
}
}
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(remote = "~~~")] //~^ HELP: failed to parse path: "~~~"
#[derive(Serialize)]
#[serde(remote = "~~~")]
//~^^ ERROR: failed to parse path: "~~~"
struct S {
a: u8,
}
@@ -11,17 +11,18 @@ extern crate serde_derive;
mod remote {
pub enum E {
A { a: u8 }
A { a: u8 },
}
}
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
#[serde(remote = "remote::E")]
pub enum E {
A {
#[serde(getter = "get_a")] //~^^^^ HELP: #[serde(getter = "...")] is not allowed in an enum
#[serde(getter = "get_a")]
//~^^^^^ ERROR: #[serde(getter = "...")] is not allowed in an enum
a: u8,
}
},
}
fn main() {}
@@ -19,7 +19,8 @@ mod remote {
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::S")]
struct S {
a: u8, //~^^^ ERROR: missing field `b` in initializer of `remote::S`
a: u8,
//~^^^ ERROR: missing field `b` in initializer of `remote::S`
}
fn main() {}
@@ -9,9 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
struct S {
#[serde(getter = "S::get")] //~^^ HELP: #[serde(getter = "...")] can only be used in structs that have #[serde(remote = "...")]
#[serde(getter = "S::get")]
//~^^^ ERROR: #[serde(getter = "...")] can only be used in structs that have #[serde(remote = "...")]
a: u8,
}
@@ -18,8 +18,9 @@ mod remote {
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::S")]
struct S {
//~^^^ ERROR: struct `remote::S` has no field named `b`
b: u8, //~^^^^ ERROR: no field `b` on type `&remote::S`
b: u8,
//~^ ERROR: struct `remote::S` has no field named `b`
//~^^ ERROR: no field `b` on type `&remote::S`
}
fn main() {}
@@ -13,8 +13,10 @@ mod remote {
pub struct S(pub u16);
}
#[derive(Deserialize)] //~ ERROR: mismatched types
#[derive(Deserialize)]
#[serde(remote = "remote::S")]
struct S(u8); //~^^ expected u16, found u8
struct S(u8);
//~^^^ ERROR: mismatched types
//~^^^^ expected u16, found u8
fn main() {}
@@ -21,11 +21,13 @@ mod remote {
}
}
#[derive(Serialize)] //~ ERROR: mismatched types
#[derive(Serialize)]
#[serde(remote = "remote::S")]
struct S {
#[serde(getter = "remote::S::get")]
a: u8, //~^^^^ expected u8, found u16
//~^^^^ ERROR: mismatched types
a: u8,
//~^^^^^^ expected u8, found u16
}
fn main() {}
@@ -15,10 +15,12 @@ mod remote {
}
}
#[derive(Serialize)] //~ ERROR: mismatched types
#[derive(Serialize)]
#[serde(remote = "remote::S")]
struct S {
a: u8, //~^^^ expected u8, found u16
a: u8,
//~^^^^ ERROR: mismatched types
//~^^^^^ expected u8, found u16
}
fn main() {}
@@ -9,10 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
#[serde(transparent)]
//~^^ ERROR: #[serde(transparent)] requires struct to have at most one transparent field
struct S {
//~^^^ HELP: #[serde(transparent)] requires struct to have at most one transparent field
a: u8,
b: u8,
}
@@ -9,10 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[derive(Deserialize)]
#[serde(transparent)]
//~^^ ERROR: #[serde(transparent)] requires at least one field that is neither skipped nor has a default
struct S {
//~^^^ HELP: #[serde(transparent)] requires at least one field that is neither skipped nor has a default
#[serde(skip)]
a: u8,
#[serde(default)]
@@ -9,10 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
#[serde(transparent)]
//~^^ ERROR: #[serde(transparent)] requires at least one field that is not skipped
struct S {
//~^^^ HELP: #[serde(transparent)] requires at least one field that is not skipped
#[serde(skip)]
a: u8,
}
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
#[serde(from = "Option<T")] //~^ HELP: failed to parse type: from = "Option<T"
#[derive(Deserialize)]
#[serde(from = "Option<T")]
//~^^ ERROR: failed to parse type: from = "Option<T"
enum TestOne {
Testing,
One,
@@ -9,8 +9,9 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(into = "Option<T")] //~^ HELP: failed to parse type: into = "Option<T"
#[derive(Serialize)]
#[serde(into = "Option<T")]
//~^^ ERROR: failed to parse type: into = "Option<T"
enum TestOne {
Testing,
One,
@@ -9,10 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[serde(abc="xyz")] //~^ HELP: unknown serde container attribute `abc`
#[derive(Serialize)]
#[serde(abc = "xyz")]
//~^^ ERROR: unknown serde container attribute `abc`
struct A {
x: u32,
}
fn main() { }
fn main() {}
@@ -9,10 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
struct C {
#[serde(abc="xyz")] //~^^ HELP: unknown serde field attribute `abc`
#[serde(abc = "xyz")]
//~^^^ ERROR: unknown serde field attribute `abc`
x: u32,
}
fn main() { }
fn main() {}
@@ -9,10 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
#[derive(Serialize)]
enum E {
#[serde(abc="xyz")] //~^^ HELP: unknown serde variant attribute `abc`
#[serde(abc = "xyz")]
//~^^^ ERROR: unknown serde variant attribute `abc`
V,
}
fn main() { }
fn main() {}
@@ -9,11 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: variant `Newtype` cannot have both #[serde(deserialize_with)] and a field 0 marked with #[serde(skip_deserializing)]
#[derive(Deserialize)]
enum Enum {
#[serde(deserialize_with = "deserialize_some_newtype_variant")]
//~^^^ ERROR: variant `Newtype` cannot have both #[serde(deserialize_with)] and a field 0 marked with #[serde(skip_deserializing)]
Newtype(#[serde(skip_deserializing)] String),
}
fn main() { }
fn main() {}
@@ -9,10 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: variant `Struct` cannot have both #[serde(deserialize_with)] and a field `f1` marked with #[serde(skip_deserializing)]
#[derive(Deserialize)]
enum Enum {
#[serde(deserialize_with = "deserialize_some_other_variant")]
//~^^^ ERROR: variant `Struct` cannot have both #[serde(deserialize_with)] and a field `f1` marked with #[serde(skip_deserializing)]
Struct {
#[serde(skip_deserializing)]
f1: String,
@@ -20,4 +20,4 @@ enum Enum {
},
}
fn main() { }
fn main() {}
@@ -9,11 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: variant `Tuple` cannot have both #[serde(deserialize_with)] and a field 0 marked with #[serde(skip_deserializing)]
#[derive(Deserialize)]
enum Enum {
#[serde(deserialize_with = "deserialize_some_other_variant")]
//~^^^ ERROR: variant `Tuple` cannot have both #[serde(deserialize_with)] and a field 0 marked with #[serde(skip_deserializing)]
Tuple(#[serde(skip_deserializing)] String, u8),
}
fn main() { }
fn main() {}
@@ -9,12 +9,12 @@
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: variant `Unit` cannot have both #[serde(deserialize_with)] and #[serde(skip_deserializing)]
#[derive(Deserialize)]
enum Enum {
#[serde(deserialize_with = "deserialize_some_unit_variant")]
#[serde(skip_deserializing)]
//~^^^^ ERROR: variant `Unit` cannot have both #[serde(deserialize_with)] and #[serde(skip_deserializing)]
Unit,
}
fn main() { }
fn main() {}
@@ -9,11 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: variant `Newtype` cannot have both #[serde(serialize_with)] and a field 0 marked with #[serde(skip_serializing)]
#[derive(Serialize)]
enum Enum {
#[serde(serialize_with = "serialize_some_newtype_variant")]
//~^^^ ERROR: variant `Newtype` cannot have both #[serde(serialize_with)] and a field 0 marked with #[serde(skip_serializing)]
Newtype(#[serde(skip_serializing)] String),
}
fn main() { }
fn main() {}
@@ -9,11 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: variant `Newtype` cannot have both #[serde(serialize_with)] and a field 0 marked with #[serde(skip_serializing_if)]
#[derive(Serialize)]
enum Enum {
#[serde(serialize_with = "serialize_some_newtype_variant")]
//~^^^ ERROR: variant `Newtype` cannot have both #[serde(serialize_with)] and a field 0 marked with #[serde(skip_serializing_if)]
Newtype(#[serde(skip_serializing_if = "always")] String),
}
fn main() { }
fn main() {}
@@ -9,10 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: variant `Struct` cannot have both #[serde(serialize_with)] and a field `f1` marked with #[serde(skip_serializing)]
#[derive(Serialize)]
enum Enum {
#[serde(serialize_with = "serialize_some_other_variant")]
//~^^^ ERROR: variant `Struct` cannot have both #[serde(serialize_with)] and a field `f1` marked with #[serde(skip_serializing)]
Struct {
#[serde(skip_serializing)]
f1: String,
@@ -20,4 +20,4 @@ enum Enum {
},
}
fn main() { }
fn main() {}
@@ -9,10 +9,10 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: variant `Struct` cannot have both #[serde(serialize_with)] and a field `f1` marked with #[serde(skip_serializing_if)]
#[derive(Serialize)]
enum Enum {
#[serde(serialize_with = "serialize_some_newtype_variant")]
//~^^^ ERROR: variant `Struct` cannot have both #[serde(serialize_with)] and a field `f1` marked with #[serde(skip_serializing_if)]
Struct {
#[serde(skip_serializing_if = "always")]
f1: String,
@@ -20,4 +20,4 @@ enum Enum {
},
}
fn main() { }
fn main() {}
@@ -9,11 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: variant `Tuple` cannot have both #[serde(serialize_with)] and a field 0 marked with #[serde(skip_serializing)]
#[derive(Serialize)]
enum Enum {
#[serde(serialize_with = "serialize_some_other_variant")]
//~^^^ ERROR: variant `Tuple` cannot have both #[serde(serialize_with)] and a field 0 marked with #[serde(skip_serializing)]
Tuple(#[serde(skip_serializing)] String, u8),
}
fn main() { }
fn main() {}
@@ -9,11 +9,11 @@
#[macro_use]
extern crate serde_derive;
#[derive(Serialize)] //~ ERROR: proc-macro derive panicked
//~^ HELP: variant `Tuple` cannot have both #[serde(serialize_with)] and a field 0 marked with #[serde(skip_serializing_if)]
#[derive(Serialize)]
enum Enum {
#[serde(serialize_with = "serialize_some_other_variant")]
//~^^^ ERROR: variant `Tuple` cannot have both #[serde(serialize_with)] and a field 0 marked with #[serde(skip_serializing_if)]
Tuple(#[serde(skip_serializing_if = "always")] String, u8),
}
fn main() { }
fn main() {}

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