use serde::de; use std::fmt::Display; use std::fs::File; use std::io::{BufReader, Read, Seek}; use std::iter::Peekable; use std::path::Path; use events::{self, Event}; use {u64_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(msg: T) -> Self { Error::Serde(msg.to_string()) } } /// A structure that deserializes plist event streams into Rust values. pub struct Deserializer where I: IntoIterator>, { events: Peekable<::IntoIter>, } impl Deserializer where I: IntoIterator>, { pub fn new(iter: I) -> Deserializer { Deserializer { events: iter.into_iter().peekable(), } } } impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer where I: IntoIterator>, { type Error = Error; fn deserialize_any(self, visitor: V) -> Result where V: de::Visitor<'de>, { match try_next!(self.events.next()) { Event::StartArray(len) => { let len = len.and_then(u64_to_usize); 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 = len.and_then(u64_to_usize); 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(self, visitor: V) -> Result where V: de::Visitor<'de>, { expect!(self.events.next(), Event::StringValue(_)); visitor.visit_unit() } fn deserialize_option(self, visitor: V) -> Result 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::()? } 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( self, _name: &'static str, visitor: V, ) -> Result where V: de::Visitor<'de>, { visitor.visit_newtype_struct(self) } fn deserialize_struct( self, _name: &'static str, _fields: &'static [&'static str], visitor: V, ) -> Result 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( self, _enum: &'static str, _variants: &'static [&'static str], visitor: V, ) -> Result 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 where I: IntoIterator>, { type Error = Error; type Variant = Self; fn variant_seed(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 where I: IntoIterator>, { type Error = Error; fn unit_variant(self) -> Result<(), Self::Error> { <() as de::Deserialize>::deserialize(self) } fn newtype_variant_seed(self, seed: T) -> Result where T: de::DeserializeSeed<'de>, { seed.deserialize(self) } fn tuple_variant(self, len: usize, visitor: V) -> Result where V: de::Visitor<'de>, { ::deserialize_tuple(self, len, visitor) } fn struct_variant( self, fields: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { let name = ""; ::deserialize_struct(self, name, fields, visitor) } } pub struct StructValueDeserializer<'a, I: 'a> where I: IntoIterator>, { de: &'a mut Deserializer, } impl<'de, 'a, I> de::Deserializer<'de> for StructValueDeserializer<'a, I> where I: IntoIterator>, { type Error = Error; fn deserialize_any(self, visitor: V) -> Result 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(self, visitor: V) -> Result where V: de::Visitor<'de>, { self.de.deserialize_unit(visitor) } fn deserialize_option(self, visitor: V) -> Result 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( self, name: &'static str, visitor: V, ) -> Result where V: de::Visitor<'de>, { self.de.deserialize_newtype_struct(name, visitor) } fn deserialize_struct( self, name: &'static str, fields: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { self.de.deserialize_struct(name, fields, visitor) } fn deserialize_enum( self, enum_: &'static str, variants: &'static [&'static str], visitor: V, ) -> Result where V: de::Visitor<'de>, { self.de.deserialize_enum(enum_, variants, visitor) } } struct MapAndSeqAccess<'a, I> where I: 'a + IntoIterator>, { de: &'a mut Deserializer, is_struct: bool, remaining: Option, } impl<'a, I> MapAndSeqAccess<'a, I> where I: 'a + IntoIterator>, { fn new( de: &'a mut Deserializer, is_struct: bool, len: Option, ) -> MapAndSeqAccess<'a, I> { MapAndSeqAccess { de, is_struct, remaining: len, } } } impl<'de, 'a, I> de::SeqAccess<'de> for MapAndSeqAccess<'a, I> where I: 'a + IntoIterator>, { type Error = Error; fn next_element_seed(&mut self, seed: T) -> Result, 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 { self.remaining } } impl<'de, 'a, I> de::MapAccess<'de> for MapAndSeqAccess<'a, I> where I: 'a + IntoIterator>, { type Error = Error; fn next_key_seed(&mut self, seed: K) -> Result, 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(&mut self, seed: V) -> Result 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 { self.remaining } } /// Deserializes an instance of type `T` from a plist file of any encoding. pub fn from_file, T: de::DeserializeOwned>(path: P) -> Result { let file = File::open(path)?; from_reader(BufReader::new(file)) } /// Deserializes an instance of type `T` from a seekable byte stream containing a plist file of any encoding. pub fn from_reader(reader: R) -> Result { let reader = events::Reader::new(reader); let mut de = Deserializer::new(reader); de::Deserialize::deserialize(&mut de) } /// Deserializes an instance of type `T` from a byte stream containing an XML encoded plist file. pub fn from_reader_xml(reader: R) -> Result { let reader = events::XmlReader::new(reader); let mut de = Deserializer::new(reader); de::Deserialize::deserialize(&mut de) }