diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index d00e483d..0d1d8a4f 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -565,7 +565,7 @@ array_impls! { macro_rules! tuple_impls { () => {}; - ($($visitor:ident => ($($name:ident),+),)+) => { + ($($len:expr => $visitor:ident => ($($name:ident),+),)+) => { $( pub struct $visitor<$($name,)+> { marker: PhantomData<($($name,)+)>, @@ -610,7 +610,7 @@ macro_rules! tuple_impls { fn deserialize(deserializer: &mut D) -> Result<($($name,)+), D::Error> where D: Deserializer, { - deserializer.visit_tuple($visitor::new()) + deserializer.visit_tuple($len, $visitor::new()) } } )+ @@ -618,18 +618,18 @@ macro_rules! tuple_impls { } tuple_impls! { - TupleVisitor1 => (T0), - TupleVisitor2 => (T0, T1), - TupleVisitor3 => (T0, T1, T2), - TupleVisitor4 => (T0, T1, T2, T3), - TupleVisitor5 => (T0, T1, T2, T3, T4), - TupleVisitor6 => (T0, T1, T2, T3, T4, T5), - TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6), - TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7), - TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8), - TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9), - TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10), - TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11), + 1 => TupleVisitor1 => (T0), + 2 => TupleVisitor2 => (T0, T1), + 3 => TupleVisitor3 => (T0, T1, T2), + 4 => TupleVisitor4 => (T0, T1, T2, T3), + 5 => TupleVisitor5 => (T0, T1, T2, T3, T4), + 6 => TupleVisitor6 => (T0, T1, T2, T3, T4, T5), + 7 => TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6), + 8 => TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7), + 9 => TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8), + 10 => TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9), + 11 => TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10), + 12 => TupleVisitor12 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11), } /////////////////////////////////////////////////////////////////////////////// @@ -877,6 +877,14 @@ impl Deserialize for Result where T: Deserialize, E: Deserialize { impl ::de::Visitor for FieldVisitor { type Value = Field; + fn visit_usize(&mut self, value: usize) -> Result where E: Error { + match value { + 0 => Ok(Field::Ok), + 1 => Ok(Field::Err), + _ => Err(Error::unknown_field_error(&value.to_string())), + } + } + fn visit_str(&mut self, value: &str) -> Result where E: Error { match value { "Ok" => Ok(Field::Ok), @@ -916,17 +924,19 @@ impl Deserialize for Result where T: Deserialize, E: Deserialize { { match try!(visitor.visit_variant()) { Field::Ok => { - let (value,) = try!(visitor.visit_seq(TupleVisitor1::new())); + let value = try!(visitor.visit_simple()); Ok(Ok(value)) } Field::Err => { - let (value,) = try!(visitor.visit_seq(TupleVisitor1::new())); + let value = try!(visitor.visit_simple()); Ok(Err(value)) } } } } - deserializer.visit_enum("Result", Visitor(PhantomData)) + const VARIANTS: &'static [&'static str] = &["Ok", "Err"]; + + deserializer.visit_enum("Result", VARIANTS, Visitor(PhantomData)) } } diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 2f3c6a30..0f865920 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -211,7 +211,9 @@ pub trait Deserializer { /// This method hints that the `Deserialize` type is expecting a named unit. This allows /// deserializers to a named unit that aren't tagged as a named unit. #[inline] - fn visit_unit_struct(&mut self, _name: &str, visitor: V) -> Result + fn visit_unit_struct(&mut self, + _name: &'static str, + visitor: V) -> Result where V: Visitor, { self.visit_unit(visitor) @@ -220,17 +222,20 @@ pub trait Deserializer { /// This method hints that the `Deserialize` type is expecting a tuple struct. This allows /// deserializers to parse sequences that aren't tagged as sequences. #[inline] - fn visit_tuple_struct(&mut self, _name: &str, visitor: V) -> Result + fn visit_tuple_struct(&mut self, + _name: &'static str, + len: usize, + visitor: V) -> Result where V: Visitor, { - self.visit_tuple(visitor) + self.visit_tuple(len, visitor) } /// This method hints that the `Deserialize` type is expecting a struct. This allows /// deserializers to parse sequences that aren't tagged as maps. #[inline] fn visit_struct(&mut self, - _name: &str, + _name: &'static str, _fields: &'static [&'static str], visitor: V) -> Result where V: Visitor, @@ -241,7 +246,7 @@ pub trait Deserializer { /// This method hints that the `Deserialize` type is expecting a tuple value. This allows /// deserializers that provide a custom tuple serialization to properly deserialize the type. #[inline] - fn visit_tuple(&mut self, visitor: V) -> Result + fn visit_tuple(&mut self, _len: usize, visitor: V) -> Result where V: Visitor, { self.visit_seq(visitor) @@ -251,7 +256,10 @@ pub trait Deserializer { /// deserializers that provide a custom enumeration serialization to properly deserialize the /// type. #[inline] - fn visit_enum(&mut self, _enum: &str, _visitor: V) -> Result + fn visit_enum(&mut self, + _enum: &'static str, + _variants: &'static [&'static str], + _visitor: V) -> Result where V: EnumVisitor, { Err(Error::syntax_error()) @@ -389,7 +397,7 @@ pub trait Visitor { } #[inline] - fn visit_unit_struct(&mut self, _name: &str) -> Result + fn visit_unit_struct(&mut self, _name: &'static str) -> Result where E: Error, { self.visit_unit() @@ -572,21 +580,25 @@ pub trait VariantVisitor { } /// `visit_simple` is called when deserializing a variant with a single value. - fn visit_simple(&mut self) -> Result { + fn visit_simple(&mut self) -> Result + where T: Deserialize, + { Err(Error::syntax_error()) } - /// `visit_seq` is called when deserializing a tuple-like variant. - fn visit_seq(&mut self, _visitor: V) -> Result + /// `visit_tuple` is called when deserializing a tuple-like variant. + fn visit_tuple(&mut self, + _len: usize, + _visitor: V) -> Result where V: Visitor { Err(Error::syntax_error()) } - /// `visit_map` is called when deserializing a struct-like variant. - fn visit_map(&mut self, - _fields: &'static [&'static str], - _visitor: V) -> Result + /// `visit_struct` is called when deserializing a struct-like variant. + fn visit_struct(&mut self, + _fields: &'static [&'static str], + _visitor: V) -> Result where V: Visitor { Err(Error::syntax_error()) @@ -606,22 +618,26 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor { (**self).visit_unit() } - fn visit_simple(&mut self) -> Result { + fn visit_simple(&mut self) -> Result + where D: Deserialize, + { (**self).visit_simple() } - fn visit_seq(&mut self, visitor: V) -> Result + fn visit_tuple(&mut self, + len: usize, + visitor: V) -> Result where V: Visitor, { - (**self).visit_seq(visitor) + (**self).visit_tuple(len, visitor) } - fn visit_map(&mut self, + fn visit_struct(&mut self, fields: &'static [&'static str], visitor: V) -> Result where V: Visitor, { - (**self).visit_map(fields, visitor) + (**self).visit_struct(fields, visitor) } } diff --git a/serde/src/de/value.rs b/serde/src/de/value.rs index e512badc..8ad281b7 100644 --- a/serde/src/de/value.rs +++ b/serde/src/de/value.rs @@ -136,7 +136,10 @@ impl<'a> de::Deserializer for StrDeserializer<'a> { } } - fn visit_enum(&mut self, _name: &str, mut visitor: V) -> Result + fn visit_enum(&mut self, + _name: &str, + _variants: &'static [&'static str], + mut visitor: V) -> Result where V: de::EnumVisitor, { visitor.visit(self) @@ -182,7 +185,10 @@ impl de::Deserializer for StringDeserializer { } } - fn visit_enum(&mut self, _name: &str, mut visitor: V) -> Result + fn visit_enum(&mut self, + _name: &str, + _variants: &'static [&'static str], + mut visitor: V) -> Result where V: de::EnumVisitor, { visitor.visit(self) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index a8efe18a..ec7c3884 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -97,6 +97,26 @@ impl Serialize for Option where T: Serialize { } } +impl SeqVisitor for Option where T: Serialize { + #[inline] + fn visit(&mut self, serializer: &mut S) -> Result, S::Error> + where S: Serializer, + { + match self.take() { + Some(value) => { + try!(serializer.visit_seq_elt(value)); + Ok(Some(())) + } + None => Ok(None), + } + } + + #[inline] + fn len(&self) -> Option { + Some(if self.is_some() { 1 } else { 0 }) + } +} + /////////////////////////////////////////////////////////////////////////////// pub struct SeqIteratorVisitor { @@ -126,8 +146,8 @@ impl SeqVisitor for SeqIteratorVisitor { match self.iter.next() { Some(value) => { - let value = try!(serializer.visit_seq_elt(value)); - Ok(Some(value)) + try!(serializer.visit_seq_elt(value)); + Ok(Some(())) } None => Ok(None), } @@ -612,47 +632,10 @@ impl Serialize for Result where T: Serialize, E: Serialize { fn serialize(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer { match *self { Result::Ok(ref value) => { - struct Visitor<'a, T: 'a>(Option<&'a T>); - - impl<'a, T> SeqVisitor for Visitor<'a, T> where T: Serialize + 'a { - #[inline] - fn visit(&mut self, serializer: &mut S) -> Result, S::Error> - where S: Serializer - { - match self.0.take() { - Some(value) => Ok(Some(try!(serializer.visit_seq_elt(value)))), - None => Ok(None), - } - } - - #[inline] - fn len(&self) -> Option { - Some(1) - } - } - - serializer.visit_enum_seq("Result", 0, "Ok", Visitor(Some(value))) + serializer.visit_enum_simple("Result", 0, "Ok", value) } Result::Err(ref value) => { - struct Visitor<'a, E: 'a>(Option<&'a E>); - - impl<'a, E> SeqVisitor for Visitor<'a, E> where E: Serialize + 'a { - #[inline] - fn visit(&mut self, serializer: &mut S) -> Result, S::Error> - where S: Serializer { - match self.0.take() { - Some(value) => Ok(Some(try!(serializer.visit_seq_elt(value)))), - None => Ok(None), - } - } - - #[inline] - fn len(&self) -> Option { - Some(1) - } - } - - serializer.visit_enum_seq("Result", 1, "Err", Visitor(Some(value))) + serializer.visit_enum_simple("Result", 1, "Err", value) } } } diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 4484d344..816e932a 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -113,25 +113,32 @@ pub trait Serializer { fn visit_unit(&mut self) -> Result<(), Self::Error>; #[inline] - fn visit_unit_struct(&mut self, _name: &str) -> Result<(), Self::Error> { + fn visit_unit_struct(&mut self, _name: &'static str) -> Result<(), Self::Error> { self.visit_unit() } #[inline] - fn visit_enum_unit(&mut self, - _name: &str, - _variant_index: usize, - _variant: &str) -> Result<(), Self::Error> { + fn visit_unit_variant(&mut self, + _name: &'static str, + _variant_index: usize, + _variant: &'static str) -> Result<(), Self::Error> { self.visit_unit() } #[inline] fn visit_enum_simple(&mut self, - _name: &str, - _variant: &str, - _value: T, - ) -> Result<(), Self::Error> - where T: Serialize; + name: &'static str, + variant_index: usize, + variant: &'static str, + value: T) -> Result<(), Self::Error> + where T: Serialize, + { + self.visit_tuple_variant( + name, + variant_index, + variant, + Some(value)) + } fn visit_none(&mut self) -> Result<(), Self::Error>; @@ -160,8 +167,8 @@ pub trait Serializer { #[inline] fn visit_tuple_struct(&mut self, - _name: &'static str, - visitor: V) -> Result<(), Self::Error> + _name: &'static str, + visitor: V) -> Result<(), Self::Error> where V: SeqVisitor, { self.visit_tuple(visitor) @@ -175,18 +182,18 @@ pub trait Serializer { } #[inline] - fn visit_enum_seq(&mut self, - _name: &'static str, - _variant_index: usize, - variant: &'static str, - visitor: V) -> Result<(), Self::Error> + fn visit_tuple_variant(&mut self, + _name: &'static str, + _variant_index: usize, + variant: &'static str, + visitor: V) -> Result<(), Self::Error> where V: SeqVisitor, { self.visit_tuple_struct(variant, visitor) } #[inline] - fn visit_enum_seq_elt(&mut self, value: T) -> Result<(), Self::Error> + fn visit_tuple_variant_elt(&mut self, value: T) -> Result<(), Self::Error> where T: Serialize { self.visit_tuple_struct_elt(value) @@ -201,15 +208,17 @@ pub trait Serializer { #[inline] fn visit_struct(&mut self, - _name: &'static str, - visitor: V) -> Result<(), Self::Error> + _name: &'static str, + visitor: V) -> Result<(), Self::Error> where V: MapVisitor, { self.visit_map(visitor) } #[inline] - fn visit_struct_elt(&mut self, key: K, value: V) -> Result<(), Self::Error> + fn visit_struct_elt(&mut self, + key: K, + value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize, { @@ -217,18 +226,20 @@ pub trait Serializer { } #[inline] - fn visit_enum_map(&mut self, - _name: &'static str, - _variant_index: usize, - variant: &'static str, - visitor: V) -> Result<(), Self::Error> + fn visit_struct_variant(&mut self, + _name: &'static str, + _variant_index: usize, + variant: &'static str, + visitor: V) -> Result<(), Self::Error> where V: MapVisitor, { self.visit_struct(variant, visitor) } #[inline] - fn visit_enum_map_elt(&mut self, key: K, value: V) -> Result<(), Self::Error> + fn visit_struct_variant_elt(&mut self, + key: K, + value: V) -> Result<(), Self::Error> where K: Serialize, V: Serialize, { diff --git a/serde_codegen/src/de.rs b/serde_codegen/src/de.rs index 8fb69f0e..a34d44d6 100644 --- a/serde_codegen/src/de.rs +++ b/serde_codegen/src/de.rs @@ -318,7 +318,7 @@ fn deserialize_tuple_struct( } } - deserializer.visit_tuple_struct($type_name, $visitor_expr) + deserializer.visit_tuple_struct($type_name, $fields, $visitor_expr) }) } @@ -489,6 +489,19 @@ fn deserialize_item_enum( .collect() ); + let variants_expr = builder.expr().addr_of().slice() + .with_exprs( + enum_def.variants.iter() + .map(|variant| { + builder.expr().str(variant.node.name) + }) + ) + .build(); + + let variants_stmt = quote_stmt!(cx, + const VARIANTS: &'static [&'static str] = $variants_expr; + ).unwrap(); + // Match arms to extract a variant from a string let variant_arms: Vec<_> = enum_def.variants.iter() .enumerate() @@ -535,7 +548,9 @@ fn deserialize_item_enum( } } - deserializer.visit_enum($type_name, $visitor_expr) + $variants_stmt + + deserializer.visit_enum($type_name, VARIANTS, $visitor_expr) }) } @@ -626,7 +641,7 @@ fn deserialize_tuple_variant( } } - visitor.visit_seq($visitor_expr) + visitor.visit_tuple($fields, $visitor_expr) }) } @@ -693,7 +708,7 @@ fn deserialize_struct_variant( $fields_stmt - visitor.visit_map(FIELDS, $visitor_expr) + visitor.visit_struct(FIELDS, $visitor_expr) }) } @@ -750,10 +765,10 @@ fn deserialize_field_visitor( let str_body = if formats.is_empty() { // No formats specific attributes, so no match on format required quote_expr!(cx, - match value { - $default_field_arms - _ => { Err(::serde::de::Error::unknown_field_error(value)) } - }) + match value { + $default_field_arms + _ => { Err(::serde::de::Error::unknown_field_error(value)) } + }) } else { let field_arms: Vec<_> = formats.iter() .map(|fmt| { diff --git a/serde_codegen/src/ser.rs b/serde_codegen/src/ser.rs index b4e4f7f4..7d80f9dd 100644 --- a/serde_codegen/src/ser.rs +++ b/serde_codegen/src/ser.rs @@ -288,7 +288,7 @@ fn serialize_variant( quote_arm!(cx, $pat => { - ::serde::ser::Serializer::visit_enum_unit( + ::serde::ser::Serializer::visit_unit_variant( serializer, $type_name, $variant_index, @@ -309,6 +309,7 @@ fn serialize_variant( ::serde::ser::Serializer::visit_enum_simple( serializer, $type_name, + $variant_index, $variant_name, __simple_value, ) @@ -421,7 +422,7 @@ fn serialize_tuple_variant( quote_expr!(cx, { $visitor_struct $visitor_impl - serializer.visit_enum_seq($type_name, $variant_index, $variant_name, Visitor { + serializer.visit_tuple_variant($type_name, $variant_index, $variant_name, Visitor { value: $value_expr, state: 0, _structure_ty: ::std::marker::PhantomData::<&$structure_ty>, @@ -476,7 +477,7 @@ fn serialize_struct_variant( quote_expr!(cx, { $visitor_struct $visitor_impl - serializer.visit_enum_map($type_name, $variant_index, $variant_name, Visitor { + serializer.visit_struct_variant($type_name, $variant_index, $variant_name, Visitor { value: $value_expr, state: 0, _structure_ty: ::std::marker::PhantomData::<&$structure_ty>, diff --git a/serde_json/src/de.rs b/serde_json/src/de.rs index efdd53df..5fbbfb1c 100644 --- a/serde_json/src/de.rs +++ b/serde_json/src/de.rs @@ -454,7 +454,10 @@ impl de::Deserializer for Deserializer } #[inline] - fn visit_enum(&mut self, _name: &str, mut visitor: V) -> Result + fn visit_enum(&mut self, + _name: &str, + _variants: &'static [&'static str], + mut visitor: V) -> Result where V: de::EnumVisitor, { try!(self.parse_whitespace()); @@ -645,15 +648,17 @@ impl de::VariantVisitor for Deserializer de::Deserialize::deserialize(self) } - fn visit_seq(&mut self, visitor: V) -> Result + fn visit_tuple(&mut self, + _len: usize, + visitor: V) -> Result where V: de::Visitor, { de::Deserializer::visit(self, visitor) } - fn visit_map(&mut self, - _fields: &'static [&'static str], - visitor: V) -> Result + fn visit_struct(&mut self, + _fields: &'static [&'static str], + visitor: V) -> Result where V: de::Visitor, { de::Deserializer::visit(self, visitor) diff --git a/serde_json/src/ser.rs b/serde_json/src/ser.rs index b7f5b2d8..c1368833 100644 --- a/serde_json/src/ser.rs +++ b/serde_json/src/ser.rs @@ -159,10 +159,10 @@ impl ser::Serializer for Serializer } #[inline] - fn visit_enum_unit(&mut self, - _name: &str, - _variant_index: usize, - variant: &str) -> io::Result<()> { + fn visit_unit_variant(&mut self, + _name: &str, + _variant_index: usize, + variant: &str) -> io::Result<()> { try!(self.formatter.open(&mut self.writer, b'{')); try!(self.formatter.comma(&mut self.writer, true)); try!(self.visit_str(variant)); @@ -174,6 +174,7 @@ impl ser::Serializer for Serializer #[inline] fn visit_enum_simple(&mut self, _name: &str, + _variant_index: usize, variant: &str, value: T, ) -> io::Result<()> @@ -209,11 +210,11 @@ impl ser::Serializer for Serializer } #[inline] - fn visit_enum_seq(&mut self, - _name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> io::Result<()> + fn visit_tuple_variant(&mut self, + _name: &str, + _variant_index: usize, + variant: &str, + visitor: V) -> io::Result<()> where V: ser::SeqVisitor, { try!(self.formatter.open(&mut self.writer, b'{')); @@ -257,11 +258,11 @@ impl ser::Serializer for Serializer } #[inline] - fn visit_enum_map(&mut self, - _name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> io::Result<()> + fn visit_struct_variant(&mut self, + _name: &str, + _variant_index: usize, + variant: &str, + visitor: V) -> io::Result<()> where V: ser::MapVisitor, { try!(self.formatter.open(&mut self.writer, b'{')); diff --git a/serde_json/src/value.rs b/serde_json/src/value.rs index f01dfe1d..ea40cb83 100644 --- a/serde_json/src/value.rs +++ b/serde_json/src/value.rs @@ -459,10 +459,10 @@ impl ser::Serializer for Serializer { } #[inline] - fn visit_enum_unit(&mut self, - _name: &str, - _variant_index: usize, - variant: &str) -> Result<(), ()> { + fn visit_unit_variant(&mut self, + _name: &str, + _variant_index: usize, + variant: &str) -> Result<(), ()> { let mut values = BTreeMap::new(); values.insert(variant.to_string(), Value::Array(vec![])); @@ -474,6 +474,7 @@ impl ser::Serializer for Serializer { #[inline] fn visit_enum_simple(&mut self, _name: &str, + _variant_index: usize, variant: &str, value: T, ) -> Result<(), ()> @@ -509,11 +510,11 @@ impl ser::Serializer for Serializer { } #[inline] - fn visit_enum_seq(&mut self, - _name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> Result<(), ()> + fn visit_tuple_variant(&mut self, + _name: &str, + _variant_index: usize, + variant: &str, + visitor: V) -> Result<(), ()> where V: ser::SeqVisitor, { try!(self.visit_seq(visitor)); @@ -572,11 +573,11 @@ impl ser::Serializer for Serializer { } #[inline] - fn visit_enum_map(&mut self, - _name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> Result<(), ()> + fn visit_struct_variant(&mut self, + _name: &str, + _variant_index: usize, + variant: &str, + visitor: V) -> Result<(), ()> where V: ser::MapVisitor, { try!(self.visit_map(visitor)); @@ -692,7 +693,10 @@ impl de::Deserializer for Deserializer { } #[inline] - fn visit_enum(&mut self, _name: &str, mut visitor: V) -> Result + fn visit_enum(&mut self, + _name: &str, + _variants: &'static [&'static str], + mut visitor: V) -> Result where V: de::EnumVisitor, { let value = match self.value.take() { @@ -740,17 +744,19 @@ impl<'a> de::VariantVisitor for VariantDeserializer<'a> { de::Deserialize::deserialize(&mut Deserializer::new(self.variant.take().unwrap())) } - fn visit_unit(&mut self) -> Result<(), Error> + fn visit_unit(&mut self) -> Result<(), Error> { + de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap())) + } + + fn visit_simple(&mut self) -> Result + where T: de::Deserialize, { de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap())) } - fn visit_simple(&mut self) -> Result - { - de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap())) - } - - fn visit_seq(&mut self, visitor: V) -> Result + fn visit_tuple(&mut self, + _len: usize, + visitor: V) -> Result where V: de::Visitor, { if let Value::Array(fields) = self.val.take().unwrap() { @@ -767,7 +773,9 @@ impl<'a> de::VariantVisitor for VariantDeserializer<'a> { } } - fn visit_map(&mut self, _fields: &'static[&'static str], visitor: V) -> Result + fn visit_struct(&mut self, + _fields: &'static[&'static str], + visitor: V) -> Result where V: de::Visitor, { if let Value::Object(fields) = self.val.take().unwrap() { diff --git a/serde_tests/benches/bench_enum.rs b/serde_tests/benches/bench_enum.rs index 2b83507b..b97c20cc 100644 --- a/serde_tests/benches/bench_enum.rs +++ b/serde_tests/benches/bench_enum.rs @@ -288,7 +288,10 @@ mod deserializer { } #[inline] - fn visit_enum(&mut self, _name: &str, mut visitor: V) -> Result + fn visit_enum(&mut self, + _name: &str, + _variants: &[&str], + mut visitor: V) -> Result where V: de::EnumVisitor, { match self.stack.pop() { @@ -350,7 +353,9 @@ mod deserializer { de::Deserialize::deserialize(self.de) } - fn visit_seq(&mut self, mut visitor: V) -> Result + fn visit_tuple(&mut self, + _len: usize, + mut visitor: V) -> Result where V: de::Visitor, { visitor.visit_seq(self) diff --git a/serde_tests/tests/test_bytes.rs b/serde_tests/tests/test_bytes.rs index 65c466a3..3ca97285 100644 --- a/serde_tests/tests/test_bytes.rs +++ b/serde_tests/tests/test_bytes.rs @@ -39,15 +39,6 @@ impl serde::Serializer for BytesSerializer { Err(Error) } - fn visit_enum_simple(&mut self, - _name: &str, - _variant: &str, - _value: T, - ) -> Result<(), Error> - { - Err(Error) - } - fn visit_bool(&mut self, _v: bool) -> Result<(), Error> { Err(Error) } diff --git a/serde_tests/tests/test_de.rs b/serde_tests/tests/test_de.rs index 9b789c84..2783654c 100644 --- a/serde_tests/tests/test_de.rs +++ b/serde_tests/tests/test_de.rs @@ -22,6 +22,7 @@ enum Token { Char(char), Str(&'static str), String(String), + Bytes(&'static [u8]), Option(bool), @@ -38,6 +39,10 @@ enum Token { MapEnd, EnumStart(&'static str), + EnumUnit, + EnumSimple, + EnumSeq, + EnumMap, EnumEnd, } @@ -99,6 +104,7 @@ impl Deserializer for TokenDeserializer { Some(Token::Char(v)) => visitor.visit_char(v), Some(Token::Str(v)) => visitor.visit_str(v), Some(Token::String(v)) => visitor.visit_string(v), + Some(Token::Bytes(v)) => visitor.visit_bytes(v), Some(Token::Option(false)) => visitor.visit_none(), Some(Token::Option(true)) => visitor.visit_some(self), Some(Token::Unit) => visitor.visit_unit(), @@ -143,7 +149,10 @@ impl Deserializer for TokenDeserializer { } } - fn visit_enum(&mut self, name: &str, mut visitor: V) -> Result + fn visit_enum(&mut self, + name: &str, + _variants: &'static [&'static str], + mut visitor: V) -> Result where V: de::EnumVisitor, { match self.tokens.next() { @@ -178,7 +187,10 @@ impl Deserializer for TokenDeserializer { } } - fn visit_tuple_struct(&mut self, name: &str, visitor: V) -> Result + fn visit_tuple_struct(&mut self, + name: &str, + _len: usize, + visitor: V) -> Result where V: de::Visitor, { match self.tokens.peek() { @@ -318,21 +330,53 @@ impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> { } fn visit_unit(&mut self) -> Result<(), Error> { - de::Deserialize::deserialize(self.de) + match self.de.tokens.next() { + Some(Token::EnumUnit) => { + de::Deserialize::deserialize(self.de) + } + Some(_) => Err(Error::SyntaxError), + None => Err(Error::EndOfStreamError), + } } - fn visit_seq(&mut self, visitor: V) -> Result - where V: de::Visitor, + fn visit_simple(&mut self) -> Result + where T: de::Deserialize, { - de::Deserializer::visit(self.de, visitor) + match self.de.tokens.next() { + Some(Token::EnumSimple) => { + de::Deserialize::deserialize(self.de) + } + Some(_) => Err(Error::SyntaxError), + None => Err(Error::EndOfStreamError), + } } - fn visit_map(&mut self, - _fields: &'static [&'static str], - visitor: V) -> Result + fn visit_tuple(&mut self, + _len: usize, + visitor: V) -> Result where V: de::Visitor, { - de::Deserializer::visit(self.de, visitor) + match self.de.tokens.next() { + Some(Token::EnumSeq) => { + de::Deserializer::visit(self.de, visitor) + } + Some(_) => Err(Error::SyntaxError), + None => Err(Error::EndOfStreamError), + } + } + + fn visit_struct(&mut self, + _fields: &'static [&'static str], + visitor: V) -> Result + where V: de::Visitor, + { + match self.de.tokens.next() { + Some(Token::EnumMap) => { + de::Deserializer::visit(self.de, visitor) + } + Some(_) => Err(Error::SyntaxError), + None => Err(Error::EndOfStreamError), + } } } @@ -354,6 +398,7 @@ struct Struct { #[derive(PartialEq, Debug, Deserialize)] enum Enum { Unit, + Simple(i32), Seq(i32, i32, i32), Map { a: i32, b: i32, c: i32 } } @@ -495,20 +540,18 @@ declare_tests! { Ok::(0) => vec![ Token::EnumStart("Result"), Token::Str("Ok"), - Token::SeqStart(1), - Token::SeqSep, - Token::I32(0), - Token::SeqEnd, - Token::EnumEnd, + + Token::EnumSimple, + Token::I32(0), + Token::SeqEnd, ], Err::(1) => vec![ Token::EnumStart("Result"), Token::Str("Err"), - Token::SeqStart(1), - Token::SeqSep, - Token::I32(1), - Token::SeqEnd, - Token::EnumEnd, + + Token::EnumSimple, + Token::I32(1), + Token::SeqEnd, ], } test_unit { @@ -880,14 +923,28 @@ declare_tests! { Enum::Unit => vec![ Token::EnumStart("Enum"), Token::Str("Unit"), + + Token::EnumUnit, Token::Unit, Token::EnumEnd, ], } + test_enum_simple { + Enum::Simple(1) => vec![ + Token::EnumStart("Enum"), + Token::Str("Simple"), + + Token::EnumSimple, + Token::I32(1), + Token::EnumEnd, + ], + } test_enum_seq { Enum::Seq(1, 2, 3) => vec![ Token::EnumStart("Enum"), Token::Str("Seq"), + + Token::EnumSeq, Token::SeqStart(3), Token::SeqSep, Token::I32(1), @@ -905,6 +962,8 @@ declare_tests! { Enum::Map { a: 1, b: 2, c: 3 } => vec![ Token::EnumStart("Enum"), Token::Str("Map"), + + Token::EnumMap, Token::MapStart(3), Token::MapSep, Token::Str("a"), @@ -921,4 +980,24 @@ declare_tests! { Token::EnumEnd, ], } + test_enum_unit_usize { + Enum::Unit => vec![ + Token::EnumStart("Enum"), + Token::Usize(0), + + Token::EnumUnit, + Token::Unit, + Token::EnumEnd, + ], + } + test_enum_unit_bytes { + Enum::Unit => vec![ + Token::EnumStart("Enum"), + Token::Bytes(b"Unit"), + + Token::EnumUnit, + Token::Unit, + Token::EnumEnd, + ], + } } diff --git a/serde_tests/tests/test_ser.rs b/serde_tests/tests/test_ser.rs index 62627fba..6b0d8347 100644 --- a/serde_tests/tests/test_ser.rs +++ b/serde_tests/tests/test_ser.rs @@ -84,6 +84,7 @@ impl<'a> Serializer for AssertSerializer<'a> { fn visit_enum_simple(&mut self, name: &str, + _variant_index: usize, variant: &str, value: T, ) -> Result<(), ()> @@ -98,10 +99,10 @@ impl<'a> Serializer for AssertSerializer<'a> { Ok(()) } - fn visit_enum_unit(&mut self, - name: &str, - _variant_index: usize, - variant: &str) -> Result<(), ()> { + fn visit_unit_variant(&mut self, + name: &str, + _variant_index: usize, + variant: &str) -> Result<(), ()> { assert_eq!( self.iter.next().unwrap(), Token::EnumUnit(name, variant) @@ -221,11 +222,11 @@ impl<'a> Serializer for AssertSerializer<'a> { self.visit_sequence(visitor) } - fn visit_enum_seq(&mut self, - name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> Result<(), ()> + fn visit_tuple_variant(&mut self, + name: &str, + _variant_index: usize, + variant: &str, + visitor: V) -> Result<(), ()> where V: SeqVisitor { let len = visitor.len(); @@ -268,11 +269,11 @@ impl<'a> Serializer for AssertSerializer<'a> { self.visit_mapping(visitor) } - fn visit_enum_map(&mut self, - name: &str, - _variant_index: usize, - variant: &str, - visitor: V) -> Result<(), ()> + fn visit_struct_variant(&mut self, + name: &str, + _variant_index: usize, + variant: &str, + visitor: V) -> Result<(), ()> where V: MapVisitor { let len = visitor.len(); @@ -396,16 +397,12 @@ declare_tests! { } test_result { Ok::(0) => vec![ - Token::EnumSeqStart("Result", "Ok", Some(1)), - Token::SeqSep, + Token::EnumSimple("Result", "Ok"), Token::I32(0), - Token::SeqEnd, ], Err::(1) => vec![ - Token::EnumSeqStart("Result", "Err", Some(1)), - Token::SeqSep, + Token::EnumSimple("Result", "Err"), Token::I32(1), - Token::SeqEnd, ], } test_slice {