opcua_xml/encoding/
writer.rs

1use std::io::Write;
2
3use quick_xml::{
4    events::{BytesEnd, BytesStart, BytesText, Event},
5    ElementWriter,
6};
7use thiserror::Error;
8
9/// XML stream writer specialized for working with OPC-UA XML.
10pub struct XmlStreamWriter<T> {
11    writer: quick_xml::Writer<T>,
12}
13
14#[derive(Debug, Error)]
15/// Error returned when writing XML.
16pub enum XmlWriteError {
17    #[error("{0}")]
18    /// Invalid XML input.
19    Xml(#[from] quick_xml::Error),
20    #[error("Failed to write to stream: {0}")]
21    /// Failed to write XML to stream.
22    Io(#[from] std::io::Error),
23}
24
25impl<T: Write> XmlStreamWriter<T> {
26    /// Create a new writer with the given inner Write implementation.
27    pub fn new(writer: T) -> Self {
28        Self {
29            writer: quick_xml::Writer::new(writer),
30        }
31    }
32
33    /// Write an event to the stream.
34    pub fn write_event(&mut self, element: Event<'_>) -> Result<(), XmlWriteError> {
35        self.writer.write_event(element)?;
36        Ok(())
37    }
38
39    /// Write a start tag to the stream.
40    pub fn write_start(&mut self, tag: &str) -> Result<(), XmlWriteError> {
41        self.writer
42            .write_event(Event::Start(BytesStart::new(tag)))?;
43        Ok(())
44    }
45
46    /// Write an end tag to the stream.
47    pub fn write_end(&mut self, tag: &str) -> Result<(), XmlWriteError> {
48        self.writer.write_event(Event::End(BytesEnd::new(tag)))?;
49        Ok(())
50    }
51
52    /// Write an empty tag to the stream.
53    pub fn write_empty(&mut self, tag: &str) -> Result<(), XmlWriteError> {
54        self.writer
55            .write_event(Event::Empty(BytesStart::new(tag)))?;
56        Ok(())
57    }
58
59    /// Write node contents to the stream.
60    pub fn write_text(&mut self, text: &str) -> Result<(), XmlWriteError> {
61        self.writer.write_event(Event::Text(BytesText::new(text)))?;
62        Ok(())
63    }
64
65    /// Get a flexible event builder from quick-xml.
66    pub fn create_element<'a>(&'a mut self, name: &'a str) -> ElementWriter<'a, T> {
67        self.writer.create_element(name)
68    }
69}
70
71impl XmlStreamWriter<&mut dyn Write> {
72    /// Write the given bytes raw to the stream.
73    /// This may produce invalid XML, if the data is not valid and properly escaped.
74    pub fn write_raw(&mut self, data: &[u8]) -> Result<(), XmlWriteError> {
75        self.writer.get_mut().write_all(data)?;
76        Ok(())
77    }
78}