nextcloud_dav/xml/
writer.rs1use super::escape::escape_text;
4
5#[derive(Debug, Default)]
12pub struct XmlWriter {
13 output: String,
14}
15
16impl XmlWriter {
17 pub fn new() -> Self {
19 Self::default()
20 }
21
22 pub fn prolog(&mut self) {
24 self.output
25 .push_str("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
26 }
27
28 pub fn open(&mut self, name: &str) {
30 self.open_with(name, &[]);
31 }
32
33 pub fn open_with(&mut self, name: &str, attributes: &[(&str, &str)]) {
35 self.output.push('<');
36 self.output.push_str(name);
37 for (key, value) in attributes {
38 self.output.push(' ');
39 self.output.push_str(key);
40 self.output.push_str("=\"");
41 self.output.push_str(&escape_text(value));
42 self.output.push('"');
43 }
44 self.output.push('>');
45 }
46
47 pub fn close(&mut self, name: &str) {
49 self.output.push_str("</");
50 self.output.push_str(name);
51 self.output.push('>');
52 }
53
54 pub fn empty(&mut self, name: &str) {
56 self.output.push('<');
57 self.output.push_str(name);
58 self.output.push_str("/>");
59 }
60
61 pub fn text(&mut self, value: &str) {
63 self.output.push_str(&escape_text(value));
64 }
65
66 pub fn as_str(&self) -> &str {
68 &self.output
69 }
70
71 pub fn into_string(self) -> String {
73 self.output
74 }
75}
76
77#[cfg(test)]
78mod tests {
79 use super::XmlWriter;
80
81 #[test]
82 fn nests_elements() {
83 let mut writer = XmlWriter::new();
84 writer.open("d:prop");
85 writer.empty("d:getetag");
86 writer.close("d:prop");
87 assert_eq!(writer.as_str(), "<d:prop><d:getetag/></d:prop>");
88 }
89
90 #[test]
91 fn escapes_attribute_values_and_text() {
92 let mut writer = XmlWriter::new();
93 writer.open_with("e", &[("name", "a&b")]);
94 writer.text("1 < 2");
95 writer.close("e");
96 assert_eq!(writer.as_str(), "<e name=\"a&b\">1 < 2</e>");
97 }
98}