Add a StructDecoder
This commit is contained in:
parent
6e917c0800
commit
ad2d7a5deb
245
de.rs
245
de.rs
@ -438,7 +438,7 @@ mod tests {
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[deriving(Eq, Show)]
|
#[deriving(Clone, Eq, Show, Decodable)]
|
||||||
struct Inner {
|
struct Inner {
|
||||||
a: (),
|
a: (),
|
||||||
b: uint,
|
b: uint,
|
||||||
@ -459,7 +459,7 @@ mod tests {
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[deriving(Eq, Show)]
|
#[deriving(Clone, Eq, Show, Decodable)]
|
||||||
struct Outer {
|
struct Outer {
|
||||||
inner: Vec<Inner>,
|
inner: Vec<Inner>,
|
||||||
}
|
}
|
||||||
@ -954,6 +954,216 @@ mod tests {
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#[deriving(Show)]
|
||||||
|
enum OuterDecoderState {
|
||||||
|
OuterDecoderOuterState(Outer),
|
||||||
|
OuterDecoderInnerState(Inner),
|
||||||
|
OuterDecoderNullState,
|
||||||
|
OuterDecoderUintState(uint),
|
||||||
|
OuterDecoderCharState(char),
|
||||||
|
OuterDecoderStrState(StrBuf),
|
||||||
|
OuterDecoderFieldState(&'static str),
|
||||||
|
OuterDecoderVecState(Vec<Inner>),
|
||||||
|
OuterDecoderMapState(HashMap<StrBuf, Option<char>>),
|
||||||
|
OuterDecoderOptionState(bool),
|
||||||
|
}
|
||||||
|
|
||||||
|
struct OuterDecoder {
|
||||||
|
stack: Vec<OuterDecoderState>,
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OuterDecoder {
|
||||||
|
#[inline]
|
||||||
|
fn new(animal: Outer) -> OuterDecoder {
|
||||||
|
OuterDecoder {
|
||||||
|
stack: vec!(OuterDecoderOuterState(animal)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Decoder<Error> for OuterDecoder {
|
||||||
|
// Primitive types:
|
||||||
|
#[inline]
|
||||||
|
fn read_nil(&mut self) -> Result<(), Error> {
|
||||||
|
match self.stack.pop() {
|
||||||
|
Some(OuterDecoderNullState) => Ok(()),
|
||||||
|
_ => Err(SyntaxError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn read_uint(&mut self) -> Result<uint, Error> {
|
||||||
|
match self.stack.pop() {
|
||||||
|
Some(OuterDecoderUintState(value)) => Ok(value),
|
||||||
|
_ => Err(SyntaxError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn read_u64(&mut self) -> Result<u64, Error> { Err(SyntaxError) }
|
||||||
|
fn read_u32(&mut self) -> Result<u32, Error> { Err(SyntaxError) }
|
||||||
|
fn read_u16(&mut self) -> Result<u16, Error> { Err(SyntaxError) }
|
||||||
|
fn read_u8(&mut self) -> Result<u8, Error> { Err(SyntaxError) }
|
||||||
|
fn read_int(&mut self) -> Result<int, Error> { Err(SyntaxError) }
|
||||||
|
fn read_i64(&mut self) -> Result<i64, Error> { Err(SyntaxError) }
|
||||||
|
fn read_i32(&mut self) -> Result<i32, Error> { Err(SyntaxError) }
|
||||||
|
fn read_i16(&mut self) -> Result<i16, Error> { Err(SyntaxError) }
|
||||||
|
fn read_i8(&mut self) -> Result<i8, Error> { Err(SyntaxError) }
|
||||||
|
fn read_bool(&mut self) -> Result<bool, Error> { Err(SyntaxError) }
|
||||||
|
fn read_f64(&mut self) -> Result<f64, Error> { Err(SyntaxError) }
|
||||||
|
fn read_f32(&mut self) -> Result<f32, Error> { Err(SyntaxError) }
|
||||||
|
#[inline]
|
||||||
|
fn read_char(&mut self) -> Result<char, Error> {
|
||||||
|
match self.stack.pop() {
|
||||||
|
Some(OuterDecoderCharState(c)) => Ok(c),
|
||||||
|
_ => Err(SyntaxError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn read_str(&mut self) -> Result<StrBuf, Error> {
|
||||||
|
match self.stack.pop() {
|
||||||
|
Some(OuterDecoderStrState(value)) => Ok(value),
|
||||||
|
_ => Err(SyntaxError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compound types:
|
||||||
|
fn read_enum<T>(&mut self, _name: &str, _f: |&mut OuterDecoder| -> Result<T, Error>) -> Result<T, Error> { Err(SyntaxError) }
|
||||||
|
|
||||||
|
fn read_enum_variant<T>(&mut self,
|
||||||
|
_names: &[&str],
|
||||||
|
_f: |&mut OuterDecoder, uint| -> Result<T, Error>)
|
||||||
|
-> Result<T, Error> { Err(SyntaxError) }
|
||||||
|
fn read_enum_variant_arg<T>(&mut self,
|
||||||
|
_a_idx: uint,
|
||||||
|
_f: |&mut OuterDecoder| -> Result<T, Error>)
|
||||||
|
-> Result<T, Error> { Err(SyntaxError) }
|
||||||
|
|
||||||
|
fn read_enum_struct_variant<T>(&mut self,
|
||||||
|
_names: &[&str],
|
||||||
|
_f: |&mut OuterDecoder, uint| -> Result<T, Error>)
|
||||||
|
-> Result<T, Error> { Err(SyntaxError) }
|
||||||
|
fn read_enum_struct_variant_field<T>(&mut self,
|
||||||
|
_f_name: &str,
|
||||||
|
_f_idx: uint,
|
||||||
|
_f: |&mut OuterDecoder| -> Result<T, Error>)
|
||||||
|
-> Result<T, Error> { Err(SyntaxError) }
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_struct<T>(&mut self, s_name: &str, _len: uint, f: |&mut OuterDecoder| -> Result<T, Error>) -> Result<T, Error> {
|
||||||
|
match self.stack.pop() {
|
||||||
|
Some(OuterDecoderOuterState(Outer { inner: inner })) => {
|
||||||
|
if s_name == "Outer" {
|
||||||
|
self.stack.push(OuterDecoderVecState(inner));
|
||||||
|
self.stack.push(OuterDecoderFieldState("inner"));
|
||||||
|
f(self)
|
||||||
|
} else {
|
||||||
|
Err(SyntaxError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(OuterDecoderInnerState(Inner { a: (), b: b, c: c })) => {
|
||||||
|
if s_name == "Inner" {
|
||||||
|
self.stack.push(OuterDecoderMapState(c));
|
||||||
|
self.stack.push(OuterDecoderFieldState("c"));
|
||||||
|
|
||||||
|
self.stack.push(OuterDecoderUintState(b));
|
||||||
|
self.stack.push(OuterDecoderFieldState("b"));
|
||||||
|
|
||||||
|
self.stack.push(OuterDecoderNullState);
|
||||||
|
self.stack.push(OuterDecoderFieldState("a"));
|
||||||
|
f(self)
|
||||||
|
} else {
|
||||||
|
Err(SyntaxError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Err(SyntaxError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn read_struct_field<T>(&mut self, f_name: &str, _f_idx: uint, f: |&mut OuterDecoder| -> Result<T, Error>) -> Result<T, Error> {
|
||||||
|
match self.stack.pop() {
|
||||||
|
Some(OuterDecoderFieldState(name)) => {
|
||||||
|
if f_name == name {
|
||||||
|
f(self)
|
||||||
|
} else {
|
||||||
|
Err(SyntaxError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => Err(SyntaxError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_tuple<T>(&mut self, _f: |&mut OuterDecoder, uint| -> Result<T, Error>) -> Result<T, Error> { Err(SyntaxError) }
|
||||||
|
fn read_tuple_arg<T>(&mut self, _a_idx: uint, _f: |&mut OuterDecoder| -> Result<T, Error>) -> Result<T, Error> { Err(SyntaxError) }
|
||||||
|
|
||||||
|
fn read_tuple_struct<T>(&mut self,
|
||||||
|
_s_name: &str,
|
||||||
|
_f: |&mut OuterDecoder, uint| -> Result<T, Error>)
|
||||||
|
-> Result<T, Error> { Err(SyntaxError) }
|
||||||
|
fn read_tuple_struct_arg<T>(&mut self,
|
||||||
|
_a_idx: uint,
|
||||||
|
_f: |&mut OuterDecoder| -> Result<T, Error>)
|
||||||
|
-> Result<T, Error> { Err(SyntaxError) }
|
||||||
|
|
||||||
|
// Specialized types:
|
||||||
|
#[inline]
|
||||||
|
fn read_option<T>(&mut self, f: |&mut OuterDecoder, bool| -> Result<T, Error>) -> Result<T, Error> {
|
||||||
|
match self.stack.pop() {
|
||||||
|
Some(OuterDecoderOptionState(b)) => f(self, b),
|
||||||
|
_ => Err(SyntaxError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_seq<T>(&mut self, f: |&mut OuterDecoder, uint| -> Result<T, Error>) -> Result<T, Error> {
|
||||||
|
match self.stack.pop() {
|
||||||
|
Some(OuterDecoderVecState(value)) => {
|
||||||
|
let len = value.len();
|
||||||
|
for inner in value.move_iter().rev() {
|
||||||
|
self.stack.push(OuterDecoderInnerState(inner));
|
||||||
|
}
|
||||||
|
f(self, len)
|
||||||
|
}
|
||||||
|
_ => Err(SyntaxError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn read_seq_elt<T>(&mut self, _idx: uint, f: |&mut OuterDecoder| -> Result<T, Error>) -> Result<T, Error> {
|
||||||
|
f(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn read_map<T>(&mut self, f: |&mut OuterDecoder, uint| -> Result<T, Error>) -> Result<T, Error> {
|
||||||
|
match self.stack.pop() {
|
||||||
|
Some(OuterDecoderMapState(map)) => {
|
||||||
|
let len = map.len();
|
||||||
|
for (key, value) in map.move_iter() {
|
||||||
|
match value {
|
||||||
|
Some(c) => {
|
||||||
|
self.stack.push(OuterDecoderCharState(c));
|
||||||
|
self.stack.push(OuterDecoderOptionState(true));
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
self.stack.push(OuterDecoderOptionState(false));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.stack.push(OuterDecoderStrState(key));
|
||||||
|
}
|
||||||
|
f(self, len)
|
||||||
|
}
|
||||||
|
_ => Err(SyntaxError),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn read_map_elt_key<T>(&mut self, _idx: uint, f: |&mut OuterDecoder| -> Result<T, Error>) -> Result<T, Error> {
|
||||||
|
f(self)
|
||||||
|
}
|
||||||
|
#[inline]
|
||||||
|
fn read_map_elt_val<T>(&mut self, _idx: uint, f: |&mut OuterDecoder| -> Result<T, Error>) -> Result<T, Error> {
|
||||||
|
f(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_tokens_int() {
|
fn test_tokens_int() {
|
||||||
let tokens = vec!(
|
let tokens = vec!(
|
||||||
@ -1338,10 +1548,10 @@ mod tests {
|
|||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let animal = Frog("Henry".to_strbuf(), 349);
|
let animal = Frog("Henry".to_strbuf(), 349);
|
||||||
|
|
||||||
let mut d = AnimalDecoder::new(animal);
|
let mut d = AnimalDecoder::new(animal.clone());
|
||||||
let value: Animal = Decodable::decode(&mut d).unwrap();
|
let value: Animal = Decodable::decode(&mut d).unwrap();
|
||||||
|
|
||||||
assert_eq!(value, Frog("Henry".to_strbuf(), 349));
|
assert_eq!(value, animal);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1350,10 +1560,33 @@ mod tests {
|
|||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
let animal = Frog("Henry".to_strbuf(), 349);
|
let animal = Frog("Henry".to_strbuf(), 349);
|
||||||
|
|
||||||
let mut d = AnimalDeserializer::new(animal);
|
let mut d = AnimalDeserializer::new(animal.clone());
|
||||||
let value: Animal = Deserializable::deserialize(&mut d).unwrap();
|
let value: Animal = Deserializable::deserialize(&mut d).unwrap();
|
||||||
|
|
||||||
assert_eq!(value, Frog("Henry".to_strbuf(), 349));
|
assert_eq!(value, animal);
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[bench]
|
||||||
|
fn bench_struct_decoder(b: &mut Bencher) {
|
||||||
|
b.iter(|| {
|
||||||
|
let mut map = HashMap::new();
|
||||||
|
map.insert("abc".to_strbuf(), Some('c'));
|
||||||
|
|
||||||
|
let outer = Outer {
|
||||||
|
inner: vec!(
|
||||||
|
Inner {
|
||||||
|
a: (),
|
||||||
|
b: 5,
|
||||||
|
c: map,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut d = OuterDecoder::new(outer.clone());
|
||||||
|
let value: Outer = Decodable::decode(&mut d).unwrap();
|
||||||
|
|
||||||
|
assert_eq!(value, outer);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user