diff options
| -rw-r--r-- | Cargo.toml | 2 | ||||
| -rw-r--r-- | src/xml/reader.rs | 25 | ||||
| -rw-r--r-- | src/xml/writer.rs | 53 |
3 files changed, 42 insertions, 38 deletions
@@ -10,6 +10,6 @@ keywords = ["plist", "parser"] [dependencies] rustc-serialize = "0.3.16" -xml-rs = "0.1.26" +xml-rs = "0.2.2" byteorder = "0.3.13" chrono = "0.2.16"
\ No newline at end of file diff --git a/src/xml/reader.rs b/src/xml/reader.rs index b372e8e..abf671d 100644 --- a/src/xml/reader.rs +++ b/src/xml/reader.rs @@ -2,8 +2,7 @@ use chrono::{DateTime, UTC}; use rustc_serialize::base64::FromBase64; use std::io::Read; use std::str::FromStr; -use xml_rs::reader::{EventReader, ParserConfig}; -use xml_rs::reader::events::XmlEvent; +use xml_rs::reader::{EventReader, ParserConfig, XmlEvent}; use super::super::{ParserError, ParserResult, PlistEvent}; @@ -25,7 +24,7 @@ impl<R: Read> StreamingParser<R> { }; StreamingParser { - xml_reader: EventReader::with_config(reader, config), + xml_reader: EventReader::new_with_config(reader, config), queued_event: None, element_stack: Vec::new(), finished: false @@ -34,8 +33,8 @@ impl<R: Read> StreamingParser<R> { fn read_content<F>(&mut self, f: F) -> ParserResult<PlistEvent> where F:FnOnce(String) -> ParserResult<PlistEvent> { match self.xml_reader.next() { - XmlEvent::Characters(s) => f(s), - event @ XmlEvent::EndElement{..} => { + Ok(XmlEvent::Characters(s)) => f(s), + Ok(event @ XmlEvent::EndElement{..}) => { self.queued_event = Some(event); f("".to_owned()) }, @@ -43,18 +42,18 @@ impl<R: Read> StreamingParser<R> { } } - fn next_event(&mut self) -> XmlEvent { + fn next_event(&mut self) -> Result<XmlEvent, ()> { if let Some(event) = self.queued_event.take() { - event + Ok(event) } else { - self.xml_reader.next() + self.xml_reader.next().map_err(|_| ()) } } fn read_next(&mut self) -> Option<ParserResult<PlistEvent>> { loop { match self.next_event() { - XmlEvent::StartElement { name, .. } => { + Ok(XmlEvent::StartElement { name, .. }) => { // Add the current element to the element stack self.element_stack.push(name.local_name.clone()); @@ -92,7 +91,7 @@ impl<R: Read> StreamingParser<R> { _ => return Some(Err(ParserError::InvalidData)) } }, - XmlEvent::EndElement { name, .. } => { + Ok(XmlEvent::EndElement { name, .. }) => { // Check the corrent element is being closed match self.element_stack.pop() { Some(ref open_name) if &name.local_name == open_name => (), @@ -107,13 +106,13 @@ impl<R: Read> StreamingParser<R> { _ => () } }, - XmlEvent::EndDocument => { + Ok(XmlEvent::EndDocument) => { match self.element_stack.is_empty() { true => return None, false => return Some(Err(ParserError::UnexpectedEof)) } }, - XmlEvent::Error(_) => return Some(Err(ParserError::InvalidData)), + Err(_) => return Some(Err(ParserError::InvalidData)), _ => () } } @@ -188,8 +187,6 @@ mod tests { #[test] fn bad_data() { - use PlistEvent::*; - let reader = File::open(&Path::new("./tests/data/xml_error.plist")).unwrap(); let streaming_parser = StreamingParser::new(reader); let events: Vec<_> = streaming_parser.collect(); diff --git a/src/xml/writer.rs b/src/xml/writer.rs index 1b3eb5f..bd73b1e 100644 --- a/src/xml/writer.rs +++ b/src/xml/writer.rs @@ -1,4 +1,5 @@ use rustc_serialize::base64::{MIME, ToBase64}; +use std::borrow::Cow; use std::io::Write; use xml_rs::attribute::Attribute; use xml_rs::name::Name; @@ -29,12 +30,15 @@ pub struct Writer<W: Write> { impl<W: Write> Writer<W> { pub fn new(writer: W) -> Writer<W> { let config = EmitterConfig { - line_separator: "\n".to_owned(), - indent_string: " ".to_owned(), + line_separator: "\n".into(), + indent_string: " ".into(), perform_indent: true, + perform_escaping: true, write_document_declaration: true, normalize_empty_elements: true, cdata_to_characters: true, + keep_element_names_stack: false, + autopad_comments: true }; Writer { @@ -54,8 +58,8 @@ impl<W: Write> Writer<W> { fn start_element(&mut self, name: &str) -> Result<(), ()> { let result = self.xml_writer.write(WriteXmlEvent::StartElement { name: Name::local(name), - attributes: Vec::new(), - namespace: &self.empty_namespace + attributes: Cow::Borrowed(&[]), + namespace: Cow::Borrowed(&self.empty_namespace) }); match result { @@ -66,7 +70,7 @@ impl<W: Write> Writer<W> { fn end_element(&mut self, name: &str) -> Result<(), ()> { let result = self.xml_writer.write(WriteXmlEvent::EndElement { - name: Name::local(name) + name: Some(Name::local(name)) }); match result { @@ -106,8 +110,8 @@ impl<W: Write> Writer<W> { let result = self.xml_writer.write(WriteXmlEvent::StartElement { name: Name::local("plist"), - attributes: vec!(version_attr), - namespace: &self.empty_namespace + attributes: Cow::Borrowed(&[version_attr]), + namespace: Cow::Borrowed(&self.empty_namespace) }); match result { @@ -175,11 +179,8 @@ impl<W: Write> Writer<W> { mod tests { use chrono::{TimeZone, UTC}; use std::io::Cursor; - use std::fs::File; - use std::path::Path; use super::*; - use PlistEvent; #[test] fn streaming_parser() { @@ -218,19 +219,25 @@ mod tests { } let comparison = "<?xml version=\"1.0\" encoding=\"utf-8\"?> -<plist version=\"1.0\"><dict><key>Author</key> -<string>William Shakespeare</string> -<key>Lines</key> -<array><string>It is a tale told by an idiot,</string> -<string>Full of sound and fury, signifying nothing.</string></array> -<key>Death</key> -<integer>1564</integer> -<key>Height</key> -<real>1.6</real> -<key>Data</key> -<data>AAAAvgAAAAMAAAAeAAAA</data> -<key>Birthdate</key> -<date>1981-05-16T11:32:06+00:00</date></dict></plist>"; +<plist version=\"1.0\"> + <dict> + <key>Author</key> + <string>William Shakespeare</string> + <key>Lines</key> + <array> + <string>It is a tale told by an idiot,</string> + <string>Full of sound and fury, signifying nothing.</string> + </array> + <key>Death</key> + <integer>1564</integer> + <key>Height</key> + <real>1.6</real> + <key>Data</key> + <data>AAAAvgAAAAMAAAAeAAAA</data> + <key>Birthdate</key> + <date>1981-05-16T11:32:06+00:00</date> + </dict> +</plist>"; let s = String::from_utf8(cursor.into_inner()).unwrap(); |
