mirror of
https://github.com/pezkuwichain/serde.git
synced 2026-04-23 14:08:06 +00:00
Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7350b58f5c | |||
| 7351e0e55a | |||
| b3ff7e43ef | |||
| a50e1c20e9 | |||
| 6980727d74 | |||
| bb1dedf04d | |||
| f3520e526b | |||
| e8fd2c85c3 | |||
| 97962d51e2 | |||
| 95b1a5d3d9 | |||
| 0856a2c101 | |||
| 9f331cc257 | |||
| ef16c815f6 | |||
| c45a809d5c | |||
| f7d06cae4c | |||
| 31fe82a215 | |||
| ef6ed1d1be | |||
| 9d1251548b | |||
| c20730ee39 | |||
| afd51ef0f4 | |||
| 3167f98689 | |||
| 078b171c1b | |||
| da8d6f678e | |||
| 548eb8f667 | |||
| 1fe39043ee | |||
| c2114491ca | |||
| 9f47c47cad | |||
| d6b39fd2c1 | |||
| 4d6d0ae539 | |||
| dda070f45c | |||
| b97a183e82 | |||
| 9433004307 | |||
| 9476838264 | |||
| 172edc4cf4 | |||
| 3c97e1b9a9 | |||
| a81968af3c |
@@ -109,6 +109,14 @@ jobs:
|
||||
- run: cd serde && cargo build --no-default-features
|
||||
- run: cd serde && cargo build
|
||||
|
||||
derive:
|
||||
name: Rust 1.31.0
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: dtolnay/rust-toolchain@1.31.0
|
||||
- run: cd serde_derive && cargo check
|
||||
|
||||
alloc:
|
||||
name: Rust 1.36.0
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
@@ -4,11 +4,6 @@ Serde welcomes contribution from everyone in the form of suggestions, bug
|
||||
reports, pull requests, and feedback. This document gives some guidance if you
|
||||
are thinking of helping us.
|
||||
|
||||
Please reach out here in a GitHub issue or in the #serde IRC channel on
|
||||
[`irc.mozilla.org`] if we can do anything to help you contribute.
|
||||
|
||||
[`irc.mozilla.org`]: https://wiki.mozilla.org/IRC
|
||||
|
||||
## Submitting bug reports and feature requests
|
||||
|
||||
Serde development is spread across lots of repositories, but this serde-rs/serde
|
||||
|
||||
@@ -75,13 +75,23 @@ fn main() {
|
||||
|
||||
## Getting help
|
||||
|
||||
Serde developers live in the #serde channel on [`irc.mozilla.org`][irc]. The
|
||||
\#rust channel is also a good resource with generally faster response time but
|
||||
less specific knowledge about Serde. If IRC is not your thing or you don't get a
|
||||
good response, we are happy to respond to [GitHub issues][issues] as well.
|
||||
Serde is one of the most widely used Rust libraries so any place that Rustaceans
|
||||
congregate will be able to help you out. For chat, consider trying the
|
||||
[#general] or [#beginners] channels of the unofficial community Discord, the
|
||||
[#rust-usage] channel of the official Rust Project Discord, or the
|
||||
[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag
|
||||
on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned
|
||||
weekly easy questions post, or the Rust [Discourse forum][discourse]. It's
|
||||
acceptable to file a support issue in this repo but they tend not to get as many
|
||||
eyes as any of the above and may get closed without a response after some time.
|
||||
|
||||
[irc]: https://wiki.mozilla.org/IRC
|
||||
[issues]: https://github.com/serde-rs/serde/issues/new/choose
|
||||
[#general]: https://discord.com/channels/273534239310479360/274215136414400513
|
||||
[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281
|
||||
[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
|
||||
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
|
||||
[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
|
||||
[/r/rust]: https://www.reddit.com/r/rust
|
||||
[discourse]: https://users.rust-lang.org
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
+16
-6
@@ -43,10 +43,20 @@ fn main() {
|
||||
|
||||
## Getting help
|
||||
|
||||
Serde developers live in the #serde channel on [`irc.mozilla.org`][irc]. The
|
||||
\#rust channel is also a good resource with generally faster response time but
|
||||
less specific knowledge about Serde. If IRC is not your thing or you don't get a
|
||||
good response, we are happy to respond to [GitHub issues][issues] as well.
|
||||
Serde is one of the most widely used Rust libraries so any place that Rustaceans
|
||||
congregate will be able to help you out. For chat, consider trying the
|
||||
[#general] or [#beginners] channels of the unofficial community Discord, the
|
||||
[#rust-usage] channel of the official Rust Project Discord, or the
|
||||
[#general][zulip] stream in Zulip. For asynchronous, consider the [\[rust\] tag
|
||||
on StackOverflow][stackoverflow], the [/r/rust] subreddit which has a pinned
|
||||
weekly easy questions post, or the Rust [Discourse forum][discourse]. It's
|
||||
acceptable to file a support issue in this repo but they tend not to get as many
|
||||
eyes as any of the above and may get closed without a response after some time.
|
||||
|
||||
[irc]: https://wiki.mozilla.org/IRC
|
||||
[issues]: https://github.com/serde-rs/serde/issues/new/choose
|
||||
[#general]: https://discord.com/channels/273534239310479360/274215136414400513
|
||||
[#beginners]: https://discord.com/channels/273534239310479360/273541522815713281
|
||||
[#rust-usage]: https://discord.com/channels/442252698964721669/443150878111694848
|
||||
[zulip]: https://rust-lang.zulipchat.com/#narrow/stream/122651-general
|
||||
[stackoverflow]: https://stackoverflow.com/questions/tagged/rust
|
||||
[/r/rust]: https://www.reddit.com/r/rust
|
||||
[discourse]: https://users.rust-lang.org
|
||||
|
||||
+3
-3
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde"
|
||||
version = "1.0.108" # remember to update html_root_url and serde_derive dependency
|
||||
version = "1.0.113" # remember to update html_root_url and serde_derive dependency
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "A generic serialization/deserialization framework"
|
||||
@@ -10,11 +10,11 @@ documentation = "https://docs.serde.rs/serde/"
|
||||
keywords = ["serde", "serialization", "no_std"]
|
||||
categories = ["encoding"]
|
||||
readme = "crates-io.md"
|
||||
include = ["Cargo.toml", "build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
build = "build.rs"
|
||||
|
||||
[dependencies]
|
||||
serde_derive = { version = "=1.0.108", optional = true, path = "../serde_derive" }
|
||||
serde_derive = { version = "=1.0.113", optional = true, path = "../serde_derive" }
|
||||
|
||||
[dev-dependencies]
|
||||
serde_derive = { version = "1.0", path = "../serde_derive" }
|
||||
|
||||
+1
-1
@@ -66,7 +66,7 @@ fn main() {
|
||||
}
|
||||
|
||||
// Non-zero integers stabilized in Rust 1.28:
|
||||
// https://github.com/rust-lang/rust/pull/50808
|
||||
// https://blog.rust-lang.org/2018/08/02/Rust-1.28.html#library-stabilizations
|
||||
if minor >= 28 {
|
||||
println!("cargo:rustc-cfg=num_nonzero");
|
||||
}
|
||||
|
||||
+10
-1
@@ -53,6 +53,10 @@
|
||||
//! *(deserialization only)*
|
||||
//! - [Envy Store], a way to deserialize [AWS Parameter Store] parameters into
|
||||
//! Rust structs. *(deserialization only)*
|
||||
//! - [S-expressions], the textual representation of code and data used by the
|
||||
//! Lisp language family.
|
||||
//! - [D-Bus]'s binary wire format.
|
||||
//! - [FlexBuffers], the schemaless cousin of Google's FlatBuffers zero-copy serialization format.
|
||||
//!
|
||||
//! [JSON]: https://github.com/serde-rs/json
|
||||
//! [Bincode]: https://github.com/TyOverby/bincode
|
||||
@@ -71,11 +75,14 @@
|
||||
//! [Envy Store]: https://github.com/softprops/envy-store
|
||||
//! [Cargo]: http://doc.crates.io/manifest.html
|
||||
//! [AWS Parameter Store]: https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-paramstore.html
|
||||
//! [S-expressions]: https://github.com/rotty/lexpr-rs
|
||||
//! [D-Bus]: https://docs.rs/zvariant
|
||||
//! [FlexBuffers]: https://github.com/google/flatbuffers/tree/master/rust/flexbuffers
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Serde types in rustdoc of other crates get linked to here.
|
||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.108")]
|
||||
#![doc(html_root_url = "https://docs.rs/serde/1.0.113")]
|
||||
// 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
|
||||
@@ -90,6 +97,8 @@
|
||||
#![cfg_attr(
|
||||
feature = "cargo-clippy",
|
||||
allow(
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
|
||||
unnested_or_patterns,
|
||||
// not available in our oldest supported compiler
|
||||
checked_conversions,
|
||||
empty_enum,
|
||||
|
||||
@@ -1562,7 +1562,7 @@ mod content {
|
||||
other.unexpected(),
|
||||
&"struct variant",
|
||||
)),
|
||||
_ => Err(de::Error::invalid_type(
|
||||
None => Err(de::Error::invalid_type(
|
||||
de::Unexpected::UnitVariant,
|
||||
&"struct variant",
|
||||
)),
|
||||
@@ -2252,7 +2252,7 @@ mod content {
|
||||
other.unexpected(),
|
||||
&"struct variant",
|
||||
)),
|
||||
_ => Err(de::Error::invalid_type(
|
||||
None => Err(de::Error::invalid_type(
|
||||
de::Unexpected::UnitVariant,
|
||||
&"struct variant",
|
||||
)),
|
||||
|
||||
@@ -1243,6 +1243,18 @@ where
|
||||
self.0.serialize_value(value)
|
||||
}
|
||||
|
||||
fn serialize_entry<K: ?Sized, V: ?Sized>(
|
||||
&mut self,
|
||||
key: &K,
|
||||
value: &V,
|
||||
) -> Result<(), Self::Error>
|
||||
where
|
||||
K: Serialize,
|
||||
V: Serialize,
|
||||
{
|
||||
self.0.serialize_entry(key, value)
|
||||
}
|
||||
|
||||
fn end(self) -> Result<(), Self::Error> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -616,7 +616,7 @@ impl Serialize for SystemTime {
|
||||
use super::SerializeStruct;
|
||||
let duration_since_epoch = self
|
||||
.duration_since(UNIX_EPOCH)
|
||||
.expect("SystemTime must be later than UNIX_EPOCH");
|
||||
.map_err(|_| S::Error::custom("SystemTime must be later than UNIX_EPOCH"))?;
|
||||
let mut state = try!(serializer.serialize_struct("SystemTime", 2));
|
||||
try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
|
||||
try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_derive"
|
||||
version = "1.0.108" # remember to update html_root_url
|
||||
version = "1.0.113" # remember to update html_root_url
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
|
||||
@@ -9,7 +9,7 @@ repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "https://serde.rs/derive.html"
|
||||
keywords = ["serde", "serialization", "no_std"]
|
||||
readme = "crates-io.md"
|
||||
include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
include = ["build.rs", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
use std::env;
|
||||
use std::process::Command;
|
||||
use std::str;
|
||||
|
||||
// The rustc-cfg strings below are *not* public API. Please let us know by
|
||||
// opening a GitHub issue if your build environment requires some way to enable
|
||||
// these cfgs other than by executing our build script.
|
||||
fn main() {
|
||||
let minor = match rustc_minor_version() {
|
||||
Some(minor) => minor,
|
||||
None => return,
|
||||
};
|
||||
|
||||
// Underscore const names stabilized in Rust 1.37:
|
||||
// https://blog.rust-lang.org/2019/08/15/Rust-1.37.0.html#using-unnamed-const-items-for-macros
|
||||
if minor >= 37 {
|
||||
println!("cargo:rustc-cfg=underscore_consts");
|
||||
}
|
||||
}
|
||||
|
||||
fn rustc_minor_version() -> Option<u32> {
|
||||
let rustc = env::var_os("RUSTC")?;
|
||||
let output = Command::new(rustc).arg("--version").output().ok()?;
|
||||
let version = str::from_utf8(&output.stdout).ok()?;
|
||||
let mut pieces = version.split('.');
|
||||
if pieces.next() != Some("rustc 1") {
|
||||
return None;
|
||||
}
|
||||
pieces.next()?.parse().ok()
|
||||
}
|
||||
@@ -5,7 +5,7 @@ use syn::punctuated::{Pair, Punctuated};
|
||||
use syn::visit::{self, Visit};
|
||||
|
||||
use internals::ast::{Container, Data};
|
||||
use internals::attr;
|
||||
use internals::{attr, ungroup};
|
||||
|
||||
use proc_macro2::Span;
|
||||
|
||||
@@ -114,7 +114,7 @@ pub fn with_bound(
|
||||
}
|
||||
impl<'ast> Visit<'ast> for FindTyParams<'ast> {
|
||||
fn visit_field(&mut self, field: &'ast syn::Field) {
|
||||
if let syn::Type::Path(ty) = &field.ty {
|
||||
if let syn::Type::Path(ty) = ungroup(&field.ty) {
|
||||
if let Some(Pair::Punctuated(t, _)) = ty.path.segments.pairs().next() {
|
||||
if self.all_type_params.contains(&t.ident) {
|
||||
self.associated_type_usage.push(ty);
|
||||
|
||||
+34
-29
@@ -8,7 +8,7 @@ use bound;
|
||||
use dummy;
|
||||
use fragment::{Expr, Fragment, Match, Stmts};
|
||||
use internals::ast::{Container, Data, Field, Style, Variant};
|
||||
use internals::{attr, Ctxt, Derive};
|
||||
use internals::{attr, ungroup, Ctxt, Derive};
|
||||
use pretend;
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
@@ -77,7 +77,7 @@ fn precondition(cx: &Ctxt, cont: &Container) {
|
||||
fn precondition_sized(cx: &Ctxt, cont: &Container) {
|
||||
if let Data::Struct(_, fields) = &cont.data {
|
||||
if let Some(last) = fields.last() {
|
||||
if let syn::Type::Slice(_) = *last.ty {
|
||||
if let syn::Type::Slice(_) = ungroup(last.ty) {
|
||||
cx.error_spanned_by(
|
||||
cont.original,
|
||||
"cannot deserialize a dynamically sized struct",
|
||||
@@ -1377,39 +1377,44 @@ fn deserialize_adjacently_tagged_enum(
|
||||
}
|
||||
};
|
||||
|
||||
fn is_unit(variant: &Variant) -> bool {
|
||||
match variant.style {
|
||||
Style::Unit => true,
|
||||
Style::Struct | Style::Tuple | Style::Newtype => false,
|
||||
}
|
||||
}
|
||||
|
||||
let mut missing_content = quote! {
|
||||
_serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
|
||||
};
|
||||
if variants.iter().any(is_unit) {
|
||||
let fallthrough = if variants.iter().all(is_unit) {
|
||||
None
|
||||
} else {
|
||||
Some(quote! {
|
||||
_ => #missing_content
|
||||
})
|
||||
};
|
||||
let arms = variants
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing() && is_unit(variant))
|
||||
.map(|(i, variant)| {
|
||||
let variant_index = field_i(i);
|
||||
let variant_ident = &variant.ident;
|
||||
quote! {
|
||||
__Field::#variant_index => _serde::export::Ok(#this::#variant_ident),
|
||||
let mut missing_content_fallthrough = quote!();
|
||||
let missing_content_arms = variants
|
||||
.iter()
|
||||
.enumerate()
|
||||
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
|
||||
.filter_map(|(i, variant)| {
|
||||
let variant_index = field_i(i);
|
||||
let variant_ident = &variant.ident;
|
||||
|
||||
let arm = match variant.style {
|
||||
Style::Unit => quote! {
|
||||
_serde::export::Ok(#this::#variant_ident)
|
||||
},
|
||||
Style::Newtype if variant.attrs.deserialize_with().is_none() => {
|
||||
let span = variant.original.span();
|
||||
let func = quote_spanned!(span=> _serde::private::de::missing_field);
|
||||
quote! {
|
||||
#func(#content).map(#this::#variant_ident)
|
||||
}
|
||||
}
|
||||
});
|
||||
_ => {
|
||||
missing_content_fallthrough = quote!(_ => #missing_content);
|
||||
return None;
|
||||
}
|
||||
};
|
||||
Some(quote! {
|
||||
__Field::#variant_index => #arm,
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
if !missing_content_arms.is_empty() {
|
||||
missing_content = quote! {
|
||||
match __field {
|
||||
#(#arms)*
|
||||
#fallthrough
|
||||
#(#missing_content_arms)*
|
||||
#missing_content_fallthrough
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use proc_macro2::{Ident, Span, TokenStream};
|
||||
use proc_macro2::{Ident, TokenStream};
|
||||
use quote::format_ident;
|
||||
|
||||
use syn;
|
||||
use try;
|
||||
@@ -11,10 +12,11 @@ pub fn wrap_in_const(
|
||||
) -> TokenStream {
|
||||
let try_replacement = try::replacement();
|
||||
|
||||
let dummy_const = Ident::new(
|
||||
&format!("_IMPL_{}_FOR_{}", trait_, unraw(ty)),
|
||||
Span::call_site(),
|
||||
);
|
||||
let dummy_const = if cfg!(underscore_consts) {
|
||||
format_ident!("_")
|
||||
} else {
|
||||
format_ident!("_IMPL_{}_FOR_{}", trait_, unraw(ty))
|
||||
};
|
||||
|
||||
let use_serde = match serde_path {
|
||||
Some(path) => quote! {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use internals::symbol::*;
|
||||
use internals::Ctxt;
|
||||
use internals::{ungroup, Ctxt};
|
||||
use proc_macro2::{Group, Span, TokenStream, TokenTree};
|
||||
use quote::ToTokens;
|
||||
use std::borrow::Cow;
|
||||
@@ -222,6 +222,7 @@ pub struct Container {
|
||||
identifier: Identifier,
|
||||
has_flatten: bool,
|
||||
serde_path: Option<syn::Path>,
|
||||
is_packed: bool,
|
||||
}
|
||||
|
||||
/// Styles of representing an enum.
|
||||
@@ -592,6 +593,16 @@ impl Container {
|
||||
}
|
||||
}
|
||||
|
||||
let mut is_packed = false;
|
||||
for attr in &item.attrs {
|
||||
if attr.path.is_ident("repr") {
|
||||
let _ = attr.parse_args_with(|input: ParseStream| {
|
||||
is_packed |= input.parse::<Ident>()? == "packed";
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Container {
|
||||
name: Name::from_attrs(unraw(&item.ident), ser_name, de_name, None),
|
||||
transparent: transparent.get(),
|
||||
@@ -611,6 +622,7 @@ impl Container {
|
||||
identifier: decide_identifier(cx, item, field_identifier, variant_identifier),
|
||||
has_flatten: false,
|
||||
serde_path: serde_path.get(),
|
||||
is_packed,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,6 +674,10 @@ impl Container {
|
||||
self.remote.as_ref()
|
||||
}
|
||||
|
||||
pub fn is_packed(&self) -> bool {
|
||||
self.is_packed
|
||||
}
|
||||
|
||||
pub fn identifier(&self) -> Identifier {
|
||||
self.identifier
|
||||
}
|
||||
@@ -1721,7 +1737,7 @@ fn is_implicitly_borrowed_reference(ty: &syn::Type) -> bool {
|
||||
// cow: Cow<'a, str>,
|
||||
// }
|
||||
fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
||||
let path = match ty {
|
||||
let path = match ungroup(ty) {
|
||||
syn::Type::Path(ty) => &ty.path,
|
||||
_ => {
|
||||
return false;
|
||||
@@ -1748,7 +1764,7 @@ fn is_cow(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
||||
}
|
||||
|
||||
fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
||||
let path = match ty {
|
||||
let path = match ungroup(ty) {
|
||||
syn::Type::Path(ty) => &ty.path,
|
||||
_ => {
|
||||
return false;
|
||||
@@ -1795,7 +1811,7 @@ fn is_option(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
||||
// r: &'a str,
|
||||
// }
|
||||
fn is_reference(ty: &syn::Type, elem: fn(&syn::Type) -> bool) -> bool {
|
||||
match ty {
|
||||
match ungroup(ty) {
|
||||
syn::Type::Reference(ty) => ty.mutability.is_none() && elem(&ty.elem),
|
||||
_ => false,
|
||||
}
|
||||
@@ -1806,14 +1822,14 @@ fn is_str(ty: &syn::Type) -> bool {
|
||||
}
|
||||
|
||||
fn is_slice_u8(ty: &syn::Type) -> bool {
|
||||
match ty {
|
||||
match ungroup(ty) {
|
||||
syn::Type::Slice(ty) => is_primitive_type(&ty.elem, "u8"),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_primitive_type(ty: &syn::Type, primitive: &str) -> bool {
|
||||
match ty {
|
||||
match ungroup(ty) {
|
||||
syn::Type::Path(ty) => ty.qself.is_none() && is_primitive_path(&ty.path, primitive),
|
||||
_ => false,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use internals::ast::{Container, Data, Field, Style};
|
||||
use internals::attr::{Identifier, TagType};
|
||||
use internals::{Ctxt, Derive};
|
||||
use internals::{ungroup, Ctxt, Derive};
|
||||
use syn::{Member, Type};
|
||||
|
||||
/// Cross-cutting checks that require looking at more than a single attrs
|
||||
@@ -396,7 +396,7 @@ fn member_message(member: &Member) -> String {
|
||||
}
|
||||
|
||||
fn allow_transparent(field: &Field, derive: Derive) -> bool {
|
||||
if let Type::Path(ty) = field.ty {
|
||||
if let Type::Path(ty) = ungroup(&field.ty) {
|
||||
if let Some(seg) = ty.path.segments.last() {
|
||||
if seg.ident == "PhantomData" {
|
||||
return false;
|
||||
|
||||
@@ -8,8 +8,17 @@ mod case;
|
||||
mod check;
|
||||
mod symbol;
|
||||
|
||||
use syn::Type;
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum Derive {
|
||||
Serialize,
|
||||
Deserialize,
|
||||
}
|
||||
|
||||
pub fn ungroup(mut ty: &Type) -> &Type {
|
||||
while let Type::Group(group) = ty {
|
||||
ty = &group.elem;
|
||||
}
|
||||
ty
|
||||
}
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
//!
|
||||
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.108")]
|
||||
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.113")]
|
||||
#![allow(unknown_lints, bare_trait_objects)]
|
||||
#![deny(clippy::all, clippy::pedantic)]
|
||||
// Ignored clippy lints
|
||||
@@ -24,7 +24,9 @@
|
||||
clippy::too_many_arguments,
|
||||
clippy::trivially_copy_pass_by_ref,
|
||||
clippy::used_underscore_binding,
|
||||
clippy::wildcard_in_or_patterns
|
||||
clippy::wildcard_in_or_patterns,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
|
||||
clippy::unnested_or_patterns,
|
||||
)]
|
||||
// Ignored clippy_pedantic lints
|
||||
#![allow(
|
||||
|
||||
+18
-2
@@ -87,6 +87,9 @@ struct Parameters {
|
||||
|
||||
/// Type has a `serde(remote = "...")` attribute.
|
||||
is_remote: bool,
|
||||
|
||||
/// Type has a repr(packed) attribute.
|
||||
is_packed: bool,
|
||||
}
|
||||
|
||||
impl Parameters {
|
||||
@@ -103,6 +106,8 @@ impl Parameters {
|
||||
None => cont.ident.clone().into(),
|
||||
};
|
||||
|
||||
let is_packed = cont.attrs.is_packed();
|
||||
|
||||
let generics = build_generics(cont);
|
||||
|
||||
Parameters {
|
||||
@@ -110,6 +115,7 @@ impl Parameters {
|
||||
this,
|
||||
generics,
|
||||
is_remote,
|
||||
is_packed,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1238,9 +1244,19 @@ fn mut_if(is_mut: bool) -> Option<TokenStream> {
|
||||
fn get_member(params: &Parameters, field: &Field, member: &Member) -> TokenStream {
|
||||
let self_var = ¶ms.self_var;
|
||||
match (params.is_remote, field.attrs.getter()) {
|
||||
(false, None) => quote!(&#self_var.#member),
|
||||
(false, None) => {
|
||||
if params.is_packed {
|
||||
quote!(&{#self_var.#member})
|
||||
} else {
|
||||
quote!(&#self_var.#member)
|
||||
}
|
||||
}
|
||||
(true, None) => {
|
||||
let inner = quote!(&#self_var.#member);
|
||||
let inner = if params.is_packed {
|
||||
quote!(&{#self_var.#member})
|
||||
} else {
|
||||
quote!(&#self_var.#member)
|
||||
};
|
||||
let ty = field.ty;
|
||||
quote!(_serde::private::ser::constrain::<#ty>(#inner))
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ homepage = "https://serde.rs"
|
||||
repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "https://docs.rs/serde_derive_internals"
|
||||
keywords = ["serde", "serialization"]
|
||||
include = ["Cargo.toml", "lib.rs", "src/**/*.rs", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
include = ["lib.rs", "src/**/*.rs", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
@@ -7,7 +7,9 @@
|
||||
cognitive_complexity,
|
||||
redundant_field_names,
|
||||
trivially_copy_pass_by_ref,
|
||||
wildcard_in_or_patterns
|
||||
wildcard_in_or_patterns,
|
||||
// clippy bug: https://github.com/rust-lang/rust-clippy/issues/5704
|
||||
unnested_or_patterns,
|
||||
)
|
||||
)]
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "serde_test"
|
||||
version = "1.0.108" # remember to update html_root_url
|
||||
version = "1.0.113" # remember to update html_root_url
|
||||
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
|
||||
license = "MIT OR Apache-2.0"
|
||||
description = "Token De/Serializer for testing De/Serialize implementations"
|
||||
@@ -9,7 +9,7 @@ repository = "https://github.com/serde-rs/serde"
|
||||
documentation = "https://docs.serde.rs/serde_test/"
|
||||
keywords = ["serde", "serialization"]
|
||||
readme = "crates-io.md"
|
||||
include = ["Cargo.toml", "src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
include = ["src/**/*.rs", "crates-io.md", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
|
||||
|
||||
[dependencies]
|
||||
serde = { version = "1.0.60", path = "../serde" }
|
||||
|
||||
@@ -144,7 +144,7 @@
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.108")]
|
||||
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.113")]
|
||||
#![cfg_attr(feature = "cargo-clippy", allow(renamed_and_removed_lints))]
|
||||
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
|
||||
// Ignored clippy lints
|
||||
|
||||
@@ -9,7 +9,7 @@ enum DeEnum<B, C, D> {
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_DeEnum: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -261,7 +261,7 @@ const _IMPL_SERIALIZE_FOR_DeEnum: () = {
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_DeEnum: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -10,7 +10,7 @@ struct DefaultTyParam<T: AssociatedType<X = i32> = i32> {
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_DefaultTyParam: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -45,7 +45,7 @@ const _IMPL_SERIALIZE_FOR_DefaultTyParam: () = {
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_DefaultTyParam: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -7,7 +7,7 @@ pub enum GenericEnum<T, U> {
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_GenericEnum: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -110,7 +110,7 @@ const _IMPL_SERIALIZE_FOR_GenericEnum: () = {
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_GenericEnum: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -4,7 +4,7 @@ pub struct GenericStruct<T> {
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_GenericStruct: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -38,7 +38,7 @@ const _IMPL_SERIALIZE_FOR_GenericStruct: () = {
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_GenericStruct: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -400,7 +400,7 @@ const _IMPL_DESERIALIZE_FOR_GenericStruct: () = {
|
||||
pub struct GenericNewTypeStruct<T>(T);
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_GenericNewTypeStruct: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -422,7 +422,7 @@ const _IMPL_SERIALIZE_FOR_GenericNewTypeStruct: () = {
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_GenericNewTypeStruct: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
||||
pub struct GenericTupleStruct<T, U>(T, U);
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_GenericTupleStruct: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -7,7 +7,7 @@ enum Lifetimes<'a> {
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_Lifetimes: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -91,7 +91,7 @@ const _IMPL_SERIALIZE_FOR_Lifetimes: () = {
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_Lifetimes: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -6,7 +6,7 @@ struct SerNamedMap<'a, 'b, A: 'a, B: 'b, C> {
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_SerNamedMap: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -59,7 +59,7 @@ struct DeNamedMap<A, B, C> {
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_DeNamedMap: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
||||
struct SerNamedTuple<'a, 'b, A: 'a, B: 'b, C>(&'a A, &'b mut B, C);
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_SerNamedTuple: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -51,7 +51,7 @@ const _IMPL_SERIALIZE_FOR_SerNamedTuple: () = {
|
||||
struct DeNamedTuple<A, B, C>(A, B, C);
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_DeNamedTuple: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
||||
struct NamedUnit;
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_NamedUnit: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -17,7 +17,7 @@ const _IMPL_SERIALIZE_FOR_NamedUnit: () = {
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_NamedUnit: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -12,7 +12,7 @@ where
|
||||
}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_SerEnum: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize};
|
||||
enum Void {}
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_SERIALIZE_FOR_Void: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
@@ -17,7 +17,7 @@ const _IMPL_SERIALIZE_FOR_Void: () = {
|
||||
};
|
||||
#[doc(hidden)]
|
||||
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
|
||||
const _IMPL_DESERIALIZE_FOR_Void: () = {
|
||||
const _: () = {
|
||||
#[allow(rust_2018_idioms, clippy::useless_attribute)]
|
||||
extern crate serde as _serde;
|
||||
#[automatically_derived]
|
||||
|
||||
@@ -701,6 +701,24 @@ fn test_gen() {
|
||||
#[serde(other)]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[repr(packed)]
|
||||
struct Packed {
|
||||
x: u8,
|
||||
y: u16,
|
||||
}
|
||||
|
||||
macro_rules! deriving {
|
||||
($field:ty) => {
|
||||
#[derive(Deserialize)]
|
||||
struct MacroRules<'a> {
|
||||
field: $field,
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
deriving!(&'a str);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -1145,6 +1145,20 @@ fn test_adjacently_tagged_enum() {
|
||||
],
|
||||
);
|
||||
|
||||
// optional newtype with no content field
|
||||
assert_de_tokens(
|
||||
&AdjacentlyTagged::Newtype::<Option<u8>>(None),
|
||||
&[
|
||||
Token::Struct {
|
||||
name: "AdjacentlyTagged",
|
||||
len: 1,
|
||||
},
|
||||
Token::Str("t"),
|
||||
Token::Str("Newtype"),
|
||||
Token::StructEnd,
|
||||
],
|
||||
);
|
||||
|
||||
// tuple with tag first
|
||||
assert_tokens(
|
||||
&AdjacentlyTagged::Tuple::<u8>(1, 1),
|
||||
|
||||
Reference in New Issue
Block a user