Compare commits

...

18 Commits

Author SHA1 Message Date
David Tolnay e85ca8411e Release 0.8.7 2016-09-05 09:39:27 -07:00
Homu 1ff2053262 Auto merge of #536 - serde-rs:mutempty, r=oli-obk
Fix "variable does not need to be mutable" warning

Fixes #534.

cc @EliDupree
2016-09-06 01:10:43 +09:00
Homu bf779ea343 Auto merge of #525 - serde-rs:forward, r=oli-obk
Expose forward_to_deserialize macro

Fixes #522.

```rust
impl Deserializer for MyDeserializer {
    fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
        where V: Visitor
    {
        /* ... */
    }

    forward_to_deserialize! {
        bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
        unit option seq seq_fixed_size bytes map unit_struct newtype_struct
        tuple_struct struct struct_field tuple enum ignored_any
    }
}
```

cc @nox
2016-09-06 00:37:18 +09:00
David Tolnay 8fe66c7f2a Merge pull request #520 from serde-rs/bytes
Add constructors for Bytes and ByteBuf
2016-09-05 08:37:10 -07:00
David Tolnay e03dedabe4 Use peekable iterator to check for nonzero serialized fields 2016-09-05 08:22:17 -07:00
David Tolnay 08bc2d2e76 Use constructors to create Bytes and ByteBuf 2016-09-05 08:09:23 -07:00
David Tolnay 35be61d85f Resolve merge conflict 2016-09-05 08:02:35 -07:00
David Tolnay 3692edfd08 Merge branch serde-rs/master into serde-rs/forward 2016-09-05 07:59:42 -07:00
Homu 5a258ade27 Auto merge of #527 - serde-rs:seqvisitor, r=oli-obk
Impl SeqVisitor for MapDeserializer

@nox is this what you were trying to implement?
2016-09-05 20:09:44 +09:00
Homu f3052c392e Auto merge of #538 - serde-rs:notfalse, r=oli-obk
Remove `if !false { ... }` from generated serialization code

I don't think this negatively affects maintainability of the code in serde_codegen and I think there is some value in keeping our generated code relatively clear so that people can use it as a template when implementing Serialize manually with minor modifications.
2016-09-05 19:52:43 +09:00
David Tolnay d1ce4d62c9 Change to expression so that syntex keeps the semicolon 2016-09-02 18:07:26 -07:00
David Tolnay 869ebd9e4e Remove if !false { ... } from generated serialization code 2016-09-02 17:22:58 -07:00
David Tolnay 14446af537 Fix "variable does not need to be mutable" warning 2016-09-02 11:42:33 -07:00
David Tolnay d36f28971c Support no_std in forward_to_deserialize macro 2016-08-29 00:27:11 -07:00
David Tolnay 278e8eb720 Add deserialize_seq methods to MapDeserializer 2016-08-25 10:45:25 -04:00
David Tolnay e9b04de9a5 Impl SeqVisitor for MapDeserializer 2016-08-25 10:12:23 -04:00
David Tolnay 2a2891d54b Expose forward_to_deserialize macro 2016-08-24 00:16:22 -04:00
David Tolnay fb7ba225d1 Add constructors for Bytes and ByteBuf
This commit adds `Bytes::new(&[u8])` and `ByteBuf::from<T: Into<Vec<u8>>>(T)`.
2016-08-23 16:24:00 -04:00
13 changed files with 469 additions and 287 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde"
version = "0.8.6"
version = "0.8.7"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
+22 -22
View File
@@ -19,6 +19,15 @@ pub struct Bytes<'a> {
bytes: &'a [u8],
}
impl<'a> Bytes<'a> {
/// Wrap an existing `&[u8]`.
pub fn new(bytes: &'a [u8]) -> Self {
Bytes {
bytes: bytes,
}
}
}
impl<'a> fmt::Debug for Bytes<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(f.write_str("b\""));
@@ -31,18 +40,14 @@ impl<'a> fmt::Debug for Bytes<'a> {
impl<'a> From<&'a [u8]> for Bytes<'a> {
fn from(bytes: &'a [u8]) -> Self {
Bytes {
bytes: bytes,
}
Bytes::new(bytes)
}
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<'a> From<&'a Vec<u8>> for Bytes<'a> {
fn from(bytes: &'a Vec<u8>) -> Self {
Bytes {
bytes: bytes,
}
Bytes::new(bytes)
}
}
@@ -90,15 +95,18 @@ mod bytebuf {
impl ByteBuf {
/// Construct a new, empty `ByteBuf`.
pub fn new() -> Self {
ByteBuf {
bytes: Vec::new(),
}
ByteBuf::from(Vec::new())
}
/// Construct a new, empty `ByteBuf` with the specified capacity.
pub fn with_capacity(cap: usize) -> Self {
ByteBuf::from(Vec::with_capacity(cap))
}
/// Wrap existing bytes in a `ByteBuf`.
pub fn from<T: Into<Vec<u8>>>(bytes: T) -> Self {
ByteBuf {
bytes: Vec::with_capacity(cap)
bytes: bytes.into(),
}
}
}
@@ -121,9 +129,7 @@ mod bytebuf {
impl From<Vec<u8>> for ByteBuf {
fn from(bytes: Vec<u8>) -> Self {
ByteBuf {
bytes: bytes,
}
ByteBuf::from(bytes)
}
}
@@ -179,9 +185,7 @@ mod bytebuf {
fn visit_unit<E>(&mut self) -> Result<ByteBuf, E>
where E: de::Error,
{
Ok(ByteBuf {
bytes: Vec::new(),
})
Ok(ByteBuf::new())
}
#[inline]
@@ -197,9 +201,7 @@ mod bytebuf {
try!(visitor.end());
Ok(ByteBuf {
bytes: values,
})
Ok(ByteBuf::from(values))
}
#[inline]
@@ -213,9 +215,7 @@ mod bytebuf {
fn visit_byte_buf<E>(&mut self, v: Vec<u8>) -> Result<ByteBuf, E>
where E: de::Error,
{
Ok(ByteBuf {
bytes: v,
})
Ok(ByteBuf::from(v))
}
}
-65
View File
@@ -11,71 +11,6 @@ use collections::{String, Vec};
use core::fmt;
///////////////////////////////////////////////////////////////////////////////
/// Macro helper to not have to re-implement all the defaulted methods.
/// Every given method ignores all arguments and forwards to `deserialize`.
/// Note that `deserialize_enum` simply returns an `Error::invalid_type`.
macro_rules! de_forward_to_deserialize {
($($func:ident),*) => {
$(de_forward_to_deserialize!{func: $func})*
};
(func: deserialize_unit_struct) => {
de_forward_to_deserialize!{named: deserialize_unit_struct}
};
(func: deserialize_newtype_struct) => {
de_forward_to_deserialize!{named: deserialize_newtype_struct}
};
(func: deserialize_tuple) => {
de_forward_to_deserialize!{tup_fn: deserialize_tuple}
};
(func: deserialize_seq_fixed_size) => {
de_forward_to_deserialize!{tup_fn: deserialize_seq_fixed_size}
};
(func: deserialize_tuple_struct) => {
#[inline]
fn deserialize_tuple_struct<__V>(&mut self, _: &str, _: usize, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor {
self.deserialize(visitor)
}
};
(func: deserialize_struct) => {
#[inline]
fn deserialize_struct<__V>(&mut self, _: &str, _: &[&str], visitor: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor {
self.deserialize(visitor)
}
};
(func: deserialize_enum) => {
#[inline]
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], _: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::EnumVisitor {
Err($crate::de::Error::invalid_type($crate::de::Type::Enum))
}
};
(named: $func:ident) => {
#[inline]
fn $func<__V>(&mut self, _: &str, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor {
self.deserialize(visitor)
}
};
(tup_fn: $func: ident) => {
#[inline]
fn $func<__V>(&mut self, _: usize, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor {
self.deserialize(visitor)
}
};
(func: $func:ident) => {
#[inline]
fn $func<__V>(&mut self, visitor: __V) -> Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor {
self.deserialize(visitor)
}
};
}
///////////////////////////////////////////////////////////////////////////////
// modules come after macros
pub mod impls;
pub mod value;
+189 -167
View File
@@ -178,20 +178,10 @@ impl<E> de::Deserializer for UnitDeserializer<E>
{
type Error = E;
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
}
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error>
@@ -229,21 +219,11 @@ macro_rules! primitive_deserializer {
{
type Error = E;
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
string unit option seq seq_fixed_size bytes map unit_struct
newtype_struct tuple_struct struct struct_field tuple enum
ignored_any
}
fn deserialize<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error>
@@ -311,20 +291,10 @@ impl<'a, E> de::Deserializer for StrDeserializer<'a, E>
visitor.visit(self)
}
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple ignored_any
}
}
@@ -408,20 +378,10 @@ impl<E> de::Deserializer for StringDeserializer<E>
visitor.visit(self)
}
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple ignored_any
}
}
@@ -507,20 +467,10 @@ impl<'a, E> de::Deserializer for CowStrDeserializer<'a, E>
visitor.visit(self)
}
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple ignored_any
}
}
@@ -599,21 +549,10 @@ impl<I, T, E> de::Deserializer for SeqDeserializer<I, E>
visitor.visit_seq(self)
}
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
}
}
@@ -722,21 +661,10 @@ impl<V_, E> de::Deserializer for SeqVisitorDeserializer<V_, E>
visitor.visit_seq(&mut self.visitor)
}
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
}
}
@@ -781,6 +709,15 @@ impl<I, K, V, E> MapDeserializer<I, K, V, E>
marker: PhantomData,
}
}
fn next(&mut self) -> Option<(K, V)> {
self.iter.next().map(|(k, v)| {
if let Some(len) = self.len.as_mut() {
*len -= 1;
}
(k, v)
})
}
}
impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
@@ -797,21 +734,26 @@ impl<I, K, V, E> de::Deserializer for MapDeserializer<I, K, V, E>
visitor.visit_map(self)
}
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
fn deserialize_seq<V_>(&mut self, mut visitor: V_) -> Result<V_::Value, Self::Error>
where V_: de::Visitor,
{
visitor.visit_seq(self)
}
fn deserialize_seq_fixed_size<V_>(&mut self, len: usize, mut visitor: V_) -> Result<V_::Value, Self::Error>
where V_: de::Visitor,
{
match self.len {
Some(map_len) if map_len == len => visitor.visit_seq(self),
Some(_) => Err(de::Error::invalid_length(len)),
None => visitor.visit_seq(self),
}
}
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option bytes map unit_struct newtype_struct tuple_struct struct
struct_field tuple enum ignored_any
}
}
@@ -826,14 +768,11 @@ impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
fn visit_key<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: de::Deserialize,
{
match self.iter.next() {
match self.next() {
Some((key, value)) => {
if let Some(len) = self.len.as_mut() {
*len -= 1;
}
self.value = Some(value);
let mut de = key.into_deserializer();
Ok(Some(try!(de::Deserialize::deserialize(&mut de))))
de::Deserialize::deserialize(&mut de).map(Some)
}
None => Ok(None),
}
@@ -867,6 +806,123 @@ impl<I, K, V, E> de::MapVisitor for MapDeserializer<I, K, V, E>
}
}
impl<I, K, V, E> de::SeqVisitor for MapDeserializer<I, K, V, E>
where I: Iterator<Item=(K, V)>,
K: ValueDeserializer<E>,
V: ValueDeserializer<E>,
E: de::Error,
{
type Error = E;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: de::Deserialize,
{
match self.next() {
Some(kv) => {
let mut de = PairDeserializer(Some(kv), PhantomData);
de::Deserialize::deserialize(&mut de).map(Some)
}
None => Ok(None),
}
}
fn end(&mut self) -> Result<(), Self::Error> {
de::MapVisitor::end(self)
}
fn size_hint(&self) -> (usize, Option<usize>) {
de::MapVisitor::size_hint(self)
}
}
// Used in the `impl SeqVisitor for MapDeserializer` to visit the map as a
// sequence of pairs.
struct PairDeserializer<A, B, E>(Option<(A, B)>, PhantomData<E>);
impl<A, B, E> de::Deserializer for PairDeserializer<A, B, E>
where A: ValueDeserializer<E>,
B: ValueDeserializer<E>,
E: de::Error
{
type Error = E;
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option bytes map unit_struct newtype_struct tuple_struct struct
struct_field tuple enum ignored_any
}
fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor,
{
self.deserialize_seq(visitor)
}
fn deserialize_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor,
{
match self.0.take() {
Some((k, v)) => {
visitor.visit_seq(PairVisitor(Some(k), Some(v), PhantomData))
}
None => Err(de::Error::end_of_stream()),
}
}
fn deserialize_seq_fixed_size<V>(&mut self, len: usize, visitor: V) -> Result<V::Value, Self::Error>
where V: de::Visitor,
{
if len == 2 {
self.deserialize_seq(visitor)
} else {
Err(de::Error::invalid_length(len))
}
}
}
struct PairVisitor<A, B, E>(Option<A>, Option<B>, PhantomData<E>);
impl<A, B, E> de::SeqVisitor for PairVisitor<A, B, E>
where A: ValueDeserializer<E>,
B: ValueDeserializer<E>,
E: de::Error,
{
type Error = E;
fn visit<T>(&mut self) -> Result<Option<T>, Self::Error>
where T: de::Deserialize,
{
if let Some(k) = self.0.take() {
let mut de = k.into_deserializer();
de::Deserialize::deserialize(&mut de).map(Some)
} else if let Some(v) = self.1.take() {
let mut de = v.into_deserializer();
de::Deserialize::deserialize(&mut de).map(Some)
} else {
Ok(None)
}
}
fn end(&mut self) -> Result<(), Self::Error> {
if self.1.is_none() {
Ok(())
} else {
Err(de::Error::invalid_length(self.size_hint().0))
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = if self.0.is_some() {
2
} else if self.1.is_some() {
1
} else {
0
};
(len, Some(len))
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))]
@@ -928,21 +984,10 @@ impl<V_, E> de::Deserializer for MapVisitorDeserializer<V_, E>
visitor.visit_map(&mut self.visitor)
}
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
}
}
@@ -975,25 +1020,13 @@ impl<'a, E> de::Deserializer for BytesDeserializer<'a, E>
}
}
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "collections"))]
@@ -1026,20 +1059,9 @@ impl<E> de::Deserializer for ByteBufDeserializer<E>
}
}
de_forward_to_deserialize!{
deserialize_bool,
deserialize_f64, deserialize_f32,
deserialize_u8, deserialize_u16, deserialize_u32, deserialize_u64, deserialize_usize,
deserialize_i8, deserialize_i16, deserialize_i32, deserialize_i64, deserialize_isize,
deserialize_char, deserialize_str, deserialize_string,
deserialize_ignored_any,
deserialize_bytes,
deserialize_unit_struct, deserialize_unit,
deserialize_seq, deserialize_seq_fixed_size,
deserialize_map, deserialize_newtype_struct, deserialize_struct_field,
deserialize_tuple,
deserialize_enum,
deserialize_struct, deserialize_tuple_struct,
deserialize_option
forward_to_deserialize! {
bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
unit option seq seq_fixed_size bytes map unit_struct newtype_struct
tuple_struct struct struct_field tuple enum ignored_any
}
}
+3
View File
@@ -45,6 +45,9 @@ macro_rules! format {
($s:expr, $($rest:tt)*) => ($s)
}
#[macro_use]
mod macros;
pub mod bytes;
pub mod de;
#[cfg(feature = "std")]
+179
View File
@@ -0,0 +1,179 @@
#[cfg(feature = "std")]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_method {
($func:ident($($arg:ty),*)) => {
#[inline]
fn $func<__V>(&mut self, $(_: $arg,)* visitor: __V) -> ::std::result::Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor
{
self.deserialize(visitor)
}
};
}
#[cfg(not(feature = "std"))]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_method {
($func:ident($($arg:ty),*)) => {
#[inline]
fn $func<__V>(&mut self, $(_: $arg,)* visitor: __V) -> ::core::result::Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor
{
self.deserialize(visitor)
}
};
}
#[cfg(feature = "std")]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_enum {
() => {
#[inline]
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], _: __V) -> ::std::result::Result<__V::Value, Self::Error>
where __V: $crate::de::EnumVisitor
{
Err($crate::de::Error::invalid_type($crate::de::Type::Enum))
}
};
}
#[cfg(not(feature = "std"))]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_enum {
() => {
#[inline]
fn deserialize_enum<__V>(&mut self, _: &str, _: &[&str], _: __V) -> ::core::result::Result<__V::Value, Self::Error>
where __V: $crate::de::EnumVisitor
{
Err($crate::de::Error::invalid_type($crate::de::Type::Enum))
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_helper {
(bool) => {
forward_to_deserialize_method!{deserialize_bool()}
};
(usize) => {
forward_to_deserialize_method!{deserialize_usize()}
};
(u8) => {
forward_to_deserialize_method!{deserialize_u8()}
};
(u16) => {
forward_to_deserialize_method!{deserialize_u16()}
};
(u32) => {
forward_to_deserialize_method!{deserialize_u32()}
};
(u64) => {
forward_to_deserialize_method!{deserialize_u64()}
};
(isize) => {
forward_to_deserialize_method!{deserialize_isize()}
};
(i8) => {
forward_to_deserialize_method!{deserialize_i8()}
};
(i16) => {
forward_to_deserialize_method!{deserialize_i16()}
};
(i32) => {
forward_to_deserialize_method!{deserialize_i32()}
};
(i64) => {
forward_to_deserialize_method!{deserialize_i64()}
};
(f32) => {
forward_to_deserialize_method!{deserialize_f32()}
};
(f64) => {
forward_to_deserialize_method!{deserialize_f64()}
};
(char) => {
forward_to_deserialize_method!{deserialize_char()}
};
(str) => {
forward_to_deserialize_method!{deserialize_str()}
};
(string) => {
forward_to_deserialize_method!{deserialize_string()}
};
(unit) => {
forward_to_deserialize_method!{deserialize_unit()}
};
(option) => {
forward_to_deserialize_method!{deserialize_option()}
};
(seq) => {
forward_to_deserialize_method!{deserialize_seq()}
};
(seq_fixed_size) => {
forward_to_deserialize_method!{deserialize_seq_fixed_size(usize)}
};
(bytes) => {
forward_to_deserialize_method!{deserialize_bytes()}
};
(map) => {
forward_to_deserialize_method!{deserialize_map()}
};
(unit_struct) => {
forward_to_deserialize_method!{deserialize_unit_struct(&'static str)}
};
(newtype_struct) => {
forward_to_deserialize_method!{deserialize_newtype_struct(&'static str)}
};
(tuple_struct) => {
forward_to_deserialize_method!{deserialize_tuple_struct(&'static str, usize)}
};
(struct) => {
forward_to_deserialize_method!{deserialize_struct(&'static str, &'static [&'static str])}
};
(struct_field) => {
forward_to_deserialize_method!{deserialize_struct_field()}
};
(tuple) => {
forward_to_deserialize_method!{deserialize_tuple(usize)}
};
(ignored_any) => {
forward_to_deserialize_method!{deserialize_ignored_any()}
};
(enum) => {
forward_to_deserialize_enum!();
};
}
/// Helper to forward `Deserializer` methods to `Deserializer::deserialize`.
/// Every given method ignores all arguments and forwards to `deserialize`.
/// Note that `deserialize_enum` simply returns an `Error::invalid_type`; a
/// better approach is tracked in [serde-rs/serde#521][1].
///
/// ```rust,ignore
/// impl Deserializer for MyDeserializer {
/// fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor
/// {
/// /* ... */
/// }
///
/// forward_to_deserialize! {
/// bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str string
/// unit option seq seq_fixed_size bytes map unit_struct newtype_struct
/// tuple_struct struct struct_field tuple enum ignored_any
/// }
/// }
/// ```
///
/// [1]: https://github.com/serde-rs/serde/issues/521
#[macro_export]
macro_rules! forward_to_deserialize {
($($func:ident)*) => {
$(forward_to_deserialize_helper!{$func})*
};
}
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_codegen"
version = "0.8.6"
version = "0.8.7"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
+53 -20
View File
@@ -4,6 +4,7 @@ use syntax::ast::{self, Ident, MetaItem};
use syntax::codemap::Span;
use syntax::ext::base::{Annotatable, ExtCtxt};
use syntax::ptr::P;
use syntax::tokenstream::TokenTree;
use bound;
use span;
@@ -226,9 +227,10 @@ fn serialize_tuple_struct(
let type_name = name_expr(builder, item_attrs.name());
let len = serialize_stmts.len();
let let_mut = mut_if(cx, len > 0);
quote_block!(cx, {
let mut state = try!(_serializer.serialize_tuple_struct($type_name, $len));
let $let_mut state = try!(_serializer.serialize_tuple_struct($type_name, $len));
$serialize_stmts
_serializer.serialize_tuple_struct_end(state)
}).unwrap()
@@ -253,8 +255,14 @@ fn serialize_struct(
);
let type_name = name_expr(builder, item_attrs.name());
let len = fields.iter()
let mut serialized_fields = fields.iter()
.filter(|&field| !field.attrs.skip_serializing())
.peekable();
let let_mut = mut_if(cx, serialized_fields.peek().is_some());
let len = serialized_fields
.map(|field| {
let ident = field.ident.expect("struct has unnamed fields");
let field_expr = quote_expr!(cx, &self.$ident);
@@ -267,7 +275,7 @@ fn serialize_struct(
.fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr));
quote_block!(cx, {
let mut state = try!(_serializer.serialize_struct($type_name, $len));
let $let_mut state = try!(_serializer.serialize_struct($type_name, $len));
$serialize_fields
_serializer.serialize_struct_end(state)
}).unwrap()
@@ -458,9 +466,10 @@ fn serialize_tuple_variant(
);
let len = serialize_stmts.len();
let let_mut = mut_if(cx, len > 0);
quote_block!(cx, {
let mut state = try!(_serializer.serialize_tuple_variant($type_name, $variant_index, $variant_name, $len));
let $let_mut state = try!(_serializer.serialize_tuple_variant($type_name, $variant_index, $variant_name, $len));
$serialize_stmts
_serializer.serialize_tuple_variant_end(state)
}).unwrap()
@@ -488,8 +497,14 @@ fn serialize_struct_variant(
);
let item_name = name_expr(builder, item_attrs.name());
let len = fields.iter()
let mut serialized_fields = fields.iter()
.filter(|&field| !field.attrs.skip_serializing())
.peekable();
let let_mut = mut_if(cx, serialized_fields.peek().is_some());
let len = serialized_fields
.map(|field| {
let ident = field.ident.expect("struct has unnamed fields");
let field_expr = quote_expr!(cx, $ident);
@@ -502,7 +517,7 @@ fn serialize_struct_variant(
.fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr));
quote_block!(cx, {
let mut state = try!(_serializer.serialize_struct_variant(
let $let_mut state = try!(_serializer.serialize_struct_variant(
$item_name,
$variant_index,
$variant_name,
@@ -532,19 +547,21 @@ fn serialize_tuple_struct_visitor(
};
let skip = field.attrs.skip_serializing_if()
.map(|path| quote_expr!(cx, $path($field_expr)))
.unwrap_or(quote_expr!(cx, false));
.map(|path| quote_expr!(cx, $path($field_expr)));
if let Some(path) = field.attrs.serialize_with() {
field_expr = wrap_serialize_with(cx, builder,
&structure_ty, generics, &field.ty, path, field_expr);
}
quote_stmt!(cx,
if !$skip {
try!(_serializer.$func(&mut state, $field_expr));
}
).unwrap()
let ser = quote_expr!(cx,
try!(_serializer.$func(&mut state, $field_expr));
);
match skip {
None => quote_stmt!(cx, $ser).unwrap(),
Some(skip) => quote_stmt!(cx, if !$skip { $ser }).unwrap(),
}
})
.collect()
}
@@ -571,19 +588,21 @@ fn serialize_struct_visitor(
let key_expr = name_expr(builder, field.attrs.name());
let skip = field.attrs.skip_serializing_if()
.map(|path| quote_expr!(cx, $path($field_expr)))
.unwrap_or(quote_expr!(cx, false));
.map(|path| quote_expr!(cx, $path($field_expr)));
if let Some(path) = field.attrs.serialize_with() {
field_expr = wrap_serialize_with(cx, builder,
&structure_ty, generics, &field.ty, path, field_expr)
}
quote_stmt!(cx,
if !$skip {
try!(_serializer.$func(&mut state, $key_expr, $field_expr));
}
).unwrap()
let ser = quote_expr!(cx,
try!(_serializer.$func(&mut state, $key_expr, $field_expr));
);
match skip {
None => quote_stmt!(cx, $ser).unwrap(),
Some(skip) => quote_stmt!(cx, if !$skip { $ser }).unwrap(),
}
})
.collect()
}
@@ -637,3 +656,17 @@ fn name_expr(
) -> P<ast::Expr> {
builder.expr().str(name.serialize_name())
}
// Serialization of an empty struct results in code like:
//
// let mut state = try!(serializer.serialize_struct("S", 0));
// serializer.serialize_struct_end(state)
//
// where we want to omit the `mut` to avoid a warning.
fn mut_if(cx: &ExtCtxt, is_mut: bool) -> Vec<TokenTree> {
if is_mut {
quote_tokens!(cx, mut)
} else {
Vec::new()
}
}
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_derive"
version = "0.8.6"
version = "0.8.7"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
@@ -15,9 +15,9 @@ name = "serde_derive"
rustc-macro = true
[dependencies]
serde_codegen = { version = "=0.8.6", path = "../serde_codegen" }
serde_codegen = { version = "=0.8.7", path = "../serde_codegen" }
[dev-dependencies]
fnv = "1.0"
serde = { version = "0.8.6", path = "../serde" }
serde_test = { version = "0.8.6", path = "../serde_test" }
serde = { version = "0.8.7", path = "../serde" }
serde_test = { version = "0.8.7", path = "../serde_test" }
+4 -4
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_macros"
version = "0.8.6"
version = "0.8.7"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Macros to auto-generate implementations for the serde framework"
@@ -23,14 +23,14 @@ unstable-testing = [
[dependencies]
clippy = { version = "^0.*", optional = true }
serde_codegen = { version = "=0.8.6", default-features = false, features = ["unstable"], path = "../serde_codegen" }
serde_codegen = { version = "=0.8.7", default-features = false, features = ["unstable"], path = "../serde_codegen" }
[dev-dependencies]
compiletest_rs = "^0.2.0"
fnv = "1.0"
rustc-serialize = "^0.3.16"
serde = { version = "0.8.6", path = "../serde" }
serde_test = { version = "0.8.6", path = "../serde_test" }
serde = { version = "0.8.7", path = "../serde" }
serde_test = { version = "0.8.7", path = "../serde_test" }
[[test]]
name = "test"
+2 -2
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_test"
version = "0.8.6"
version = "0.8.7"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations"
@@ -12,4 +12,4 @@ keywords = ["serde", "serialization"]
include = ["Cargo.toml", "src/**/*.rs"]
[dependencies]
serde = { version = "0.8.6", path = "../serde" }
serde = { version = "0.8.7", path = "../serde" }
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "serde_testing"
version = "0.8.6"
version = "0.8.7"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
+10
View File
@@ -187,6 +187,16 @@ fn test_gen() {
#[serde(bound(deserialize = "T::Owned: Deserialize"))]
struct CowT<'a, T: ?Sized + 'a + ToOwned>(Cow<'a, T>);
assert::<CowT<str>>();
#[derive(Serialize, Deserialize)]
struct EmptyStruct {}
assert::<EmptyStruct>();
#[derive(Serialize, Deserialize)]
enum EmptyEnumVariant {
EmptyStruct {},
}
assert::<EmptyEnumVariant>();
}
//////////////////////////////////////////////////////////////////////////