aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/date.rs8
-rw-r--r--src/serde/ser.rs412
2 files changed, 362 insertions, 58 deletions
diff --git a/src/date.rs b/src/date.rs
index de4bd67..4729193 100644
--- a/src/date.rs
+++ b/src/date.rs
@@ -62,7 +62,7 @@ impl FromStr for Date {
}
#[cfg(feature = "serde")]
-mod serde_impls {
+pub mod serde_impls {
use serde_base::de::{Deserialize, Deserializer, Error, Visitor, Unexpected};
use serde_base::ser::{Serialize, Serializer};
use std::fmt;
@@ -70,12 +70,14 @@ mod serde_impls {
use Date;
+ pub const DATE_NEWTYPE_STRUCT_NAME: &'static str = "PLIST-DATE";
+
impl Serialize for Date {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
let date_str = self.to_string();
- serializer.serialize_newtype_struct("PLIST-DATE", &date_str)
+ serializer.serialize_newtype_struct(DATE_NEWTYPE_STRUCT_NAME, &date_str)
}
}
@@ -115,7 +117,7 @@ mod serde_impls {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: Deserializer<'de>
{
- deserializer.deserialize_newtype_struct("PLIST-DATE", DateNewtypeVisitor)
+ deserializer.deserialize_newtype_struct(DATE_NEWTYPE_STRUCT_NAME, DateNewtypeVisitor)
}
}
}
diff --git a/src/serde/ser.rs b/src/serde/ser.rs
index f19093b..5d73ad1 100644
--- a/src/serde/ser.rs
+++ b/src/serde/ser.rs
@@ -6,6 +6,7 @@ use std::fmt::Display;
use std::str::FromStr;
use {Date, Error, EventWriter, PlistEvent};
+use date::serde_impls::DATE_NEWTYPE_STRUCT_NAME;
impl ser::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
@@ -15,32 +16,16 @@ impl ser::Error for Error {
pub struct Serializer<W: EventWriter> {
writer: W,
- // We don't want to serialize None if the Option is in a struct field as this is how null
- // fields are represented in plists. This is fragile but results in minimal code duplication.
- // TODO: This is fragile. Use distinct types instead.
- maybe_option_field_name: Option<&'static str>,
- expecting_date: bool,
}
impl<W: EventWriter> Serializer<W> {
pub fn new(writer: W) -> Serializer<W> {
- Serializer {
- writer: writer,
- maybe_option_field_name: None,
- expecting_date: false,
- }
+ Serializer { writer: writer }
}
fn emit(&mut self, event: PlistEvent) -> Result<(), Error> {
- // Write a waiting struct field name.
- // TODO: This is fragile. Use distinct types instead.
- if let Some(field_name) = self.maybe_option_field_name.take() {
- self.emit(PlistEvent::StringValue(field_name.to_owned()))?;
- }
- if self.expecting_date {
- panic!("Expecting date");
- }
- Ok(self.writer.write(&event)?)
+ self.writer.write(&event)?;
+ Ok(())
}
pub fn into_inner(self) -> W {
@@ -120,42 +105,24 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
self.emit(PlistEvent::StringValue(v.to_string()))
}
- fn serialize_str(self, value: &str) -> Result<(), Self::Error> {
- if self.expecting_date {
- self.expecting_date = false;
- self.emit(PlistEvent::DateValue(Date::from_str(value).expect("Invalid date format")))
- } else {
- self.emit(PlistEvent::StringValue(value.to_owned()))
- }
+ fn serialize_str(self, v: &str) -> Result<(), Self::Error> {
+ self.emit(PlistEvent::StringValue(v.to_owned()))
}
- fn serialize_bytes(self, value: &[u8]) -> Result<(), Self::Error> {
- self.emit(PlistEvent::DataValue(value.to_owned()))
+ fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
+ self.emit(PlistEvent::DataValue(v.to_owned()))
}
fn serialize_none(self) -> Result<(), Self::Error> {
- // Don't write a dict for None if the Option is a struct field.
- // TODO: This is fragile. Use distinct types instead.
- if let None = self.maybe_option_field_name.take() {
- self.single_key_dict("None".to_owned())?;
- self.serialize_unit()?;
- self.single_key_dict_end()?;
- }
- Ok(())
+ self.single_key_dict("None".to_owned())?;
+ self.serialize_unit()?;
+ self.single_key_dict_end()
}
fn serialize_some<T: ?Sized + ser::Serialize>(self, value: &T) -> Result<(), Self::Error> {
- // Don't write a dict for None if the Option is a struct field.
- // Can't use the write in emit here in case there is a Some(None).
- // TODO: This is fragile. Use distinct types instead.
- if let Some(field_name) = self.maybe_option_field_name.take() {
- self.emit(PlistEvent::StringValue(field_name.to_owned()))?;
- value.serialize(&mut *self)
- } else {
- self.single_key_dict("Some".to_owned())?;
- value.serialize(&mut *self)?;
- self.single_key_dict_end()
- }
+ self.single_key_dict("Some".to_owned())?;
+ value.serialize(&mut *self)?;
+ self.single_key_dict_end()
}
fn serialize_unit(self) -> Result<(), Self::Error> {
@@ -179,13 +146,14 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
}
fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(self,
- _name: &'static str,
+ name: &'static str,
value: &T)
-> Result<(), Self::Error> {
- if _name == "PLIST-DATE" {
- self.expecting_date = true;
+ if name == DATE_NEWTYPE_STRUCT_NAME {
+ value.serialize(DateSerializer { ser: &mut *self })
+ } else {
+ value.serialize(self)
}
- value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(self,
@@ -251,6 +219,338 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
}
}
+struct StructFieldSerializer<'a, W: 'a + EventWriter> {
+ ser: &'a mut Serializer<W>,
+ field_name: &'static str,
+}
+
+impl<'a, W: EventWriter> StructFieldSerializer<'a, W> {
+ fn use_ser(self) -> Result<&'a mut Serializer<W>, Error> {
+ // We are going to serialize something so write the struct field name.
+ self.ser.emit(PlistEvent::StringValue(self.field_name.to_owned()))?;
+ Ok(self.ser)
+ }
+}
+
+impl<'a, W: EventWriter> ser::Serializer for StructFieldSerializer<'a, W> {
+ type Ok = ();
+ type Error = Error;
+
+ type SerializeSeq = Compound<'a, W>;
+ type SerializeTuple = Compound<'a, W>;
+ type SerializeTupleStruct = Compound<'a, W>;
+ type SerializeTupleVariant = Compound<'a, W>;
+ type SerializeMap = Compound<'a, W>;
+ type SerializeStruct = Compound<'a, W>;
+ type SerializeStructVariant = Compound<'a, W>;
+
+ fn serialize_bool(self, v: bool) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_bool(v)
+ }
+
+ fn serialize_i8(self, v: i8) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_i8(v)
+ }
+
+ fn serialize_i16(self, v: i16) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_i16(v)
+ }
+
+ fn serialize_i32(self, v: i32) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_i32(v)
+ }
+
+ fn serialize_i64(self, v: i64) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_i64(v)
+ }
+
+ fn serialize_u8(self, v: u8) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_u8(v)
+ }
+
+ fn serialize_u16(self, v: u16) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_u16(v)
+ }
+
+ fn serialize_u32(self, v: u32) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_u32(v)
+ }
+
+ fn serialize_u64(self, v: u64) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_u64(v)
+ }
+
+ fn serialize_f32(self, v: f32) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_f32(v)
+ }
+
+ fn serialize_f64(self, v: f64) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_f64(v)
+ }
+
+ fn serialize_char(self, v: char) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_char(v)
+ }
+
+ fn serialize_str(self, v: &str) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_str(v)
+ }
+
+ fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_bytes(v)
+ }
+
+ fn serialize_none(self) -> Result<(), Self::Error> {
+ // Don't write a dict for None if the Option is in a struct.
+ Ok(())
+ }
+
+ fn serialize_some<T: ?Sized + ser::Serialize>(self, value: &T) -> Result<(), Self::Error> {
+ let ser = self.use_ser()?;
+ value.serialize(ser)
+ }
+
+ fn serialize_unit(self) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_unit()
+ }
+
+ fn serialize_unit_struct(self, name: &'static str) -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_unit_struct(name)
+ }
+
+ fn serialize_unit_variant(self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str)
+ -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_unit_variant(name, variant_index, variant)
+ }
+
+ fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(self,
+ name: &'static str,
+ value: &T)
+ -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_newtype_struct(name, value)
+ }
+
+ fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ value: &T)
+ -> Result<(), Self::Error> {
+ self.use_ser()?.serialize_newtype_variant(name, variant_index, variant, value)
+ }
+
+ fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ self.use_ser()?.serialize_seq(len)
+ }
+
+ fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ self.use_ser()?.serialize_tuple(len)
+ }
+
+ fn serialize_tuple_struct(self,
+ name: &'static str,
+ len: usize)
+ -> Result<Self::SerializeTupleStruct, Self::Error> {
+ self.use_ser()?.serialize_tuple_struct(name, len)
+ }
+
+ fn serialize_tuple_variant(self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize)
+ -> Result<Self::SerializeTupleVariant, Self::Error> {
+ self.use_ser()?.serialize_tuple_variant(name, variant_index, variant, len)
+ }
+
+ fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ self.use_ser()?.serialize_map(len)
+ }
+
+ fn serialize_struct(self,
+ name: &'static str,
+ len: usize)
+ -> Result<Self::SerializeStruct, Self::Error> {
+ self.use_ser()?.serialize_struct(name, len)
+ }
+
+ fn serialize_struct_variant(self,
+ name: &'static str,
+ variant_index: u32,
+ variant: &'static str,
+ len: usize)
+ -> Result<Self::SerializeStructVariant, Self::Error> {
+ self.use_ser()?.serialize_struct_variant(name, variant_index, variant, len)
+ }
+}
+
+struct DateSerializer<'a, W: 'a + EventWriter> {
+ ser: &'a mut Serializer<W>,
+}
+
+impl<'a, W: EventWriter> DateSerializer<'a, W> {
+ fn expecting_date_error(&self) -> Error {
+ ser::Error::custom("plist date string expected")
+ }
+}
+
+impl<'a, W: EventWriter> ser::Serializer for DateSerializer<'a, W> {
+ type Ok = ();
+ type Error = Error;
+
+ type SerializeSeq = ser::Impossible<(), Error>;
+ type SerializeTuple = ser::Impossible<(), Error>;
+ type SerializeTupleStruct = ser::Impossible<(), Error>;
+ type SerializeTupleVariant = ser::Impossible<(), Error>;
+ type SerializeMap = ser::Impossible<(), Error>;
+ type SerializeStruct = ser::Impossible<(), Error>;
+ type SerializeStructVariant = ser::Impossible<(), Error>;
+
+ fn serialize_bool(self, _: bool) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_i8(self, _: i8) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_i16(self, _: i16) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_i32(self, _: i32) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_i64(self, _: i64) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_u8(self, _: u8) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_u16(self, _: u16) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_u32(self, _: u32) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_u64(self, _: u64) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_f32(self, _: f32) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_f64(self, _: f64) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_char(self, _: char) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_str(self, v: &str) -> Result<(), Self::Error> {
+ let date = Date::from_str(v).map_err(|_| self.expecting_date_error())?;
+ self.ser.emit(PlistEvent::DateValue(date))
+ }
+
+ fn serialize_bytes(self, _: &[u8]) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_none(self) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_some<T: ?Sized + ser::Serialize>(self, _: &T) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_unit(self) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_unit_struct(self, _: &'static str) -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_unit_variant(self,
+ _: &'static str,
+ _: u32,
+ _: &'static str)
+ -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_newtype_struct<T: ?Sized + ser::Serialize>(self,
+ _: &'static str,
+ _: &T)
+ -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_newtype_variant<T: ?Sized + ser::Serialize>(self,
+ _: &'static str,
+ _: u32,
+ _: &'static str,
+ _: &T)
+ -> Result<(), Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple, Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_tuple_struct(self,
+ _: &'static str,
+ _: usize)
+ -> Result<Self::SerializeTupleStruct, Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_tuple_variant(self,
+ _: &'static str,
+ _: u32,
+ _: &'static str,
+ _: usize)
+ -> Result<Self::SerializeTupleVariant, Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_map(self, _: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_struct(self,
+ _: &'static str,
+ _: usize)
+ -> Result<Self::SerializeStruct, Self::Error> {
+ Err(self.expecting_date_error())
+ }
+
+ fn serialize_struct_variant(self,
+ _: &'static str,
+ _: u32,
+ _: &'static str,
+ _: usize)
+ -> Result<Self::SerializeStructVariant, Self::Error> {
+ Err(self.expecting_date_error())
+ }
+}
+
#[doc(hidden)]
pub struct Compound<'a, W: 'a + EventWriter> {
ser: &'a mut Serializer<W>,
@@ -344,10 +644,12 @@ impl<'a, W: EventWriter> ser::SerializeStruct for Compound<'a, W> {
key: &'static str,
value: &T)
-> Result<(), Self::Error> {
- // Don't write a dict for None if the Option is a struct field.
- // TODO: This is fragile. Use distinct types instead.
- self.ser.maybe_option_field_name = Some(key);
- value.serialize(&mut *self.ser)
+ // We don't want to serialize None if the Option is a struct field as this is how null
+ // fields are represented in plists.
+ value.serialize(StructFieldSerializer {
+ field_name: key,
+ ser: &mut *self.ser,
+ })
}
fn end(self) -> Result<Self::Ok, Self::Error> {