feed_parser/parsers/atom/
mod.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
use crate::parsers::Feed;
use core::str;
use quick_xml::de::from_str;
use quick_xml::events::{BytesEnd, BytesStart, BytesText, Event};
use quick_xml::Reader;
use quick_xml::Writer;
use std::io::Cursor;

#[cfg(test)]
mod tests;

pub fn parse(text: &str) -> Vec<Feed> {
    let mut reader = Reader::from_str(text);
    reader.config_mut().trim_text(true);

    let mut feeds = Vec::new();
    let mut writer = Writer::new(Cursor::new(Vec::new()));
    let mut parsing = false;
    loop {
        match reader.read_event() {
            Ok(Event::Start(e)) => {
                if parsing {
                    if e.name().as_ref() == b"dc:creator" {
                        assert!(writer
                            .write_event(Event::Start(BytesStart::new("creator")))
                            .is_ok());
                    } else if e.name().as_ref() == b"dc:date" {
                        assert!(writer
                            .write_event(Event::Start(BytesStart::new("date")))
                            .is_ok());
                    } else if e.name().as_ref() == b"pubDate" {
                        assert!(writer
                            .write_event(Event::Start(BytesStart::new("publish_date")))
                            .is_ok());
                    } else {
                        assert!(writer.write_event(Event::Start(e.clone())).is_ok());
                    }
                }
                if e.name().as_ref() == b"entry" {
                    assert!(writer
                        .write_event(Event::Start(BytesStart::new("entry")))
                        .is_ok());
                    parsing = true;
                }
            }
            Ok(Event::Empty(e)) => {
                if parsing {
                    if e.name().as_ref() == b"link" {
                        for attr in e.attributes() {
                            let attr = attr.unwrap();
                            if attr.key.0 == b"href" {
                                assert!(writer
                                    .write_event(Event::Start(BytesStart::new("link")))
                                    .is_ok());
                                let attr_text: &str = str::from_utf8(attr.value.as_ref()).unwrap();
                                assert!(writer
                                    .write_event(Event::Text(BytesText::new(attr_text)))
                                    .is_ok());
                                assert!(writer
                                    .write_event(Event::End(BytesEnd::new("link")))
                                    .is_ok());
                            }
                        }
                    } else {
                        assert!(writer.write_event(Event::Empty(e)).is_ok());
                    }
                }
            }
            Ok(Event::End(e)) => {
                if e.name().as_ref() == b"entry" {
                    assert!(writer
                        .write_event(Event::End(BytesEnd::new("entry")))
                        .is_ok());
                    let feed_text = writer.into_inner().into_inner();
                    println!("{}", str::from_utf8(&feed_text).unwrap());
                    let feed = from_str::<Feed>(str::from_utf8(&feed_text).unwrap()).unwrap();
                    feeds.push(feed);

                    writer = Writer::new(Cursor::new(Vec::new()));
                    parsing = false;
                }
                if parsing {
                    if e.name().as_ref() == b"dc:creator" {
                        assert!(writer
                            .write_event(Event::End(BytesEnd::new("creator")))
                            .is_ok());
                    } else if e.name().as_ref() == b"dc:date" {
                        assert!(writer
                            .write_event(Event::End(BytesEnd::new("date")))
                            .is_ok());
                    } else if e.name().as_ref() == b"pubDate" {
                        assert!(writer
                            .write_event(Event::End(BytesEnd::new("publish_date")))
                            .is_ok());
                    } else {
                        assert!(writer.write_event(Event::End(e)).is_ok());
                    }
                }
            }
            Ok(Event::Text(e)) => {
                if parsing {
                    assert!(writer.write_event(Event::Text(e)).is_ok());
                }
            }
            Ok(Event::Eof) => break,
            Ok(_e) => {}
            Err(e) => panic!("Error at position {}: {:?}", reader.error_position(), e),
        }
    }
    return feeds;
}