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
use crate::node::{Attribute, Node};

use std::io::Write;
use xml::writer::Result;
use xml::writer::XmlEvent;
use xml::{EmitterConfig, EventWriter};

// impl Document {
//     pub fn write_xml(&self, writer: impl Write) -> Result<()> {
//         let mut writer = EmitterConfig::new()
//             .perform_indent(true)
//             .create_writer(writer);
//
//         for element in &self.content {
//             element.write_xml(&mut writer)?;
//         }
//
//         Ok(())
//     }
// }

pub fn write_elements_to_xml(elements: &Vec<Node>, writer: impl Write) -> Result<()> {
    let mut writer = EmitterConfig::new()
        .perform_indent(true)
        .create_writer(writer);

    writer
        .write(XmlEvent::start_element("document").ns("parameter", "document.command.parameter"))?;

    for element in elements {
        element.write_xml(&mut writer)?;
    }

    writer.write(XmlEvent::end_element())?;

    Ok(())
}

impl Attribute {
    pub fn to_string(&self) -> String {
        match self {
            Attribute::Int(n) => n.to_string(),
            Attribute::Float(n) => n.to_string(),
            Attribute::String(s) => s.clone(),
            Attribute::Enum(v) => v.clone(),
            Attribute::Flag => "".to_string(),
            Attribute::Compound(_x) => "".to_string(),
        }
    }
}

impl Node {
    pub fn write_xml<W: Write>(&self, writer: &mut EventWriter<W>) -> Result<()> {
        match self {
            Node::Plain(s) => {
                writer.write(XmlEvent::start_element("text"))?;
                writer.write(XmlEvent::characters(s.as_str()))?;
                writer.write(XmlEvent::end_element())
            }
            Node::Compound(node) => {
                let mut start = XmlEvent::start_element(node.type_id.as_str());
                let attr: Vec<(String, String)> = node
                    .attributes
                    .iter()
                    .map(|(k, v)| (k.clone().unwrap_or_default(), v.to_string()))
                    .collect();
                for (k, v) in &attr {
                    start = start.attr(k.as_str(), v);
                }
                writer.write(start)?;

                for c in &node.children {
                    c.write_xml(writer)?;
                }

                writer.write(XmlEvent::end_element())
            }
            Node::Script(script) => {
                writer.write(XmlEvent::start_element("rhai_script"))?;
                for (i, elem) in script.elements.iter().enumerate() {
                    writer
                        .write(XmlEvent::start_element("element").attr("index", &i.to_string()))?;
                    for child in elem {
                        child.write_xml(writer)?;
                    }
                    writer.write(XmlEvent::end_element())?;
                }

                writer.write(XmlEvent::start_element("src"))?;
                writer.write(XmlEvent::characters(&script.src))?;
                writer.write(XmlEvent::end_element())?;

                writer.write(XmlEvent::end_element())
            }
        }
    }
}