Skip to main content

docx_rs/reader/
styles.rs

1use super::*;
2use crate::reader::{FromXML, ReaderError};
3use std::io::Read;
4
5use std::str::FromStr;
6
7impl FromXML for Styles {
8    fn from_xml<R: Read>(reader: R) -> Result<Self, ReaderError> {
9        let mut parser = EventReader::new(reader);
10        let mut styles = Self::default();
11        loop {
12            let e = parser.next();
13            match e {
14                Ok(XmlEvent::StartElement {
15                    attributes, name, ..
16                }) => {
17                    let e = XMLElement::from_str(&name.local_name).unwrap();
18                    match e {
19                        XMLElement::Style => {
20                            if let Ok(s) = Style::read(&mut parser, &attributes) {
21                                styles = styles.add_style(s);
22                            }
23                            continue;
24                        }
25                        XMLElement::DocDefaults => {
26                            if let Ok(d) = DocDefaults::read(&mut parser, &attributes) {
27                                styles = styles.doc_defaults(d);
28                            }
29                            continue;
30                        }
31                        _ => {}
32                    }
33                }
34                Ok(XmlEvent::EndElement { name, .. }) => {
35                    let e = XMLElement::from_str(&name.local_name).unwrap();
36                    if let XMLElement::Styles = e {
37                        break;
38                    }
39                }
40                Err(_) => return Err(ReaderError::XMLReadError),
41                _ => {}
42            }
43        }
44        Ok(styles)
45    }
46}
47
48#[cfg(test)]
49mod tests {
50
51    use super::*;
52    use crate::types::*;
53    #[cfg(test)]
54    use pretty_assertions::assert_eq;
55
56    #[test]
57    fn test_from_xml() {
58        let xml = r#"<w:styles xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
59    <w:style w:type="character" w:styleId="FootnoteTextChar">
60        <w:name w:val="Footnote Text Char"></w:name>
61        <w:rPr>
62            <w:sz w:val="20"></w:sz>
63            <w:szCs w:val="20"></w:szCs>
64        </w:rPr>
65        <w:uiPriority w:val="99"></w:uiPriority>
66        <w:unhideWhenUsed></w:unhideWhenUsed>
67        <w:basedOn w:val="DefaultParagraphFont"></w:basedOn>
68        <w:link w:val="FootnoteText"></w:link>
69        <w:uiPriority w:val="99"></w:uiPriority>
70        <w:semiHidden></w:semiHidden>
71    </w:style>
72</w:styles>"#;
73        let s = Styles::from_xml(xml.as_bytes()).unwrap();
74        let mut styles = Styles::new();
75        styles = styles.add_style(
76            Style::new("FootnoteTextChar", StyleType::Character)
77                .name("Footnote Text Char")
78                .size(20)
79                .based_on("DefaultParagraphFont")
80                .link("FootnoteText"),
81        );
82        assert_eq!(s, styles);
83    }
84}