From 8f6e1fb5b3bbdd8df9587fdb6ee530c1b81ea4dc Mon Sep 17 00:00:00 2001 From: Michael Mokrysz Date: Wed, 22 Feb 2017 23:59:47 +0000 Subject: [PATCH] Resolved error typing. Needs to adapt to Content::Map with non-String keys. `EnumDeserializer` is being adapted from: `serde_json::Value::Map>` serde has a Map variant that allows non-String keys: `serde::de::Content::Map>` There's a lot of assumptions in `EnumDeserializer` about `String` keys and I'm not sure what the adaptation should be. --- serde/src/de/content.rs | 131 +++++++++++++++++++++++++--------------- 1 file changed, 82 insertions(+), 49 deletions(-) diff --git a/serde/src/de/content.rs b/serde/src/de/content.rs index a9b8fc62..4e59d36c 100644 --- a/serde/src/de/content.rs +++ b/serde/src/de/content.rs @@ -14,8 +14,6 @@ use core::cmp; use core::fmt; use core::marker::PhantomData; -use std::collections::BTreeMap; - #[cfg(all(not(feature = "std"), feature = "collections"))] use collections::{String, Vec}; @@ -24,6 +22,7 @@ use alloc::boxed::Box; use de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqVisitor, MapVisitor, EnumVisitor, Unexpected}; +use de::value::ValueDeserializer; /// Used from generated code to buffer the contents of the Deserializer when /// deserializing untagged enums and internally tagged enums. @@ -60,6 +59,34 @@ pub enum Content { Map(Vec<(Content, Content)>), } +impl Content { + fn unexpected(&self) -> Unexpected { + match *self { + Content::Bool(b) => Unexpected::Bool(b), + Content::U8(n) => Unexpected::Unsigned(n as u64), + Content::U16(n) => Unexpected::Unsigned(n as u64), + Content::U32(n) => Unexpected::Unsigned(n as u64), + Content::U64(n) => Unexpected::Unsigned(n), + Content::I8(n) => Unexpected::Signed(n as i64), + Content::I16(n) => Unexpected::Signed(n as i64), + Content::I32(n) => Unexpected::Signed(n as i64), + Content::I64(n) => Unexpected::Signed(n), + Content::F32(f) => Unexpected::Float(f as f64), + Content::F64(f) => Unexpected::Float(f), + Content::Char(c) => Unexpected::Char(c), + Content::String(ref s) => Unexpected::Str(s), + Content::Bytes(ref b) => Unexpected::Bytes(b), + // @TODO: Are these mappings correct? + Content::None => Unexpected::Option, + Content::Some(_) => Unexpected::Option, + Content::Unit => Unexpected::Unit, + Content::Newtype(_) => Unexpected::NewtypeStruct, + Content::Seq(_) => Unexpected::Seq, + Content::Map(_) => Unexpected::Map, + } + } +} + impl Deserialize for Content { fn deserialize(deserializer: D) -> Result { // Untagged and internally tagged enums are only supported in @@ -612,7 +639,7 @@ impl Deserializer for ContentDeserializer fn deserialize_enum(self, _name: &str, _variants: &'static [&'static str], visitor: V) -> Result where V: Visitor, { - let (variant, value) = match self { + let (variant, value) = match self.content { Content::Map(value) => { let mut iter = value.into_iter(); let (variant, value) = match iter.next() { @@ -627,7 +654,7 @@ impl Deserializer for ContentDeserializer } (variant, Some(value)) } - Content::String(variant) => (variant, None), + Content::String(variant) => (Content::String(variant), None), other => { return Err(de::Error::invalid_type(other.unexpected(), &"string or map")); } @@ -636,6 +663,7 @@ impl Deserializer for ContentDeserializer visitor.visit_enum(EnumDeserializer { variant: variant, value: value, + err: PhantomData, }) } @@ -664,49 +692,50 @@ struct EnumDeserializer where E: de::Error { impl de::EnumVisitor for EnumDeserializer where E: de::Error { type Error = E; - type Variant = VariantDeserializer; + type Variant = VariantDeserializer; - fn visit_variant_seed(self, seed: V) -> Result<(V::Value, VariantDeserializer), Self::Error> + fn visit_variant_seed(self, seed: V) -> Result<(V::Value, VariantDeserializer), Self::Error> where V: de::DeserializeSeed { let variant = self.variant.into_deserializer(); - let visitor = VariantDeserializer { value: self.value }; + let visitor = VariantDeserializer { value: self.value, err: PhantomData, }; seed.deserialize(variant).map(|v| (v, visitor)) } } -struct VariantDeserializer { +struct VariantDeserializer where E: de::Error { value: Option, + err: PhantomData, } -impl de::VariantVisitor for VariantDeserializer { - type Error = de::Error; +impl de::VariantVisitor for VariantDeserializer where E: de::Error { + type Error = E; - fn visit_unit(self) -> Result<(), de::Error> { + fn visit_unit(self) -> Result<(), E> { match self.value { - Some(value) => de::Deserialize::deserialize(value), + Some(value) => de::Deserialize::deserialize(ContentDeserializer::new(value)), None => Ok(()), } } - fn visit_newtype_seed(self, seed: T) -> Result - where T: de::DeserializeSeed, E: de::Error + fn visit_newtype_seed(self, seed: T) -> Result + where T: de::DeserializeSeed { match self.value { - Some(value) => seed.deserialize(value), + Some(value) => seed.deserialize(ContentDeserializer::new(value)), None => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"newtype variant")), } } - fn visit_tuple( + fn visit_tuple( self, _len: usize, visitor: V - ) -> Result - where V: de::Visitor, E: de::Error + ) -> Result + where V: de::Visitor { match self.value { - Some(Content::Array(v)) => { + Some(Content::Seq(v)) => { de::Deserializer::deserialize(SeqDeserializer::new(v), visitor) } Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"tuple variant")), @@ -714,12 +743,12 @@ impl de::VariantVisitor for VariantDeserializer { } } - fn visit_struct( + fn visit_struct( self, _fields: &'static [&'static str], visitor: V - ) -> Result - where V: de::Visitor, E: de::Error + ) -> Result + where V: de::Visitor { match self.value { Some(Content::Map(v)) => { @@ -731,24 +760,26 @@ impl de::VariantVisitor for VariantDeserializer { } } -struct SeqDeserializer { +struct SeqDeserializer where E: de::Error { iter: ::std::vec::IntoIter, + err: PhantomData, } -impl SeqDeserializer { +impl SeqDeserializer where E: de::Error { fn new(vec: Vec) -> Self { SeqDeserializer { iter: vec.into_iter(), + err: PhantomData, } } } -impl de::Deserializer for SeqDeserializer { - type Error = de::Error; +impl de::Deserializer for SeqDeserializer where E: de::Error { + type Error = E; #[inline] - fn deserialize(mut self, visitor: V) -> Result - where V: de::Visitor, E: de::Error, + fn deserialize(mut self, visitor: V) -> Result + where V: de::Visitor, { let len = self.iter.len(); if len == 0 { @@ -771,14 +802,14 @@ impl de::Deserializer for SeqDeserializer { } } -impl de::SeqVisitor for SeqDeserializer { - type Error = de::Error; +impl de::SeqVisitor for SeqDeserializer where E: de::Error { + type Error = E; - fn visit_seed(&mut self, seed: T) -> Result, E> - where T: de::DeserializeSeed, E: de::Error, + fn visit_seed(&mut self, seed: T) -> Result, Self::Error> + where T: de::DeserializeSeed, { match self.iter.next() { - Some(value) => seed.deserialize(value).map(Some), + Some(value) => seed.deserialize(ContentDeserializer::new(value)).map(Some), None => Ok(None), } } @@ -788,40 +819,42 @@ impl de::SeqVisitor for SeqDeserializer { } } -struct MapDeserializer { - iter: as IntoIterator>::IntoIter, +struct MapDeserializer where E: de::Error { + iter: as IntoIterator>::IntoIter, value: Option, + err: PhantomData, } -impl MapDeserializer { - fn new(map: BTreeMap) -> Self { +impl MapDeserializer where E: de::Error { + fn new(map: Vec<(String, Content)>) -> Self { MapDeserializer { iter: map.into_iter(), value: None, + err: PhantomData, } } } -impl de::MapVisitor for MapDeserializer { - type Error = de::Error; +impl de::MapVisitor for MapDeserializer where E: de::Error { + type Error = E; - fn visit_key_seed(&mut self, seed: T) -> Result, E> - where T: de::DeserializeSeed, E: de::Error, + fn visit_key_seed(&mut self, seed: T) -> Result, Self::Error> + where T: de::DeserializeSeed, { match self.iter.next() { Some((key, value)) => { self.value = Some(value); - seed.deserialize(Content::String(key)).map(Some) + seed.deserialize(ContentDeserializer::new(Content::String(key))).map(Some) } None => Ok(None), } } - fn visit_value_seed(&mut self, seed: T) -> Result - where T: de::DeserializeSeed, E: de::Error, + fn visit_value_seed(&mut self, seed: T) -> Result + where T: de::DeserializeSeed, { match self.value.take() { - Some(value) => seed.deserialize(value), + Some(value) => seed.deserialize(ContentDeserializer::new(value)), None => Err(de::Error::custom("value is missing")), } } @@ -831,12 +864,12 @@ impl de::MapVisitor for MapDeserializer { } } -impl de::Deserializer for MapDeserializer { - type Error = de::Error; +impl de::Deserializer for MapDeserializer where E: de::Error { + type Error = E; #[inline] - fn deserialize(self, visitor: V) -> Result - where V: de::Visitor, E: de::Error, + fn deserialize(self, visitor: V) -> Result + where V: de::Visitor, { visitor.visit_map(self) }