From 6c9cebdcc3e536dc849d62509410c493f3559e3b Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Wed, 29 Jul 2015 12:04:31 -0700 Subject: [PATCH 01/13] Pass the variant fields and tuple lengths into visit_{enum,tuple,tuple_struct} --- serde/src/de/impls.rs | 36 ++++++++++++++++--------------- serde/src/de/mod.rs | 20 +++++++++++------ serde/src/de/value.rs | 10 +++++++-- serde_codegen/src/de.rs | 21 +++++++++++++++--- serde_json/src/de.rs | 9 ++++++-- serde_json/src/value.rs | 13 ++++++++--- serde_tests/benches/bench_enum.rs | 9 ++++++-- serde_tests/tests/test_de.rs | 14 +++++++++--- 8 files changed, 93 insertions(+), 39 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index d00e483d..0b43eed3 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), } /////////////////////////////////////////////////////////////////////////////// @@ -916,17 +916,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_seq(1, TupleVisitor1::new())); Ok(Ok(value)) } Field::Err => { - let (value,) = try!(visitor.visit_seq(TupleVisitor1::new())); + let (value,) = try!(visitor.visit_seq(1, TupleVisitor1::new())); 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..a04e0a74 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -220,10 +220,13 @@ 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: &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 @@ -241,7 +244,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 +254,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: &str, + _variants: &'static [&'static str], + _visitor: V) -> Result where V: EnumVisitor, { Err(Error::syntax_error()) @@ -577,7 +583,7 @@ pub trait VariantVisitor { } /// `visit_seq` is called when deserializing a tuple-like variant. - fn visit_seq(&mut self, _visitor: V) -> Result + fn visit_seq(&mut self, _len: usize, _visitor: V) -> Result where V: Visitor { Err(Error::syntax_error()) @@ -610,10 +616,10 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor { (**self).visit_simple() } - fn visit_seq(&mut self, visitor: V) -> Result + fn visit_seq(&mut self, len: usize, visitor: V) -> Result where V: Visitor, { - (**self).visit_seq(visitor) + (**self).visit_seq(len, visitor) } fn visit_map(&mut self, 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_codegen/src/de.rs b/serde_codegen/src/de.rs index 8fb69f0e..ab8adced 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_seq($fields, $visitor_expr) }) } diff --git a/serde_json/src/de.rs b/serde_json/src/de.rs index efdd53df..dc0ce34d 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,7 +648,9 @@ impl de::VariantVisitor for Deserializer de::Deserialize::deserialize(self) } - fn visit_seq(&mut self, visitor: V) -> Result + fn visit_seq(&mut self, + _len: usize, + visitor: V) -> Result where V: de::Visitor, { de::Deserializer::visit(self, visitor) diff --git a/serde_json/src/value.rs b/serde_json/src/value.rs index f01dfe1d..061c80ab 100644 --- a/serde_json/src/value.rs +++ b/serde_json/src/value.rs @@ -692,7 +692,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() { @@ -750,7 +753,9 @@ impl<'a> de::VariantVisitor for VariantDeserializer<'a> { de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap())) } - fn visit_seq(&mut self, visitor: V) -> Result + fn visit_seq(&mut self, + _len: usize, + visitor: V) -> Result where V: de::Visitor, { if let Value::Array(fields) = self.val.take().unwrap() { @@ -767,7 +772,9 @@ impl<'a> de::VariantVisitor for VariantDeserializer<'a> { } } - fn visit_map(&mut self, _fields: &'static[&'static str], visitor: V) -> Result + fn visit_map(&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_de.rs b/serde_tests/tests/test_de.rs index 9b789c84..67ad4c74 100644 --- a/serde_tests/tests/test_de.rs +++ b/serde_tests/tests/test_de.rs @@ -143,7 +143,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 +181,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() { @@ -321,7 +327,9 @@ impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> { de::Deserialize::deserialize(self.de) } - fn visit_seq(&mut self, visitor: V) -> Result + fn visit_seq(&mut self, + _len: usize, + visitor: V) -> Result where V: de::Visitor, { de::Deserializer::visit(self.de, visitor) From 578a0178b505d9c7e0a926ccfb651853791a9d7b Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Wed, 29 Jul 2015 12:07:29 -0700 Subject: [PATCH 02/13] Make sure the visit_{enum,struct,tuple_struct} name is a `&'static str` --- serde/src/de/mod.rs | 12 +++++++----- serde/src/ser/mod.rs | 6 +++--- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index a04e0a74..611c8c8e 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) @@ -221,7 +223,7 @@ pub trait Deserializer { /// deserializers to parse sequences that aren't tagged as sequences. #[inline] fn visit_tuple_struct(&mut self, - _name: &str, + _name: &'static str, len: usize, visitor: V) -> Result where V: Visitor, @@ -233,7 +235,7 @@ pub trait Deserializer { /// 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, @@ -255,7 +257,7 @@ pub trait Deserializer { /// type. #[inline] fn visit_enum(&mut self, - _enum: &str, + _enum: &'static str, _variants: &'static [&'static str], _visitor: V) -> Result where V: EnumVisitor, @@ -395,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() diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 4484d344..ac20dad6 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -113,15 +113,15 @@ 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, + _name: &'static str, _variant_index: usize, - _variant: &str) -> Result<(), Self::Error> { + _variant: &'static str) -> Result<(), Self::Error> { self.visit_unit() } From 7585ce9ed4aeec816fbf05b207362a6c3a9e122c Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Wed, 29 Jul 2015 12:08:15 -0700 Subject: [PATCH 03/13] Re-indent --- serde/src/ser/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index ac20dad6..85d7b336 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -160,8 +160,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) @@ -201,8 +201,8 @@ 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) From 351b7039a8a5b699abd13d658ed0cb99f9125d0b Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Wed, 29 Jul 2015 12:24:16 -0700 Subject: [PATCH 04/13] Rename de::VariantVisitor::visit_{map,seq} to visit_{struct,tuple} --- serde/src/de/impls.rs | 4 ++-- serde/src/de/mod.rs | 24 ++++++++++++++---------- serde_codegen/src/de.rs | 4 ++-- serde_json/src/de.rs | 12 ++++++------ serde_json/src/value.rs | 12 ++++++------ serde_tests/tests/test_de.rs | 12 ++++++------ 6 files changed, 36 insertions(+), 32 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index 0b43eed3..aaaaed96 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -916,11 +916,11 @@ impl Deserialize for Result where T: Deserialize, E: Deserialize { { match try!(visitor.visit_variant()) { Field::Ok => { - let (value,) = try!(visitor.visit_seq(1, TupleVisitor1::new())); + let (value,) = try!(visitor.visit_tuple(1, TupleVisitor1::new())); Ok(Ok(value)) } Field::Err => { - let (value,) = try!(visitor.visit_seq(1, TupleVisitor1::new())); + let (value,) = try!(visitor.visit_tuple(1, TupleVisitor1::new())); Ok(Err(value)) } } diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 611c8c8e..54ca9e67 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -584,17 +584,19 @@ pub trait VariantVisitor { Err(Error::syntax_error()) } - /// `visit_seq` is called when deserializing a tuple-like variant. - fn visit_seq(&mut self, _len: usize, _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()) @@ -618,18 +620,20 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor { (**self).visit_simple() } - fn visit_seq(&mut self, len: usize, visitor: V) -> Result + fn visit_tuple(&mut self, + len: usize, + visitor: V) -> Result where V: Visitor, { - (**self).visit_seq(len, 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_codegen/src/de.rs b/serde_codegen/src/de.rs index ab8adced..d1e114de 100644 --- a/serde_codegen/src/de.rs +++ b/serde_codegen/src/de.rs @@ -641,7 +641,7 @@ fn deserialize_tuple_variant( } } - visitor.visit_seq($fields, $visitor_expr) + visitor.visit_tuple($fields, $visitor_expr) }) } @@ -708,7 +708,7 @@ fn deserialize_struct_variant( $fields_stmt - visitor.visit_map(FIELDS, $visitor_expr) + visitor.visit_struct(FIELDS, $visitor_expr) }) } diff --git a/serde_json/src/de.rs b/serde_json/src/de.rs index dc0ce34d..5fbbfb1c 100644 --- a/serde_json/src/de.rs +++ b/serde_json/src/de.rs @@ -648,17 +648,17 @@ impl de::VariantVisitor for Deserializer de::Deserialize::deserialize(self) } - fn visit_seq(&mut self, - _len: usize, - 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/value.rs b/serde_json/src/value.rs index 061c80ab..42356be2 100644 --- a/serde_json/src/value.rs +++ b/serde_json/src/value.rs @@ -753,9 +753,9 @@ impl<'a> de::VariantVisitor for VariantDeserializer<'a> { de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap())) } - fn visit_seq(&mut self, - _len: usize, - 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() { @@ -772,9 +772,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/tests/test_de.rs b/serde_tests/tests/test_de.rs index 67ad4c74..0e3834a6 100644 --- a/serde_tests/tests/test_de.rs +++ b/serde_tests/tests/test_de.rs @@ -327,17 +327,17 @@ impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> { de::Deserialize::deserialize(self.de) } - fn visit_seq(&mut self, - _len: usize, - visitor: V) -> Result + fn visit_tuple(&mut self, + _len: usize, + visitor: V) -> Result where V: de::Visitor, { de::Deserializer::visit(self.de, 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.de, visitor) From d2fef277218addfb131e7aa6ba3135505bfd20e8 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Wed, 29 Jul 2015 12:25:16 -0700 Subject: [PATCH 05/13] Rename ser::Serializer::visit_enum_{unit,seq,map} to visit_{unit,tuple,struct}_variant --- serde/src/ser/impls.rs | 4 ++-- serde/src/ser/mod.rs | 38 +++++++++++++++++++---------------- serde_codegen/src/ser.rs | 6 +++--- serde_json/src/ser.rs | 28 +++++++++++++------------- serde_json/src/value.rs | 28 +++++++++++++------------- serde_tests/tests/test_ser.rs | 28 +++++++++++++------------- 6 files changed, 68 insertions(+), 64 deletions(-) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index a8efe18a..33d86aa4 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -631,7 +631,7 @@ impl Serialize for Result where T: Serialize, E: Serialize { } } - serializer.visit_enum_seq("Result", 0, "Ok", Visitor(Some(value))) + serializer.visit_tuple_variant("Result", 0, "Ok", Visitor(Some(value))) } Result::Err(ref value) => { struct Visitor<'a, E: 'a>(Option<&'a E>); @@ -652,7 +652,7 @@ impl Serialize for Result where T: Serialize, E: Serialize { } } - serializer.visit_enum_seq("Result", 1, "Err", Visitor(Some(value))) + serializer.visit_tuple_variant("Result", 1, "Err", Visitor(Some(value))) } } } diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 85d7b336..11935cb6 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -118,10 +118,10 @@ pub trait Serializer { } #[inline] - fn visit_enum_unit(&mut self, - _name: &'static str, - _variant_index: usize, - _variant: &'static 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() } @@ -175,18 +175,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) @@ -209,7 +209,9 @@ pub trait Serializer { } #[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 +219,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/ser.rs b/serde_codegen/src/ser.rs index b4e4f7f4..e20a3a53 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, @@ -421,7 +421,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 +476,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/ser.rs b/serde_json/src/ser.rs index b7f5b2d8..5b546e3e 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)); @@ -209,11 +209,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 +257,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 42356be2..6d0c6a8a 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![])); @@ -509,11 +509,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 +572,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)); diff --git a/serde_tests/tests/test_ser.rs b/serde_tests/tests/test_ser.rs index 62627fba..01fe11f3 100644 --- a/serde_tests/tests/test_ser.rs +++ b/serde_tests/tests/test_ser.rs @@ -98,10 +98,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 +221,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 +268,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(); From 49fa20824225ad5ef03c6bbeb3883cc93b7fa867 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Wed, 29 Jul 2015 13:46:45 -0700 Subject: [PATCH 06/13] Minor cleanup --- serde/src/de/mod.rs | 8 ++++++-- serde/src/ser/impls.rs | 4 ++-- serde/src/ser/mod.rs | 3 +-- serde_codegen/src/de.rs | 8 ++++---- serde_json/src/value.rs | 6 +++--- serde_tests/tests/test_bytes.rs | 3 +-- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/serde/src/de/mod.rs b/serde/src/de/mod.rs index 54ca9e67..0f865920 100644 --- a/serde/src/de/mod.rs +++ b/serde/src/de/mod.rs @@ -580,7 +580,9 @@ 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()) } @@ -616,7 +618,9 @@ 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() } diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 33d86aa4..311e77f9 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -126,8 +126,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), } diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 11935cb6..971cc50a 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -129,8 +129,7 @@ pub trait Serializer { fn visit_enum_simple(&mut self, _name: &str, _variant: &str, - _value: T, - ) -> Result<(), Self::Error> + _value: T) -> Result<(), Self::Error> where T: Serialize; fn visit_none(&mut self) -> Result<(), Self::Error>; diff --git a/serde_codegen/src/de.rs b/serde_codegen/src/de.rs index d1e114de..a34d44d6 100644 --- a/serde_codegen/src/de.rs +++ b/serde_codegen/src/de.rs @@ -765,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_json/src/value.rs b/serde_json/src/value.rs index 6d0c6a8a..794d8b21 100644 --- a/serde_json/src/value.rs +++ b/serde_json/src/value.rs @@ -743,12 +743,12 @@ 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 + fn visit_simple(&mut self) -> Result + where T: de::Deserialize, { de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap())) } diff --git a/serde_tests/tests/test_bytes.rs b/serde_tests/tests/test_bytes.rs index 65c466a3..c7499ffe 100644 --- a/serde_tests/tests/test_bytes.rs +++ b/serde_tests/tests/test_bytes.rs @@ -42,8 +42,7 @@ impl serde::Serializer for BytesSerializer { fn visit_enum_simple(&mut self, _name: &str, _variant: &str, - _value: T, - ) -> Result<(), Error> + _value: T) -> Result<(), Error> { Err(Error) } From 2cb7d66767dcc89c6fe60328034c9cd3a021cb52 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 30 Jul 2015 07:54:55 -0700 Subject: [PATCH 07/13] Add test for deserializing a simple enum --- serde_tests/tests/test_de.rs | 61 ++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 3 deletions(-) diff --git a/serde_tests/tests/test_de.rs b/serde_tests/tests/test_de.rs index 0e3834a6..78c3f16f 100644 --- a/serde_tests/tests/test_de.rs +++ b/serde_tests/tests/test_de.rs @@ -38,6 +38,10 @@ enum Token { MapEnd, EnumStart(&'static str), + EnumUnit, + EnumSimple, + EnumSeq, + EnumMap, EnumEnd, } @@ -324,7 +328,25 @@ 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_simple(&mut self) -> Result + where T: de::Deserialize, + { + match self.de.tokens.next() { + Some(Token::EnumSimple) => { + de::Deserialize::deserialize(self.de) + } + Some(_) => Err(Error::SyntaxError), + None => Err(Error::EndOfStreamError), + } } fn visit_tuple(&mut self, @@ -332,7 +354,13 @@ impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> { 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, @@ -340,7 +368,13 @@ impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> { visitor: V) -> Result where V: de::Visitor, { - de::Deserializer::visit(self.de, visitor) + match self.de.tokens.next() { + Some(Token::EnumMap) => { + de::Deserializer::visit(self.de, visitor) + } + Some(_) => Err(Error::SyntaxError), + None => Err(Error::EndOfStreamError), + } } } @@ -362,6 +396,7 @@ struct Struct { #[derive(PartialEq, Debug, Deserialize)] enum Enum { Unit, + Simple(i32), Seq(i32, i32, i32), Map { a: i32, b: i32, c: i32 } } @@ -503,6 +538,8 @@ declare_tests! { Ok::(0) => vec![ Token::EnumStart("Result"), Token::Str("Ok"), + + Token::EnumSeq, Token::SeqStart(1), Token::SeqSep, Token::I32(0), @@ -512,6 +549,8 @@ declare_tests! { Err::(1) => vec![ Token::EnumStart("Result"), Token::Str("Err"), + + Token::EnumSeq, Token::SeqStart(1), Token::SeqSep, Token::I32(1), @@ -888,14 +927,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), @@ -913,6 +966,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"), From 71cc95248c4b5aa902be3e8e71b6b087d18e559a Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 30 Jul 2015 07:57:46 -0700 Subject: [PATCH 08/13] Allow Option to be used directly as a ser::SeqVisitor --- serde/src/ser/impls.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 311e77f9..559f67a0 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 { From 5dc245d2cefa9b78edde11d8349a85c95b93cb97 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 30 Jul 2015 07:58:02 -0700 Subject: [PATCH 09/13] Switch serializing Result to using simple enums --- serde/src/de/impls.rs | 4 ++-- serde/src/ser/impls.rs | 41 ++--------------------------------- serde_tests/tests/test_de.rs | 18 +++++---------- serde_tests/tests/test_ser.rs | 8 ++----- 4 files changed, 12 insertions(+), 59 deletions(-) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index aaaaed96..d2d4c337 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -916,11 +916,11 @@ impl Deserialize for Result where T: Deserialize, E: Deserialize { { match try!(visitor.visit_variant()) { Field::Ok => { - let (value,) = try!(visitor.visit_tuple(1, TupleVisitor1::new())); + let value = try!(visitor.visit_simple()); Ok(Ok(value)) } Field::Err => { - let (value,) = try!(visitor.visit_tuple(1, TupleVisitor1::new())); + let value = try!(visitor.visit_simple()); Ok(Err(value)) } } diff --git a/serde/src/ser/impls.rs b/serde/src/ser/impls.rs index 559f67a0..ec7c3884 100644 --- a/serde/src/ser/impls.rs +++ b/serde/src/ser/impls.rs @@ -632,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_tuple_variant("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_tuple_variant("Result", 1, "Err", Visitor(Some(value))) + serializer.visit_enum_simple("Result", 1, "Err", value) } } } diff --git a/serde_tests/tests/test_de.rs b/serde_tests/tests/test_de.rs index 78c3f16f..f226ef7e 100644 --- a/serde_tests/tests/test_de.rs +++ b/serde_tests/tests/test_de.rs @@ -539,23 +539,17 @@ declare_tests! { Token::EnumStart("Result"), Token::Str("Ok"), - Token::EnumSeq, - 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::EnumSeq, - Token::SeqStart(1), - Token::SeqSep, - Token::I32(1), - Token::SeqEnd, - Token::EnumEnd, + Token::EnumSimple, + Token::I32(1), + Token::SeqEnd, ], } test_unit { diff --git a/serde_tests/tests/test_ser.rs b/serde_tests/tests/test_ser.rs index 01fe11f3..c667cf35 100644 --- a/serde_tests/tests/test_ser.rs +++ b/serde_tests/tests/test_ser.rs @@ -396,16 +396,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 { From 0348a3914da9d4209af8f14d90e1c6894f9e541f Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Wed, 29 Jul 2015 14:05:51 -0700 Subject: [PATCH 10/13] Pass variant index to visit_enum_simple --- serde/src/ser/mod.rs | 7 ++++--- serde_codegen/src/ser.rs | 1 + serde_json/src/ser.rs | 1 + serde_json/src/value.rs | 1 + serde_tests/tests/test_bytes.rs | 1 + serde_tests/tests/test_ser.rs | 1 + 6 files changed, 9 insertions(+), 3 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index 971cc50a..e0cc35a5 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -127,9 +127,10 @@ pub trait Serializer { #[inline] fn visit_enum_simple(&mut self, - _name: &str, - _variant: &str, - _value: T) -> Result<(), Self::Error> + name: &'static str, + variant_index: usize, + variant: &'static str, + value: T) -> Result<(), Self::Error> where T: Serialize; fn visit_none(&mut self) -> Result<(), Self::Error>; diff --git a/serde_codegen/src/ser.rs b/serde_codegen/src/ser.rs index e20a3a53..7d80f9dd 100644 --- a/serde_codegen/src/ser.rs +++ b/serde_codegen/src/ser.rs @@ -309,6 +309,7 @@ fn serialize_variant( ::serde::ser::Serializer::visit_enum_simple( serializer, $type_name, + $variant_index, $variant_name, __simple_value, ) diff --git a/serde_json/src/ser.rs b/serde_json/src/ser.rs index 5b546e3e..c1368833 100644 --- a/serde_json/src/ser.rs +++ b/serde_json/src/ser.rs @@ -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<()> diff --git a/serde_json/src/value.rs b/serde_json/src/value.rs index 794d8b21..ea40cb83 100644 --- a/serde_json/src/value.rs +++ b/serde_json/src/value.rs @@ -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<(), ()> diff --git a/serde_tests/tests/test_bytes.rs b/serde_tests/tests/test_bytes.rs index c7499ffe..b6b31a6d 100644 --- a/serde_tests/tests/test_bytes.rs +++ b/serde_tests/tests/test_bytes.rs @@ -41,6 +41,7 @@ impl serde::Serializer for BytesSerializer { fn visit_enum_simple(&mut self, _name: &str, + _variant_index: usize, _variant: &str, _value: T) -> Result<(), Error> { diff --git a/serde_tests/tests/test_ser.rs b/serde_tests/tests/test_ser.rs index c667cf35..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<(), ()> From 97f08086dd325e2292b7eba0dee23f8df3970cba Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Wed, 29 Jul 2015 14:06:17 -0700 Subject: [PATCH 11/13] Have visit_enum_simple default to calling visit_tuple_variant --- serde/src/ser/mod.rs | 9 ++++++++- serde_tests/tests/test_bytes.rs | 9 --------- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/serde/src/ser/mod.rs b/serde/src/ser/mod.rs index e0cc35a5..816e932a 100644 --- a/serde/src/ser/mod.rs +++ b/serde/src/ser/mod.rs @@ -131,7 +131,14 @@ pub trait Serializer { variant_index: usize, variant: &'static str, value: T) -> Result<(), Self::Error> - where T: Serialize; + where T: Serialize, + { + self.visit_tuple_variant( + name, + variant_index, + variant, + Some(value)) + } fn visit_none(&mut self) -> Result<(), Self::Error>; diff --git a/serde_tests/tests/test_bytes.rs b/serde_tests/tests/test_bytes.rs index b6b31a6d..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_index: usize, - _variant: &str, - _value: T) -> Result<(), Error> - { - Err(Error) - } - fn visit_bool(&mut self, _v: bool) -> Result<(), Error> { Err(Error) } From de1059f648c74fd508272a9cf96ffafc247394c1 Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 30 Jul 2015 07:35:57 -0700 Subject: [PATCH 12/13] Allow Result to use usize variant names --- serde/src/de/impls.rs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/serde/src/de/impls.rs b/serde/src/de/impls.rs index d2d4c337..0d1d8a4f 100644 --- a/serde/src/de/impls.rs +++ b/serde/src/de/impls.rs @@ -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), From 5a5639481481a9ea65138d9bdbb0c1b59454a3ef Mon Sep 17 00:00:00 2001 From: Erick Tryzelaar Date: Thu, 30 Jul 2015 08:05:41 -0700 Subject: [PATCH 13/13] Add test to deserialize variants from usize and &[u8] --- serde_tests/tests/test_de.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/serde_tests/tests/test_de.rs b/serde_tests/tests/test_de.rs index f226ef7e..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), @@ -103,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(), @@ -978,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, + ], + } }