use crate::node::{Attribute, Node};
use std::io::Write;
use xml::writer::Result;
use xml::writer::XmlEvent;
use xml::{EmitterConfig, EventWriter};
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())
}
}
}
}