opcua_types/variant/
xml_element.rs

1// OPCUA for Rust
2// SPDX-License-Identifier: MPL-2.0
3// Copyright (C) 2017-2025 Einar Omang
4
5use crate::{BinaryDecodable, BinaryEncodable, UAString, UaNullable};
6
7/// XML element, represented as a string.
8///
9/// Note that this is deprecated, according to the OPC-UA standard,
10/// it is kept in the library for backwards compatibility.
11///
12/// Constructors are not checked, so the contents are not guaranteed to
13/// be valid XML, or really XML at all.
14#[derive(Debug, Clone, PartialEq, Default)]
15pub struct XmlElement(UAString);
16
17impl XmlElement {
18    /// Create a new null XmlElement.
19    pub fn null() -> Self {
20        Self(UAString::null())
21    }
22}
23
24impl std::fmt::Display for XmlElement {
25    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26        self.0.fmt(f)
27    }
28}
29
30impl From<String> for XmlElement {
31    fn from(value: String) -> Self {
32        Self(UAString::from(value))
33    }
34}
35
36impl From<&str> for XmlElement {
37    fn from(value: &str) -> Self {
38        Self(UAString::from(value))
39    }
40}
41
42impl From<UAString> for XmlElement {
43    fn from(value: UAString) -> Self {
44        Self(value)
45    }
46}
47
48impl BinaryEncodable for XmlElement {
49    fn byte_len(&self, ctx: &crate::Context<'_>) -> usize {
50        self.0.byte_len(ctx)
51    }
52
53    fn encode<S: std::io::Write + ?Sized>(
54        &self,
55        stream: &mut S,
56        ctx: &crate::Context<'_>,
57    ) -> crate::EncodingResult<()> {
58        self.0.encode(stream, ctx)
59    }
60}
61
62impl BinaryDecodable for XmlElement {
63    fn decode<S: std::io::Read + ?Sized>(
64        stream: &mut S,
65        ctx: &crate::Context<'_>,
66    ) -> crate::EncodingResult<Self> {
67        Ok(XmlElement(UAString::decode(stream, ctx)?))
68    }
69}
70
71impl UaNullable for XmlElement {
72    fn is_ua_null(&self) -> bool {
73        self.0.is_null()
74    }
75}
76
77#[cfg(feature = "json")]
78mod json {
79    use crate::{json::*, UAString};
80
81    // XMLElement is stored as a string in JSON.
82
83    impl JsonEncodable for super::XmlElement {
84        fn encode(
85            &self,
86            stream: &mut JsonStreamWriter<&mut dyn std::io::Write>,
87            ctx: &crate::Context<'_>,
88        ) -> crate::EncodingResult<()> {
89            self.0.encode(stream, ctx)
90        }
91    }
92
93    impl JsonDecodable for super::XmlElement {
94        fn decode(
95            stream: &mut JsonStreamReader<&mut dyn std::io::Read>,
96            ctx: &Context<'_>,
97        ) -> crate::EncodingResult<Self> {
98            Ok(super::XmlElement(UAString::decode(stream, ctx)?))
99        }
100    }
101}
102
103#[cfg(feature = "xml")]
104mod xml {
105    use crate::xml::*;
106
107    impl XmlType for super::XmlElement {
108        const TAG: &'static str = "XmlElement";
109    }
110
111    impl XmlEncodable for super::XmlElement {
112        fn encode(
113            &self,
114            writer: &mut XmlStreamWriter<&mut dyn std::io::Write>,
115            _context: &Context<'_>,
116        ) -> EncodingResult<()> {
117            writer.write_raw(self.0.as_ref().as_bytes())?;
118            Ok(())
119        }
120    }
121
122    impl XmlDecodable for super::XmlElement {
123        fn decode(
124            read: &mut XmlStreamReader<&mut dyn std::io::Read>,
125            _context: &Context<'_>,
126        ) -> Result<Self, Error>
127        where
128            Self: Sized,
129        {
130            let raw = read.consume_raw()?;
131            let string = String::from_utf8(raw).map_err(Error::decoding)?;
132            Ok(Self(string.into()))
133        }
134    }
135}