use super::escape::escape_text;
#[derive(Debug, Default)]
pub struct XmlWriter {
output: String,
}
impl XmlWriter {
pub fn new() -> Self {
Self::default()
}
pub fn prolog(&mut self) {
self.output
.push_str("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
}
pub fn open(&mut self, name: &str) {
self.open_with(name, &[]);
}
pub fn open_with(&mut self, name: &str, attributes: &[(&str, &str)]) {
self.output.push('<');
self.output.push_str(name);
for (key, value) in attributes {
self.output.push(' ');
self.output.push_str(key);
self.output.push_str("=\"");
self.output.push_str(&escape_text(value));
self.output.push('"');
}
self.output.push('>');
}
pub fn close(&mut self, name: &str) {
self.output.push_str("</");
self.output.push_str(name);
self.output.push('>');
}
pub fn empty(&mut self, name: &str) {
self.output.push('<');
self.output.push_str(name);
self.output.push_str("/>");
}
pub fn text(&mut self, value: &str) {
self.output.push_str(&escape_text(value));
}
pub fn as_str(&self) -> &str {
&self.output
}
pub fn into_string(self) -> String {
self.output
}
}
#[cfg(test)]
mod tests {
use super::XmlWriter;
#[test]
fn nests_elements() {
let mut writer = XmlWriter::new();
writer.open("d:prop");
writer.empty("d:getetag");
writer.close("d:prop");
assert_eq!(writer.as_str(), "<d:prop><d:getetag/></d:prop>");
}
#[test]
fn escapes_attribute_values_and_text() {
let mut writer = XmlWriter::new();
writer.open_with("e", &[("name", "a&b")]);
writer.text("1 < 2");
writer.close("e");
assert_eq!(writer.as_str(), "<e name=\"a&b\">1 < 2</e>");
}
}