From 6e2f2c39e48fb5ec067b144ec39e9e32121615de Mon Sep 17 00:00:00 2001 From: Oliver Schneider Date: Mon, 20 Apr 2015 15:11:34 +0200 Subject: [PATCH] most tests work now --- src/decoder/serde.rs | 177 ++++++++++++++++++++++++++++++++++--------- tests/serde.rs | 21 +++-- 2 files changed, 159 insertions(+), 39 deletions(-) diff --git a/src/decoder/serde.rs b/src/decoder/serde.rs index 326f7ee..048fede 100644 --- a/src/decoder/serde.rs +++ b/src/decoder/serde.rs @@ -1,10 +1,9 @@ use serde::de; use Value; use super::{Decoder, DecodeError, DecodeErrorKind}; +use std::collections::BTreeMap; -struct DecodeValue(Value); -struct MapVisitor(I, Option); -struct SubDecoder(Decoder); +struct MapVisitor<'a, I>(I, Option, &'a mut Option, Option); fn se2toml(err: de::value::Error, ty: &'static str) -> DecodeError { match err { @@ -49,13 +48,11 @@ impl de::Deserializer for Decoder { } Some(Value::Array(a)) => { let len = a.len(); - let iter = a.into_iter().map(DecodeValue); - let e = visitor.visit_seq(de::value::SeqDeserializer::new(iter, - len)); - e.map_err(|e| se2toml(e, "array")) + let iter = a.into_iter(); + visitor.visit_seq(SeqDeserializer::new(iter, len, &mut self.toml)) } Some(Value::Table(t)) => { - visitor.visit_map(MapVisitor(t.into_iter(), None)) + visitor.visit_map(MapVisitor(t.into_iter(), None, &mut self.toml, None)) } None => Err(de::Error::end_of_stream_error()), } @@ -84,6 +81,81 @@ impl de::Deserializer for Decoder { } } +struct SeqDeserializer<'a, I> { + iter: I, + len: usize, + toml: &'a mut Option, +} + +impl<'a, I> SeqDeserializer<'a, I> + where I: Iterator, +{ + pub fn new(iter: I, len: usize, toml: &'a mut Option) -> Self { + SeqDeserializer { + iter: iter, + len: len, + toml: toml, + } + } + fn remember(&mut self, v: Value) { + *self.toml = self.toml.take().or(Some(Value::Array(Vec::new()))); + // remember unknown field + match self.toml.as_mut().unwrap() { + &mut Value::Array(ref mut a) => { + a.push(v); + }, + _ => unreachable!(), + } + } +} + +impl<'a, I> de::Deserializer for SeqDeserializer<'a, I> + where I: Iterator, +{ + type Error = DecodeError; + + fn visit(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + visitor.visit_seq(self) + } +} + +impl<'a, I> de::SeqVisitor for SeqDeserializer<'a, I> + where I: Iterator +{ + type Error = DecodeError; + + fn visit(&mut self) -> Result, DecodeError> + where V: de::Deserialize + { + match self.iter.next() { + Some(value) => { + self.len -= 1; + let mut de = Decoder::new(value); + let v = try!(de::Deserialize::deserialize(&mut de)); + if let Some(t) = de.toml { + self.remember(t); + } + Ok(Some(v)) + } + None => Ok(None), + } + } + + fn end(&mut self) -> Result<(), DecodeError> { + if self.len == 0 { + Ok(()) + } else { + Err(de::Error::end_of_stream_error()) + } + } + + fn size_hint(&self) -> (usize, Option) { + (self.len, Some(self.len)) + } +} + impl de::Error for DecodeError { fn syntax_error() -> DecodeError { DecodeError { field: None, kind: DecodeErrorKind::SyntaxError } @@ -105,31 +177,20 @@ impl de::Error for DecodeError { } } -impl de::Deserializer for SubDecoder { - type Error = de::value::Error; - - fn visit(&mut self, visitor: V) -> Result - where V: de::Visitor - { - self.0.visit(visitor).map_err(|e| { - match e.kind { - DecodeErrorKind::SyntaxError => de::value::Error::SyntaxError, - DecodeErrorKind::EndOfStream => de::value::Error::EndOfStreamError, - _ => de::value::Error::SyntaxError, - } - }) +impl<'a, I> MapVisitor<'a, I> { + fn remember(&mut self, v: Value) { + *self.2 = self.2.take().or(Some(Value::Table(BTreeMap::new()))); + // remember unknown field + match self.2.as_mut().unwrap() { + &mut Value::Table(ref mut t) => { + t.insert(self.3.take().unwrap(), v); + }, + _ => unreachable!(), + } } } -impl de::value::ValueDeserializer for DecodeValue { - type Deserializer = SubDecoder; - - fn into_deserializer(self) -> SubDecoder { - SubDecoder(Decoder::new(self.0)) - } -} - -impl de::MapVisitor for MapVisitor +impl<'a, I> de::MapVisitor for MapVisitor<'a, I> where I: Iterator { type Error = DecodeError; @@ -139,9 +200,19 @@ impl de::MapVisitor for MapVisitor { match self.0.next() { Some((k, v)) => { - self.1 = Some(v); - de::Deserialize::deserialize(&mut Decoder::new(Value::String(k))) - .map(|v| Some(v)) + self.3 = Some(k.clone()); + let dec = &mut Decoder::new(Value::String(k)); + match de::Deserialize::deserialize(dec) { + Err(DecodeError {kind: DecodeErrorKind::UnknownField, ..}) => { + self.remember(v); + self.visit_key() + } + Ok(val) => { + self.1 = Some(v); + Ok(Some(val)) + }, + Err(e) => Err(e), + } } None => Ok(None), } @@ -152,7 +223,14 @@ impl de::MapVisitor for MapVisitor where V: de::Deserialize { match self.1.take() { - Some(t) => de::Deserialize::deserialize(&mut Decoder::new(t)), + Some(t) => { + let mut dec = Decoder::new(t); + let v = try!(de::Deserialize::deserialize(&mut dec)); + if let Some(t) = dec.toml { + self.remember(t); + } + Ok(v) + }, None => Err(de::Error::end_of_stream_error()) } } @@ -161,4 +239,35 @@ impl de::MapVisitor for MapVisitor Ok(()) } + fn missing_field(&mut self, field_name: &'static str) -> Result + where V: de::Deserialize, + { + println!("missing field: {}", field_name); + // See if the type can deserialize from a unit. + match de::Deserialize::deserialize(&mut UnitDeserializer) { + Err(DecodeError {kind: DecodeErrorKind::SyntaxError, field}) => Err(DecodeError { + field: field.or(Some(field_name.to_string())), + kind: DecodeErrorKind::ExpectedField(None), + }), + v => v, + } + } +} + +struct UnitDeserializer; + +impl de::Deserializer for UnitDeserializer { + type Error = DecodeError; + + fn visit(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + visitor.visit_unit() + } + + fn visit_option(&mut self, mut visitor: V) -> Result + where V: de::Visitor, + { + visitor.visit_none() + } } diff --git a/tests/serde.rs b/tests/serde.rs index 7e3c325..4c0cc96 100644 --- a/tests/serde.rs +++ b/tests/serde.rs @@ -214,14 +214,22 @@ fn hashmap() { fn tuple_struct() { #[derive(Serialize, Deserialize, PartialEq, Debug)] struct Foo(isize, String, f64); + #[derive(Serialize, Deserialize, PartialEq, Debug)] + struct Bar { + whee: Foo, + } - let v = Foo(1, "foo".to_string(), 4.5); + let v = Bar { + whee: Foo(1, "foo".to_string(), 4.5) + }; assert_eq!( encode!(v), map! { - _field0, Integer(1), - _field1, Value::String("foo".to_string()), - _field2, Float(4.5) + whee, Value::Array(vec![ + Integer(1), + Value::String("foo".to_string()), + Float(4.5), + ]) } ); assert_eq!(v, decode!(Table(encode!(v)))); @@ -256,6 +264,7 @@ fn type_errors() { bar, Float(1.0) })); let a: Result = Deserialize::deserialize(&mut d); + // serde uses FromPrimitive, that's why this works match a { Ok(..) => panic!("should not have decoded"), Err(e) => { @@ -278,7 +287,7 @@ fn missing_errors() { Ok(..) => panic!("should not have decoded"), Err(e) => { assert_eq!(format!("{}", e), - "expected a value of type `integer` for the key `bar`"); + "expected a value for the key `bar`"); } } } @@ -299,6 +308,8 @@ fn parse_enum() { } let v = Foo { a: E::Bar(10) }; + // technically serde is correct here. a single element tuple still is a tuple and therefor + // a sequence assert_eq!( encode!(v), map! { a, Integer(10) }