rss/
item.rs

1use quick_xml::{XmlReader, Event, Element};
2
3use fromxml::{self, FromXml};
4use error::Error;
5use category::Category;
6use guid::Guid;
7use enclosure::Enclosure;
8use source::Source;
9use extension::ExtensionMap;
10use extension::itunes::ITunesItemExtension;
11use extension::dublincore::DublinCoreExtension;
12
13/// A representation of the `<item>` element.
14#[derive(Debug, Default, Clone, PartialEq)]
15pub struct Item {
16    /// The title of the item.
17    pub title: Option<String>,
18    /// The URL of the item.
19    pub link: Option<String>,
20    /// The item synopsis.
21    pub description: Option<String>,
22    /// The email address of author of the item.
23    pub author: Option<String>,
24    /// The categories the item belongs to.
25    pub categories: Vec<Category>,
26    /// The URL for the comments page of the item.
27    pub comments: Option<String>,
28    /// The description of a media object that is attached to the item.
29    pub enclosure: Option<Enclosure>,
30    /// A unique identifier for the item.
31    pub guid: Option<Guid>,
32    /// The date the item was published.
33    pub pub_date: Option<String>,
34    /// The RSS channel the item came from.
35    pub source: Option<Source>,
36    /// The HTML contents of the item.
37    pub content: Option<String>,
38    /// The extensions for the item.
39    pub extensions: ExtensionMap,
40    /// The iTunes extension for the item.
41    pub itunes_ext: Option<ITunesItemExtension>,
42    /// The Dublin Core extension for the item.
43    pub dublin_core_ext: Option<DublinCoreExtension>,
44}
45
46impl FromXml for Item {
47    fn from_xml<R: ::std::io::BufRead>(mut reader: XmlReader<R>,
48                                       _: Element)
49                                       -> Result<(Self, XmlReader<R>), Error> {
50        let mut item = Item::default();
51
52        while let Some(e) = reader.next() {
53            match e {
54                Ok(Event::Start(element)) => {
55                    match element.name() {
56                        b"category" => {
57                            let (category, reader_) = try!(Category::from_xml(reader, element));
58                            reader = reader_;
59                            item.categories.push(category);
60                        }
61                        b"guid" => {
62                            let (guid, reader_) = try!(Guid::from_xml(reader, element));
63                            reader = reader_;
64                            item.guid = Some(guid);
65                        }
66                        b"enclosure" => {
67                            let (enclosure, reader_) = try!(Enclosure::from_xml(reader, element));
68                            reader = reader_;
69                            item.enclosure = Some(enclosure);
70                        }
71                        b"source" => {
72                            let (source, reader_) = try!(Source::from_xml(reader, element));
73                            reader = reader_;
74                            item.source = Some(source);
75                        }
76                        b"title" => item.title = element_text!(reader),
77                        b"link" => item.link = element_text!(reader),
78                        b"description" => item.description = element_text!(reader),
79                        b"author" => item.author = element_text!(reader),
80                        b"comments" => item.comments = element_text!(reader),
81                        b"pubDate" => item.pub_date = element_text!(reader),
82                        b"content:encoded" => item.content = element_text!(reader),
83                        _ => {
84                            if let Some((ns, name)) = fromxml::extension_name(&element) {
85                                parse_extension!(reader, element, ns, name, item.extensions);
86                            } else {
87                                skip_element!(reader);
88                            }
89                        }
90                    }
91                }
92                Ok(Event::End(_)) => {
93                    if !item.extensions.is_empty() {
94                        if let Some(map) = item.extensions.remove("itunes") {
95                            item.itunes_ext = Some(ITunesItemExtension::from_map(map));
96                        }
97
98                        if let Some(map) = item.extensions.remove("dc") {
99                            item.dublin_core_ext = Some(DublinCoreExtension::from_map(map));
100                        }
101                    }
102
103                    return Ok((item, reader));
104                }
105                Err(err) => return Err(err.into()),
106                _ => {}
107            }
108        }
109
110        Err(Error::EOF)
111    }
112}