most tests work now
This commit is contained in:
parent
ac86f4c941
commit
6e2f2c39e4
|
@ -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<'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<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.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);
|
||||
de::Deserialize::deserialize(&mut Decoder::new(Value::String(k)))
|
||||
.map(|v| 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()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<Foo, DecodeError> = 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) }
|
||||
|
|
Loading…
Reference in a new issue