Skip to content

Commit

Permalink
Swap xml-rs out with rustyxml
Browse files Browse the repository at this point in the history
  • Loading branch information
frewsxcv committed Feb 26, 2015
1 parent 499538f commit f261c40
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 141 deletions.
6 changes: 2 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,5 @@ name = "rust-rss"
version = "0.0.1"
authors = ["Corey Farwell <coreyf@rwell.org>"]


[dependencies]

xml-rs = "0.1.19"
[dependencies.RustyXML]
git = "https://github.com/Florob/RustyXML"
190 changes: 53 additions & 137 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,195 +1,111 @@
#![feature(old_io)]

extern crate xml;

use xml::attribute::Attribute;
use xml::common::XmlVersion;
use xml::name::Name;
use xml::namespace::Namespace;
use xml::writer::EventWriter;
use xml::writer::events::XmlEvent;


fn add_block<'a>(events: &mut Vec<XmlEvent<'a>>, namespace: &'a Namespace, tag_name: &'static str, chars: &'a str) {
// <(tag_name)>
events.push(XmlEvent::StartElement {
name: Name::local(tag_name),
attributes: vec![],
namespace: namespace,
});

events.push(XmlEvent::Characters(chars));

// </(tag_name)>
events.push(XmlEvent::EndElement {
name: Name::local(tag_name),
});
}
use xml::{Element, Xml};


trait Write {
fn write<W: Writer>(&self, writer: W) -> Result<(), ()>;
fn elem_with_text(tag_name: &'static str, chars: &str) -> Element {
let mut elem = Element::new(tag_name, None, &[]);
elem.text(chars);
elem
}


trait ToXml<'a> {
// todo: get rid of namespace parameter
fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent>;
trait ToXml<> {
fn to_xml(&self) -> Element;
}


/// RSS version 2.0
pub struct Rss<'a>(pub Vec<Channel<'a>>);

impl<'a> ToXml<'a> for Rss<'a> {
fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent> {
let mut events = vec![];

// <?xml version="1.0" encoding="UTF-8"?>
events.push(XmlEvent::StartDocument{
version: XmlVersion::Version10,
encoding: Some("UTF-8"),
standalone: None,
});

// <rss version="2.0">
events.push(XmlEvent::StartElement {
name: Name::local("rss"),
attributes: vec![
Attribute::new(Name::local("version"), "2.0"),
],
namespace: namespace,
});
pub struct Rss(pub Vec<Channel>);

impl ToXml for Rss {
fn to_xml(&self) -> Element {
let mut rss = Element::new("rss", None, &[("version", None, "2.0")]);

let &Rss(ref channels) = self;
for channel in channels {
for event in channel.to_xml(namespace) {
events.push(event);
}
rss.tag(channel.to_xml());
}

// </rss>
events.push(XmlEvent::EndElement {
name: Name::local("rss"),
});

events
rss
}
}

impl<'a> Write for Rss<'a> {
fn write<W: Writer>(&self, writer: W) -> Result<(), ()> {
let mut event_writer = EventWriter::new(writer);

let namespace = Namespace::empty();
let events = self.to_xml(&namespace);

for event in events {
match event_writer.write(event) {
Ok(..) => (),
Err(..) => return Err(()),
}
};

Ok(())
impl Rss {
fn to_string(&self) -> String {
let mut ret = format!("{}", Xml::PINode("xml version='1.0' encoding='UTF-8'".to_string()));
ret.push_str(&format!("{}", self.to_xml()));
ret
}
}


pub struct Channel<'a> {
pub title: &'a str,
pub link: &'a str,
pub description: &'a str,
pub items: Vec<Item<'a>>,
pub struct Channel {
pub title: String,
pub link: String,
pub description: String,
pub items: Vec<Item>,
}

impl<'a> ToXml<'a> for Channel<'a> {
fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent> {
let mut events = vec![];

// <channel>
events.push(XmlEvent::StartElement {
name: Name::local("channel"),
attributes: vec![],
namespace: namespace,
});
impl ToXml for Channel {
fn to_xml(&self) -> Element {
let mut channel = Element::new("channel", None, &[]);

add_block(&mut events, namespace, "title", self.title);
add_block(&mut events, namespace, "link", self.link);
add_block(&mut events, namespace, "description", self.description);
channel.tag(elem_with_text("title", &self.title));
channel.tag(elem_with_text("link", &self.link));
channel.tag(elem_with_text("description", &self.description));

for item in &self.items {
for event in item.to_xml(namespace) {
events.push(event);
}
channel.tag(item.to_xml());
}

// </channel>
events.push(XmlEvent::EndElement {
name: Name::local("channel"),
});

events
channel
}
}

pub struct Item<'a> {
pub title: Option<&'a str>,
pub link: Option<&'a str>,
pub description: Option<&'a str>,
pub struct Item {
pub title: Option<String>,
pub link: Option<String>,
pub description: Option<String>,
}


impl<'a> ToXml<'a> for Item<'a> {
fn to_xml(&'a self, namespace: &'a Namespace) -> Vec<XmlEvent> {
let mut events = vec![];

// <item>
events.push(XmlEvent::StartElement {
name: Name::local("item"),
attributes: vec![],
namespace: namespace,
});
impl ToXml for Item {
fn to_xml(&self) -> Element {
let mut item = Element::new("item", None, &[]);

if let Some(s) = self.title {
add_block(&mut events, namespace, "title", s);
if let Some(ref s) = self.title {
item.tag(elem_with_text("title", s));
}

if let Some(s) = self.link {
add_block(&mut events, namespace, "link", s);
if let Some(ref s) = self.link {
item.tag(elem_with_text("link", s));
}

if let Some(s) = self.description {
add_block(&mut events, namespace, "description", s);
if let Some(ref s) = self.description {
item.tag(elem_with_text("description", s));
}

// </item>
events.push(XmlEvent::EndElement {
name: Name::local("item"),
});

events
item
}
}


#[test]
fn test_consruct() {
use std::old_io;

let item = Item {
title: Some("My first post!"),
link: Some("http://myblog.com/post1"),
description: Some("This is my first post"),
title: Some(String::from_str("My first post!")),
link: Some(String::from_str("http://myblog.com/post1")),
description: Some(String::from_str("This is my first post")),
};

let channel = Channel {
title: "My Blog",
link: "http://myblog.com",
description: "Where I write stuff",
title: String::from_str("My Blog"),
link: String::from_str("http://myblog.com"),
description: String::from_str("Where I write stuff"),
items: vec![item],
};

let rss = Rss(vec![channel]);
rss.write(old_io::stdout());
assert_eq!(rss.to_string(), "<?xml version=\'1.0\' encoding=\'UTF-8\'?><rss version=\'2.0\'><channel><title>My Blog</title><link>http://myblog.com</link><description>Where I write stuff</description><item><title>My first post!</title><link>http://myblog.com/post1</link><description>This is my first post</description></item></channel></rss>");
}

0 comments on commit f261c40

Please sign in to comment.