docx_rs/reader/
hyperlink.rs

1use std::io::Read;
2use std::str::FromStr;
3
4use xml::attribute::OwnedAttribute;
5use xml::reader::{EventReader, XmlEvent};
6
7use super::*;
8
9use super::attributes::*;
10
11impl ElementReader for Hyperlink {
12    fn read<R: Read>(
13        r: &mut EventReader<R>,
14        attrs: &[OwnedAttribute],
15    ) -> Result<Self, ReaderError> {
16        let mut rid: Option<String> = read(attrs, "id");
17        let mut anchor: Option<String> = read(attrs, "anchor");
18        let history: Option<String> = read(attrs, "history");
19        let mut link = Hyperlink {
20            link: if anchor.is_some() {
21                HyperlinkData::Anchor {
22                    anchor: anchor.take().unwrap(),
23                }
24            } else {
25                HyperlinkData::External {
26                    rid: rid.take().unwrap_or_default(),
27                    path: String::default(), // not used
28                }
29            },
30            history: history.map(|h| usize::from_str(&h).unwrap_or(1)),
31            children: vec![],
32        };
33
34        loop {
35            let e = r.next();
36            match e {
37                Ok(XmlEvent::StartElement {
38                    attributes, name, ..
39                }) => {
40                    let e = XMLElement::from_str(&name.local_name).unwrap();
41
42                    match e {
43                        XMLElement::Run => {
44                            if let Ok(run) = Run::read(r, attrs) {
45                                link = link.add_run(run);
46                            }
47                            continue;
48                        }
49                        XMLElement::Insert => {
50                            if let Ok(ins) = Insert::read(r, &attributes) {
51                                link = link.add_insert(ins);
52                            }
53                            continue;
54                        }
55                        XMLElement::Delete => {
56                            if let Ok(del) = Delete::read(r, &attributes) {
57                                link = link.add_delete(del);
58                            }
59                            continue;
60                        }
61                        XMLElement::BookmarkStart => {
62                            if let Ok(s) = BookmarkStart::read(r, &attributes) {
63                                link = link.add_bookmark_start(s.id, s.name);
64                            }
65                            continue;
66                        }
67                        XMLElement::BookmarkEnd => {
68                            if let Ok(e) = BookmarkEnd::read(r, &attributes) {
69                                link = link.add_bookmark_end(e.id);
70                            }
71                            continue;
72                        }
73                        XMLElement::CommentRangeStart => {
74                            if let Some(id) = read(&attributes, "id") {
75                                if let Ok(id) = usize::from_str(&id) {
76                                    let comment = Comment::new(id);
77                                    link = link.add_comment_start(comment);
78                                }
79                            }
80                            continue;
81                        }
82                        XMLElement::CommentRangeEnd => {
83                            if let Some(id) = read(&attributes, "id") {
84                                if let Ok(id) = usize::from_str(&id) {
85                                    link = link.add_comment_end(id);
86                                }
87                            }
88                            continue;
89                        }
90                        _ => {}
91                    }
92                }
93                Ok(XmlEvent::EndElement { name, .. }) => {
94                    let e = XMLElement::from_str(&name.local_name).unwrap();
95                    if e == XMLElement::Hyperlink {
96                        return Ok(link);
97                    }
98                }
99                Err(_) => return Err(ReaderError::XMLReadError),
100                _ => {}
101            }
102        }
103    }
104}