Compare commits

...

30 Commits

Author SHA1 Message Date
David Tolnay 893c0578dd Release 1.0.44 2018-05-01 22:34:27 -07:00
David Tolnay cb2b92f828 Handle flatten + deserialize_with 2018-05-01 22:25:06 -07:00
David Tolnay 47a4ffbd31 Fill in missing fully qualified paths in flatten 2018-05-01 22:24:25 -07:00
David Tolnay d82d1707d6 Format with rustfmt 0.6.0 2018-04-30 01:42:46 -07:00
David Tolnay 89278996c5 Release 1.0.43 2018-04-23 11:23:58 -07:00
David Tolnay ecef937e26 Merge pull request #1234 from serde-rs/newtype
Unpack a layer of NewtypeStruct when content is newtype
2018-04-23 11:23:21 -07:00
David Tolnay bceda5fb18 Unpack a layer of NewtypeStruct when content is newtype 2018-04-23 11:04:42 -07:00
David Tolnay f46a08b04e Merge pull request #1231 from ignatenkobrain/patch-1
derive: bump min version of quote to 0.5.2
2018-04-22 16:48:11 -07:00
Igor Gnatenko f3cb7c7a32 derive: bump min version of quote to 0.5.2
Fixes: https://github.com/serde-rs/serde/issues/1230
2018-04-22 09:22:47 +02:00
David Tolnay af795e2e54 Release 1.0.42 2018-04-21 15:16:10 -07:00
David Tolnay 6aa07fe0d6 Merge pull request #1229 from serde-rs/cold
Mark error construction as cold code
2018-04-21 14:57:11 -07:00
David Tolnay c455720f81 Mark error construction as cold code
This eliminates 12% of the Serde-related code in the Xi release binary
as measured by:

nm -S target/release/xi-core \
    | awk '/serde/{sum += strtonum("0x"$2)} END{print sum}'
2018-04-21 14:41:14 -07:00
David Tolnay b07a208716 Merge pull request #1228 from serde-rs/untagged
Reduce instantiations of Result::map in Deserialize of unit variants
2018-04-21 13:46:36 -07:00
David Tolnay df93fab5fa Reduce instantiations of Result::map in Deserialize of unit variants
This eliminates 110 instantiations of Result::map in Xi and reduces
binary size by 229 kilobytes.
2018-04-21 13:27:17 -07:00
David Tolnay 1a972d2105 Merge pull request #1227 from serde-rs/ser
Improve Serialize of adjacently tagged newtype variants
2018-04-21 12:10:28 -07:00
David Tolnay 6d1807bb4a Improve Serialize of adjacently tagged newtype variants
The existing implementation was unnecessarily complicated.

    struct __AdjacentlyTagged<'__a> {
        data: (&'__a String,),
        phantom: _serde::export::PhantomData<AdjacentlyTagged>,
    }
    impl<'__a> _serde::Serialize for __AdjacentlyTagged<'__a> {
        fn serialize<__S>(
            &self,
            __serializer: __S,
        ) -> _serde::export::Result<__S::Ok, __S::Error>
        where
            __S: _serde::Serializer,
        {
            let (__field0,) = self.data;
            _serde::Serialize::serialize(__field0, __serializer)
        }
    }
    _serde::ser::SerializeStruct::serialize_field(
        &mut __struct,
        "content",
        &__AdjacentlyTagged {
            data: (__field0,),
            phantom: _serde::export::PhantomData::<AdjacentlyTagged>,
        },
    )?;

Instead the new implementation does simply:

    _serde::ser::SerializeStruct::serialize_field(
        &mut __struct,
        "content",
        __field0,
    )?;
2018-04-21 11:41:39 -07:00
David Tolnay b37cf858ce Remove unneeded quote_spanned that uses call_site 2018-04-21 11:33:39 -07:00
David Tolnay 5f8fa33756 Quote's default has changed to call_site 2018-04-21 11:33:38 -07:00
David Tolnay f3f006f411 Merge pull request #1226 from serde-rs/try
More efficient try!() alternative
2018-04-21 11:33:28 -07:00
David Tolnay 607966dcf7 Fix error message type inference in compile-fail/remote/wrong_de.rs 2018-04-21 11:21:13 -07:00
David Tolnay 6a8c39b2aa More efficient try!() alternative 2018-04-21 10:53:13 -07:00
David Tolnay 382f3c2771 Release 1.0.41 2018-04-19 22:13:45 -07:00
David Tolnay 85ca12a8c3 Deserialize any integer from any buffered integer type 2018-04-19 22:11:14 -07:00
David Tolnay 541f9180cf Release 1.0.40 2018-04-19 10:31:33 -07:00
David Tolnay 3c4961c48e Lenient byte and string deserialization from buffered content 2018-04-19 10:21:55 -07:00
David Tolnay 184264ee92 Release 1.0.39 2018-04-17 11:35:45 -07:00
David Tolnay 6050229e7e Simplify counting remaining elements 2018-04-17 00:15:09 -07:00
David Tolnay e1db820c9f Implement all &Content deserializer hints 2018-04-17 00:15:05 -07:00
David Tolnay 0081cc961d Implement all Content deserializer hints 2018-04-17 00:14:59 -07:00
David Tolnay 9bc05803fe Fix clippy lint about literal in format string 2018-04-15 22:07:47 -07:00
22 changed files with 1271 additions and 304 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "1.0.38" # remember to update html_root_url
version = "1.0.44" # 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"
+7
View File
@@ -196,6 +196,7 @@ macro_rules! declare_error_trait {
/// For example if we try to deserialize a String out of a JSON file
/// containing an integer, the unexpected type is the integer and the
/// expected type is the string.
#[cold]
fn invalid_type(unexp: Unexpected, exp: &Expected) -> Self {
Error::custom(format_args!("invalid type: {}, expected {}", unexp, exp))
}
@@ -213,6 +214,7 @@ macro_rules! declare_error_trait {
/// For example if we try to deserialize a String out of some binary data
/// that is not valid UTF-8, the unexpected value is the bytes and the
/// expected value is a string.
#[cold]
fn invalid_value(unexp: Unexpected, exp: &Expected) -> Self {
Error::custom(format_args!("invalid value: {}, expected {}", unexp, exp))
}
@@ -226,12 +228,14 @@ macro_rules! declare_error_trait {
/// The `exp` argument provides information about what data was being
/// expected. For example `exp` might say that a tuple of size 6 was
/// expected.
#[cold]
fn invalid_length(len: usize, exp: &Expected) -> Self {
Error::custom(format_args!("invalid length {}, expected {}", len, exp))
}
/// Raised when a `Deserialize` enum type received a variant with an
/// unrecognized name.
#[cold]
fn unknown_variant(variant: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() {
Error::custom(format_args!("unknown variant `{}`, there are no variants",
@@ -245,6 +249,7 @@ macro_rules! declare_error_trait {
/// Raised when a `Deserialize` struct type received a field with an
/// unrecognized name.
#[cold]
fn unknown_field(field: &str, expected: &'static [&'static str]) -> Self {
if expected.is_empty() {
Error::custom(format_args!("unknown field `{}`, there are no fields",
@@ -259,12 +264,14 @@ macro_rules! declare_error_trait {
/// Raised when a `Deserialize` struct type expected to receive a required
/// field with a particular name but that field was not present in the
/// input.
#[cold]
fn missing_field(field: &'static str) -> Self {
Error::custom(format_args!("missing field `{}`", field))
}
/// Raised when a `Deserialize` struct type received more than one of the
/// same field.
#[cold]
fn duplicate_field(field: &'static str) -> Self {
Error::custom(format_args!("duplicate field `{}`", field))
}
+7 -10
View File
@@ -58,6 +58,7 @@ type ErrorImpl = ();
impl de::Error for Error {
#[cfg(any(feature = "std", feature = "alloc"))]
#[cold]
fn custom<T>(msg: T) -> Self
where
T: Display,
@@ -68,6 +69,7 @@ impl de::Error for Error {
}
#[cfg(not(any(feature = "std", feature = "alloc")))]
#[cold]
fn custom<T>(msg: T) -> Self
where
T: Display,
@@ -78,6 +80,7 @@ impl de::Error for Error {
}
impl ser::Error for Error {
#[cold]
fn custom<T>(msg: T) -> Self
where
T: Display,
@@ -652,11 +655,8 @@ where
{
/// Check for remaining elements after passing a `SeqDeserializer` to
/// `Visitor::visit_seq`.
pub fn end(mut self) -> Result<(), E> {
let mut remaining = 0;
while self.iter.next().is_some() {
remaining += 1;
}
pub fn end(self) -> Result<(), E> {
let remaining = self.iter.count();
if remaining == 0 {
Ok(())
} else {
@@ -849,11 +849,8 @@ where
{
/// Check for remaining elements after passing a `MapDeserializer` to
/// `Visitor::visit_map`.
pub fn end(mut self) -> Result<(), E> {
let mut remaining = 0;
while self.iter.next().is_some() {
remaining += 1;
}
pub fn end(self) -> Result<(), E> {
let remaining = self.iter.count();
if remaining == 0 {
Ok(())
} else {
+3
View File
@@ -16,6 +16,9 @@ pub use lib::result::Result::{self, Err, Ok};
pub use self::string::from_utf8_lossy;
#[cfg(any(feature = "alloc", feature = "std"))]
pub use lib::Vec;
mod string {
use lib::*;
+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.38")]
#![doc(html_root_url = "https://docs.rs/serde/1.0.44")]
// 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
+618 -67
View File
@@ -229,8 +229,8 @@ mod content {
use lib::*;
use super::size_hint;
use de::{self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, MapAccess, SeqAccess,
Unexpected, Visitor};
use de::{self, Deserialize, DeserializeSeed, Deserializer, EnumAccess, Expected, MapAccess,
SeqAccess, Unexpected, Visitor};
/// Used from generated code to buffer the contents of the Deserializer when
/// deserializing untagged enums and internally tagged enums.
@@ -277,6 +277,7 @@ mod content {
}
}
#[cold]
fn unexpected(&self) -> Unexpected {
match *self {
Content::Bool(b) => Unexpected::Bool(b),
@@ -1013,6 +1014,62 @@ mod content {
err: PhantomData<E>,
}
impl<'de, E> ContentDeserializer<'de, E>
where
E: de::Error,
{
#[cold]
fn invalid_type(self, exp: &Expected) -> E {
de::Error::invalid_type(self.content.unexpected(), exp)
}
fn deserialize_integer<V>(self, visitor: V) -> Result<V::Value, E>
where
V: Visitor<'de>,
{
match self.content {
Content::U8(v) => visitor.visit_u8(v),
Content::U16(v) => visitor.visit_u16(v),
Content::U32(v) => visitor.visit_u32(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I8(v) => visitor.visit_i8(v),
Content::I16(v) => visitor.visit_i16(v),
Content::I32(v) => visitor.visit_i32(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
}
}
fn visit_content_seq<'de, V, E>(content: Vec<Content<'de>>, visitor: V) -> Result<V::Value, E>
where
V: Visitor<'de>,
E: de::Error,
{
let seq = content.into_iter().map(ContentDeserializer::new);
let mut seq_visitor = de::value::SeqDeserializer::new(seq);
let value = try!(visitor.visit_seq(&mut seq_visitor));
try!(seq_visitor.end());
Ok(value)
}
fn visit_content_map<'de, V, E>(
content: Vec<(Content<'de>, Content<'de>)>,
visitor: V,
) -> Result<V::Value, E>
where
V: Visitor<'de>,
E: de::Error,
{
let map = content
.into_iter()
.map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
let mut map_visitor = de::value::MapDeserializer::new(map);
let value = try!(visitor.visit_map(&mut map_visitor));
try!(map_visitor.end());
Ok(value)
}
/// Used when deserializing an internally tagged enum because the content will
/// be used exactly once.
impl<'de, E> Deserializer<'de> for ContentDeserializer<'de, E>
@@ -1046,21 +1103,152 @@ mod content {
Content::None => visitor.visit_none(),
Content::Some(v) => visitor.visit_some(ContentDeserializer::new(*v)),
Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)),
Content::Seq(v) => {
let seq = v.into_iter().map(ContentDeserializer::new);
let mut seq_visitor = de::value::SeqDeserializer::new(seq);
let value = try!(visitor.visit_seq(&mut seq_visitor));
try!(seq_visitor.end());
Ok(value)
}
Content::Map(v) => {
let map = v.into_iter()
.map(|(k, v)| (ContentDeserializer::new(k), ContentDeserializer::new(v)));
let mut map_visitor = de::value::MapDeserializer::new(map);
let value = try!(visitor.visit_map(&mut map_visitor));
try!(map_visitor.end());
Ok(value)
}
Content::Seq(v) => visit_content_seq(v, visitor),
Content::Map(v) => visit_content_map(v, visitor),
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::Bool(v) => visitor.visit_bool(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::F32(v) => visitor.visit_f32(v),
Content::F64(v) => visitor.visit_f64(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::F64(v) => visitor.visit_f64(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::Char(v) => visitor.visit_char(v),
Content::String(v) => visitor.visit_string(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_string(visitor)
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::String(v) => visitor.visit_string(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(v) => visitor.visit_byte_buf(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_byte_buf(visitor)
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::String(v) => visitor.visit_string(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(v) => visitor.visit_byte_buf(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::Seq(v) => visit_content_seq(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
@@ -1076,6 +1264,44 @@ mod content {
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::Unit => visitor.visit_unit(),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_unit_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
// As a special case, allow deserializing untagged newtype
// variant containing unit struct.
//
// #[derive(Deserialize)]
// struct Info;
//
// #[derive(Deserialize)]
// #[serde(tag = "topic")]
// enum Message {
// Info(Info),
// }
//
// We want {"topic":"Info"} to deserialize even though
// ordinarily unit structs do not deserialize from empty map.
Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
_ => self.deserialize_any(visitor),
}
}
fn deserialize_newtype_struct<V>(
self,
_name: &str,
@@ -1084,7 +1310,65 @@ mod content {
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
match self.content {
Content::Newtype(v) => visitor.visit_newtype_struct(ContentDeserializer::new(*v)),
_ => visitor.visit_newtype_struct(self),
}
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::Seq(v) => visit_content_seq(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::Map(v) => visit_content_map(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
Content::Seq(v) => visit_content_seq(v, visitor),
Content::Map(v) => visit_content_map(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_enum<V>(
@@ -1129,38 +1413,23 @@ mod content {
visitor.visit_enum(EnumDeserializer::new(variant, value))
}
fn deserialize_unit_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match self.content {
// As a special case, allow deserializing untagged newtype
// variant containing unit struct.
//
// #[derive(Deserialize)]
// struct Info;
//
// #[derive(Deserialize)]
// #[serde(tag = "topic")]
// enum Message {
// Info(Info),
// }
//
// We want {"topic":"Info"} to deserialize even though
// ordinarily unit structs do not deserialize from empty map.
Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
_ => self.deserialize_any(visitor),
Content::String(v) => visitor.visit_string(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
_ => Err(self.invalid_type(&visitor)),
}
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf unit seq tuple tuple_struct map struct identifier
ignored_any
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
drop(self);
visitor.visit_unit()
}
}
@@ -1452,6 +1721,68 @@ mod content {
err: PhantomData<E>,
}
impl<'a, 'de, E> ContentRefDeserializer<'a, 'de, E>
where
E: de::Error,
{
#[cold]
fn invalid_type(self, exp: &Expected) -> E {
de::Error::invalid_type(self.content.unexpected(), exp)
}
fn deserialize_integer<V>(self, visitor: V) -> Result<V::Value, E>
where
V: Visitor<'de>,
{
match *self.content {
Content::U8(v) => visitor.visit_u8(v),
Content::U16(v) => visitor.visit_u16(v),
Content::U32(v) => visitor.visit_u32(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I8(v) => visitor.visit_i8(v),
Content::I16(v) => visitor.visit_i16(v),
Content::I32(v) => visitor.visit_i32(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
}
}
fn visit_content_seq_ref<'a, 'de, V, E>(
content: &'a [Content<'de>],
visitor: V,
) -> Result<V::Value, E>
where
V: Visitor<'de>,
E: de::Error,
{
let seq = content.into_iter().map(ContentRefDeserializer::new);
let mut seq_visitor = de::value::SeqDeserializer::new(seq);
let value = try!(visitor.visit_seq(&mut seq_visitor));
try!(seq_visitor.end());
Ok(value)
}
fn visit_content_map_ref<'a, 'de, V, E>(
content: &'a [(Content<'de>, Content<'de>)],
visitor: V,
) -> Result<V::Value, E>
where
V: Visitor<'de>,
E: de::Error,
{
let map = content.into_iter().map(|&(ref k, ref v)| {
(
ContentRefDeserializer::new(k),
ContentRefDeserializer::new(v),
)
});
let mut map_visitor = de::value::MapDeserializer::new(map);
let value = try!(visitor.visit_map(&mut map_visitor));
try!(map_visitor.end());
Ok(value)
}
/// 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>
@@ -1487,28 +1818,155 @@ mod content {
Content::Newtype(ref v) => {
visitor.visit_newtype_struct(ContentRefDeserializer::new(v))
}
Content::Seq(ref v) => {
let seq = v.into_iter().map(ContentRefDeserializer::new);
let mut seq_visitor = de::value::SeqDeserializer::new(seq);
let value = try!(visitor.visit_seq(&mut seq_visitor));
try!(seq_visitor.end());
Ok(value)
}
Content::Map(ref v) => {
let map = v.into_iter().map(|&(ref k, ref v)| {
(
ContentRefDeserializer::new(k),
ContentRefDeserializer::new(v),
)
});
let mut map_visitor = de::value::MapDeserializer::new(map);
let value = try!(visitor.visit_map(&mut map_visitor));
try!(map_visitor.end());
Ok(value)
}
Content::Seq(ref v) => visit_content_seq_ref(v, visitor),
Content::Map(ref v) => visit_content_map_ref(v, visitor),
}
}
fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::Bool(v) => visitor.visit_bool(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_integer(visitor)
}
fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::F32(v) => visitor.visit_f32(v),
Content::F64(v) => visitor.visit_f64(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::F64(v) => visitor.visit_f64(v),
Content::U64(v) => visitor.visit_u64(v),
Content::I64(v) => visitor.visit_i64(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_char<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::Char(v) => visitor.visit_char(v),
Content::String(ref v) => visitor.visit_str(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_str<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::String(ref v) => visitor.visit_str(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(ref v) => visitor.visit_bytes(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_string<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_str(visitor)
}
fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::String(ref v) => visitor.visit_str(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
Content::ByteBuf(ref v) => visitor.visit_bytes(v),
Content::Bytes(v) => visitor.visit_borrowed_bytes(v),
Content::Seq(ref v) => visit_content_seq_ref(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_bytes(visitor)
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, E>
where
V: Visitor<'de>,
@@ -1521,11 +1979,92 @@ mod content {
}
}
fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::Unit => visitor.visit_unit(),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_unit_struct<V>(
self,
_name: &'static str,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_unit(visitor)
}
fn deserialize_newtype_struct<V>(self, _name: &str, visitor: V) -> Result<V::Value, E>
where
V: Visitor<'de>,
{
visitor.visit_newtype_struct(self)
match *self.content {
Content::Newtype(ref v) => {
visitor.visit_newtype_struct(ContentRefDeserializer::new(v))
}
_ => visitor.visit_newtype_struct(self),
}
}
fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::Seq(ref v) => visit_content_seq_ref(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_tuple_struct<V>(
self,
_name: &'static str,
_len: usize,
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
self.deserialize_seq(visitor)
}
fn deserialize_map<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::Map(ref v) => visit_content_map_ref(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_struct<V>(
self,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::Seq(ref v) => visit_content_seq_ref(v, visitor),
Content::Map(ref v) => visit_content_map_ref(v, visitor),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_enum<V>(
@@ -1574,10 +2113,22 @@ mod content {
})
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf unit unit_struct seq tuple tuple_struct map struct
identifier ignored_any
fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
match *self.content {
Content::String(ref v) => visitor.visit_str(v),
Content::Str(v) => visitor.visit_borrowed_str(v),
_ => Err(self.invalid_type(&visitor)),
}
}
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>,
{
visitor.visit_unit()
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "1.0.38" # remember to update html_root_url
version = "1.0.44" # 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)]"
@@ -24,7 +24,7 @@ proc-macro = true
[dependencies]
proc-macro2 = "0.3"
quote = "0.5"
quote = "0.5.2"
serde_derive_internals = { version = "=0.23.1", default-features = false, path = "../serde_derive_internals" }
syn = { version = "0.13", features = ["visit"] }
+57 -51
View File
@@ -16,6 +16,7 @@ use bound;
use fragment::{Expr, Fragment, Match, Stmts};
use internals::ast::{Container, Data, Field, Style, Variant};
use internals::{self, attr};
use try;
use std::collections::BTreeSet;
@@ -36,10 +37,9 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis;
let fun = quote_spanned!(Span::call_site()=> deserialize);
quote! {
impl #de_impl_generics #ident #ty_generics #where_clause {
#vis fn #fun<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
#vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
where __D: _serde::Deserializer<#delife>
{
#body
@@ -63,10 +63,12 @@ pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, Str
}
};
let try_replacement = try::replacement();
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
extern crate serde as _serde;
#try_replacement
#impl_block
};
};
@@ -583,11 +585,11 @@ fn deserialize_seq(
let mut result = if is_struct {
let names = fields.iter().map(|f| &f.ident);
quote_spanned! {Span::call_site()=>
quote! {
#type_path { #( #names: #vars ),* }
}
} else {
quote_spanned! {Span::call_site()=>
quote! {
#type_path ( #(#vars),* )
}
};
@@ -649,11 +651,10 @@ fn deserialize_seq_in_place(
})
});
let dot = quote_spanned!(Span::call_site()=> .);
if field.attrs.skip_deserializing() {
let default = Expr(expr_is_missing(field, cattrs));
quote! {
self.place #dot #field_name = #default;
self.place.#field_name = #default;
}
} else {
let return_invalid_length = quote! {
@@ -663,7 +664,7 @@ fn deserialize_seq_in_place(
None => {
quote! {
if let _serde::export::None = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
_serde::private::de::InPlaceSeed(&mut self.place #dot #field_name)))
_serde::private::de::InPlaceSeed(&mut self.place.#field_name)))
{
#return_invalid_length
}
@@ -676,7 +677,7 @@ fn deserialize_seq_in_place(
#wrapper
match try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)) {
_serde::export::Some(__wrap) => {
self.place #dot #field_name = __wrap.value;
self.place.#field_name = __wrap.value;
}
_serde::export::None => {
#return_invalid_length
@@ -732,7 +733,7 @@ fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &F
}
};
let mut result = quote_spanned!(Span::call_site()=> #type_path(#value));
let mut result = quote!(#type_path(__field0));
if params.has_getter {
let this = &params.this;
result = quote! {
@@ -745,6 +746,7 @@ fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &F
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
where __E: _serde::Deserializer<#delife>
{
let __field0 = #value;
_serde::export::Ok(#result)
}
}
@@ -757,13 +759,12 @@ fn deserialize_newtype_struct_in_place(params: &Parameters, field: &Field) -> To
let delife = params.borrowed.de_lifetime();
let elem = quote_spanned!(Span::call_site()=> .0);
quote! {
#[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
where __E: _serde::Deserializer<#delife>
{
_serde::Deserialize::deserialize_in_place(__e, &mut self.place #elem)
_serde::Deserialize::deserialize_in_place(__e, &mut self.place.0)
}
}
}
@@ -1625,12 +1626,13 @@ fn deserialize_untagged_variant(
let type_name = params.type_name();
let variant_name = variant.ident.as_ref();
quote_expr! {
_serde::export::Result::map(
_serde::Deserializer::deserialize_any(
#deserializer,
_serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
),
|()| #this::#variant_ident)
match _serde::Deserializer::deserialize_any(
#deserializer,
_serde::private::de::UntaggedUnitVisitor::new(#type_name, #variant_name)
) {
_serde::export::Ok(()) => _serde::export::Ok(#this::#variant_ident),
_serde::export::Err(__err) => _serde::export::Err(__err),
}
}
}
Style::Newtype => deserialize_untagged_newtype_variant(
@@ -1939,82 +1941,82 @@ fn deserialize_identifier(
let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
let visit_other = if collect_other_fields {
quote! {
fn visit_bool<__E>(self, __value: bool) -> Result<Self::Value, __E>
fn visit_bool<__E>(self, __value: bool) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::Bool(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::Bool(__value)))
}
fn visit_i8<__E>(self, __value: i8) -> Result<Self::Value, __E>
fn visit_i8<__E>(self, __value: i8) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::I8(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I8(__value)))
}
fn visit_i16<__E>(self, __value: i16) -> Result<Self::Value, __E>
fn visit_i16<__E>(self, __value: i16) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::I16(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I16(__value)))
}
fn visit_i32<__E>(self, __value: i32) -> Result<Self::Value, __E>
fn visit_i32<__E>(self, __value: i32) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::I32(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I32(__value)))
}
fn visit_i64<__E>(self, __value: i64) -> Result<Self::Value, __E>
fn visit_i64<__E>(self, __value: i64) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::I64(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::I64(__value)))
}
fn visit_u8<__E>(self, __value: u8) -> Result<Self::Value, __E>
fn visit_u8<__E>(self, __value: u8) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::U8(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U8(__value)))
}
fn visit_u16<__E>(self, __value: u16) -> Result<Self::Value, __E>
fn visit_u16<__E>(self, __value: u16) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::U16(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U16(__value)))
}
fn visit_u32<__E>(self, __value: u32) -> Result<Self::Value, __E>
fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::U32(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U32(__value)))
}
fn visit_u64<__E>(self, __value: u64) -> Result<Self::Value, __E>
fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::U64(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::U64(__value)))
}
fn visit_f32<__E>(self, __value: f32) -> Result<Self::Value, __E>
fn visit_f32<__E>(self, __value: f32) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::F32(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::F32(__value)))
}
fn visit_f64<__E>(self, __value: f64) -> Result<Self::Value, __E>
fn visit_f64<__E>(self, __value: f64) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::F64(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::F64(__value)))
}
fn visit_char<__E>(self, __value: char) -> Result<Self::Value, __E>
fn visit_char<__E>(self, __value: char) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::Char(__value)))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::Char(__value)))
}
fn visit_unit<__E>(self) -> Result<Self::Value, __E>
fn visit_unit<__E>(self) -> _serde::export::Result<Self::Value, __E>
where __E: _serde::de::Error
{
Ok(__Field::__other(_serde::private::de::Content::Unit))
_serde::export::Ok(__Field::__other(_serde::private::de::Content::Unit))
}
fn visit_borrowed_str<__E>(self, __value: &'de str) -> _serde::export::Result<Self::Value, __E>
@@ -2177,7 +2179,7 @@ fn deserialize_map(
// Collect contents for flatten fields into a buffer
let let_collect = if cattrs.has_flatten() {
Some(quote! {
let mut __collect = Vec::<Option<(
let mut __collect = _serde::export::Vec::<_serde::export::Option<(
_serde::private::de::Content,
_serde::private::de::Content
)>>::new();
@@ -2225,7 +2227,7 @@ fn deserialize_map(
let ignored_arm = if cattrs.has_flatten() {
Some(quote! {
__Field::__other(__name) => {
__collect.push(Some((
__collect.push(_serde::export::Some((
__name,
try!(_serde::de::MapAccess::next_value(&mut __map)))));
}
@@ -2277,8 +2279,12 @@ fn deserialize_map(
.filter(|&&(field, _)| field.attrs.flatten())
.map(|&(field, ref name)| {
let field_ty = field.ty;
let func = match field.attrs.deserialize_with() {
None => quote!(_serde::de::Deserialize::deserialize),
Some(path) => quote!(#path),
};
quote! {
let #name: #field_ty = try!(_serde::de::Deserialize::deserialize(
let #name: #field_ty = try!(#func(
_serde::private::de::FlatMapDeserializer(
&mut __collect,
_serde::export::PhantomData)));
@@ -2287,8 +2293,8 @@ fn deserialize_map(
let collected_deny_unknown_fields = if cattrs.has_flatten() && cattrs.deny_unknown_fields() {
Some(quote! {
if let Some(Some((__key, _))) = __collect.into_iter().filter(|x| x.is_some()).next() {
if let Some(__key) = __key.as_str() {
if let _serde::export::Some(_serde::export::Some((__key, _))) = __collect.into_iter().filter(|x| x.is_some()).next() {
if let _serde::export::Some(__key) = __key.as_str() {
return _serde::export::Err(
_serde::de::Error::custom(format_args!("unknown field `{}`", &__key)));
} else {
@@ -2305,9 +2311,9 @@ fn deserialize_map(
let ident = field.ident.expect("struct contains unnamed fields");
if field.attrs.skip_deserializing() {
let value = Expr(expr_is_missing(field, cattrs));
quote_spanned!(Span::call_site()=> #ident: #value)
quote!(#ident: #value)
} else {
quote_spanned!(Span::call_site()=> #ident: #name)
quote!(#ident: #name)
}
});
@@ -2325,7 +2331,7 @@ fn deserialize_map(
}
};
let mut result = quote_spanned!(Span::call_site()=> #struct_path { #(#result),* });
let mut result = quote!(#struct_path { #(#result),* });
if params.has_getter {
let this = &params.this;
result = quote! {
+2 -9
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.38")]
#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.44")]
#![cfg_attr(
feature = "cargo-clippy",
allow(enum_variant_names, redundant_field_names, too_many_arguments, used_underscore_binding)
@@ -43,14 +43,6 @@ extern crate proc_macro2;
use proc_macro::TokenStream;
use syn::DeriveInput;
// Quote's default is def_site but it appears call_site is likely to stabilize
// before def_site. Thus we try to use only call_site.
macro_rules! quote {
($($tt:tt)*) => {
quote_spanned!($crate::proc_macro2::Span::call_site()=> $($tt)*)
}
}
#[macro_use]
mod bound;
#[macro_use]
@@ -58,6 +50,7 @@ mod fragment;
mod de;
mod ser;
mod try;
#[proc_macro_derive(Serialize, attributes(serde))]
pub fn derive_serialize(input: TokenStream) -> TokenStream {
+15 -7
View File
@@ -15,6 +15,7 @@ use bound;
use fragment::{Fragment, Match, Stmts};
use internals::ast::{Container, Data, Field, Style, Variant};
use internals::{attr, Ctxt};
use try;
use std::u32;
@@ -32,10 +33,9 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
let impl_block = if let Some(remote) = cont.attrs.remote() {
let vis = &input.vis;
let fun = quote_spanned!(Span::call_site()=> serialize);
quote! {
impl #impl_generics #ident #ty_generics #where_clause {
#vis fn #fun<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
#vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer
{
#body
@@ -55,10 +55,12 @@ pub fn expand_derive_serialize(input: &syn::DeriveInput) -> Result<Tokens, Strin
}
};
let try_replacement = try::replacement();
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
extern crate serde as _serde;
#try_replacement
#impl_block
};
};
@@ -594,9 +596,15 @@ fn serialize_adjacently_tagged_variant(
field_expr = wrap_serialize_field_with(params, field.ty, path, &field_expr);
}
quote_expr! {
_serde::Serialize::serialize(#field_expr, __serializer)
}
return quote_block! {
let mut __struct = try!(_serde::Serializer::serialize_struct(
__serializer, #type_name, 2));
try!(_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name));
try!(_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #content, #field_expr));
_serde::ser::SerializeStruct::end(__struct)
};
}
Style::Tuple => {
serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
@@ -1056,9 +1064,9 @@ fn mut_if(is_mut: bool) -> Option<Tokens> {
fn get_member(params: &Parameters, field: &Field, member: &Member) -> Tokens {
let self_var = &params.self_var;
match (params.is_remote, field.attrs.getter()) {
(false, None) => quote_spanned!(Span::call_site()=> &#self_var.#member),
(false, None) => quote!(&#self_var.#member),
(true, None) => {
let inner = quote_spanned!(Span::call_site()=> &#self_var.#member);
let inner = quote!(&#self_var.#member);
let ty = field.ty;
quote!(_serde::private::ser::constrain::<#ty>(#inner))
}
+25
View File
@@ -0,0 +1,25 @@
use proc_macro2::{Op, Spacing};
use quote::Tokens;
// None of our generated code requires the `From::from` error conversion
// performed by the standard library's `try!` macro. With this simplified macro
// we see a significant improvement in type checking and borrow checking time of
// the generated code and a slight improvement in binary size.
pub fn replacement() -> Tokens {
// Cannot pass `$expr` to `quote!` prior to Rust 1.17.0 so interpolate it.
let dollar = Op::new('$', Spacing::Alone);
quote! {
#[allow(unused_macros)]
macro_rules! try {
(#dollar __expr:expr) => {
match #dollar __expr {
_serde::export::Ok(__val) => __val,
_serde::export::Err(__err) => {
return _serde::export::Err(__err);
}
}
}
}
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_test"
version = "1.0.38" # remember to update html_root_url
version = "1.0.44" # 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
@@ -155,7 +155,7 @@
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.38")]
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.44")]
#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
// Whitelisted clippy lints
#![cfg_attr(feature = "cargo-clippy", allow(float_cmp))]
+3 -3
View File
@@ -45,7 +45,7 @@ macro_rules! assert_next_token {
($ser:expr, $expected:ident($v:expr)) => {
assert_next_token!(
$ser,
format_args!("{}({:?})", stringify!($expected), $v),
format_args!(concat!(stringify!($expected), "({:?})"), $v),
Token::$expected(v),
v == $v
);
@@ -56,13 +56,13 @@ macro_rules! assert_next_token {
use std::fmt::Write;
let mut buffer = String::new();
$(
write!(&mut buffer, "{}: {:?}, ", stringify!($k), $k).unwrap();
write!(&mut buffer, concat!(stringify!($k), ": {:?}, "), $k).unwrap();
)*
buffer
};
assert_next_token!(
$ser,
format_args!("{} {{ {}}}", stringify!($expected), field_format()),
format_args!(concat!(stringify!($expected), " {{ {}}}"), field_format()),
Token::$expected { $($k),* },
($($k,)*) == compare
);
+58
View File
@@ -0,0 +1,58 @@
use serde::de::{Deserializer, Error, SeqAccess, Visitor};
use std::fmt;
pub fn deserialize<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_byte_buf(ByteBufVisitor)
}
struct ByteBufVisitor;
impl<'de> Visitor<'de> for ByteBufVisitor {
type Value = Vec<u8>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("byte array")
}
fn visit_seq<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
where
V: SeqAccess<'de>,
{
let mut values = Vec::new();
while let Some(value) = try!(visitor.next_element()) {
values.push(value);
}
Ok(values)
}
fn visit_bytes<E>(self, v: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v.to_vec())
}
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v)
}
fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v.as_bytes().to_vec())
}
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
Ok(v.into_bytes())
}
}
+48 -54
View File
@@ -12,9 +12,9 @@
extern crate serde_derive;
extern crate serde;
use std::collections::HashMap;
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
use self::serde::de::{self, Unexpected};
use self::serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::collections::HashMap;
extern crate serde_test;
use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens,
@@ -114,10 +114,7 @@ struct FlattenStructEnumWrapper {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
enum FlattenStructEnum {
InsertInteger {
index: u32,
value: u32
},
InsertInteger { index: u32, value: u32 },
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
@@ -133,10 +130,7 @@ struct FlattenStructTagContentEnumNewtype(pub FlattenStructTagContentEnum);
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case", tag = "type", content = "value")]
enum FlattenStructTagContentEnum {
InsertInteger {
index: u32,
value: u32
},
InsertInteger { index: u32, value: u32 },
NewtypeVariant(FlattenStructTagContentEnumNewtypeVariant),
}
@@ -529,12 +523,10 @@ enum RenameEnumSerializeDeserialize<A> {
fn test_rename_enum() {
assert_tokens(
&RenameEnum::Batman,
&[
Token::UnitVariant {
name: "Superhero",
variant: "bruce_wayne",
},
],
&[Token::UnitVariant {
name: "Superhero",
variant: "bruce_wayne",
}],
);
assert_tokens(
@@ -1221,12 +1213,7 @@ fn test_missing_renamed_field_enum() {
#[derive(Debug, PartialEq, Deserialize)]
enum InvalidLengthEnum {
A(i32, i32, i32),
B(
#[serde(skip_deserializing)]
i32,
i32,
i32,
),
B(#[serde(skip_deserializing)] i32, i32, i32),
}
#[test]
@@ -1345,7 +1332,7 @@ fn test_flatten_struct_enum() {
let change_request = FlattenStructEnumWrapper {
data: FlattenStructEnum::InsertInteger {
index: 0,
value: 42
value: 42,
},
extra,
};
@@ -1362,7 +1349,7 @@ fn test_flatten_struct_enum() {
Token::MapEnd,
Token::Str("extra_key"),
Token::Str("extra value"),
Token::MapEnd
Token::MapEnd,
],
);
assert_ser_tokens(
@@ -1370,7 +1357,10 @@ fn test_flatten_struct_enum() {
&[
Token::Map { len: None },
Token::Str("insert_integer"),
Token::Struct { len: 2, name: "insert_integer" },
Token::Struct {
len: 2,
name: "insert_integer",
},
Token::Str("index"),
Token::U32(0),
Token::Str("value"),
@@ -1378,7 +1368,7 @@ fn test_flatten_struct_enum() {
Token::StructEnd,
Token::Str("extra_key"),
Token::Str("extra value"),
Token::MapEnd
Token::MapEnd,
],
);
}
@@ -1387,12 +1377,10 @@ fn test_flatten_struct_enum() {
fn test_flatten_struct_tag_content_enum() {
let change_request = FlattenStructTagContentEnumWrapper {
outer: 42,
data: FlattenStructTagContentEnumNewtype(
FlattenStructTagContentEnum::InsertInteger {
index: 0,
value: 42
}
),
data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::InsertInteger {
index: 0,
value: 42,
}),
};
assert_de_tokens(
&change_request,
@@ -1421,7 +1409,10 @@ fn test_flatten_struct_tag_content_enum() {
Token::Str("type"),
Token::Str("insert_integer"),
Token::Str("value"),
Token::Struct { len: 2, name: "insert_integer" },
Token::Struct {
len: 2,
name: "insert_integer",
},
Token::Str("index"),
Token::U32(0),
Token::Str("value"),
@@ -1436,13 +1427,9 @@ fn test_flatten_struct_tag_content_enum() {
fn test_flatten_struct_tag_content_enum_newtype() {
let change_request = FlattenStructTagContentEnumWrapper {
outer: 42,
data: FlattenStructTagContentEnumNewtype(
FlattenStructTagContentEnum::NewtypeVariant(
FlattenStructTagContentEnumNewtypeVariant {
value: 23
}
)
),
data: FlattenStructTagContentEnumNewtype(FlattenStructTagContentEnum::NewtypeVariant(
FlattenStructTagContentEnumNewtypeVariant { value: 23 },
)),
};
assert_de_tokens(
&change_request,
@@ -1469,7 +1456,10 @@ fn test_flatten_struct_tag_content_enum_newtype() {
Token::Str("type"),
Token::Str("newtype_variant"),
Token::Str("value"),
Token::Struct { len: 1, name: "FlattenStructTagContentEnumNewtypeVariant" },
Token::Struct {
len: 1,
name: "FlattenStructTagContentEnumNewtypeVariant",
},
Token::Str("value"),
Token::U32(23),
Token::StructEnd,
@@ -1525,7 +1515,7 @@ fn test_complex_flatten() {
first: First,
#[serde(flatten)]
second: Second,
z: u32
z: u32,
}
#[derive(Debug, PartialEq, Serialize, Deserialize)]
@@ -1552,10 +1542,8 @@ fn test_complex_flatten() {
d: "c".into(),
e: Some(2),
},
second: Second {
f: 3
},
z: 4
second: Second { f: 3 },
z: 4,
},
&[
Token::Map { len: None },
@@ -1592,10 +1580,8 @@ fn test_complex_flatten() {
d: "c".into(),
e: Some(2),
},
second: Second {
f: 3
},
z: 4
second: Second { f: 3 },
z: 4,
},
&[
Token::Map { len: None },
@@ -1652,7 +1638,7 @@ fn test_flatten_unsupported_type() {
Token::Str("foo"),
Token::Str("a"),
Token::Str("b"),
Token::MapEnd
Token::MapEnd,
],
"can only flatten structs and maps",
);
@@ -1671,7 +1657,11 @@ fn test_non_string_keys() {
let mut mapping = HashMap::new();
mapping.insert(0, 42);
assert_tokens(
&TestStruct { name: "peter".into(), age: 3, mapping },
&TestStruct {
name: "peter".into(),
age: 3,
mapping,
},
&[
Token::Map { len: None },
Token::Str("name"),
@@ -1720,7 +1710,9 @@ fn test_lifetime_propagation_for_flatten() {
let mut borrowed_map = HashMap::new();
borrowed_map.insert("x", 42u32);
assert_ser_tokens(
&B { t: borrowed_map.clone() },
&B {
t: borrowed_map.clone(),
},
&[
Token::Map { len: None },
Token::BorrowedStr("x"),
@@ -1742,7 +1734,9 @@ fn test_lifetime_propagation_for_flatten() {
let mut borrowed_map = HashMap::new();
borrowed_map.insert(&b"x"[..], 42u32);
assert_ser_tokens(
&C { t: borrowed_map.clone() },
&C {
t: borrowed_map.clone(),
},
&[
Token::Map { len: None },
Token::Seq { len: Some(1) },
+4 -4
View File
@@ -12,14 +12,14 @@
extern crate serde_derive;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::net;
use std::path::{Path, PathBuf};
use std::time::{Duration, UNIX_EPOCH};
use std::default::Default;
use std::ffi::{CString, OsString};
use std::net;
use std::num::Wrapping;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::Arc;
use std::num::Wrapping;
use std::time::{Duration, UNIX_EPOCH};
#[cfg(feature = "unstable")]
use std::ffi::CStr;
+40 -42
View File
@@ -17,8 +17,8 @@
extern crate serde_derive;
extern crate serde;
use self::serde::ser::{Serialize, Serializer};
use self::serde::de::{DeserializeOwned, Deserializer};
use self::serde::ser::{Serialize, Serializer};
use std::borrow::Cow;
use std::marker::PhantomData;
@@ -92,14 +92,10 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
enum EnumWith<T> {
Unit,
Newtype(
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
X,
),
Newtype(#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X),
Tuple(
T,
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
X,
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X,
),
Struct {
t: T,
@@ -122,17 +118,13 @@ fn test_gen() {
assert_ser::<MultipleRef<i32>>();
#[derive(Serialize, Deserialize)]
struct Newtype(
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
X,
);
struct Newtype(#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X);
assert::<Newtype>();
#[derive(Serialize, Deserialize)]
struct Tuple<T>(
T,
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")]
X,
#[serde(serialize_with = "ser_x", deserialize_with = "de_x")] X,
);
assert::<Tuple<i32>>();
@@ -191,12 +183,16 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
#[serde(bound = "D: SerializeWith + DeserializeWith")]
struct WithTraits1<D, E> {
#[serde(serialize_with = "SerializeWith::serialize_with",
deserialize_with = "DeserializeWith::deserialize_with")]
#[serde(
serialize_with = "SerializeWith::serialize_with",
deserialize_with = "DeserializeWith::deserialize_with"
)]
d: D,
#[serde(serialize_with = "SerializeWith::serialize_with",
deserialize_with = "DeserializeWith::deserialize_with",
bound = "E: SerializeWith + DeserializeWith")]
#[serde(
serialize_with = "SerializeWith::serialize_with",
deserialize_with = "DeserializeWith::deserialize_with",
bound = "E: SerializeWith + DeserializeWith"
)]
e: E,
}
assert::<WithTraits1<X, X>>();
@@ -204,13 +200,18 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
#[serde(bound(serialize = "D: SerializeWith", deserialize = "D: DeserializeWith"))]
struct WithTraits2<D, E> {
#[serde(serialize_with = "SerializeWith::serialize_with",
deserialize_with = "DeserializeWith::deserialize_with")]
#[serde(
serialize_with = "SerializeWith::serialize_with",
deserialize_with = "DeserializeWith::deserialize_with"
)]
d: D,
#[serde(serialize_with = "SerializeWith::serialize_with",
bound(serialize = "E: SerializeWith"))]
#[serde(deserialize_with = "DeserializeWith::deserialize_with",
bound(deserialize = "E: DeserializeWith"))]
#[serde(
serialize_with = "SerializeWith::serialize_with", bound(serialize = "E: SerializeWith")
)]
#[serde(
deserialize_with = "DeserializeWith::deserialize_with",
bound(deserialize = "E: DeserializeWith")
)]
e: E,
}
assert::<WithTraits2<X, X>>();
@@ -270,17 +271,11 @@ fn test_gen() {
struct EmptyTupleDenyUnknown();
#[derive(Serialize, Deserialize)]
struct TupleSkipAll(
#[serde(skip_deserializing)]
u8,
);
struct TupleSkipAll(#[serde(skip_deserializing)] u8);
#[derive(Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
struct TupleSkipAllDenyUnknown(
#[serde(skip_deserializing)]
u8,
);
struct TupleSkipAllDenyUnknown(#[serde(skip_deserializing)] u8);
#[derive(Serialize, Deserialize)]
enum EmptyEnum {}
@@ -305,10 +300,7 @@ fn test_gen() {
#[serde(skip_deserializing)]
f: u8,
},
TupleSkip(
#[serde(skip_deserializing)]
u8,
),
TupleSkip(#[serde(skip_deserializing)] u8),
}
#[cfg(feature = "unstable")]
@@ -321,10 +313,7 @@ fn test_gen() {
#[serde(skip_deserializing)]
f: u8,
},
TupleSkip(
#[serde(skip_deserializing)]
u8,
),
TupleSkip(#[serde(skip_deserializing)] u8),
}
#[derive(Serialize, Deserialize)]
@@ -503,6 +492,13 @@ fn test_gen() {
}
assert_ser::<UntaggedVariantWith>();
#[derive(Serialize, Deserialize)]
struct FlattenWith {
#[serde(flatten, serialize_with = "ser_x", deserialize_with = "de_x")]
x: X,
}
assert::<FlattenWith>();
#[derive(Serialize, Deserialize)]
struct StaticStrStruct<'a> {
a: &'a str,
@@ -531,7 +527,9 @@ fn test_gen() {
assert::<SkippedStaticStr>();
macro_rules! T {
() => { () }
() => {
()
};
}
#[derive(Serialize, Deserialize)]
@@ -559,7 +557,7 @@ fn test_gen() {
#[derive(Serialize, Deserialize)]
struct AssocDerive<T: AssocSerde> {
assoc: T::Assoc
assoc: T::Assoc,
}
assert::<AssocDerive<NoSerdeImpl>>();
+367 -25
View File
@@ -7,13 +7,16 @@
// except according to those terms.
#![deny(trivial_numeric_casts)]
#![cfg_attr(feature = "cargo-clippy", allow(redundant_field_names))]
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_test;
mod bytes;
use self::serde_test::{assert_de_tokens, assert_de_tokens_error, assert_ser_tokens, assert_tokens,
Token};
@@ -222,12 +225,10 @@ fn test_de_named_map() {
fn test_ser_enum_unit() {
assert_ser_tokens(
&SerEnum::Unit::<u32, u32, u32>,
&[
Token::UnitVariant {
name: "SerEnum",
variant: "Unit",
},
],
&[Token::UnitVariant {
name: "SerEnum",
variant: "Unit",
}],
);
}
@@ -292,12 +293,10 @@ fn test_ser_enum_map() {
fn test_de_enum_unit() {
assert_tokens(
&DeEnum::Unit::<u32, u32, u32>,
&[
Token::UnitVariant {
name: "DeEnum",
variant: "Unit",
},
],
&[Token::UnitVariant {
name: "DeEnum",
variant: "Unit",
}],
);
}
@@ -442,6 +441,51 @@ fn test_generic_newtype_struct() {
);
}
#[test]
fn test_untagged_newtype_struct() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
enum E {
Newtype(GenericNewTypeStruct<u32>),
Null,
}
assert_tokens(
&E::Newtype(GenericNewTypeStruct(5u32)),
&[
Token::NewtypeStruct {
name: "GenericNewTypeStruct",
},
Token::U32(5),
],
);
}
#[test]
fn test_adjacently_tagged_newtype_struct() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
#[serde(tag = "t", content = "c")]
enum E {
Newtype(GenericNewTypeStruct<u32>),
Null,
}
assert_de_tokens(
&E::Newtype(GenericNewTypeStruct(5u32)),
&[
Token::Struct { name: "E", len: 2 },
Token::Str("c"),
Token::NewtypeStruct {
name: "GenericNewTypeStruct",
},
Token::U32(5),
Token::Str("t"),
Token::Str("Newtype"),
Token::StructEnd,
],
);
}
#[test]
fn test_generic_tuple_struct() {
assert_tokens(
@@ -462,12 +506,10 @@ fn test_generic_tuple_struct() {
fn test_generic_enum_unit() {
assert_tokens(
&GenericEnum::Unit::<u32, u32>,
&[
Token::UnitVariant {
name: "GenericEnum",
variant: "Unit",
},
],
&[Token::UnitVariant {
name: "GenericEnum",
variant: "Unit",
}],
);
}
@@ -779,6 +821,166 @@ fn test_internally_tagged_enum() {
);
}
#[test]
fn test_internally_tagged_bytes() {
#[derive(Debug, PartialEq, Deserialize)]
#[serde(tag = "type")]
enum InternallyTagged {
String {
string: String,
},
Bytes {
#[serde(with = "bytes")]
bytes: Vec<u8>,
},
}
assert_de_tokens(
&InternallyTagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "String",
len: 2,
},
Token::Str("type"),
Token::Str("String"),
Token::Str("string"),
Token::Str("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "String",
len: 2,
},
Token::Str("type"),
Token::Str("String"),
Token::Str("string"),
Token::String("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "String",
len: 2,
},
Token::Str("type"),
Token::Str("String"),
Token::Str("string"),
Token::Bytes(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "String",
len: 2,
},
Token::Str("type"),
Token::Str("String"),
Token::Str("string"),
Token::ByteBuf(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Bytes",
len: 2,
},
Token::Str("type"),
Token::Str("Bytes"),
Token::Str("bytes"),
Token::Str("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Bytes",
len: 2,
},
Token::Str("type"),
Token::Str("Bytes"),
Token::Str("bytes"),
Token::String("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Bytes",
len: 2,
},
Token::Str("type"),
Token::Str("Bytes"),
Token::Str("bytes"),
Token::Bytes(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Bytes",
len: 2,
},
Token::Str("type"),
Token::Str("Bytes"),
Token::Str("bytes"),
Token::ByteBuf(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&InternallyTagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Bytes",
len: 2,
},
Token::Str("type"),
Token::Str("Bytes"),
Token::Str("bytes"),
Token::Seq { len: Some(1) },
Token::U8(0),
Token::SeqEnd,
Token::StructEnd,
],
);
}
#[test]
fn test_internally_tagged_struct_variant_containing_unit_variant() {
#[derive(Debug, PartialEq, Serialize, Deserialize)]
@@ -1198,12 +1400,10 @@ fn test_enum_in_untagged_enum() {
assert_tokens(
&Outer::Inner(Inner::Unit),
&[
Token::UnitVariant {
name: "Inner",
variant: "Unit",
},
],
&[Token::UnitVariant {
name: "Inner",
variant: "Unit",
}],
);
assert_tokens(
@@ -1246,6 +1446,148 @@ fn test_enum_in_untagged_enum() {
);
}
#[test]
fn test_untagged_bytes() {
#[derive(Debug, PartialEq, Deserialize)]
#[serde(untagged)]
enum Untagged {
String {
string: String,
},
Bytes {
#[serde(with = "bytes")]
bytes: Vec<u8>,
},
}
assert_de_tokens(
&Untagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "Untagged",
len: 1,
},
Token::Str("string"),
Token::Str("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&Untagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "Untagged",
len: 1,
},
Token::Str("string"),
Token::String("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&Untagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "Untagged",
len: 1,
},
Token::Str("string"),
Token::Bytes(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&Untagged::String {
string: "\0".to_owned(),
},
&[
Token::Struct {
name: "Untagged",
len: 1,
},
Token::Str("string"),
Token::ByteBuf(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&Untagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Untagged",
len: 1,
},
Token::Str("bytes"),
Token::Str("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&Untagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Untagged",
len: 1,
},
Token::Str("bytes"),
Token::String("\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&Untagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Untagged",
len: 1,
},
Token::Str("bytes"),
Token::Bytes(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&Untagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Untagged",
len: 1,
},
Token::Str("bytes"),
Token::ByteBuf(b"\0"),
Token::StructEnd,
],
);
assert_de_tokens(
&Untagged::Bytes { bytes: vec![0] },
&[
Token::Struct {
name: "Untagged",
len: 1,
},
Token::Str("bytes"),
Token::Seq { len: Some(1) },
Token::U8(0),
Token::SeqEnd,
Token::StructEnd,
],
);
}
#[test]
fn test_rename_all() {
#[derive(Serialize, Deserialize, Debug, PartialEq)]
+6 -21
View File
@@ -121,10 +121,7 @@ struct UnitDef;
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::PrimitivePriv")]
struct PrimitivePrivDef(
#[serde(getter = "remote::PrimitivePriv::get")]
u8,
);
struct PrimitivePrivDef(#[serde(getter = "remote::PrimitivePriv::get")] u8);
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::PrimitivePub")]
@@ -132,34 +129,22 @@ struct PrimitivePubDef(u8);
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::NewtypePriv")]
struct NewtypePrivDef(
#[serde(getter = "remote::NewtypePriv::get", with = "UnitDef")]
remote::Unit,
);
struct NewtypePrivDef(#[serde(getter = "remote::NewtypePriv::get", with = "UnitDef")] remote::Unit);
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::NewtypePub")]
struct NewtypePubDef(
#[serde(with = "UnitDef")]
remote::Unit,
);
struct NewtypePubDef(#[serde(with = "UnitDef")] remote::Unit);
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::TuplePriv")]
struct TuplePrivDef(
#[serde(getter = "remote::TuplePriv::first")]
u8,
#[serde(getter = "remote::TuplePriv::second", with = "UnitDef")]
remote::Unit,
#[serde(getter = "remote::TuplePriv::first")] u8,
#[serde(getter = "remote::TuplePriv::second", with = "UnitDef")] remote::Unit,
);
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::TuplePub")]
struct TuplePubDef(
u8,
#[serde(with = "UnitDef")]
remote::Unit,
);
struct TuplePubDef(u8, #[serde(with = "UnitDef")] remote::Unit);
#[derive(Serialize, Deserialize)]
#[serde(remote = "remote::StructPriv")]
+4 -4
View File
@@ -10,13 +10,13 @@
extern crate serde_derive;
use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use std::net;
use std::path::{Path, PathBuf};
use std::time::{Duration, UNIX_EPOCH};
use std::ffi::CString;
use std::net;
use std::num::Wrapping;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::Arc;
use std::num::Wrapping;
use std::time::{Duration, UNIX_EPOCH};
#[cfg(unix)]
use std::str;
+1 -1
View File
@@ -10,8 +10,8 @@
extern crate serde_derive;
extern crate serde;
use serde::Deserialize;
use serde::de::{value, IntoDeserializer};
use serde::Deserialize;
#[test]
fn test_u32_to_enum() {