Change de::VariantVisitor to let deserializers know the variant kind

This allows formats like cbor that encode a unit variant as just a
string to work.

[breaking-change]
This commit is contained in:
Erick Tryzelaar
2015-04-06 20:04:01 -07:00
parent d36879f5ee
commit 1da47c0870
7 changed files with 94 additions and 24 deletions
+3 -5
View File
@@ -339,10 +339,8 @@ mod deserializer {
de::Deserialize::deserialize(self.de)
}
fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
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<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_seq(self)
+3 -3
View File
@@ -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)
})
}
+35 -4
View File
@@ -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<V>(&mut self) -> Result<V, Self::Error>
where V: Deserialize;
fn visit_value<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
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<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor
{
Err(Error::syntax_error())
}
/// `visit_map` is called when deserializing a struct-like variant.
fn visit_map<V>(&mut self, _visitor: V) -> Result<V::Value, Self::Error>
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<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
fn visit_unit(&mut self) -> Result<(), T::Error> {
(**self).visit_unit()
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{
(**self).visit_value(visitor)
(**self).visit_seq(visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{
(**self).visit_map(visitor)
}
}
+4 -8
View File
@@ -149,10 +149,8 @@ impl<'a> de::VariantVisitor for StrDeserializer<'a> {
de::Deserialize::deserialize(self)
}
fn visit_value<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
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<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_unit()
fn visit_unit(&mut self) -> Result<(), Error> {
Ok(())
}
}
+15 -1
View File
@@ -618,7 +618,21 @@ impl<Iter> de::VariantVisitor for Deserializer<Iter>
de::Deserialize::deserialize(self)
}
fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit_unit(&mut self) -> Result<(), Error> {
try!(self.parse_object_colon());
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
try!(self.parse_object_colon());
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
try!(self.parse_object_colon());
+23 -2
View File
@@ -737,7 +737,18 @@ impl<'a> de::VariantVisitor for SeqDeserializer<'a> {
de::Deserialize::deserialize(self.de)
}
fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit_unit(&mut self) -> Result<(), Error>
{
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
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<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
+11 -1
View File
@@ -315,7 +315,17 @@ impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> {
de::Deserialize::deserialize(self.de)
}
fn visit_value<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit_unit(&mut self) -> Result<(), Error> {
de::Deserialize::deserialize(self.de)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self.de, visitor)
}
fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self.de, visitor)