use std::io::BufRead; use std::str; use quick_xml::reader::Reader; use quick_xml::events::Event; use errors::Result; use xmlutil::{FromXml, element_text}; use revision::Revision; #[derive(Debug, Default, Clone, PartialEq, Serialize, Deserialize)] pub struct Page { pub namespace: i32, pub title: String, pub redirect: Option, pub revision: Revision, } impl FromXml for Page { fn from_xml(reader: &mut Reader) -> Result { let mut page = Page::default(); let mut buf = Vec::new(); loop { match reader.read_event(&mut buf) { Ok(Event::Start(ref e)) => { match e.name() { b"title" => { let res = element_text(reader); page.title = res?; }, b"ns" => { let res = element_text(reader); page.namespace = res?.parse()?; }, b"revision" => { match Revision::from_xml(reader) { Ok(rev) => { page.revision = rev; }, Err(err) => bail!(err), } }, _ => (), } }, Ok(Event::Empty(e)) => { match e.name() { b"redirect" => { for attr in e.attributes().with_checks(false) { if let Ok(attr) = attr { if attr.key == b"title" { page.redirect = Some(str::from_utf8(attr.value)?.into()); } } } }, _ => (), } }, Ok(Event::End(e)) => { if e.name() == b"page" { return Ok(page) } }, Err(err) => bail!(err), _ => (), } } } } pub struct PageIter { reader: Reader, buf: Vec, } impl Iterator for PageIter { type Item = Page; fn next(&mut self) -> Option { loop { match self.reader.read_event(&mut self.buf) { Ok(Event::Start(ref e)) => { match e.name() { b"page" => { match Page::from_xml(&mut self.reader) { Ok(page) => { return Some(page) }, Err(err) => { println!("parse error: {}", err); return None } } } _ => (), } }, Ok(Event::Eof) => return None, Err(err) => { println!("parse error: {}", err); return None } _ => (), } } } } impl PageIter { pub fn new(reader: Reader) -> Self { PageIter { reader, buf: Vec::new(), } } }