lib3mf_core/writer/
xml_writer.rs1use crate::error::{Lib3mfError, Result};
2use quick_xml::Writer;
3use quick_xml::events::{BytesDecl, BytesEnd, BytesStart, BytesText, Event};
4use std::io::Write;
5
6pub struct XmlWriter<W: Write> {
7 writer: Writer<W>,
8}
9
10impl<W: Write> XmlWriter<W> {
11 pub fn new(inner: W) -> Self {
12 Self {
13 writer: Writer::new_with_indent(inner, b' ', 2),
14 }
15 }
16
17 pub fn write_declaration(&mut self) -> Result<()> {
18 let decl = BytesDecl::new("1.0", Some("UTF-8"), None);
19 self.writer
20 .write_event(Event::Decl(decl))
21 .map_err(|e| Lib3mfError::Validation(e.to_string()))
22 }
23
24 pub fn start_element(&mut self, name: &str) -> ElementBuilder<'_, W> {
25 ElementBuilder {
26 writer: self,
27 name: name.to_string(),
28 attributes: Vec::new(),
29 }
30 }
31
32 pub fn end_element(&mut self, name: &str) -> Result<()> {
33 self.writer
34 .write_event(Event::End(BytesEnd::new(name)))
35 .map_err(|e| Lib3mfError::Validation(e.to_string()))
36 }
37
38 pub fn write_text(&mut self, text: &str) -> Result<()> {
39 self.writer
40 .write_event(Event::Text(BytesText::new(text)))
41 .map_err(|e| Lib3mfError::Validation(e.to_string()))
42 }
43}
44
45pub struct ElementBuilder<'a, W: Write> {
46 writer: &'a mut XmlWriter<W>,
47 name: String,
48 attributes: Vec<(String, String)>,
49}
50
51impl<'a, W: Write> ElementBuilder<'a, W> {
52 pub fn attr(mut self, key: &str, value: &str) -> Self {
53 self.attributes.push((key.to_string(), value.to_string()));
54 self
55 }
56
57 pub fn optional_attr(mut self, key: &str, value: Option<&str>) -> Self {
58 if let Some(v) = value {
59 self.attributes.push((key.to_string(), v.to_string()));
60 }
61 self
62 }
63
64 pub fn write_empty(self) -> Result<()> {
65 let mut elem = BytesStart::new(&self.name);
66 for (k, v) in &self.attributes {
67 elem.push_attribute((k.as_str(), v.as_str()));
68 }
69 self.writer
70 .writer
71 .write_event(Event::Empty(elem))
72 .map_err(|e| Lib3mfError::Validation(e.to_string()))
73 }
74
75 pub fn write_start(self) -> Result<()> {
76 let mut elem = BytesStart::new(&self.name);
77 for (k, v) in &self.attributes {
78 elem.push_attribute((k.as_str(), v.as_str()));
79 }
80 self.writer
81 .writer
82 .write_event(Event::Start(elem))
83 .map_err(|e| Lib3mfError::Validation(e.to_string()))
84 }
85}