From 35c46d1a361d14ac692ea1ad5b80ac0bc7d30c77 Mon Sep 17 00:00:00 2001 From: Edward Barnard Date: Fri, 6 Nov 2015 20:02:42 +0000 Subject: xml::Writer works! --- src/xml/mod.rs | 2 -- src/xml/writer.rs | 100 +++++++++++++++++++++++++++++++++++++++++------------- 2 files changed, 76 insertions(+), 26 deletions(-) (limited to 'src') diff --git a/src/xml/mod.rs b/src/xml/mod.rs index 8770a60..71c098e 100644 --- a/src/xml/mod.rs +++ b/src/xml/mod.rs @@ -2,6 +2,4 @@ mod reader; mod writer; pub use self::reader::StreamingParser; - -/// WIP: Does not work correctly pub use self::writer::Writer; \ No newline at end of file diff --git a/src/xml/writer.rs b/src/xml/writer.rs index 6638bd5..1b3eb5f 100644 --- a/src/xml/writer.rs +++ b/src/xml/writer.rs @@ -8,8 +8,20 @@ use xml_rs::writer::events::XmlEvent as WriteXmlEvent; use {PlistEvent}; +enum Element { + Dictionary(DictionaryState), + Array, + Root +} + +enum DictionaryState { + ExpectKey, + ExpectValue +} + pub struct Writer { xml_writer: EventWriter, + stack: Vec, // Not very nice empty_namespace: Namespace } @@ -27,6 +39,7 @@ impl Writer { Writer { xml_writer: EventWriter::new_with_config(writer, config), + stack: Vec::new(), empty_namespace: Namespace::empty() } } @@ -72,29 +85,68 @@ impl Writer { } pub fn write(&mut self, event: &PlistEvent) -> Result<(), ()> { + match self.stack.pop() { + Some(Element::Dictionary(DictionaryState::ExpectKey)) => { + match *event { + PlistEvent::StringValue(ref value) => { + try!(self.write_element_and_value("key", &*value)); + self.stack.push(Element::Dictionary(DictionaryState::ExpectValue)); + } + PlistEvent::EndDictionary => try!(self.end_element("dict")), + _ => return Err(()) // Invalid event + }; + return Ok(()) + }, + Some(Element::Dictionary(DictionaryState::ExpectValue)) => self.stack.push(Element::Dictionary(DictionaryState::ExpectKey)), + Some(other) => self.stack.push(other), + None => match *event { + PlistEvent::StartPlist => { + let version_name = Name::local("version"); + let version_attr = Attribute::new(version_name, "1.0"); + + let result = self.xml_writer.write(WriteXmlEvent::StartElement { + name: Name::local("plist"), + attributes: vec!(version_attr), + namespace: &self.empty_namespace + }); + + match result { + Ok(()) => (), + Err(_) => return Err(()) + } + + self.stack.push(Element::Root); + return Ok(()) + }, + _ => return Err(()) // Invalid event + } + } + Ok(match *event { - PlistEvent::StartPlist => { - let version_name = Name::local("version"); - let version_attr = Attribute::new(version_name, "1.0"); - - let result = self.xml_writer.write(WriteXmlEvent::StartElement { - name: Name::local("plist"), - attributes: vec!(version_attr), - namespace: &self.empty_namespace - }); - - match result { - Ok(()) => (), - Err(_) => return Err(()) + PlistEvent::StartPlist => return Err(()), // Invalid event + PlistEvent::EndPlist => { + try!(self.end_element("plist")); + if let Some(Element::Root) = self.stack.pop() {} else { + return Err(()); // Invalid event } }, - PlistEvent::EndPlist => try!(self.end_element("plist")), - PlistEvent::StartArray(_) => try!(self.start_element("array")), - PlistEvent::EndArray => try!(self.end_element("array")), + PlistEvent::StartArray(_) => { + try!(self.start_element("array")); + self.stack.push(Element::Array); + } + PlistEvent::EndArray => { + try!(self.end_element("array")); + if let Some(Element::Array) = self.stack.pop() {} else { + return Err(()); // Invalid event + } + } - PlistEvent::StartDictionary(_) => try!(self.start_element("dict")), - PlistEvent::EndDictionary => try!(self.end_element("dict")), + PlistEvent::StartDictionary(_) => { + try!(self.start_element("dict")); + self.stack.push(Element::Dictionary(DictionaryState::ExpectKey)); + } + PlistEvent::EndDictionary => return Err(()), // Invalid event PlistEvent::BooleanValue(true) => { try!(self.start_element("true")); @@ -166,18 +218,18 @@ mod tests { } let comparison = " -Author +Author William Shakespeare -Lines +Lines It is a tale told by an idiot, Full of sound and fury, signifying nothing. -Death +Death 1564 -Height +Height 1.6 -Data +Data AAAAvgAAAAMAAAAeAAAA -Birthdate +Birthdate 1981-05-16T11:32:06+00:00"; -- cgit v1.2.3