Merge pull request #120 from erickt/enum-fields

Add enum fields and tuple length to deserialization visitor methods, renamed some more methods
This commit is contained in:
Erick Tryzelaar 2015-07-30 09:51:01 -07:00
commit 7e25ed863c
14 changed files with 338 additions and 210 deletions

View File

@ -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<D>(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<T, E> Deserialize for Result<T, E> where T: Deserialize, E: Deserialize {
impl ::de::Visitor for FieldVisitor {
type Value = Field;
fn visit_usize<E>(&mut self, value: usize) -> Result<Field, E> where E: Error {
match value {
0 => Ok(Field::Ok),
1 => Ok(Field::Err),
_ => Err(Error::unknown_field_error(&value.to_string())),
}
}
fn visit_str<E>(&mut self, value: &str) -> Result<Field, E> where E: Error {
match value {
"Ok" => Ok(Field::Ok),
@ -916,17 +924,19 @@ impl<T, E> Deserialize for Result<T, E> 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))
}
}

View File

@ -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<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
fn visit_unit_struct<V>(&mut self,
_name: &'static str,
visitor: V) -> Result<V::Value, Self::Error>
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<V>(&mut self, _name: &str, visitor: V) -> Result<V::Value, Self::Error>
fn visit_tuple_struct<V>(&mut self,
_name: &'static str,
len: usize,
visitor: V) -> Result<V::Value, Self::Error>
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<V>(&mut self,
_name: &str,
_name: &'static str,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Self::Error>
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<V>(&mut self, visitor: V) -> Result<V::Value, Self::Error>
fn visit_tuple<V>(&mut self, _len: usize, visitor: V) -> Result<V::Value, Self::Error>
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<V>(&mut self, _enum: &str, _visitor: V) -> Result<V::Value, Self::Error>
fn visit_enum<V>(&mut self,
_enum: &'static str,
_variants: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error>
where V: EnumVisitor,
{
Err(Error::syntax_error())
@ -389,7 +397,7 @@ pub trait Visitor {
}
#[inline]
fn visit_unit_struct<E>(&mut self, _name: &str) -> Result<Self::Value, E>
fn visit_unit_struct<E>(&mut self, _name: &'static str) -> Result<Self::Value, E>
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<T: Deserialize>(&mut self) -> Result<T, Self::Error> {
fn visit_simple<T>(&mut self) -> Result<T, Self::Error>
where T: Deserialize,
{
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>
/// `visit_tuple` is called when deserializing a tuple-like variant.
fn visit_tuple<V>(&mut self,
_len: usize,
_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,
_fields: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error>
/// `visit_struct` is called when deserializing a struct-like variant.
fn visit_struct<V>(&mut self,
_fields: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error>
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<D: Deserialize>(&mut self) -> Result<D, T::Error> {
fn visit_simple<D>(&mut self) -> Result<D, T::Error>
where D: Deserialize,
{
(**self).visit_simple()
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, T::Error>
fn visit_tuple<V>(&mut self,
len: usize,
visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{
(**self).visit_seq(visitor)
(**self).visit_tuple(len, visitor)
}
fn visit_map<V>(&mut self,
fn visit_struct<V>(&mut self,
fields: &'static [&'static str],
visitor: V) -> Result<V::Value, T::Error>
where V: Visitor,
{
(**self).visit_map(fields, visitor)
(**self).visit_struct(fields, visitor)
}
}

View File

@ -136,7 +136,10 @@ impl<'a> de::Deserializer for StrDeserializer<'a> {
}
}
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
_name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
visitor.visit(self)
@ -182,7 +185,10 @@ impl de::Deserializer for StringDeserializer {
}
}
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
_name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
visitor.visit(self)

View File

@ -97,6 +97,26 @@ impl<T> Serialize for Option<T> where T: Serialize {
}
}
impl<T> SeqVisitor for Option<T> where T: Serialize {
#[inline]
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, 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<usize> {
Some(if self.is_some() { 1 } else { 0 })
}
}
///////////////////////////////////////////////////////////////////////////////
pub struct SeqIteratorVisitor<Iter> {
@ -126,8 +146,8 @@ impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
{
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<T, E> Serialize for Result<T, E> where T: Serialize, E: Serialize {
fn serialize<S>(&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<S>(&mut self, serializer: &mut S) -> Result<Option<()>, 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<usize> {
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<S>(&mut self, serializer: &mut S) -> Result<Option<()>, 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<usize> {
Some(1)
}
}
serializer.visit_enum_seq("Result", 1, "Err", Visitor(Some(value)))
serializer.visit_enum_simple("Result", 1, "Err", value)
}
}
}

View File

@ -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<T>(&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<V>(&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<V>(&mut self,
_name: &'static str,
_variant_index: usize,
variant: &'static str,
visitor: V) -> Result<(), Self::Error>
fn visit_tuple_variant<V>(&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<T>(&mut self, value: T) -> Result<(), Self::Error>
fn visit_tuple_variant_elt<T>(&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<V>(&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<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
fn visit_struct_elt<K, V>(&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<V>(&mut self,
_name: &'static str,
_variant_index: usize,
variant: &'static str,
visitor: V) -> Result<(), Self::Error>
fn visit_struct_variant<V>(&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<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
fn visit_struct_variant_elt<K, V>(&mut self,
key: K,
value: V) -> Result<(), Self::Error>
where K: Serialize,
V: Serialize,
{

View File

@ -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| {

View File

@ -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>,

View File

@ -454,7 +454,10 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
}
#[inline]
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
_name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
try!(self.parse_whitespace());
@ -645,15 +648,17 @@ impl<Iter> de::VariantVisitor for Deserializer<Iter>
de::Deserialize::deserialize(self)
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit_tuple<V>(&mut self,
_len: usize,
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)
}
fn visit_map<V>(&mut self,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Error>
fn visit_struct<V>(&mut self,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
de::Deserializer::visit(self, visitor)

View File

@ -159,10 +159,10 @@ impl<W, F> ser::Serializer for Serializer<W, F>
}
#[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<W, F> ser::Serializer for Serializer<W, F>
#[inline]
fn visit_enum_simple<T>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
value: T,
) -> io::Result<()>
@ -209,11 +210,11 @@ impl<W, F> ser::Serializer for Serializer<W, F>
}
#[inline]
fn visit_enum_seq<V>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> io::Result<()>
fn visit_tuple_variant<V>(&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<W, F> ser::Serializer for Serializer<W, F>
}
#[inline]
fn visit_enum_map<V>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> io::Result<()>
fn visit_struct_variant<V>(&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'{'));

View File

@ -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<T>(&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<V>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> Result<(), ()>
fn visit_tuple_variant<V>(&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<V>(&mut self,
_name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> Result<(), ()>
fn visit_struct_variant<V>(&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<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
_name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
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<T>(&mut self) -> Result<T, Error>
where T: de::Deserialize,
{
de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap()))
}
fn visit_simple<D: de::Deserialize>(&mut self) -> Result<D, Error>
{
de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap()))
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
fn visit_tuple<V>(&mut self,
_len: usize,
visitor: V) -> Result<V::Value, Error>
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<V>(&mut self, _fields: &'static[&'static str], visitor: V) -> Result<V::Value, Error>
fn visit_struct<V>(&mut self,
_fields: &'static[&'static str],
visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
if let Value::Object(fields) = self.val.take().unwrap() {

View File

@ -288,7 +288,10 @@ mod deserializer {
}
#[inline]
fn visit_enum<V>(&mut self, _name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
_name: &str,
_variants: &[&str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
match self.stack.pop() {
@ -350,7 +353,9 @@ mod deserializer {
de::Deserialize::deserialize(self.de)
}
fn visit_seq<V>(&mut self, mut visitor: V) -> Result<V::Value, Error>
fn visit_tuple<V>(&mut self,
_len: usize,
mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
visitor.visit_seq(self)

View File

@ -39,15 +39,6 @@ impl serde::Serializer for BytesSerializer {
Err(Error)
}
fn visit_enum_simple<T>(&mut self,
_name: &str,
_variant: &str,
_value: T,
) -> Result<(), Error>
{
Err(Error)
}
fn visit_bool(&mut self, _v: bool) -> Result<(), Error> {
Err(Error)
}

View File

@ -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<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value, Error>
fn visit_enum<V>(&mut self,
name: &str,
_variants: &'static [&'static str],
mut visitor: V) -> Result<V::Value, Error>
where V: de::EnumVisitor,
{
match self.tokens.next() {
@ -178,7 +187,10 @@ impl Deserializer for TokenDeserializer {
}
}
fn visit_tuple_struct<V>(&mut self, name: &str, visitor: V) -> Result<V::Value, Error>
fn visit_tuple_struct<V>(&mut self,
name: &str,
_len: usize,
visitor: V) -> Result<V::Value, Error>
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<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
fn visit_simple<T>(&mut self) -> Result<T, Self::Error>
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<V>(&mut self,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Error>
fn visit_tuple<V>(&mut self,
_len: usize,
visitor: V) -> Result<V::Value, Error>
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<V>(&mut self,
_fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Error>
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::<i32, i32>(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::<i32, i32>(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,
],
}
}

View File

@ -84,6 +84,7 @@ impl<'a> Serializer for AssertSerializer<'a> {
fn visit_enum_simple<T>(&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<V>(&mut self,
name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> Result<(), ()>
fn visit_tuple_variant<V>(&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<V>(&mut self,
name: &str,
_variant_index: usize,
variant: &str,
visitor: V) -> Result<(), ()>
fn visit_struct_variant<V>(&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::<i32, i32>(0) => vec![
Token::EnumSeqStart("Result", "Ok", Some(1)),
Token::SeqSep,
Token::EnumSimple("Result", "Ok"),
Token::I32(0),
Token::SeqEnd,
],
Err::<i32, i32>(1) => vec![
Token::EnumSeqStart("Result", "Err", Some(1)),
Token::SeqSep,
Token::EnumSimple("Result", "Err"),
Token::I32(1),
Token::SeqEnd,
],
}
test_slice {