Skip to content

Commit

Permalink
Change de::VariantVisitor to let deserializers know the variant kind
Browse files Browse the repository at this point in the history
This allows formats like cbor that encode a unit variant as just a
string to work.

[breaking-change]
  • Loading branch information
erickt committed Apr 12, 2015
1 parent d36879f commit 1da47c0
Show file tree
Hide file tree
Showing 7 changed files with 94 additions and 24 deletions.
8 changes: 3 additions & 5 deletions benches/bench_enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
}

Expand All @@ -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)
Expand Down
6 changes: 3 additions & 3 deletions serde_macros/src/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})
}
Expand Down Expand Up @@ -482,7 +482,7 @@ fn deserialize_tuple_variant(
}
}

visitor.visit_value($visitor_expr)
visitor.visit_seq($visitor_expr)
})
}

Expand Down Expand Up @@ -524,7 +524,7 @@ fn deserialize_struct_variant(
}
}

visitor.visit_value($visitor_expr)
visitor.visit_map($visitor_expr)
})
}

Expand Down
39 changes: 35 additions & 4 deletions src/de/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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 {
Expand All @@ -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_seq(visitor)
}

fn visit_map<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{
(**self).visit_value(visitor)
(**self).visit_map(visitor)
}
}

Expand Down
12 changes: 4 additions & 8 deletions src/de/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(())
}
}

Expand Down Expand Up @@ -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(())
}
}

Expand Down
16 changes: 15 additions & 1 deletion src/json/de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
25 changes: 23 additions & 2 deletions src/json/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
12 changes: 11 additions & 1 deletion tests/test_de.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down

0 comments on commit 1da47c0

Please sign in to comment.