From 25425310fdfdc76dd3804857257d862f81eb0134 Mon Sep 17 00:00:00 2001 From: Edward Barnard Date: Fri, 28 Aug 2015 20:12:51 +0700 Subject: Remove Error variant from PlistEvent --- src/binary.rs | 11 ++++++----- src/lib.rs | 49 ++++++++++++++++++++++--------------------------- src/xml.rs | 56 +++++++++++++++++++++++++++----------------------------- 3 files changed, 55 insertions(+), 61 deletions(-) (limited to 'src') diff --git a/src/binary.rs b/src/binary.rs index c189c1a..0f1b707 100644 --- a/src/binary.rs +++ b/src/binary.rs @@ -225,12 +225,13 @@ impl StreamingParser { } impl Iterator for StreamingParser { - type Item = PlistEvent; + type Item = ParserResult; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option> { match self.read_next() { - Ok(result) => result, - Err(err) => Some(PlistEvent::Error(err)) + Ok(Some(result)) => Some(Ok(result)), + Err(err) => Some(Err(err)), + Ok(None) => None } } } @@ -249,7 +250,7 @@ mod tests { let reader = File::open(&Path::new("./tests/data/binary.plist")).unwrap(); let streaming_parser = StreamingParser::new(reader); - let events: Vec = streaming_parser.collect(); + let events: Vec = streaming_parser.map(|e| e.unwrap()).collect(); let comparison = &[ StartPlist, diff --git a/src/lib.rs b/src/lib.rs index 8de9efa..7a00ca0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -41,11 +41,9 @@ pub enum PlistEvent { IntegerValue(i64), RealValue(f64), StringValue(String), - - Error(ParserError) } -type ParserResult = Result; +pub type ParserResult = Result; #[derive(Debug)] pub enum ParserError { @@ -55,13 +53,6 @@ pub enum ParserError { Io(IoError) } -// No two errors are the same - this is a bit annoying though -impl PartialEq for ParserError { - fn eq(&self, other: &ParserError) -> bool { - false - } -} - impl From for ParserError { fn from(io_error: IoError) -> ParserError { ParserError::Io(io_error) @@ -110,9 +101,9 @@ impl StreamingParser { } impl Iterator for StreamingParser { - type Item = PlistEvent; + type Item = ParserResult; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option> { match *self { StreamingParser::Xml(ref mut parser) => parser.next(), StreamingParser::Binary(ref mut parser) => parser.next() @@ -122,7 +113,7 @@ impl Iterator for StreamingParser { pub type BuilderResult = Result; -#[derive(Debug, PartialEq)] +#[derive(Debug)] pub enum BuilderError { InvalidEvent, UnsupportedDictionaryKey, @@ -146,7 +137,7 @@ impl Builder> { } } -impl> Builder { +impl>> Builder { pub fn from_event_stream(stream: T) -> Builder { Builder { stream: stream, @@ -155,24 +146,29 @@ impl> Builder { } pub fn build(mut self) -> BuilderResult { - self.bump(); + try!(self.bump()); if let Some(PlistEvent::StartPlist) = self.token { - self.bump(); + try!(self.bump()); } let plist = try!(self.build_value()); - self.bump(); + try!(self.bump()); match self.token { None => (), - Some(PlistEvent::EndPlist) => self.bump(), + Some(PlistEvent::EndPlist) => try!(self.bump()), // The stream should have finished _ => return Err(BuilderError::InvalidEvent) }; Ok(plist) } - fn bump(&mut self) { - self.token = self.stream.next(); + fn bump(&mut self) -> BuilderResult<()> { + self.token = match self.stream.next() { + Some(Ok(token)) => Some(token), + Some(Err(err)) => return Err(BuilderError::ParserError(err)), + None => None, + }; + Ok(()) } fn build_value(&mut self) -> BuilderResult { @@ -192,7 +188,7 @@ impl> Builder { Some(PlistEvent::EndArray) => Err(BuilderError::InvalidEvent), Some(PlistEvent::EndDictionary) => Err(BuilderError::InvalidEvent), - Some(PlistEvent::Error(_)) => Err(BuilderError::InvalidEvent), + // The stream should not have ended here None => Err(BuilderError::InvalidEvent) } @@ -205,7 +201,7 @@ impl> Builder { }; loop { - self.bump(); + try!(self.bump()); if let Some(PlistEvent::EndArray) = self.token { self.token.take(); return Ok(values); @@ -221,12 +217,11 @@ impl> Builder { }; loop { - - self.bump(); + try!(self.bump()); match self.token.take() { Some(PlistEvent::EndDictionary) => return Ok(values), Some(PlistEvent::StringValue(s)) => { - self.bump(); + try!(self.bump()); values.insert(s, try!(self.build_value())); }, _ => { @@ -268,7 +263,7 @@ mod tests { EndPlist, ]; - let builder = Builder::from_event_stream(events.into_iter()); + let builder = Builder::from_event_stream(events.into_iter().map(|e| Ok(e))); let plist = builder.build(); // Expected output @@ -283,6 +278,6 @@ mod tests { dict.insert("Birthdate".to_owned(), Plist::Integer(1564)); dict.insert("Height".to_owned(), Plist::Real(1.60)); - assert_eq!(plist, Ok(Plist::Dictionary(dict))); + assert_eq!(plist.unwrap(), Plist::Dictionary(dict)); } } \ No newline at end of file diff --git a/src/xml.rs b/src/xml.rs index 4e02f54..a85d321 100644 --- a/src/xml.rs +++ b/src/xml.rs @@ -7,7 +7,7 @@ use xml_rs::reader::events::XmlEvent; use xml_rs::writer::{EventWriter, EmitterConfig}; use xml_rs::writer::events::XmlEvent as WriteXmlEvent; -use super::{ParserError, PlistEvent}; +use super::{ParserError, ParserResult, PlistEvent}; pub struct Writer { xml_writer: EventWriter, @@ -98,8 +98,6 @@ impl Writer { 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(()) }) } } @@ -126,18 +124,18 @@ impl StreamingParser { } } - fn read_content(&mut self, f: F) -> PlistEvent where F:FnOnce(String) -> PlistEvent { + fn read_content(&mut self, f: F) -> ParserResult where F:FnOnce(String) -> ParserResult { match self.xml_reader.next() { XmlEvent::Characters(s) => f(s), - _ => PlistEvent::Error(ParserError::InvalidData) + _ => Err(ParserError::InvalidData) } } } impl Iterator for StreamingParser { - type Item = PlistEvent; + type Item = ParserResult; - fn next(&mut self) -> Option { + fn next(&mut self) -> Option> { loop { match self.xml_reader.next() { XmlEvent::StartElement { name, .. } => { @@ -145,54 +143,54 @@ impl Iterator for StreamingParser { self.element_stack.push(name.local_name.clone()); match &name.local_name[..] { - "plist" => return Some(PlistEvent::StartPlist), - "array" => return Some(PlistEvent::StartArray(None)), - "dict" => return Some(PlistEvent::StartDictionary(None)), - "key" => return Some(self.read_content(|s| PlistEvent::StringValue(s))), - "true" => return Some(PlistEvent::BooleanValue(true)), - "false" => return Some(PlistEvent::BooleanValue(false)), + "plist" => return Some(Ok(PlistEvent::StartPlist)), + "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))), "data" => return Some(self.read_content(|s| { match FromBase64::from_base64(&s[..]) { - Ok(b) => PlistEvent::DataValue(b), - Err(_) => PlistEvent::Error(ParserError::InvalidData) + Ok(b) => Ok(PlistEvent::DataValue(b)), + Err(_) => Err(ParserError::InvalidData) } })), - "date" => return Some(self.read_content(|s| PlistEvent::DateValue(s))), + "date" => return Some(self.read_content(|s| Ok(PlistEvent::DateValue(s)))), "integer" => return Some(self.read_content(|s| { match FromStr::from_str(&s) { - Ok(i) => PlistEvent::IntegerValue(i), - Err(_) => PlistEvent::Error(ParserError::InvalidData) + Ok(i) => Ok(PlistEvent::IntegerValue(i)), + Err(_) => Err(ParserError::InvalidData) } })), "real" => return Some(self.read_content(|s| { match FromStr::from_str(&s) { - Ok(f) => PlistEvent::RealValue(f), - Err(_) => PlistEvent::Error(ParserError::InvalidData) + Ok(f) => Ok(PlistEvent::RealValue(f)), + Err(_) => Err(ParserError::InvalidData) } })), - "string" => return Some(self.read_content(|s| PlistEvent::StringValue(s))), - _ => return Some(PlistEvent::Error(ParserError::InvalidData)) + "string" => return Some(self.read_content(|s| Ok(PlistEvent::StringValue(s)))), + _ => return Some(Err(ParserError::InvalidData)) } }, 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 => (), - Some(ref open_name) => return Some(PlistEvent::Error(ParserError::InvalidData)), - None => return Some(PlistEvent::Error(ParserError::InvalidData)) + Some(ref open_name) => return Some(Err(ParserError::InvalidData)), + None => return Some(Err(ParserError::InvalidData)) } match &name.local_name[..] { - "array" => return Some(PlistEvent::EndArray), - "dict" => return Some(PlistEvent::EndDictionary), - "plist" => return Some(PlistEvent::EndPlist), + "array" => return Some(Ok(PlistEvent::EndArray)), + "dict" => return Some(Ok(PlistEvent::EndDictionary)), + "plist" => return Some(Ok(PlistEvent::EndPlist)), _ => () } }, XmlEvent::EndDocument => { match self.element_stack.is_empty() { true => return None, - false => return Some(PlistEvent::Error(ParserError::UnexpectedEof)) + false => return Some(Err(ParserError::UnexpectedEof)) } } _ => () @@ -215,7 +213,7 @@ mod tests { let reader = File::open(&Path::new("./tests/data/xml.plist")).unwrap(); let streaming_parser = StreamingParser::new(reader); - let events: Vec = streaming_parser.collect(); + let events: Vec = streaming_parser.map(|e| e.unwrap()).collect(); let comparison = &[ StartPlist, -- cgit v1.2.3