Remove the first argument from visit_{seq,map}_elt

This commit is contained in:
Erick Tryzelaar 2015-03-16 22:30:02 -07:00
parent a6ba251ef9
commit b40d8f7bac
6 changed files with 271 additions and 79 deletions

View File

@ -449,7 +449,6 @@ fn serialize_tuple_struct_visitor(
) -> (P<ast::Item>, P<ast::Item>) {
let arms: Vec<ast::Arm> = (0 .. fields)
.map(|i| {
let first = builder.expr().bool(i == 0);
let expr = builder.expr()
.tup_field(i)
.field("value").self_();
@ -457,7 +456,7 @@ fn serialize_tuple_struct_visitor(
quote_arm!(cx,
$i => {
self.state += 1;
let v = try!(serializer.visit_seq_elt($first, &$expr));
let v = try!(serializer.visit_seq_elt(&$expr));
Ok(Some(v))
}
)
@ -524,8 +523,6 @@ fn serialize_struct_visitor<I>(
.zip(value_exprs)
.enumerate()
.map(|(i, (key_expr, value_expr))| {
let first = i == 0;
quote_arm!(cx,
$i => {
self.state += 1;
@ -533,7 +530,6 @@ fn serialize_struct_visitor<I>(
Some(
try!(
serializer.visit_map_elt(
$first,
$key_expr,
$value_expr,
)

View File

@ -9,6 +9,10 @@ use ser;
pub struct Serializer<W, F=CompactFormatter> {
writer: W,
formatter: F,
/// `first` is used to signify if we should print a comma when we are walking through a
/// sequence.
first: bool,
}
impl<W> Serializer<W>
@ -33,6 +37,7 @@ impl<W, F> Serializer<W, F>
Serializer {
writer: writer,
formatter: formatter,
first: false,
}
}
@ -166,6 +171,8 @@ impl<W, F> ser::Serializer for Serializer<W, F>
_ => {
try!(self.formatter.open(&mut self.writer, b'['));
self.first = true;
while let Some(()) = try!(visitor.visit(self)) { }
self.formatter.close(&mut self.writer, b']')
@ -187,10 +194,11 @@ impl<W, F> ser::Serializer for Serializer<W, F>
}
#[inline]
fn visit_seq_elt<T>(&mut self, first: bool, value: T) -> io::Result<()>
fn visit_seq_elt<T>(&mut self, value: T) -> io::Result<()>
where T: ser::Serialize,
{
try!(self.formatter.comma(&mut self.writer, first));
try!(self.formatter.comma(&mut self.writer, self.first));
self.first = false;
value.serialize(self)
}
@ -206,6 +214,8 @@ impl<W, F> ser::Serializer for Serializer<W, F>
_ => {
try!(self.formatter.open(&mut self.writer, b'{'));
self.first = true;
while let Some(()) = try!(visitor.visit(self)) { }
self.formatter.close(&mut self.writer, b'}')
@ -227,11 +237,13 @@ impl<W, F> ser::Serializer for Serializer<W, F>
}
#[inline]
fn visit_map_elt<K, V>(&mut self, first: bool, key: K, value: V) -> io::Result<()>
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> io::Result<()>
where K: ser::Serialize,
V: ser::Serialize,
{
try!(self.formatter.comma(&mut self.writer, first));
try!(self.formatter.comma(&mut self.writer, self.first));
self.first = false;
try!(key.serialize(self));
try!(self.formatter.colon(&mut self.writer));
value.serialize(self)

View File

@ -271,7 +271,7 @@ impl ser::Serializer for Serializer {
}
#[inline]
fn visit_seq_elt<T>(&mut self, _first: bool, value: T) -> Result<(), ()>
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), ()>
where T: ser::Serialize,
{
try!(value.serialize(self));
@ -330,7 +330,7 @@ impl ser::Serializer for Serializer {
}
#[inline]
fn visit_map_elt<K, V>(&mut self, _first: bool, key: K, value: V) -> Result<(), ()>
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), ()>
where K: ser::Serialize,
V: ser::Serialize,
{

View File

@ -124,9 +124,7 @@ pub trait Serializer {
self.visit_seq(visitor)
}
fn visit_seq_elt<T>(&mut self,
first: bool,
value: T) -> Result<(), Self::Error>
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), Self::Error>
where T: Serialize;
fn visit_map<V>(&mut self, visitor: V) -> Result<(), Self::Error>
@ -151,10 +149,7 @@ pub trait Serializer {
self.visit_map(visitor)
}
fn visit_map_elt<K, V>(&mut self,
first: bool,
key: K,
value: V) -> Result<(), Self::Error>
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), Self::Error>
where K: Serialize,
V: Serialize;
}
@ -250,7 +245,6 @@ impl<T> Serialize for Option<T> where T: Serialize {
pub struct SeqIteratorVisitor<Iter> {
iter: Iter,
len: Option<usize>,
first: bool,
}
impl<T, Iter> SeqIteratorVisitor<Iter>
@ -261,7 +255,6 @@ impl<T, Iter> SeqIteratorVisitor<Iter>
SeqIteratorVisitor {
iter: iter,
len: len,
first: true,
}
}
}
@ -274,12 +267,9 @@ impl<T, Iter> SeqVisitor for SeqIteratorVisitor<Iter>
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
let first = self.first;
self.first = false;
match self.iter.next() {
Some(value) => {
let value = try!(serializer.visit_seq_elt(first, value));
let value = try!(serializer.visit_seq_elt(value));
Ok(Some(value))
}
None => Ok(None),
@ -365,7 +355,6 @@ macro_rules! tuple_impls {
pub struct $TupleVisitor<'a, $($T: 'a),+> {
tuple: &'a ($($T,)+),
state: u8,
first: bool,
}
impl<'a, $($T: 'a),+> $TupleVisitor<'a, $($T),+> {
@ -373,7 +362,6 @@ macro_rules! tuple_impls {
$TupleVisitor {
tuple: tuple,
state: 0,
first: true,
}
}
}
@ -384,14 +372,11 @@ macro_rules! tuple_impls {
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
let first = self.first;
self.first = false;
match self.state {
$(
$state => {
self.state += 1;
Ok(Some(try!(serializer.visit_seq_elt(first, &e!(self.tuple.$idx)))))
Ok(Some(try!(serializer.visit_seq_elt(&e!(self.tuple.$idx)))))
}
)+
_ => {
@ -527,7 +512,6 @@ tuple_impls! {
pub struct MapIteratorVisitor<Iter> {
iter: Iter,
len: Option<usize>,
first: bool,
}
impl<K, V, Iter> MapIteratorVisitor<Iter>
@ -538,7 +522,6 @@ impl<K, V, Iter> MapIteratorVisitor<Iter>
MapIteratorVisitor {
iter: iter,
len: len,
first: true,
}
}
}
@ -552,12 +535,9 @@ impl<K, V, I> MapVisitor for MapIteratorVisitor<I>
fn visit<S>(&mut self, serializer: &mut S) -> Result<Option<()>, S::Error>
where S: Serializer,
{
let first = self.first;
self.first = false;
match self.iter.next() {
Some((key, value)) => {
let value = try!(serializer.visit_map_elt(first, key, value));
let value = try!(serializer.visit_map_elt(key, value));
Ok(Some(value))
}
None => Ok(None)

View File

@ -144,6 +144,68 @@ fn test_write_list() {
(vec![true, false], "[true,false]"),
]);
test_encode_ok(&[
(vec![vec![], vec![], vec![]], "[[],[],[]]"),
(vec![vec![1, 2, 3], vec![], vec![]], "[[1,2,3],[],[]]"),
(vec![vec![], vec![1, 2, 3], vec![]], "[[],[1,2,3],[]]"),
(vec![vec![], vec![], vec![1, 2, 3]], "[[],[],[1,2,3]]"),
]);
test_pretty_encode_ok(&[
(
vec![vec![], vec![], vec![]],
concat!(
"[\n",
" [],\n",
" [],\n",
" []\n",
"]"
),
),
(
vec![vec![1, 2, 3], vec![], vec![]],
concat!(
"[\n",
" [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ],\n",
" [],\n",
" []\n",
"]"
),
),
(
vec![vec![], vec![1, 2, 3], vec![]],
concat!(
"[\n",
" [],\n",
" [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ],\n",
" []\n",
"]"
),
),
(
vec![vec![], vec![], vec![1, 2, 3]],
concat!(
"[\n",
" [],\n",
" [],\n",
" [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
"]"
),
),
]);
test_pretty_encode_ok(&[
(vec![], "[]"),
(
@ -207,6 +269,154 @@ fn test_write_object() {
"{\"a\":true,\"b\":false}"),
]);
test_encode_ok(&[
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"{\"a\":{},\"b\":{},\"c\":{}}",
),
(
treemap![
"a".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"{\"a\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"b\":{},\"c\":{}}",
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"c".to_string() => treemap![]
],
"{\"a\":{},\"b\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}},\"c\":{}}",
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
]
],
"{\"a\":{},\"b\":{},\"c\":{\"a\":{\"a\":[1,2,3]},\"b\":{},\"c\":{}}}",
),
]);
test_pretty_encode_ok(&[
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
concat!(
"{\n",
" \"a\": {},\n",
" \"b\": {},\n",
" \"c\": {}\n",
"}",
),
),
(
treemap![
"a".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
concat!(
"{\n",
" \"a\": {\n",
" \"a\": {\n",
" \"a\": [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
"}"
),
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
],
"c".to_string() => treemap![]
],
concat!(
"{\n",
" \"a\": {},\n",
" \"b\": {\n",
" \"a\": {\n",
" \"a\": [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
" },\n",
" \"c\": {}\n",
"}"
),
),
(
treemap![
"a".to_string() => treemap![],
"b".to_string() => treemap![],
"c".to_string() => treemap![
"a".to_string() => treemap!["a" => vec![1,2,3]],
"b".to_string() => treemap![],
"c".to_string() => treemap![]
]
],
concat!(
"{\n",
" \"a\": {},\n",
" \"b\": {},\n",
" \"c\": {\n",
" \"a\": {\n",
" \"a\": [\n",
" 1,\n",
" 2,\n",
" 3\n",
" ]\n",
" },\n",
" \"b\": {},\n",
" \"c\": {}\n",
" }\n",
"}"
),
),
]);
test_pretty_encode_ok(&[
(treemap!(), "{}"),
(

View File

@ -36,13 +36,13 @@ pub enum Token<'a> {
SeqStart(Option<usize>),
NamedSeqStart(&'a str, Option<usize>),
EnumSeqStart(&'a str, &'a str, Option<usize>),
SeqSep(bool),
SeqSep,
SeqEnd,
MapStart(Option<usize>),
NamedMapStart(&'a str, Option<usize>),
EnumMapStart(&'a str, &'a str, Option<usize>),
MapSep(bool),
MapSep,
MapEnd,
}
@ -217,10 +217,10 @@ impl<'a> Serializer for AssertSerializer<'a> {
self.visit_sequence(visitor)
}
fn visit_seq_elt<T>(&mut self, first: bool, value: T) -> Result<(), ()>
fn visit_seq_elt<T>(&mut self, value: T) -> Result<(), ()>
where T: Serialize
{
assert_eq!(self.iter.next(), Some(Token::SeqSep(first)));
assert_eq!(self.iter.next(), Some(Token::SeqSep));
value.serialize(self)
}
@ -244,10 +244,7 @@ impl<'a> Serializer for AssertSerializer<'a> {
self.visit_mapping(visitor)
}
fn visit_enum_map<V>(&mut self,
name: &str,
variant: &str,
visitor: V) -> Result<(), ()>
fn visit_enum_map<V>(&mut self, name: &str, variant: &str, visitor: V) -> Result<(), ()>
where V: MapVisitor
{
let len = visitor.len();
@ -257,14 +254,11 @@ impl<'a> Serializer for AssertSerializer<'a> {
self.visit_mapping(visitor)
}
fn visit_map_elt<K, V>(&mut self,
first: bool,
key: K,
value: V) -> Result<(), ()>
fn visit_map_elt<K, V>(&mut self, key: K, value: V) -> Result<(), ()>
where K: Serialize,
V: Serialize,
{
assert_eq!(self.iter.next(), Some(Token::MapSep(first)));
assert_eq!(self.iter.next(), Some(Token::MapSep));
try!(key.serialize(self));
value.serialize(self)
@ -375,13 +369,13 @@ declare_tests! {
],
&[1, 2, 3][..] => vec![
Token::SeqStart(Some(3)),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
@ -393,22 +387,22 @@ declare_tests! {
],
vec![vec![], vec![1], vec![2, 3]] => vec![
Token::SeqStart(Some(3)),
Token::SeqSep(true),
Token::SeqSep,
Token::SeqStart(Some(0)),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqSep,
Token::SeqStart(Some(1)),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
Token::SeqSep(false),
Token::SeqSep,
Token::SeqStart(Some(2)),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
Token::SeqEnd,
@ -417,19 +411,19 @@ declare_tests! {
test_tuple {
(1,) => vec![
Token::SeqStart(Some(1)),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqEnd,
],
(1, 2, 3) => vec![
Token::SeqStart(Some(3)),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
@ -437,37 +431,37 @@ declare_tests! {
test_btreemap {
btreemap![1 => 2] => vec![
Token::MapStart(Some(1)),
Token::MapSep(true),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapEnd,
],
btreemap![1 => 2, 3 => 4] => vec![
Token::MapStart(Some(2)),
Token::MapSep(true),
Token::MapSep,
Token::I32(1),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapEnd,
],
btreemap![1 => btreemap![], 2 => btreemap![3 => 4, 5 => 6]] => vec![
Token::MapStart(Some(2)),
Token::MapSep(true),
Token::MapSep,
Token::I32(1),
Token::MapStart(Some(0)),
Token::MapEnd,
Token::MapSep(false),
Token::MapSep,
Token::I32(2),
Token::MapStart(Some(2)),
Token::MapSep(true),
Token::MapSep,
Token::I32(3),
Token::I32(4),
Token::MapSep(false),
Token::MapSep,
Token::I32(5),
Token::I32(6),
Token::MapEnd,
@ -480,13 +474,13 @@ declare_tests! {
test_named_seq {
NamedSeq(1, 2, 3) => vec![
Token::NamedSeqStart("NamedSeq", Some(3)),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(3),
Token::SeqEnd,
],
@ -494,15 +488,15 @@ declare_tests! {
test_named_map {
NamedMap { a: 1, b: 2, c: 3 } => vec![
Token::NamedMapStart("NamedMap", Some(3)),
Token::MapSep(true),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapSep(false),
Token::MapSep,
Token::Str("c"),
Token::I32(3),
Token::MapEnd,
@ -512,20 +506,20 @@ declare_tests! {
Enum::Unit => vec![Token::EnumUnit("Enum", "Unit")],
Enum::Seq(1, 2) => vec![
Token::EnumSeqStart("Enum", "Seq", Some(2)),
Token::SeqSep(true),
Token::SeqSep,
Token::I32(1),
Token::SeqSep(false),
Token::SeqSep,
Token::I32(2),
Token::SeqEnd,
],
Enum::Map { a: 1, b: 2 } => vec![
Token::EnumMapStart("Enum", "Map", Some(2)),
Token::MapSep(true),
Token::MapSep,
Token::Str("a"),
Token::I32(1),
Token::MapSep(false),
Token::MapSep,
Token::Str("b"),
Token::I32(2),
Token::MapEnd,