1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! WebSettings part
//!
//! The corresponding ZIP item is `/word/webSettings.xml`.
//!

use hard_xml::{XmlRead, XmlResult, XmlWrite, XmlWriter};
use std::io::Write;

use crate::__xml_test_suites;
use crate::schema::{SCHEMA_MAIN, SCHEMA_WORDML_14};

/// The root element of the main document part.
#[derive(Debug, Default, XmlRead, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:webSettings")]
pub struct WebSettings {
    #[xml(child = "w:optimizeForBrowser")]
    pub optimize_for_browser: Option<OptimizeForBrowser>,
    #[xml(child = "w:relyOnVML")]
    pub rely_on_vml: Option<RelyOnVml>,
    #[xml(child = "w:allowPNG")]
    pub allow_png: Option<AllowPNG>,
    #[xml(child = "w:doNotSaveAsSingleFile")]
    pub do_not_save_as_single_file: Option<DoNotSaveAsSingleFile>,
}

#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:optimizeForBrowser")]
pub struct OptimizeForBrowser {}

#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:relyOnVML")]
pub struct RelyOnVml {}

#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:allowPNG")]
pub struct AllowPNG {}

#[derive(Debug, Default, XmlRead, XmlWrite, Clone)]
#[cfg_attr(test, derive(PartialEq))]
#[xml(tag = "w:doNotSaveAsSingleFile")]
pub struct DoNotSaveAsSingleFile {}

impl XmlWrite for WebSettings {
    fn to_writer<W: Write>(&self, writer: &mut XmlWriter<W>) -> XmlResult<()> {
        let WebSettings {
            optimize_for_browser,
            rely_on_vml,
            allow_png,
            do_not_save_as_single_file,
        } = self;

        log::debug!("[WebSettings] Started writing.");
        let _ = write!(writer.inner, "{}", crate::schema::SCHEMA_XML);

        writer.write_element_start("w:webSettings")?;

        writer.write_attribute("xmlns:w", SCHEMA_MAIN)?;

        writer.write_attribute("xmlns:w14", SCHEMA_WORDML_14)?;

        writer.write_element_end_open()?;

        write_attr(optimize_for_browser, writer)?;

        write_attr(rely_on_vml, writer)?;

        write_attr(allow_png, writer)?;

        write_attr(do_not_save_as_single_file, writer)?;

        writer.write_element_end_close("w:webSettings")?;

        log::debug!("[webSettings] Finished writing.");

        Ok(())
    }
}

fn write_attr<W: Write, T: XmlWrite>(
    element: &Option<T>,
    writer: &mut XmlWriter<W>,
) -> Result<(), hard_xml::XmlError> {
    if let Some(e) = element {
        e.to_writer(writer)?;
    };
    Ok(())
}

__xml_test_suites!(
    WebSettings,
    WebSettings::default(),
    format!(
        r#"{}<w:webSettings xmlns:w="{}" xmlns:w14="{}"></w:webSettings>"#,
        crate::schema::SCHEMA_XML,
        SCHEMA_MAIN,
        SCHEMA_WORDML_14
    )
    .as_str(),
);

#[test]
fn regular_namespace() {
    let alt_web_settings = r#"<?xml version="1.0" encoding="UTF-8"?>
    <w:webSettings xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
        <w:allowPNG />
        <w:doNotSaveAsSingleFile />
    </w:webSettings>
    "#;
    let web_settings = WebSettings::from_str(&alt_web_settings).unwrap();
    assert_eq!(web_settings.allow_png, Some(AllowPNG {}));
    assert_eq!(
        web_settings.do_not_save_as_single_file,
        Some(DoNotSaveAsSingleFile {})
    );
}

#[test]
fn alternative_namespace() {
    let alt_web_settings = r#"<?xml version="1.0" encoding="UTF-8"?>
    <ns0:webSettings xmlns:ns0="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
        <ns0:allowPNG />
        <ns0:doNotSaveAsSingleFile />
    </ns0:webSettings>
    "#
    .replace("ns0:", "w:");
    let web_settings = WebSettings::from_str(&alt_web_settings).unwrap();
    assert_eq!(web_settings.allow_png, Some(AllowPNG {}));
    assert_eq!(
        web_settings.do_not_save_as_single_file,
        Some(DoNotSaveAsSingleFile {})
    );
}