feed_parser/parsers/rss1/
mod.rs

1use crate::parsers::Feed;
2use core::str;
3use quick_xml::de::from_str;
4use quick_xml::events::{BytesEnd, BytesStart, Event};
5use quick_xml::Reader;
6use quick_xml::Writer;
7use std::io::Cursor;
8
9#[cfg(test)]
10mod tests;
11
12pub fn parse(text: &str) -> Result<Vec<Feed>, String> {
13    let mut reader = Reader::from_str(text);
14    reader.config_mut().trim_text(true);
15
16    let mut feeds = Vec::new();
17    let mut writer = Writer::new(Cursor::new(Vec::new()));
18    let mut parsing = false;
19    loop {
20        match reader.read_event() {
21            Ok(Event::Start(e)) => {
22                if parsing {
23                    if e.name().as_ref() == b"dc:creator" {
24                        assert!(writer
25                            .write_event(Event::Start(BytesStart::new("creator")))
26                            .is_ok());
27                    } else if e.name().as_ref() == b"dc:date" {
28                        assert!(writer
29                            .write_event(Event::Start(BytesStart::new("date")))
30                            .is_ok());
31                    } else if e.name().as_ref() == b"pubDate" {
32                        assert!(writer
33                            .write_event(Event::Start(BytesStart::new("publish_date")))
34                            .is_ok());
35                    } else {
36                        assert!(writer.write_event(Event::Start(e.clone())).is_ok());
37                    }
38                }
39                if e.name().as_ref() == b"item" {
40                    assert!(writer
41                        .write_event(Event::Start(BytesStart::new("item")))
42                        .is_ok());
43                    parsing = true;
44                }
45            }
46            Ok(Event::End(e)) => {
47                if e.name().as_ref() == b"item" {
48                    assert!(writer
49                        .write_event(Event::End(BytesEnd::new("item")))
50                        .is_ok());
51                    let feed_text = writer.into_inner().into_inner();
52                    let feed = from_str::<Feed>(str::from_utf8(&feed_text).unwrap()).unwrap();
53                    feeds.push(feed);
54
55                    writer = Writer::new(Cursor::new(Vec::new()));
56                    parsing = false;
57                }
58                if parsing {
59                    if e.name().as_ref() == b"dc:creator" {
60                        assert!(writer
61                            .write_event(Event::End(BytesEnd::new("creator")))
62                            .is_ok());
63                    } else if e.name().as_ref() == b"dc:date" {
64                        assert!(writer
65                            .write_event(Event::End(BytesEnd::new("date")))
66                            .is_ok());
67                    } else if e.name().as_ref() == b"pubDate" {
68                        assert!(writer
69                            .write_event(Event::End(BytesEnd::new("publish_date")))
70                            .is_ok());
71                    } else {
72                        assert!(writer.write_event(Event::End(e)).is_ok());
73                    }
74                }
75            }
76            Ok(Event::Text(e)) => {
77                if parsing {
78                    assert!(writer.write_event(Event::Text(e)).is_ok());
79                }
80            }
81            Ok(Event::CData(e)) => {
82                if parsing {
83                    assert!(writer.write_event(Event::CData(e)).is_ok());
84                }
85            }
86            Ok(Event::Eof) => break,
87            Ok(_e) => {}
88            Err(e) => {
89                return Err(format!(
90                    "Error at position {}: {:?}",
91                    reader.error_position(),
92                    e
93                ))
94            }
95        }
96    }
97    return Ok(feeds);
98}