aboutsummaryrefslogtreecommitdiffstats
path: root/src/xml.rs
diff options
context:
space:
mode:
authorEdward Barnard2015-08-28 18:58:55 +0700
committerEdward Barnard2015-08-28 18:58:55 +0700
commitd6e5780da526ce66d9c9daa7723ed45b39fa434e (patch)
tree76fc009b2fe49b75ccb41d2907f9867da22e6006 /src/xml.rs
parentb5ad734bd68454fcb304a555bd2b1f0bb3274ec9 (diff)
downloadrust-plist-d6e5780da526ce66d9c9daa7723ed45b39fa434e.tar.bz2
First pass at an xml format writer
Diffstat (limited to 'src/xml.rs')
-rw-r--r--src/xml.rs101
1 files changed, 100 insertions, 1 deletions
diff --git a/src/xml.rs b/src/xml.rs
index 27eb3ae..4e02f54 100644
--- a/src/xml.rs
+++ b/src/xml.rs
@@ -1,11 +1,110 @@
use rustc_serialize::base64::FromBase64;
-use std::io::Read;
+use std::io::{Read, Write};
use std::str::FromStr;
+use xml_rs::namespace::Namespace;
use xml_rs::reader::{EventReader, ParserConfig};
use xml_rs::reader::events::XmlEvent;
+use xml_rs::writer::{EventWriter, EmitterConfig};
+use xml_rs::writer::events::XmlEvent as WriteXmlEvent;
use super::{ParserError, PlistEvent};
+pub struct Writer<W: Write> {
+ xml_writer: EventWriter<W>,
+ // Not very nice
+ empty_namespace: Namespace
+}
+
+impl<W: Write> Writer<W> {
+ fn new(writer: W) -> Writer<W> {
+ let config = EmitterConfig {
+ line_separator: "\n".to_owned(),
+ indent_string: " ".to_owned(),
+ perform_indent: true,
+ write_document_declaration: true,
+ normalize_empty_elements: true,
+ cdata_to_characters: true,
+ };
+
+ Writer {
+ xml_writer: EventWriter::new_with_config(writer, config),
+ empty_namespace: Namespace::empty()
+ }
+ }
+
+ fn write_element_and_value(&mut self, name: &str, value: &str) -> Result<(), ()> {
+ try!(self.start_element(name));
+ try!(self.write_value(value));
+ try!(self.end_element(name));
+ Ok(())
+ }
+
+ fn start_element(&mut self, name: &str) -> Result<(), ()> {
+ let result = self.xml_writer.write(WriteXmlEvent::StartElement {
+ name: ::xml_rs::name::Name::local(name),
+ attributes: Vec::new(),
+ namespace: &self.empty_namespace
+ });
+
+ match result {
+ Ok(()) => Ok(()),
+ Err(_) => Err(())
+ }
+ }
+
+ fn end_element(&mut self, name: &str) -> Result<(), ()> {
+ let result = self.xml_writer.write(WriteXmlEvent::EndElement {
+ name: ::xml_rs::name::Name::local(name)
+ });
+
+ match result {
+ Ok(()) => Ok(()),
+ Err(_) => Err(())
+ }
+ }
+
+ fn write_value(&mut self, value: &str) -> Result<(), ()> {
+ let result = self.xml_writer.write(WriteXmlEvent::Characters(value));
+
+ match result {
+ Ok(()) => Ok(()),
+ Err(_) => Err(())
+ }
+ }
+
+ fn write(&mut self, event: PlistEvent) -> Result<(), ()> {
+ Ok(match event {
+ PlistEvent::StartPlist => try!(self.start_element("plist")),
+ PlistEvent::EndPlist => try!(self.end_element("plist")),
+
+ PlistEvent::StartArray(_) => try!(self.start_element("array")),
+ PlistEvent::EndArray => try!(self.end_element("array")),
+
+ PlistEvent::StartDictionary(_) => try!(self.start_element("dict")),
+ PlistEvent::EndDictionary => try!(self.end_element("dict")),
+
+ PlistEvent::BooleanValue(true) => {
+ try!(self.start_element("true"));
+ try!(self.end_element("true"));
+ },
+ PlistEvent::BooleanValue(false) => {
+ try!(self.start_element("false"));
+ try!(self.end_element("false"));
+ },
+ PlistEvent::DataValue(value) => {
+ panic!();
+ },
+ PlistEvent::DateValue(value) => panic!("unimpl"),
+ PlistEvent::IntegerValue(value) => try!(self.write_element_and_value("integer", &value.to_string())),
+ PlistEvent::RealValue(value) => try!(self.write_element_and_value("real", &value.to_string())),
+ PlistEvent::StringValue(value) => try!(self.write_element_and_value("string", &value)),
+
+ PlistEvent::Error(_) => return Err(())
+ })
+ }
+}
+
+
pub struct StreamingParser<R: Read> {
xml_reader: EventReader<R>,
element_stack: Vec<String>