1use hard_xml::{XmlRead, XmlResult, XmlWrite, XmlWriter};
6use std::borrow::Cow;
7use std::io::Write;
8
9use crate::schema::{SCHEMAS_EXTENDED, SCHEMA_DOC_PROPS_V_TYPES, SCHEMA_XML};
10
11#[derive(Debug, XmlRead, XmlWrite, Clone)]
12pub enum App<'a> {
13 #[xml(tag = "Properties")]
14 AppNoApNamespace(AppNoApNamespace<'a>),
15 #[xml(tag = "ap:Properties")]
16 AppWithApNamespace(AppWithApNamespace<'a>),
17}
18
19#[derive(Debug, XmlRead, Clone)]
20#[xml(tag = "Properties")]
21pub struct AppNoApNamespace<'a> {
22 #[xml(flatten_text = "Template")]
23 pub template: Option<Cow<'a, str>>,
24 #[xml(flatten_text = "TotalTime")]
25 pub total_time: Option<Cow<'a, str>>,
26 #[xml(flatten_text = "Pages")]
27 pub pages: Option<Cow<'a, str>>,
28 #[xml(flatten_text = "Words")]
29 pub words: Option<Cow<'a, str>>,
30 #[xml(flatten_text = "Characters")]
31 pub characters: Option<Cow<'a, str>>,
32 #[xml(flatten_text = "Application")]
33 pub application: Option<Cow<'a, str>>,
34 #[xml(flatten_text = "DocSecurity")]
35 pub doc_security: Option<Cow<'a, str>>,
36 #[xml(flatten_text = "Lines")]
37 pub lines: Option<Cow<'a, str>>,
38 #[xml(flatten_text = "Paragraphs")]
39 pub paragraphs: Option<Cow<'a, str>>,
40 #[xml(flatten_text = "ScaleCrop")]
41 pub scale_crop: Option<Cow<'a, str>>,
42 #[xml(flatten_text = "Company")]
43 pub company: Option<Cow<'a, str>>,
44 #[xml(flatten_text = "LinksUpToDate")]
45 pub links_up_to_date: Option<Cow<'a, str>>,
46 #[xml(flatten_text = "CharactersWithSpaces")]
47 pub characters_with_spaces: Option<Cow<'a, str>>,
48 #[xml(flatten_text = "SharedDoc")]
49 pub shared_doc: Option<Cow<'a, str>>,
50 #[xml(flatten_text = "HyperlinksChanged")]
51 pub hyperlinks_changed: Option<Cow<'a, str>>,
52 #[xml(flatten_text = "AppVersion")]
53 pub app_version: Option<Cow<'a, str>>,
54}
55
56#[derive(Debug, XmlRead, Clone)]
57#[xml(tag = "ap:Properties")]
58pub struct AppWithApNamespace<'a> {
59 #[xml(flatten_text = "ap:Template")]
60 pub template: Option<Cow<'a, str>>,
61 #[xml(flatten_text = "ap:TotalTime")]
62 pub total_time: Option<Cow<'a, str>>,
63 #[xml(flatten_text = "ap:Pages")]
64 pub pages: Option<Cow<'a, str>>,
65 #[xml(flatten_text = "ap:Words")]
66 pub words: Option<Cow<'a, str>>,
67 #[xml(flatten_text = "ap:Characters")]
68 pub characters: Option<Cow<'a, str>>,
69 #[xml(flatten_text = "ap:Application")]
70 pub application: Option<Cow<'a, str>>,
71 #[xml(flatten_text = "ap:DocSecurity")]
72 pub doc_security: Option<Cow<'a, str>>,
73 #[xml(flatten_text = "ap:Lines")]
74 pub lines: Option<Cow<'a, str>>,
75 #[xml(flatten_text = "ap:Paragraphs")]
76 pub paragraphs: Option<Cow<'a, str>>,
77 #[xml(flatten_text = "ap:ScaleCrop")]
78 pub scale_crop: Option<Cow<'a, str>>,
79 #[xml(flatten_text = "ap:Company")]
80 pub company: Option<Cow<'a, str>>,
81 #[xml(flatten_text = "ap:LinksUpToDate")]
82 pub links_up_to_date: Option<Cow<'a, str>>,
83 #[xml(flatten_text = "ap:CharactersWithSpaces")]
84 pub characters_with_spaces: Option<Cow<'a, str>>,
85 #[xml(flatten_text = "ap:SharedDoc")]
86 pub shared_doc: Option<Cow<'a, str>>,
87 #[xml(flatten_text = "ap:HyperlinksChanged")]
88 pub hyperlinks_changed: Option<Cow<'a, str>>,
89 #[xml(flatten_text = "ap:AppVersion")]
90 pub app_version: Option<Cow<'a, str>>,
91}
92
93impl Default for AppNoApNamespace<'static> {
94 fn default() -> AppNoApNamespace<'static> {
95 AppNoApNamespace {
96 template: Some("Normal.dotm".into()),
97 total_time: Some("1".into()),
98 pages: Some("1".into()),
99 words: Some("0".into()),
100 characters: Some("0".into()),
101 application: Some("docx-rs".into()),
102 doc_security: Some("0".into()),
103 lines: Some("0".into()),
104 paragraphs: Some("1".into()),
105 scale_crop: Some("false".into()),
106 company: Some("MS".into()),
107 links_up_to_date: Some("false".into()),
108 characters_with_spaces: Some("25".into()),
109 shared_doc: Some("false".into()),
110 hyperlinks_changed: Some("false".into()),
111 app_version: Some("12.0000".into()),
112 }
113 }
114}
115
116impl Default for AppWithApNamespace<'static> {
117 fn default() -> AppWithApNamespace<'static> {
118 AppWithApNamespace {
119 template: Some("Normal.dotm".into()),
120 total_time: Some("1".into()),
121 pages: Some("1".into()),
122 words: Some("0".into()),
123 characters: Some("0".into()),
124 application: Some("docx-rs".into()),
125 doc_security: Some("0".into()),
126 lines: Some("0".into()),
127 paragraphs: Some("1".into()),
128 scale_crop: Some("false".into()),
129 company: Some("MS".into()),
130 links_up_to_date: Some("false".into()),
131 characters_with_spaces: Some("25".into()),
132 shared_doc: Some("false".into()),
133 hyperlinks_changed: Some("false".into()),
134 app_version: Some("12.0000".into()),
135 }
136 }
137}
138
139impl<'a> XmlWrite for AppNoApNamespace<'a> {
140 fn to_writer<W: Write>(&self, writer: &mut XmlWriter<W>) -> XmlResult<()> {
141 let AppNoApNamespace {
142 template,
143 total_time,
144 pages,
145 words,
146 characters,
147 application,
148 doc_security,
149 lines,
150 paragraphs,
151 scale_crop,
152 company,
153 links_up_to_date,
154 characters_with_spaces,
155 shared_doc,
156 hyperlinks_changed,
157 app_version,
158 } = self;
159
160 log::debug!("[App] Started writing.");
161
162 let _ = write!(writer.inner, "{}", SCHEMA_XML);
163
164 writer.write_element_start("Properties")?;
165
166 writer.write_attribute("xmlns", SCHEMAS_EXTENDED)?;
167 writer.write_attribute("xmlns:vt", SCHEMA_DOC_PROPS_V_TYPES)?;
168
169 if template.is_none()
170 && total_time.is_none()
171 && pages.is_none()
172 && words.is_none()
173 && characters.is_none()
174 && application.is_none()
175 && doc_security.is_none()
176 && lines.is_none()
177 && paragraphs.is_none()
178 && scale_crop.is_none()
179 && company.is_none()
180 && links_up_to_date.is_none()
181 && characters_with_spaces.is_none()
182 && shared_doc.is_none()
183 && hyperlinks_changed.is_none()
184 && app_version.is_none()
185 {
186 writer.write_element_end_empty()?;
187 } else {
188 writer.write_element_end_open()?;
189 if let Some(val) = template {
190 writer.write_flatten_text("Template", val, false)?;
191 }
192 if let Some(val) = total_time {
193 writer.write_flatten_text("TotalTime", val, false)?;
194 }
195 if let Some(val) = pages {
196 writer.write_flatten_text("Pages", val, false)?;
197 }
198 if let Some(val) = words {
199 writer.write_flatten_text("Words", val, false)?;
200 }
201 if let Some(val) = characters {
202 writer.write_flatten_text("Characters", val, false)?;
203 }
204 if let Some(val) = application {
205 writer.write_flatten_text("Application", val, false)?;
206 }
207 if let Some(val) = doc_security {
208 writer.write_flatten_text("DocSecurity", val, false)?;
209 }
210 if let Some(val) = lines {
211 writer.write_flatten_text("Lines", val, false)?;
212 }
213 if let Some(val) = paragraphs {
214 writer.write_flatten_text("Paragraphs", val, false)?;
215 }
216 if let Some(val) = scale_crop {
217 writer.write_flatten_text("ScaleCrop", val, false)?;
218 }
219 if let Some(val) = company {
220 writer.write_flatten_text("Company", val, false)?;
221 }
222 if let Some(val) = links_up_to_date {
223 writer.write_flatten_text("LinksUpToDate", val, false)?;
224 }
225 if let Some(val) = characters_with_spaces {
226 writer.write_flatten_text("CharactersWithSpaces", val, false)?;
227 }
228 if let Some(val) = shared_doc {
229 writer.write_flatten_text("SharedDoc", val, false)?;
230 }
231 if let Some(val) = hyperlinks_changed {
232 writer.write_flatten_text("HyperlinksChanged", val, false)?;
233 }
234 if let Some(val) = app_version {
235 writer.write_flatten_text("AppVersion", val, false)?;
236 }
237 writer.write_element_end_close("Properties")?;
238 }
239
240 log::debug!("[App] Finished writing.");
241
242 Ok(())
243 }
244}
245
246impl<'a> XmlWrite for AppWithApNamespace<'a> {
247 fn to_writer<W: Write>(&self, writer: &mut XmlWriter<W>) -> XmlResult<()> {
248 let AppWithApNamespace {
249 template,
250 total_time,
251 pages,
252 words,
253 characters,
254 application,
255 doc_security,
256 lines,
257 paragraphs,
258 scale_crop,
259 company,
260 links_up_to_date,
261 characters_with_spaces,
262 shared_doc,
263 hyperlinks_changed,
264 app_version,
265 } = self;
266
267 log::debug!("[App] Started writing.");
268
269 let _ = write!(writer.inner, "{}", SCHEMA_XML);
270
271 writer.write_element_start("ap:Properties")?;
272
273 writer.write_attribute("xmlns", SCHEMAS_EXTENDED)?;
274 writer.write_attribute("xmlns:vt", SCHEMA_DOC_PROPS_V_TYPES)?;
275
276 if template.is_none()
277 && total_time.is_none()
278 && pages.is_none()
279 && words.is_none()
280 && characters.is_none()
281 && application.is_none()
282 && doc_security.is_none()
283 && lines.is_none()
284 && paragraphs.is_none()
285 && scale_crop.is_none()
286 && company.is_none()
287 && links_up_to_date.is_none()
288 && characters_with_spaces.is_none()
289 && shared_doc.is_none()
290 && hyperlinks_changed.is_none()
291 && app_version.is_none()
292 {
293 writer.write_element_end_empty()?;
294 } else {
295 writer.write_element_end_open()?;
296 if let Some(val) = template {
297 writer.write_flatten_text("ap:Template", val, false)?;
298 }
299 if let Some(val) = total_time {
300 writer.write_flatten_text("ap:TotalTime", val, false)?;
301 }
302 if let Some(val) = pages {
303 writer.write_flatten_text("ap:Pages", val, false)?;
304 }
305 if let Some(val) = words {
306 writer.write_flatten_text("ap:Words", val, false)?;
307 }
308 if let Some(val) = characters {
309 writer.write_flatten_text("ap:Characters", val, false)?;
310 }
311 if let Some(val) = application {
312 writer.write_flatten_text("ap:Application", val, false)?;
313 }
314 if let Some(val) = doc_security {
315 writer.write_flatten_text("ap:DocSecurity", val, false)?;
316 }
317 if let Some(val) = lines {
318 writer.write_flatten_text("ap:Lines", val, false)?;
319 }
320 if let Some(val) = paragraphs {
321 writer.write_flatten_text("ap:Paragraphs", val, false)?;
322 }
323 if let Some(val) = scale_crop {
324 writer.write_flatten_text("ap:ScaleCrop", val, false)?;
325 }
326 if let Some(val) = company {
327 writer.write_flatten_text("ap:Company", val, false)?;
328 }
329 if let Some(val) = links_up_to_date {
330 writer.write_flatten_text("ap:LinksUpToDate", val, false)?;
331 }
332 if let Some(val) = characters_with_spaces {
333 writer.write_flatten_text("ap:CharactersWithSpaces", val, false)?;
334 }
335 if let Some(val) = shared_doc {
336 writer.write_flatten_text("ap:SharedDoc", val, false)?;
337 }
338 if let Some(val) = hyperlinks_changed {
339 writer.write_flatten_text("ap:HyperlinksChanged", val, false)?;
340 }
341 if let Some(val) = app_version {
342 writer.write_flatten_text("ap:AppVersion", val, false)?;
343 }
344 writer.write_element_end_close("ap:Properties")?;
345 }
346
347 log::debug!("[App] Finished writing.");
348
349 Ok(())
350 }
351}