Compare commits

...

21 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
David Tolnay 797d049db5 Release 1.0.22 2017-11-29 20:01:43 -08:00
David Tolnay d61a373f12 Merge pull request #1104 from serde-rs/abs
Fix missing absolute paths in deserialize_seq
2017-11-29 19:58:21 -08:00
David Tolnay e0eea551b4 Fix missing absolute paths in deserialize_seq 2017-11-29 19:45:22 -08:00
David Tolnay c650a92bf7 Update to compiletest-rs 0.3 to fix "every suggestion should have at least one span" 2017-11-24 17:12:58 -08:00
David Tolnay f218f4d7bf Release 1.0.21 2017-11-15 22:24:18 -08:00
Alex Shapiro 8c0a2015be Fix error when deserializing untagged enum
Serde's `ContentDeserializer` and `ContentRefDeserializer`
cannot deserialize struct enum variant associated data when
that data is encoded as a sequence. This failure leads to
errors when decoding an enum nested in another untagged
enum. For example:

    #[derive(Serialize, Deserialize)]
    #[serde(untagged)]
    enum Foo {
        A(Bar),
    }

    #[derive(Serialize, Deserialize)]
    enum Bar {
        B{f1: String},
    }

    let data1 = Foo::A(Bar::B{f1: "Hello".into()});
    let bytes = rmp_serde::to_vec(&data1).unwrap();
    let data2 = rmp_serde::from_slice::<Foo>(&bytes).unwrap();

Deserializing fails with the error `Syntax("data did not
match any variant of untagged enum Foo")`, but the
underlying failure occurs when decoding the associated data
of `Bar::B`.

This pull request fixes the issue by allowing
`ContentDeserializer` and `ContentRefDeserializer` to
deserialize sequence-encoded struct enum variant data.
2017-11-15 21:56:33 -08:00
David Tolnay 4773863e3a Release 1.0.20 2017-11-12 10:29:08 -08:00
David Tolnay 80cd9c7617 Merge pull request #1091 from serde-rs/fields-len
Catch wrong field names length in serde_test
2017-11-12 10:28:26 -08:00
David Tolnay 436cafb0a3 Catch wrong field names length in serde_test 2017-11-12 10:16:43 -08:00
David Tolnay 98bb02e9b4 Whitelist use of Debug in serde_test 2017-11-07 10:00:18 -08:00
David Tolnay 142439088c Merge pull request #1086 from Marwes/better_errors
Print the contents of the expected token when a serialize assert fails
2017-11-07 09:53:58 -08:00
Markus Westerlind ce81288235 Print the contents of the expected token when a serialize assert fails
Before
```
expected Token::Str but serialized as Str(“F9168C5E-CEB2-4FAA-B6BF-329BF39FA1E4")
```
After
```
expected Token::Str(“f9168c5e-ceb2-4faa-b6bf-329bf39fa1e4”) but serialized as Str(“F9168C5E-CEB2-4FAA-B6BF-329BF39FA1E4")
```
2017-11-07 14:22:42 +01:00
20 changed files with 196 additions and 80 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.19" # 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.19")]
#![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)]
+7
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)
}
@@ -1246,6 +1247,9 @@ mod content {
Some(Content::Map(v)) => {
de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
}
Some(Content::Seq(v)) => {
de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
}
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),),
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),),
}
@@ -1640,6 +1644,9 @@ mod content {
Some(&Content::Map(ref v)) => {
de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
}
Some(&Content::Seq(ref v)) => {
de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
}
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),),
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),),
}
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.19" # 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]
+29 -6
View File
@@ -418,8 +418,8 @@ fn deserialize_seq(
};
let assign = quote! {
let #var = match #visit {
Some(__value) => __value,
None => {
_serde::export::Some(__value) => __value,
_serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
}
};
@@ -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.19")]
#![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.19" # 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"
+1 -1
View File
@@ -215,7 +215,7 @@ where
///
/// assert_de_tokens_error::<S>(
/// &[
/// Token::Struct { name: "S", len: 1 },
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("x"),
/// ],
/// "unknown field `x`, expected `a` or `b`",
+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 -1
View File
@@ -155,7 +155,7 @@
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.19")]
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.24")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
@@ -164,6 +164,7 @@
#![cfg_attr(feature = "cargo-clippy", allow(
missing_docs_in_private_items,
stutter,
use_debug,
use_self,
))]
+24 -6
View File
@@ -40,25 +40,43 @@ impl<'a> Serializer<'a> {
macro_rules! assert_next_token {
($ser:expr, $expected:ident) => {
assert_next_token!($ser, $expected, Token::$expected, true);
assert_next_token!($ser, stringify!($expected), Token::$expected, true);
};
($ser:expr, $expected:ident($v:expr)) => {
assert_next_token!($ser, $expected, Token::$expected(v), v == $v);
assert_next_token!(
$ser,
format_args!("{}({:?})", stringify!($expected), $v),
Token::$expected(v),
v == $v
);
};
($ser:expr, $expected:ident { $($k:ident),* }) => {
let compare = ($($k,)*);
assert_next_token!($ser, $expected, Token::$expected { $($k),* }, ($($k,)*) == compare);
let field_format = || {
use std::fmt::Write;
let mut buffer = String::new();
$(
write!(&mut buffer, "{}: {:?}, ", stringify!($k), $k).unwrap();
)*
buffer
};
assert_next_token!(
$ser,
format_args!("{} {{ {}}}", stringify!($expected), field_format()),
Token::$expected { $($k),* },
($($k,)*) == compare
);
};
($ser:expr, $expected:ident, $pat:pat, $guard:expr) => {
($ser:expr, $expected:expr, $pat:pat, $guard:expr) => {
match $ser.next_token() {
Some($pat) if $guard => {}
Some(other) => {
panic!("expected Token::{} but serialized as {}",
stringify!($expected), other);
$expected, other);
}
None => {
panic!("expected Token::{} after end of serialized tokens",
stringify!($expected));
$expected);
}
}
};
+1 -1
View File
@@ -15,4 +15,4 @@ serde_derive = { path = "../serde_derive" }
serde_test = { path = "../serde_test" }
[dependencies]
compiletest_rs = { version = "0.2", optional = true }
compiletest_rs = { version = "0.3", optional = true }
+4 -4
View File
@@ -135,7 +135,7 @@ fn test_default_struct() {
a5: 123,
},
&[
Token::Struct { name: "DefaultStruct", len: 1 },
Token::Struct { name: "DefaultStruct", len: 3 },
Token::Str("a1"),
Token::I32(1),
@@ -309,7 +309,7 @@ fn test_elt_not_deserialize() {
c: NotDeserializeStruct(123),
e: NotDeserializeEnum::Trouble,
},
&[Token::Struct { name: "ContainsNotDeserialize", len: 3 }, Token::StructEnd],
&[Token::Struct { name: "ContainsNotDeserialize", len: 1 }, Token::StructEnd],
);
}
@@ -331,7 +331,7 @@ fn test_ignore_unknown() {
a5: 123,
},
&[
Token::Struct { name: "DefaultStruct", len: 5 },
Token::Struct { name: "DefaultStruct", len: 3 },
Token::Str("whoops1"),
Token::I32(2),
@@ -359,7 +359,7 @@ fn test_ignore_unknown() {
assert_de_tokens_error::<DenyUnknown>(
&[
Token::Struct { name: "DenyUnknown", len: 2 },
Token::Struct { name: "DenyUnknown", len: 1 },
Token::Str("a1"),
Token::I32(1),
+28 -8
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 {
@@ -538,7 +552,7 @@ declare_tests! {
Token::MapEnd,
],
Struct { a: 1, b: 2, c: 0 } => &[
Token::Struct { name: "Struct", len: 3 },
Token::Struct { name: "Struct", len: 2 },
Token::Str("a"),
Token::I32(1),
@@ -570,7 +584,7 @@ declare_tests! {
Token::MapEnd,
],
Struct { a: 1, b: 2, c: 0 } => &[
Token::Struct { name: "Struct", len: 3 },
Token::Struct { name: "Struct", len: 2 },
Token::Str("a"),
Token::I32(1),
@@ -591,7 +605,7 @@ declare_tests! {
Token::StructEnd,
],
StructSkipAll { a: 0 } => &[
Token::Struct { name: "StructSkipAll", len: 1 },
Token::Struct { name: "StructSkipAll", len: 0 },
Token::Str("a"),
Token::I32(1),
@@ -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 },
@@ -608,7 +628,7 @@ declare_tests! {
}
test_struct_default {
StructDefault { a: 50, b: "overwritten".to_string() } => &[
Token::Struct { name: "StructDefault", len: 1 },
Token::Struct { name: "StructDefault", len: 2 },
Token::Str("a"),
Token::I32(50),
@@ -617,7 +637,7 @@ declare_tests! {
Token::StructEnd,
],
StructDefault { a: 100, b: "default".to_string() } => &[
Token::Struct { name: "StructDefault", len: 0 },
Token::Struct { name: "StructDefault", len: 2 },
Token::StructEnd,
],
}
@@ -954,7 +974,7 @@ fn test_cstr_internal_null_end() {
declare_error_tests! {
test_unknown_field<StructDenyUnknown> {
&[
Token::Struct { name: "StructDenyUnknown", len: 2 },
Token::Struct { name: "StructDenyUnknown", len: 1 },
Token::Str("a"),
Token::I32(0),
@@ -964,14 +984,14 @@ declare_error_tests! {
}
test_skipped_field_is_unknown<StructDenyUnknown> {
&[
Token::Struct { name: "StructDenyUnknown", len: 2 },
Token::Struct { name: "StructDenyUnknown", len: 1 },
Token::Str("b"),
],
"unknown field `b`, expected `a`",
}
test_skip_all_deny_unknown<StructSkipAllDenyUnknown> {
&[
Token::Struct { name: "StructSkipAllDenyUnknown", len: 1 },
Token::Struct { name: "StructSkipAllDenyUnknown", len: 0 },
Token::Str("a"),
],
"unknown field `a`, there are no fields",
+12 -5
View File
@@ -23,6 +23,7 @@ use self::serde::de::{DeserializeOwned, Deserializer};
use std::borrow::Cow;
use std::marker::PhantomData;
use std::option::Option as StdOption;
use std::result::Result as StdResult;
// Try to trip up the generated code if it fails to use fully qualified paths.
@@ -32,6 +33,12 @@ struct Result;
struct Ok;
#[allow(dead_code)]
struct Err;
#[allow(dead_code)]
struct Option;
#[allow(dead_code)]
struct Some;
#[allow(dead_code)]
struct None;
//////////////////////////////////////////////////////////////////////////
@@ -56,7 +63,7 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
struct WithRef<'a, T: 'a> {
#[serde(skip_deserializing)]
t: Option<&'a T>,
t: StdOption<&'a T>,
#[serde(serialize_with="ser_x", deserialize_with="de_x")]
x: X,
}
@@ -77,9 +84,9 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
struct NoBounds<T> {
t: T,
option: Option<T>,
option: StdOption<T>,
boxed: Box<T>,
option_boxed: Option<Box<T>>,
option_boxed: StdOption<Box<T>>,
}
assert::<NoBounds<i32>>();
@@ -175,8 +182,8 @@ fn test_gen() {
#[derive(Serialize)]
struct OptionStatic<'a> {
a: Option<&'a str>,
b: Option<&'static str>,
a: StdOption<&'a str>,
b: StdOption<&'static str>,
}
assert_ser::<OptionStatic>();
+21 -8
View File
@@ -786,7 +786,7 @@ fn test_adjacently_tagged_enum() {
}
// unit with no content
assert_tokens(
assert_ser_tokens(
&AdjacentlyTagged::Unit::<u8>,
&[
Token::Struct { name: "AdjacentlyTagged", len: 1 },
@@ -798,11 +798,24 @@ fn test_adjacently_tagged_enum() {
],
);
// unit with no content
assert_de_tokens(
&AdjacentlyTagged::Unit::<u8>,
&[
Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("t"),
Token::Str("Unit"),
Token::StructEnd,
],
);
// unit with tag first
assert_de_tokens(
&AdjacentlyTagged::Unit::<u8>,
&[
Token::Struct { name: "AdjacentlyTagged", len: 1 },
Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("t"),
Token::Str("Unit"),
@@ -818,7 +831,7 @@ fn test_adjacently_tagged_enum() {
assert_de_tokens(
&AdjacentlyTagged::Unit::<u8>,
&[
Token::Struct { name: "AdjacentlyTagged", len: 1 },
Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("c"),
Token::Unit,
@@ -834,7 +847,7 @@ fn test_adjacently_tagged_enum() {
assert_de_tokens(
&AdjacentlyTagged::Unit::<u8>,
&[
Token::Struct { name: "AdjacentlyTagged", len: 3 },
Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("f"),
Token::Unit,
@@ -975,7 +988,7 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
assert_de_tokens(
&AdjacentlyTagged::Unit,
&[
Token::Struct { name: "AdjacentlyTagged", len: 2},
Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("t"),
Token::Str("Unit"),
@@ -989,7 +1002,7 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
assert_de_tokens_error::<AdjacentlyTagged>(
&[
Token::Struct { name: "AdjacentlyTagged", len: 3},
Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("t"),
Token::Str("Unit"),
@@ -1004,7 +1017,7 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
assert_de_tokens_error::<AdjacentlyTagged>(
&[
Token::Struct { name: "AdjacentlyTagged", len: 3},
Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("h"),
],
@@ -1013,7 +1026,7 @@ fn test_adjacently_tagged_enum_deny_unknown_fields() {
assert_de_tokens_error::<AdjacentlyTagged>(
&[
Token::Struct { name: "AdjacentlyTagged", len: 3},
Token::Struct { name: "AdjacentlyTagged", len: 2 },
Token::Str("c"),
Token::Unit,