From 6f22cff63ad58c722293f8d74c978a0bf616be67 Mon Sep 17 00:00:00 2001 From: Sam Scott Date: Mon, 22 May 2017 10:49:22 +0100 Subject: Add detection of indexed sequences. Clean up the code in places. --- src/de/mod.rs | 126 +++++++++++++++------------------------------------------- 1 file changed, 32 insertions(+), 94 deletions(-) (limited to 'src/de/mod.rs') diff --git a/src/de/mod.rs b/src/de/mod.rs index cf32c5e..ce4124a 100644 --- a/src/de/mod.rs +++ b/src/de/mod.rs @@ -32,8 +32,8 @@ //! be thought of as similar to the `serde_json::Value` enum. //! //! Each `Level` can be deserialized through `LevelDeserializer`. This will -//! recursively call back to the top level `QsDeserializer`, or when `Level` is -//! a flat value it will attempt to deserialize it to a primitive via +//! recursively call back to the top level `QsDeserializer` for maps, or when +//! `Level` is a flat value it will attempt to deserialize it to a primitive via //! `ParsableStringDeserializer`. @@ -43,8 +43,6 @@ mod parse; pub use de::parse::Config; use error::*; -use data_encoding::base64url as base64; - use serde::de; use serde::de::IntoDeserializer; @@ -135,6 +133,7 @@ pub struct QsDeserializer { #[derive(Debug)] enum Level { Nested(BTreeMap), + OrderedSeq(BTreeMap), Sequence(Vec), Flat(String), Invalid(&'static str), @@ -436,6 +435,10 @@ macro_rules! deserialize_primitive { Err(de::Error::custom(format!("Expected: {:?}, got a Map", stringify!($ty)))) }, + Level::OrderedSeq(_) => { + Err(de::Error::custom(format!("Expected: {:?}, got an OrderedSequence", + stringify!($ty)))) + }, Level::Sequence(_) => { Err(de::Error::custom(format!("Expected: {:?}, got a Sequence", stringify!($ty)))) @@ -459,7 +462,7 @@ impl LevelDeserializer { }, Level::Invalid(e) => { Err(de::Error::custom(e)) - } + }, l => { Err(de::Error::custom(format!("could not convert {:?} to QsDeserializer", l))) }, @@ -475,11 +478,13 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer { { match self.0 { Level::Nested(_) => { - self.deserialize_map(visitor) + self.into_deserializer()?.deserialize_map(visitor) }, - Level::Sequence(_) => { - self.deserialize_seq(visitor) - + Level::OrderedSeq(map) => { + visitor.visit_seq(LevelSeq(map.into_iter().map(|(_k, v)| v))) + }, + Level::Sequence(seq) => { + visitor.visit_seq(LevelSeq(seq.into_iter())) }, Level::Flat(x) => { visitor.visit_string(x) @@ -490,25 +495,6 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer { } } - fn deserialize_seq(self, visitor: V) -> Result - where V: de::Visitor<'de>, - { - match self.0 { - Level::Nested(map) => { - visitor.visit_seq(LevelSeq(map.into_iter().map(|(_k, v)| v))) - }, - Level::Sequence(x) => { - visitor.visit_seq(LevelSeq(x.into_iter())) - }, - Level::Invalid(e) => { - Err(de::Error::custom(e)) - }, - x => { - visitor.visit_seq(LevelSeq(vec![x].into_iter())) - }, - } - } - fn deserialize_option(self, visitor: V) -> Result where V: de::Visitor<'de>, { @@ -543,84 +529,27 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer { } } - fn deserialize_map(self, visitor: V) -> Result - where V: de::Visitor<'de>, - { - self.into_deserializer()?.deserialize_map(visitor) - - } - - fn deserialize_struct(self, - name: &'static str, - fields: &'static [&'static str], - visitor: V) - -> Result - where V: de::Visitor<'de>, - { - self.into_deserializer()?.deserialize_struct(name, fields, visitor) - } - fn deserialize_newtype_struct( self, _name: &'static str, visitor: V ) -> Result where V: de::Visitor<'de> - { - self.deserialize_seq(visitor) - } - - fn deserialize_tuple( - self, - _len: usize, - visitor: V - ) -> Result - where V: de::Visitor<'de> - { - self.deserialize_seq(visitor) - } - fn deserialize_tuple_struct( - self, - _name: &'static str, - _len: usize, - visitor: V - ) -> Result - where V: de::Visitor<'de> - { - self.deserialize_seq(visitor) - } - - fn deserialize_bytes(self, visitor: V) -> Result - where V: de::Visitor<'de> { match self.0 { Level::Nested(_) => { - Err(de::Error::custom("Expected: base64-encoded string, got a Map")) - }, - Level::Sequence(_) => { - Err(de::Error::custom("Expected: base64-encoded string, got a Sequence")) + self.into_deserializer()?.deserialize_map(visitor) }, - Level::Flat(x) => { - visitor.visit_byte_buf(base64::decode_nopad(x.as_bytes())?) - }, - Level::Invalid(e) => { - Err(de::Error::custom(e)) - } - } - } - - fn deserialize_byte_buf(self, visitor: V) -> Result - where V: de::Visitor<'de> - { - match self.0 { - Level::Nested(_) => { - Err(de::Error::custom("Expected: base64-encoded string, got a Map")) + Level::OrderedSeq(map) => { + visitor.visit_seq(LevelSeq(map.into_iter().map(|(_k, v)| v))) }, - Level::Sequence(_) => { - Err(de::Error::custom("Expected: base64-encoded string, got a Sequence")) + Level::Sequence(seq) => { + visitor.visit_seq(LevelSeq(seq.into_iter())) }, - Level::Flat(x) => { - visitor.visit_byte_buf(base64::decode_nopad(x.as_bytes())?) + Level::Flat(_) => { + // For a newtype_struct, attempt to deserialize a flat value as a + // single element sequence. + visitor.visit_seq(LevelSeq(vec![self.0].into_iter())) }, Level::Invalid(e) => { Err(de::Error::custom(e)) @@ -628,6 +557,7 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer { } } + deserialize_primitive!(bool, deserialize_bool, visit_bool); deserialize_primitive!(i8, deserialize_i8, visit_i8); deserialize_primitive!(i16, deserialize_i16, visit_i16); @@ -645,10 +575,18 @@ impl<'de> de::Deserializer<'de> for LevelDeserializer { char str string + bytes + byte_buf unit unit_struct + // newtype_struct + tuple_struct + struct identifier + tuple ignored_any + seq + map } } -- cgit v1.2.3