diff options
Diffstat (limited to 'src/de.rs')
| -rw-r--r-- | src/de.rs | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/src/de.rs b/src/de.rs new file mode 100644 index 0000000..148b7b7 --- /dev/null +++ b/src/de.rs @@ -0,0 +1,393 @@ +use serde::de; +use std::fmt::Display; +use std::io::{Read, Seek}; +use std::iter::Peekable; + +use events::{self, Event}; +use {u64_option_to_usize, Error}; + +macro_rules! expect { + ($next:expr, $pat:pat) => { + match $next { + Some(Ok(v @ $pat)) => v, + None => return Err(Error::UnexpectedEof), + _ => return Err(event_mismatch_error()), + } + }; + ($next:expr, $pat:pat => $save:expr) => { + match $next { + Some(Ok($pat)) => $save, + None => return Err(Error::UnexpectedEof), + _ => return Err(event_mismatch_error()), + } + }; +} + +macro_rules! try_next { + ($next:expr) => { + match $next { + Some(Ok(v)) => v, + Some(Err(_)) => return Err(event_mismatch_error()), + None => return Err(Error::UnexpectedEof), + } + }; +} + +fn event_mismatch_error() -> Error { + Error::InvalidData +} + +impl de::Error for Error { + fn custom<T: Display>(msg: T) -> Self { + Error::Serde(msg.to_string()) + } +} + +pub struct Deserializer<I> +where + I: IntoIterator<Item = Result<Event, Error>>, +{ + events: Peekable<<I as IntoIterator>::IntoIter>, +} + +impl<I> Deserializer<I> +where + I: IntoIterator<Item = Result<Event, Error>>, +{ + pub fn new(iter: I) -> Deserializer<I> { + Deserializer { + events: iter.into_iter().peekable(), + } + } +} + +impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer<I> +where + I: IntoIterator<Item = Result<Event, Error>>, +{ + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + match try_next!(self.events.next()) { + Event::StartArray(len) => { + let len = u64_option_to_usize(len)?; + let ret = visitor.visit_seq(MapAndSeqAccess::new(self, false, len))?; + expect!(self.events.next(), Event::EndArray); + Ok(ret) + } + Event::EndArray => Err(event_mismatch_error()), + + Event::StartDictionary(len) => { + let len = u64_option_to_usize(len)?; + let ret = visitor.visit_map(MapAndSeqAccess::new(self, false, len))?; + expect!(self.events.next(), Event::EndDictionary); + Ok(ret) + } + Event::EndDictionary => Err(event_mismatch_error()), + + Event::BooleanValue(v) => visitor.visit_bool(v), + Event::DataValue(v) => visitor.visit_byte_buf(v), + Event::DateValue(v) => visitor.visit_string(v.to_rfc3339()), + Event::IntegerValue(v) if v.is_positive() => visitor.visit_u64(v as u64), + Event::IntegerValue(v) => visitor.visit_i64(v as i64), + Event::RealValue(v) => visitor.visit_f64(v), + Event::StringValue(v) => visitor.visit_string(v), + } + } + + forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string + seq bytes byte_buf map unit_struct + tuple_struct tuple ignored_any identifier + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + expect!(self.events.next(), Event::StringValue(_)); + visitor.visit_unit() + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + expect!(self.events.next(), Event::StartDictionary(_)); + + let ret = match try_next!(self.events.next()) { + Event::StringValue(ref s) if &s[..] == "None" => { + expect!(self.events.next(), Event::StringValue(_)); + visitor.visit_none::<Self::Error>()? + } + Event::StringValue(ref s) if &s[..] == "Some" => visitor.visit_some(&mut *self)?, + _ => return Err(event_mismatch_error()), + }; + + expect!(self.events.next(), Event::EndDictionary); + + Ok(ret) + } + + fn deserialize_newtype_struct<V>( + self, + _name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + visitor.visit_newtype_struct(self) + } + + fn deserialize_struct<V>( + self, + _name: &'static str, + _fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + expect!(self.events.next(), Event::StartDictionary(_)); + let ret = visitor.visit_map(MapAndSeqAccess::new(self, true, None))?; + expect!(self.events.next(), Event::EndDictionary); + Ok(ret) + } + + fn deserialize_enum<V>( + self, + _enum: &'static str, + _variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + expect!(self.events.next(), Event::StartDictionary(_)); + let ret = visitor.visit_enum(&mut *self)?; + expect!(self.events.next(), Event::EndDictionary); + Ok(ret) + } +} + +impl<'de, 'a, I> de::EnumAccess<'de> for &'a mut Deserializer<I> +where + I: IntoIterator<Item = Result<Event, Error>>, +{ + type Error = Error; + type Variant = Self; + + fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self), Self::Error> + where + V: de::DeserializeSeed<'de>, + { + Ok((seed.deserialize(&mut *self)?, self)) + } +} + +impl<'de, 'a, I> de::VariantAccess<'de> for &'a mut Deserializer<I> +where + I: IntoIterator<Item = Result<Event, Error>>, +{ + type Error = Error; + + fn unit_variant(self) -> Result<(), Self::Error> { + <() as de::Deserialize>::deserialize(self) + } + + fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + seed.deserialize(self) + } + + fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + <Self as de::Deserializer>::deserialize_tuple(self, len, visitor) + } + + fn struct_variant<V>( + self, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + let name = ""; + <Self as de::Deserializer>::deserialize_struct(self, name, fields, visitor) + } +} + +pub struct StructValueDeserializer<'a, I: 'a> +where + I: IntoIterator<Item = Result<Event, Error>>, +{ + de: &'a mut Deserializer<I>, +} + +impl<'de, 'a, I> de::Deserializer<'de> for StructValueDeserializer<'a, I> +where + I: IntoIterator<Item = Result<Event, Error>>, +{ + type Error = Error; + + fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + self.de.deserialize_any(visitor) + } + + forward_to_deserialize_any! { + bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string + seq bytes byte_buf map unit_struct + tuple_struct tuple ignored_any identifier + } + + fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + self.de.deserialize_unit(visitor) + } + + fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + // None struct values are ignored so if we're here the value must be Some. + visitor.visit_some(self.de) + } + + fn deserialize_newtype_struct<V>( + self, + name: &'static str, + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + self.de.deserialize_newtype_struct(name, visitor) + } + + fn deserialize_struct<V>( + self, + name: &'static str, + fields: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + self.de.deserialize_struct(name, fields, visitor) + } + + fn deserialize_enum<V>( + self, + enum_: &'static str, + variants: &'static [&'static str], + visitor: V, + ) -> Result<V::Value, Self::Error> + where + V: de::Visitor<'de>, + { + self.de.deserialize_enum(enum_, variants, visitor) + } +} + +struct MapAndSeqAccess<'a, I> +where + I: 'a + IntoIterator<Item = Result<Event, Error>>, +{ + de: &'a mut Deserializer<I>, + is_struct: bool, + remaining: Option<usize>, +} + +impl<'a, I> MapAndSeqAccess<'a, I> +where + I: 'a + IntoIterator<Item = Result<Event, Error>>, +{ + fn new( + de: &'a mut Deserializer<I>, + is_struct: bool, + len: Option<usize>, + ) -> MapAndSeqAccess<'a, I> { + MapAndSeqAccess { + de: de, + is_struct: is_struct, + remaining: len, + } + } +} + +impl<'de, 'a, I> de::SeqAccess<'de> for MapAndSeqAccess<'a, I> +where + I: 'a + IntoIterator<Item = Result<Event, Error>>, +{ + type Error = Error; + + fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error> + where + T: de::DeserializeSeed<'de>, + { + if let Some(&Ok(Event::EndArray)) = self.de.events.peek() { + return Ok(None); + } + + self.remaining = self.remaining.map(|r| r.saturating_sub(1)); + seed.deserialize(&mut *self.de).map(Some) + } + + fn size_hint(&self) -> Option<usize> { + self.remaining + } +} + +impl<'de, 'a, I> de::MapAccess<'de> for MapAndSeqAccess<'a, I> +where + I: 'a + IntoIterator<Item = Result<Event, Error>>, +{ + type Error = Error; + + fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Self::Error> + where + K: de::DeserializeSeed<'de>, + { + if let Some(&Ok(Event::EndDictionary)) = self.de.events.peek() { + return Ok(None); + } + + self.remaining = self.remaining.map(|r| r.saturating_sub(1)); + seed.deserialize(&mut *self.de).map(Some) + } + + fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Self::Error> + where + V: de::DeserializeSeed<'de>, + { + if self.is_struct { + seed.deserialize(StructValueDeserializer { de: &mut *self.de }) + } else { + seed.deserialize(&mut *self.de) + } + } + + fn size_hint(&self) -> Option<usize> { + self.remaining + } +} + +pub fn deserialize<R: Read + Seek, T: de::DeserializeOwned>(reader: R) -> Result<T, Error> { + let reader = events::Reader::new(reader); + let mut de = Deserializer::new(reader); + de::Deserialize::deserialize(&mut de) +} |
