aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEdward Barnard2018-05-17 20:30:41 +0100
committerEdward Barnard2018-05-17 20:50:21 +0100
commit2af279c344a6a917ce4102fec82e6cba8cf8b37c (patch)
treea2d3746d4981e8e22e30b91fd3b4d1821444777a
parentd8a4f4ef2a0e80f1dc6237678410807cce83cce0 (diff)
downloadrust-plist-2af279c344a6a917ce4102fec82e6cba8cf8b37c.tar.bz2
Reorganise crate.
-rw-r--r--src/binary/mod.rs3
-rw-r--r--src/builder.rs62
-rw-r--r--src/date.rs4
-rw-r--r--src/de.rs (renamed from src/serde/de.rs)86
-rw-r--r--src/events/binary_reader.rs (renamed from src/binary/reader.rs)73
-rw-r--r--src/events/mod.rs95
-rw-r--r--src/events/xml_reader.rs (renamed from src/xml/reader.rs)72
-rw-r--r--src/events/xml_writer.rs (renamed from src/xml/writer.rs)66
-rw-r--r--src/lib.rs111
-rw-r--r--src/plist.rs376
-rw-r--r--src/ser.rs (renamed from src/serde/ser.rs)86
-rw-r--r--src/serde/mod.rs25
-rw-r--r--src/value.rs377
-rw-r--r--src/xml/mod.rs5
-rw-r--r--tests/fuzzer.rs6
-rw-r--r--tests/serde_tests/mod.rs31
16 files changed, 737 insertions, 741 deletions
diff --git a/src/binary/mod.rs b/src/binary/mod.rs
deleted file mode 100644
index 7c9ae75..0000000
--- a/src/binary/mod.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-mod reader;
-
-pub use self::reader::EventReader;
diff --git a/src/builder.rs b/src/builder.rs
index 6f448e8..8cd580e 100644
--- a/src/builder.rs
+++ b/src/builder.rs
@@ -1,13 +1,14 @@
use std::collections::BTreeMap;
-use {Error, Plist, PlistEvent, Result, u64_option_to_usize};
+use events::Event;
+use {u64_option_to_usize, Error, Result, Value};
pub struct Builder<T> {
stream: T,
- token: Option<PlistEvent>,
+ token: Option<Event>,
}
-impl<T: Iterator<Item = Result<PlistEvent>>> Builder<T> {
+impl<T: Iterator<Item = Result<Event>>> Builder<T> {
pub fn new(stream: T) -> Builder<T> {
Builder {
stream: stream,
@@ -15,7 +16,7 @@ impl<T: Iterator<Item = Result<PlistEvent>>> Builder<T> {
}
}
- pub fn build(mut self) -> Result<Plist> {
+ pub fn build(mut self) -> Result<Value> {
self.bump()?;
let plist = self.build_value()?;
@@ -37,27 +38,27 @@ impl<T: Iterator<Item = Result<PlistEvent>>> Builder<T> {
Ok(())
}
- fn build_value(&mut self) -> Result<Plist> {
+ fn build_value(&mut self) -> Result<Value> {
match self.token.take() {
- Some(PlistEvent::StartArray(len)) => Ok(Plist::Array(self.build_array(len)?)),
- Some(PlistEvent::StartDictionary(len)) => Ok(Plist::Dictionary(self.build_dict(len)?)),
+ Some(Event::StartArray(len)) => Ok(Value::Array(self.build_array(len)?)),
+ Some(Event::StartDictionary(len)) => Ok(Value::Dictionary(self.build_dict(len)?)),
- Some(PlistEvent::BooleanValue(b)) => Ok(Plist::Boolean(b)),
- Some(PlistEvent::DataValue(d)) => Ok(Plist::Data(d)),
- Some(PlistEvent::DateValue(d)) => Ok(Plist::Date(d)),
- Some(PlistEvent::IntegerValue(i)) => Ok(Plist::Integer(i)),
- Some(PlistEvent::RealValue(f)) => Ok(Plist::Real(f)),
- Some(PlistEvent::StringValue(s)) => Ok(Plist::String(s)),
+ Some(Event::BooleanValue(b)) => Ok(Value::Boolean(b)),
+ Some(Event::DataValue(d)) => Ok(Value::Data(d)),
+ Some(Event::DateValue(d)) => Ok(Value::Date(d)),
+ Some(Event::IntegerValue(i)) => Ok(Value::Integer(i)),
+ Some(Event::RealValue(f)) => Ok(Value::Real(f)),
+ Some(Event::StringValue(s)) => Ok(Value::String(s)),
- Some(PlistEvent::EndArray) => Err(Error::InvalidData),
- Some(PlistEvent::EndDictionary) => Err(Error::InvalidData),
+ Some(Event::EndArray) => Err(Error::InvalidData),
+ Some(Event::EndDictionary) => Err(Error::InvalidData),
// The stream should not have ended here
None => Err(Error::InvalidData),
}
}
- fn build_array(&mut self, len: Option<u64>) -> Result<Vec<Plist>> {
+ fn build_array(&mut self, len: Option<u64>) -> Result<Vec<Value>> {
let len = u64_option_to_usize(len)?;
let mut values = match len {
Some(len) => Vec::with_capacity(len),
@@ -66,7 +67,7 @@ impl<T: Iterator<Item = Result<PlistEvent>>> Builder<T> {
loop {
self.bump()?;
- if let Some(PlistEvent::EndArray) = self.token {
+ if let Some(Event::EndArray) = self.token {
self.token.take();
return Ok(values);
}
@@ -74,14 +75,14 @@ impl<T: Iterator<Item = Result<PlistEvent>>> Builder<T> {
}
}
- fn build_dict(&mut self, _len: Option<u64>) -> Result<BTreeMap<String, Plist>> {
+ fn build_dict(&mut self, _len: Option<u64>) -> Result<BTreeMap<String, Value>> {
let mut values = BTreeMap::new();
loop {
self.bump()?;
match self.token.take() {
- Some(PlistEvent::EndDictionary) => return Ok(values),
- Some(PlistEvent::StringValue(s)) => {
+ Some(Event::EndDictionary) => return Ok(values),
+ Some(Event::StringValue(s)) => {
self.bump()?;
values.insert(s, self.build_value()?);
}
@@ -99,14 +100,12 @@ mod tests {
use std::collections::BTreeMap;
use super::*;
- use Plist;
+ use events::Event::*;
+ use Value;
#[test]
fn builder() {
- use PlistEvent::*;
-
// Input
-
let events = vec![
StartDictionary(None),
StringValue("Author".to_owned()),
@@ -127,22 +126,21 @@ mod tests {
let plist = builder.build();
// Expected output
-
let mut lines = Vec::new();
- lines.push(Plist::String("It is a tale told by an idiot,".to_owned()));
- lines.push(Plist::String(
+ lines.push(Value::String("It is a tale told by an idiot,".to_owned()));
+ lines.push(Value::String(
"Full of sound and fury, signifying nothing.".to_owned(),
));
let mut dict = BTreeMap::new();
dict.insert(
"Author".to_owned(),
- Plist::String("William Shakespeare".to_owned()),
+ Value::String("William Shakespeare".to_owned()),
);
- dict.insert("Lines".to_owned(), Plist::Array(lines));
- dict.insert("Birthdate".to_owned(), Plist::Integer(1564));
- dict.insert("Height".to_owned(), Plist::Real(1.60));
+ dict.insert("Lines".to_owned(), Value::Array(lines));
+ dict.insert("Birthdate".to_owned(), Value::Integer(1564));
+ dict.insert("Height".to_owned(), Value::Real(1.60));
- assert_eq!(plist.unwrap(), Plist::Dictionary(dict));
+ assert_eq!(plist.unwrap(), Value::Dictionary(dict));
}
}
diff --git a/src/date.rs b/src/date.rs
index 509dfac..3c83c9b 100644
--- a/src/date.rs
+++ b/src/date.rs
@@ -70,8 +70,8 @@ impl Into<SystemTime> for Date {
#[cfg(feature = "serde")]
pub mod serde_impls {
- use serde_base::de::{Deserialize, Deserializer, Error, Unexpected, Visitor};
- use serde_base::ser::{Serialize, Serializer};
+ use serde::de::{Deserialize, Deserializer, Error, Unexpected, Visitor};
+ use serde::ser::{Serialize, Serializer};
use std::fmt;
use Date;
diff --git a/src/serde/de.rs b/src/de.rs
index 58e0973..148b7b7 100644
--- a/src/serde/de.rs
+++ b/src/de.rs
@@ -1,8 +1,10 @@
-use serde_base::de;
+use serde::de;
use std::fmt::Display;
+use std::io::{Read, Seek};
use std::iter::Peekable;
-use {Error, PlistEvent, u64_option_to_usize};
+use events::{self, Event};
+use {u64_option_to_usize, Error};
macro_rules! expect {
($next:expr, $pat:pat) => {
@@ -43,14 +45,14 @@ impl de::Error for Error {
pub struct Deserializer<I>
where
- I: IntoIterator<Item = Result<PlistEvent, Error>>,
+ I: IntoIterator<Item = Result<Event, Error>>,
{
events: Peekable<<I as IntoIterator>::IntoIter>,
}
impl<I> Deserializer<I>
where
- I: IntoIterator<Item = Result<PlistEvent, Error>>,
+ I: IntoIterator<Item = Result<Event, Error>>,
{
pub fn new(iter: I) -> Deserializer<I> {
Deserializer {
@@ -61,7 +63,7 @@ where
impl<'de, 'a, I> de::Deserializer<'de> for &'a mut Deserializer<I>
where
- I: IntoIterator<Item = Result<PlistEvent, Error>>,
+ I: IntoIterator<Item = Result<Event, Error>>,
{
type Error = Error;
@@ -70,29 +72,29 @@ where
V: de::Visitor<'de>,
{
match try_next!(self.events.next()) {
- PlistEvent::StartArray(len) => {
+ Event::StartArray(len) => {
let len = u64_option_to_usize(len)?;
let ret = visitor.visit_seq(MapAndSeqAccess::new(self, false, len))?;
- expect!(self.events.next(), PlistEvent::EndArray);
+ expect!(self.events.next(), Event::EndArray);
Ok(ret)
}
- PlistEvent::EndArray => Err(event_mismatch_error()),
+ Event::EndArray => Err(event_mismatch_error()),
- PlistEvent::StartDictionary(len) => {
+ Event::StartDictionary(len) => {
let len = u64_option_to_usize(len)?;
let ret = visitor.visit_map(MapAndSeqAccess::new(self, false, len))?;
- expect!(self.events.next(), PlistEvent::EndDictionary);
+ expect!(self.events.next(), Event::EndDictionary);
Ok(ret)
}
- PlistEvent::EndDictionary => Err(event_mismatch_error()),
-
- 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),
+ 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),
}
}
@@ -106,7 +108,7 @@ where
where
V: de::Visitor<'de>,
{
- expect!(self.events.next(), PlistEvent::StringValue(_));
+ expect!(self.events.next(), Event::StringValue(_));
visitor.visit_unit()
}
@@ -114,18 +116,18 @@ where
where
V: de::Visitor<'de>,
{
- expect!(self.events.next(), PlistEvent::StartDictionary(_));
+ expect!(self.events.next(), Event::StartDictionary(_));
let ret = match try_next!(self.events.next()) {
- PlistEvent::StringValue(ref s) if &s[..] == "None" => {
- expect!(self.events.next(), PlistEvent::StringValue(_));
+ Event::StringValue(ref s) if &s[..] == "None" => {
+ expect!(self.events.next(), Event::StringValue(_));
visitor.visit_none::<Self::Error>()?
}
- PlistEvent::StringValue(ref s) if &s[..] == "Some" => visitor.visit_some(&mut *self)?,
+ Event::StringValue(ref s) if &s[..] == "Some" => visitor.visit_some(&mut *self)?,
_ => return Err(event_mismatch_error()),
};
- expect!(self.events.next(), PlistEvent::EndDictionary);
+ expect!(self.events.next(), Event::EndDictionary);
Ok(ret)
}
@@ -150,9 +152,9 @@ where
where
V: de::Visitor<'de>,
{
- expect!(self.events.next(), PlistEvent::StartDictionary(_));
+ expect!(self.events.next(), Event::StartDictionary(_));
let ret = visitor.visit_map(MapAndSeqAccess::new(self, true, None))?;
- expect!(self.events.next(), PlistEvent::EndDictionary);
+ expect!(self.events.next(), Event::EndDictionary);
Ok(ret)
}
@@ -165,16 +167,16 @@ where
where
V: de::Visitor<'de>,
{
- expect!(self.events.next(), PlistEvent::StartDictionary(_));
+ expect!(self.events.next(), Event::StartDictionary(_));
let ret = visitor.visit_enum(&mut *self)?;
- expect!(self.events.next(), PlistEvent::EndDictionary);
+ 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<PlistEvent, Error>>,
+ I: IntoIterator<Item = Result<Event, Error>>,
{
type Error = Error;
type Variant = Self;
@@ -189,7 +191,7 @@ where
impl<'de, 'a, I> de::VariantAccess<'de> for &'a mut Deserializer<I>
where
- I: IntoIterator<Item = Result<PlistEvent, Error>>,
+ I: IntoIterator<Item = Result<Event, Error>>,
{
type Error = Error;
@@ -226,14 +228,14 @@ where
pub struct StructValueDeserializer<'a, I: 'a>
where
- I: IntoIterator<Item = Result<PlistEvent, Error>>,
+ 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<PlistEvent, Error>>,
+ I: IntoIterator<Item = Result<Event, Error>>,
{
type Error = Error;
@@ -303,7 +305,7 @@ where
struct MapAndSeqAccess<'a, I>
where
- I: 'a + IntoIterator<Item = Result<PlistEvent, Error>>,
+ I: 'a + IntoIterator<Item = Result<Event, Error>>,
{
de: &'a mut Deserializer<I>,
is_struct: bool,
@@ -312,7 +314,7 @@ where
impl<'a, I> MapAndSeqAccess<'a, I>
where
- I: 'a + IntoIterator<Item = Result<PlistEvent, Error>>,
+ I: 'a + IntoIterator<Item = Result<Event, Error>>,
{
fn new(
de: &'a mut Deserializer<I>,
@@ -329,7 +331,7 @@ where
impl<'de, 'a, I> de::SeqAccess<'de> for MapAndSeqAccess<'a, I>
where
- I: 'a + IntoIterator<Item = Result<PlistEvent, Error>>,
+ I: 'a + IntoIterator<Item = Result<Event, Error>>,
{
type Error = Error;
@@ -337,7 +339,7 @@ where
where
T: de::DeserializeSeed<'de>,
{
- if let Some(&Ok(PlistEvent::EndArray)) = self.de.events.peek() {
+ if let Some(&Ok(Event::EndArray)) = self.de.events.peek() {
return Ok(None);
}
@@ -352,7 +354,7 @@ where
impl<'de, 'a, I> de::MapAccess<'de> for MapAndSeqAccess<'a, I>
where
- I: 'a + IntoIterator<Item = Result<PlistEvent, Error>>,
+ I: 'a + IntoIterator<Item = Result<Event, Error>>,
{
type Error = Error;
@@ -360,7 +362,7 @@ where
where
K: de::DeserializeSeed<'de>,
{
- if let Some(&Ok(PlistEvent::EndDictionary)) = self.de.events.peek() {
+ if let Some(&Ok(Event::EndDictionary)) = self.de.events.peek() {
return Ok(None);
}
@@ -383,3 +385,9 @@ where
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)
+}
diff --git a/src/binary/reader.rs b/src/events/binary_reader.rs
index bee34f7..e077904 100644
--- a/src/binary/reader.rs
+++ b/src/events/binary_reader.rs
@@ -3,7 +3,8 @@ use std::io::{Read, Seek, SeekFrom};
use std::mem::size_of;
use std::string::{FromUtf16Error, FromUtf8Error};
-use {Date, Error, PlistEvent, Result, u64_to_usize};
+use events::Event;
+use {u64_to_usize, Date, Error, Result};
impl From<FromUtf8Error> for Error {
fn from(_: FromUtf8Error) -> Error {
@@ -30,7 +31,7 @@ enum StackType {
/// https://opensource.apple.com/source/CF/CF-550/CFBinaryPList.c
/// https://hg.python.org/cpython/file/3.4/Lib/plistlib.py
-pub struct EventReader<R> {
+pub struct BinaryReader<R> {
stack: Vec<StackItem>,
object_offsets: Vec<u64>,
reader: R,
@@ -48,9 +49,9 @@ pub struct EventReader<R> {
current_objects: usize,
}
-impl<R: Read + Seek> EventReader<R> {
- pub fn new(reader: R) -> EventReader<R> {
- EventReader {
+impl<R: Read + Seek> BinaryReader<R> {
+ pub fn new(reader: R) -> BinaryReader<R> {
+ BinaryReader {
stack: Vec::new(),
object_offsets: Vec::new(),
reader: reader,
@@ -165,13 +166,14 @@ impl<R: Read + Seek> EventReader<R> {
fn seek_to_object(&mut self, object_ref: u64) -> Result<u64> {
let object_ref = u64_to_usize(object_ref)?;
- let offset = *self.object_offsets
+ let offset = *self
+ .object_offsets
.get(object_ref)
.ok_or(Error::InvalidData)?;
Ok(self.reader.seek(SeekFrom::Start(offset))?)
}
- fn read_next(&mut self) -> Result<Option<PlistEvent>> {
+ fn read_next(&mut self) -> Result<Option<Event>> {
if self.ref_size == 0 {
// Initialise here rather than in new
self.read_trailer()?;
@@ -195,8 +197,8 @@ impl<R: Read + Seek> EventReader<R> {
// We're at the end of an array or dict. Pop the top stack item and return
let item = self.stack.pop().unwrap();
match item.ty {
- StackType::Array => return Ok(Some(PlistEvent::EndArray)),
- StackType::Dict => return Ok(Some(PlistEvent::EndDictionary)),
+ StackType::Array => return Ok(Some(Event::EndArray)),
+ StackType::Dict => return Ok(Some(Event::EndDictionary)),
// We're at the end of the plist
StackType::Root => return Ok(None),
}
@@ -209,40 +211,40 @@ impl<R: Read + Seek> EventReader<R> {
let result = match (ty, size) {
(0x0, 0x00) => return Err(Error::InvalidData), // null
- (0x0, 0x08) => Some(PlistEvent::BooleanValue(false)),
- (0x0, 0x09) => Some(PlistEvent::BooleanValue(true)),
+ (0x0, 0x08) => Some(Event::BooleanValue(false)),
+ (0x0, 0x09) => Some(Event::BooleanValue(true)),
(0x0, 0x0f) => return Err(Error::InvalidData), // fill
- (0x1, 0) => Some(PlistEvent::IntegerValue(self.reader.read_u8()? as i64)),
- (0x1, 1) => Some(PlistEvent::IntegerValue(
- self.reader.read_u16::<BigEndian>()? as i64,
+ (0x1, 0) => Some(Event::IntegerValue(self.reader.read_u8()? as i64)),
+ (0x1, 1) => Some(Event::IntegerValue(
+ self.reader.read_u16::<BigEndian>()? as i64
)),
- (0x1, 2) => Some(PlistEvent::IntegerValue(
- self.reader.read_u32::<BigEndian>()? as i64,
+ (0x1, 2) => Some(Event::IntegerValue(
+ self.reader.read_u32::<BigEndian>()? as i64
)),
- (0x1, 3) => Some(PlistEvent::IntegerValue(self.reader.read_i64::<BigEndian>()?)),
+ (0x1, 3) => Some(Event::IntegerValue(self.reader.read_i64::<BigEndian>()?)),
(0x1, 4) => return Err(Error::InvalidData), // 128 bit int
(0x1, _) => return Err(Error::InvalidData), // variable length int
- (0x2, 2) => Some(PlistEvent::RealValue(self.reader.read_f32::<BigEndian>()? as f64)),
- (0x2, 3) => Some(PlistEvent::RealValue(self.reader.read_f64::<BigEndian>()?)),
+ (0x2, 2) => Some(Event::RealValue(self.reader.read_f32::<BigEndian>()? as f64)),
+ (0x2, 3) => Some(Event::RealValue(self.reader.read_f64::<BigEndian>()?)),
(0x2, _) => return Err(Error::InvalidData), // odd length float
(0x3, 3) => {
// Date. Seconds since 1/1/2001 00:00:00.
let secs = self.reader.read_f64::<BigEndian>()?;
- Some(PlistEvent::DateValue(Date::from_seconds_since_plist_epoch(
+ Some(Event::DateValue(Date::from_seconds_since_plist_epoch(
secs,
)?))
}
(0x4, n) => {
// Data
let len = self.read_object_len(n)?;
- Some(PlistEvent::DataValue(self.read_data(len)?))
+ Some(Event::DataValue(self.read_data(len)?))
}
(0x5, n) => {
// ASCII string
let len = self.read_object_len(n)?;
let raw = self.read_data(len)?;
let string = String::from_utf8(raw)?;
- Some(PlistEvent::StringValue(string))
+ Some(Event::StringValue(string))
}
(0x6, n) => {
// UTF-16 string
@@ -254,7 +256,7 @@ impl<R: Read + Seek> EventReader<R> {
}
let string = String::from_utf16(&raw_utf16)?;
- Some(PlistEvent::StringValue(string))
+ Some(Event::StringValue(string))
}
(0xa, n) => {
// Array
@@ -268,7 +270,7 @@ impl<R: Read + Seek> EventReader<R> {
object_refs: object_refs,
});
- Some(PlistEvent::StartArray(Some(len)))
+ Some(Event::StartArray(Some(len)))
}
(0xd, n) => {
// Dict
@@ -289,7 +291,7 @@ impl<R: Read + Seek> EventReader<R> {
object_refs: object_refs,
});
- Some(PlistEvent::StartDictionary(Some(len as u64)))
+ Some(Event::StartDictionary(Some(len as u64)))
}
(_, _) => return Err(Error::InvalidData),
};
@@ -303,10 +305,10 @@ impl<R: Read + Seek> EventReader<R> {
}
}
-impl<R: Read + Seek> Iterator for EventReader<R> {
- type Item = Result<PlistEvent>;
+impl<R: Read + Seek> Iterator for BinaryReader<R> {
+ type Item = Result<Event>;
- fn next(&mut self) -> Option<Result<PlistEvent>> {
+ fn next(&mut self) -> Option<Result<Event>> {
if self.finished {
None
} else {
@@ -332,15 +334,14 @@ mod tests {
use std::path::Path;
use super::*;
- use PlistEvent;
+ use events::Event;
+ use events::Event::*;
#[test]
fn streaming_parser() {
- use PlistEvent::*;
-
let reader = File::open(&Path::new("./tests/data/binary.plist")).unwrap();
- let streaming_parser = EventReader::new(reader);
- let events: Vec<PlistEvent> = streaming_parser.map(|e| e.unwrap()).collect();
+ let streaming_parser = BinaryReader::new(reader);
+ let events: Vec<Event> = streaming_parser.map(|e| e.unwrap()).collect();
let comparison = &[
StartDictionary(Some(6)),
@@ -367,11 +368,9 @@ mod tests {
#[test]
fn utf16_plist() {
- use PlistEvent::*;
-
let reader = File::open(&Path::new("./tests/data/utf16_bplist.plist")).unwrap();
- let streaming_parser = EventReader::new(reader);
- let mut events: Vec<PlistEvent> = streaming_parser.map(|e| e.unwrap()).collect();
+ let streaming_parser = BinaryReader::new(reader);
+ let mut events: Vec<Event> = streaming_parser.map(|e| e.unwrap()).collect();
assert_eq!(events[2], StringValue("\u{2605} or better".to_owned()));
diff --git a/src/events/mod.rs b/src/events/mod.rs
new file mode 100644
index 0000000..b933ceb
--- /dev/null
+++ b/src/events/mod.rs
@@ -0,0 +1,95 @@
+mod binary_reader;
+pub use self::binary_reader::BinaryReader;
+
+mod xml_reader;
+pub use self::xml_reader::XmlReader;
+
+mod xml_writer;
+pub use self::xml_writer::XmlWriter;
+
+use std::io::{Read, Seek, SeekFrom};
+use {Date, Result};
+
+/// An encoding of a plist as a flat structure.
+///
+/// Output by the event readers.
+///
+/// Dictionary keys and values are represented as pairs of values e.g.:
+///
+/// ```ignore rust
+/// StartDictionary
+/// StringValue("Height") // Key
+/// RealValue(181.2) // Value
+/// StringValue("Age") // Key
+/// IntegerValue(28) // Value
+/// EndDictionary
+/// ```
+#[derive(Clone, Debug, PartialEq)]
+pub enum Event {
+ // While the length of an array or dict cannot be feasably greater than max(usize) this better
+ // conveys the concept of an effectively unbounded event stream.
+ StartArray(Option<u64>),
+ EndArray,
+
+ StartDictionary(Option<u64>),
+ EndDictionary,
+
+ BooleanValue(bool),
+ DataValue(Vec<u8>),
+ DateValue(Date),
+ IntegerValue(i64),
+ RealValue(f64),
+ StringValue(String),
+}
+
+pub struct Reader<R: Read + Seek>(ReaderInner<R>);
+
+enum ReaderInner<R: Read + Seek> {
+ Uninitialized(Option<R>),
+ Xml(XmlReader<R>),
+ Binary(BinaryReader<R>),
+}
+
+impl<R: Read + Seek> Reader<R> {
+ pub fn new(reader: R) -> Reader<R> {
+ Reader(ReaderInner::Uninitialized(Some(reader)))
+ }
+
+ fn is_binary(reader: &mut R) -> Result<bool> {
+ reader.seek(SeekFrom::Start(0))?;
+ let mut magic = [0; 8];
+ reader.read_exact(&mut magic)?;
+ reader.seek(SeekFrom::Start(0))?;
+
+ Ok(&magic == b"bplist00")
+ }
+}
+
+impl<R: Read + Seek> Iterator for Reader<R> {
+ type Item = Result<Event>;
+
+ fn next(&mut self) -> Option<Result<Event>> {
+ let mut reader = match self.0 {
+ ReaderInner::Xml(ref mut parser) => return parser.next(),
+ ReaderInner::Binary(ref mut parser) => return parser.next(),
+ ReaderInner::Uninitialized(ref mut reader) => reader.take().unwrap(),
+ };
+
+ let event_reader = match Reader::is_binary(&mut reader) {
+ Ok(true) => ReaderInner::Binary(BinaryReader::new(reader)),
+ Ok(false) => ReaderInner::Xml(XmlReader::new(reader)),
+ Err(err) => {
+ ::std::mem::replace(&mut self.0, ReaderInner::Uninitialized(Some(reader)));
+ return Some(Err(err));
+ }
+ };
+
+ ::std::mem::replace(&mut self.0, event_reader);
+
+ self.next()
+ }
+}
+
+pub trait Writer {
+ fn write(&mut self, event: &Event) -> Result<()>;
+}
diff --git a/src/xml/reader.rs b/src/events/xml_reader.rs
index 6642d59..46e0062 100644
--- a/src/xml/reader.rs
+++ b/src/events/xml_reader.rs
@@ -1,19 +1,20 @@
use base64;
use std::io::Read;
use std::str::FromStr;
-use xml_rs::reader::{EventReader as XmlEventReader, ParserConfig, XmlEvent};
+use xml_rs::reader::{EventReader, ParserConfig, XmlEvent};
-use {Date, Error, PlistEvent, Result};
+use events::Event;
+use {Date, Error, Result};
-pub struct EventReader<R: Read> {
- xml_reader: XmlEventReader<R>,
+pub struct XmlReader<R: Read> {
+ xml_reader: EventReader<R>,
queued_event: Option<XmlEvent>,
element_stack: Vec<String>,
finished: bool,
}
-impl<R: Read> EventReader<R> {
- pub fn new(reader: R) -> EventReader<R> {
+impl<R: Read> XmlReader<R> {
+ pub fn new(reader: R) -> XmlReader<R> {
let config = ParserConfig::new()
.trim_whitespace(false)
.whitespace_to_characters(true)
@@ -21,17 +22,17 @@ impl<R: Read> EventReader<R> {
.ignore_comments(true)
.coalesce_characters(true);
- EventReader {
- xml_reader: XmlEventReader::new_with_config(reader, config),
+ XmlReader {
+ xml_reader: EventReader::new_with_config(reader, config),
queued_event: None,
element_stack: Vec::new(),
finished: false,
}
}
- fn read_content<F>(&mut self, f: F) -> Result<PlistEvent>
+ fn read_content<F>(&mut self, f: F) -> Result<Event>
where
- F: FnOnce(String) -> Result<PlistEvent>,
+ F: FnOnce(String) -> Result<Event>,
{
match self.xml_reader.next() {
Ok(XmlEvent::Characters(s)) => f(s),
@@ -51,7 +52,7 @@ impl<R: Read> EventReader<R> {
}
}
- fn read_next(&mut self) -> Option<Result<PlistEvent>> {
+ fn read_next(&mut self) -> Option<Result<Event>> {
loop {
match self.next_event() {
Ok(XmlEvent::StartElement { name, .. }) => {
@@ -60,38 +61,38 @@ impl<R: Read> EventReader<R> {
match &name.local_name[..] {
"plist" => (),
- "array" => return Some(Ok(PlistEvent::StartArray(None))),
- "dict" => return Some(Ok(PlistEvent::StartDictionary(None))),
- "key" => return Some(self.read_content(|s| Ok(PlistEvent::StringValue(s)))),
- "true" => return Some(Ok(PlistEvent::BooleanValue(true))),
- "false" => return Some(Ok(PlistEvent::BooleanValue(false))),
+ "array" => return Some(Ok(Event::StartArray(None))),
+ "dict" => return Some(Ok(Event::StartDictionary(None))),
+ "key" => return Some(self.read_content(|s| Ok(Event::StringValue(s)))),
+ "true" => return Some(Ok(Event::BooleanValue(true))),
+ "false" => return Some(Ok(Event::BooleanValue(false))),
"data" => {
return Some(self.read_content(|s| {
let data = base64::decode_config(&s, base64::MIME)
.map_err(|_| Error::InvalidData)?;
- Ok(PlistEvent::DataValue(data))
+ Ok(Event::DataValue(data))
}))
}
"date" => {
- return Some(self.read_content(|s| {
- Ok(PlistEvent::DateValue(Date::from_rfc3339(&s)?))
- }))
+ return Some(
+ self.read_content(|s| {
+ Ok(Event::DateValue(Date::from_rfc3339(&s)?))
+ }),
+ )
}
"integer" => {
return Some(self.read_content(|s| match FromStr::from_str(&s) {
- Ok(i) => Ok(PlistEvent::IntegerValue(i)),
+ Ok(i) => Ok(Event::IntegerValue(i)),
Err(_) => Err(Error::InvalidData),
}))
}
"real" => {
return Some(self.read_content(|s| match FromStr::from_str(&s) {
- Ok(f) => Ok(PlistEvent::RealValue(f)),
+ Ok(f) => Ok(Event::RealValue(f)),
Err(_) => Err(Error::InvalidData),
}))
}
- "string" => {
- return Some(self.read_content(|s| Ok(PlistEvent::StringValue(s))))
- }
+ "string" => return Some(self.read_content(|s| Ok(Event::StringValue(s)))),
_ => return Some(Err(Error::InvalidData)),
}
}
@@ -104,8 +105,8 @@ impl<R: Read> EventReader<R> {
}
match &name.local_name[..] {
- "array" => return Some(Ok(PlistEvent::EndArray)),
- "dict" => return Some(Ok(PlistEvent::EndDictionary)),
+ "array" => return Some(Ok(Event::EndArray)),
+ "dict" => return Some(Ok(Event::EndDictionary)),
"plist" => (),
_ => (),
}
@@ -124,10 +125,10 @@ impl<R: Read> EventReader<R> {
}
}
-impl<R: Read> Iterator for EventReader<R> {
- type Item = Result<PlistEvent>;
+impl<R: Read> Iterator for XmlReader<R> {
+ type Item = Result<Event>;
- fn next(&mut self) -> Option<Result<PlistEvent>> {
+ fn next(&mut self) -> Option<Result<Event>> {
if self.finished {
None
} else {
@@ -153,15 +154,14 @@ mod tests {
use std::path::Path;
use super::*;
- use PlistEvent;
+ use events::Event;
+ use events::Event::*;
#[test]
fn streaming_parser() {
- use PlistEvent::*;
-
let reader = File::open(&Path::new("./tests/data/xml.plist")).unwrap();
- let streaming_parser = EventReader::new(reader);
- let events: Vec<PlistEvent> = streaming_parser.map(|e| e.unwrap()).collect();
+ let streaming_parser = XmlReader::new(reader);
+ let events: Vec<Event> = streaming_parser.map(|e| e.unwrap()).collect();
let comparison = &[
StartDictionary(None),
@@ -191,7 +191,7 @@ mod tests {
#[test]
fn bad_data() {
let reader = File::open(&Path::new("./tests/data/xml_error.plist")).unwrap();
- let streaming_parser = EventReader::new(reader);
+ let streaming_parser = XmlReader::new(reader);
let events: Vec<_> = streaming_parser.collect();
assert!(events.last().unwrap().is_err());
diff --git a/src/xml/writer.rs b/src/events/xml_writer.rs
index e002e55..f89ea81 100644
--- a/src/xml/writer.rs
+++ b/src/events/xml_writer.rs
@@ -3,10 +3,10 @@ use std::borrow::Cow;
use std::io::Write;
use xml_rs::name::Name;
use xml_rs::namespace::Namespace;
-use xml_rs::writer::events::XmlEvent as WriteXmlEvent;
-use xml_rs::writer::{EmitterConfig, Error as XmlWriterError, EventWriter as XmlEventWriter};
+use xml_rs::writer::{EmitterConfig, Error as XmlWriterError, EventWriter, XmlEvent};
-use {Error, EventWriter as PlistEventWriter, PlistEvent, Result};
+use events::{Event, Writer};
+use {Error, Result};
impl From<XmlWriterError> for Error {
fn from(err: XmlWriterError) -> Error {
@@ -28,15 +28,15 @@ enum DictionaryState {
ExpectValue,
}
-pub struct EventWriter<W: Write> {
- xml_writer: XmlEventWriter<W>,
+pub struct XmlWriter<W: Write> {
+ xml_writer: EventWriter<W>,
stack: Vec<Element>,
// Not very nice
empty_namespace: Namespace,
}
-impl<W: Write> EventWriter<W> {
- pub fn new(writer: W) -> EventWriter<W> {
+impl<W: Write> XmlWriter<W> {
+ pub fn new(writer: W) -> XmlWriter<W> {
let config = EmitterConfig::new()
.line_separator("\n")
.indent_string("\t")
@@ -47,8 +47,8 @@ impl<W: Write> EventWriter<W> {
.keep_element_names_stack(false)
.autopad_comments(true);
- EventWriter {
- xml_writer: XmlEventWriter::new_with_config(writer, config),
+ XmlWriter {
+ xml_writer: EventWriter::new_with_config(writer, config),
stack: Vec::new(),
empty_namespace: Namespace::empty(),
}
@@ -62,7 +62,7 @@ impl<W: Write> EventWriter<W> {
}
fn start_element(&mut self, name: &str) -> Result<()> {
- self.xml_writer.write(WriteXmlEvent::StartElement {
+ self.xml_writer.write(XmlEvent::StartElement {
name: Name::local(name),
attributes: Cow::Borrowed(&[]),
namespace: Cow::Borrowed(&self.empty_namespace),
@@ -71,14 +71,14 @@ impl<W: Write> EventWriter<W> {
}
fn end_element(&mut self, name: &str) -> Result<()> {
- self.xml_writer.write(WriteXmlEvent::EndElement {
+ self.xml_writer.write(XmlEvent::EndElement {
name: Some(Name::local(name)),
})?;
Ok(())
}
fn write_value(&mut self, value: &str) -> Result<()> {
- self.xml_writer.write(WriteXmlEvent::Characters(value))?;
+ self.xml_writer.write(XmlEvent::Characters(value))?;
Ok(())
}
@@ -96,22 +96,22 @@ impl<W: Write> EventWriter<W> {
Ok(())
}
- pub fn write(&mut self, event: &PlistEvent) -> Result<()> {
- <Self as PlistEventWriter>::write(self, event)
+ pub fn write(&mut self, event: &Event) -> Result<()> {
+ <Self as Writer>::write(self, event)
}
}
-impl<W: Write> PlistEventWriter for EventWriter<W> {
- fn write(&mut self, event: &PlistEvent) -> Result<()> {
+impl<W: Write> Writer for XmlWriter<W> {
+ fn write(&mut self, event: &Event) -> Result<()> {
match self.stack.pop() {
Some(Element::Dictionary(DictionaryState::ExpectKey)) => {
match *event {
- PlistEvent::StringValue(ref value) => {
+ Event::StringValue(ref value) => {
self.write_element_and_value("key", &*value)?;
self.stack
.push(Element::Dictionary(DictionaryState::ExpectValue));
}
- PlistEvent::EndDictionary => {
+ Event::EndDictionary => {
self.end_element("dict")?;
// We might be closing the last tag here as well
self.maybe_end_plist()?;
@@ -120,7 +120,8 @@ impl<W: Write> PlistEventWriter for EventWriter<W> {
};
return Ok(());
}
- Some(Element::Dictionary(DictionaryState::ExpectValue)) => self.stack
+ Some(Element::Dictionary(DictionaryState::ExpectValue)) => self
+ .stack
.push(Element::Dictionary(DictionaryState::ExpectKey)),
Some(other) => self.stack.push(other),
None => {
@@ -136,11 +137,11 @@ impl<W: Write> PlistEventWriter for EventWriter<W> {
}
match *event {
- PlistEvent::StartArray(_) => {
+ Event::StartArray(_) => {
self.start_element("array")?;
self.stack.push(Element::Array);
}
- PlistEvent::EndArray => {
+ Event::EndArray => {
self.end_element("array")?;
if let Some(Element::Array) = self.stack.pop() {
} else {
@@ -148,35 +149,35 @@ impl<W: Write> PlistEventWriter for EventWriter<W> {
}
}
- PlistEvent::StartDictionary(_) => {
+ Event::StartDictionary(_) => {
self.start_element("dict")?;
self.stack
.push(Element::Dictionary(DictionaryState::ExpectKey));
}
- PlistEvent::EndDictionary => return Err(Error::InvalidData),
+ Event::EndDictionary => return Err(Error::InvalidData),
- PlistEvent::BooleanValue(true) => {
+ Event::BooleanValue(true) => {
self.start_element("true")?;
self.end_element("true")?;
}
- PlistEvent::BooleanValue(false) => {
+ Event::BooleanValue(false) => {
self.start_element("false")?;
self.end_element("false")?;
}
- PlistEvent::DataValue(ref value) => {
+ Event::DataValue(ref value) => {
let base64_data = base64::encode_config(&value, base64::MIME);
self.write_element_and_value("data", &base64_data)?;
}
- PlistEvent::DateValue(ref value) => {
+ Event::DateValue(ref value) => {
self.write_element_and_value("date", &value.to_rfc3339())?
}
- PlistEvent::IntegerValue(ref value) => {
+ Event::IntegerValue(ref value) => {
self.write_element_and_value("integer", &value.to_string())?
}
- PlistEvent::RealValue(ref value) => {
+ Event::RealValue(ref value) => {
self.write_element_and_value("real", &value.to_string())?
}
- PlistEvent::StringValue(ref value) => self.write_element_and_value("string", &*value)?,
+ Event::StringValue(ref value) => self.write_element_and_value("string", &*value)?,
};
self.maybe_end_plist()?;
@@ -191,11 +192,10 @@ mod tests {
use std::io::Cursor;
use super::*;
+ use events::Event::*;
#[test]
fn streaming_parser() {
- use PlistEvent::*;
-
let plist = &[
StartDictionary(None),
StringValue("Author".to_owned()),
@@ -221,7 +221,7 @@ mod tests {
let mut cursor = Cursor::new(Vec::new());
{
- let mut plist_w = EventWriter::new(&mut cursor);
+ let mut plist_w = XmlWriter::new(&mut cursor);
for item in plist {
plist_w.write(item).unwrap();
diff --git a/src/lib.rs b/src/lib.rs
index ddcce58..c129400 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -20,14 +20,14 @@
//! ## Examples
//!
//! ```rust
-//! use plist::Plist;
+//! use plist::Value;
//! use std::fs::File;
//!
//! let file = File::open("tests/data/xml.plist").unwrap();
-//! let plist = Plist::read(file).unwrap();
+//! let plist = Value::read(file).unwrap();
//!
//! match plist {
-//! Plist::Array(_array) => (),
+//! Value::Array(_array) => (),
//! _ => ()
//! }
//! ```
@@ -40,7 +40,7 @@
//!
//! # #[cfg(feature = "serde")]
//! # fn main() {
-//! use plist::serde::deserialize;
+//! use plist::deserialize;
//! use std::fs::File;
//!
//! #[derive(Deserialize)]
@@ -63,57 +63,30 @@ extern crate byteorder;
extern crate humantime;
extern crate xml as xml_rs;
-pub mod binary;
-pub mod xml;
+pub mod events;
mod builder;
mod date;
-mod plist;
+mod value;
pub use date::Date;
-pub use plist::Plist;
+pub use value::Value;
// Optional serde module
#[cfg(feature = "serde")]
#[macro_use]
-extern crate serde as serde_base;
+extern crate serde;
#[cfg(feature = "serde")]
-pub mod serde;
+mod de;
+#[cfg(feature = "serde")]
+mod ser;
+#[cfg(feature = "serde")]
+pub use self::de::{deserialize, Deserializer};
+#[cfg(feature = "serde")]
+pub use self::ser::{serialize_to_xml, Serializer};
use std::fmt;
-use std::io::{self, Read, Seek, SeekFrom};
-
-/// An encoding of a plist as a flat structure.
-///
-/// Output by the event readers.
-///
-/// Dictionary keys and values are represented as pairs of values e.g.:
-///
-/// ```ignore rust
-/// StartDictionary
-/// StringValue("Height") // Key
-/// RealValue(181.2) // Value
-/// StringValue("Age") // Key
-/// IntegerValue(28) // Value
-/// EndDictionary
-/// ```
-#[derive(Clone, Debug, PartialEq)]
-pub enum PlistEvent {
- // While the length of an array or dict cannot be feasably greater than max(usize) this better
- // conveys the concept of an effectively unbounded event stream.
- StartArray(Option<u64>),
- EndArray,
-
- StartDictionary(Option<u64>),
- EndDictionary,
-
- BooleanValue(bool),
- DataValue(Vec<u8>),
- DateValue(Date),
- IntegerValue(i64),
- RealValue(f64),
- StringValue(String),
-}
+use std::io;
type Result<T> = ::std::result::Result<T, Error>;
@@ -158,58 +131,6 @@ impl From<io::Error> for Error {
}
}
-pub struct EventReader<R: Read + Seek>(EventReaderInner<R>);
-
-enum EventReaderInner<R: Read + Seek> {
- Uninitialized(Option<R>),
- Xml(xml::EventReader<R>),
- Binary(binary::EventReader<R>),
-}
-
-impl<R: Read + Seek> EventReader<R> {
- pub fn new(reader: R) -> EventReader<R> {
- EventReader(EventReaderInner::Uninitialized(Some(reader)))
- }
-
- fn is_binary(reader: &mut R) -> Result<bool> {
- reader.seek(SeekFrom::Start(0))?;
- let mut magic = [0; 8];
- reader.read_exact(&mut magic)?;
- reader.seek(SeekFrom::Start(0))?;
-
- Ok(&magic == b"bplist00")
- }
-}
-
-impl<R: Read + Seek> Iterator for EventReader<R> {
- type Item = Result<PlistEvent>;
-
- fn next(&mut self) -> Option<Result<PlistEvent>> {
- let mut reader = match self.0 {
- EventReaderInner::Xml(ref mut parser) => return parser.next(),
- EventReaderInner::Binary(ref mut parser) => return parser.next(),
- EventReaderInner::Uninitialized(ref mut reader) => reader.take().unwrap(),
- };
-
- let event_reader = match EventReader::is_binary(&mut reader) {
- Ok(true) => EventReaderInner::Binary(binary::EventReader::new(reader)),
- Ok(false) => EventReaderInner::Xml(xml::EventReader::new(reader)),
- Err(err) => {
- ::std::mem::replace(&mut self.0, EventReaderInner::Uninitialized(Some(reader)));
- return Some(Err(err));
- }
- };
-
- ::std::mem::replace(&mut self.0, event_reader);
-
- self.next()
- }
-}
-
-pub trait EventWriter {
- fn write(&mut self, event: &PlistEvent) -> Result<()>;
-}
-
fn u64_to_usize(len_u64: u64) -> Result<usize> {
let len = len_u64 as usize;
if len as u64 != len_u64 {
diff --git a/src/plist.rs b/src/plist.rs
deleted file mode 100644
index f0646f5..0000000
--- a/src/plist.rs
+++ /dev/null
@@ -1,376 +0,0 @@
-use std::collections::BTreeMap;
-use std::io::{Read, Seek};
-
-use {builder, Date, EventReader, PlistEvent, Result};
-
-#[derive(Clone, Debug, PartialEq)]
-pub enum Plist {
- Array(Vec<Plist>),
- Dictionary(BTreeMap<String, Plist>),
- Boolean(bool),
- Data(Vec<u8>),
- Date(Date),
- Real(f64),
- Integer(i64),
- String(String),
-}
-
-impl Plist {
- pub fn read<R: Read + Seek>(reader: R) -> Result<Plist> {
- let reader = EventReader::new(reader);
- Plist::from_events(reader)
- }
-
- pub fn from_events<T>(events: T) -> Result<Plist>
- where
- T: IntoIterator<Item = Result<PlistEvent>>,
- {
- let iter = events.into_iter();
- let builder = builder::Builder::new(iter);
- builder.build()
- }
-
- pub fn into_events(self) -> Vec<PlistEvent> {
- let mut events = Vec::new();
- self.into_events_inner(&mut events);
- events
- }
-
- fn into_events_inner(self, events: &mut Vec<PlistEvent>) {
- match self {
- Plist::Array(array) => {
- events.push(PlistEvent::StartArray(Some(array.len() as u64)));
- for value in array {
- value.into_events_inner(events);
- }
- events.push(PlistEvent::EndArray);
- }
- Plist::Dictionary(dict) => {
- events.push(PlistEvent::StartDictionary(Some(dict.len() as u64)));
- for (key, value) in dict {
- events.push(PlistEvent::StringValue(key));
- value.into_events_inner(events);
- }
- events.push(PlistEvent::EndDictionary);
- }
- Plist::Boolean(value) => events.push(PlistEvent::BooleanValue(value)),
- Plist::Data(value) => events.push(PlistEvent::DataValue(value)),
- Plist::Date(value) => events.push(PlistEvent::DateValue(value)),
- Plist::Real(value) => events.push(PlistEvent::RealValue(value)),
- Plist::Integer(value) => events.push(PlistEvent::IntegerValue(value)),
- Plist::String(value) => events.push(PlistEvent::StringValue(value)),
- }
- }
-
- /// If the `Plist` is an Array, returns the associated Vec.
- /// Returns None otherwise.
- pub fn as_array(&self) -> Option<&Vec<Plist>> {
- match *self {
- Plist::Array(ref array) => Some(array),
- _ => None,
- }
- }
-
- /// If the `Plist` is an Array, returns the associated mutable Vec.
- /// Returns None otherwise.
- pub fn as_array_mut(&mut self) -> Option<&mut Vec<Plist>> {
- match *self {
- Plist::Array(ref mut array) => Some(array),
- _ => None,
- }
- }
-
- /// If the `Plist` is a Dictionary, returns the associated BTreeMap.
- /// Returns None otherwise.
- pub fn as_dictionary(&self) -> Option<&BTreeMap<String, Plist>> {
- match *self {
- Plist::Dictionary(ref map) => Some(map),
- _ => None,
- }
- }
-
- /// If the `Plist` is a Dictionary, returns the associated mutable BTreeMap.
- /// Returns None otherwise.
- pub fn as_dictionary_mut(&mut self) -> Option<&mut BTreeMap<String, Plist>> {
- match *self {
- Plist::Dictionary(ref mut map) => Some(map),
- _ => None,
- }
- }
-
- /// If the `Plist` is a Boolean, returns the associated bool.
- /// Returns None otherwise.
- pub fn as_boolean(&self) -> Option<bool> {
- match *self {
- Plist::Boolean(v) => Some(v),
- _ => None,
- }
- }
-
- /// If the `Plist` is a Data, returns the underlying Vec.
- /// Returns None otherwise.
- ///
- /// This method consumes the `Plist`. If this is not desired, please use
- /// `as_data` method.
- pub fn into_data(self) -> Option<Vec<u8>> {
- match self {
- Plist::Data(data) => Some(data),
- _ => None,
- }
- }
-
- /// If the `Plist` is a Data, returns the associated Vec.
- /// Returns None otherwise.
- pub fn as_data(&self) -> Option<&[u8]> {
- match *self {
- Plist::Data(ref data) => Some(data),
- _ => None,
- }
- }
-
- /// If the `Plist` is a Date, returns the associated DateTime.
- /// Returns None otherwise.
- pub fn as_date(&self) -> Option<&Date> {
- match *self {
- Plist::Date(ref date) => Some(date),
- _ => None,
- }
- }
-
- /// If the `Plist` is a Real, returns the associated f64.
- /// Returns None otherwise.
- pub fn as_real(&self) -> Option<f64> {
- match *self {
- Plist::Real(v) => Some(v),
- _ => None,
- }
- }
-
- /// If the `Plist` is an Integer, returns the associated i64.
- /// Returns None otherwise.
- pub fn as_integer(&self) -> Option<i64> {
- match *self {
- Plist::Integer(v) => Some(v),
- _ => None,
- }
- }
-
- /// If the `Plist` is a String, returns the underlying String.
- /// Returns None otherwise.
- ///
- /// This method consumes the `Plist`. If this is not desired, please use
- /// `as_string` method.
- pub fn into_string(self) -> Option<String> {
- match self {
- Plist::String(v) => Some(v),
- _ => None,
- }
- }
-
- /// If the `Plist` is a String, returns the associated str.
- /// Returns None otherwise.
- pub fn as_string(&self) -> Option<&str> {
- match *self {
- Plist::String(ref v) => Some(v),
- _ => None,
- }
- }
-}
-
-impl From<Vec<Plist>> for Plist {
- fn from(from: Vec<Plist>) -> Plist {
- Plist::Array(from)
- }
-}
-
-impl From<BTreeMap<String, Plist>> for Plist {
- fn from(from: BTreeMap<String, Plist>) -> Plist {
- Plist::Dictionary(from)
- }
-}
-
-impl From<bool> for Plist {
- fn from(from: bool) -> Plist {
- Plist::Boolean(from)
- }
-}
-
-impl<'a> From<&'a bool> for Plist {
- fn from(from: &'a bool) -> Plist {
- Plist::Boolean(*from)
- }
-}
-
-impl From<Date> for Plist {
- fn from(from: Date) -> Plist {
- Plist::Date(from)
- }
-}
-
-impl<'a> From<&'a Date> for Plist {
- fn from(from: &'a Date) -> Plist {
- Plist::Date(from.clone())
- }
-}
-
-impl From<f64> for Plist {
- fn from(from: f64) -> Plist {
- Plist::Real(from)
- }
-}
-
-impl From<f32> for Plist {
- fn from(from: f32) -> Plist {
- Plist::Real(from as f64)
- }
-}
-
-impl From<i64> for Plist {
- fn from(from: i64) -> Plist {
- Plist::Integer(from)
- }
-}
-
-impl From<i32> for Plist {
- fn from(from: i32) -> Plist {
- Plist::Integer(from as i64)
- }
-}
-
-impl From<i16> for Plist {
- fn from(from: i16) -> Plist {
- Plist::Integer(from as i64)
- }
-}
-
-impl From<i8> for Plist {
- fn from(from: i8) -> Plist {
- Plist::Integer(from as i64)
- }
-}
-
-impl From<u32> for Plist {
- fn from(from: u32) -> Plist {
- Plist::Integer(from as i64)
- }
-}
-
-impl From<u16> for Plist {
- fn from(from: u16) -> Plist {
- Plist::Integer(from as i64)
- }
-}
-
-impl From<u8> for Plist {
- fn from(from: u8) -> Plist {
- Plist::Integer(from as i64)
- }
-}
-
-impl<'a> From<&'a f64> for Plist {
- fn from(from: &'a f64) -> Plist {
- Plist::Real(*from)
- }
-}
-
-impl<'a> From<&'a f32> for Plist {
- fn from(from: &'a f32) -> Plist {
- Plist::Real(*from as f64)
- }
-}
-
-impl<'a> From<&'a i64> for Plist {
- fn from(from: &'a i64) -> Plist {
- Plist::Integer(*from)
- }
-}
-
-impl<'a> From<&'a i32> for Plist {
- fn from(from: &'a i32) -> Plist {
- Plist::Integer(*from as i64)
- }
-}
-
-impl<'a> From<&'a i16> for Plist {
- fn from(from: &'a i16) -> Plist {
- Plist::Integer(*from as i64)
- }
-}
-
-impl<'a> From<&'a i8> for Plist {
- fn from(from: &'a i8) -> Plist {
- Plist::Integer(*from as i64)
- }
-}
-
-impl<'a> From<&'a u32> for Plist {
- fn from(from: &'a u32) -> Plist {
- Plist::Integer(*from as i64)
- }
-}
-
-impl<'a> From<&'a u16> for Plist {
- fn from(from: &'a u16) -> Plist {
- Plist::Integer(*from as i64)
- }
-}
-
-impl<'a> From<&'a u8> for Plist {
- fn from(from: &'a u8) -> Plist {
- Plist::Integer(*from as i64)
- }
-}
-
-impl From<String> for Plist {
- fn from(from: String) -> Plist {
- Plist::String(from)
- }
-}
-
-impl<'a> From<&'a str> for Plist {
- fn from(from: &'a str) -> Plist {
- Plist::String(from.into())
- }
-}
-
-#[cfg(test)]
-mod tests {
- use std::collections::BTreeMap;
- use std::time::SystemTime;
-
- use {Date, Plist};
-
- #[test]
- fn test_plist_access() {
- let vec = vec![Plist::Real(0.0)];
- let mut array = Plist::Array(vec.clone());
- assert_eq!(array.as_array(), Some(&vec.clone()));
- assert_eq!(array.as_array_mut(), Some(&mut vec.clone()));
-
- let mut map = BTreeMap::new();
- map.insert("key1".to_owned(), Plist::String("value1".to_owned()));
- let mut dict = Plist::Dictionary(map.clone());
- assert_eq!(dict.as_dictionary(), Some(&map.clone()));
- assert_eq!(dict.as_dictionary_mut(), Some(&mut map.clone()));
-
- assert_eq!(Plist::Boolean(true).as_boolean(), Some(true));
-
- let slice: &[u8] = &[1, 2, 3];
- assert_eq!(Plist::Data(slice.to_vec()).as_data(), Some(slice));
- assert_eq!(
- Plist::Data(slice.to_vec()).into_data(),
- Some(slice.to_vec())
- );
-
- let date: Date = SystemTime::now().into();
- assert_eq!(Plist::Date(date.clone()).as_date(), Some(&date));
-
- assert_eq!(Plist::Real(0.0).as_real(), Some(0.0));
- assert_eq!(Plist::Integer(1).as_integer(), Some(1));
- assert_eq!(Plist::String("2".to_owned()).as_string(), Some("2"));
- assert_eq!(
- Plist::String("t".to_owned()).into_string(),
- Some("t".to_owned())
- );
- }
-}
diff --git a/src/serde/ser.rs b/src/ser.rs
index f9cb5b3..4a2a42b 100644
--- a/src/serde/ser.rs
+++ b/src/ser.rs
@@ -1,8 +1,10 @@
-use serde_base::ser;
+use serde::ser;
use std::fmt::Display;
+use std::io::Write;
use date::serde_impls::DATE_NEWTYPE_STRUCT_NAME;
-use {Date, Error, EventWriter, PlistEvent};
+use events::{self, Event, Writer};
+use {Date, Error};
impl ser::Error for Error {
fn custom<T: Display>(msg: T) -> Self {
@@ -10,16 +12,16 @@ impl ser::Error for Error {
}
}
-pub struct Serializer<W: EventWriter> {
+pub struct Serializer<W: Writer> {
writer: W,
}
-impl<W: EventWriter> Serializer<W> {
+impl<W: Writer> Serializer<W> {
pub fn new(writer: W) -> Serializer<W> {
Serializer { writer: writer }
}
- fn emit(&mut self, event: PlistEvent) -> Result<(), Error> {
+ fn emit(&mut self, event: Event) -> Result<(), Error> {
self.writer.write(&event)?;
Ok(())
}
@@ -30,18 +32,18 @@ impl<W: EventWriter> Serializer<W> {
// Emit {key: value}
fn single_key_dict(&mut self, key: String) -> Result<(), Error> {
- self.emit(PlistEvent::StartDictionary(Some(1)))?;
- self.emit(PlistEvent::StringValue(key))?;
+ self.emit(Event::StartDictionary(Some(1)))?;
+ self.emit(Event::StringValue(key))?;
Ok(())
}
fn single_key_dict_end(&mut self) -> Result<(), Error> {
- self.emit(PlistEvent::EndDictionary)?;
+ self.emit(Event::EndDictionary)?;
Ok(())
}
}
-impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
+impl<'a, W: Writer> ser::Serializer for &'a mut Serializer<W> {
type Ok = ();
type Error = Error;
@@ -54,7 +56,7 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
type SerializeStructVariant = Compound<'a, W>;
fn serialize_bool(self, v: bool) -> Result<(), Self::Error> {
- self.emit(PlistEvent::BooleanValue(v))
+ self.emit(Event::BooleanValue(v))
}
fn serialize_i8(self, v: i8) -> Result<(), Self::Error> {
@@ -70,7 +72,7 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
}
fn serialize_i64(self, v: i64) -> Result<(), Self::Error> {
- self.emit(PlistEvent::IntegerValue(v))
+ self.emit(Event::IntegerValue(v))
}
fn serialize_u8(self, v: u8) -> Result<(), Self::Error> {
@@ -86,7 +88,7 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
}
fn serialize_u64(self, v: u64) -> Result<(), Self::Error> {
- self.emit(PlistEvent::IntegerValue(v as i64))
+ self.emit(Event::IntegerValue(v as i64))
}
fn serialize_f32(self, v: f32) -> Result<(), Self::Error> {
@@ -94,19 +96,19 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
}
fn serialize_f64(self, v: f64) -> Result<(), Self::Error> {
- self.emit(PlistEvent::RealValue(v))
+ self.emit(Event::RealValue(v))
}
fn serialize_char(self, v: char) -> Result<(), Self::Error> {
- self.emit(PlistEvent::StringValue(v.to_string()))
+ self.emit(Event::StringValue(v.to_string()))
}
fn serialize_str(self, v: &str) -> Result<(), Self::Error> {
- self.emit(PlistEvent::StringValue(v.to_owned()))
+ self.emit(Event::StringValue(v.to_owned()))
}
fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
- self.emit(PlistEvent::DataValue(v.to_owned()))
+ self.emit(Event::DataValue(v.to_owned()))
}
fn serialize_none(self) -> Result<(), Self::Error> {
@@ -123,7 +125,7 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
fn serialize_unit(self) -> Result<(), Self::Error> {
// Emit empty string
- self.emit(PlistEvent::StringValue(String::new()))
+ self.emit(Event::StringValue(String::new()))
}
fn serialize_unit_struct(self, _name: &'static str) -> Result<(), Self::Error> {
@@ -168,7 +170,7 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error> {
let len = len.map(|len| len as u64);
- self.emit(PlistEvent::StartArray(len))?;
+ self.emit(Event::StartArray(len))?;
Ok(Compound { ser: self })
}
@@ -197,7 +199,7 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error> {
let len = len.map(|len| len as u64);
- self.emit(PlistEvent::StartDictionary(len))?;
+ self.emit(Event::StartDictionary(len))?;
Ok(Compound { ser: self })
}
@@ -222,21 +224,21 @@ impl<'a, W: EventWriter> ser::Serializer for &'a mut Serializer<W> {
}
}
-struct StructFieldSerializer<'a, W: 'a + EventWriter> {
+struct StructFieldSerializer<'a, W: 'a + Writer> {
ser: &'a mut Serializer<W>,
field_name: &'static str,
}
-impl<'a, W: EventWriter> StructFieldSerializer<'a, W> {
+impl<'a, W: Writer> 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()))?;
+ .emit(Event::StringValue(self.field_name.to_owned()))?;
Ok(self.ser)
}
}
-impl<'a, W: EventWriter> ser::Serializer for StructFieldSerializer<'a, W> {
+impl<'a, W: Writer> ser::Serializer for StructFieldSerializer<'a, W> {
type Ok = ();
type Error = Error;
@@ -402,17 +404,17 @@ impl<'a, W: EventWriter> ser::Serializer for StructFieldSerializer<'a, W> {
}
}
-struct DateSerializer<'a, W: 'a + EventWriter> {
+struct DateSerializer<'a, W: 'a + Writer> {
ser: &'a mut Serializer<W>,
}
-impl<'a, W: EventWriter> DateSerializer<'a, W> {
+impl<'a, W: Writer> 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> {
+impl<'a, W: Writer> ser::Serializer for DateSerializer<'a, W> {
type Ok = ();
type Error = Error;
@@ -474,7 +476,7 @@ impl<'a, W: EventWriter> ser::Serializer for DateSerializer<'a, W> {
fn serialize_str(self, v: &str) -> Result<(), Self::Error> {
let date = Date::from_rfc3339(v).map_err(|_| self.expecting_date_error())?;
- self.ser.emit(PlistEvent::DateValue(date))
+ self.ser.emit(Event::DateValue(date))
}
fn serialize_bytes(self, _: &[u8]) -> Result<(), Self::Error> {
@@ -574,11 +576,11 @@ impl<'a, W: EventWriter> ser::Serializer for DateSerializer<'a, W> {
}
#[doc(hidden)]
-pub struct Compound<'a, W: 'a + EventWriter> {
+pub struct Compound<'a, W: 'a + Writer> {
ser: &'a mut Serializer<W>,
}
-impl<'a, W: EventWriter> ser::SerializeSeq for Compound<'a, W> {
+impl<'a, W: Writer> ser::SerializeSeq for Compound<'a, W> {
type Ok = ();
type Error = Error;
@@ -590,11 +592,11 @@ impl<'a, W: EventWriter> ser::SerializeSeq for Compound<'a, W> {
}
fn end(self) -> Result<Self::Ok, Self::Error> {
- self.ser.emit(PlistEvent::EndArray)
+ self.ser.emit(Event::EndArray)
}
}
-impl<'a, W: EventWriter> ser::SerializeTuple for Compound<'a, W> {
+impl<'a, W: Writer> ser::SerializeTuple for Compound<'a, W> {
type Ok = ();
type Error = Error;
@@ -610,7 +612,7 @@ impl<'a, W: EventWriter> ser::SerializeTuple for Compound<'a, W> {
}
}
-impl<'a, W: EventWriter> ser::SerializeTupleStruct for Compound<'a, W> {
+impl<'a, W: Writer> ser::SerializeTupleStruct for Compound<'a, W> {
type Ok = ();
type Error = Error;
@@ -626,7 +628,7 @@ impl<'a, W: EventWriter> ser::SerializeTupleStruct for Compound<'a, W> {
}
}
-impl<'a, W: EventWriter> ser::SerializeTupleVariant for Compound<'a, W> {
+impl<'a, W: Writer> ser::SerializeTupleVariant for Compound<'a, W> {
type Ok = ();
type Error = Error;
@@ -638,12 +640,12 @@ impl<'a, W: EventWriter> ser::SerializeTupleVariant for Compound<'a, W> {
}
fn end(self) -> Result<Self::Ok, Self::Error> {
- self.ser.emit(PlistEvent::EndArray)?;
+ self.ser.emit(Event::EndArray)?;
self.ser.single_key_dict_end()
}
}
-impl<'a, W: EventWriter> ser::SerializeMap for Compound<'a, W> {
+impl<'a, W: Writer> ser::SerializeMap for Compound<'a, W> {
type Ok = ();
type Error = Error;
@@ -659,11 +661,11 @@ impl<'a, W: EventWriter> ser::SerializeMap for Compound<'a, W> {
}
fn end(self) -> Result<Self::Ok, Self::Error> {
- self.ser.emit(PlistEvent::EndDictionary)
+ self.ser.emit(Event::EndDictionary)
}
}
-impl<'a, W: EventWriter> ser::SerializeStruct for Compound<'a, W> {
+impl<'a, W: Writer> ser::SerializeStruct for Compound<'a, W> {
type Ok = ();
type Error = Error;
@@ -685,7 +687,7 @@ impl<'a, W: EventWriter> ser::SerializeStruct for Compound<'a, W> {
}
}
-impl<'a, W: EventWriter> ser::SerializeStructVariant for Compound<'a, W> {
+impl<'a, W: Writer> ser::SerializeStructVariant for Compound<'a, W> {
type Ok = ();
type Error = Error;
@@ -698,7 +700,13 @@ impl<'a, W: EventWriter> ser::SerializeStructVariant for Compound<'a, W> {
}
fn end(self) -> Result<Self::Ok, Self::Error> {
- self.ser.emit(PlistEvent::EndDictionary)?;
+ self.ser.emit(Event::EndDictionary)?;
self.ser.single_key_dict_end()
}
}
+
+pub fn serialize_to_xml<W: Write, T: ser::Serialize>(writer: W, value: &T) -> Result<(), Error> {
+ let writer = events::XmlWriter::new(writer);
+ let mut ser = Serializer::new(writer);
+ value.serialize(&mut ser)
+}
diff --git a/src/serde/mod.rs b/src/serde/mod.rs
deleted file mode 100644
index 2b2411c..0000000
--- a/src/serde/mod.rs
+++ /dev/null
@@ -1,25 +0,0 @@
-mod de;
-mod ser;
-
-pub use self::de::Deserializer;
-pub use self::ser::Serializer;
-
-use serde_base::de::{Deserialize, DeserializeOwned};
-use serde_base::ser::Serialize;
-use std::io::{Read, Seek, Write};
-
-use EventReader;
-use Result;
-use xml;
-
-pub fn deserialize<R: Read + Seek, T: DeserializeOwned>(reader: R) -> Result<T> {
- let reader = EventReader::new(reader);
- let mut de = Deserializer::new(reader);
- Deserialize::deserialize(&mut de)
-}
-
-pub fn serialize_to_xml<W: Write, T: Serialize>(writer: W, value: &T) -> Result<()> {
- let writer = xml::EventWriter::new(writer);
- let mut ser = Serializer::new(writer);
- value.serialize(&mut ser)
-}
diff --git a/src/value.rs b/src/value.rs
new file mode 100644
index 0000000..d04ad86
--- /dev/null
+++ b/src/value.rs
@@ -0,0 +1,377 @@
+use std::collections::BTreeMap;
+use std::io::{Read, Seek};
+
+use events::{Event, Reader};
+use {builder, Date, Result};
+
+#[derive(Clone, Debug, PartialEq)]
+pub enum Value {
+ Array(Vec<Value>),
+ Dictionary(BTreeMap<String, Value>),
+ Boolean(bool),
+ Data(Vec<u8>),
+ Date(Date),
+ Real(f64),
+ Integer(i64),
+ String(String),
+}
+
+impl Value {
+ pub fn read<R: Read + Seek>(reader: R) -> Result<Value> {
+ let reader = Reader::new(reader);
+ Value::from_events(reader)
+ }
+
+ pub fn from_events<T>(events: T) -> Result<Value>
+ where
+ T: IntoIterator<Item = Result<Event>>,
+ {
+ let iter = events.into_iter();
+ let builder = builder::Builder::new(iter);
+ builder.build()
+ }
+
+ pub fn into_events(self) -> Vec<Event> {
+ let mut events = Vec::new();
+ self.into_events_inner(&mut events);
+ events
+ }
+
+ fn into_events_inner(self, events: &mut Vec<Event>) {
+ match self {
+ Value::Array(array) => {
+ events.push(Event::StartArray(Some(array.len() as u64)));
+ for value in array {
+ value.into_events_inner(events);
+ }
+ events.push(Event::EndArray);
+ }
+ Value::Dictionary(dict) => {
+ events.push(Event::StartDictionary(Some(dict.len() as u64)));
+ for (key, value) in dict {
+ events.push(Event::StringValue(key));
+ value.into_events_inner(events);
+ }
+ events.push(Event::EndDictionary);
+ }
+ Value::Boolean(value) => events.push(Event::BooleanValue(value)),
+ Value::Data(value) => events.push(Event::DataValue(value)),
+ Value::Date(value) => events.push(Event::DateValue(value)),
+ Value::Real(value) => events.push(Event::RealValue(value)),
+ Value::Integer(value) => events.push(Event::IntegerValue(value)),
+ Value::String(value) => events.push(Event::StringValue(value)),
+ }
+ }
+
+ /// If the `Value` is an Array, returns the associated Vec.
+ /// Returns None otherwise.
+ pub fn as_array(&self) -> Option<&Vec<Value>> {
+ match *self {
+ Value::Array(ref array) => Some(array),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is an Array, returns the associated mutable Vec.
+ /// Returns None otherwise.
+ pub fn as_array_mut(&mut self) -> Option<&mut Vec<Value>> {
+ match *self {
+ Value::Array(ref mut array) => Some(array),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a Dictionary, returns the associated BTreeMap.
+ /// Returns None otherwise.
+ pub fn as_dictionary(&self) -> Option<&BTreeMap<String, Value>> {
+ match *self {
+ Value::Dictionary(ref map) => Some(map),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a Dictionary, returns the associated mutable BTreeMap.
+ /// Returns None otherwise.
+ pub fn as_dictionary_mut(&mut self) -> Option<&mut BTreeMap<String, Value>> {
+ match *self {
+ Value::Dictionary(ref mut map) => Some(map),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a Boolean, returns the associated bool.
+ /// Returns None otherwise.
+ pub fn as_boolean(&self) -> Option<bool> {
+ match *self {
+ Value::Boolean(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a Data, returns the underlying Vec.
+ /// Returns None otherwise.
+ ///
+ /// This method consumes the `Value`. If this is not desired, please use
+ /// `as_data` method.
+ pub fn into_data(self) -> Option<Vec<u8>> {
+ match self {
+ Value::Data(data) => Some(data),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a Data, returns the associated Vec.
+ /// Returns None otherwise.
+ pub fn as_data(&self) -> Option<&[u8]> {
+ match *self {
+ Value::Data(ref data) => Some(data),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a Date, returns the associated DateTime.
+ /// Returns None otherwise.
+ pub fn as_date(&self) -> Option<&Date> {
+ match *self {
+ Value::Date(ref date) => Some(date),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a Real, returns the associated f64.
+ /// Returns None otherwise.
+ pub fn as_real(&self) -> Option<f64> {
+ match *self {
+ Value::Real(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is an Integer, returns the associated i64.
+ /// Returns None otherwise.
+ pub fn as_integer(&self) -> Option<i64> {
+ match *self {
+ Value::Integer(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a String, returns the underlying String.
+ /// Returns None otherwise.
+ ///
+ /// This method consumes the `Value`. If this is not desired, please use
+ /// `as_string` method.
+ pub fn into_string(self) -> Option<String> {
+ match self {
+ Value::String(v) => Some(v),
+ _ => None,
+ }
+ }
+
+ /// If the `Value` is a String, returns the associated str.
+ /// Returns None otherwise.
+ pub fn as_string(&self) -> Option<&str> {
+ match *self {
+ Value::String(ref v) => Some(v),
+ _ => None,
+ }
+ }
+}
+
+impl From<Vec<Value>> for Value {
+ fn from(from: Vec<Value>) -> Value {
+ Value::Array(from)
+ }
+}
+
+impl From<BTreeMap<String, Value>> for Value {
+ fn from(from: BTreeMap<String, Value>) -> Value {
+ Value::Dictionary(from)
+ }
+}
+
+impl From<bool> for Value {
+ fn from(from: bool) -> Value {
+ Value::Boolean(from)
+ }
+}
+
+impl<'a> From<&'a bool> for Value {
+ fn from(from: &'a bool) -> Value {
+ Value::Boolean(*from)
+ }
+}
+
+impl From<Date> for Value {
+ fn from(from: Date) -> Value {
+ Value::Date(from)
+ }
+}
+
+impl<'a> From<&'a Date> for Value {
+ fn from(from: &'a Date) -> Value {
+ Value::Date(from.clone())
+ }
+}
+
+impl From<f64> for Value {
+ fn from(from: f64) -> Value {
+ Value::Real(from)
+ }
+}
+
+impl From<f32> for Value {
+ fn from(from: f32) -> Value {
+ Value::Real(from as f64)
+ }
+}
+
+impl From<i64> for Value {
+ fn from(from: i64) -> Value {
+ Value::Integer(from)
+ }
+}
+
+impl From<i32> for Value {
+ fn from(from: i32) -> Value {
+ Value::Integer(from as i64)
+ }
+}
+
+impl From<i16> for Value {
+ fn from(from: i16) -> Value {
+ Value::Integer(from as i64)
+ }
+}
+
+impl From<i8> for Value {
+ fn from(from: i8) -> Value {
+ Value::Integer(from as i64)
+ }
+}
+
+impl From<u32> for Value {
+ fn from(from: u32) -> Value {
+ Value::Integer(from as i64)
+ }
+}
+
+impl From<u16> for Value {
+ fn from(from: u16) -> Value {
+ Value::Integer(from as i64)
+ }
+}
+
+impl From<u8> for Value {
+ fn from(from: u8) -> Value {
+ Value::Integer(from as i64)
+ }
+}
+
+impl<'a> From<&'a f64> for Value {
+ fn from(from: &'a f64) -> Value {
+ Value::Real(*from)
+ }
+}
+
+impl<'a> From<&'a f32> for Value {
+ fn from(from: &'a f32) -> Value {
+ Value::Real(*from as f64)
+ }
+}
+
+impl<'a> From<&'a i64> for Value {
+ fn from(from: &'a i64) -> Value {
+ Value::Integer(*from)
+ }
+}
+
+impl<'a> From<&'a i32> for Value {
+ fn from(from: &'a i32) -> Value {
+ Value::Integer(*from as i64)
+ }
+}
+
+impl<'a> From<&'a i16> for Value {
+ fn from(from: &'a i16) -> Value {
+ Value::Integer(*from as i64)
+ }
+}
+
+impl<'a> From<&'a i8> for Value {
+ fn from(from: &'a i8) -> Value {
+ Value::Integer(*from as i64)
+ }
+}
+
+impl<'a> From<&'a u32> for Value {
+ fn from(from: &'a u32) -> Value {
+ Value::Integer(*from as i64)
+ }
+}
+
+impl<'a> From<&'a u16> for Value {
+ fn from(from: &'a u16) -> Value {
+ Value::Integer(*from as i64)
+ }
+}
+
+impl<'a> From<&'a u8> for Value {
+ fn from(from: &'a u8) -> Value {
+ Value::Integer(*from as i64)
+ }
+}
+
+impl From<String> for Value {
+ fn from(from: String) -> Value {
+ Value::String(from)
+ }
+}
+
+impl<'a> From<&'a str> for Value {
+ fn from(from: &'a str) -> Value {
+ Value::String(from.into())
+ }
+}
+
+#[cfg(test)]
+mod tests {
+ use std::collections::BTreeMap;
+ use std::time::SystemTime;
+
+ use {Date, Value};
+
+ #[test]
+ fn test_plist_access() {
+ let vec = vec![Value::Real(0.0)];
+ let mut array = Value::Array(vec.clone());
+ assert_eq!(array.as_array(), Some(&vec.clone()));
+ assert_eq!(array.as_array_mut(), Some(&mut vec.clone()));
+
+ let mut map = BTreeMap::new();
+ map.insert("key1".to_owned(), Value::String("value1".to_owned()));
+ let mut dict = Value::Dictionary(map.clone());
+ assert_eq!(dict.as_dictionary(), Some(&map.clone()));
+ assert_eq!(dict.as_dictionary_mut(), Some(&mut map.clone()));
+
+ assert_eq!(Value::Boolean(true).as_boolean(), Some(true));
+
+ let slice: &[u8] = &[1, 2, 3];
+ assert_eq!(Value::Data(slice.to_vec()).as_data(), Some(slice));
+ assert_eq!(
+ Value::Data(slice.to_vec()).into_data(),
+ Some(slice.to_vec())
+ );
+
+ let date: Date = SystemTime::now().into();
+ assert_eq!(Value::Date(date.clone()).as_date(), Some(&date));
+
+ assert_eq!(Value::Real(0.0).as_real(), Some(0.0));
+ assert_eq!(Value::Integer(1).as_integer(), Some(1));
+ assert_eq!(Value::String("2".to_owned()).as_string(), Some("2"));
+ assert_eq!(
+ Value::String("t".to_owned()).into_string(),
+ Some("t".to_owned())
+ );
+ }
+}
diff --git a/src/xml/mod.rs b/src/xml/mod.rs
deleted file mode 100644
index 0400e13..0000000
--- a/src/xml/mod.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-mod reader;
-mod writer;
-
-pub use self::reader::EventReader;
-pub use self::writer::EventWriter;
diff --git a/tests/fuzzer.rs b/tests/fuzzer.rs
index 539c689..160bc53 100644
--- a/tests/fuzzer.rs
+++ b/tests/fuzzer.rs
@@ -1,6 +1,6 @@
extern crate plist;
-use plist::{Error, Plist};
+use plist::{Error, Value};
use std::io::Cursor;
#[test]
@@ -59,9 +59,9 @@ fn issue_22_binary_with_byte_ref_size() {
test_fuzzer_data_ok(data);
}
-fn test_fuzzer_data(data: &[u8]) -> Result<Plist, Error> {
+fn test_fuzzer_data(data: &[u8]) -> Result<Value, Error> {
let cursor = Cursor::new(data);
- Plist::read(cursor)
+ Value::read(cursor)
}
fn test_fuzzer_data_ok(data: &[u8]) {
diff --git a/tests/serde_tests/mod.rs b/tests/serde_tests/mod.rs
index d908f08..881dc7b 100644
--- a/tests/serde_tests/mod.rs
+++ b/tests/serde_tests/mod.rs
@@ -1,13 +1,14 @@
-use plist::PlistEvent::*;
-use plist::serde::{Deserializer, Serializer};
-use plist::{Date, Error, EventWriter, PlistEvent};
+use plist::events::Event;
+use plist::events::Event::*;
+use plist::events::Writer;
+use plist::{Date, Deserializer, Error, Serializer};
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use std::fmt::Debug;
use std::time::SystemTime;
struct VecWriter {
- events: Vec<PlistEvent>,
+ events: Vec<Event>,
}
impl VecWriter {
@@ -15,13 +16,13 @@ impl VecWriter {
VecWriter { events: Vec::new() }
}
- pub fn into_inner(self) -> Vec<PlistEvent> {
+ pub fn into_inner(self) -> Vec<Event> {
self.events
}
}
-impl EventWriter for VecWriter {
- fn write(&mut self, event: &PlistEvent) -> Result<(), Error> {
+impl Writer for VecWriter {
+ fn write(&mut self, event: &Event) -> Result<(), Error> {
self.events.push(event.clone());
Ok(())
}
@@ -31,12 +32,12 @@ fn new_serializer() -> Serializer<VecWriter> {
Serializer::new(VecWriter::new())
}
-fn new_deserializer(events: Vec<PlistEvent>) -> Deserializer<Vec<Result<PlistEvent, Error>>> {
+fn new_deserializer(events: Vec<Event>) -> Deserializer<Vec<Result<Event, Error>>> {
let result_events = events.into_iter().map(Ok).collect();
Deserializer::new(result_events)
}
-fn assert_roundtrip<T>(obj: T, comparison: Option<&[PlistEvent]>)
+fn assert_roundtrip<T>(obj: T, comparison: Option<&[Event]>)
where
T: Debug + DeserializeOwned + PartialEq + Serialize,
{
@@ -98,13 +99,11 @@ fn cow() {
#[test]
fn dog() {
let dog = Animal::Dog(DogOuter {
- inner: vec![
- DogInner {
- a: (),
- b: 12,
- c: vec!["a".to_string(), "b".to_string()],
- },
- ],
+ inner: vec![DogInner {
+ a: (),
+ b: 12,
+ c: vec!["a".to_string(), "b".to_string()],
+ }],
});
let comparison = &[