diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/binary.rs | 11 | ||||
| -rw-r--r-- | src/lib.rs | 49 | ||||
| -rw-r--r-- | src/xml.rs | 56 |
3 files changed, 55 insertions, 61 deletions
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<R: Read+Seek> StreamingParser<R> { } impl<R: Read+Seek> Iterator for StreamingParser<R> { - type Item = PlistEvent; + type Item = ParserResult<PlistEvent>; - fn next(&mut self) -> Option<PlistEvent> { + fn next(&mut self) -> Option<ParserResult<PlistEvent>> { 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<PlistEvent> = streaming_parser.collect(); + let events: Vec<PlistEvent> = streaming_parser.map(|e| e.unwrap()).collect(); let comparison = &[ StartPlist, @@ -41,11 +41,9 @@ pub enum PlistEvent { IntegerValue(i64), RealValue(f64), StringValue(String), - - Error(ParserError) } -type ParserResult<T> = Result<T, ParserError>; +pub type ParserResult<T> = Result<T, ParserError>; #[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<IoError> for ParserError { fn from(io_error: IoError) -> ParserError { ParserError::Io(io_error) @@ -110,9 +101,9 @@ impl<R: Read+Seek> StreamingParser<R> { } impl<R: Read+Seek> Iterator for StreamingParser<R> { - type Item = PlistEvent; + type Item = ParserResult<PlistEvent>; - fn next(&mut self) -> Option<PlistEvent> { + fn next(&mut self) -> Option<ParserResult<PlistEvent>> { match *self { StreamingParser::Xml(ref mut parser) => parser.next(), StreamingParser::Binary(ref mut parser) => parser.next() @@ -122,7 +113,7 @@ impl<R: Read+Seek> Iterator for StreamingParser<R> { pub type BuilderResult<T> = Result<T, BuilderError>; -#[derive(Debug, PartialEq)] +#[derive(Debug)] pub enum BuilderError { InvalidEvent, UnsupportedDictionaryKey, @@ -146,7 +137,7 @@ impl<R: Read + Seek> Builder<StreamingParser<R>> { } } -impl<T:Iterator<Item=PlistEvent>> Builder<T> { +impl<T:Iterator<Item=ParserResult<PlistEvent>>> Builder<T> { pub fn from_event_stream(stream: T) -> Builder<T> { Builder { stream: stream, @@ -155,24 +146,29 @@ impl<T:Iterator<Item=PlistEvent>> Builder<T> { } pub fn build(mut self) -> BuilderResult<Plist> { - 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<Plist> { @@ -192,7 +188,7 @@ impl<T:Iterator<Item=PlistEvent>> Builder<T> { 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<T:Iterator<Item=PlistEvent>> Builder<T> { }; loop { - self.bump(); + try!(self.bump()); if let Some(PlistEvent::EndArray) = self.token { self.token.take(); return Ok(values); @@ -221,12 +217,11 @@ impl<T:Iterator<Item=PlistEvent>> Builder<T> { }; 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 @@ -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<W: Write> { xml_writer: EventWriter<W>, @@ -98,8 +98,6 @@ impl<W: Write> Writer<W> { 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<R: Read> StreamingParser<R> { } } - fn read_content<F>(&mut self, f: F) -> PlistEvent where F:FnOnce(String) -> PlistEvent { + 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), - _ => PlistEvent::Error(ParserError::InvalidData) + _ => Err(ParserError::InvalidData) } } } impl<R: Read> Iterator for StreamingParser<R> { - type Item = PlistEvent; + type Item = ParserResult<PlistEvent>; - fn next(&mut self) -> Option<PlistEvent> { + fn next(&mut self) -> Option<ParserResult<PlistEvent>> { loop { match self.xml_reader.next() { XmlEvent::StartElement { name, .. } => { @@ -145,54 +143,54 @@ impl<R: Read> Iterator for StreamingParser<R> { 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<PlistEvent> = streaming_parser.collect(); + let events: Vec<PlistEvent> = streaming_parser.map(|e| e.unwrap()).collect(); let comparison = &[ StartPlist, |
