cdoc_base/node/
xml_writer.rs

1use crate::node::{Attribute, Node};
2use std::fmt::{Display, Formatter};
3
4use std::io::Write;
5use xml::writer::Result;
6use xml::writer::XmlEvent;
7use xml::{EmitterConfig, EventWriter};
8
9// impl Document {
10//     pub fn write_xml(&self, writer: impl Write) -> Result<()> {
11//         let mut writer = EmitterConfig::new()
12//             .perform_indent(true)
13//             .create_writer(writer);
14//
15//         for element in &self.content {
16//             element.write_xml(&mut writer)?;
17//         }
18//
19//         Ok(())
20//     }
21// }
22
23pub fn write_elements_to_xml(elements: &Vec<Node>, writer: impl Write) -> Result<()> {
24    let mut writer = EmitterConfig::new()
25        .perform_indent(true)
26        .create_writer(writer);
27
28    writer
29        .write(XmlEvent::start_element("document").ns("parameter", "document.command.parameter"))?;
30
31    for element in elements {
32        element.write_xml(&mut writer)?;
33    }
34
35    writer.write(XmlEvent::end_element())?;
36
37    Ok(())
38}
39
40impl Display for Attribute {
41    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
42        match self {
43            Attribute::Int(n) => write!(f, "{}", n),
44            Attribute::Float(n) => write!(f, "{}", n),
45            Attribute::String(s) => write!(f, "{}", s),
46            Attribute::Enum(v) => write!(f, "{}", v),
47            Attribute::Flag => Ok(()),
48            Attribute::Compound(_x) => Ok(()),
49        }
50    }
51}
52
53impl Node {
54    pub fn write_xml<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<()> {
55        match self {
56            Node::Plain(s) => {
57                writer.write(XmlEvent::start_element("text"))?;
58                writer.write(XmlEvent::characters(s.as_str()))?;
59                writer.write(XmlEvent::end_element())
60            }
61            Node::Compound(node) => {
62                let mut start = XmlEvent::start_element(node.type_id.as_str());
63                let attr: Vec<(String, String)> = node
64                    .attributes
65                    .iter()
66                    .map(|(k, v)| (k.clone().unwrap_or_default(), v.to_string()))
67                    .collect();
68                for (k, v) in &attr {
69                    start = start.attr(k.as_str(), v);
70                }
71                writer.write(start)?;
72
73                for c in &node.children {
74                    c.write_xml(writer)?;
75                }
76
77                writer.write(XmlEvent::end_element())
78            }
79            Node::Script(script) => {
80                writer.write(XmlEvent::start_element("rhai_script"))?;
81                for (i, elem) in script.elements.iter().enumerate() {
82                    writer
83                        .write(XmlEvent::start_element("element").attr("index", &i.to_string()))?;
84                    for child in elem {
85                        child.write_xml(writer)?;
86                    }
87                    writer.write(XmlEvent::end_element())?;
88                }
89
90                writer.write(XmlEvent::start_element("src"))?;
91                writer.write(XmlEvent::characters(&script.src))?;
92                writer.write(XmlEvent::end_element())?;
93
94                writer.write(XmlEvent::end_element())
95            }
96        }
97    }
98}