diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index cd8e5964..159ff1bc 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -64,8 +64,6 @@ use super::{ Error, Serialize, Serializer, - SeqSerializer, - MapSerializer, }; /////////////////////////////////////////////////////////////////////////////// @@ -155,11 +153,11 @@ impl Serialize for [T] where S: Serializer, { - let mut seq_serializer = try!(serializer.serialize_seq()); + let mut seq_serializer = try!(serializer.serialize_seq(Some(self.len()))); for e in self.iter() { try!(seq_serializer.serialize_elt(e)); } - Ok(()) + seq_serializer.drop() } } @@ -172,11 +170,11 @@ macro_rules! array_impls { fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - let mut seq_serializer = try!(serializer.serialize_seq()); + let mut seq_serializer = try!(serializer.serialize_fixed_size_array($len)); for e in self.iter() { try!(seq_serializer.serialize_elt(e)); } - Ok(()) + seq_serializer.drop() } } } @@ -226,11 +224,11 @@ impl Serialize for BinaryHeap fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - let mut seq_serializer = try!(serializer.serialize_seq()); + let mut seq_serializer = try!(serializer.serialize_seq(Some(self.len()))); for e in self.iter() { try!(seq_serializer.serialize_elt(e)); } - Ok(()) + seq_serializer.drop() } } @@ -242,11 +240,11 @@ impl Serialize for BTreeSet fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - let mut seq_serializer = try!(serializer.serialize_seq()); + let mut seq_serializer = try!(serializer.serialize_seq(Some(self.len()))); for e in self.iter() { try!(seq_serializer.serialize_elt(e)); } - Ok(()) + seq_serializer.drop() } } @@ -258,7 +256,7 @@ impl Serialize for EnumSet fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - let mut seq_serializer = try!(serializer.serialize_seq()); + let mut seq_serializer = try!(serializer.serialize_seq(Some(self.len()))); for e in self.iter() { try!(seq_serializer.serialize_elt(e)); } @@ -274,11 +272,11 @@ impl Serialize for HashSet fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - let mut seq_serializer = try!(serializer.serialize_seq()); + let mut seq_serializer = try!(serializer.serialize_seq(Some(self.len()))); for e in self.iter() { try!(seq_serializer.serialize_elt(e)); } - Ok(()) + seq_serializer.drop() } } @@ -290,11 +288,11 @@ impl Serialize for LinkedList fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - let mut seq_serializer = try!(serializer.serialize_seq()); + let mut seq_serializer = try!(serializer.serialize_seq(Some(self.len()))); for e in self.iter() { try!(seq_serializer.serialize_elt(e)); } - Ok(()) + seq_serializer.drop() } } @@ -307,11 +305,11 @@ impl Serialize for ops::Range fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serialize, { - let mut seq_serializer = try!(serializer.serialize_seq()); + let mut seq_serializer = try!(serializer.serialize_seq(Some(self.len()))); for e in self.iter() { try!(seq_serializer.serialize_elt(e)); } - Ok(()) + seq_serializer.drop() } } @@ -331,11 +329,11 @@ impl Serialize for VecDeque where T: Serialize { fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - let mut seq_serializer = try!(serializer.serialize_seq()); + let mut seq_serializer = try!(serializer.serialize_seq(Some(self.len()))); for e in self.iter() { try!(seq_serializer.serialize_elt(e)); } - Ok(()) + seq_serializer.drop() } } @@ -357,7 +355,6 @@ macro_rules! e { ($e:expr) => { $e } } -/* TODO: FIX tuple magic macro_rules! tuple_impls { ($( $TupleVisitor:ident ($len:expr, $($T:ident),+) { @@ -369,15 +366,14 @@ macro_rules! tuple_impls { where $($T: Serialize),+ { #[inline] - fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> - where S: Serializer, - SS : SeqSerializer, + fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> + where S: Serializer, { - - for e in self.iter() { - try!(seq_serializer.serialize_elt(e)); - } - serializer.serialize_tuple($TupleVisitor::new(self)) + let mut ser = try!(serializer.serialize_tuple($len)); + $( + try!(ser.serialize_elt(&e!(self.$idx))); + )+ + ser.drop() } } )+ @@ -554,7 +550,6 @@ tuple_impls! { 15 => 15, } } -*/ /////////////////////////////////////////////////////////////////////////////// @@ -567,11 +562,11 @@ impl Serialize for BTreeMap fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - let mut map_serializer = try!(serializer.serialize_map()); + let mut map_serializer = try!(serializer.serialize_map(Some(self.len()))); for (k, v) in self.iter() { try!(map_serializer.serialize_elt(k, v)); } - Ok(()) + map_serializer.drop() } } @@ -585,11 +580,11 @@ impl Serialize for HashMap fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer, { - let mut map_serializer = try!(serializer.serialize_map()); + let mut map_serializer = try!(serializer.serialize_map(Some(self.len()))); for (k, v) in self.iter() { try!(map_serializer.serialize_elt(k, v)); } - Ok(()) + map_serializer.drop() } } diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index c42efe6e..8cf626da 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -44,9 +44,14 @@ pub trait MapSerializer : Sized { type Error: Error; /// Serializes an element of a map (key-value pair). - fn serialize_elt(&mut self, key: K, value: V) -> Result<(), Self::Error> + fn serialize_elt(&mut self, serializer: &mut S, key: K, value: V) -> Result<(), Self::Error> where K: Serialize, - V: Serialize; + V: Serialize, + S: Serializer; + + /// Finish serializing the map + fn drop(self, serializer: &mut S) -> Result<(), Self::Error> + where S: Serializer; } /// A trait that described a type that can serialize elements of a Sequence @@ -55,8 +60,58 @@ pub trait SeqSerializer : Sized { type Error: Error; /// Serializes an element of a sequence. - fn serialize_elt(&mut self, value: T) -> Result<(), Self::Error> - where T: Serialize; + fn serialize_elt(&mut self, serializer: &mut S, value: T) -> Result<(), Self::Error> + where T: Serialize, + S: Serializer; + + /// Finish serializing the map + fn drop(self, serializer: &mut S) -> Result<(), Self::Error> + where S: Serializer; +} + +/// A helper type for serializing maps. This is a workaround for HKL associated types +pub struct MapHelper<'a, S: Serializer + 'a + ?Sized>(&'a mut S, S::MapSerializer); + +impl<'a, S: Serializer + 'a + ?Sized> MapHelper<'a, S> { + /// Create a new MapHelper + pub fn new(s: &'a mut S, ms: S::MapSerializer) -> Self { + MapHelper(s, ms) + } +} + +impl<'a, S: Serializer + ?Sized> MapHelper<'a, S> { + /// Serializes an element of a map (key-value pair). + pub fn serialize_elt(&mut self, key: K, value: V) -> Result<(), S::Error> + where K: Serialize, + V: Serialize { + self.1.serialize_elt(self.0, key, value) + } + /// Closes the sequence + pub fn drop(self) -> Result<(), S::Error> { + self.1.drop(self.0) + } +} + +/// A helper type for serializing sequences. This is a workaround for HKL associated types +pub struct SeqHelper<'a, S: Serializer + 'a + ?Sized>(&'a mut S, S::SeqSerializer); + +impl<'a, S: Serializer + 'a + ?Sized> SeqHelper<'a, S> { + /// Create a new SeqHelper + pub fn new(s: &'a mut S, ms: S::SeqSerializer) -> Self { + SeqHelper(s, ms) + } +} + +impl<'a, S: Serializer + ?Sized> SeqHelper<'a, S> { + /// Serializes an element of a sequence. + pub fn serialize_elt(&mut self, value: V) -> Result<(), S::Error> + where V: Serialize { + self.1.serialize_elt(self.0, value) + } + /// Closes the sequence + pub fn drop(self) -> Result<(), S::Error> { + self.1.drop(self.0) + } } /////////////////////////////////////////////////////////////////////////////// @@ -162,11 +217,11 @@ pub trait Serializer { /// byte slices separately from generic arrays. By default it serializes as a regular array. #[inline] fn serialize_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> { - let mut seq_serializer = try!(self.serialize_seq()); + let mut seq_serializer = try!(self.serialize_seq(Some(value.len()))); for b in value.iter() { try!(seq_serializer.serialize_elt(b)); } - Ok(()) + seq_serializer.drop() } /// Serializes a `()` value. @@ -200,7 +255,9 @@ pub trait Serializer { value: T) -> Result<(), Self::Error> where T: Serialize, { - self.serialize_tuple_struct(name).and_then(|mut s| s.serialize_elt(Some(value))) + let mut ser = try!(self.serialize_tuple_struct(name, 1)); + try!(ser.serialize_elt((value,))); + ser.drop() } /// Allows a variant with a single item to be more efficiently @@ -214,10 +271,9 @@ pub trait Serializer { value: T) -> Result<(), Self::Error> where T: Serialize, { - self.serialize_tuple_variant( - name, - variant_index, - variant).and_then(|mut s| s.serialize_elt(Some(value))) + let mut ser = try!(self.serialize_tuple_variant(name, variant_index, variant, 1)); + try!(ser.serialize_elt((value,))); + ser.drop() } /// Serializes a `None` value..serialize @@ -231,15 +287,22 @@ pub trait Serializer { /// /// Callees of this method need to construct a `SeqVisitor`, which iterates through each item /// in the sequence. - fn serialize_seq(&mut self) -> Result; + fn serialize_seq<'a>(&'a mut self, len: Option) -> Result, Self::Error>; + + /// Serializes a sequence element. + fn serialize_seq_elt(&mut self, value: T) -> Result<(), Self::Error> + where T: Serialize; + + /// Finish serializing a sequence. + fn serialize_seq_end(&mut self) -> Result<(), Self::Error>; /// Serializes a tuple. /// /// By default this serializes a tuple as a sequence. #[inline] - fn serialize_tuple(&mut self) -> Result + fn serialize_tuple<'a>(&'a mut self, len: usize) -> Result, Self::Error> { - self.serialize_seq() + self.serialize_seq(Some(len)) } /// Serializes a tuple element. @@ -247,32 +310,37 @@ pub trait Serializer { /// By default, tuples are serialized as a sequence. #[inline] fn serialize_tuple_elt(&mut self, value: T) -> Result<(), Self::Error> - where T: Serialize - { - self.serialize_seq().and_then(|mut s| s.serialize_elt(value)) + where T: Serialize { + self.serialize_seq_elt(value) + } + + /// Finishes serialization of a tuple. + /// + /// By default, tuples are serialized as a sequence. + #[inline] + fn serialize_tuple_end(&mut self) -> Result<(), Self::Error> { + self.serialize_seq_end() } - /* - TODO: Fixed-sized visitor would kind of make sense here /// Serializes a fixed-size array. /// /// By default this serializes an array as a sequence. #[inline] - fn serialize_fixed_size_array(&mut self, visitor: V) -> Result<(), Self::Error> + fn serialize_fixed_size_array<'a>(&'a mut self, size: usize) -> Result, Self::Error> { - self.serialize_seq(visitor) + self.serialize_seq(Some(size)) } - */ /// Serializes a tuple struct. /// /// By default, tuple structs are serialized as a tuple. #[inline] - fn serialize_tuple_struct(&mut self, + fn serialize_tuple_struct<'a>(&'a mut self, _name: &'static str, - ) -> Result + len: usize, + ) -> Result, Self::Error> { - self.serialize_tuple() + self.serialize_tuple(len) } /// Serializes a tuple struct element. @@ -285,53 +353,106 @@ pub trait Serializer { self.serialize_tuple_elt(value) } + /// Finishes serialization of a tuple struct. + /// + /// By default, tuple structs are serialized as a sequence. + #[inline] + fn serialize_tuple_struct_end(&mut self) -> Result<(), Self::Error> { + self.serialize_tuple_end() + } + /// Serializes a tuple variant. /// /// By default, tuple variants are serialized as a tuple struct. #[inline] - fn serialize_tuple_variant(&mut self, + fn serialize_tuple_variant<'a>(&'a mut self, _name: &'static str, _variant_index: usize, variant: &'static str, - ) -> Result + len: usize, + ) -> Result, Self::Error> { - self.serialize_tuple_struct(variant) + self.serialize_tuple_struct(variant, len) } - /// Serializes a tuple element. + /// Serializes a tuple variant element. /// - /// By default, tuples are serialized as a sequence. + /// By default, tuple variants are serialized as tuples. #[inline] fn serialize_tuple_variant_elt(&mut self, value: T) -> Result<(), Self::Error> where T: Serialize { - self.serialize_tuple_struct_elt(value) + self.serialize_tuple_elt(value) + } + + /// Finishes serialization of a tuple variant. + /// + /// By default, tuple variants are serialized as tuples. + #[inline] + fn serialize_tuple_variant_end(&mut self) -> Result<(), Self::Error> { + self.serialize_tuple_end() } /// Serialize a map. - fn serialize_map(&mut self) -> Result; + fn serialize_map<'a>(&'a mut self, len: Option) -> Result, Self::Error>; + + /// Serialize a map element + fn serialize_map_elt<'a, K, V>(&'a mut self, key: K, value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize; + + /// Finishes serializing a map + fn serialize_map_end<'a>(&'a mut self) -> Result<(), Self::Error>; /// Serializes a struct. /// /// By default, structs are serialized as a map with the field name as the key. #[inline] - fn serialize_struct(&mut self, + fn serialize_struct<'a>(&'a mut self, _name: &'static str, - ) -> Result + len: usize, + ) -> Result, Self::Error> { - self.serialize_map() + self.serialize_map(Some(len)) + } + + /// Serialize a struct field + /// + /// By default, structs are serialized as a map with the field name as the key. + fn serialize_struct_elt<'a, K, V>(&'a mut self, key: K, value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize { + self.serialize_map_elt(key, value) + } + + /// Finishes serializing a struct + /// + /// By default, structs are serialized as a map with the field name as the key. + fn serialize_struct_end<'a>(&'a mut self) -> Result<(), Self::Error> { + self.serialize_map_end() } /// Serializes a struct variant. /// /// By default, struct variants are serialized as a struct. #[inline] - fn serialize_struct_variant(&mut self, + fn serialize_struct_variant<'a>(&'a mut self, _name: &'static str, _variant_index: usize, - variant: &'static str - ) -> Result + variant: &'static str, + len: usize, + ) -> Result, Self::Error> { - self.serialize_struct(variant) + self.serialize_struct(variant, len) + } + + /// Serialize a struct variant element + /// + /// By default, structs are serialized as a map with the field name as the key. + fn serialize_struct_variant_elt<'a, K, V>(&'a mut self, key: K, value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize { + self.serialize_struct_elt(key, value) + } + + /// Finishes serializing a struct variant + /// + /// By default, structs are serialized as a map with the field name as the key. + fn serialize_struct_variant_end<'a>(&'a mut self) -> Result<(), Self::Error> { + self.serialize_struct_end() } } diff --git a/serde_codegen/src/ser.rs b/serde_codegen/src/ser.rs index 3f549c0f..231a5d55 100644 --- a/serde_codegen/src/ser.rs +++ b/serde_codegen/src/ser.rs @@ -216,30 +216,22 @@ fn serialize_tuple_struct( fields: &[Field], item_attrs: &attr::Item, ) -> P { - let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor( + let serialize_stmts = serialize_tuple_struct_visitor( cx, builder, ty.clone(), - builder.ty() - .ref_() - .lifetime("'__a") - .build_ty(ty.clone()), - builder.id("serialize_tuple_struct_elt"), fields, impl_generics, false, ); let type_name = name_expr(builder, item_attrs.name()); + let len = serialize_stmts.len(); quote_expr!(cx, { - $visitor_struct - $visitor_impl - _serializer.serialize_tuple_struct($type_name, Visitor { - value: self, - state: 0, - _structure_ty: ::std::marker::PhantomData::<&$ty>, - }) + let mut _seq_serializer = try!(_serializer.serialize_tuple_struct($type_name, $len)); + $serialize_stmts + _seq_serializer.drop() }) } @@ -251,30 +243,33 @@ fn serialize_struct( fields: &[Field], item_attrs: &attr::Item, ) -> P { - let (visitor_struct, visitor_impl) = serialize_struct_visitor( + let serialize_fields = serialize_struct_visitor( cx, builder, ty.clone(), - builder.ty() - .ref_() - .lifetime("'__a") - .build_ty(ty.clone()), - builder.id("serialize_struct_elt"), fields, impl_generics, false, ); let type_name = name_expr(builder, item_attrs.name()); + let len = fields.iter() + .filter(|&field| !field.attrs.skip_serializing()) + .map(|field| { + let ident = field.ident.expect("struct has unnamed fields"); + let field_expr = quote_expr!(cx, &self.$ident); + + match field.attrs.skip_serializing_if() { + Some(path) => quote_expr!(cx, if $path($field_expr) { 0 } else { 1 }), + None => quote_expr!(cx, 1), + } + }) + .fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr)); quote_expr!(cx, { - $visitor_struct - $visitor_impl - _serializer.serialize_struct($type_name, Visitor { - value: self, - state: 0, - _structure_ty: ::std::marker::PhantomData::<&$ty>, - }) + let mut _map_serializer = try!(_serializer.serialize_struct($type_name, $len)); + $serialize_fields + _map_serializer.drop() }) } @@ -377,7 +372,6 @@ fn serialize_variant( generics, ty, &variant.fields, - field_names, ); quote_arm!(cx, @@ -385,24 +379,16 @@ fn serialize_variant( ) } Style::Struct => { - let field_names: Vec<_> = (0 .. variant.fields.len()) - .map(|i| builder.id(format!("__field{}", i))) - .collect(); - let pat = builder.pat().struct_() .id(type_ident).id(variant_ident).build() - .with_pats( - field_names.iter() - .zip(variant.fields.iter()) - .map(|(id, field)| { - let name = match field.ident { - Some(name) => name, + .with_pats(variant.fields.iter() + .map(|field| { + match field.ident { + Some(name) => (name, builder.pat().ref_id(name)), None => { cx.span_bug(field.span, "struct variant has unnamed fields") } - }; - - (name, builder.pat().ref_id(id)) + } }) ) .build(); @@ -415,7 +401,6 @@ fn serialize_variant( generics, ty, &variant.fields, - field_names, item_attrs, ); @@ -462,46 +447,22 @@ fn serialize_tuple_variant( generics: &ast::Generics, structure_ty: P, fields: &[Field], - field_names: Vec, ) -> P { - let variant_ty = builder.ty().tuple() - .with_tys( - fields.iter().map(|field| { - builder.ty() - .ref_() - .lifetime("'__a") - .build_ty(field.ty.clone()) - }) - ) - .build(); - - let (visitor_struct, visitor_impl) = serialize_tuple_struct_visitor( + let serialize_stmts = serialize_tuple_struct_visitor( cx, builder, - structure_ty.clone(), - variant_ty, - builder.id("serialize_tuple_variant_elt"), + structure_ty, fields, generics, true, ); - let value_expr = builder.expr().tuple() - .with_exprs( - field_names.iter().map(|field| { - builder.expr().id(field) - }) - ) - .build(); + let len = serialize_stmts.len(); quote_expr!(cx, { - $visitor_struct - $visitor_impl - _serializer.serialize_tuple_variant($type_name, $variant_index, $variant_name, Visitor { - value: $value_expr, - state: 0, - _structure_ty: ::std::marker::PhantomData::<&$structure_ty>, - }) + let mut _seq_serializer = try!(_serializer.serialize_tuple_variant($type_name, $variant_index, $variant_name, $len)); + $serialize_stmts + _seq_serializer.drop() }) } @@ -513,83 +474,41 @@ fn serialize_struct_variant( generics: &ast::Generics, ty: P, fields: &[Field], - field_names: Vec, item_attrs: &attr::Item, ) -> P { - let variant_generics = builder.generics() - .with(generics.clone()) - .add_lifetime_bound("'__serde_variant") - .lifetime_name("'__serde_variant") - .build(); - let variant_struct = builder.item().struct_("__VariantStruct") - .with_generics(variant_generics.clone()) - .with_fields( - fields.iter().map(|field| { - builder.struct_field(field.ident.expect("struct has unnamed fields")) - .ty() - .ref_() - .lifetime("'__serde_variant") - .build_ty(field.ty.clone()) - }) - ) - .field("__serde_container_ty") - .ty().phantom_data().build(ty.clone()) - .build(); - - let variant_expr = builder.expr().struct_id("__VariantStruct") - .with_id_exprs( - fields.iter() - .zip(field_names.iter()) - .map(|(field, field_name)| { - ( - field.ident.expect("struct has unnamed fields"), - builder.expr().id(field_name), - ) - }) - ) - .field("__serde_container_ty").path() - .global() - .id("std").id("marker") - .segment("PhantomData") - .with_ty(ty.clone()) - .build() - .build() - .build(); - - let variant_ty = builder.ty().path() - .segment("__VariantStruct") - .with_generics(variant_generics.clone()) - .build() - .build(); - - let (visitor_struct, visitor_impl) = serialize_struct_visitor( + let serialize_fields = serialize_struct_visitor( cx, builder, - variant_ty.clone(), - variant_ty.clone(), - builder.id("serialize_struct_variant_elt"), + ty.clone(), fields, - &variant_generics, + &generics, true, ); let item_name = name_expr(builder, item_attrs.name()); + let len = fields.iter() + .filter(|&field| !field.attrs.skip_serializing()) + .map(|field| { + let ident = field.ident.expect("struct has unnamed fields"); + let field_expr = quote_expr!(cx, $ident); + + match field.attrs.skip_serializing_if() { + Some(path) => quote_expr!(cx, if $path($field_expr) { 0 } else { 1 }), + None => quote_expr!(cx, 1), + } + }) + .fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr)); quote_expr!(cx, { - $variant_struct - $visitor_struct - $visitor_impl - _serializer.serialize_struct_variant( + let mut _map_serializer = try!(_serializer.serialize_struct_variant( $item_name, $variant_index, $variant_name, - Visitor { - value: $variant_expr, - state: 0, - _structure_ty: ::std::marker::PhantomData, - }, - ) + $len, + )); + $serialize_fields + _map_serializer.drop() }) } @@ -597,187 +516,73 @@ fn serialize_tuple_struct_visitor( cx: &ExtCtxt, builder: &aster::AstBuilder, structure_ty: P, - variant_ty: P, - serializer_method: ast::Ident, fields: &[Field], generics: &ast::Generics, is_enum: bool, -) -> (P, P) { - let arms: Vec<_> = fields.iter() +) -> Vec { + fields.iter() .enumerate() .map(|(i, field)| { - let mut field_expr = builder.expr().tup_field(i).field("value").self_(); - if !is_enum { - field_expr = quote_expr!(cx, &$field_expr); - } + let mut field_expr = if is_enum { + builder.expr().path().id(format!("__field{}", i)).build() + } else { + builder.expr().tup_field(i).ref_().self_() + }; - let continue_if_skip = field.attrs.skip_serializing_if() - .map(|path| quote_stmt!(cx, if $path($field_expr) { continue })); + let skip = field.attrs.skip_serializing_if() + .map(|path| quote_expr!(cx, $path($field_expr))) + .unwrap_or(quote_expr!(cx, false)); if let Some(path) = field.attrs.serialize_with() { field_expr = wrap_serialize_with(cx, builder, &structure_ty, generics, &field.ty, path, field_expr); } - quote_arm!(cx, - $i => { - self.state += 1; - $continue_if_skip - Ok(Some(try!(_serializer.$serializer_method($field_expr)))) + quote_stmt!(cx, + if !$skip { + try!(_seq_serializer.serialize_elt($field_expr)); } - ) + ).unwrap() }) - .collect(); - - let visitor_impl_generics = builder.from_generics(generics.clone()) - .add_lifetime_bound("'__a") - .lifetime_name("'__a") - .build(); - - let where_clause = &visitor_impl_generics.where_clause; - - let visitor_generics = builder.from_generics(visitor_impl_generics.clone()) - .strip_bounds() - .build(); - - let nfields = fields.len(); - - ( - quote_item!(cx, - struct Visitor $visitor_impl_generics $where_clause { - state: usize, - value: $variant_ty, - _structure_ty: ::std::marker::PhantomData<&'__a $structure_ty>, - } - ).unwrap(), - - quote_item!(cx, - impl $visitor_impl_generics _serde::ser::SeqVisitor - for Visitor $visitor_generics - $where_clause { - #[inline] - fn visit<__S>(&mut self, _serializer: &mut __S) -> ::std::result::Result, __S::Error> - where __S: _serde::ser::Serializer - { - match self.state { - $arms - _ => Ok(None) - } - } - - #[inline] - fn len(&self) -> Option { - Some($nfields) - } - } - ).unwrap(), - ) + .collect() } fn serialize_struct_visitor( cx: &ExtCtxt, builder: &aster::AstBuilder, structure_ty: P, - variant_ty: P, - serializer_method: ast::Ident, fields: &[Field], generics: &ast::Generics, is_enum: bool, -) -> (P, P) { - let arms: Vec = fields.iter() +) -> Vec { + fields.iter() .filter(|&field| !field.attrs.skip_serializing()) - .enumerate() - .map(|(i, field)| { + .map(|field| { let ident = field.ident.expect("struct has unnamed field"); - let mut field_expr = quote_expr!(cx, self.value.$ident); - if !is_enum { - field_expr = quote_expr!(cx, &$field_expr); - } + let mut field_expr = if is_enum { + quote_expr!(cx, $ident) + } else { + quote_expr!(cx, &self.$ident) + }; let key_expr = name_expr(builder, field.attrs.name()); - let continue_if_skip = field.attrs.skip_serializing_if() - .map(|path| quote_stmt!(cx, if $path($field_expr) { continue })); + let skip = field.attrs.skip_serializing_if() + .map(|path| quote_expr!(cx, $path($field_expr))) + .unwrap_or(quote_expr!(cx, false)); if let Some(path) = field.attrs.serialize_with() { field_expr = wrap_serialize_with(cx, builder, &structure_ty, generics, &field.ty, path, field_expr) } - let expr = quote_expr!(cx, - _serializer.$serializer_method($key_expr, $field_expr) - ); - - quote_arm!(cx, - $i => { - self.state += 1; - $continue_if_skip - return Ok(Some(try!($expr))); + quote_stmt!(cx, + if !$skip { + try!(_map_serializer.serialize_elt($key_expr, $field_expr)); } - ) + ).unwrap() }) - .collect(); - - let visitor_impl_generics = builder.from_generics(generics.clone()) - .add_lifetime_bound("'__a") - .lifetime_name("'__a") - .build(); - - let where_clause = &visitor_impl_generics.where_clause; - - let visitor_generics = builder.from_generics(visitor_impl_generics.clone()) - .strip_bounds() - .build(); - - let len = fields.iter() - .filter(|&field| !field.attrs.skip_serializing()) - .map(|field| { - let ident = field.ident.expect("struct has unnamed fields"); - let mut field_expr = quote_expr!(cx, self.value.$ident); - if !is_enum { - field_expr = quote_expr!(cx, &$field_expr); - } - - match field.attrs.skip_serializing_if() { - Some(path) => quote_expr!(cx, if $path($field_expr) { 0 } else { 1 }), - None => quote_expr!(cx, 1), - } - }) - .fold(quote_expr!(cx, 0), |sum, expr| quote_expr!(cx, $sum + $expr)); - - ( - quote_item!(cx, - struct Visitor $visitor_impl_generics $where_clause { - state: usize, - value: $variant_ty, - _structure_ty: ::std::marker::PhantomData<&'__a $structure_ty>, - } - ).unwrap(), - - quote_item!(cx, - impl $visitor_impl_generics - _serde::ser::MapVisitor - for Visitor $visitor_generics - $where_clause { - #[inline] - fn visit<__S>(&mut self, _serializer: &mut __S) -> ::std::result::Result, __S::Error> - where __S: _serde::ser::Serializer, - { - loop { - match self.state { - $arms - _ => { return Ok(None); } - } - } - } - - #[inline] - fn len(&self) -> Option { - Some($len) - } - } - ).unwrap(), - ) + .collect() } fn wrap_serialize_with( diff --git a/serde_test/src/de.rs b/serde_test/src/de.rs index a2d4c3d7..24dabe19 100644 --- a/serde_test/src/de.rs +++ b/serde_test/src/de.rs @@ -135,15 +135,18 @@ impl de::Deserializer for Deserializer Some(Token::Option(true)) => visitor.visit_some(self), Some(Token::Unit) => visitor.visit_unit(), Some(Token::UnitStruct(name)) => visitor.visit_unit_struct(name), - Some(Token::SeqStart(len)) | Some(Token::TupleStructStart(_, len)) => { + Some(Token::SeqStart(len)) => { self.visit_seq(len, visitor) } - Some(Token::SeqArrayStart(len)) => { + Some(Token::SeqArrayStart(len))| Some(Token::TupleStructStart(_, len)) => { self.visit_seq(Some(len), visitor) } - Some(Token::MapStart(len)) | Some(Token::StructStart(_, len)) => { + Some(Token::MapStart(len)) => { self.visit_map(len, visitor) } + Some(Token::StructStart(_, len)) => { + self.visit_map(Some(len), visitor) + } Some(token) => Err(Error::UnexpectedToken(token)), None => Err(Error::EndOfStream), } @@ -745,7 +748,7 @@ impl<'a, I> VariantVisitor for DeserializerVariantVisitor<'a, I> where V: Visitor, { match self.de.tokens.peek() { - Some(&Token::EnumSeqStart(_, _, Some(enum_len))) => { + Some(&Token::EnumSeqStart(_, _, enum_len)) => { let token = self.de.tokens.next().unwrap(); if len == enum_len { @@ -776,7 +779,7 @@ impl<'a, I> VariantVisitor for DeserializerVariantVisitor<'a, I> where V: Visitor, { match self.de.tokens.peek() { - Some(&Token::EnumMapStart(_, _, Some(enum_len))) => { + Some(&Token::EnumMapStart(_, _, enum_len)) => { let token = self.de.tokens.next().unwrap(); if fields.len() == enum_len { diff --git a/serde_test/src/ser.rs b/serde_test/src/ser.rs index 2f028d3b..0411de1b 100644 --- a/serde_test/src/ser.rs +++ b/serde_test/src/ser.rs @@ -2,14 +2,73 @@ use std::marker::PhantomData; use serde::ser::{ self, - MapVisitor, - SeqVisitor, Serialize, + MapHelper, + SeqHelper, }; use error::Error; use token::Token; +pub enum MapSerializer { + Map, + Struct, + Enum, +} + +impl ser::MapSerializer for MapSerializer { + type Error = Error; + + fn serialize_elt(&mut self, serializer: &mut S, key: K, value: V) -> Result<(), Self::Error> + where K: Serialize, + V: Serialize, + S: ser::Serializer { + match *self { + MapSerializer::Map => serializer.serialize_map_elt(key, value), + MapSerializer::Struct => serializer.serialize_struct_elt(key, value), + MapSerializer::Enum => serializer.serialize_struct_variant_elt(key, value), + } + } + + fn drop(self, serializer: &mut S) -> Result<(), Self::Error> where S: ser::Serializer { + match self { + MapSerializer::Map => serializer.serialize_map_end(), + MapSerializer::Struct => serializer.serialize_struct_end(), + MapSerializer::Enum => serializer.serialize_struct_variant_end(), + } + } +} + +pub enum SeqSerializer { + Seq, + Tuple, + TupleStruct, + Enum, +} + +impl ser::SeqSerializer for SeqSerializer { + type Error = Error; + + fn serialize_elt(&mut self, serializer: &mut S, value: T) -> Result<(), Self::Error> + where T: Serialize, S: ser::Serializer { + match *self { + SeqSerializer::Seq => serializer.serialize_seq_elt(value), + SeqSerializer::Tuple => serializer.serialize_tuple_elt(value), + SeqSerializer::TupleStruct => serializer.serialize_tuple_struct_elt(value), + SeqSerializer::Enum => serializer.serialize_tuple_variant_elt(value), + } + } + + fn drop(self, serializer: &mut S) -> Result<(), Self::Error> where S: ser::Serializer { + match self { + SeqSerializer::Seq => serializer.serialize_seq_end(), + SeqSerializer::Tuple => serializer.serialize_tuple_end(), + SeqSerializer::TupleStruct => serializer.serialize_tuple_struct_end(), + SeqSerializer::Enum => serializer.serialize_tuple_variant_end(), + } + } +} + pub struct Serializer<'a, I> where I: Iterator>, { @@ -30,32 +89,14 @@ impl<'a, I> Serializer<'a, I> pub fn next_token(&mut self) -> Option<&'a Token<'a>> { self.tokens.next() } - - fn visit_seq(&mut self, mut visitor: V) -> Result<(), Error> - where V: SeqVisitor - { - while let Some(()) = try!(visitor.visit(self)) { } - - assert_eq!(self.tokens.next(), Some(&Token::SeqEnd)); - - Ok(()) - } - - fn visit_map(&mut self, mut visitor: V) -> Result<(), Error> - where V: MapVisitor - { - while let Some(()) = try!(visitor.visit(self)) { } - - assert_eq!(self.tokens.next(), Some(&Token::MapEnd)); - - Ok(()) - } } impl<'a, I> ser::Serializer for Serializer<'a, I> where I: Iterator>, { type Error = Error; + type SeqSerializer = SeqSerializer; + type MapSerializer = MapSerializer; fn serialize_unit(&mut self) -> Result<(), Error> { assert_eq!(self.tokens.next(), Some(&Token::Unit)); @@ -174,25 +215,10 @@ impl<'a, I> ser::Serializer for Serializer<'a, I> value.serialize(self) } - - fn serialize_seq(&mut self, visitor: V) -> Result<(), Error> - where V: SeqVisitor + fn serialize_seq<'b>(&'b mut self, len: Option) -> Result, Error> { - let len = visitor.len(); - assert_eq!(self.tokens.next(), Some(&Token::SeqStart(len))); - - self.visit_seq(visitor) - } - - fn serialize_fixed_size_array(&mut self, visitor: V) -> Result<(), Error> - where V: SeqVisitor - { - let len = visitor.len().expect("arrays must have a length"); - - assert_eq!(self.tokens.next(), Some(&Token::SeqArrayStart(len))); - - self.visit_seq(visitor) + Ok(SeqHelper::new(self, SeqSerializer::Seq)) } fn serialize_seq_elt(&mut self, value: T) -> Result<(), Error> @@ -202,18 +228,22 @@ impl<'a, I> ser::Serializer for Serializer<'a, I> value.serialize(self) } - fn serialize_tuple(&mut self, mut visitor: V) -> Result<(), Error> - where V: SeqVisitor - { - let len = visitor.len().expect("arrays must have a length"); + fn serialize_seq_end(&mut self) -> Result<(), Error> { + assert_eq!(self.tokens.next(), Some(&Token::SeqEnd)); + Ok(()) + } + fn serialize_fixed_size_array<'b>(&'b mut self, len: usize) -> Result, Error> + { + assert_eq!(self.tokens.next(), Some(&Token::SeqArrayStart(len))); + Ok(SeqHelper::new(self, SeqSerializer::Seq)) + } + + fn serialize_tuple<'b>(&'b mut self, len: usize) -> Result, Error> + { assert_eq!(self.tokens.next(), Some(&Token::TupleStart(len))); - while let Some(()) = try!(visitor.visit(self)) { } - - assert_eq!(self.tokens.next(), Some(&Token::TupleEnd)); - - Ok(()) + Ok(SeqHelper::new(self, SeqSerializer::Tuple)) } fn serialize_tuple_elt(&mut self, value: T) -> Result<(), Error> @@ -223,128 +253,117 @@ impl<'a, I> ser::Serializer for Serializer<'a, I> value.serialize(self) } + fn serialize_tuple_end(&mut self) -> Result<(), Error> { + assert_eq!(self.tokens.next(), Some(&Token::TupleEnd)); + Ok(()) + } + fn serialize_newtype_struct(&mut self, - name: &'static str, - value: T) -> Result<(), Error> + name: &'static str, + value: T) -> Result<(), Error> where T: Serialize, { assert_eq!(self.tokens.next(), Some(&Token::StructNewType(name))); value.serialize(self) } - fn serialize_tuple_struct(&mut self, name: &str, mut visitor: V) -> Result<(), Error> - where V: SeqVisitor + fn serialize_tuple_struct<'b>(&'b mut self, name: &str, len: usize) -> Result, Error> { - let len = visitor.len(); - assert_eq!(self.tokens.next(), Some(&Token::TupleStructStart(name, len))); - while let Some(()) = try!(visitor.visit(self)) { } - - assert_eq!(self.tokens.next(), Some(&Token::TupleStructEnd)); - - Ok(()) + Ok(SeqHelper::new(self, SeqSerializer::TupleStruct)) } fn serialize_tuple_struct_elt(&mut self, value: T) -> Result<(), Error> - where T: Serialize, + where T: Serialize { assert_eq!(self.tokens.next(), Some(&Token::TupleStructSep)); value.serialize(self) } - fn serialize_tuple_variant(&mut self, - name: &str, - _variant_index: usize, - variant: &str, - mut visitor: V) -> Result<(), Error> - where V: SeqVisitor - { - let len = visitor.len(); - - assert_eq!(self.tokens.next(), Some(&Token::EnumSeqStart(name, variant, len))); - - while let Some(()) = try!(visitor.visit(self)) { } - - assert_eq!(self.tokens.next(), Some(&Token::EnumSeqEnd)); - + fn serialize_tuple_struct_end(&mut self) -> Result<(), Error> { + assert_eq!(self.tokens.next(), Some(&Token::TupleStructEnd)); Ok(()) } + fn serialize_tuple_variant<'b>(&'b mut self, + name: &str, + _variant_index: usize, + variant: &str, + len: usize) -> Result, Error> + { + assert_eq!(self.tokens.next(), Some(&Token::EnumSeqStart(name, variant, len))); + + Ok(SeqHelper::new(self, SeqSerializer::Enum)) + } + fn serialize_tuple_variant_elt(&mut self, value: T) -> Result<(), Error> - where T: Serialize, + where T: Serialize { assert_eq!(self.tokens.next(), Some(&Token::EnumSeqSep)); value.serialize(self) } - fn serialize_map(&mut self, visitor: V) -> Result<(), Error> - where V: MapVisitor - { - let len = visitor.len(); + fn serialize_tuple_variant_end(&mut self) -> Result<(), Error> { + assert_eq!(self.tokens.next(), Some(&Token::EnumSeqEnd)); + Ok(()) + } + fn serialize_map<'b>(&'b mut self, len: Option) -> Result, Error> + { assert_eq!(self.tokens.next(), Some(&Token::MapStart(len))); - self.visit_map(visitor) + Ok(MapHelper::new(self, MapSerializer::Map)) } - fn serialize_map_elt(&mut self, key: K, value: V) -> Result<(), Error> - where K: Serialize, - V: Serialize, - { + fn serialize_map_elt(&mut self, key: K, value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize { assert_eq!(self.tokens.next(), Some(&Token::MapSep)); - try!(key.serialize(self)); value.serialize(self) } - fn serialize_struct(&mut self, name: &str, mut visitor: V) -> Result<(), Error> - where V: MapVisitor - { - let len = visitor.len(); + fn serialize_map_end(&mut self) -> Result<(), Self::Error> { + assert_eq!(self.tokens.next(), Some(&Token::MapEnd)); + Ok(()) + } + fn serialize_struct<'b>(&'b mut self, name: &str, len: usize) -> Result, Error> + { assert_eq!(self.tokens.next(), Some(&Token::StructStart(name, len))); - while let Some(()) = try!(visitor.visit(self)) { } - - assert_eq!(self.tokens.next(), Some(&Token::StructEnd)); - - Ok(()) + Ok(MapHelper::new(self, MapSerializer::Struct)) } - fn serialize_struct_elt(&mut self, key: &'static str, value: T) -> Result<(), Error> - where T: Serialize, - { + fn serialize_struct_elt(&mut self, key: K, value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize { assert_eq!(self.tokens.next(), Some(&Token::StructSep)); - try!(key.serialize(self)); value.serialize(self) } - fn serialize_struct_variant(&mut self, - name: &str, - _variant_index: usize, - variant: &str, - mut visitor: V) -> Result<(), Error> - where V: MapVisitor - { - let len = visitor.len(); + fn serialize_struct_end(&mut self) -> Result<(), Self::Error> { + assert_eq!(self.tokens.next(), Some(&Token::StructEnd)); + Ok(()) + } + fn serialize_struct_variant<'b>(&'b mut self, + name: &str, + _variant_index: usize, + variant: &str, + len: usize) -> Result, Error> + { assert_eq!(self.tokens.next(), Some(&Token::EnumMapStart(name, variant, len))); - while let Some(()) = try!(visitor.visit(self)) { } - - assert_eq!(self.tokens.next(), Some(&Token::EnumMapEnd)); - - Ok(()) + Ok(MapHelper::new(self, MapSerializer::Enum)) } - fn serialize_struct_variant_elt(&mut self, key: &'static str, value: T) -> Result<(), Error> - where T: Serialize, - { + fn serialize_struct_variant_elt(&mut self, key: K, value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize { assert_eq!(self.tokens.next(), Some(&Token::EnumMapSep)); - try!(key.serialize(self)); value.serialize(self) } + + fn serialize_struct_variant_end(&mut self) -> Result<(), Self::Error> { + assert_eq!(self.tokens.next(), Some(&Token::EnumMapEnd)); + Ok(()) + } } diff --git a/serde_test/src/token.rs b/serde_test/src/token.rs index dcb1137f..e4b3a825 100644 --- a/serde_test/src/token.rs +++ b/serde_test/src/token.rs @@ -38,7 +38,7 @@ pub enum Token<'a> { TupleSep, TupleEnd, - TupleStructStart(&'a str, Option), + TupleStructStart(&'a str, usize), TupleStructSep, TupleStructEnd, @@ -46,15 +46,15 @@ pub enum Token<'a> { MapSep, MapEnd, - StructStart(&'a str, Option), + StructStart(&'a str, usize), StructSep, StructEnd, - EnumSeqStart(&'a str, &'a str, Option), + EnumSeqStart(&'a str, &'a str, usize), EnumSeqSep, EnumSeqEnd, - EnumMapStart(&'a str, &'a str, Option), + EnumMapStart(&'a str, &'a str, usize), EnumMapSep, EnumMapEnd, } diff --git a/testing/tests/test_annotations.rs b/testing/tests/test_annotations.rs index a18a4b82..ba77f8f9 100644 --- a/testing/tests/test_annotations.rs +++ b/testing/tests/test_annotations.rs @@ -82,7 +82,7 @@ fn test_default_struct() { assert_de_tokens( &DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, &[ - Token::StructStart("DefaultStruct", Some(3)), + Token::StructStart("DefaultStruct", 3), Token::StructSep, Token::Str("a1"), @@ -111,7 +111,7 @@ fn test_default_struct() { assert_de_tokens( &DefaultStruct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 }, &[ - Token::StructStart("DefaultStruct", Some(1)), + Token::StructStart("DefaultStruct", 1), Token::StructSep, Token::Str("a1"), @@ -145,7 +145,7 @@ fn test_default_enum() { assert_de_tokens( &DefaultEnum::Struct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, &[ - Token::EnumMapStart("DefaultEnum", "Struct", Some(5)), + Token::EnumMapStart("DefaultEnum", "Struct", 5), Token::EnumMapSep, Token::Str("a1"), @@ -174,7 +174,7 @@ fn test_default_enum() { assert_de_tokens( &DefaultEnum::Struct { a1: 1, a2: 0, a3: 123, a4: 0, a5: 123 }, &[ - Token::EnumMapStart("DefaultEnum", "Struct", Some(5)), + Token::EnumMapStart("DefaultEnum", "Struct", 5), Token::EnumMapSep, Token::Str("a1"), @@ -208,7 +208,7 @@ fn test_no_std_default() { assert_de_tokens( &ContainsNoStdDefault { a: NoStdDefault(123) }, &[ - Token::StructStart("ContainsNoStdDefault", Some(1)), + Token::StructStart("ContainsNoStdDefault", 1), Token::StructEnd, ] ); @@ -216,7 +216,7 @@ fn test_no_std_default() { assert_de_tokens( &ContainsNoStdDefault { a: NoStdDefault(8) }, &[ - Token::StructStart("ContainsNoStdDefault", Some(1)), + Token::StructStart("ContainsNoStdDefault", 1), Token::StructSep, Token::Str("a"), @@ -281,7 +281,7 @@ fn test_elt_not_deserialize() { e: NotDeserializeEnum::Trouble, }, &[ - Token::StructStart("ContainsNotDeserialize", Some(3)), + Token::StructStart("ContainsNotDeserialize", 3), Token::StructEnd, ] ); @@ -299,7 +299,7 @@ fn test_ignore_unknown() { assert_de_tokens( &DefaultStruct { a1: 1, a2: 2, a3: 3, a4: 0, a5: 123 }, &[ - Token::StructStart("DefaultStruct", Some(5)), + Token::StructStart("DefaultStruct", 5), Token::StructSep, Token::Str("whoops1"), @@ -334,7 +334,7 @@ fn test_ignore_unknown() { assert_de_tokens_error::( &[ - Token::StructStart("DenyUnknown", Some(2)), + Token::StructStart("DenyUnknown", 2), Token::StructSep, Token::Str("a1"), @@ -368,7 +368,7 @@ fn test_rename_struct() { assert_tokens( &RenameStruct { a1: 1, a2: 2 }, &[ - Token::StructStart("Superhero", Some(2)), + Token::StructStart("Superhero", 2), Token::StructSep, Token::Str("a1"), @@ -385,7 +385,7 @@ fn test_rename_struct() { assert_ser_tokens( &RenameStructSerializeDeserialize { a1: 1, a2: 2 }, &[ - Token::StructStart("SuperheroSer", Some(2)), + Token::StructStart("SuperheroSer", 2), Token::StructSep, Token::Str("a1"), @@ -402,7 +402,7 @@ fn test_rename_struct() { assert_de_tokens( &RenameStructSerializeDeserialize { a1: 1, a2: 2 }, &[ - Token::StructStart("SuperheroDe", Some(2)), + Token::StructStart("SuperheroDe", 2), Token::StructSep, Token::Str("a1"), @@ -465,7 +465,7 @@ fn test_rename_enum() { assert_tokens( &RenameEnum::WonderWoman(0, 1), &[ - Token::EnumSeqStart("Superhero", "diana_prince", Some(2)), + Token::EnumSeqStart("Superhero", "diana_prince", 2), Token::EnumSeqSep, Token::I8(0), @@ -480,7 +480,7 @@ fn test_rename_enum() { assert_tokens( &RenameEnum::Flash { a: 1 }, &[ - Token::EnumMapStart("Superhero", "barry_allan", Some(1)), + Token::EnumMapStart("Superhero", "barry_allan", 1), Token::EnumMapSep, Token::Str("b"), @@ -496,7 +496,7 @@ fn test_rename_enum() { b: String::new(), }, &[ - Token::EnumMapStart("SuperheroSer", "dick_grayson", Some(2)), + Token::EnumMapStart("SuperheroSer", "dick_grayson", 2), Token::EnumMapSep, Token::Str("a"), @@ -516,7 +516,7 @@ fn test_rename_enum() { b: String::new(), }, &[ - Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)), + Token::EnumMapStart("SuperheroDe", "jason_todd", 2), Token::EnumMapSep, Token::Str("a"), @@ -550,7 +550,7 @@ fn test_skip_serializing_struct() { c: 3, }, &[ - Token::StructStart("SkipSerializingStruct", Some(2)), + Token::StructStart("SkipSerializingStruct", 2), Token::StructSep, Token::Str("a"), @@ -571,7 +571,7 @@ fn test_skip_serializing_struct() { c: 123, }, &[ - Token::StructStart("SkipSerializingStruct", Some(1)), + Token::StructStart("SkipSerializingStruct", 1), Token::StructSep, Token::Str("a"), @@ -603,7 +603,7 @@ fn test_skip_serializing_enum() { c: 3, }, &[ - Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(2)), + Token::EnumMapStart("SkipSerializingEnum", "Struct", 2), Token::EnumMapSep, Token::Str("a"), @@ -624,7 +624,7 @@ fn test_skip_serializing_enum() { c: 123, }, &[ - Token::EnumMapStart("SkipSerializingEnum", "Struct", Some(1)), + Token::EnumMapStart("SkipSerializingEnum", "Struct", 1), Token::EnumMapSep, Token::Str("a"), @@ -671,7 +671,7 @@ fn test_elt_not_serialize() { d: NotSerializeEnum::Trouble, }, &[ - Token::StructStart("ContainsNotSerialize", Some(2)), + Token::StructStart("ContainsNotSerialize", 2), Token::StructSep, Token::Str("a"), @@ -703,7 +703,7 @@ fn test_serialize_with_struct() { b: 2, }, &[ - Token::StructStart("SerializeWithStruct", Some(2)), + Token::StructStart("SerializeWithStruct", 2), Token::StructSep, Token::Str("a"), @@ -723,7 +723,7 @@ fn test_serialize_with_struct() { b: 123, }, &[ - Token::StructStart("SerializeWithStruct", Some(2)), + Token::StructStart("SerializeWithStruct", 2), Token::StructSep, Token::Str("a"), @@ -756,7 +756,7 @@ fn test_serialize_with_enum() { b: 2, }, &[ - Token::EnumMapStart("SerializeWithEnum", "Struct", Some(2)), + Token::EnumMapStart("SerializeWithEnum", "Struct", 2), Token::EnumMapSep, Token::Str("a"), @@ -776,7 +776,7 @@ fn test_serialize_with_enum() { b: 123, }, &[ - Token::EnumMapStart("SerializeWithEnum", "Struct", Some(2)), + Token::EnumMapStart("SerializeWithEnum", "Struct", 2), Token::EnumMapSep, Token::Str("a"), @@ -806,7 +806,7 @@ fn test_deserialize_with_struct() { b: 2, }, &[ - Token::StructStart("DeserializeWithStruct", Some(2)), + Token::StructStart("DeserializeWithStruct", 2), Token::StructSep, Token::Str("a"), @@ -826,7 +826,7 @@ fn test_deserialize_with_struct() { b: 123, }, &[ - Token::StructStart("DeserializeWithStruct", Some(2)), + Token::StructStart("DeserializeWithStruct", 2), Token::StructSep, Token::Str("a"), @@ -858,7 +858,7 @@ fn test_deserialize_with_enum() { b: 2, }, &[ - Token::EnumMapStart("DeserializeWithEnum", "Struct", Some(2)), + Token::EnumMapStart("DeserializeWithEnum", "Struct", 2), Token::EnumMapSep, Token::Str("a"), @@ -878,7 +878,7 @@ fn test_deserialize_with_enum() { b: 123, }, &[ - Token::EnumMapStart("DeserializeWithEnum", "Struct", Some(2)), + Token::EnumMapStart("DeserializeWithEnum", "Struct", 2), Token::EnumMapSep, Token::Str("a"), @@ -897,7 +897,7 @@ fn test_deserialize_with_enum() { fn test_missing_renamed_field_struct() { assert_de_tokens_error::( &[ - Token::StructStart("Superhero", Some(2)), + Token::StructStart("Superhero", 2), Token::StructSep, Token::Str("a1"), @@ -910,7 +910,7 @@ fn test_missing_renamed_field_struct() { assert_de_tokens_error::( &[ - Token::StructStart("SuperheroDe", Some(2)), + Token::StructStart("SuperheroDe", 2), Token::StructSep, Token::Str("a1"), @@ -926,7 +926,7 @@ fn test_missing_renamed_field_struct() { fn test_missing_renamed_field_enum() { assert_de_tokens_error::( &[ - Token::EnumMapStart("Superhero", "barry_allan", Some(1)), + Token::EnumMapStart("Superhero", "barry_allan", 1), Token::EnumMapEnd, ], @@ -935,7 +935,7 @@ fn test_missing_renamed_field_enum() { assert_de_tokens_error::>( &[ - Token::EnumMapStart("SuperheroDe", "jason_todd", Some(2)), + Token::EnumMapStart("SuperheroDe", "jason_todd", 2), Token::EnumMapSep, Token::Str("a"), @@ -957,7 +957,7 @@ enum InvalidLengthEnum { fn test_invalid_length_enum() { assert_de_tokens_error::( &[ - Token::EnumSeqStart("InvalidLengthEnum", "A", Some(3)), + Token::EnumSeqStart("InvalidLengthEnum", "A", 3), Token::EnumSeqSep, Token::I32(1), Token::EnumSeqEnd, @@ -966,7 +966,7 @@ fn test_invalid_length_enum() { ); assert_de_tokens_error::( &[ - Token::EnumSeqStart("InvalidLengthEnum", "B", Some(3)), + Token::EnumSeqStart("InvalidLengthEnum", "B", 3), Token::EnumSeqSep, Token::I32(1), Token::EnumSeqEnd, diff --git a/testing/tests/test_bytes.rs b/testing/tests/test_bytes.rs index 7a9906a4..ab1db513 100644 --- a/testing/tests/test_bytes.rs +++ b/testing/tests/test_bytes.rs @@ -50,8 +50,42 @@ impl BytesSerializer { } } +struct SeqSerializer; + +impl serde::ser::SeqSerializer for SeqSerializer { + type Error = Error; + + fn serialize_elt(&mut self, _serializer: &mut S, _value: T) -> Result<(), Self::Error> + where T: Serialize, S: serde::ser::Serializer { + Err(Error) + } + + fn drop(self, _serializer: &mut S) -> Result<(), Self::Error> where S: serde::ser::Serializer { + Err(Error) + } +} + +struct MapSerializer; + +impl serde::ser::MapSerializer for MapSerializer { + type Error = Error; + + fn serialize_elt(&mut self, _serializer: &mut S, _key: K, _value: V) -> Result<(), Self::Error> + where K: Serialize, + V: Serialize, + S: serde::ser::Serializer { + Err(Error) + } + + fn drop(self, _serializer: &mut S) -> Result<(), Self::Error> where S: serde::ser::Serializer { + Err(Error) + } +} + impl serde::Serializer for BytesSerializer { type Error = Error; + type SeqSerializer = SeqSerializer; + type MapSerializer = MapSerializer; fn serialize_unit(&mut self) -> Result<(), Error> { Err(Error) @@ -95,8 +129,7 @@ impl serde::Serializer for BytesSerializer { Err(Error) } - fn serialize_seq(&mut self, _visitor: V) -> Result<(), Error> - where V: serde::ser::SeqVisitor, + fn serialize_seq<'a>(&'a mut self, _len: Option) -> Result, Error> { Err(Error) } @@ -107,8 +140,12 @@ impl serde::Serializer for BytesSerializer { Err(Error) } - fn serialize_map(&mut self, _visitor: V) -> Result<(), Error> - where V: serde::ser::MapVisitor, + fn serialize_seq_end(&mut self) -> Result<(), Error> + { + Err(Error) + } + + fn serialize_map<'a>(&mut self, _: Option) -> Result, Error> { Err(Error) } @@ -120,6 +157,11 @@ impl serde::Serializer for BytesSerializer { Err(Error) } + fn serialize_map_end(&mut self) -> Result<(), Error> + { + Err(Error) + } + fn serialize_bytes(&mut self, bytes: &[u8]) -> Result<(), Error> { assert_eq!(self.bytes, bytes); Ok(()) diff --git a/testing/tests/test_de.rs b/testing/tests/test_de.rs index fcd17448..08c06af6 100644 --- a/testing/tests/test_de.rs +++ b/testing/tests/test_de.rs @@ -81,9 +81,9 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token<'static>]) { struct IgnoreBase { a: i32, } - + let expected = IgnoreBase{a: 1}; - + // Embed the tokens to be ignored in the normal token // stream for an IgnoreBase type let concated_tokens : Vec> = vec![ @@ -91,7 +91,7 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token<'static>]) { Token::MapSep, Token::Str("a"), Token::I32(1), - + Token::MapSep, Token::Str("ignored") ] @@ -101,17 +101,17 @@ fn assert_de_tokens_ignore(ignorable_tokens: &[Token<'static>]) { Token::MapEnd, ].into_iter()) .collect(); - + let mut de = serde_test::Deserializer::new(concated_tokens.into_iter()); let v: Result = Deserialize::deserialize(&mut de); - + // We run this test on every token stream for convenience, but // some token streams don't make sense embedded as a map value, // so we ignore those. SyntaxError is the real sign of trouble. if let Err(Error::UnexpectedToken(_)) = v { return; } - + assert_eq!(v.as_ref(), Ok(&expected)); assert_eq!(de.next_token(), None); } @@ -197,7 +197,7 @@ declare_tests! { Token::SeqEnd, ], () => &[ - Token::TupleStructStart("Anything", Some(0)), + Token::TupleStructStart("Anything", 0), Token::SeqEnd, ], } @@ -241,7 +241,7 @@ declare_tests! { Token::SeqEnd, ], TupleStruct(1, 2, 3) => &[ - Token::TupleStructStart("TupleStruct", Some(3)), + Token::TupleStructStart("TupleStruct", 3), Token::TupleStructSep, Token::I32(1), @@ -253,7 +253,7 @@ declare_tests! { Token::TupleStructEnd, ], TupleStruct(1, 2, 3) => &[ - Token::TupleStructStart("TupleStruct", None), + Token::TupleStructStart("TupleStruct", 3), Token::TupleStructSep, Token::I32(1), @@ -299,7 +299,7 @@ declare_tests! { Token::UnitStruct("Anything"), ], BTreeSet::::new() => &[ - Token::TupleStructStart("Anything", Some(0)), + Token::TupleStructStart("Anything", 0), Token::SeqEnd, ], } @@ -327,7 +327,7 @@ declare_tests! { Token::UnitStruct("Anything"), ], HashSet::::new() => &[ - Token::TupleStructStart("Anything", Some(0)), + Token::TupleStructStart("Anything", 0), Token::SeqEnd, ], hashset![FnvHasher @ 1, 2, 3] => &[ @@ -377,7 +377,7 @@ declare_tests! { Token::UnitStruct("Anything"), ], Vec::::new() => &[ - Token::TupleStructStart("Anything", Some(0)), + Token::TupleStructStart("Anything", 0), Token::SeqEnd, ], } @@ -441,7 +441,7 @@ declare_tests! { Token::UnitStruct("Anything"), ], [0; 0] => &[ - Token::TupleStructStart("Anything", Some(0)), + Token::TupleStructStart("Anything", 0), Token::SeqEnd, ], } @@ -533,7 +533,7 @@ declare_tests! { Token::UnitStruct("Anything"), ], BTreeMap::::new() => &[ - Token::StructStart("Anything", Some(0)), + Token::StructStart("Anything", 0), Token::MapEnd, ], } @@ -587,7 +587,7 @@ declare_tests! { Token::UnitStruct("Anything"), ], HashMap::::new() => &[ - Token::StructStart("Anything", Some(0)), + Token::StructStart("Anything", 0), Token::MapEnd, ], hashmap![FnvHasher @ 1 => 2, 3 => 4] => &[ @@ -615,7 +615,7 @@ declare_tests! { Token::MapEnd, ], Struct { a: 1, b: 2, c: 0 } => &[ - Token::StructStart("Struct", Some(3)), + Token::StructStart("Struct", 3), Token::StructSep, Token::Str("a"), Token::I32(1), @@ -656,7 +656,7 @@ declare_tests! { Token::MapEnd, ], Struct { a: 1, b: 2, c: 0 } => &[ - Token::StructStart("Struct", Some(3)), + Token::StructStart("Struct", 3), Token::StructSep, Token::Str("a"), Token::I32(1), @@ -688,7 +688,7 @@ declare_tests! { } test_enum_seq { Enum::Seq(1, 2, 3) => &[ - Token::EnumSeqStart("Enum", "Seq", Some(3)), + Token::EnumSeqStart("Enum", "Seq", 3), Token::EnumSeqSep, Token::I32(1), @@ -702,7 +702,7 @@ declare_tests! { } test_enum_map { Enum::Map { a: 1, b: 2, c: 3 } => &[ - Token::EnumMapStart("Enum", "Map", Some(3)), + Token::EnumMapStart("Enum", "Map", 3), Token::EnumMapSep, Token::Str("a"), Token::I32(1), @@ -803,7 +803,7 @@ declare_error_tests! { } test_duplicate_field_enum { &[ - Token::EnumMapStart("Enum", "Map", Some(3)), + Token::EnumMapStart("Enum", "Map", 3), Token::EnumMapSep, Token::Str("a"), Token::I32(1), diff --git a/testing/tests/test_macros.rs b/testing/tests/test_macros.rs index ca4dffaa..58ddfeab 100644 --- a/testing/tests/test_macros.rs +++ b/testing/tests/test_macros.rs @@ -174,7 +174,7 @@ fn test_ser_named_tuple() { assert_ser_tokens( &SerNamedTuple(&a, &mut b, c), &[ - Token::TupleStructStart("SerNamedTuple", Some(3)), + Token::TupleStructStart("SerNamedTuple", 3), Token::TupleStructSep, Token::I32(5), @@ -211,7 +211,7 @@ fn test_de_named_tuple() { assert_de_tokens( &DeNamedTuple(5, 6, 7), &[ - Token::TupleStructStart("DeNamedTuple", Some(3)), + Token::TupleStructStart("DeNamedTuple", 3), Token::TupleStructSep, Token::I32(5), @@ -239,7 +239,7 @@ fn test_ser_named_map() { c: c, }, &[ - Token::StructStart("SerNamedMap", Some(3)), + Token::StructStart("SerNamedMap", 3), Token::StructSep, Token::Str("a"), @@ -267,7 +267,7 @@ fn test_de_named_map() { c: 7, }, &[ - Token::StructStart("DeNamedMap", Some(3)), + Token::StructStart("DeNamedMap", 3), Token::StructSep, Token::Str("a"), @@ -315,7 +315,7 @@ fn test_ser_enum_seq() { //f, ), &[ - Token::EnumSeqStart("SerEnum", "Seq", Some(4)), + Token::EnumSeqStart("SerEnum", "Seq", 4), Token::EnumSeqSep, Token::I8(1), @@ -353,7 +353,7 @@ fn test_ser_enum_map() { //f: f, }, &[ - Token::EnumMapStart("SerEnum", "Map", Some(4)), + Token::EnumMapStart("SerEnum", "Map", 4), Token::EnumMapSep, Token::Str("a"), @@ -405,7 +405,7 @@ fn test_de_enum_seq() { //f, ), &[ - Token::EnumSeqStart("DeEnum", "Seq", Some(4)), + Token::EnumSeqStart("DeEnum", "Seq", 4), Token::EnumSeqSep, Token::I8(1), @@ -443,7 +443,7 @@ fn test_de_enum_map() { //f: f, }, &[ - Token::EnumMapStart("DeEnum", "Map", Some(4)), + Token::EnumMapStart("DeEnum", "Map", 4), Token::EnumMapSep, Token::Str("a"), @@ -489,7 +489,7 @@ fn test_lifetimes() { assert_ser_tokens( &Lifetimes::LifetimeMap { a: &value }, &[ - Token::EnumMapStart("Lifetimes", "LifetimeMap", Some(1)), + Token::EnumMapStart("Lifetimes", "LifetimeMap", 1), Token::EnumMapSep, Token::Str("a"), @@ -502,7 +502,7 @@ fn test_lifetimes() { assert_ser_tokens( &Lifetimes::NoLifetimeMap { a: 5 }, &[ - Token::EnumMapStart("Lifetimes", "NoLifetimeMap", Some(1)), + Token::EnumMapStart("Lifetimes", "NoLifetimeMap", 1), Token::EnumMapSep, Token::Str("a"), @@ -518,7 +518,7 @@ fn test_generic_struct() { assert_tokens( &GenericStruct { x: 5u32 }, &[ - Token::StructStart("GenericStruct", Some(1)), + Token::StructStart("GenericStruct", 1), Token::StructSep, Token::Str("x"), @@ -545,7 +545,7 @@ fn test_generic_tuple_struct() { assert_tokens( &GenericTupleStruct(5u32, 6u32), &[ - Token::TupleStructStart("GenericTupleStruct", Some(2)), + Token::TupleStructStart("GenericTupleStruct", 2), Token::TupleStructSep, Token::U32(5), @@ -584,7 +584,7 @@ fn test_generic_enum_seq() { assert_tokens( &GenericEnum::Seq::(5, 6), &[ - Token::EnumSeqStart("GenericEnum", "Seq", Some(2)), + Token::EnumSeqStart("GenericEnum", "Seq", 2), Token::EnumSeqSep, Token::U32(5), @@ -602,7 +602,7 @@ fn test_generic_enum_map() { assert_tokens( &GenericEnum::Map:: { x: 5, y: 6 }, &[ - Token::EnumMapStart("GenericEnum", "Map", Some(2)), + Token::EnumMapStart("GenericEnum", "Map", 2), Token::EnumMapSep, Token::Str("x"), @@ -622,7 +622,7 @@ fn test_default_ty_param() { assert_tokens( &DefaultTyParam:: { phantom: PhantomData }, &[ - Token::StructStart("DefaultTyParam", Some(1)), + Token::StructStart("DefaultTyParam", 1), Token::StructSep, Token::Str("phantom"), diff --git a/testing/tests/test_ser.rs b/testing/tests/test_ser.rs index 981ddb86..e772e05e 100644 --- a/testing/tests/test_ser.rs +++ b/testing/tests/test_ser.rs @@ -256,7 +256,7 @@ declare_ser_tests! { } test_tuple_struct { TupleStruct(1, 2, 3) => &[ - Token::TupleStructStart("TupleStruct", Some(3)), + Token::TupleStructStart("TupleStruct", 3), Token::TupleStructSep, Token::I32(1), @@ -270,7 +270,7 @@ declare_ser_tests! { } test_struct { Struct { a: 1, b: 2, c: 3 } => &[ - Token::StructStart("Struct", Some(3)), + Token::StructStart("Struct", 3), Token::StructSep, Token::Str("a"), Token::I32(1), @@ -289,7 +289,7 @@ declare_ser_tests! { Enum::Unit => &[Token::EnumUnit("Enum", "Unit")], Enum::One(42) => &[Token::EnumNewType("Enum", "One"), Token::I32(42)], Enum::Seq(1, 2) => &[ - Token::EnumSeqStart("Enum", "Seq", Some(2)), + Token::EnumSeqStart("Enum", "Seq", 2), Token::EnumSeqSep, Token::I32(1), @@ -298,7 +298,7 @@ declare_ser_tests! { Token::EnumSeqEnd, ], Enum::Map { a: 1, b: 2 } => &[ - Token::EnumMapStart("Enum", "Map", Some(2)), + Token::EnumMapStart("Enum", "Map", 2), Token::EnumMapSep, Token::Str("a"), Token::I32(1),