diff --git a/benches/bench_enum.rs b/benches/bench_enum.rs index 0d3b14c2..43d8d9d5 100644 --- a/benches/bench_enum.rs +++ b/benches/bench_enum.rs @@ -339,10 +339,8 @@ mod deserializer { de::Deserialize::deserialize(self.de) } - fn visit_value(&mut self, visitor: V) -> Result - where V: de::Visitor, - { - de::Deserializer::visit(self.de, visitor) + fn visit_unit(&mut self) -> Result<(), Error> { + de::Deserialize::deserialize(self.de) } } @@ -360,7 +358,7 @@ mod deserializer { de::Deserialize::deserialize(self.de) } - fn visit_value(&mut self, mut visitor: V) -> Result + fn visit_seq(&mut self, mut visitor: V) -> Result where V: de::Visitor, { visitor.visit_seq(self) diff --git a/serde_macros/src/de.rs b/serde_macros/src/de.rs index 1a95722c..fc7d324a 100644 --- a/serde_macros/src/de.rs +++ b/serde_macros/src/de.rs @@ -417,7 +417,7 @@ fn deserialize_variant( match variant.node.kind { ast::TupleVariantKind(ref args) if args.is_empty() => { quote_expr!(cx, { - try!(visitor.visit_value(::serde::de::impls::UnitVisitor)); + try!(visitor.visit_unit()); Ok($type_ident::$variant_ident) }) } @@ -482,7 +482,7 @@ fn deserialize_tuple_variant( } } - visitor.visit_value($visitor_expr) + visitor.visit_seq($visitor_expr) }) } @@ -524,7 +524,7 @@ fn deserialize_struct_variant( } } - visitor.visit_value($visitor_expr) + visitor.visit_map($visitor_expr) }) } diff --git a/src/de/mod.rs b/src/de/mod.rs index d8417292..0b316fb1 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -385,6 +385,8 @@ impl<'a, V_> MapVisitor for &'a mut V_ where V_: MapVisitor { /////////////////////////////////////////////////////////////////////////////// +/// `EnumVisitor` is a visitor that is created by the `Deserialize` and passed to the +/// `Deserializer` in order to deserialize enums. pub trait EnumVisitor { type Value; @@ -394,14 +396,33 @@ pub trait EnumVisitor { /////////////////////////////////////////////////////////////////////////////// +/// `VariantVisitor` is a visitor that is created by the `Deserializer` and passed to the +/// `Deserialize` in order to deserialize a specific enum variant. pub trait VariantVisitor { type Error: Error; + /// `visit_variant` is called to identify which variant to deserialize. fn visit_variant(&mut self) -> Result where V: Deserialize; - fn visit_value(&mut self, _visitor: V) -> Result - where V: Visitor; + /// `visit_unit` is called when deserializing a variant with no values. + fn visit_unit(&mut self) -> Result<(), Self::Error> { + Err(Error::syntax_error()) + } + + /// `visit_seq` is called when deserializing a tuple-like variant. + fn visit_seq(&mut self, _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, _visitor: V) -> Result + where V: Visitor + { + Err(Error::syntax_error()) + } } impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor { @@ -413,10 +434,20 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor { (**self).visit_variant() } - fn visit_value(&mut self, visitor: V) -> Result + fn visit_unit(&mut self) -> Result<(), T::Error> { + (**self).visit_unit() + } + + fn visit_seq(&mut self, visitor: V) -> Result where V: Visitor, { - (**self).visit_value(visitor) + (**self).visit_seq(visitor) + } + + fn visit_map(&mut self, visitor: V) -> Result + where V: Visitor, + { + (**self).visit_map(visitor) } } diff --git a/src/de/value.rs b/src/de/value.rs index 4059453a..de26d8cb 100644 --- a/src/de/value.rs +++ b/src/de/value.rs @@ -149,10 +149,8 @@ impl<'a> de::VariantVisitor for StrDeserializer<'a> { de::Deserialize::deserialize(self) } - fn visit_value(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - visitor.visit_unit() + fn visit_unit(&mut self) -> Result<(), Error> { + Ok(()) } } @@ -197,10 +195,8 @@ impl<'a> de::VariantVisitor for StringDeserializer { de::Deserialize::deserialize(self) } - fn visit_value(&mut self, mut visitor: V) -> Result - where V: de::Visitor, - { - visitor.visit_unit() + fn visit_unit(&mut self) -> Result<(), Error> { + Ok(()) } } diff --git a/src/json/de.rs b/src/json/de.rs index 7d95fd63..c966e668 100644 --- a/src/json/de.rs +++ b/src/json/de.rs @@ -618,7 +618,21 @@ impl de::VariantVisitor for Deserializer de::Deserialize::deserialize(self) } - fn visit_value(&mut self, visitor: V) -> Result + fn visit_unit(&mut self) -> Result<(), Error> { + try!(self.parse_object_colon()); + + de::Deserialize::deserialize(self) + } + + fn visit_seq(&mut self, visitor: V) -> Result + where V: de::Visitor, + { + try!(self.parse_object_colon()); + + de::Deserializer::visit(self, visitor) + } + + fn visit_map(&mut self, visitor: V) -> Result where V: de::Visitor, { try!(self.parse_object_colon()); diff --git a/src/json/value.rs b/src/json/value.rs index 2a150ecf..5857f9c4 100644 --- a/src/json/value.rs +++ b/src/json/value.rs @@ -737,7 +737,18 @@ impl<'a> de::VariantVisitor for SeqDeserializer<'a> { de::Deserialize::deserialize(self.de) } - fn visit_value(&mut self, visitor: V) -> Result + fn visit_unit(&mut self) -> Result<(), Error> + { + de::Deserialize::deserialize(self) + } + + fn visit_seq(&mut self, visitor: V) -> Result + where V: de::Visitor, + { + de::Deserializer::visit(self, visitor) + } + + fn visit_map(&mut self, visitor: V) -> Result where V: de::Visitor, { de::Deserializer::visit(self, visitor) @@ -836,7 +847,17 @@ impl<'a> de::VariantVisitor for MapDeserializer<'a> { de::Deserialize::deserialize(self.de) } - fn visit_value(&mut self, visitor: V) -> Result + fn visit_unit(&mut self) -> Result<(), Error> { + de::Deserialize::deserialize(self) + } + + fn visit_seq(&mut self, visitor: V) -> Result + where V: de::Visitor, + { + de::Deserializer::visit(self, visitor) + } + + fn visit_map(&mut self, visitor: V) -> Result where V: de::Visitor, { de::Deserializer::visit(self, visitor) diff --git a/tests/test_de.rs b/tests/test_de.rs index 7162acec..2f446b13 100644 --- a/tests/test_de.rs +++ b/tests/test_de.rs @@ -315,7 +315,17 @@ impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> { de::Deserialize::deserialize(self.de) } - fn visit_value(&mut self, visitor: V) -> Result + fn visit_unit(&mut self) -> Result<(), Error> { + de::Deserialize::deserialize(self.de) + } + + fn visit_seq(&mut self, visitor: V) -> Result + where V: de::Visitor, + { + de::Deserializer::visit(self.de, visitor) + } + + fn visit_map(&mut self, visitor: V) -> Result where V: de::Visitor, { de::Deserializer::visit(self.de, visitor)