Skip to main content

docx_rs/reader/
section_property.rs

1use std::io::Read;
2use std::str::FromStr;
3
4use crate::SectionType;
5
6use super::*;
7
8fn read_page_size(attributes: &[OwnedAttribute]) -> Result<PageSize, ReaderError> {
9    let mut size = PageSize::new();
10    for a in attributes {
11        let local_name = &a.name.local_name;
12        match local_name.as_str() {
13            "w" => {
14                size = size.width(value_to_dax(&a.value)? as u32);
15            }
16            "h" => {
17                size = size.height(value_to_dax(&a.value)? as u32);
18            }
19            _ => {}
20        }
21    }
22    Ok(size)
23}
24
25fn read_page_margin(
26    attributes: &[OwnedAttribute],
27) -> Result<crate::types::PageMargin, ReaderError> {
28    let mut margin = crate::types::PageMargin::new();
29    for a in attributes {
30        let local_name = &a.name.local_name;
31        match local_name.as_str() {
32            "top" => {
33                margin = margin.top(value_to_dax(&a.value)? as i32);
34            }
35            "right" => {
36                margin = margin.right(value_to_dax(&a.value)? as i32);
37            }
38            "bottom" => {
39                margin = margin.bottom(value_to_dax(&a.value)? as i32);
40            }
41            "left" => {
42                margin = margin.left(value_to_dax(&a.value)? as i32);
43            }
44            "header" => {
45                margin = margin.header(value_to_dax(&a.value)? as i32);
46            }
47            "footer" => {
48                margin = margin.footer(value_to_dax(&a.value)? as i32);
49            }
50            "gutter" => {
51                margin = margin.gutter(value_to_dax(&a.value)? as i32);
52            }
53            _ => {}
54        }
55    }
56    Ok(margin)
57}
58
59fn read_header_or_footer_reference(
60    attributes: &[OwnedAttribute],
61) -> Result<(String, String), ReaderError> {
62    let mut rid = "".to_owned();
63    let mut header_type = "default".to_owned();
64    for a in attributes {
65        let local_name = &a.name.local_name;
66        match local_name.as_str() {
67            "type" => {
68                header_type = a.value.to_owned();
69            }
70            "id" => {
71                rid = a.value.to_owned();
72            }
73            _ => {}
74        }
75    }
76    Ok((rid, header_type))
77}
78
79impl ElementReader for SectionProperty {
80    fn read<R: Read>(
81        r: &mut EventReader<R>,
82        _attrs: &[OwnedAttribute],
83    ) -> Result<Self, ReaderError> {
84        let mut sp = SectionProperty::new();
85        loop {
86            let e = r.next();
87            match e {
88                Ok(XmlEvent::StartElement {
89                    attributes, name, ..
90                }) => {
91                    let e = XMLElement::from_str(&name.local_name).unwrap();
92                    match e {
93                        XMLElement::PageMargin => {
94                            let margin = read_page_margin(&attributes)?;
95                            sp = sp.page_margin(margin);
96                        }
97                        XMLElement::PageSize => {
98                            let size = read_page_size(&attributes)?;
99                            sp = sp.page_size(size);
100                        }
101                        XMLElement::DocGrid => {
102                            if let Ok(doc_grid) = DocGrid::read(r, &attributes) {
103                                sp = sp.doc_grid(doc_grid);
104                            }
105                        }
106                        XMLElement::PageNumType => {
107                            if let Ok(page_num_type) = PageNumType::read(r, &attributes) {
108                                sp = sp.page_num_type(page_num_type);
109                            }
110                        }
111                        XMLElement::HeaderReference => {
112                            if let Ok((rid, header_type)) =
113                                read_header_or_footer_reference(&attributes)
114                            {
115                                match header_type.as_str() {
116                                    "default" => {
117                                        sp.header_reference =
118                                            Some(HeaderReference::new(header_type, rid));
119                                    }
120                                    "first" => {
121                                        sp.first_header_reference =
122                                            Some(HeaderReference::new(header_type, rid));
123                                    }
124                                    "even" => {
125                                        sp.even_header_reference =
126                                            Some(HeaderReference::new(header_type, rid));
127                                    }
128                                    _ => {}
129                                }
130                            }
131                        }
132                        XMLElement::FooterReference => {
133                            if let Ok((rid, footer_type)) =
134                                read_header_or_footer_reference(&attributes)
135                            {
136                                match footer_type.as_str() {
137                                    "default" => {
138                                        sp.footer_reference =
139                                            Some(FooterReference::new(footer_type, rid));
140                                    }
141                                    "first" => {
142                                        sp.first_footer_reference =
143                                            Some(FooterReference::new(footer_type, rid));
144                                    }
145                                    "even" => {
146                                        sp.even_footer_reference =
147                                            Some(FooterReference::new(footer_type, rid));
148                                    }
149                                    _ => {}
150                                }
151                            }
152                        }
153                        XMLElement::Type => {
154                            if let Some(val) = read_val(&attributes) {
155                                if let Ok(val) = SectionType::from_str(&val) {
156                                    sp.section_type = Some(val);
157                                }
158                            }
159                        }
160                        XMLElement::TitlePg => sp = sp.title_pg(),
161                        _ => {}
162                    }
163                }
164                Ok(XmlEvent::EndElement { name, .. }) => {
165                    let e = XMLElement::from_str(&name.local_name).unwrap();
166                    if e == XMLElement::SectionProperty {
167                        return Ok(sp);
168                    }
169                }
170                Err(_) => return Err(ReaderError::XMLReadError),
171                _ => {}
172            }
173        }
174    }
175}