docx_rs/reader/
font_group.rs

1#![allow(clippy::single_match)]
2
3use std::io::Read;
4use std::str::FromStr;
5
6use xml::attribute::OwnedAttribute;
7use xml::reader::{EventReader, XmlEvent};
8
9use super::*;
10
11fn read_typeface(attributes: &[OwnedAttribute]) -> Option<String> {
12    for a in attributes {
13        let local_name = &a.name.local_name;
14        if let "typeface" = local_name.as_str() {
15            return Some(a.value.to_string());
16        }
17    }
18    None
19}
20
21fn read_script_and_typeface(attributes: &[OwnedAttribute]) -> Option<(String, String)> {
22    let mut script = None;
23    let mut typeface = None;
24    for a in attributes {
25        let local_name = &a.name.local_name;
26        if let "script" = local_name.as_str() {
27            script = Some(a.value.to_string());
28        }
29        if let "typeface" = local_name.as_str() {
30            typeface = Some(a.value.to_string());
31        }
32    }
33    if let (Some(script), Some(typeface)) = (script, typeface) {
34        return Some((script, typeface));
35    }
36    None
37}
38
39impl ElementReader for FontGroup {
40    fn read<R: Read>(
41        r: &mut EventReader<R>,
42        _attrs: &[OwnedAttribute],
43    ) -> Result<Self, ReaderError> {
44        let mut f = FontGroup::default();
45        loop {
46            let e = r.next();
47            match e {
48                Ok(XmlEvent::StartElement {
49                    attributes, name, ..
50                }) => {
51                    let e = AXMLElement::from_str(&name.local_name).unwrap();
52                    match e {
53                        AXMLElement::Latin => {
54                            if let Some(t) = read_typeface(&attributes) {
55                                f.latin = t;
56                            }
57                        }
58                        AXMLElement::Ea => {
59                            if let Some(t) = read_typeface(&attributes) {
60                                f.ea = t;
61                            }
62                        }
63                        AXMLElement::Cs => {
64                            if let Some(t) = read_typeface(&attributes) {
65                                f.cs = t;
66                            }
67                        }
68                        AXMLElement::Font => {
69                            if let Some((script, typeface)) = read_script_and_typeface(&attributes)
70                            {
71                                f.fonts.push(FontSchemeFont { script, typeface })
72                            }
73                        }
74                        _ => {}
75                    }
76                }
77                Ok(XmlEvent::EndElement { name, .. }) => {
78                    let e = AXMLElement::from_str(&name.local_name).unwrap();
79                    match e {
80                        AXMLElement::MajorFont | AXMLElement::MinorFont => {
81                            return Ok(f);
82                        }
83                        _ => {}
84                    }
85                }
86                Err(_) => return Err(ReaderError::XMLReadError),
87                _ => {}
88            }
89        }
90    }
91}