Add deserializer type hinting hooks

Formats like xml have trouble knowing if they should deserialize
tags into a sequence from the stream they are deserializing from.
This PR adds hooks so the deserializee can inform the deserializer
to provide them a sequence if possible.

Closes #38.
This commit is contained in:
Erick Tryzelaar
2015-03-20 08:32:33 -07:00
parent 5378d22708
commit d17846eff1
4 changed files with 200 additions and 138 deletions
+56 -37
View File
@@ -30,7 +30,7 @@ pub struct Outer {
//////////////////////////////////////////////////////////////////////////////
#[derive(Debug)]
#[derive(Debug, PartialEq)]
pub enum Error {
EndOfStream,
SyntaxError,
@@ -366,30 +366,6 @@ mod deserializer {
where V: de::Visitor,
{
match self.stack.pop() {
Some(State::OuterState(Outer { inner })) => {
self.stack.push(State::VecState(inner));
self.stack.push(State::StrState("inner"));
visitor.visit_named_map("Outer", OuterMapVisitor {
de: self,
state: 0,
})
}
Some(State::InnerState(Inner { a: (), b, c })) => {
self.stack.push(State::MapState(c));
self.stack.push(State::StrState("c"));
self.stack.push(State::UsizeState(b));
self.stack.push(State::StrState("b"));
self.stack.push(State::NullState);
self.stack.push(State::StrState("a"));
visitor.visit_named_map("Inner", InnerMapVisitor {
de: self,
state: 0,
})
}
Some(State::VecState(value)) => {
visitor.visit_seq(OuterSeqVisitor {
de: self,
@@ -423,9 +399,52 @@ mod deserializer {
Some(State::OptionState(true)) => {
visitor.visit_some(self)
}
Some(token) => Err(Error::SyntaxError),
None => Err(Error::EndOfStream),
}
}
fn visit_named_map<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value, Error>
where V: de::Visitor,
{
match self.stack.pop() {
Some(State::OuterState(Outer { inner })) => {
if name != "Outer" {
return Err(Error::SyntaxError);
}
self.stack.push(State::VecState(inner));
self.stack.push(State::StrState("inner"));
visitor.visit_map(OuterMapVisitor {
de: self,
state: 0,
})
}
Some(State::InnerState(Inner { a: (), b, c })) => {
if name != "Inner" {
return Err(Error::SyntaxError);
}
self.stack.push(State::MapState(c));
self.stack.push(State::StrState("c"));
self.stack.push(State::UsizeState(b));
self.stack.push(State::StrState("b"));
self.stack.push(State::NullState);
self.stack.push(State::StrState("a"));
visitor.visit_map(InnerMapVisitor {
de: self,
state: 0,
})
}
_ => {
Err(Error::SyntaxError)
}
}
}
}
struct OuterMapVisitor<'a> {
@@ -605,9 +624,9 @@ fn bench_decoder_0_0(b: &mut Bencher) {
};
let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Decodable::decode(&mut d).unwrap();
let value: Result<Outer, Error> = Decodable::decode(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -627,9 +646,9 @@ fn bench_decoder_1_0(b: &mut Bencher) {
};
let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Decodable::decode(&mut d).unwrap();
let value: Result<Outer, Error> = Decodable::decode(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -654,9 +673,9 @@ fn bench_decoder_1_5(b: &mut Bencher) {
};
let mut d = decoder::OuterDecoder::new(outer.clone());
let value: Outer = Decodable::decode(&mut d).unwrap();
let value: Result<Outer, Error> = Decodable::decode(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -668,9 +687,9 @@ fn bench_deserializer_0_0(b: &mut Bencher) {
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserialize::deserialize(&mut d).unwrap();
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -690,9 +709,9 @@ fn bench_deserializer_1_0(b: &mut Bencher) {
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserialize::deserialize(&mut d).unwrap();
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}
@@ -717,8 +736,8 @@ fn bench_deserializer_1_5(b: &mut Bencher) {
};
let mut d = deserializer::OuterDeserializer::new(outer.clone());
let value: Outer = Deserialize::deserialize(&mut d).unwrap();
let value: Result<Outer, Error> = Deserialize::deserialize(&mut d);
assert_eq!(value, outer);
assert_eq!(value, Ok(outer));
})
}