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
14 changed files with 338 additions and 210 deletions
+27 -17
View File
@@ -565,7 +565,7 @@ array_impls! {
macro_rules! tuple_impls { macro_rules! tuple_impls {
() => {}; () => {};
($($visitor:ident => ($($name:ident),+),)+) => { ($($len:expr => $visitor:ident => ($($name:ident),+),)+) => {
$( $(
pub struct $visitor<$($name,)+> { pub struct $visitor<$($name,)+> {
marker: PhantomData<($($name,)+)>, marker: PhantomData<($($name,)+)>,
@@ -610,7 +610,7 @@ macro_rules! tuple_impls {
fn deserialize<D>(deserializer: &mut D) -> Result<($($name,)+), D::Error> fn deserialize<D>(deserializer: &mut D) -> Result<($($name,)+), D::Error>
where D: Deserializer, where D: Deserializer,
{ {
deserializer.visit_tuple($visitor::new()) deserializer.visit_tuple($len, $visitor::new())
} }
} }
)+ )+
@@ -618,18 +618,18 @@ macro_rules! tuple_impls {
} }
tuple_impls! { tuple_impls! {
TupleVisitor1 => (T0), 1 => TupleVisitor1 => (T0),
TupleVisitor2 => (T0, T1), 2 => TupleVisitor2 => (T0, T1),
TupleVisitor3 => (T0, T1, T2), 3 => TupleVisitor3 => (T0, T1, T2),
TupleVisitor4 => (T0, T1, T2, T3), 4 => TupleVisitor4 => (T0, T1, T2, T3),
TupleVisitor5 => (T0, T1, T2, T3, T4), 5 => TupleVisitor5 => (T0, T1, T2, T3, T4),
TupleVisitor6 => (T0, T1, T2, T3, T4, T5), 6 => TupleVisitor6 => (T0, T1, T2, T3, T4, T5),
TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6), 7 => TupleVisitor7 => (T0, T1, T2, T3, T4, T5, T6),
TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7), 8 => TupleVisitor8 => (T0, T1, T2, T3, T4, T5, T6, T7),
TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8), 9 => TupleVisitor9 => (T0, T1, T2, T3, T4, T5, T6, T7, T8),
TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9), 10 => TupleVisitor10 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9),
TupleVisitor11 => (T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10), 11 => 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), 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 { impl ::de::Visitor for FieldVisitor {
type Value = Field; 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 { fn visit_str<E>(&mut self, value: &str) -> Result<Field, E> where E: Error {
match value { match value {
"Ok" => Ok(Field::Ok), "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()) { match try!(visitor.visit_variant()) {
Field::Ok => { Field::Ok => {
let (value,) = try!(visitor.visit_seq(TupleVisitor1::new())); let value = try!(visitor.visit_simple());
Ok(Ok(value)) Ok(Ok(value))
} }
Field::Err => { Field::Err => {
let (value,) = try!(visitor.visit_seq(TupleVisitor1::new())); let value = try!(visitor.visit_simple());
Ok(Err(value)) Ok(Err(value))
} }
} }
} }
} }
deserializer.visit_enum("Result", Visitor(PhantomData)) const VARIANTS: &'static [&'static str] = &["Ok", "Err"];
deserializer.visit_enum("Result", VARIANTS, Visitor(PhantomData))
} }
} }
+35 -19
View File
@@ -211,7 +211,9 @@ pub trait Deserializer {
/// This method hints that the `Deserialize` type is expecting a named unit. This allows /// 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. /// deserializers to a named unit that aren't tagged as a named unit.
#[inline] #[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, where V: Visitor,
{ {
self.visit_unit(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 /// This method hints that the `Deserialize` type is expecting a tuple struct. This allows
/// deserializers to parse sequences that aren't tagged as sequences. /// deserializers to parse sequences that aren't tagged as sequences.
#[inline] #[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, 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 /// This method hints that the `Deserialize` type is expecting a struct. This allows
/// deserializers to parse sequences that aren't tagged as maps. /// deserializers to parse sequences that aren't tagged as maps.
#[inline] #[inline]
fn visit_struct<V>(&mut self, fn visit_struct<V>(&mut self,
_name: &str, _name: &'static str,
_fields: &'static [&'static str], _fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Self::Error> visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor, where V: Visitor,
@@ -241,7 +246,7 @@ pub trait Deserializer {
/// This method hints that the `Deserialize` type is expecting a tuple value. This allows /// 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. /// deserializers that provide a custom tuple serialization to properly deserialize the type.
#[inline] #[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, where V: Visitor,
{ {
self.visit_seq(visitor) self.visit_seq(visitor)
@@ -251,7 +256,10 @@ pub trait Deserializer {
/// deserializers that provide a custom enumeration serialization to properly deserialize the /// deserializers that provide a custom enumeration serialization to properly deserialize the
/// type. /// type.
#[inline] #[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, where V: EnumVisitor,
{ {
Err(Error::syntax_error()) Err(Error::syntax_error())
@@ -389,7 +397,7 @@ pub trait Visitor {
} }
#[inline] #[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, where E: Error,
{ {
self.visit_unit() self.visit_unit()
@@ -572,21 +580,25 @@ pub trait VariantVisitor {
} }
/// `visit_simple` is called when deserializing a variant with a single value. /// `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()) Err(Error::syntax_error())
} }
/// `visit_seq` is called when deserializing a tuple-like variant. /// `visit_tuple` is called when deserializing a tuple-like variant.
fn visit_seq<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 where V: Visitor
{ {
Err(Error::syntax_error()) Err(Error::syntax_error())
} }
/// `visit_map` is called when deserializing a struct-like variant. /// `visit_struct` is called when deserializing a struct-like variant.
fn visit_map<V>(&mut self, fn visit_struct<V>(&mut self,
_fields: &'static [&'static str], _fields: &'static [&'static str],
_visitor: V) -> Result<V::Value, Self::Error> _visitor: V) -> Result<V::Value, Self::Error>
where V: Visitor where V: Visitor
{ {
Err(Error::syntax_error()) Err(Error::syntax_error())
@@ -606,22 +618,26 @@ impl<'a, T> VariantVisitor for &'a mut T where T: VariantVisitor {
(**self).visit_unit() (**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() (**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, 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], fields: &'static [&'static str],
visitor: V) -> Result<V::Value, T::Error> visitor: V) -> Result<V::Value, T::Error>
where V: Visitor, where V: Visitor,
{ {
(**self).visit_map(fields, visitor) (**self).visit_struct(fields, visitor)
} }
} }
+8 -2
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, where V: de::EnumVisitor,
{ {
visitor.visit(self) 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, where V: de::EnumVisitor,
{ {
visitor.visit(self) visitor.visit(self)
+24 -41
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> { pub struct SeqIteratorVisitor<Iter> {
@@ -126,8 +146,8 @@ impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
{ {
match self.iter.next() { match self.iter.next() {
Some(value) => { Some(value) => {
let value = try!(serializer.visit_seq_elt(value)); try!(serializer.visit_seq_elt(value));
Ok(Some(value)) Ok(Some(()))
} }
None => Ok(None), 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 { fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error> where S: Serializer {
match *self { match *self {
Result::Ok(ref value) => { Result::Ok(ref value) => {
struct Visitor<'a, T: 'a>(Option<&'a T>); serializer.visit_enum_simple("Result", 0, "Ok", value)
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)))
} }
Result::Err(ref value) => { Result::Err(ref value) => {
struct Visitor<'a, E: 'a>(Option<&'a E>); serializer.visit_enum_simple("Result", 1, "Err", value)
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)))
} }
} }
} }
+38 -27
View File
@@ -113,25 +113,32 @@ pub trait Serializer {
fn visit_unit(&mut self) -> Result<(), Self::Error>; fn visit_unit(&mut self) -> Result<(), Self::Error>;
#[inline] #[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() self.visit_unit()
} }
#[inline] #[inline]
fn visit_enum_unit(&mut self, fn visit_unit_variant(&mut self,
_name: &str, _name: &'static str,
_variant_index: usize, _variant_index: usize,
_variant: &str) -> Result<(), Self::Error> { _variant: &'static str) -> Result<(), Self::Error> {
self.visit_unit() self.visit_unit()
} }
#[inline] #[inline]
fn visit_enum_simple<T>(&mut self, fn visit_enum_simple<T>(&mut self,
_name: &str, name: &'static str,
_variant: &str, variant_index: usize,
_value: T, variant: &'static str,
) -> Result<(), Self::Error> 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>; fn visit_none(&mut self) -> Result<(), Self::Error>;
@@ -160,8 +167,8 @@ pub trait Serializer {
#[inline] #[inline]
fn visit_tuple_struct<V>(&mut self, fn visit_tuple_struct<V>(&mut self,
_name: &'static str, _name: &'static str,
visitor: V) -> Result<(), Self::Error> visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor, where V: SeqVisitor,
{ {
self.visit_tuple(visitor) self.visit_tuple(visitor)
@@ -175,18 +182,18 @@ pub trait Serializer {
} }
#[inline] #[inline]
fn visit_enum_seq<V>(&mut self, fn visit_tuple_variant<V>(&mut self,
_name: &'static str, _name: &'static str,
_variant_index: usize, _variant_index: usize,
variant: &'static str, variant: &'static str,
visitor: V) -> Result<(), Self::Error> visitor: V) -> Result<(), Self::Error>
where V: SeqVisitor, where V: SeqVisitor,
{ {
self.visit_tuple_struct(variant, visitor) self.visit_tuple_struct(variant, visitor)
} }
#[inline] #[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 where T: Serialize
{ {
self.visit_tuple_struct_elt(value) self.visit_tuple_struct_elt(value)
@@ -201,15 +208,17 @@ pub trait Serializer {
#[inline] #[inline]
fn visit_struct<V>(&mut self, fn visit_struct<V>(&mut self,
_name: &'static str, _name: &'static str,
visitor: V) -> Result<(), Self::Error> visitor: V) -> Result<(), Self::Error>
where V: MapVisitor, where V: MapVisitor,
{ {
self.visit_map(visitor) self.visit_map(visitor)
} }
#[inline] #[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, where K: Serialize,
V: Serialize, V: Serialize,
{ {
@@ -217,18 +226,20 @@ pub trait Serializer {
} }
#[inline] #[inline]
fn visit_enum_map<V>(&mut self, fn visit_struct_variant<V>(&mut self,
_name: &'static str, _name: &'static str,
_variant_index: usize, _variant_index: usize,
variant: &'static str, variant: &'static str,
visitor: V) -> Result<(), Self::Error> visitor: V) -> Result<(), Self::Error>
where V: MapVisitor, where V: MapVisitor,
{ {
self.visit_struct(variant, visitor) self.visit_struct(variant, visitor)
} }
#[inline] #[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, where K: Serialize,
V: Serialize, V: Serialize,
{ {
+23 -8
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() .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 // Match arms to extract a variant from a string
let variant_arms: Vec<_> = enum_def.variants.iter() let variant_arms: Vec<_> = enum_def.variants.iter()
.enumerate() .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 $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() { let str_body = if formats.is_empty() {
// No formats specific attributes, so no match on format required // No formats specific attributes, so no match on format required
quote_expr!(cx, quote_expr!(cx,
match value { match value {
$default_field_arms $default_field_arms
_ => { Err(::serde::de::Error::unknown_field_error(value)) } _ => { Err(::serde::de::Error::unknown_field_error(value)) }
}) })
} else { } else {
let field_arms: Vec<_> = formats.iter() let field_arms: Vec<_> = formats.iter()
.map(|fmt| { .map(|fmt| {
+4 -3
View File
@@ -288,7 +288,7 @@ fn serialize_variant(
quote_arm!(cx, quote_arm!(cx,
$pat => { $pat => {
::serde::ser::Serializer::visit_enum_unit( ::serde::ser::Serializer::visit_unit_variant(
serializer, serializer,
$type_name, $type_name,
$variant_index, $variant_index,
@@ -309,6 +309,7 @@ fn serialize_variant(
::serde::ser::Serializer::visit_enum_simple( ::serde::ser::Serializer::visit_enum_simple(
serializer, serializer,
$type_name, $type_name,
$variant_index,
$variant_name, $variant_name,
__simple_value, __simple_value,
) )
@@ -421,7 +422,7 @@ fn serialize_tuple_variant(
quote_expr!(cx, { quote_expr!(cx, {
$visitor_struct $visitor_struct
$visitor_impl $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, value: $value_expr,
state: 0, state: 0,
_structure_ty: ::std::marker::PhantomData::<&$structure_ty>, _structure_ty: ::std::marker::PhantomData::<&$structure_ty>,
@@ -476,7 +477,7 @@ fn serialize_struct_variant(
quote_expr!(cx, { quote_expr!(cx, {
$visitor_struct $visitor_struct
$visitor_impl $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, value: $value_expr,
state: 0, state: 0,
_structure_ty: ::std::marker::PhantomData::<&$structure_ty>, _structure_ty: ::std::marker::PhantomData::<&$structure_ty>,
+10 -5
View File
@@ -454,7 +454,10 @@ impl<Iter> de::Deserializer for Deserializer<Iter>
} }
#[inline] #[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, where V: de::EnumVisitor,
{ {
try!(self.parse_whitespace()); try!(self.parse_whitespace());
@@ -645,15 +648,17 @@ impl<Iter> de::VariantVisitor for Deserializer<Iter>
de::Deserialize::deserialize(self) 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, where V: de::Visitor,
{ {
de::Deserializer::visit(self, visitor) de::Deserializer::visit(self, visitor)
} }
fn visit_map<V>(&mut self, fn visit_struct<V>(&mut self,
_fields: &'static [&'static str], _fields: &'static [&'static str],
visitor: V) -> Result<V::Value, Error> visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
de::Deserializer::visit(self, visitor) de::Deserializer::visit(self, visitor)
+15 -14
View File
@@ -159,10 +159,10 @@ impl<W, F> ser::Serializer for Serializer<W, F>
} }
#[inline] #[inline]
fn visit_enum_unit(&mut self, fn visit_unit_variant(&mut self,
_name: &str, _name: &str,
_variant_index: usize, _variant_index: usize,
variant: &str) -> io::Result<()> { variant: &str) -> io::Result<()> {
try!(self.formatter.open(&mut self.writer, b'{')); try!(self.formatter.open(&mut self.writer, b'{'));
try!(self.formatter.comma(&mut self.writer, true)); try!(self.formatter.comma(&mut self.writer, true));
try!(self.visit_str(variant)); try!(self.visit_str(variant));
@@ -174,6 +174,7 @@ impl<W, F> ser::Serializer for Serializer<W, F>
#[inline] #[inline]
fn visit_enum_simple<T>(&mut self, fn visit_enum_simple<T>(&mut self,
_name: &str, _name: &str,
_variant_index: usize,
variant: &str, variant: &str,
value: T, value: T,
) -> io::Result<()> ) -> io::Result<()>
@@ -209,11 +210,11 @@ impl<W, F> ser::Serializer for Serializer<W, F>
} }
#[inline] #[inline]
fn visit_enum_seq<V>(&mut self, fn visit_tuple_variant<V>(&mut self,
_name: &str, _name: &str,
_variant_index: usize, _variant_index: usize,
variant: &str, variant: &str,
visitor: V) -> io::Result<()> visitor: V) -> io::Result<()>
where V: ser::SeqVisitor, where V: ser::SeqVisitor,
{ {
try!(self.formatter.open(&mut self.writer, b'{')); try!(self.formatter.open(&mut self.writer, b'{'));
@@ -257,11 +258,11 @@ impl<W, F> ser::Serializer for Serializer<W, F>
} }
#[inline] #[inline]
fn visit_enum_map<V>(&mut self, fn visit_struct_variant<V>(&mut self,
_name: &str, _name: &str,
_variant_index: usize, _variant_index: usize,
variant: &str, variant: &str,
visitor: V) -> io::Result<()> visitor: V) -> io::Result<()>
where V: ser::MapVisitor, where V: ser::MapVisitor,
{ {
try!(self.formatter.open(&mut self.writer, b'{')); try!(self.formatter.open(&mut self.writer, b'{'));
+31 -23
View File
@@ -459,10 +459,10 @@ impl ser::Serializer for Serializer {
} }
#[inline] #[inline]
fn visit_enum_unit(&mut self, fn visit_unit_variant(&mut self,
_name: &str, _name: &str,
_variant_index: usize, _variant_index: usize,
variant: &str) -> Result<(), ()> { variant: &str) -> Result<(), ()> {
let mut values = BTreeMap::new(); let mut values = BTreeMap::new();
values.insert(variant.to_string(), Value::Array(vec![])); values.insert(variant.to_string(), Value::Array(vec![]));
@@ -474,6 +474,7 @@ impl ser::Serializer for Serializer {
#[inline] #[inline]
fn visit_enum_simple<T>(&mut self, fn visit_enum_simple<T>(&mut self,
_name: &str, _name: &str,
_variant_index: usize,
variant: &str, variant: &str,
value: T, value: T,
) -> Result<(), ()> ) -> Result<(), ()>
@@ -509,11 +510,11 @@ impl ser::Serializer for Serializer {
} }
#[inline] #[inline]
fn visit_enum_seq<V>(&mut self, fn visit_tuple_variant<V>(&mut self,
_name: &str, _name: &str,
_variant_index: usize, _variant_index: usize,
variant: &str, variant: &str,
visitor: V) -> Result<(), ()> visitor: V) -> Result<(), ()>
where V: ser::SeqVisitor, where V: ser::SeqVisitor,
{ {
try!(self.visit_seq(visitor)); try!(self.visit_seq(visitor));
@@ -572,11 +573,11 @@ impl ser::Serializer for Serializer {
} }
#[inline] #[inline]
fn visit_enum_map<V>(&mut self, fn visit_struct_variant<V>(&mut self,
_name: &str, _name: &str,
_variant_index: usize, _variant_index: usize,
variant: &str, variant: &str,
visitor: V) -> Result<(), ()> visitor: V) -> Result<(), ()>
where V: ser::MapVisitor, where V: ser::MapVisitor,
{ {
try!(self.visit_map(visitor)); try!(self.visit_map(visitor));
@@ -692,7 +693,10 @@ impl de::Deserializer for Deserializer {
} }
#[inline] #[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, where V: de::EnumVisitor,
{ {
let value = match self.value.take() { 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())) 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())) de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap()))
} }
fn visit_simple<D: de::Deserialize>(&mut self) -> Result<D, Error> fn visit_tuple<V>(&mut self,
{ _len: usize,
de::Deserialize::deserialize(&mut Deserializer::new(self.val.take().unwrap())) visitor: V) -> Result<V::Value, Error>
}
fn visit_seq<V>(&mut self, visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, where V: de::Visitor,
{ {
if let Value::Array(fields) = self.val.take().unwrap() { 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, where V: de::Visitor,
{ {
if let Value::Object(fields) = self.val.take().unwrap() { if let Value::Object(fields) = self.val.take().unwrap() {
+7 -2
View File
@@ -288,7 +288,10 @@ mod deserializer {
} }
#[inline] #[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, where V: de::EnumVisitor,
{ {
match self.stack.pop() { match self.stack.pop() {
@@ -350,7 +353,9 @@ mod deserializer {
de::Deserialize::deserialize(self.de) 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, where V: de::Visitor,
{ {
visitor.visit_seq(self) visitor.visit_seq(self)
-9
View File
@@ -39,15 +39,6 @@ impl serde::Serializer for BytesSerializer {
Err(Error) 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> { fn visit_bool(&mut self, _v: bool) -> Result<(), Error> {
Err(Error) Err(Error)
} }
+99 -20
View File
@@ -22,6 +22,7 @@ enum Token {
Char(char), Char(char),
Str(&'static str), Str(&'static str),
String(String), String(String),
Bytes(&'static [u8]),
Option(bool), Option(bool),
@@ -38,6 +39,10 @@ enum Token {
MapEnd, MapEnd,
EnumStart(&'static str), EnumStart(&'static str),
EnumUnit,
EnumSimple,
EnumSeq,
EnumMap,
EnumEnd, EnumEnd,
} }
@@ -99,6 +104,7 @@ impl Deserializer for TokenDeserializer {
Some(Token::Char(v)) => visitor.visit_char(v), Some(Token::Char(v)) => visitor.visit_char(v),
Some(Token::Str(v)) => visitor.visit_str(v), Some(Token::Str(v)) => visitor.visit_str(v),
Some(Token::String(v)) => visitor.visit_string(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(false)) => visitor.visit_none(),
Some(Token::Option(true)) => visitor.visit_some(self), Some(Token::Option(true)) => visitor.visit_some(self),
Some(Token::Unit) => visitor.visit_unit(), 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, where V: de::EnumVisitor,
{ {
match self.tokens.next() { 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, where V: de::Visitor,
{ {
match self.tokens.peek() { match self.tokens.peek() {
@@ -318,21 +330,53 @@ impl<'a> de::VariantVisitor for TokenDeserializerVariantVisitor<'a> {
} }
fn visit_unit(&mut self) -> Result<(), Error> { 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> fn visit_simple<T>(&mut self) -> Result<T, Self::Error>
where V: de::Visitor, 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, fn visit_tuple<V>(&mut self,
_fields: &'static [&'static str], _len: usize,
visitor: V) -> Result<V::Value, Error> visitor: V) -> Result<V::Value, Error>
where V: de::Visitor, 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)] #[derive(PartialEq, Debug, Deserialize)]
enum Enum { enum Enum {
Unit, Unit,
Simple(i32),
Seq(i32, i32, i32), Seq(i32, i32, i32),
Map { a: i32, b: i32, c: i32 } Map { a: i32, b: i32, c: i32 }
} }
@@ -495,20 +540,18 @@ declare_tests! {
Ok::<i32, i32>(0) => vec![ Ok::<i32, i32>(0) => vec![
Token::EnumStart("Result"), Token::EnumStart("Result"),
Token::Str("Ok"), Token::Str("Ok"),
Token::SeqStart(1),
Token::SeqSep, Token::EnumSimple,
Token::I32(0), Token::I32(0),
Token::SeqEnd, Token::SeqEnd,
Token::EnumEnd,
], ],
Err::<i32, i32>(1) => vec![ Err::<i32, i32>(1) => vec![
Token::EnumStart("Result"), Token::EnumStart("Result"),
Token::Str("Err"), Token::Str("Err"),
Token::SeqStart(1),
Token::SeqSep, Token::EnumSimple,
Token::I32(1), Token::I32(1),
Token::SeqEnd, Token::SeqEnd,
Token::EnumEnd,
], ],
} }
test_unit { test_unit {
@@ -880,14 +923,28 @@ declare_tests! {
Enum::Unit => vec![ Enum::Unit => vec![
Token::EnumStart("Enum"), Token::EnumStart("Enum"),
Token::Str("Unit"), Token::Str("Unit"),
Token::EnumUnit,
Token::Unit, Token::Unit,
Token::EnumEnd, 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 { test_enum_seq {
Enum::Seq(1, 2, 3) => vec![ Enum::Seq(1, 2, 3) => vec![
Token::EnumStart("Enum"), Token::EnumStart("Enum"),
Token::Str("Seq"), Token::Str("Seq"),
Token::EnumSeq,
Token::SeqStart(3), Token::SeqStart(3),
Token::SeqSep, Token::SeqSep,
Token::I32(1), Token::I32(1),
@@ -905,6 +962,8 @@ declare_tests! {
Enum::Map { a: 1, b: 2, c: 3 } => vec![ Enum::Map { a: 1, b: 2, c: 3 } => vec![
Token::EnumStart("Enum"), Token::EnumStart("Enum"),
Token::Str("Map"), Token::Str("Map"),
Token::EnumMap,
Token::MapStart(3), Token::MapStart(3),
Token::MapSep, Token::MapSep,
Token::Str("a"), Token::Str("a"),
@@ -921,4 +980,24 @@ declare_tests! {
Token::EnumEnd, 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,
],
}
} }
+17 -20
View File
@@ -84,6 +84,7 @@ impl<'a> Serializer for AssertSerializer<'a> {
fn visit_enum_simple<T>(&mut self, fn visit_enum_simple<T>(&mut self,
name: &str, name: &str,
_variant_index: usize,
variant: &str, variant: &str,
value: T, value: T,
) -> Result<(), ()> ) -> Result<(), ()>
@@ -98,10 +99,10 @@ impl<'a> Serializer for AssertSerializer<'a> {
Ok(()) Ok(())
} }
fn visit_enum_unit(&mut self, fn visit_unit_variant(&mut self,
name: &str, name: &str,
_variant_index: usize, _variant_index: usize,
variant: &str) -> Result<(), ()> { variant: &str) -> Result<(), ()> {
assert_eq!( assert_eq!(
self.iter.next().unwrap(), self.iter.next().unwrap(),
Token::EnumUnit(name, variant) Token::EnumUnit(name, variant)
@@ -221,11 +222,11 @@ impl<'a> Serializer for AssertSerializer<'a> {
self.visit_sequence(visitor) self.visit_sequence(visitor)
} }
fn visit_enum_seq<V>(&mut self, fn visit_tuple_variant<V>(&mut self,
name: &str, name: &str,
_variant_index: usize, _variant_index: usize,
variant: &str, variant: &str,
visitor: V) -> Result<(), ()> visitor: V) -> Result<(), ()>
where V: SeqVisitor where V: SeqVisitor
{ {
let len = visitor.len(); let len = visitor.len();
@@ -268,11 +269,11 @@ impl<'a> Serializer for AssertSerializer<'a> {
self.visit_mapping(visitor) self.visit_mapping(visitor)
} }
fn visit_enum_map<V>(&mut self, fn visit_struct_variant<V>(&mut self,
name: &str, name: &str,
_variant_index: usize, _variant_index: usize,
variant: &str, variant: &str,
visitor: V) -> Result<(), ()> visitor: V) -> Result<(), ()>
where V: MapVisitor where V: MapVisitor
{ {
let len = visitor.len(); let len = visitor.len();
@@ -396,16 +397,12 @@ declare_tests! {
} }
test_result { test_result {
Ok::<i32, i32>(0) => vec![ Ok::<i32, i32>(0) => vec![
Token::EnumSeqStart("Result", "Ok", Some(1)), Token::EnumSimple("Result", "Ok"),
Token::SeqSep,
Token::I32(0), Token::I32(0),
Token::SeqEnd,
], ],
Err::<i32, i32>(1) => vec![ Err::<i32, i32>(1) => vec![
Token::EnumSeqStart("Result", "Err", Some(1)), Token::EnumSimple("Result", "Err"),
Token::SeqSep,
Token::I32(1), Token::I32(1),
Token::SeqEnd,
], ],
} }
test_slice { test_slice {