docx_rs/reader/
section_property.rs1use 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}