xml_builder/
xml.rs

1use std::io::Write;
2
3use crate::{Result, XMLElement, XMLVersion};
4
5/// Structure representing a XML document.
6/// It must be used to create a XML document.
7pub struct XML {
8    /// The XML version to set for the document.
9    ///
10    /// Defaults to `XML1.0`.
11    version: XMLVersion,
12
13    /// The encoding to set for the document.
14    ///
15    /// Defaults to `UTF-8`.
16    encoding: String,
17
18    /// XML standalone attribute.
19    ///
20    /// A `None` value indicates no displaying.
21    ///
22    /// Defaults to `None`
23    standalone: Option<bool>,
24
25    /// Whether the XML attributes should be sorted or not.
26    ///
27    /// Defaults to `false`.
28    sort_attributes: bool,
29
30    /// Whether we want to indentate the document.
31    ///
32    /// Defaults to `true`.
33    indent: bool,
34
35    /// Whether we want to break lines or not.
36    ///
37    /// Defaults to `true`.
38    break_lines: bool,
39
40    /// Whether we want to expand empty tags or not.
41    ///
42    /// Defaults to `false`.
43    expand_empty_tags: bool,
44
45    /// The root XML element.
46    root: Option<XMLElement>,
47}
48
49impl XML {
50    pub(crate) fn new(
51        version: XMLVersion,
52        encoding: String,
53        standalone: Option<bool>,
54        indent: bool,
55        sort_attributes: bool,
56        break_lines: bool,
57        expand_empty_tags: bool,
58    ) -> Self {
59        Self {
60            version,
61            encoding,
62            standalone,
63            indent,
64            sort_attributes,
65            break_lines,
66            expand_empty_tags,
67            root: None,
68        }
69    }
70
71    /// Sets the XML document root element.
72    ///
73    /// # Arguments
74    ///
75    /// `element` - An XMLElement qualified as root for the XML document.
76    pub fn set_root_element(&mut self, element: XMLElement) {
77        self.root = Some(element);
78    }
79
80    /// Generates an XML document into the specified `Writer`.
81    ///
82    /// Consumes the XML object.
83    pub fn generate<W: Write>(self, mut writer: W) -> Result<()> {
84        let standalone_attribute = match self.standalone {
85            Some(_) => r#" standalone="yes""#.to_string(),
86            None => String::default(),
87        };
88        let suffix = match self.break_lines {
89            true => "\n",
90            false => "",
91        };
92
93        write!(
94            writer,
95            r#"<?xml version="{}" encoding="{}"{}?>{}"#,
96            self.version, self.encoding, standalone_attribute, suffix
97        )?;
98
99        // And then XML elements if present...
100        if let Some(elem) = &self.root {
101            elem.render(
102                &mut writer,
103                self.sort_attributes,
104                self.indent,
105                self.break_lines,
106                self.expand_empty_tags,
107            )?;
108        }
109
110        Ok(())
111    }
112}