diff options
Diffstat (limited to 'src/page.rs')
-rw-r--r-- | src/page.rs | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/page.rs b/src/page.rs new file mode 100644 index 0000000..b864640 --- /dev/null +++ b/src/page.rs @@ -0,0 +1,118 @@ +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<String>, + pub revision: Revision, +} + +impl FromXml for Page { + fn from_xml<B: BufRead>(reader: &mut Reader<B>) -> Result<Self> { + 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"namespace" => { + 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<B: BufRead> { + reader: Reader<B>, + buf: Vec<u8>, +} + +impl<B: BufRead> Iterator for PageIter<B> { + type Item = Page; + + fn next(&mut self) -> Option<Self::Item> { + 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<B: BufRead> PageIter<B> { + pub fn new(reader: Reader<B>) -> Self { + PageIter { + reader, + buf: Vec::new(), + } + } +} |