aboutsummaryrefslogtreecommitdiff
path: root/src/page.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/page.rs')
-rw-r--r--src/page.rs118
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(),
+ }
+ }
+}