cdoc-base 0.10.0-alpha.1

Base type definitions for the Courses ecosystem.
Documentation
use crate::node::{Attribute, Node};
use std::fmt::{Display, Formatter};

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 Display for Attribute {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        match self {
            Attribute::Int(n) => write!(f, "{}", n),
            Attribute::Float(n) => write!(f, "{}", n),
            Attribute::String(s) => write!(f, "{}", s),
            Attribute::Enum(v) => write!(f, "{}", v),
            Attribute::Flag => Ok(()),
            Attribute::Compound(_x) => Ok(()),
        }
    }
}

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())
            }
        }
    }
}