From 8868a6880b67fce7c7147526b2973ba59376d93a Mon Sep 17 00:00:00 2001 From: Edward Barnard Date: Thu, 24 Dec 2015 19:39:07 +0000 Subject: Implement serde serialization --- src/de.rs | 286 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib.rs | 11 +++ src/ser.rs | 173 +++++++++++++++++++++++++++++++++++++ 3 files changed, 470 insertions(+) create mode 100644 src/de.rs create mode 100644 src/ser.rs (limited to 'src') diff --git a/src/de.rs b/src/de.rs new file mode 100644 index 0000000..9d77e4d --- /dev/null +++ b/src/de.rs @@ -0,0 +1,286 @@ +use serde::de::{Deserializer as SerdeDeserializer, Error as SerdeError, Visitor, SeqVisitor, + MapVisitor, VariantVisitor, Deserialize, EnumVisitor}; +use std::iter::Peekable; + +use PlistEvent; + +macro_rules! expect { + ($next:expr, $pat:pat) => { + match $next { + Some(Ok(v@$pat)) => v, + None => return Err(Error::end_of_stream()), + _ => return Err(Error::syntax("")) + } + }; + ($next:expr, $pat:pat => $save:expr) => { + match $next { + Some(Ok($pat)) => $save, + None => return Err(Error::end_of_stream()), + _ => return Err(Error::syntax("")) + } + }; +} + +macro_rules! try_next { + ($next:expr) => { + match $next { + Some(Ok(v)) => v, + Some(Err(_)) => return Err(Error::syntax("")), + None => return Err(Error::end_of_stream()) + } + } +} + +#[derive(Debug)] +pub enum Error { + None, +} + +impl SerdeError for Error { + fn syntax(_msg: &str) -> Self { + panic!("stx"); + Error::None + } + + fn end_of_stream() -> Self { + panic!("eos"); + Error::None + } + + fn unknown_field(_field: &str) -> Self { + panic!("uf"); + Error::None + } + + fn missing_field(_field: &'static str) -> Self { + panic!("mf"); + Error::None + } +} + +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 SerdeDeserializer for Deserializer + where I: IntoIterator> +{ + type Error = Error; + + fn visit(&mut self, mut visitor: V) -> Result + where V: Visitor + { + match try_next!(self.events.next()) { + PlistEvent::StartPlist => panic!(), + PlistEvent::EndPlist => panic!(), + + PlistEvent::StartArray(len) => { + visitor.visit_seq(MapSeq::new(self, len.map(|l| l as usize))) + } + PlistEvent::EndArray => return Err(Error::syntax("")), + + PlistEvent::StartDictionary(len) => { + visitor.visit_map(MapSeq::new(self, len.map(|l| l as usize))) + } + PlistEvent::EndDictionary => return Err(Error::syntax("")), + + PlistEvent::BooleanValue(v) => visitor.visit_bool(v), + PlistEvent::DataValue(v) => visitor.visit_byte_buf(v), + PlistEvent::DateValue(v) => visitor.visit_string(v.to_rfc3339()), + PlistEvent::IntegerValue(v) if v.is_positive() => visitor.visit_u64(v as u64), + PlistEvent::IntegerValue(v) => visitor.visit_i64(v as i64), + PlistEvent::RealValue(v) => visitor.visit_f64(v), + PlistEvent::StringValue(v) => visitor.visit_string(v), + } + } + + fn visit_unit(&mut self, mut visitor: V) -> Result + where V: Visitor + { + expect!(self.events.next(), PlistEvent::StringValue(_)); + visitor.visit_unit() + } + + fn visit_option(&mut self, mut visitor: V) -> Result + where V: Visitor + { + expect!(self.events.next(), PlistEvent::StartDictionary(_)); + + let ret = match try_next!(self.events.next()) { + PlistEvent::StringValue(ref s) if &s[..] == "None" => { + let ret = try!(visitor.visit_none()); + expect!(self.events.next(), PlistEvent::StringValue(_)); + ret + } + PlistEvent::StringValue(ref s) if &s[..] == "Some" => try!(visitor.visit_some(self)), + _ => return Err(Error::syntax("")), + }; + + expect!(self.events.next(), PlistEvent::EndDictionary); + + Ok(ret) + } + + fn visit_newtype_struct(&mut self, + _name: &'static str, + mut visitor: V) + -> Result + where V: Visitor + { + visitor.visit_newtype_struct(self) + } + + fn visit_enum(&mut self, + _enum: &'static str, + _variants: &'static [&'static str], + mut visitor: V) + -> Result + where V: EnumVisitor + { + expect!(self.events.next(), PlistEvent::StartDictionary(_)); + let ret = try!(visitor.visit(&mut *self)); + expect!(self.events.next(), PlistEvent::EndDictionary); + Ok(ret) + } +} + +impl VariantVisitor for Deserializer where I: IntoIterator> +{ + type Error = Error; + + fn visit_variant(&mut self) -> Result + where V: Deserialize + { + ::deserialize(self) + } + + fn visit_unit(&mut self) -> Result<(), Self::Error> { + <() as Deserialize>::deserialize(self) + } + + fn visit_newtype(&mut self) -> Result + where T: Deserialize + { + ::deserialize(self) + } + + fn visit_tuple(&mut self, len: usize, visitor: V) -> Result + where V: Visitor + { + ::visit_tuple(self, len, visitor) + } + + fn visit_struct(&mut self, + fields: &'static [&'static str], + visitor: V) + -> Result + where V: Visitor + { + let name = ""; + ::visit_struct(self, name, fields, visitor) + } +} + +struct MapSeq<'a, I, E> + where E: 'a, + I: 'a + IntoIterator> +{ + de: &'a mut Deserializer, + remaining: Option, + finished: bool, +} + +impl<'a, I, E> MapSeq<'a, I, E> + where E: 'a, + I: 'a + IntoIterator> +{ + fn new(de: &'a mut Deserializer, len: Option) -> MapSeq<'a, I, E> { + MapSeq { + de: de, + remaining: len, + finished: false, + } + } +} + +impl<'a, I, E> SeqVisitor for MapSeq<'a, I, E> + where E: 'a, + I: 'a + IntoIterator> +{ + type Error = Error; + + fn visit(&mut self) -> Result, Self::Error> + where T: Deserialize + { + match self.de.events.peek() { + Some(&Ok(PlistEvent::EndArray)) => { + self.de.events.next(); + self.finished = true; + return Ok(None); + } + _ => ::deserialize(self.de).map(|k| Some(k)), + } + } + + fn end(&mut self) -> Result<(), Self::Error> { + if !self.finished { + self.finished = true; + expect!(self.de.events.next(), PlistEvent::EndArray); + } + Ok(()) + } + + fn size_hint(&self) -> (usize, Option) { + ::size_hint(self) + } +} + +impl<'a, I, E> MapVisitor for MapSeq<'a, I, E> + where E: 'a, + I: 'a + IntoIterator> +{ + type Error = Error; + + fn visit_key(&mut self) -> Result, Self::Error> + where K: Deserialize + { + match self.de.events.peek() { + Some(&Ok(PlistEvent::EndDictionary)) => { + self.de.events.next(); + self.finished = true; + return Ok(None); + } + _ => ::deserialize(self.de).map(|k| Some(k)), + } + } + + fn visit_value(&mut self) -> Result + where V: Deserialize + { + ::deserialize(self.de) + } + + fn end(&mut self) -> Result<(), Self::Error> { + if !self.finished { + self.finished = true; + expect!(self.de.events.next(), PlistEvent::EndDictionary); + } + Ok(()) + } + + fn size_hint(&self) -> (usize, Option) { + match self.remaining { + Some(len) => (len, Some(len)), + None => (0, None), + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 682b11c..7c699c7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -38,11 +38,18 @@ extern crate byteorder; extern crate chrono; extern crate rustc_serialize; +extern crate serde; extern crate xml as xml_rs; pub mod binary; pub mod xml; + mod builder; +mod de; +mod ser; + +pub use de::Deserializer; +pub use ser::Serializer; use chrono::{DateTime, UTC}; use chrono::format::ParseError as ChronoParseError; @@ -241,3 +248,7 @@ impl Iterator for EventReader { self.next() } } + +pub trait EventWriter { + fn write(&mut self, event: &PlistEvent) -> Result<(), ()>; +} diff --git a/src/ser.rs b/src/ser.rs new file mode 100644 index 0000000..059bbd7 --- /dev/null +++ b/src/ser.rs @@ -0,0 +1,173 @@ +use serde::ser::{MapVisitor, Serialize, Serializer as SerdeSerializer, SeqVisitor}; + +use {EventWriter, PlistEvent}; + +pub struct Serializer { + writer: W, +} + +impl Serializer { + pub fn new(writer: W) -> Serializer { + Serializer { writer: writer } + } + + #[inline] + fn emit(&mut self, event: PlistEvent) -> Result<(), ()> { + self.writer.write(&event) + } + + pub fn into_inner(self) -> W { + self.writer + } + + fn single_key_dict(&mut self, + key: String, + value_fn: F) + -> Result<(), ::Error> + where F: FnOnce(&mut Serializer) -> Result<(), ::Error> + { + // Emit {key: value} + try!(self.emit(PlistEvent::StartDictionary(Some(1)))); + try!(self.emit(PlistEvent::StringValue(key))); + try!(value_fn(self)); + try!(self.emit(PlistEvent::EndDictionary)); + Ok(()) + } +} + +impl SerdeSerializer for Serializer { + type Error = (); + + fn visit_bool(&mut self, v: bool) -> Result<(), Self::Error> { + self.emit(PlistEvent::BooleanValue(v)) + } + + fn visit_i64(&mut self, v: i64) -> Result<(), Self::Error> { + self.emit(PlistEvent::IntegerValue(v)) + } + + fn visit_u64(&mut self, v: u64) -> Result<(), Self::Error> { + self.emit(PlistEvent::IntegerValue(v as i64)) + } + + fn visit_f64(&mut self, v: f64) -> Result<(), Self::Error> { + self.emit(PlistEvent::RealValue(v)) + } + + fn visit_str(&mut self, value: &str) -> Result<(), Self::Error> { + self.emit(PlistEvent::StringValue(value.to_owned())) + } + + fn visit_bytes(&mut self, value: &[u8]) -> Result<(), Self::Error> { + self.emit(PlistEvent::DataValue(value.to_owned())) + } + + fn visit_unit(&mut self) -> Result<(), Self::Error> { + // Emit empty string + self.emit(PlistEvent::StringValue(String::new())) + } + + fn visit_none(&mut self) -> Result<(), Self::Error> { + self.single_key_dict("None".to_owned(), |this| this.visit_unit()) + } + + fn visit_some(&mut self, value: V) -> Result<(), Self::Error> + where V: Serialize + { + self.single_key_dict("Some".to_owned(), |this| value.serialize(this)) + } + + fn visit_seq(&mut self, mut visitor: V) -> Result<(), Self::Error> + where V: SeqVisitor + { + let len = visitor.len().map(|len| len as u64); + try!(self.emit(PlistEvent::StartArray(len))); + loop { + match try!(visitor.visit(self)) { + Some(()) => (), + None => break, + } + } + try!(self.emit(PlistEvent::EndArray)); + Ok(()) + } + + fn visit_seq_elt(&mut self, value: T) -> Result<(), Self::Error> + where T: Serialize + { + value.serialize(self) + } + + fn visit_map(&mut self, mut visitor: V) -> Result<(), Self::Error> + where V: MapVisitor + { + let len = visitor.len().map(|len| len as u64); + try!(self.emit(PlistEvent::StartDictionary(len))); + loop { + match try!(visitor.visit(self)) { + Some(()) => (), + None => break, + } + } + try!(self.emit(PlistEvent::EndDictionary)); + Ok(()) + } + + fn visit_map_elt(&mut self, key: K, value: V) -> Result<(), Self::Error> + where K: Serialize, + V: Serialize + { + try!(key.serialize(self)); + try!(value.serialize(self)); + Ok(()) + } + + fn visit_unit_variant(&mut self, + _name: &'static str, + _variant_index: usize, + variant: &'static str) + -> Result<(), Self::Error> { + self.single_key_dict(variant.to_owned(), |this| this.visit_unit()) + } + + fn visit_newtype_struct(&mut self, _name: &'static str, value: T) -> Result<(), Self::Error> + where T: Serialize + { + value.serialize(self) + } + + fn visit_newtype_variant(&mut self, + _name: &'static str, + _variant_index: usize, + variant: &'static str, + value: T) + -> Result<(), Self::Error> + where T: Serialize + { + self.single_key_dict(variant.to_owned(), |this| value.serialize(this)) + } + + fn visit_tuple_variant(&mut self, + _name: &'static str, + _variant_index: usize, + variant: &'static str, + visitor: V) + -> Result<(), Self::Error> + where V: SeqVisitor + { + self.single_key_dict(variant.to_owned(), + |this| this.visit_tuple_struct(variant, visitor)) + } + + fn visit_struct_variant(&mut self, + _name: &'static str, + _variant_index: usize, + variant: &'static str, + visitor: V) + -> Result<(), Self::Error> + where V: MapVisitor + { + self.single_key_dict(variant.to_owned(), + |this| this.visit_struct(variant, visitor)) + } +} -- cgit v1.2.3