xlsbye-xml 0.1.0

SpreadsheetML XML writer for xlsbye
Documentation
use quick_xml::events::{BytesDecl, BytesEnd, BytesStart, BytesText, Event};
use quick_xml::Writer;
use std::io::Write;

pub type Result<T> = std::io::Result<T>;

pub struct XmlWriter<W: Write> {
    inner: Writer<W>,
}

impl<W: Write> XmlWriter<W> {
    pub fn new(writer: W) -> Self {
        Self {
            inner: Writer::new_with_indent(writer, b' ', 2),
        }
    }

    pub fn into_inner(self) -> W {
        self.inner.into_inner()
    }

    pub fn writer(&mut self) -> &mut Writer<W> {
        &mut self.inner
    }

    pub fn write_xml_declaration(&mut self) -> Result<()> {
        self.inner
            .write_event(Event::Decl(BytesDecl::new("1.0", Some("UTF-8"), Some("yes"))))
    }

    pub fn write_start_element<I, K, V>(&mut self, name: &str, attrs: I) -> Result<()>
    where
        I: IntoIterator<Item = (K, V)>,
        K: AsRef<str>,
        V: AsRef<str>,
    {
        let mut element = BytesStart::new(name);
        for (key, value) in attrs {
            element.push_attribute((key.as_ref(), value.as_ref()));
        }
        self.inner.write_event(Event::Start(element))
    }

    pub fn write_empty_element<I, K, V>(&mut self, name: &str, attrs: I) -> Result<()>
    where
        I: IntoIterator<Item = (K, V)>,
        K: AsRef<str>,
        V: AsRef<str>,
    {
        let mut element = BytesStart::new(name);
        for (key, value) in attrs {
            element.push_attribute((key.as_ref(), value.as_ref()));
        }
        self.inner.write_event(Event::Empty(element))
    }

    pub fn write_start_element_with_ns<I, N, K1, V1, K2, V2>(
        &mut self,
        name: &str,
        namespaces: N,
        attrs: I,
    ) -> Result<()>
    where
        I: IntoIterator<Item = (K1, V1)>,
        N: IntoIterator<Item = (K2, V2)>,
        K1: AsRef<str>,
        V1: AsRef<str>,
        K2: AsRef<str>,
        V2: AsRef<str>,
    {
        let mut element = BytesStart::new(name);

        for (prefix, uri) in namespaces {
            if prefix.as_ref().is_empty() {
                element.push_attribute(("xmlns", uri.as_ref()));
            } else {
                let key = format!("xmlns:{}", prefix.as_ref());
                element.push_attribute((key.as_str(), uri.as_ref()));
            }
        }

        for (key, value) in attrs {
            element.push_attribute((key.as_ref(), value.as_ref()));
        }

        self.inner.write_event(Event::Start(element))
    }

    pub fn write_end_element(&mut self, name: &str) -> Result<()> {
        self.inner.write_event(Event::End(BytesEnd::new(name)))
    }

    pub fn write_text(&mut self, text: &str) -> Result<()> {
        self.inner.write_event(Event::Text(BytesText::new(text)))
    }

    pub fn write_text_element<I, K, V>(&mut self, name: &str, attrs: I, text: &str) -> Result<()>
    where
        I: IntoIterator<Item = (K, V)>,
        K: AsRef<str>,
        V: AsRef<str>,
    {
        self.write_start_element(name, attrs)?;
        self.write_text(text)?;
        self.write_end_element(name)
    }
}