Compare commits

...

9 Commits

Author SHA1 Message Date
David Tolnay b7eb42aa6b Release 1.0.24 2017-12-09 14:43:55 -08:00
David Tolnay 750f8ba299 Clean up trailing whitespace 2017-12-09 14:42:59 -08:00
David Tolnay 49cdef074d Merge pull request #1115 from Binero/master
Solved #1105.
2017-12-08 08:57:31 -08:00
Jeroen Bollen aa86b04714 Adressed concerns raised by @oli-obk.
Specifically:
 - Change identation in `de.rs`.
 - Make `attr::Field` take a `attr::Default` as opposed to the entire parent `attr::Container`.
2017-12-08 15:13:05 +01:00
Jeroen Bollen c887a0b472 Solved #1105.
When a field should be skipped during deserialization, it will not use its own Default implementation
when the container structure has `#[serde(default)]` set.
2017-12-06 21:14:02 +01:00
David Tolnay 0c34e06e51 Merge pull request #1106 from khuey/inlines
Inline various deserialization helper methods.
2017-12-02 15:57:07 -08:00
Kyle Huey 4a0c4e0c25 Mark size_hint::cautious as inline. 2017-12-01 14:31:52 -08:00
David Tolnay 8c34e0940f Release 1.0.23 2017-11-29 22:26:32 -08:00
David Tolnay eb6bf16a51 Revert "Catch wrong field names length in serde_test"
There are at least two reasonable things to expect the len field to
check: the length of the fields array passed to deserialize_struct, or
the number of field tokens. Even beyond these, in some cases it can be
useful to test deserialization with a bogus len to test how the
Deserialize impl reacts to an incorrect size_hint.

This reverts commit 436cafb0a3 which was
released in serde_test 1.0.20.
2017-11-29 22:21:05 -08:00
16 changed files with 118 additions and 55 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.22" # remember to update html_root_url
version = "1.0.24" # 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"
+1 -1
View File
@@ -79,7 +79,7 @@
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.22")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.24")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
+1
View File
@@ -198,6 +198,7 @@ pub mod size_hint {
helper(iter.size_hint())
}
#[inline]
pub fn cautious(hint: Option<usize>) -> usize {
cmp::min(hint.unwrap_or(0), 4096)
}
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.22" # remember to update html_root_url
version = "1.0.24" # 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)]"
@@ -20,7 +20,7 @@ proc-macro = true
[dependencies]
quote = "0.3.8"
serde_derive_internals = { version = "=0.17.0", default-features = false, path = "../serde_derive_internals" }
serde_derive_internals = { version = "=0.18.0", default-features = false, path = "../serde_derive_internals" }
syn = { version = "0.11", features = ["visit"] }
[dev-dependencies]
+27 -4
View File
@@ -447,7 +447,30 @@ fn deserialize_seq(
};
}
let let_default = match *cattrs.default() {
attr::Default::Default => {
Some(
quote!(
let __default: Self::Value = _serde::export::Default::default();
),
)
}
attr::Default::Path(ref path) => {
Some(
quote!(
let __default: Self::Value = #path();
),
)
}
attr::Default::None => {
// We don't need the default value, to prevent an unused variable warning
// we'll leave the line empty.
None
}
};
quote_block! {
#let_default
#(#let_values)*
_serde::export::Ok(#result)
}
@@ -1701,15 +1724,15 @@ fn deserialize_map(
attr::Default::Default => {
Some(
quote!(
let __default: Self::Value = _serde::export::Default::default();
),
let __default: Self::Value = _serde::export::Default::default();
),
)
}
attr::Default::Path(ref path) => {
Some(
quote!(
let __default: Self::Value = #path();
),
let __default: Self::Value = #path();
),
)
}
attr::Default::None => {
+1 -1
View File
@@ -22,7 +22,7 @@
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.22")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.24")]
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
#![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))]
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive_internals"
version = "0.17.0" # remember to update html_root_url
version = "0.18.0" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "AST representation used by Serde derive macros. Unstable."
+42 -22
View File
@@ -49,9 +49,11 @@ impl<'a> Container<'a> {
let attrs = attr::Container::from_ast(cx, item);
let mut body = match item.body {
syn::Body::Enum(ref variants) => Body::Enum(enum_from_ast(cx, variants)),
syn::Body::Enum(ref variants) => {
Body::Enum(enum_from_ast(cx, variants, &attrs.default()))
}
syn::Body::Struct(ref variant_data) => {
let (style, fields) = struct_from_ast(cx, variant_data, None);
let (style, fields) = struct_from_ast(cx, variant_data, None, &attrs.default());
Body::Struct(style, fields)
}
};
@@ -98,36 +100,54 @@ impl<'a> Body<'a> {
}
}
fn enum_from_ast<'a>(cx: &Ctxt, variants: &'a [syn::Variant]) -> Vec<Variant<'a>> {
fn enum_from_ast<'a>(
cx: &Ctxt,
variants: &'a [syn::Variant],
container_default: &attr::Default,
) -> Vec<Variant<'a>> {
variants
.iter()
.map(
|variant| {
let attrs = attr::Variant::from_ast(cx, variant);
let (style, fields) = struct_from_ast(cx, &variant.data, Some(&attrs));
Variant {
ident: variant.ident.clone(),
attrs: attrs,
style: style,
fields: fields,
}
},
)
.map(|variant| {
let attrs = attr::Variant::from_ast(cx, variant);
let (style, fields) =
struct_from_ast(cx, &variant.data, Some(&attrs), container_default);
Variant {
ident: variant.ident.clone(),
attrs: attrs,
style: style,
fields: fields,
}
})
.collect()
}
fn struct_from_ast<'a>(cx: &Ctxt, data: &'a syn::VariantData, attrs: Option<&attr::Variant>) -> (Style, Vec<Field<'a>>) {
fn struct_from_ast<'a>(
cx: &Ctxt,
data: &'a syn::VariantData,
attrs: Option<&attr::Variant>,
container_default: &attr::Default,
) -> (Style, Vec<Field<'a>>) {
match *data {
syn::VariantData::Struct(ref fields) => (Style::Struct, fields_from_ast(cx, fields, attrs)),
syn::VariantData::Tuple(ref fields) if fields.len() == 1 => {
(Style::Newtype, fields_from_ast(cx, fields, attrs))
syn::VariantData::Struct(ref fields) => {
(Style::Struct, fields_from_ast(cx, fields, attrs, container_default))
}
syn::VariantData::Tuple(ref fields) if fields.len() == 1 => (
Style::Newtype,
fields_from_ast(cx, fields, attrs, container_default),
),
syn::VariantData::Tuple(ref fields) => {
(Style::Tuple, fields_from_ast(cx, fields, attrs, container_default))
}
syn::VariantData::Tuple(ref fields) => (Style::Tuple, fields_from_ast(cx, fields, attrs)),
syn::VariantData::Unit => (Style::Unit, Vec::new()),
}
}
fn fields_from_ast<'a>(cx: &Ctxt, fields: &'a [syn::Field], attrs: Option<&attr::Variant>) -> Vec<Field<'a>> {
fn fields_from_ast<'a>(
cx: &Ctxt,
fields: &'a [syn::Field],
attrs: Option<&attr::Variant>,
container_default: &attr::Default,
) -> Vec<Field<'a>> {
fields
.iter()
.enumerate()
@@ -135,7 +155,7 @@ fn fields_from_ast<'a>(cx: &Ctxt, fields: &'a [syn::Field], attrs: Option<&attr:
|(i, field)| {
Field {
ident: field.ident.clone(),
attrs: attr::Field::from_ast(cx, i, field, attrs),
attrs: attr::Field::from_ast(cx, i, field, attrs, container_default),
ty: &field.ty,
}
},
+11 -4
View File
@@ -714,7 +714,13 @@ pub enum Default {
impl Field {
/// Extract out the `#[serde(...)]` attributes from a struct field.
pub fn from_ast(cx: &Ctxt, index: usize, field: &syn::Field, attrs: Option<&Variant>) -> Self {
pub fn from_ast(
cx: &Ctxt,
index: usize,
field: &syn::Field,
attrs: Option<&Variant>,
container_default: &Default,
) -> Self {
let mut ser_name = Attr::none(cx, "rename");
let mut de_name = Attr::none(cx, "rename");
let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
@@ -881,9 +887,10 @@ impl Field {
}
}
// Is skip_deserializing, initialize the field to Default::default()
// unless a different default is specified by `#[serde(default = "...")]`
if skip_deserializing.0.value.is_some() {
// 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 container_default == &Default::None && skip_deserializing.0.value.is_some() {
default.set_if_none(Default::Default);
}
+1 -1
View File
@@ -6,7 +6,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.17.0")]
#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.18.0")]
extern crate syn;
#[macro_use]
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_test"
version = "1.0.22" # remember to update html_root_url
version = "1.0.24" # 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"
+6 -6
View File
@@ -11,17 +11,17 @@ pub struct Compact<T: ?Sized>(T);
/// Trait to determine whether a value is represented in human-readable or
/// compact form.
///
///
/// ```
/// extern crate serde;
/// extern crate serde_test;
///
///
/// use serde::{Deserialize, Deserializer, Serialize, Serializer};
/// use serde_test::{Configure, Token, assert_tokens};
///
///
/// #[derive(Debug, PartialEq)]
/// struct Example(u8, u8);
///
///
/// impl Serialize for Example {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer,
@@ -33,7 +33,7 @@ pub struct Compact<T: ?Sized>(T);
/// }
/// }
/// }
///
///
/// impl<'de> Deserialize<'de> for Example {
/// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
/// where D: Deserializer<'de>,
@@ -52,7 +52,7 @@ pub struct Compact<T: ?Sized>(T);
/// }
/// }
/// }
///
///
/// fn main() {
/// assert_tokens(
/// &Example(1, 0).compact(),
+2 -2
View File
@@ -352,8 +352,8 @@ impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
V: Visitor<'de>,
{
match self.peek_token() {
Token::Struct { .. } => {
assert_next_token!(self, Token::Struct { name: name, len: fields.len() });
Token::Struct { len: n, .. } => {
assert_next_token!(self, Token::Struct { name: name, len: n });
self.visit_map(Some(fields.len()), Token::StructEnd, visitor)
}
Token::Map { .. } => {
+1 -1
View File
@@ -155,7 +155,7 @@
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.22")]
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.24")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
-8
View File
@@ -425,10 +425,6 @@ pub enum Token {
/// The header of a struct.
///
/// When testing deserialization, the `len` field must match the number of
/// fields that the struct expects to deserialize. This may be different
/// from the number of fields contained in the input tokens.
///
/// After this header are the fields of the struct, followed by `StructEnd`.
///
/// ```rust
@@ -465,10 +461,6 @@ pub enum Token {
/// The header of a struct variant of an enum.
///
/// When testing deserialization, the `len` field must match the number of
/// fields that the struct variant expects to deserialize. This may be
/// different from the number of fields contained in the input tokens.
///
/// After this header are the fields of the struct variant, followed by
/// `StructVariantEnd`.
///
+20
View File
@@ -80,6 +80,20 @@ struct StructSkipAll {
#[serde(skip_deserializing)] a: i32,
}
#[derive(PartialEq, Debug, Deserialize)]
#[serde(default)]
struct StructSkipDefault {
#[serde(skip_deserializing)] a: i32,
}
impl Default for StructSkipDefault {
fn default() -> Self {
StructSkipDefault {
a: 16,
}
}
}
#[derive(PartialEq, Debug, Deserialize)]
#[serde(deny_unknown_fields)]
struct StructSkipAllDenyUnknown {
@@ -600,6 +614,12 @@ declare_tests! {
Token::StructEnd,
],
}
test_struct_skip_default {
StructSkipDefault { a: 16 } => &[
Token::Struct { name: "StructSkipDefault", len: 0 },
Token::StructEnd,
],
}
test_struct_skip_all_deny_unknown {
StructSkipAllDenyUnknown { a: 0 } => &[
Token::Struct { name: "StructSkipAllDenyUnknown", len: 0 },