diff options
author | Oliver Schneider <git1984941651981@oli-obk.de> | 2015-04-20 15:11:34 +0200 |
---|---|---|
committer | Oliver Schneider <git1984941651981@oli-obk.de> | 2015-04-20 15:11:34 +0200 |
commit | 6e2f2c39e48fb5ec067b144ec39e9e32121615de (patch) | |
tree | e15b96d7e1656fddbaf7fb3e4a51fbd83460b98e /src/decoder | |
parent | ac86f4c9415adc37e49aa645f2e930dc89fa5f8a (diff) | |
download | milf-rs-6e2f2c39e48fb5ec067b144ec39e9e32121615de.tar.gz milf-rs-6e2f2c39e48fb5ec067b144ec39e9e32121615de.zip |
most tests work now
Diffstat (limited to 'src/decoder')
-rw-r--r-- | src/decoder/serde.rs | 177 |
1 files changed, 143 insertions, 34 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>(I, Option<Value>); -struct SubDecoder(Decoder); +struct MapVisitor<'a, I>(I, Option<Value>, &'a mut Option<Value>, Option<String>); 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<Value>, +} + +impl<'a, I> SeqDeserializer<'a, I> + where I: Iterator<Item=Value>, +{ + pub fn new(iter: I, len: usize, toml: &'a mut Option<Value>) -> 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<Item=Value>, +{ + type Error = DecodeError; + + fn visit<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError> + where V: de::Visitor, + { + visitor.visit_seq(self) + } +} + +impl<'a, I> de::SeqVisitor for SeqDeserializer<'a, I> + where I: Iterator<Item=Value> +{ + type Error = DecodeError; + + fn visit<V>(&mut self) -> Result<Option<V>, 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<usize>) { + (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<V>(&mut self, visitor: V) -> Result<V::Value, de::value::Error> - 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 de::value::ValueDeserializer for DecodeValue { - type Deserializer = SubDecoder; - - fn into_deserializer(self) -> SubDecoder { - SubDecoder(Decoder::new(self.0)) +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<I> de::MapVisitor for MapVisitor<I> +impl<'a, I> de::MapVisitor for MapVisitor<'a, I> where I: Iterator<Item=(String, Value)> { type Error = DecodeError; @@ -139,9 +200,19 @@ impl<I> de::MapVisitor for MapVisitor<I> { 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<I> de::MapVisitor for MapVisitor<I> 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<I> de::MapVisitor for MapVisitor<I> Ok(()) } + fn missing_field<V>(&mut self, field_name: &'static str) -> Result<V, DecodeError> + 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<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError> + where V: de::Visitor, + { + visitor.visit_unit() + } + + fn visit_option<V>(&mut self, mut visitor: V) -> Result<V::Value, DecodeError> + where V: de::Visitor, + { + visitor.visit_none() + } } |