use quick_xml::{XmlReader, Event, Element};
use fromxml::{self, FromXml};
use error::Error;
use category::Category;
use guid::Guid;
use enclosure::Enclosure;
use source::Source;
use extension::ExtensionMap;
use extension::itunes::ITunesItemExtension;
use extension::dublincore::DublinCoreExtension;
#[derive(Debug, Default, Clone, PartialEq)]
pub struct Item {
pub title: Option<String>,
pub link: Option<String>,
pub description: Option<String>,
pub author: Option<String>,
pub categories: Vec<Category>,
pub comments: Option<String>,
pub enclosure: Option<Enclosure>,
pub guid: Option<Guid>,
pub pub_date: Option<String>,
pub source: Option<Source>,
pub content: Option<String>,
pub extensions: ExtensionMap,
pub itunes_ext: Option<ITunesItemExtension>,
pub dublin_core_ext: Option<DublinCoreExtension>,
}
impl FromXml for Item {
fn from_xml<R: ::std::io::BufRead>(mut reader: XmlReader<R>,
_: Element)
-> Result<(Self, XmlReader<R>), Error> {
let mut item = Item::default();
while let Some(e) = reader.next() {
match e {
Ok(Event::Start(element)) => {
match element.name() {
b"category" => {
let (category, reader_) = try!(Category::from_xml(reader, element));
reader = reader_;
item.categories.push(category);
}
b"guid" => {
let (guid, reader_) = try!(Guid::from_xml(reader, element));
reader = reader_;
item.guid = Some(guid);
}
b"enclosure" => {
let (enclosure, reader_) = try!(Enclosure::from_xml(reader, element));
reader = reader_;
item.enclosure = Some(enclosure);
}
b"source" => {
let (source, reader_) = try!(Source::from_xml(reader, element));
reader = reader_;
item.source = Some(source);
}
b"title" => item.title = element_text!(reader),
b"link" => item.link = element_text!(reader),
b"description" => item.description = element_text!(reader),
b"author" => item.author = element_text!(reader),
b"comments" => item.comments = element_text!(reader),
b"pubDate" => item.pub_date = element_text!(reader),
b"content:encoded" => item.content = element_text!(reader),
_ => {
if let Some((ns, name)) = fromxml::extension_name(&element) {
parse_extension!(reader, element, ns, name, item.extensions);
} else {
skip_element!(reader);
}
}
}
}
Ok(Event::End(_)) => {
if !item.extensions.is_empty() {
if let Some(map) = item.extensions.remove("itunes") {
item.itunes_ext = Some(ITunesItemExtension::from_map(map));
}
if let Some(map) = item.extensions.remove("dc") {
item.dublin_core_ext = Some(DublinCoreExtension::from_map(map));
}
}
return Ok((item, reader));
}
Err(err) => return Err(err.into()),
_ => {}
}
}
Err(Error::EOF)
}
}