From 6d1754de8dd2cb108076dde538981b7ed4c702df Mon Sep 17 00:00:00 2001 From: Einar Omang Date: Tue, 25 Feb 2025 08:11:51 +0100 Subject: [PATCH 1/3] Core encoder utils --- Cargo.lock | 10 + Cargo.toml | 1 + async-opcua-types/src/xml/builtins.rs | 159 ++++++++++++++++ async-opcua-types/src/xml/encoding.rs | 34 ++++ async-opcua-types/src/{xml.rs => xml/mod.rs} | 3 + async-opcua-xml/Cargo.toml | 1 + async-opcua-xml/src/encoding/mod.rs | 5 + async-opcua-xml/src/encoding/reader.rs | 186 +++++++++++++++++++ async-opcua-xml/src/encoding/writer.rs | 62 +++++++ async-opcua-xml/src/lib.rs | 3 + 10 files changed, 464 insertions(+) create mode 100644 async-opcua-types/src/xml/builtins.rs create mode 100644 async-opcua-types/src/xml/encoding.rs rename async-opcua-types/src/{xml.rs => xml/mod.rs} (99%) create mode 100644 async-opcua-xml/src/encoding/mod.rs create mode 100644 async-opcua-xml/src/encoding/reader.rs create mode 100644 async-opcua-xml/src/encoding/writer.rs diff --git a/Cargo.lock b/Cargo.lock index b78d4c6c..afdec840 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -359,6 +359,7 @@ name = "async-opcua-xml" version = "0.14.0" dependencies = [ "chrono", + "quick-xml", "roxmltree", "thiserror", "uuid", @@ -1585,6 +1586,15 @@ dependencies = [ "yansi", ] +[[package]] +name = "quick-xml" +version = "0.37.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "165859e9e55f79d67b96c5d96f4e88b6f2695a1972849c15a6a3f5c59fc2c003" +dependencies = [ + "memchr", +] + [[package]] name = "quote" version = "1.0.37" diff --git a/Cargo.toml b/Cargo.toml index 5776491d..1fe77d0c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ log = "^0.4" parking_lot = { version = "^0.12", features = ["send_guard"] } postcard = { version = "^1", features = ["use-std"] } proc-macro2 = "^1" +quick-xml = "0.37.2" quote = "^1" regex = "^1" roxmltree = "^0.20" diff --git a/async-opcua-types/src/xml/builtins.rs b/async-opcua-types/src/xml/builtins.rs new file mode 100644 index 00000000..4fcb3c04 --- /dev/null +++ b/async-opcua-types/src/xml/builtins.rs @@ -0,0 +1,159 @@ +use super::encoding::{XmlDecodable, XmlEncodable}; +use crate::{Context, Error}; +use opcua_xml::{XmlStreamReader, XmlStreamWriter}; +use std::io::{Read, Write}; + +macro_rules! xml_enc_number { + ($t:ty) => { + impl XmlEncodable for $t { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + _context: &Context<'_>, + ) -> Result<(), Error> { + writer.write_text(&self.to_string())?; + Ok(()) + } + } + + impl XmlDecodable for $t { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + _context: &Context<'_>, + ) -> Result { + Ok(read.consume_content()?) + } + } + }; +} + +const VALUE_INFINITY: &str = "INF"; +const VALUE_NEG_INFINITY: &str = "-INF"; +const VALUE_NAN: &str = "NaN"; + +macro_rules! xml_enc_float { + ($t:ty) => { + impl XmlEncodable for $t { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + _context: &Context<'_>, + ) -> Result<(), Error> { + if self.is_infinite() { + if self.is_sign_positive() { + writer.write_text(VALUE_INFINITY)?; + } else { + writer.write_text(VALUE_NEG_INFINITY)?; + } + } else if self.is_nan() { + writer.write_text(VALUE_NAN)?; + } else { + writer.write_text(&self.to_string())?; + } + Ok(()) + } + } + + impl XmlDecodable for $t { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + _context: &Context<'_>, + ) -> Result { + let val = read.consume_as_text()?; + match val.as_str() { + VALUE_INFINITY => Ok(Self::INFINITY), + VALUE_NEG_INFINITY => Ok(Self::NEG_INFINITY), + VALUE_NAN => Ok(Self::NAN), + _ => Ok(val.parse()?), + } + } + } + }; +} + +xml_enc_number!(u8); +xml_enc_number!(u16); +xml_enc_number!(u32); +xml_enc_number!(u64); +xml_enc_number!(i8); +xml_enc_number!(i16); +xml_enc_number!(i32); +xml_enc_number!(i64); +xml_enc_float!(f32); +xml_enc_float!(f64); + +impl XmlDecodable for String { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + _context: &Context<'_>, + ) -> Result + where + Self: Sized, + { + Ok(read.consume_as_text()?) + } +} + +impl XmlEncodable for String { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + _context: &Context<'_>, + ) -> Result<(), Error> { + writer.write_text(self)?; + Ok(()) + } +} + +impl XmlDecodable for bool { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + _context: &Context<'_>, + ) -> Result + where + Self: Sized, + { + let val = read.consume_as_text()?; + match val.as_str() { + "true" | "1" => Ok(true), + "false" | "0" => Ok(false), + _ => Err(Error::decoding(format!("Invalid boolean value: {val}"))), + } + } +} + +impl XmlEncodable for bool { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + _context: &Context<'_>, + ) -> Result<(), Error> { + writer.write_text(if *self { "true" } else { "false" })?; + Ok(()) + } +} + +impl XmlDecodable for Box +where + T: XmlDecodable, +{ + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + context: &Context<'_>, + ) -> Result { + Ok(Box::new(T::decode(read, context)?)) + } +} + +impl XmlEncodable for Box +where + T: XmlEncodable, +{ + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + context: &Context<'_>, + ) -> Result<(), Error> { + self.as_ref().encode(writer, context) + } +} diff --git a/async-opcua-types/src/xml/encoding.rs b/async-opcua-types/src/xml/encoding.rs new file mode 100644 index 00000000..d3124ebe --- /dev/null +++ b/async-opcua-types/src/xml/encoding.rs @@ -0,0 +1,34 @@ +use std::io::{Read, Write}; + +use opcua_xml::{XmlReadError, XmlStreamReader, XmlStreamWriter, XmlWriteError}; + +use crate::{Context, Error}; + +impl From for Error { + fn from(value: XmlReadError) -> Self { + Self::decoding(value) + } +} + +impl From for Error { + fn from(value: XmlWriteError) -> Self { + Self::encoding(value) + } +} + +pub trait XmlDecodable { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + context: &Context<'_>, + ) -> Result + where + Self: Sized; +} + +pub trait XmlEncodable { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + context: &Context<'_>, + ) -> Result<(), Error>; +} diff --git a/async-opcua-types/src/xml.rs b/async-opcua-types/src/xml/mod.rs similarity index 99% rename from async-opcua-types/src/xml.rs rename to async-opcua-types/src/xml/mod.rs index 6cb8ff02..8f11ce89 100644 --- a/async-opcua-types/src/xml.rs +++ b/async-opcua-types/src/xml/mod.rs @@ -2,6 +2,9 @@ //! //! Core utilities for working with decoding OPC UA types from NodeSet2 XML files. +mod builtins; +mod encoding; + use std::str::FromStr; use log::warn; diff --git a/async-opcua-xml/Cargo.toml b/async-opcua-xml/Cargo.toml index d12bb243..66302fd1 100644 --- a/async-opcua-xml/Cargo.toml +++ b/async-opcua-xml/Cargo.toml @@ -19,3 +19,4 @@ chrono = { workspace = true } roxmltree = { workspace = true } thiserror = { workspace = true } uuid = { workspace = true } +quick-xml = { workspace = true } diff --git a/async-opcua-xml/src/encoding/mod.rs b/async-opcua-xml/src/encoding/mod.rs new file mode 100644 index 00000000..8353566e --- /dev/null +++ b/async-opcua-xml/src/encoding/mod.rs @@ -0,0 +1,5 @@ +mod reader; +mod writer; + +pub use reader::{XmlReadError, XmlStreamReader}; +pub use writer::{XmlStreamWriter, XmlWriteError}; diff --git a/async-opcua-xml/src/encoding/reader.rs b/async-opcua-xml/src/encoding/reader.rs new file mode 100644 index 00000000..e3562b65 --- /dev/null +++ b/async-opcua-xml/src/encoding/reader.rs @@ -0,0 +1,186 @@ +use std::{ + io::{BufReader, Read}, + num::{ParseFloatError, ParseIntError}, + str::FromStr, +}; + +use quick_xml::events::Event; +use thiserror::Error; + +#[derive(Debug, Error)] +/// Error produced when reading XML. +pub enum XmlReadError { + #[error("{0}")] + /// Failed to parse XML. + Xml(#[from] quick_xml::Error), + #[error("Unexpected EOF")] + /// Unexpected EOF. + UnexpectedEof, + #[error("Failed to parse integer: {0}")] + /// Failed to parse value as integer. + ParseInt(#[from] ParseIntError), + #[error("Failed to parse float: {0}")] + /// Failed to parse value as float. + ParseFloat(#[from] ParseFloatError), + #[error("Failed to parse value: {0}")] + /// Some other parse error. + Parse(String), +} + +/// XML stream reader specialized for working with OPC-UA XML. +pub struct XmlStreamReader { + reader: quick_xml::Reader>, + buffer: Vec, +} + +impl XmlStreamReader { + /// Create a new stream reader with an internal buffer. + pub fn new(reader: T) -> Self { + Self { + reader: quick_xml::Reader::from_reader(BufReader::new(reader)), + buffer: Vec::new(), + } + } + + /// Get the next event from the stream. + pub fn next_event(&mut self) -> Result { + self.buffer.clear(); + Ok(self.reader.read_event_into(&mut self.buffer)?) + } + + /// Skip the current value. This should be called after encountering a + /// `Start` event, and will skip until the corresponding `End` event is consumed. + /// + /// Note that this does not check that the document is coherent, just that + /// an equal number of start and end events are consumed. + pub fn skip_value(&mut self) -> Result<(), XmlReadError> { + let mut depth = 1u32; + loop { + match self.next_event()? { + Event::Start(_) => depth += 1, + Event::End(_) => { + depth -= 1; + if depth == 0 { + return Ok(()); + } + } + Event::Eof => return Err(XmlReadError::UnexpectedEof), + _ => {} + } + } + } + + /// Consume the current event, skipping any child elements and returning the combined text + /// content with leading and trailing whitespace removed. + /// Note that if there are multiple text elements they will be concatenated, but + /// whitespace between these will not be removed. + pub fn consume_as_text(&mut self) -> Result { + let mut text: Option = None; + let mut depth = 1u32; + loop { + match self.next_event()? { + Event::Start(_) => depth += 1, + Event::End(_) => { + depth -= 1; + if depth == 0 { + if let Some(mut text) = text { + let trimmed = text.trim_ascii_end(); + text.truncate(trimmed.len()); + return Ok(text); + } else { + return Ok(String::new()); + } + } + } + Event::Text(mut e) => { + if depth != 1 { + continue; + } + if let Some(text) = text.as_mut() { + text.push_str(&e.unescape()?); + } else if e.inplace_trim_start() { + continue; + } else { + text = Some(e.unescape()?.into_owned()); + } + } + + Event::Eof => return Err(XmlReadError::UnexpectedEof), + _ => continue, + } + } + } + + /// Consume the current node as a text value and parse it as the given type. + pub fn consume_content(&mut self) -> Result + where + XmlReadError: From<::Err>, + { + let text = self.consume_as_text()?; + Ok(text.parse()?) + } +} + +#[cfg(test)] +mod test { + use std::io::Cursor; + + use quick_xml::events::Event; + + #[test] + fn test_xml_text_comments() { + let xml = r#" + + Ho + + Hello + + Hello there + + "#; + let mut cursor = Cursor::new(xml.as_bytes()); + let mut reader = super::XmlStreamReader::new(&mut cursor); + // You canend up with text everywhere. Any loading needs to account for this. + assert!(matches!(reader.next_event().unwrap(), Event::Text(_))); + assert!(matches!(reader.next_event().unwrap(), Event::Start(_))); + assert!(matches!(reader.next_event().unwrap(), Event::Text(_))); + assert!(matches!(reader.next_event().unwrap(), Event::Start(_))); + assert!(matches!(reader.next_event().unwrap(), Event::Text(_))); + assert!(matches!(reader.next_event().unwrap(), Event::End(_))); + assert!(matches!(reader.next_event().unwrap(), Event::Text(_))); + assert!(matches!(reader.next_event().unwrap(), Event::Comment(_))); + assert!(matches!(reader.next_event().unwrap(), Event::Text(_))); + assert!(matches!(reader.next_event().unwrap(), Event::End(_))); + assert!(matches!(reader.next_event().unwrap(), Event::Text(_))); + assert!(matches!(reader.next_event().unwrap(), Event::Eof)); + assert!(matches!(reader.next_event().unwrap(), Event::Eof)); + } + + #[test] + fn test_consume_as_text() { + let xml = r#" + + Hello + + Hello there + "#; + + let mut cursor = Cursor::new(xml.as_bytes()); + let mut reader = super::XmlStreamReader::new(&mut cursor); + + assert!(matches!(reader.next_event().unwrap(), Event::Start(_))); + assert_eq!(reader.consume_as_text().unwrap(), "Hello there"); + } + + #[test] + fn test_consume_content() { + let xml = r#" + 12345 + "#; + let mut cursor = Cursor::new(xml.as_bytes()); + let mut reader = super::XmlStreamReader::new(&mut cursor); + + assert!(matches!(reader.next_event().unwrap(), Event::Start(_))); + assert_eq!(reader.consume_content::().unwrap(), 12345); + } +} diff --git a/async-opcua-xml/src/encoding/writer.rs b/async-opcua-xml/src/encoding/writer.rs new file mode 100644 index 00000000..30a11807 --- /dev/null +++ b/async-opcua-xml/src/encoding/writer.rs @@ -0,0 +1,62 @@ +use std::io::Write; + +use quick_xml::{ + events::{BytesEnd, BytesStart, BytesText, Event}, + ElementWriter, +}; +use thiserror::Error; + +/// XML stream writer specialized for working with OPC-UA XML. +pub struct XmlStreamWriter { + writer: quick_xml::Writer, +} + +#[derive(Debug, Error)] +/// Error returned when writing XML. +pub enum XmlWriteError { + #[error("{0}")] + /// Invalid XML input. + Xml(#[from] quick_xml::Error), + #[error("Failed to write to stream: {0}")] + /// Failed to write XML to stream. + Io(#[from] std::io::Error), +} + +impl XmlStreamWriter { + /// Create a new writer with the given inner Write implementation. + pub fn new(writer: T) -> Self { + Self { + writer: quick_xml::Writer::new(writer), + } + } + + /// Write an event to the stream. + pub fn write_event(&mut self, element: Event<'_>) -> Result<(), XmlWriteError> { + self.writer.write_event(element)?; + Ok(()) + } + + /// Write a start tag to the stream. + pub fn write_start(&mut self, tag: &str) -> Result<(), XmlWriteError> { + self.writer + .write_event(Event::Start(BytesStart::new(tag)))?; + Ok(()) + } + + /// Write an end tag to the stream. + pub fn write_end(&mut self, tag: &str) -> Result<(), XmlWriteError> { + self.writer.write_event(Event::End(BytesEnd::new(tag)))?; + Ok(()) + } + + /// Write node contents to the stream. + pub fn write_text(&mut self, text: &str) -> Result<(), XmlWriteError> { + self.writer.write_event(Event::Text(BytesText::new(text)))?; + Ok(()) + } + + /// Get a flexible event builder from quick-xml. + pub fn create_element<'a>(&'a mut self, name: &'a str) -> ElementWriter<'a, T> { + self.writer.create_element(name) + } +} diff --git a/async-opcua-xml/src/lib.rs b/async-opcua-xml/src/lib.rs index a6a16c5f..c64c8304 100644 --- a/async-opcua-xml/src/lib.rs +++ b/async-opcua-xml/src/lib.rs @@ -14,10 +14,13 @@ use ext::NodeExt; use roxmltree::Node; +mod encoding; mod error; mod ext; pub mod schema; +pub use encoding::{XmlReadError, XmlStreamReader, XmlStreamWriter, XmlWriteError}; + pub use error::{XmlError, XmlErrorInner}; pub use schema::opc_binary_schema::load_bsd_file; pub use schema::ua_node_set::load_nodeset2_file; From 7707e49f5d2d79a7583f2dbb54f672aa9d49332a Mon Sep 17 00:00:00 2001 From: Einar Omang Date: Tue, 25 Feb 2025 08:12:06 +0100 Subject: [PATCH 2/3] Manual encoder implementations for simple types Further work is going to need derive macros to be implemented. --- async-opcua-types/src/byte_string.rs | 36 ++++++ async-opcua-types/src/date_time.rs | 30 +++++ async-opcua-types/src/diagnostic_info.rs | 28 +++++ async-opcua-types/src/expanded_node_id.rs | 39 +++++++ async-opcua-types/src/extension_object.rs | 82 ++++++++++++++ async-opcua-types/src/guid.rs | 34 ++++++ async-opcua-types/src/node_id.rs | 42 +++++++ async-opcua-types/src/status_code.rs | 33 ++++++ async-opcua-types/src/string.rs | 31 ++++++ async-opcua-types/src/xml/builtins.rs | 11 ++ async-opcua-types/src/xml/encoding.rs | 129 +++++++++++++++++++++- async-opcua-types/src/xml/mod.rs | 9 +- async-opcua-xml/src/encoding/reader.rs | 5 +- async-opcua-xml/src/lib.rs | 1 + 14 files changed, 503 insertions(+), 7 deletions(-) diff --git a/async-opcua-types/src/byte_string.rs b/async-opcua-types/src/byte_string.rs index 9dcb86e8..097d5b9f 100644 --- a/async-opcua-types/src/byte_string.rs +++ b/async-opcua-types/src/byte_string.rs @@ -74,6 +74,42 @@ mod json { } } +#[cfg(feature = "xml")] +mod xml { + use crate::xml::*; + use std::io::{Read, Write}; + + use super::ByteString; + + impl XmlEncodable for ByteString { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + _context: &Context<'_>, + ) -> EncodingResult<()> { + if self.value.is_some() { + writer.write_text(&self.as_base64())?; + } + Ok(()) + } + } + + impl XmlDecodable for ByteString { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + _context: &Context<'_>, + ) -> Result { + let s = read.consume_as_text()?; + if s.is_empty() { + Ok(ByteString::null()) + } else { + Ok(ByteString::from_base64(&s) + .ok_or_else(|| Error::decoding("Cannot decode base64 bytestring"))?) + } + } + } +} + impl SimpleBinaryEncodable for ByteString { fn byte_len(&self) -> usize { // Length plus the actual length of bytes (if not null) diff --git a/async-opcua-types/src/date_time.rs b/async-opcua-types/src/date_time.rs index 507e6c03..f8c5007d 100644 --- a/async-opcua-types/src/date_time.rs +++ b/async-opcua-types/src/date_time.rs @@ -63,6 +63,36 @@ mod json { } } +#[cfg(feature = "xml")] +mod xml { + use crate::xml::*; + use std::io::{Read, Write}; + + use super::DateTime; + + impl XmlEncodable for DateTime { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + context: &Context<'_>, + ) -> EncodingResult<()> { + self.to_rfc3339().encode(writer, context) + } + } + + impl XmlDecodable for DateTime { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + _context: &Context<'_>, + ) -> Result { + let v = read.consume_as_text()?; + let dt = DateTime::parse_from_rfc3339(&v) + .map_err(|e| Error::decoding(format!("Cannot parse date time: {e}")))?; + Ok(dt) + } + } +} + /// DateTime encoded as 64-bit signed int impl BinaryEncodable for DateTime { fn byte_len(&self, _ctx: &Context<'_>) -> usize { diff --git a/async-opcua-types/src/diagnostic_info.rs b/async-opcua-types/src/diagnostic_info.rs index 77043cc1..b0835b9f 100644 --- a/async-opcua-types/src/diagnostic_info.rs +++ b/async-opcua-types/src/diagnostic_info.rs @@ -97,6 +97,34 @@ mod json { } } +#[cfg(feature = "xml")] +mod xml { + use crate::xml::*; + use std::io::{Read, Write}; + + use super::DiagnosticBits; + + impl XmlEncodable for DiagnosticBits { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + context: &Context<'_>, + ) -> EncodingResult<()> { + self.bits().encode(writer, context) + } + } + + impl XmlDecodable for DiagnosticBits { + fn decode( + reader: &mut XmlStreamReader<&mut dyn Read>, + context: &Context<'_>, + ) -> EncodingResult { + let v = u32::decode(reader, context)?; + Ok(Self::from_bits_truncate(v)) + } + } +} + #[allow(unused)] mod opcua { pub use crate as types; diff --git a/async-opcua-types/src/expanded_node_id.rs b/async-opcua-types/src/expanded_node_id.rs index f79c22ce..e724a6f8 100644 --- a/async-opcua-types/src/expanded_node_id.rs +++ b/async-opcua-types/src/expanded_node_id.rs @@ -237,6 +237,45 @@ mod json { } } +#[cfg(feature = "xml")] +mod xml { + // ExpandedNodeId in XML is for some reason just the exact same + // as a NodeId. + use crate::{xml::*, NodeId, UAString}; + use std::io::{Read, Write}; + + use super::ExpandedNodeId; + + impl XmlEncodable for ExpandedNodeId { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + context: &Context<'_>, + ) -> EncodingResult<()> { + let Some(node_id) = context.namespaces().resolve_node_id(self) else { + return Err(Error::encoding( + "Unable to resolve ExpandedNodeId, invalid namespace", + )); + }; + node_id.encode(writer, context) + } + } + + impl XmlDecodable for ExpandedNodeId { + fn decode( + reader: &mut XmlStreamReader<&mut dyn Read>, + context: &Context<'_>, + ) -> EncodingResult { + let node_id = NodeId::decode(reader, context)?; + Ok(ExpandedNodeId { + node_id, + namespace_uri: UAString::null(), + server_index: 0, + }) + } + } +} + impl BinaryEncodable for ExpandedNodeId { fn byte_len(&self, ctx: &crate::Context<'_>) -> usize { let mut size = self.node_id.byte_len(ctx); diff --git a/async-opcua-types/src/extension_object.rs b/async-opcua-types/src/extension_object.rs index 96449a12..ee694179 100644 --- a/async-opcua-types/src/extension_object.rs +++ b/async-opcua-types/src/extension_object.rs @@ -299,6 +299,88 @@ mod json { } } +#[cfg(feature = "xml")] +mod xml { + use opcua_xml::events::Event; + + use crate::{xml::*, ByteString, NodeId}; + use std::io::{Read, Write}; + + use super::ExtensionObject; + + impl XmlEncodable for ExtensionObject { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + ctx: &crate::Context<'_>, + ) -> super::EncodingResult<()> { + let Some(body) = &self.body else { + // An empty extension object is legal, meaning a null value. + return Ok(()); + }; + let type_id = body.xml_type_id(); + let id = type_id.try_resolve(ctx.namespaces()).ok_or_else(|| { + Error::encoding(format!("Missing namespace for encoding ID: {type_id}")) + })?; + + writer.encode_child("TypeId", id.as_ref(), ctx)?; + // TODO: Encode body + + Ok(()) + } + } + + impl XmlDecodable for ExtensionObject { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + ctx: &Context<'_>, + ) -> Result { + let mut type_id = None; + let mut body = None; + read.iter_children( + |key, reader, ctx| { + match key.as_str() { + "TypeId" => type_id = Some(NodeId::decode(reader, ctx)?), + "Body" => { + // First, read the top level element. + let top_level = loop { + match reader.next_event()? { + Event::Start(s) => break s, + Event::End(_) => { + return Ok(()); // End of the body itself + } + _ => (), + } + }; + let Some(type_id) = type_id.take() else { + return Err(Error::decoding("Missing type ID in extension object")); + }; + + if top_level.name().0 == b"ByteString" { + // If it's a bytestring, decode it as a binary body. + let val = ByteString::decode(reader, ctx)?; + if let Some(raw) = val.value { + let mut cursor = std::io::Cursor::new(raw); + body = Some(ctx.load_from_binary(&type_id, &mut cursor)?); + } + } else { + // Decode from XML. + todo!(); + } + // Read to the end of the body. + reader.skip_value()?; + } + _ => (), + }; + Ok(()) + }, + ctx, + )?; + Ok(body.unwrap_or_else(ExtensionObject::null)) + } + } +} + /// An extension object holds an OPC-UA structure deserialize to a [DynEncodable]. /// This makes it possible to deserialize an extension object, the serialize it back in a different /// format, without reflecting over or inspecting the inner type. diff --git a/async-opcua-types/src/guid.rs b/async-opcua-types/src/guid.rs index 4200a21b..d478ec4e 100644 --- a/async-opcua-types/src/guid.rs +++ b/async-opcua-types/src/guid.rs @@ -57,6 +57,40 @@ mod json { } } +#[cfg(feature = "xml")] +mod xml { + use crate::xml::*; + use std::{ + io::{Read, Write}, + str::FromStr, + }; + + use super::Guid; + + impl XmlEncodable for Guid { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + ctx: &crate::xml::Context<'_>, + ) -> EncodingResult<()> { + writer.encode_child("String", &self.to_string(), ctx) + } + } + + impl XmlDecodable for Guid { + fn decode( + reader: &mut XmlStreamReader<&mut dyn Read>, + ctx: &crate::xml::Context<'_>, + ) -> EncodingResult { + let val: Option = reader.decode_single_child("String", ctx)?; + let Some(val) = val else { + return Ok(Guid::null()); + }; + Guid::from_str(&val).map_err(Error::decoding) + } + } +} + impl fmt::Display for Guid { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", self.uuid) diff --git a/async-opcua-types/src/node_id.rs b/async-opcua-types/src/node_id.rs index 53e08036..2b49111c 100644 --- a/async-opcua-types/src/node_id.rs +++ b/async-opcua-types/src/node_id.rs @@ -327,6 +327,48 @@ mod json { } } +#[cfg(feature = "xml")] +mod xml { + use crate::xml::*; + use std::{ + io::{Read, Write}, + str::FromStr, + }; + + use super::NodeId; + + impl XmlEncodable for NodeId { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + ctx: &crate::xml::Context<'_>, + ) -> Result<(), Error> { + let self_str = self.to_string(); + let val = ctx.resolve_alias(&self_str); + writer.encode_child("Identifier", val, ctx) + } + } + + impl XmlDecodable for NodeId { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + context: &Context<'_>, + ) -> Result + where + Self: Sized, + { + let val: Option = read.decode_single_child("Identifier", context)?; + let Some(val) = val else { + return Ok(NodeId::null()); + }; + + let val_str = context.resolve_alias(&val); + NodeId::from_str(val_str) + .map_err(|e| Error::new(e, format!("Invalid node ID: {val_str}"))) + } + } +} + impl BinaryEncodable for NodeId { fn byte_len(&self, ctx: &crate::Context<'_>) -> usize { // Type determines the byte code diff --git a/async-opcua-types/src/status_code.rs b/async-opcua-types/src/status_code.rs index c72ba518..ccd87cfb 100644 --- a/async-opcua-types/src/status_code.rs +++ b/async-opcua-types/src/status_code.rs @@ -44,6 +44,39 @@ mod json { } } +#[cfg(feature = "xml")] +mod xml { + use crate::xml::*; + use std::io::{Read, Write}; + + use super::StatusCode; + + impl XmlEncodable for StatusCode { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + context: &Context<'_>, + ) -> Result<(), Error> { + writer.encode_child("Code", &self.0, context) + } + } + + impl XmlDecodable for StatusCode { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + context: &Context<'_>, + ) -> Result + where + Self: Sized, + { + Ok(Self::from( + read.decode_single_child::("Code", context)? + .unwrap_or_default(), + )) + } + } +} + const SUBCODE_MASK: u32 = 0xffff_0000; const INFO_BITS_MASK: u32 = 0b0011_1111_1111; diff --git a/async-opcua-types/src/string.rs b/async-opcua-types/src/string.rs index 37973420..4de42c2e 100644 --- a/async-opcua-types/src/string.rs +++ b/async-opcua-types/src/string.rs @@ -136,6 +136,37 @@ impl SimpleBinaryDecodable for UAString { } } +#[cfg(feature = "xml")] +mod xml { + use crate::xml::*; + use std::io::{Read, Write}; + + use super::UAString; + + impl XmlEncodable for UAString { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + _ctx: &Context<'_>, + ) -> Result<(), Error> { + if let Some(s) = self.value() { + writer.write_text(s)?; + } + + Ok(()) + } + } + + impl XmlDecodable for UAString { + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + _context: &Context<'_>, + ) -> Result { + Ok(read.consume_as_text()?.into()) + } + } +} + impl From for String { fn from(value: UAString) -> Self { value.as_ref().to_string() diff --git a/async-opcua-types/src/xml/builtins.rs b/async-opcua-types/src/xml/builtins.rs index 4fcb3c04..84f04a4a 100644 --- a/async-opcua-types/src/xml/builtins.rs +++ b/async-opcua-types/src/xml/builtins.rs @@ -105,6 +105,17 @@ impl XmlEncodable for String { } } +impl XmlEncodable for str { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + _context: &Context<'_>, + ) -> Result<(), Error> { + writer.write_text(self)?; + Ok(()) + } +} + impl XmlDecodable for bool { fn decode( read: &mut XmlStreamReader<&mut dyn Read>, diff --git a/async-opcua-types/src/xml/encoding.rs b/async-opcua-types/src/xml/encoding.rs index d3124ebe..7382f856 100644 --- a/async-opcua-types/src/xml/encoding.rs +++ b/async-opcua-types/src/xml/encoding.rs @@ -1,8 +1,11 @@ -use std::io::{Read, Write}; +use std::{ + io::{Read, Write}, + str::{from_utf8, Utf8Error}, +}; use opcua_xml::{XmlReadError, XmlStreamReader, XmlStreamWriter, XmlWriteError}; -use crate::{Context, Error}; +use crate::{Context, EncodingResult, Error}; impl From for Error { fn from(value: XmlReadError) -> Self { @@ -16,7 +19,15 @@ impl From for Error { } } +impl From for Error { + fn from(value: Utf8Error) -> Self { + Self::decoding(value) + } +} + +/// Trait for types that can be decoded from XML. pub trait XmlDecodable { + /// Decode a value from an XML stream. fn decode( read: &mut XmlStreamReader<&mut dyn Read>, context: &Context<'_>, @@ -25,10 +36,122 @@ pub trait XmlDecodable { Self: Sized; } +/// Trait for types that can be encoded to XML. pub trait XmlEncodable { + /// Encode a value to an XML stream. fn encode( &self, writer: &mut XmlStreamWriter<&mut dyn Write>, context: &Context<'_>, - ) -> Result<(), Error>; + ) -> EncodingResult<()>; +} + +/// Extensions for XmlStreamWriter. +pub trait XmlWriteExt { + /// Encode a value as a child element. + fn encode_child( + &mut self, + tag: &str, + value: &T, + context: &Context<'_>, + ) -> EncodingResult<()>; +} + +impl XmlWriteExt for XmlStreamWriter<&mut dyn Write> { + fn encode_child( + &mut self, + tag: &str, + value: &T, + context: &Context<'_>, + ) -> EncodingResult<()> { + self.write_start(tag)?; + value.encode(self, context)?; + self.write_end(tag)?; + + Ok(()) + } +} + +/// Extensions for XmlStreamReader. +pub trait XmlReadExt { + /// Iterate over children, calling the provided callback for each tag. + /// The callback must consume the tag. + fn iter_children( + &mut self, + cb: impl FnMut(String, &mut Self, &Context<'_>) -> EncodingResult<()>, + context: &Context<'_>, + ) -> EncodingResult<()>; + + /// Call a callback for a single child element. This will consume the + /// current node. + fn get_single_child( + &mut self, + tag: &str, + cb: impl FnMut(&mut Self, &Context<'_>) -> Result, + context: &Context<'_>, + ) -> EncodingResult>; + + /// Decode a single child element. This will consume the + /// current node. + fn decode_single_child( + &mut self, + tag: &str, + context: &Context<'_>, + ) -> Result, Error>; +} + +impl XmlReadExt for XmlStreamReader<&mut dyn Read> { + fn iter_children( + &mut self, + mut process: impl FnMut(String, &mut Self, &Context<'_>) -> EncodingResult<()>, + context: &Context<'_>, + ) -> EncodingResult<()> { + loop { + match self.next_event()? { + opcua_xml::events::Event::Start(s) => { + let name = from_utf8(s.name().0)?; + process(name.to_owned(), self, context)?; + } + opcua_xml::events::Event::End(_) => { + return Ok(()); + } + opcua_xml::events::Event::Eof => { + return Err(Error::decoding(XmlReadError::UnexpectedEof)); + } + _ => (), + } + } + } + + fn get_single_child( + &mut self, + tag: &str, + cb: impl FnOnce(&mut Self, &Context<'_>) -> Result, + context: &Context<'_>, + ) -> EncodingResult> { + let mut cb = Some(cb); + let mut res = None; + self.iter_children( + |key, reader, ctx| { + if tag == key { + if let Some(cb) = cb.take() { + res = Some(cb(reader, ctx)?); + } + } else { + reader.skip_value()?; + } + Ok(()) + }, + context, + )?; + Ok(res) + } + + fn decode_single_child( + &mut self, + tag: &str, + context: &Context<'_>, + ) -> EncodingResult> { + self.get_single_child(tag, |reader, ctx| T::decode(reader, ctx), context) + } } diff --git a/async-opcua-types/src/xml/mod.rs b/async-opcua-types/src/xml/mod.rs index 8f11ce89..d9ea22f7 100644 --- a/async-opcua-types/src/xml/mod.rs +++ b/async-opcua-types/src/xml/mod.rs @@ -5,15 +5,18 @@ mod builtins; mod encoding; +pub use crate::{Context, EncodingResult, Error}; +pub use encoding::{XmlDecodable, XmlEncodable, XmlReadExt, XmlWriteExt}; +pub use opcua_xml::{XmlStreamReader, XmlStreamWriter}; + use std::str::FromStr; use log::warn; pub use opcua_xml::schema::opc_ua_types::XmlElement; use crate::{ - Array, ByteString, Context, DataValue, DateTime, EncodingResult, Error, ExpandedNodeId, - ExtensionObject, Guid, LocalizedText, NodeId, QualifiedName, StatusCode, UAString, - UninitializedIndex, Variant, VariantScalarTypeId, + Array, ByteString, DataValue, DateTime, ExpandedNodeId, ExtensionObject, Guid, LocalizedText, + NodeId, QualifiedName, StatusCode, UAString, UninitializedIndex, Variant, VariantScalarTypeId, }; impl From for Error { diff --git a/async-opcua-xml/src/encoding/reader.rs b/async-opcua-xml/src/encoding/reader.rs index e3562b65..79b3e53d 100644 --- a/async-opcua-xml/src/encoding/reader.rs +++ b/async-opcua-xml/src/encoding/reader.rs @@ -45,7 +45,10 @@ impl XmlStreamReader { /// Get the next event from the stream. pub fn next_event(&mut self) -> Result { self.buffer.clear(); - Ok(self.reader.read_event_into(&mut self.buffer)?) + match self.reader.read_event_into(&mut self.buffer)? { + Event::Eof => Err(XmlReadError::UnexpectedEof), + e => Ok(e), + } } /// Skip the current value. This should be called after encountering a diff --git a/async-opcua-xml/src/lib.rs b/async-opcua-xml/src/lib.rs index c64c8304..37087428 100644 --- a/async-opcua-xml/src/lib.rs +++ b/async-opcua-xml/src/lib.rs @@ -20,6 +20,7 @@ mod ext; pub mod schema; pub use encoding::{XmlReadError, XmlStreamReader, XmlStreamWriter, XmlWriteError}; +pub use quick_xml::events; pub use error::{XmlError, XmlErrorInner}; pub use schema::opc_binary_schema::load_bsd_file; From 43314d587e5b2780e8196e97070658d47e146a12 Mon Sep 17 00:00:00 2001 From: Einar Omang Date: Wed, 26 Feb 2025 13:32:22 +0100 Subject: [PATCH 3/3] Replace FromXml with XmlEncodable and XmlDecodable This is a major rewrite of XML parsing, adding support for XML serialization, and bringing it up to the same level as JSON and binary. I also fixed a few bugs I hit on in a few places. There are still some things remaining: - Unions - XML in binary/json encoded extension objects. - Proper support for the XmlElement variant (currently it doesn't work properly for XML). Note that this variant type is deprecated. This PR is already way too big. There was no real way to make it smaller, since once you start replacing FromXml there's no way to stop while still having the library compile. --- Cargo.lock | 7 + TODO.md | 5 +- async-opcua-client/src/custom_types/mod.rs | 2 + async-opcua-codegen/src/nodeset/value.rs | 10 +- async-opcua-codegen/src/types/gen.rs | 63 +- async-opcua-codegen/src/types/mod.rs | 4 +- async-opcua-macros/src/encoding/attribute.rs | 35 + async-opcua-macros/src/encoding/enums.rs | 33 +- async-opcua-macros/src/encoding/json.rs | 14 +- async-opcua-macros/src/encoding/mod.rs | 53 +- async-opcua-macros/src/encoding/unions.rs | 21 +- async-opcua-macros/src/encoding/xml.rs | 228 ++++- async-opcua-macros/src/lib.rs | 37 + async-opcua-types/Cargo.toml | 1 + async-opcua-types/src/argument.rs | 5 +- async-opcua-types/src/byte_string.rs | 4 + async-opcua-types/src/custom/custom_struct.rs | 20 +- async-opcua-types/src/custom/json.rs | 1 + async-opcua-types/src/custom/mod.rs | 2 + async-opcua-types/src/custom/type_tree.rs | 4 + async-opcua-types/src/custom/xml.rs | 443 ++++++++++ async-opcua-types/src/data_value.rs | 81 ++ async-opcua-types/src/date_time.rs | 8 +- async-opcua-types/src/diagnostic_info.rs | 17 +- async-opcua-types/src/expanded_node_id.rs | 4 + async-opcua-types/src/extension_object.rs | 71 +- .../types/activate_session_request.rs | 9 +- .../types/activate_session_response.rs | 9 +- .../src/generated/types/add_nodes_item.rs | 9 +- .../src/generated/types/add_nodes_request.rs | 9 +- .../src/generated/types/add_nodes_response.rs | 9 +- .../src/generated/types/add_nodes_result.rs | 9 +- .../generated/types/add_references_item.rs | 9 +- .../generated/types/add_references_request.rs | 9 +- .../types/add_references_response.rs | 9 +- .../types/additional_parameters_type.rs | 9 +- .../types/aggregate_configuration.rs | 9 +- .../src/generated/types/aggregate_filter.rs | 9 +- .../types/aggregate_filter_result.rs | 9 +- .../generated/types/alias_name_data_type.rs | 9 +- .../src/generated/types/annotation.rs | 9 +- .../generated/types/annotation_data_type.rs | 9 +- .../types/anonymous_identity_token.rs | 9 +- .../types/application_description.rs | 9 +- .../src/generated/types/attribute_operand.rs | 9 +- .../src/generated/types/axis_information.rs | 9 +- .../generated/types/bit_field_definition.rs | 9 +- .../broker_connection_transport_data_type.rs | 9 +- ...ker_data_set_reader_transport_data_type.rs | 9 +- ...ker_data_set_writer_transport_data_type.rs | 9 +- ...broker_writer_group_transport_data_type.rs | 9 +- .../src/generated/types/browse_description.rs | 9 +- .../generated/types/browse_next_request.rs | 9 +- .../generated/types/browse_next_response.rs | 9 +- .../src/generated/types/browse_path.rs | 9 +- .../src/generated/types/browse_path_result.rs | 9 +- .../src/generated/types/browse_path_target.rs | 9 +- .../src/generated/types/browse_request.rs | 9 +- .../src/generated/types/browse_response.rs | 9 +- .../src/generated/types/browse_result.rs | 9 +- .../src/generated/types/build_info.rs | 9 +- .../generated/types/call_method_request.rs | 9 +- .../src/generated/types/call_method_result.rs | 9 +- .../src/generated/types/call_request.rs | 9 +- .../src/generated/types/call_response.rs | 9 +- .../src/generated/types/cancel_request.rs | 9 +- .../src/generated/types/cancel_response.rs | 9 +- .../generated/types/cartesian_coordinates.rs | 9 +- .../generated/types/channel_security_token.rs | 9 +- .../types/close_secure_channel_request.rs | 9 +- .../types/close_secure_channel_response.rs | 9 +- .../generated/types/close_session_request.rs | 9 +- .../generated/types/close_session_response.rs | 9 +- .../generated/types/complex_number_type.rs | 9 +- .../types/configuration_version_data_type.rs | 9 +- .../types/connection_transport_data_type.rs | 9 +- .../src/generated/types/content_filter.rs | 9 +- .../generated/types/content_filter_element.rs | 9 +- .../types/content_filter_element_result.rs | 9 +- .../generated/types/content_filter_result.rs | 9 +- .../types/create_monitored_items_request.rs | 9 +- .../types/create_monitored_items_response.rs | 9 +- .../generated/types/create_session_request.rs | 9 +- .../types/create_session_response.rs | 9 +- .../types/create_subscription_request.rs | 9 +- .../types/create_subscription_response.rs | 9 +- .../src/generated/types/currency_unit_type.rs | 9 +- .../src/generated/types/data_change_filter.rs | 9 +- .../types/data_change_notification.rs | 9 +- .../types/data_set_meta_data_type.rs | 9 +- .../types/data_set_reader_data_type.rs | 9 +- .../data_set_reader_message_data_type.rs | 9 +- .../data_set_reader_transport_data_type.rs | 9 +- .../types/data_set_writer_data_type.rs | 9 +- .../data_set_writer_message_data_type.rs | 9 +- .../data_set_writer_transport_data_type.rs | 9 +- .../generated/types/data_type_attributes.rs | 9 +- .../generated/types/data_type_description.rs | 9 +- .../types/data_type_schema_header.rs | 9 +- ...tagram_connection_transport_2_data_type.rs | 9 +- ...datagram_connection_transport_data_type.rs | 9 +- ...ram_data_set_reader_transport_data_type.rs | 9 +- ...gram_writer_group_transport_2_data_type.rs | 9 +- ...tagram_writer_group_transport_data_type.rs | 9 +- .../generated/types/delete_at_time_details.rs | 9 +- .../generated/types/delete_event_details.rs | 9 +- .../types/delete_monitored_items_request.rs | 9 +- .../types/delete_monitored_items_response.rs | 9 +- .../src/generated/types/delete_nodes_item.rs | 9 +- .../generated/types/delete_nodes_request.rs | 9 +- .../generated/types/delete_nodes_response.rs | 9 +- .../types/delete_raw_modified_details.rs | 9 +- .../generated/types/delete_references_item.rs | 9 +- .../types/delete_references_request.rs | 9 +- .../types/delete_references_response.rs | 9 +- .../types/delete_subscriptions_request.rs | 9 +- .../types/delete_subscriptions_response.rs | 9 +- .../types/discovery_configuration.rs | 9 +- .../types/double_complex_number_type.rs | 9 +- .../src/generated/types/element_operand.rs | 9 +- .../generated/types/endpoint_configuration.rs | 9 +- .../generated/types/endpoint_description.rs | 9 +- .../src/generated/types/endpoint_type.rs | 9 +- .../types/endpoint_url_list_data_type.rs | 9 +- .../src/generated/types/enum_definition.rs | 9 +- .../src/generated/types/enum_description.rs | 9 +- .../src/generated/types/enum_field.rs | 9 +- .../src/generated/types/enum_value_type.rs | 9 +- .../src/generated/types/enums.rs | 778 +++++++++++++++--- .../src/generated/types/ephemeral_key_type.rs | 9 +- .../src/generated/types/eu_information.rs | 9 +- .../src/generated/types/event_field_list.rs | 9 +- .../src/generated/types/event_filter.rs | 9 +- .../generated/types/event_filter_result.rs | 9 +- .../types/event_notification_list.rs | 9 +- .../src/generated/types/field_meta_data.rs | 9 +- .../generated/types/field_target_data_type.rs | 9 +- .../src/generated/types/filter_operand.rs | 9 +- .../types/find_servers_on_network_request.rs | 9 +- .../types/find_servers_on_network_response.rs | 9 +- .../generated/types/find_servers_request.rs | 9 +- .../generated/types/find_servers_response.rs | 9 +- .../src/generated/types/frame.rs | 9 +- .../types/generic_attribute_value.rs | 9 +- .../src/generated/types/generic_attributes.rs | 9 +- .../generated/types/get_endpoints_request.rs | 9 +- .../generated/types/get_endpoints_response.rs | 9 +- .../src/generated/types/history_data.rs | 9 +- .../src/generated/types/history_event.rs | 9 +- .../types/history_event_field_list.rs | 9 +- .../generated/types/history_modified_data.rs | 9 +- .../generated/types/history_modified_event.rs | 9 +- .../generated/types/history_read_details.rs | 9 +- .../generated/types/history_read_request.rs | 9 +- .../generated/types/history_read_response.rs | 9 +- .../generated/types/history_read_result.rs | 9 +- .../generated/types/history_read_value_id.rs | 9 +- .../generated/types/history_update_details.rs | 9 +- .../generated/types/history_update_request.rs | 9 +- .../types/history_update_response.rs | 9 +- .../generated/types/history_update_result.rs | 9 +- .../types/identity_mapping_rule_type.rs | 9 +- .../generated/types/issued_identity_token.rs | 9 +- .../json_data_set_reader_message_data_type.rs | 9 +- .../json_data_set_writer_message_data_type.rs | 9 +- .../json_writer_group_message_data_type.rs | 9 +- .../src/generated/types/key_value_pair.rs | 9 +- .../types/linear_conversion_data_type.rs | 9 +- .../src/generated/types/literal_operand.rs | 9 +- .../types/mdns_discovery_configuration.rs | 9 +- .../src/generated/types/method_attributes.rs | 9 +- async-opcua-types/src/generated/types/mod.rs | 8 +- .../types/model_change_structure_data_type.rs | 9 +- .../src/generated/types/modification_info.rs | 10 +- .../types/modify_monitored_items_request.rs | 9 +- .../types/modify_monitored_items_response.rs | 9 +- .../types/modify_subscription_request.rs | 9 +- .../types/modify_subscription_response.rs | 9 +- .../types/monitored_item_create_request.rs | 9 +- .../types/monitored_item_create_result.rs | 9 +- .../types/monitored_item_modify_request.rs | 9 +- .../types/monitored_item_modify_result.rs | 9 +- .../types/monitored_item_notification.rs | 9 +- .../src/generated/types/monitoring_filter.rs | 9 +- .../types/monitoring_filter_result.rs | 9 +- .../generated/types/monitoring_parameters.rs | 9 +- .../types/network_address_data_type.rs | 9 +- .../types/network_address_url_data_type.rs | 9 +- .../types/network_group_data_type.rs | 9 +- .../src/generated/types/node_attributes.rs | 9 +- .../src/generated/types/node_reference.rs | 9 +- .../generated/types/node_type_description.rs | 9 +- .../src/generated/types/notification_data.rs | 9 +- .../generated/types/notification_message.rs | 9 +- .../src/generated/types/object_attributes.rs | 9 +- .../generated/types/object_type_attributes.rs | 9 +- .../types/open_secure_channel_request.rs | 9 +- .../types/open_secure_channel_response.rs | 9 +- .../src/generated/types/option_set.rs | 9 +- .../src/generated/types/orientation.rs | 9 +- .../src/generated/types/parsing_result.rs | 9 +- .../src/generated/types/portable_node_id.rs | 9 +- .../types/portable_qualified_name.rs | 9 +- .../types/priority_mapping_entry_type.rs | 9 +- .../types/program_diagnostic_2_data_type.rs | 9 +- .../types/program_diagnostic_data_type.rs | 9 +- .../pub_sub_configuration_2_data_type.rs | 9 +- .../types/pub_sub_configuration_data_type.rs | 9 +- .../pub_sub_configuration_ref_data_type.rs | 9 +- .../pub_sub_configuration_value_data_type.rs | 9 +- .../types/pub_sub_connection_data_type.rs | 9 +- .../types/pub_sub_group_data_type.rs | 9 +- .../pub_sub_key_push_target_data_type.rs | 9 +- .../src/generated/types/publish_request.rs | 9 +- .../src/generated/types/publish_response.rs | 9 +- .../types/published_data_items_data_type.rs | 9 +- ...lished_data_set_custom_source_data_type.rs | 9 +- .../types/published_data_set_data_type.rs | 9 +- .../published_data_set_source_data_type.rs | 9 +- .../types/published_events_data_type.rs | 9 +- .../types/published_variable_data_type.rs | 9 +- .../src/generated/types/qos_data_type.rs | 9 +- .../src/generated/types/quantity_dimension.rs | 9 +- .../generated/types/query_data_description.rs | 9 +- .../src/generated/types/query_data_set.rs | 9 +- .../generated/types/query_first_request.rs | 9 +- .../generated/types/query_first_response.rs | 9 +- .../src/generated/types/query_next_request.rs | 9 +- .../generated/types/query_next_response.rs | 9 +- .../src/generated/types/range.rs | 9 +- .../src/generated/types/rational_number.rs | 9 +- .../types/read_annotation_data_details.rs | 9 +- .../generated/types/read_at_time_details.rs | 9 +- .../src/generated/types/read_event_details.rs | 9 +- .../generated/types/read_event_details_2.rs | 9 +- .../generated/types/read_processed_details.rs | 9 +- .../types/read_raw_modified_details.rs | 9 +- .../src/generated/types/read_request.rs | 9 +- .../src/generated/types/read_response.rs | 9 +- .../src/generated/types/read_value_id.rs | 9 +- .../generated/types/reader_group_data_type.rs | 9 +- .../types/reader_group_message_data_type.rs | 9 +- .../types/reader_group_transport_data_type.rs | 9 +- .../generated/types/receive_qos_data_type.rs | 9 +- .../types/receive_qos_priority_data_type.rs | 9 +- .../types/redundant_server_data_type.rs | 9 +- .../generated/types/reference_description.rs | 9 +- .../types/reference_description_data_type.rs | 9 +- .../types/reference_list_entry_data_type.rs | 9 +- .../types/reference_type_attributes.rs | 9 +- .../generated/types/register_nodes_request.rs | 9 +- .../types/register_nodes_response.rs | 9 +- .../types/register_server_2_request.rs | 9 +- .../types/register_server_2_response.rs | 9 +- .../types/register_server_request.rs | 9 +- .../types/register_server_response.rs | 9 +- .../src/generated/types/registered_server.rs | 9 +- .../src/generated/types/relative_path.rs | 9 +- .../generated/types/relative_path_element.rs | 9 +- .../src/generated/types/republish_request.rs | 9 +- .../src/generated/types/republish_response.rs | 9 +- .../generated/types/role_permission_type.rs | 9 +- ...sampling_interval_diagnostics_data_type.rs | 9 +- .../types/security_group_data_type.rs | 9 +- .../semantic_change_structure_data_type.rs | 9 +- .../server_diagnostics_summary_data_type.rs | 9 +- .../src/generated/types/server_on_network.rs | 9 +- .../types/server_status_data_type.rs | 9 +- .../types/service_counter_data_type.rs | 9 +- .../src/generated/types/service_fault.rs | 9 +- .../types/session_diagnostics_data_type.rs | 9 +- .../session_security_diagnostics_data_type.rs | 9 +- .../types/sessionless_invoke_request_type.rs | 9 +- .../types/sessionless_invoke_response_type.rs | 9 +- .../types/set_monitoring_mode_request.rs | 9 +- .../types/set_monitoring_mode_response.rs | 9 +- .../types/set_publishing_mode_request.rs | 9 +- .../types/set_publishing_mode_response.rs | 9 +- .../generated/types/set_triggering_request.rs | 9 +- .../types/set_triggering_response.rs | 9 +- .../src/generated/types/signature_data.rs | 9 +- .../types/signed_software_certificate.rs | 9 +- .../types/simple_attribute_operand.rs | 9 +- .../types/simple_type_description.rs | 9 +- ...tandalone_subscribed_data_set_data_type.rs | 9 +- ...alone_subscribed_data_set_ref_data_type.rs | 9 +- .../types/status_change_notification.rs | 9 +- .../src/generated/types/status_result.rs | 9 +- .../generated/types/structure_definition.rs | 9 +- .../generated/types/structure_description.rs | 9 +- .../src/generated/types/structure_field.rs | 9 +- .../types/subscribed_data_set_data_type.rs | 9 +- .../subscribed_data_set_mirror_data_type.rs | 9 +- .../types/subscription_acknowledgement.rs | 9 +- .../subscription_diagnostics_data_type.rs | 9 +- .../types/target_variables_data_type.rs | 9 +- .../types/three_d_cartesian_coordinates.rs | 9 +- .../src/generated/types/three_d_frame.rs | 9 +- .../generated/types/three_d_orientation.rs | 9 +- .../src/generated/types/three_d_vector.rs | 9 +- .../generated/types/time_zone_data_type.rs | 9 +- .../generated/types/transaction_error_type.rs | 9 +- .../src/generated/types/transfer_result.rs | 9 +- .../types/transfer_subscriptions_request.rs | 9 +- .../types/transfer_subscriptions_response.rs | 9 +- ...nslate_browse_paths_to_node_ids_request.rs | 9 +- ...slate_browse_paths_to_node_ids_response.rs | 9 +- .../generated/types/transmit_qos_data_type.rs | 9 +- .../types/transmit_qos_priority_data_type.rs | 9 +- .../generated/types/trust_list_data_type.rs | 9 +- .../types/ua_binary_file_data_type.rs | 9 +- .../uadp_data_set_reader_message_data_type.rs | 9 +- .../uadp_data_set_writer_message_data_type.rs | 9 +- .../uadp_writer_group_message_data_type.rs | 9 +- .../types/unregister_nodes_request.rs | 9 +- .../types/unregister_nodes_response.rs | 9 +- .../types/unsigned_rational_number.rs | 9 +- .../generated/types/update_data_details.rs | 9 +- .../generated/types/update_event_details.rs | 9 +- .../types/update_structure_data_details.rs | 9 +- .../generated/types/user_identity_token.rs | 9 +- .../types/user_management_data_type.rs | 9 +- .../types/user_name_identity_token.rs | 9 +- .../src/generated/types/user_token_policy.rs | 9 +- .../generated/types/variable_attributes.rs | 9 +- .../types/variable_type_attributes.rs | 9 +- .../src/generated/types/vector.rs | 9 +- .../src/generated/types/view_attributes.rs | 9 +- .../src/generated/types/view_description.rs | 9 +- .../src/generated/types/write_request.rs | 9 +- .../src/generated/types/write_response.rs | 9 +- .../src/generated/types/write_value.rs | 9 +- .../generated/types/writer_group_data_type.rs | 9 +- .../types/writer_group_message_data_type.rs | 9 +- .../types/writer_group_transport_data_type.rs | 9 +- .../generated/types/x_509_identity_token.rs | 9 +- .../src/generated/types/xv_type.rs | 9 +- async-opcua-types/src/guid.rs | 4 + async-opcua-types/src/lib.rs | 7 +- async-opcua-types/src/localized_text.rs | 4 + async-opcua-types/src/node_id.rs | 20 +- async-opcua-types/src/qualified_name.rs | 164 +++- async-opcua-types/src/request_header.rs | 5 +- async-opcua-types/src/response_header.rs | 5 +- async-opcua-types/src/status_code.rs | 6 +- async-opcua-types/src/string.rs | 4 + async-opcua-types/src/tests/json.rs | 6 +- async-opcua-types/src/tests/xml.rs | 441 +++++----- async-opcua-types/src/type_loader.rs | 55 +- async-opcua-types/src/variant/mod.rs | 2 + async-opcua-types/src/variant/xml.rs | 296 +++++++ async-opcua-types/src/xml/builtins.rs | 151 +++- async-opcua-types/src/xml/encoding.rs | 89 +- async-opcua-types/src/xml/mod.rs | 447 +--------- async-opcua-xml/src/encoding/reader.rs | 28 +- async-opcua-xml/src/error.rs | 9 + async-opcua-xml/src/schema/opc_ua_types.rs | 16 +- code_gen_config.yml | 1 + .../src/generated/types/enums.rs | 153 +++- .../custom-codegen/src/generated/types/mod.rs | 8 +- .../src/generated/types/structs.rs | 27 +- samples/demo-server/src/customs.rs | 18 +- 362 files changed, 5477 insertions(+), 1230 deletions(-) create mode 100644 async-opcua-types/src/custom/xml.rs create mode 100644 async-opcua-types/src/variant/xml.rs diff --git a/Cargo.lock b/Cargo.lock index afdec840..fb728323 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -347,6 +347,7 @@ dependencies = [ "chrono", "hashbrown 0.15.2", "log", + "percent-encoding-rfc3986", "regex", "serde_json", "struson", @@ -1487,6 +1488,12 @@ version = "2.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" +[[package]] +name = "percent-encoding-rfc3986" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3637c05577168127568a64e9dc5a6887da720efef07b3d9472d45f63ab191166" + [[package]] name = "pico-args" version = "0.5.0" diff --git a/TODO.md b/TODO.md index f68e3cbb..a941466a 100644 --- a/TODO.md +++ b/TODO.md @@ -9,7 +9,10 @@ This is a list of things that are known to be missing, or ideas that could be im - Implement a better framework for security checks on the server. - Write a sophisticated server example with a persistent store. This would be a great way to verify the flexibility of the server. - Write some "bad ideas" servers, it would be nice to showcase how flexible this is. - - Re-implement XML. The current approach using roxmltree is easy to write, but not actually what we need if we really wanted to implement OPC-UA XML encoding. A stream-based low level XML parser like `quick-xml` would probably be a better option. An implementation could probably borrow a lot from the JSON implementation. + - Finish up XML implementation. + - Support for XML bodies in binary and JSON extension objects. + - Support for unions in derive macros. + - Support for XmlElement in Variant. - Write a framework for method calls. The foundation for this has been laid with `TryFromVariant`, if we really wanted to we could use clever trait magic to let users simply define a rust method that takes in values that each implement a trait `MethodArg`, with a blanket impl for `TryFromVariant`, and return a tuple of results. Could be really powerful, but methods are a little niche. - Implement `Query`. I never got around to this, because the service is just so complex. Currently there is no way to actually implement it, since it won't work unless _all_ node managers implement it, and the core node managers don't. - Look into running certain services concurrently. Currently they are sequential because that makes everything much simpler, but the services that don't have any cross node-manager interaction could run on all node managers concurrently. diff --git a/async-opcua-client/src/custom_types/mod.rs b/async-opcua-client/src/custom_types/mod.rs index 67e2cf8a..9c5c7ac8 100644 --- a/async-opcua-client/src/custom_types/mod.rs +++ b/async-opcua-client/src/custom_types/mod.rs @@ -52,6 +52,7 @@ struct RawTypeData { type_definition: Option, is_abstract: bool, encoding_ids: Option, + name: String, } impl bool> DataTypeTreeBuilder { @@ -282,6 +283,7 @@ impl bool> DataTypeTreeBuilder { if let Some(def) = type_data.type_definition { let info = match TypeInfo::from_type_definition( def, + type_data.name, type_data.encoding_ids, type_data.is_abstract, &id, diff --git a/async-opcua-codegen/src/nodeset/value.rs b/async-opcua-codegen/src/nodeset/value.rs index 917d2b0a..a36e5d0e 100644 --- a/async-opcua-codegen/src/nodeset/value.rs +++ b/async-opcua-codegen/src/nodeset/value.rs @@ -264,13 +264,19 @@ impl<'a> ValueBuilder<'a> { } fn render_extension_object(&self, obj: &ExtensionObject) -> Result { - let Some(body) = &obj.body else { + let Some(data) = obj.body.as_ref().and_then(|b| b.data.as_ref()) else { return Ok(quote::quote! { opcua::types::ExtensionObject::null() }); }; - let content = self.render_extension_object_inner(&body.data)?; + let element = XmlElement::parse(data)?; + let Some(element) = element else { + return Ok(quote::quote! { + opcua::types::ExtensionObject::null() + }); + }; + let content = self.render_extension_object_inner(&element)?; Ok(quote! { opcua::types::ExtensionObject::from_message(#content) diff --git a/async-opcua-codegen/src/types/gen.rs b/async-opcua-codegen/src/types/gen.rs index 279dfcf1..bb114408 100644 --- a/async-opcua-codegen/src/types/gen.rs +++ b/async-opcua-codegen/src/types/gen.rs @@ -140,7 +140,7 @@ impl CodeGenerator { fn is_default_recursive(&self, name: &str) -> bool { if self.default_excluded.contains(name) { - return false; + return true; } let Some(it) = self.import_map.get(name) else { @@ -361,20 +361,39 @@ impl CodeGenerator { } }); - // Xml impl impls.push(parse_quote! { #[cfg(feature = "xml")] - impl opcua::types::xml::FromXml for #enum_ident { - fn from_xml( - element: &opcua::types::xml::XmlElement, - ctx: &opcua::types::Context<'_> + impl opcua::types::xml::XmlDecodable for #enum_ident { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, + ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = #ty::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(#ty::decode(stream, ctx)?)) } } }); + impls.push(parse_quote! { + #[cfg(feature = "xml")] + impl opcua::types::xml::XmlEncodable for #enum_ident { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) + } + } + }); + + let name = &item.name; + impls.push(parse_quote! { + #[cfg(feature = "xml")] + impl opcua::types::xml::XmlType for #enum_ident { + const TAG: &'static str = #name; + } + }); + impls.push(parse_quote! { #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for #enum_ident { @@ -443,7 +462,10 @@ impl CodeGenerator { )] }); attrs.push(parse_quote! { - #[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] + #[cfg_attr( + feature = "xml", + derive(opcua::types::XmlEncodable, opcua::types::XmlDecodable, opcua::types::XmlType) + )] }); let ty: Type = syn::parse_str(&item.typ.to_string())?; attrs.push(parse_quote! { @@ -504,7 +526,13 @@ impl CodeGenerator { } } - let (enum_ident, _) = safe_ident(&item.name); + let (enum_ident, renamed) = safe_ident(&item.name); + if renamed { + let name = &item.name; + attrs.push(parse_quote! { + #[opcua(rename = #name)] + }); + } let res = ItemEnum { attrs, @@ -565,17 +593,26 @@ impl CodeGenerator { #[cfg_attr(feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable))] }); attrs.push(parse_quote! { - #[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] + #[cfg_attr( + feature = "xml", + derive(opcua::types::XmlEncodable, opcua::types::XmlDecodable, opcua::types::XmlType) + )] }); - if self.has_default(&item.name) { + if self.has_default(&item.name) && !self.default_excluded.contains(&item.name) { attrs.push(parse_quote! { #[derive(Default)] }); } let mut impls = Vec::new(); - let (struct_ident, _) = safe_ident(&item.name); + let (struct_ident, renamed) = safe_ident(&item.name); + if renamed { + let name = &item.name; + attrs.push(parse_quote! { + #[opcua(rename = #name)] + }); + } for field in item.visible_fields() { let typ: Type = match &field.typ { diff --git a/async-opcua-codegen/src/types/mod.rs b/async-opcua-codegen/src/types/mod.rs index f3c36caa..667df87a 100644 --- a/async-opcua-codegen/src/types/mod.rs +++ b/async-opcua-codegen/src/types/mod.rs @@ -282,14 +282,14 @@ fn xml_loader_impl(ids: &[&(EncodingIds, String)], namespace: &str) -> (TokenStr fn load_from_xml( &self, node_id: &opcua::types::NodeId, - stream: &opcua::types::xml::XmlElement, + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> Option>> { #index_check let Some(num_id) = node_id.as_u32() else { return Some(Err(opcua::types::Error::decoding( - format!("Unsupported encoding ID {node_id}, we only support numeric IDs"), + "Unsupported encoding ID. Only numeric encoding IDs are currently supported" ))); }; diff --git a/async-opcua-macros/src/encoding/attribute.rs b/async-opcua-macros/src/encoding/attribute.rs index e175c449..15e0ee61 100644 --- a/async-opcua-macros/src/encoding/attribute.rs +++ b/async-opcua-macros/src/encoding/attribute.rs @@ -89,3 +89,38 @@ impl Parse for EncodingVariantAttribute { Ok(slf) } } + +#[derive(Debug, Default)] +pub(crate) struct EncodingItemAttribute { + #[allow(unused)] + pub(crate) rename: Option, +} + +impl ItemAttr for EncodingItemAttribute { + fn combine(&mut self, other: Self) { + self.rename = other.rename; + } +} + +impl Parse for EncodingItemAttribute { + fn parse(input: syn::parse::ParseStream) -> syn::Result { + let mut slf = Self::default(); + + loop { + let ident: Ident = input.parse()?; + match ident.to_string().as_str() { + "rename" => { + input.parse::()?; + let val: LitStr = input.parse()?; + slf.rename = Some(val.value()); + } + _ => return Err(syn::Error::new_spanned(ident, "Unknown attribute value")), + } + if !input.peek(Token![,]) { + break; + } + input.parse::()?; + } + Ok(slf) + } +} diff --git a/async-opcua-macros/src/encoding/enums.rs b/async-opcua-macros/src/encoding/enums.rs index ea4ee887..bbdf764c 100644 --- a/async-opcua-macros/src/encoding/enums.rs +++ b/async-opcua-macros/src/encoding/enums.rs @@ -1,13 +1,13 @@ use proc_macro2::TokenStream; -use syn::{Attribute, DataEnum, Expr, Ident, Type, Variant}; +use syn::{Attribute, DataEnum, Ident, LitInt, Type, Variant}; use crate::utils::ItemAttr; -use quote::quote; +use quote::{quote, ToTokens}; -use super::attribute::EncodingVariantAttribute; +use super::attribute::{EncodingItemAttribute, EncodingVariantAttribute}; pub struct SimpleEnumVariant { - pub value: Expr, + pub value: LitInt, pub name: Ident, pub attr: EncodingVariantAttribute, } @@ -16,6 +16,8 @@ pub struct SimpleEnum { pub repr: Type, pub variants: Vec, pub ident: Ident, + #[allow(unused)] + pub attr: EncodingItemAttribute, } impl SimpleEnumVariant { @@ -26,6 +28,7 @@ impl SimpleEnumVariant { "Enum variant must have explicit discriminant", )); }; + let value = syn::parse2(value.into_token_stream())?; if !variant.fields.is_empty() { return Err(syn::Error::new_spanned( variant.fields, @@ -66,16 +69,19 @@ impl SimpleEnum { .collect::, _>>()?; let mut repr: Option = None; + let mut final_attr = EncodingItemAttribute::default(); for attr in attributes { - if attr.path().segments.len() == 1 - && attr - .path() - .segments - .first() - .is_some_and(|s| s.ident == "repr") - { + if attr.path().segments.len() != 1 { + continue; + } + let seg = attr.path().segments.first(); + if seg.is_some_and(|s| s.ident == "repr") { repr = Some(attr.parse_args()?); } + if seg.is_some_and(|s| s.ident == "opcua") { + let data: EncodingItemAttribute = attr.parse_args()?; + final_attr.combine(data); + } } let Some(repr) = repr else { @@ -89,6 +95,7 @@ impl SimpleEnum { repr, variants, ident, + attr: final_attr, }) } } @@ -117,9 +124,9 @@ pub fn derive_ua_enum_impl(en: SimpleEnum) -> syn::Result { let val = variant.value; let name = variant.name; let name_str = if let Some(rename) = variant.attr.rename { - rename + format!("{}_{}", rename, val.base10_digits()) } else { - name.to_string() + format!("{}_{}", name, val.base10_digits()) }; try_from_arms.extend(quote! { #val => Self::#name, diff --git a/async-opcua-macros/src/encoding/json.rs b/async-opcua-macros/src/encoding/json.rs index d5d25d74..53908da6 100644 --- a/async-opcua-macros/src/encoding/json.rs +++ b/async-opcua-macros/src/encoding/json.rs @@ -150,14 +150,16 @@ pub fn generate_json_decode_impl(strct: EncodingStruct) -> syn::Result; +pub(crate) type EncodingStruct = StructItem; pub(crate) enum EncodingInput { Struct(EncodingStruct), @@ -81,6 +81,12 @@ pub enum EncodingToImpl { JsonDecode, #[cfg(feature = "xml")] FromXml, + #[cfg(feature = "xml")] + XmlEncode, + #[cfg(feature = "xml")] + XmlDecode, + #[cfg(feature = "xml")] + XmlType, } pub fn generate_encoding_impl( @@ -126,6 +132,47 @@ pub fn generate_encoding_impl( generate_union_json_decode_impl(s) } + #[cfg(feature = "xml")] + (EncodingToImpl::XmlEncode, EncodingInput::Struct(s)) => xml::generate_xml_encode_impl(s), + #[cfg(feature = "xml")] + (EncodingToImpl::XmlEncode, EncodingInput::SimpleEnum(s)) => { + xml::generate_simple_enum_xml_encode_impl(s) + } + #[cfg(feature = "xml")] + (EncodingToImpl::XmlEncode, EncodingInput::AdvancedEnum(s)) => { + // xml::generate_union_xml_encode_impl(s) + Err(syn::Error::new_spanned( + s.ident, + "XmlEncodable is not supported on unions yet", + )) + } + #[cfg(feature = "xml")] + (EncodingToImpl::XmlDecode, EncodingInput::Struct(s)) => xml::generate_xml_decode_impl(s), + #[cfg(feature = "xml")] + (EncodingToImpl::XmlDecode, EncodingInput::SimpleEnum(s)) => { + xml::generate_simple_enum_xml_decode_impl(s) + } + #[cfg(feature = "xml")] + (EncodingToImpl::XmlDecode, EncodingInput::AdvancedEnum(s)) => { + // xml::generate_union_xml_decode_impl(s) + Err(syn::Error::new_spanned( + s.ident, + "XmlDecodable is not supported on unions yet", + )) + } + #[cfg(feature = "xml")] + (EncodingToImpl::XmlType, EncodingInput::Struct(s)) => { + xml::generate_xml_type_impl(s.ident, s.attribute) + } + #[cfg(feature = "xml")] + (EncodingToImpl::XmlType, EncodingInput::SimpleEnum(s)) => { + xml::generate_xml_type_impl(s.ident, s.attr) + } + #[cfg(feature = "xml")] + (EncodingToImpl::XmlType, EncodingInput::AdvancedEnum(s)) => { + xml::generate_xml_type_impl(s.ident, s.attr) + } + #[cfg(feature = "xml")] (EncodingToImpl::FromXml, EncodingInput::Struct(s)) => generate_xml_impl(s), #[cfg(feature = "xml")] diff --git a/async-opcua-macros/src/encoding/unions.rs b/async-opcua-macros/src/encoding/unions.rs index 0765963e..7e2ed937 100644 --- a/async-opcua-macros/src/encoding/unions.rs +++ b/async-opcua-macros/src/encoding/unions.rs @@ -2,7 +2,7 @@ use syn::{Ident, Variant}; use crate::utils::ItemAttr; -use super::attribute::EncodingVariantAttribute; +use super::attribute::{EncodingItemAttribute, EncodingVariantAttribute}; pub struct AdvancedEnumVariant { pub name: Ident, @@ -15,6 +15,8 @@ pub struct AdvancedEnum { pub variants: Vec, pub ident: Ident, pub null_variant: Option, + #[allow(unused)] + pub attr: EncodingItemAttribute, } impl AdvancedEnumVariant { @@ -52,7 +54,7 @@ impl AdvancedEnumVariant { impl AdvancedEnum { pub fn from_input( input: syn::DataEnum, - _attributes: Vec, + attributes: Vec, ident: Ident, ) -> syn::Result { let variants = input @@ -61,6 +63,20 @@ impl AdvancedEnum { .map(AdvancedEnumVariant::from_variant) .collect::>>()?; + let mut final_attr: EncodingItemAttribute = EncodingItemAttribute::default(); + for attr in attributes { + if attr.path().segments.len() == 1 + && attr + .path() + .segments + .first() + .is_some_and(|s| s.ident == "opcua") + { + let data: EncodingItemAttribute = attr.parse_args()?; + final_attr.combine(data); + } + } + let mut null_variant = None; for vrt in &variants { if vrt.is_null { @@ -77,6 +93,7 @@ impl AdvancedEnum { variants, ident, null_variant, + attr: final_attr, }) } } diff --git a/async-opcua-macros/src/encoding/xml.rs b/async-opcua-macros/src/encoding/xml.rs index 5c630e08..2a52be04 100644 --- a/async-opcua-macros/src/encoding/xml.rs +++ b/async-opcua-macros/src/encoding/xml.rs @@ -1,9 +1,10 @@ use convert_case::{Case, Casing}; -use proc_macro2::TokenStream; +use proc_macro2::{Span, TokenStream}; +use syn::Ident; use quote::quote; -use super::{enums::SimpleEnum, EncodingStruct}; +use super::{attribute::EncodingItemAttribute, enums::SimpleEnum, EncodingStruct}; pub fn generate_xml_impl(strct: EncodingStruct) -> syn::Result { let ident = strct.ident; @@ -53,3 +54,226 @@ pub fn generate_simple_enum_xml_impl(en: SimpleEnum) -> syn::Result } }) } + +pub fn generate_xml_encode_impl(strct: EncodingStruct) -> syn::Result { + let ident = strct.ident; + let mut body = quote! { + use opcua::types::xml::XmlWriteExt; + }; + + let any_optional = strct + .fields + .iter() + .any(|f| f.attr.optional && !f.attr.ignore); + + if any_optional { + let mut optional_index = 0; + body.extend(quote! { + let mut encoding_mask = 0u32; + }); + for field in &strct.fields { + if !field.attr.optional || field.attr.ignore { + continue; + } + let ident = &field.ident; + body.extend(quote! { + if self.#ident.as_ref().is_some() { + encoding_mask |= 1 << #optional_index; + } + }); + optional_index += 1; + } + body.extend(quote! { + stream.encode_child("EncodingMask", &encoding_mask, ctx)?; + }); + } + + for field in strct.fields { + if field.attr.ignore { + continue; + } + + let name = field + .attr + .rename + .unwrap_or_else(|| field.ident.to_string().to_case(Case::Pascal)); + + let ident = field.ident; + if field.attr.optional { + body.extend(quote! { + if let Some(item) = &self.#ident { + stream.encode_child(#name, item, ctx)?; + } + }); + } else { + body.extend(quote! { + stream.encode_child(#name, &self.#ident, ctx)?; + }); + } + } + + Ok(quote! { + impl opcua::types::xml::XmlEncodable for #ident { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + #body + Ok(()) + } + } + }) +} + +pub fn generate_xml_decode_impl(strct: EncodingStruct) -> syn::Result { + let ident = strct.ident; + let mut items = quote! {}; + let mut items_match = quote! {}; + let mut build = quote! {}; + + let has_header = strct.fields.iter().any(|i| { + matches!( + i.ident.to_string().as_str(), + "request_header" | "response_header" + ) + }); + + if has_header { + items.extend(quote! { + let mut __request_handle = None; + }); + } + + for field in strct.fields { + if field.attr.ignore { + let ident = field.ident; + + build.extend(quote! { + #ident: Default::default(), + }); + continue; + } + + let name = field + .attr + .rename + .unwrap_or_else(|| field.ident.to_string().to_case(Case::Pascal)); + let is_header = matches!(name.as_str(), "RequestHeader" | "ResponseHeader"); + + let ident = field.ident; + items.extend(quote! { + let mut #ident = None; + }); + if is_header { + let ty = Ident::new(&name, Span::call_site()); + items_match.extend(quote! { + #name => { + let __header: opcua::types::#ty = opcua::types::xml::XmlDecodable::decode(stream, ctx)?; + __request_handle = Some(__header.request_handle); + } + }); + } else if has_header { + items_match.extend(quote! { + #name => { + #ident = Some(opcua::types::xml::XmlDecodable::decode(stream, ctx) + .map_err(|e| e.maybe_with_request_handle(__request_handle))?); + } + }); + } else { + items_match.extend(quote! { + #name => { + #ident = Some(opcua::types::xml::XmlDecodable::decode(stream, ctx)?); + } + }); + } + + if field.attr.no_default { + let err = format!("Missing required field {name}"); + let handle = if has_header { + quote! { + .map_err(|e| e.maybe_with_request_handle(__request_handle))? + } + } else { + quote! {} + }; + build.extend(quote! { + #ident: #ident.unwrap_or_else(|| { + opcua::types::Error::decoding(#err)#handle + })?, + }); + } else { + build.extend(quote! { + #ident: #ident.unwrap_or_default(), + }); + } + } + + Ok(quote! { + impl opcua::types::xml::XmlDecodable for #ident { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult { + use opcua::types::xml::XmlReadExt; + #items + stream.iter_children(|__key, stream, ctx| { + match __key.as_str() { + #items_match + _ => { + stream.skip_value()?; + } + } + Ok(()) + }, ctx)?; + + Ok(Self { + #build + }) + } + } + }) +} + +pub fn generate_simple_enum_xml_decode_impl(en: SimpleEnum) -> syn::Result { + let ident = en.ident; + + Ok(quote! { + impl opcua::types::xml::XmlDecodable for #ident { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult { + use std::str::FromStr; + let val = stream.consume_as_text()?; + opcua::types::UaEnum::from_str(&val) + } + } + }) +} + +pub fn generate_simple_enum_xml_encode_impl(en: SimpleEnum) -> syn::Result { + let ident = en.ident; + + Ok(quote! { + impl opcua::types::xml::XmlEncodable for #ident { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + _ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + stream.write_text(opcua::types::UaEnum::as_str(self))?; + Ok(()) + } + } + }) +} + +pub fn generate_xml_type_impl(idt: Ident, attr: EncodingItemAttribute) -> syn::Result { + let name = attr.rename.unwrap_or_else(|| idt.to_string()); + Ok(quote! { + impl opcua::types::xml::XmlType for #idt { + const TAG: &'static str = #name; + } + }) +} diff --git a/async-opcua-macros/src/lib.rs b/async-opcua-macros/src/lib.rs index 0acb6486..b88a5f81 100644 --- a/async-opcua-macros/src/lib.rs +++ b/async-opcua-macros/src/lib.rs @@ -148,3 +148,40 @@ pub fn derive_ua_enum(item: TokenStream) -> TokenStream { Err(e) => e.to_compile_error().into(), } } + +#[cfg(feature = "xml")] +#[proc_macro_derive(XmlEncodable, attributes(opcua))] +/// Derive the `XmlEncodable` trait on this struct or enum, creating +/// code to write the struct as OPC-UA XML. +/// +/// All fields must be marked with `opcua(ignore)` or implement `XmlEncodable`. +pub fn derive_xml_encodable(item: TokenStream) -> TokenStream { + match generate_encoding_impl(parse_macro_input!(item), EncodingToImpl::XmlEncode) { + Ok(r) => r.into(), + Err(e) => e.to_compile_error().into(), + } +} + +#[cfg(feature = "xml")] +#[proc_macro_derive(XmlDecodable, attributes(opcua))] +/// Derive the `XmlDecodable` trait on this struct or enum, creating +/// code to read the struct from an OPC-UA xml stream. +/// +/// All fields must be marked with `opcua(ignore)` or implement `XmlDecodable`. +pub fn derive_xml_decodable(item: TokenStream) -> TokenStream { + match generate_encoding_impl(parse_macro_input!(item), EncodingToImpl::XmlDecode) { + Ok(r) => r.into(), + Err(e) => e.to_compile_error().into(), + } +} + +#[cfg(feature = "xml")] +#[proc_macro_derive(XmlType, attributes(opcua))] +/// Derive the `XmlType` trait on this struct or enum. This simply exposes +/// the type name, which can be overridden with an item-level `opcua(rename = ...)` attribute. +pub fn derive_xml_type(item: TokenStream) -> TokenStream { + match generate_encoding_impl(parse_macro_input!(item), EncodingToImpl::XmlType) { + Ok(r) => r.into(), + Err(e) => e.to_compile_error().into(), + } +} diff --git a/async-opcua-types/Cargo.toml b/async-opcua-types/Cargo.toml index 595f5be1..138b0779 100644 --- a/async-opcua-types/Cargo.toml +++ b/async-opcua-types/Cargo.toml @@ -34,6 +34,7 @@ struson = { workspace = true, optional = true } async-opcua-macros = { path = "../async-opcua-macros", version = "0.14.0" } async-opcua-xml = { path = "../async-opcua-xml", optional = true, version = "0.14.0" } +percent-encoding-rfc3986 = "0.1.3" [dev-dependencies] async-opcua-types = { path = ".", features = ["xml", "json"] } diff --git a/async-opcua-types/src/argument.rs b/async-opcua-types/src/argument.rs index ba43602c..8c6d4856 100644 --- a/async-opcua-types/src/argument.rs +++ b/async-opcua-types/src/argument.rs @@ -33,7 +33,10 @@ mod opcua { #[derive(Clone, Debug, PartialEq, Default)] #[cfg_attr(feature = "json", derive(crate::JsonEncodable, crate::JsonDecodable))] -#[cfg_attr(feature = "xml", derive(crate::FromXml))] +#[cfg_attr( + feature = "xml", + derive(crate::XmlEncodable, crate::XmlDecodable, crate::XmlType) +)] /// OPC-UA method argument. pub struct Argument { /// Argument name. diff --git a/async-opcua-types/src/byte_string.rs b/async-opcua-types/src/byte_string.rs index 097d5b9f..4490781a 100644 --- a/async-opcua-types/src/byte_string.rs +++ b/async-opcua-types/src/byte_string.rs @@ -81,6 +81,10 @@ mod xml { use super::ByteString; + impl XmlType for ByteString { + const TAG: &'static str = "ByteString"; + } + impl XmlEncodable for ByteString { fn encode( &self, diff --git a/async-opcua-types/src/custom/custom_struct.rs b/async-opcua-types/src/custom/custom_struct.rs index 30ea9247..2da0aff3 100644 --- a/async-opcua-types/src/custom/custom_struct.rs +++ b/async-opcua-types/src/custom/custom_struct.rs @@ -593,14 +593,18 @@ impl TypeLoader for DynamicTypeLoader { #[cfg(feature = "xml")] fn load_from_xml( &self, - _node_id: &crate::NodeId, - _body: &opcua_xml::XmlElement, - _ctx: &Context<'_>, + node_id: &crate::NodeId, + stream: &mut crate::xml::XmlStreamReader<&mut dyn std::io::Read>, + ctx: &Context<'_>, ) -> Option>> { - // TODO: Unimplemented. - // This is a lot less useful than the others, since this method is currently only - // used server-side, and server software will usually use codegen instead. - None + let ty_node_id = if let Some(mapped) = self.type_tree.encoding_to_data_type().get(node_id) { + mapped + } else { + node_id + }; + let t = self.type_tree.get_struct_type(ty_node_id)?; + + Some(self.xml_decode_type_inner(stream, ctx, t)) } #[cfg(feature = "json")] @@ -693,6 +697,7 @@ pub(crate) mod tests { }, ]), }), + "EUInformation".to_owned(), Some(EncodingIds { binary_id: ObjectId::EUInformation_Encoding_DefaultBinary.into(), json_id: ObjectId::EUInformation_Encoding_DefaultJson.into(), @@ -801,6 +806,7 @@ pub(crate) mod tests { }, ]), }), + "MyType".to_owned(), Some(EncodingIds { binary_id: NodeId::new(1, 6), json_id: NodeId::new(1, 7), diff --git a/async-opcua-types/src/custom/json.rs b/async-opcua-types/src/custom/json.rs index 4e85bf20..bd1b65fe 100644 --- a/async-opcua-types/src/custom/json.rs +++ b/async-opcua-types/src/custom/json.rs @@ -564,6 +564,7 @@ mod tests { }, ]), }), + "EUInformation".to_owned(), Some(EncodingIds { binary_id: NodeId::new(1, 6), json_id: NodeId::new(1, 7), diff --git a/async-opcua-types/src/custom/mod.rs b/async-opcua-types/src/custom/mod.rs index f2415221..2072f868 100644 --- a/async-opcua-types/src/custom/mod.rs +++ b/async-opcua-types/src/custom/mod.rs @@ -5,6 +5,8 @@ mod custom_struct; #[cfg(feature = "json")] mod json; mod type_tree; +#[cfg(feature = "xml")] +mod xml; pub use custom_struct::{DynamicStructure, DynamicTypeLoader}; pub use type_tree::{ diff --git a/async-opcua-types/src/custom/type_tree.rs b/async-opcua-types/src/custom/type_tree.rs index 0cb4f63a..eeffadb6 100644 --- a/async-opcua-types/src/custom/type_tree.rs +++ b/async-opcua-types/src/custom/type_tree.rs @@ -98,6 +98,8 @@ pub struct StructTypeInfo { pub is_abstract: bool, /// Structure node ID. pub node_id: NodeId, + /// Structure name. + pub name: String, } impl StructTypeInfo { @@ -308,6 +310,7 @@ impl TypeInfo { /// Build a TypeInfo from the data type definition of the data type. pub fn from_type_definition( value: DataTypeDefinition, + name: String, encoding_ids: Option, is_abstract: bool, node_id: &NodeId, @@ -340,6 +343,7 @@ impl TypeInfo { is_abstract, node_id: node_id.clone(), index_by_name: fields_by_name, + name, }))) } DataTypeDefinition::Enum(d) => Ok(Self::Enum(Arc::new(EnumTypeInfo { diff --git a/async-opcua-types/src/custom/xml.rs b/async-opcua-types/src/custom/xml.rs new file mode 100644 index 00000000..b27569bd --- /dev/null +++ b/async-opcua-types/src/custom/xml.rs @@ -0,0 +1,443 @@ +use std::{collections::HashMap, io::Write, sync::Arc}; + +use crate::{ + xml::*, Array, ByteString, DataValue, DateTime, DiagnosticInfo, DynEncodable, ExpandedNodeId, + ExtensionObject, Guid, LocalizedText, NodeId, QualifiedName, StatusCode, StructureType, + UAString, Variant, VariantScalarTypeId, XmlElement, +}; + +use super::{DynamicStructure, DynamicTypeLoader, ParsedStructureField, StructTypeInfo}; + +impl XmlType for DynamicStructure { + // Should never be used, kept as a fallback. + const TAG: &'static str = "Unknown"; + fn tag(&self) -> &str { + &self.type_def.name + } +} + +impl DynamicStructure { + fn xml_encode_field( + &self, + stream: &mut XmlStreamWriter<&mut dyn Write>, + f: &Variant, + field: &ParsedStructureField, + ctx: &Context<'_>, + ) -> EncodingResult<()> { + stream.write_start(&field.name)?; + match f { + Variant::ExtensionObject(o) => { + let Some(field_ty) = self.type_tree.get_struct_type(&field.type_id) else { + return Err(Error::encoding(format!( + "Dynamic type field missing from type tree: {}", + field.type_id + ))); + }; + if field_ty.is_abstract { + o.encode(stream, ctx) + } else { + let Some(body) = &o.body else { + return Err(Error::encoding( + "Dynamic type field is missing extension object body", + )); + }; + body.encode_xml(stream, ctx) + } + } + Variant::Array(a) => { + if field.value_rank > 1 { + let Some(dims) = &a.dimensions else { + return Err(Error::encoding( + "ArrayDimensions are required for fields with value rank > 1", + )); + }; + if dims.len() as i32 != field.value_rank { + return Err(Error::encoding( + "ArrayDimensions must have length equal to field valuerank", + )); + } + // For some incredibly annoying reason, OPC-UA insists that dimensions be + // encoded as _signed_ integers. For other encoders it's irrelevant, + // but it matters for XML. + let dims: Vec<_> = dims.iter().map(|d| *d as i32).collect(); + stream.encode_child("Dimensions", &dims, ctx)?; + + stream.write_start("Elements")?; + for item in &a.values { + item.encode(stream, ctx)?; + } + stream.write_end("Elements")?; + } else { + for item in &a.values { + item.encode(stream, ctx)?; + } + } + Ok(()) + } + Variant::Empty => Ok(()), + Variant::Boolean(v) => v.encode(stream, ctx), + Variant::SByte(v) => v.encode(stream, ctx), + Variant::Byte(v) => v.encode(stream, ctx), + Variant::Int16(v) => v.encode(stream, ctx), + Variant::UInt16(v) => v.encode(stream, ctx), + Variant::Int32(v) => v.encode(stream, ctx), + Variant::UInt32(v) => v.encode(stream, ctx), + Variant::Int64(v) => v.encode(stream, ctx), + Variant::UInt64(v) => v.encode(stream, ctx), + Variant::Float(v) => v.encode(stream, ctx), + Variant::Double(v) => v.encode(stream, ctx), + Variant::String(v) => v.encode(stream, ctx), + Variant::DateTime(v) => v.encode(stream, ctx), + Variant::Guid(v) => v.encode(stream, ctx), + Variant::StatusCode(v) => v.encode(stream, ctx), + Variant::ByteString(v) => v.encode(stream, ctx), + Variant::XmlElement(v) => v.encode(stream, ctx), + Variant::QualifiedName(v) => v.encode(stream, ctx), + Variant::LocalizedText(v) => v.encode(stream, ctx), + Variant::NodeId(v) => v.encode(stream, ctx), + Variant::ExpandedNodeId(v) => v.encode(stream, ctx), + Variant::Variant(v) => v.encode(stream, ctx), + Variant::DataValue(v) => v.encode(stream, ctx), + Variant::DiagnosticInfo(v) => v.encode(stream, ctx), + }?; + stream.write_end(&field.name)?; + Ok(()) + } +} + +impl DynamicTypeLoader { + fn xml_decode_field_value( + &self, + field: &ParsedStructureField, + stream: &mut crate::xml::XmlStreamReader<&mut dyn std::io::Read>, + ctx: &Context<'_>, + ) -> EncodingResult { + match field.scalar_type { + VariantScalarTypeId::Boolean => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::SByte => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::Byte => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::Int16 => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::UInt16 => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::Int32 => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::UInt32 => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::Int64 => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::UInt64 => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::Float => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::Double => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::String => Ok(Variant::from(::decode( + stream, ctx, + )?)), + VariantScalarTypeId::DateTime => Ok(Variant::from(::decode( + stream, ctx, + )?)), + VariantScalarTypeId::Guid => { + Ok(Variant::from(::decode(stream, ctx)?)) + } + VariantScalarTypeId::ByteString => Ok(Variant::from( + ::decode(stream, ctx)?, + )), + VariantScalarTypeId::XmlElement => Ok(Variant::from( + ::decode(stream, ctx)?, + )), + VariantScalarTypeId::NodeId => Ok(Variant::from(::decode( + stream, ctx, + )?)), + VariantScalarTypeId::ExpandedNodeId => Ok(Variant::from( + ::decode(stream, ctx)?, + )), + VariantScalarTypeId::StatusCode => Ok(Variant::from( + ::decode(stream, ctx)?, + )), + VariantScalarTypeId::QualifiedName => Ok(Variant::from( + ::decode(stream, ctx)?, + )), + VariantScalarTypeId::LocalizedText => Ok(Variant::from( + ::decode(stream, ctx)?, + )), + VariantScalarTypeId::ExtensionObject => { + let Some(field_ty) = self.type_tree.get_struct_type(&field.type_id) else { + return Err(Error::decoding(format!( + "Dynamic type field missing from type tree: {}", + field.type_id + ))); + }; + + if field_ty.is_abstract { + Ok(Variant::from(::decode( + stream, ctx, + )?)) + } else { + Ok(Variant::from(ctx.load_from_xml(&field_ty.node_id, stream)?)) + } + } + VariantScalarTypeId::DataValue => Ok(Variant::from( + ::decode(stream, ctx)?, + )), + VariantScalarTypeId::Variant => Ok(Variant::Variant(Box::new( + ::decode(stream, ctx)?, + ))), + VariantScalarTypeId::DiagnosticInfo => Ok(Variant::from( + ::decode(stream, ctx)?, + )), + } + } + + fn xml_decode_field( + &self, + field: &ParsedStructureField, + stream: &mut crate::xml::XmlStreamReader<&mut dyn std::io::Read>, + ctx: &Context<'_>, + ) -> EncodingResult { + if field.value_rank > 1 { + let mut values = Vec::new(); + let mut dims = Vec::new(); + stream.iter_children( + |key, stream, ctx| { + match key.as_str() { + "Dimensions" => { + dims = Vec::::decode(stream, ctx)?; + } + "Elements" => stream.iter_children_include_empty( + |_, stream, ctx| { + let Some(stream) = stream else { + values.push(Variant::get_variant_default(field.scalar_type)); + return Ok(()); + }; + let r = self.xml_decode_field_value(field, stream, ctx)?; + values.push(r); + Ok(()) + }, + ctx, + )?, + r => { + return Err(Error::decoding(format!( + "Invalid field in Matrix content: {r}" + ))) + } + } + Ok(()) + }, + ctx, + )?; + Ok(Variant::Array(Box::new( + Array::new_multi( + field.scalar_type, + values, + dims.into_iter() + .map(|d| d.try_into()) + .collect::, _>>() + .map_err(|_| { + Error::decoding("Invalid array dimensions, must all be non-negative") + })?, + ) + .map_err(Error::decoding)?, + ))) + } else if field.value_rank > 0 { + let mut values = Vec::new(); + stream.iter_children_include_empty( + |_, stream, ctx| { + let Some(stream) = stream else { + values.push(Variant::get_variant_default(field.scalar_type)); + return Ok(()); + }; + let r = self.xml_decode_field_value(field, stream, ctx)?; + values.push(r); + Ok(()) + }, + ctx, + )?; + Ok(Variant::Array(Box::new( + Array::new(field.scalar_type, values).map_err(Error::decoding)?, + ))) + } else { + self.xml_decode_field_value(field, stream, ctx) + } + } + + pub(super) fn xml_decode_type_inner( + &self, + stream: &mut crate::xml::XmlStreamReader<&mut dyn std::io::Read>, + ctx: &Context<'_>, + t: &Arc, + ) -> EncodingResult> { + match t.structure_type { + StructureType::Structure | StructureType::StructureWithOptionalFields => { + let mut by_name = HashMap::new(); + stream.iter_children( + |key, stream, ctx| { + let Some(field) = t.get_field_by_name(&key) else { + stream.skip_value()?; + return Ok(()); + }; + by_name.insert( + field.name.as_str(), + self.xml_decode_field(field, stream, ctx)?, + ); + Ok(()) + }, + ctx, + )?; + + let mut data = Vec::with_capacity(by_name.len()); + for field in &t.fields { + let Some(f) = by_name.remove(field.name.as_str()) else { + if field.is_optional { + data.push(Variant::Empty); + continue; + } + return Err(Error::decoding(format!( + "Missing required field {}", + field.name + ))); + }; + data.push(f); + } + + Ok(Box::new(DynamicStructure { + type_def: t.clone(), + discriminant: 0, + type_tree: self.type_tree.clone(), + data, + })) + } + StructureType::Union => { + let mut value: Option = None; + let mut discriminant: Option = None; + + stream.iter_children( + |key, stream, ctx| { + match key.as_str() { + "SwitchField" => { + discriminant = Some(u32::decode(stream, ctx)?); + } + r => { + let Some((idx, value_field)) = + t.fields.iter().enumerate().find(|(_, f)| f.name == r) + else { + stream.skip_value()?; + return Ok(()); + }; + + // If we've read the discriminant, double check that it matches the field name. + // OPC-UA unions are really only allowed to have two fields, but we can try to handle + // weird payloads anyway. + // Technically doesn't handle cases where there are multiple options _and_ the discriminant + // is late, but that violates the standard so it's probably fine. + if discriminant.is_some_and(|d| d != (idx + 1) as u32) { + stream.skip_value()?; + } else { + value = + Some(self.xml_decode_field(value_field, stream, ctx)?); + discriminant = Some((idx + 1) as u32); + } + } + } + Ok(()) + }, + ctx, + )?; + + let Some(value) = value else { + return Err(Error::decoding("Missing union value")); + }; + + let Some(discriminant) = discriminant else { + return Err(Error::decoding("Missing discriminant")); + }; + + if discriminant == 0 { + return Err(Error::decoding("Discriminant must be non-zero")); + } + + Ok(Box::new(DynamicStructure { + type_def: t.clone(), + discriminant: discriminant - 1, + type_tree: self.type_tree.clone(), + data: vec![value], + })) + } + StructureType::StructureWithSubtypedValues => { + todo!("StructureWithSubtypedValues is unsupported") + } + StructureType::UnionWithSubtypedValues => { + todo!("UnionWithSubtypedValues is unsupported") + } + } + } +} + +impl XmlEncodable for DynamicStructure { + fn encode( + &self, + stream: &mut XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &Context<'_>, + ) -> EncodingResult<()> { + let s = &self.type_def; + match s.structure_type { + StructureType::Structure => { + for (value, field) in self.data.iter().zip(s.fields.iter()) { + self.xml_encode_field(stream, value, field, ctx)?; + } + } + StructureType::StructureWithOptionalFields => { + let mut encoding_mask = 0u32; + let mut optional_idx = 0; + for (value, field) in self.data.iter().zip(s.fields.iter()) { + if field.is_optional { + if !matches!(value, Variant::Empty) { + encoding_mask |= 1 << optional_idx; + } + optional_idx += 1; + } + } + stream.encode_child("EncodingMask", &encoding_mask, ctx)?; + for (value, field) in self.data.iter().zip(s.fields.iter()) { + if !field.is_optional || !matches!(value, Variant::Empty) { + self.xml_encode_field(stream, value, field, ctx)?; + } + } + } + StructureType::Union => { + stream.encode_child("SwitchField", &self.discriminant, ctx)?; + let (Some(value), Some(field)) = + (self.data.first(), s.fields.get(self.discriminant as usize)) + else { + return Err(Error::encoding( + "Discriminant was out of range of known fields", + )); + }; + self.xml_encode_field(stream, value, field, ctx)?; + } + StructureType::StructureWithSubtypedValues => { + todo!("StructureWithSubtypedValues is unsupported") + } + StructureType::UnionWithSubtypedValues => { + todo!("UnionWithSubtypedValues is unsupported") + } + } + + Ok(()) + } +} diff --git a/async-opcua-types/src/data_value.rs b/async-opcua-types/src/data_value.rs index ab326635..20eadf9b 100644 --- a/async-opcua-types/src/data_value.rs +++ b/async-opcua-types/src/data_value.rs @@ -66,6 +66,87 @@ pub struct DataValue { pub server_picoseconds: Option, } +// For some spectacularly dumb reason Status is different in JSON and XML. +// It is named "StatusCode" in XML (5.3.1.18) and "Status" in JSON (5.4.2.18), the _only_ place +// where this is the case on a struct. So we have to implement XML manually. +#[cfg(feature = "xml")] +mod xml { + use super::DataValue; + + impl crate::xml::XmlEncodable for DataValue { + fn encode( + &self, + stream: &mut crate::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &crate::Context<'_>, + ) -> crate::EncodingResult<()> { + use crate::xml::XmlWriteExt; + stream.encode_child("Value", &self.value, ctx)?; + stream.encode_child("StatusCode", &self.status, ctx)?; + stream.encode_child("SourceTimestamp", &self.source_timestamp, ctx)?; + stream.encode_child("SourcePicoseconds", &self.source_picoseconds, ctx)?; + stream.encode_child("ServerTimestamp", &self.server_timestamp, ctx)?; + stream.encode_child("ServerPicoseconds", &self.server_picoseconds, ctx)?; + Ok(()) + } + } + impl crate::xml::XmlDecodable for DataValue { + fn decode( + stream: &mut crate::xml::XmlStreamReader<&mut dyn std::io::Read>, + ctx: &crate::Context<'_>, + ) -> crate::EncodingResult { + use crate::xml::XmlReadExt; + let mut value = None; + let mut status = None; + let mut source_timestamp = None; + let mut source_picoseconds = None; + let mut server_timestamp = None; + let mut server_picoseconds = None; + stream.iter_children( + |__key, stream, ctx| { + match __key.as_str() { + "Value" => { + value = Some(crate::xml::XmlDecodable::decode(stream, ctx)?); + } + "StatusCode" => { + status = Some(crate::xml::XmlDecodable::decode(stream, ctx)?); + } + "SourceTimestamp" => { + source_timestamp = Some(crate::xml::XmlDecodable::decode(stream, ctx)?); + } + "SourcePicoseconds" => { + source_picoseconds = + Some(crate::xml::XmlDecodable::decode(stream, ctx)?); + } + "ServerTimestamp" => { + server_timestamp = Some(crate::xml::XmlDecodable::decode(stream, ctx)?); + } + "ServerPicoseconds" => { + server_picoseconds = + Some(crate::xml::XmlDecodable::decode(stream, ctx)?); + } + _ => { + stream.skip_value()?; + } + } + Ok(()) + }, + ctx, + )?; + Ok(Self { + value: value.unwrap_or_default(), + status: status.unwrap_or_default(), + source_timestamp: source_timestamp.unwrap_or_default(), + source_picoseconds: source_picoseconds.unwrap_or_default(), + server_timestamp: server_timestamp.unwrap_or_default(), + server_picoseconds: server_picoseconds.unwrap_or_default(), + }) + } + } + impl crate::xml::XmlType for DataValue { + const TAG: &'static str = "DataValue"; + } +} + impl BinaryEncodable for DataValue { fn byte_len(&self, ctx: &opcua::types::Context<'_>) -> usize { let mut size = 1; diff --git a/async-opcua-types/src/date_time.rs b/async-opcua-types/src/date_time.rs index f8c5007d..303b34bc 100644 --- a/async-opcua-types/src/date_time.rs +++ b/async-opcua-types/src/date_time.rs @@ -57,7 +57,7 @@ mod json { ) -> super::EncodingResult { let v = stream.next_str()?; let dt = DateTime::parse_from_rfc3339(v) - .map_err(|e| Error::decoding(format!("Cannot parse date time: {e}")))?; + .map_err(|e| Error::decoding(format!("Cannot parse date time \"{v}\": {e}")))?; Ok(dt) } } @@ -70,6 +70,10 @@ mod xml { use super::DateTime; + impl XmlType for DateTime { + const TAG: &'static str = "DateTime"; + } + impl XmlEncodable for DateTime { fn encode( &self, @@ -87,7 +91,7 @@ mod xml { ) -> Result { let v = read.consume_as_text()?; let dt = DateTime::parse_from_rfc3339(&v) - .map_err(|e| Error::decoding(format!("Cannot parse date time: {e}")))?; + .map_err(|e| Error::decoding(format!("Cannot parse date time \"{v}\": {e}")))?; Ok(dt) } } diff --git a/async-opcua-types/src/diagnostic_info.rs b/async-opcua-types/src/diagnostic_info.rs index b0835b9f..4f044420 100644 --- a/async-opcua-types/src/diagnostic_info.rs +++ b/async-opcua-types/src/diagnostic_info.rs @@ -62,14 +62,6 @@ bitflags! { } } -#[cfg(feature = "xml")] -impl crate::xml::FromXml for DiagnosticBits { - fn from_xml(element: &opcua_xml::XmlElement, ctx: &Context<'_>) -> EncodingResult { - let v = u32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(v)) - } -} - #[cfg(feature = "json")] mod json { use crate::json::*; @@ -104,6 +96,10 @@ mod xml { use super::DiagnosticBits; + impl XmlType for DiagnosticBits { + const TAG: &'static str = u32::TAG; + } + impl XmlEncodable for DiagnosticBits { fn encode( &self, @@ -136,7 +132,10 @@ mod opcua { feature = "json", derive(opcua_macros::JsonEncodable, opcua_macros::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(crate::FromXml))] +#[cfg_attr( + feature = "xml", + derive(crate::XmlEncodable, crate::XmlDecodable, crate::XmlType) +)] pub struct DiagnosticInfo { /// A symbolic name for the status code. pub symbolic_id: Option, diff --git a/async-opcua-types/src/expanded_node_id.rs b/async-opcua-types/src/expanded_node_id.rs index e724a6f8..45f4f267 100644 --- a/async-opcua-types/src/expanded_node_id.rs +++ b/async-opcua-types/src/expanded_node_id.rs @@ -246,6 +246,10 @@ mod xml { use super::ExpandedNodeId; + impl XmlType for ExpandedNodeId { + const TAG: &'static str = "ExpandedNodeId"; + } + impl XmlEncodable for ExpandedNodeId { fn encode( &self, diff --git a/async-opcua-types/src/extension_object.rs b/async-opcua-types/src/extension_object.rs index ee694179..40995856 100644 --- a/async-opcua-types/src/extension_object.rs +++ b/async-opcua-types/src/extension_object.rs @@ -55,6 +55,18 @@ pub trait DynEncodable: Any + Send + Sync + std::fmt::Debug { ctx: &crate::Context<'_>, ) -> EncodingResult<()>; + #[cfg(feature = "xml")] + /// Encode the struct using OPC-UA XML encoding. + fn encode_xml( + &self, + stream: &mut crate::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &crate::Context<'_>, + ) -> EncodingResult<()>; + + #[cfg(feature = "xml")] + /// The XML tag name for this struct. + fn xml_tag_name(&self) -> &str; + /// Get the binary byte length of this struct. fn byte_len_dyn(&self, ctx: &crate::Context<'_>) -> usize; @@ -109,6 +121,20 @@ macro_rules! blanket_dyn_encodable { JsonEncodable::encode(self, stream, ctx) } + #[cfg(feature = "xml")] + fn encode_xml( + &self, + stream: &mut crate::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &crate::Context<'_>, + ) -> EncodingResult<()> { + XmlEncodable::encode(self, stream, ctx) + } + + #[cfg(feature = "xml")] + fn xml_tag_name(&self,) -> &str { + self.tag() + } + fn byte_len_dyn(&self, ctx: &crate::Context<'_>,) -> usize { BinaryEncodable::byte_len(self, ctx) } @@ -161,11 +187,36 @@ macro_rules! blanket_dyn_encodable { #[cfg(feature = "json")] use crate::json::JsonEncodable; -#[cfg(feature = "json")] -blanket_dyn_encodable!(BinaryEncodable + JsonEncodable); +#[cfg(feature = "xml")] +use crate::xml::XmlEncodable; + +#[cfg(feature = "xml")] +macro_rules! blanket_call_2 { + ($($res:tt)*) => { + blanket_dyn_encodable!($($res)* + XmlEncodable); + } +} +#[cfg(not(feature = "xml"))] +macro_rules! blanket_call_2 { + ($($res:tt)*) => { + blanket_dyn_encodable!($($res)*); + } +} +#[cfg(feature = "json")] +macro_rules! blanket_call_1 { + ($($res:tt)*) => { + blanket_call_2!($($res)* + JsonEncodable); + } +} #[cfg(not(feature = "json"))] -blanket_dyn_encodable!(BinaryEncodable); +macro_rules! blanket_call_1 { + ($($res:tt)*) => { + blanket_call_2!($($res)*); + } +} + +blanket_call_1!(BinaryEncodable); impl PartialEq for dyn DynEncodable { fn eq(&self, other: &dyn DynEncodable) -> bool { @@ -308,6 +359,10 @@ mod xml { use super::ExtensionObject; + impl XmlType for ExtensionObject { + const TAG: &'static str = "ExtensionObject"; + } + impl XmlEncodable for ExtensionObject { fn encode( &self, @@ -324,7 +379,11 @@ mod xml { })?; writer.encode_child("TypeId", id.as_ref(), ctx)?; - // TODO: Encode body + writer.write_start("Body")?; + writer.write_start(body.xml_tag_name())?; + body.encode_xml(writer, ctx)?; + writer.write_end(body.xml_tag_name())?; + writer.write_end("Body")?; Ok(()) } @@ -365,12 +424,12 @@ mod xml { } } else { // Decode from XML. - todo!(); + body = Some(ctx.load_from_xml(&type_id, reader)?); } // Read to the end of the body. reader.skip_value()?; } - _ => (), + _ => reader.skip_value()?, }; Ok(()) }, diff --git a/async-opcua-types/src/generated/types/activate_session_request.rs b/async-opcua-types/src/generated/types/activate_session_request.rs index 71dc608b..5f5e7daf 100644 --- a/async-opcua-types/src/generated/types/activate_session_request.rs +++ b/async-opcua-types/src/generated/types/activate_session_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ActivateSessionRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/activate_session_response.rs b/async-opcua-types/src/generated/types/activate_session_response.rs index e84045aa..2b97cd4e 100644 --- a/async-opcua-types/src/generated/types/activate_session_response.rs +++ b/async-opcua-types/src/generated/types/activate_session_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ActivateSessionResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/add_nodes_item.rs b/async-opcua-types/src/generated/types/add_nodes_item.rs index b6bdab4b..181fc396 100644 --- a/async-opcua-types/src/generated/types/add_nodes_item.rs +++ b/async-opcua-types/src/generated/types/add_nodes_item.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AddNodesItem { pub parent_node_id: opcua::types::expanded_node_id::ExpandedNodeId, diff --git a/async-opcua-types/src/generated/types/add_nodes_request.rs b/async-opcua-types/src/generated/types/add_nodes_request.rs index f7d651ed..304d3200 100644 --- a/async-opcua-types/src/generated/types/add_nodes_request.rs +++ b/async-opcua-types/src/generated/types/add_nodes_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AddNodesRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/add_nodes_response.rs b/async-opcua-types/src/generated/types/add_nodes_response.rs index b9570cd2..f979b39b 100644 --- a/async-opcua-types/src/generated/types/add_nodes_response.rs +++ b/async-opcua-types/src/generated/types/add_nodes_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AddNodesResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/add_nodes_result.rs b/async-opcua-types/src/generated/types/add_nodes_result.rs index 4588e53f..73099a3a 100644 --- a/async-opcua-types/src/generated/types/add_nodes_result.rs +++ b/async-opcua-types/src/generated/types/add_nodes_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AddNodesResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/add_references_item.rs b/async-opcua-types/src/generated/types/add_references_item.rs index 468b6280..b298ddf4 100644 --- a/async-opcua-types/src/generated/types/add_references_item.rs +++ b/async-opcua-types/src/generated/types/add_references_item.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AddReferencesItem { pub source_node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/add_references_request.rs b/async-opcua-types/src/generated/types/add_references_request.rs index e4680d9c..61b4de76 100644 --- a/async-opcua-types/src/generated/types/add_references_request.rs +++ b/async-opcua-types/src/generated/types/add_references_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AddReferencesRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/add_references_response.rs b/async-opcua-types/src/generated/types/add_references_response.rs index b8aaf822..bd420ac3 100644 --- a/async-opcua-types/src/generated/types/add_references_response.rs +++ b/async-opcua-types/src/generated/types/add_references_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AddReferencesResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/additional_parameters_type.rs b/async-opcua-types/src/generated/types/additional_parameters_type.rs index 8af49f67..f36a0a45 100644 --- a/async-opcua-types/src/generated/types/additional_parameters_type.rs +++ b/async-opcua-types/src/generated/types/additional_parameters_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AdditionalParametersType { pub parameters: Option>, diff --git a/async-opcua-types/src/generated/types/aggregate_configuration.rs b/async-opcua-types/src/generated/types/aggregate_configuration.rs index 64e3f62e..8e40e739 100644 --- a/async-opcua-types/src/generated/types/aggregate_configuration.rs +++ b/async-opcua-types/src/generated/types/aggregate_configuration.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AggregateConfiguration { pub use_server_capabilities_defaults: bool, diff --git a/async-opcua-types/src/generated/types/aggregate_filter.rs b/async-opcua-types/src/generated/types/aggregate_filter.rs index c3055b7b..47c9f587 100644 --- a/async-opcua-types/src/generated/types/aggregate_filter.rs +++ b/async-opcua-types/src/generated/types/aggregate_filter.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AggregateFilter { pub start_time: opcua::types::date_time::DateTime, diff --git a/async-opcua-types/src/generated/types/aggregate_filter_result.rs b/async-opcua-types/src/generated/types/aggregate_filter_result.rs index 4c84dbed..d1aeab10 100644 --- a/async-opcua-types/src/generated/types/aggregate_filter_result.rs +++ b/async-opcua-types/src/generated/types/aggregate_filter_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AggregateFilterResult { pub revised_start_time: opcua::types::date_time::DateTime, diff --git a/async-opcua-types/src/generated/types/alias_name_data_type.rs b/async-opcua-types/src/generated/types/alias_name_data_type.rs index b5996307..abefbaef 100644 --- a/async-opcua-types/src/generated/types/alias_name_data_type.rs +++ b/async-opcua-types/src/generated/types/alias_name_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AliasNameDataType { pub alias_name: opcua::types::qualified_name::QualifiedName, diff --git a/async-opcua-types/src/generated/types/annotation.rs b/async-opcua-types/src/generated/types/annotation.rs index a3cecd49..23ed9eca 100644 --- a/async-opcua-types/src/generated/types/annotation.rs +++ b/async-opcua-types/src/generated/types/annotation.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct Annotation { pub message: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/annotation_data_type.rs b/async-opcua-types/src/generated/types/annotation_data_type.rs index bfc2f7b2..626650fc 100644 --- a/async-opcua-types/src/generated/types/annotation_data_type.rs +++ b/async-opcua-types/src/generated/types/annotation_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AnnotationDataType { pub annotation: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/anonymous_identity_token.rs b/async-opcua-types/src/generated/types/anonymous_identity_token.rs index 8acf5245..51c800e8 100644 --- a/async-opcua-types/src/generated/types/anonymous_identity_token.rs +++ b/async-opcua-types/src/generated/types/anonymous_identity_token.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] pub struct AnonymousIdentityToken { pub policy_id: opcua::types::string::UAString, } diff --git a/async-opcua-types/src/generated/types/application_description.rs b/async-opcua-types/src/generated/types/application_description.rs index cfedfa54..91af90fc 100644 --- a/async-opcua-types/src/generated/types/application_description.rs +++ b/async-opcua-types/src/generated/types/application_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ApplicationDescription { pub application_uri: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/attribute_operand.rs b/async-opcua-types/src/generated/types/attribute_operand.rs index 52c25bd9..499494a5 100644 --- a/async-opcua-types/src/generated/types/attribute_operand.rs +++ b/async-opcua-types/src/generated/types/attribute_operand.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AttributeOperand { pub node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/axis_information.rs b/async-opcua-types/src/generated/types/axis_information.rs index 41f1d279..a0817faf 100644 --- a/async-opcua-types/src/generated/types/axis_information.rs +++ b/async-opcua-types/src/generated/types/axis_information.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct AxisInformation { pub engineering_units: super::eu_information::EUInformation, diff --git a/async-opcua-types/src/generated/types/bit_field_definition.rs b/async-opcua-types/src/generated/types/bit_field_definition.rs index a6b14e06..c7f96439 100644 --- a/async-opcua-types/src/generated/types/bit_field_definition.rs +++ b/async-opcua-types/src/generated/types/bit_field_definition.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BitFieldDefinition { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/broker_connection_transport_data_type.rs b/async-opcua-types/src/generated/types/broker_connection_transport_data_type.rs index ecc4c2ee..984b460f 100644 --- a/async-opcua-types/src/generated/types/broker_connection_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/broker_connection_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrokerConnectionTransportDataType { pub resource_uri: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/broker_data_set_reader_transport_data_type.rs b/async-opcua-types/src/generated/types/broker_data_set_reader_transport_data_type.rs index 6ddfb049..f5f6a719 100644 --- a/async-opcua-types/src/generated/types/broker_data_set_reader_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/broker_data_set_reader_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrokerDataSetReaderTransportDataType { pub queue_name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/broker_data_set_writer_transport_data_type.rs b/async-opcua-types/src/generated/types/broker_data_set_writer_transport_data_type.rs index 9b3a4aa2..d5a672f0 100644 --- a/async-opcua-types/src/generated/types/broker_data_set_writer_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/broker_data_set_writer_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrokerDataSetWriterTransportDataType { pub queue_name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/broker_writer_group_transport_data_type.rs b/async-opcua-types/src/generated/types/broker_writer_group_transport_data_type.rs index 07c85a4f..063337bf 100644 --- a/async-opcua-types/src/generated/types/broker_writer_group_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/broker_writer_group_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrokerWriterGroupTransportDataType { pub queue_name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/browse_description.rs b/async-opcua-types/src/generated/types/browse_description.rs index 6a3112d5..42722e44 100644 --- a/async-opcua-types/src/generated/types/browse_description.rs +++ b/async-opcua-types/src/generated/types/browse_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrowseDescription { pub node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/browse_next_request.rs b/async-opcua-types/src/generated/types/browse_next_request.rs index cf243af1..1885bc1e 100644 --- a/async-opcua-types/src/generated/types/browse_next_request.rs +++ b/async-opcua-types/src/generated/types/browse_next_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrowseNextRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/browse_next_response.rs b/async-opcua-types/src/generated/types/browse_next_response.rs index 6fbc13a1..d267c575 100644 --- a/async-opcua-types/src/generated/types/browse_next_response.rs +++ b/async-opcua-types/src/generated/types/browse_next_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrowseNextResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/browse_path.rs b/async-opcua-types/src/generated/types/browse_path.rs index 5a9e5c47..67e26cc6 100644 --- a/async-opcua-types/src/generated/types/browse_path.rs +++ b/async-opcua-types/src/generated/types/browse_path.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrowsePath { pub starting_node: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/browse_path_result.rs b/async-opcua-types/src/generated/types/browse_path_result.rs index 4a9256aa..021c3c23 100644 --- a/async-opcua-types/src/generated/types/browse_path_result.rs +++ b/async-opcua-types/src/generated/types/browse_path_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrowsePathResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/browse_path_target.rs b/async-opcua-types/src/generated/types/browse_path_target.rs index 5c0f1322..68951c3c 100644 --- a/async-opcua-types/src/generated/types/browse_path_target.rs +++ b/async-opcua-types/src/generated/types/browse_path_target.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrowsePathTarget { pub target_id: opcua::types::expanded_node_id::ExpandedNodeId, diff --git a/async-opcua-types/src/generated/types/browse_request.rs b/async-opcua-types/src/generated/types/browse_request.rs index e643caab..9e9f4de6 100644 --- a/async-opcua-types/src/generated/types/browse_request.rs +++ b/async-opcua-types/src/generated/types/browse_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrowseRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/browse_response.rs b/async-opcua-types/src/generated/types/browse_response.rs index 61f44067..6fb70788 100644 --- a/async-opcua-types/src/generated/types/browse_response.rs +++ b/async-opcua-types/src/generated/types/browse_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrowseResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/browse_result.rs b/async-opcua-types/src/generated/types/browse_result.rs index a8500389..dce28152 100644 --- a/async-opcua-types/src/generated/types/browse_result.rs +++ b/async-opcua-types/src/generated/types/browse_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BrowseResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/build_info.rs b/async-opcua-types/src/generated/types/build_info.rs index 92ab3a80..a9df8a8c 100644 --- a/async-opcua-types/src/generated/types/build_info.rs +++ b/async-opcua-types/src/generated/types/build_info.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct BuildInfo { pub product_uri: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/call_method_request.rs b/async-opcua-types/src/generated/types/call_method_request.rs index de05948d..bece86cd 100644 --- a/async-opcua-types/src/generated/types/call_method_request.rs +++ b/async-opcua-types/src/generated/types/call_method_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CallMethodRequest { pub object_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/call_method_result.rs b/async-opcua-types/src/generated/types/call_method_result.rs index 8ccd9de1..4b3ea18d 100644 --- a/async-opcua-types/src/generated/types/call_method_result.rs +++ b/async-opcua-types/src/generated/types/call_method_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CallMethodResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/call_request.rs b/async-opcua-types/src/generated/types/call_request.rs index ab96dc6f..206f4d85 100644 --- a/async-opcua-types/src/generated/types/call_request.rs +++ b/async-opcua-types/src/generated/types/call_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CallRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/call_response.rs b/async-opcua-types/src/generated/types/call_response.rs index 0b794690..98fc6739 100644 --- a/async-opcua-types/src/generated/types/call_response.rs +++ b/async-opcua-types/src/generated/types/call_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CallResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/cancel_request.rs b/async-opcua-types/src/generated/types/cancel_request.rs index d1d6c96b..1cb51607 100644 --- a/async-opcua-types/src/generated/types/cancel_request.rs +++ b/async-opcua-types/src/generated/types/cancel_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CancelRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/cancel_response.rs b/async-opcua-types/src/generated/types/cancel_response.rs index 99328d37..edf62603 100644 --- a/async-opcua-types/src/generated/types/cancel_response.rs +++ b/async-opcua-types/src/generated/types/cancel_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CancelResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/cartesian_coordinates.rs b/async-opcua-types/src/generated/types/cartesian_coordinates.rs index 0e37628e..a8465b4b 100644 --- a/async-opcua-types/src/generated/types/cartesian_coordinates.rs +++ b/async-opcua-types/src/generated/types/cartesian_coordinates.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CartesianCoordinates {} impl opcua::types::MessageInfo for CartesianCoordinates { diff --git a/async-opcua-types/src/generated/types/channel_security_token.rs b/async-opcua-types/src/generated/types/channel_security_token.rs index 2121d74f..b3d1324a 100644 --- a/async-opcua-types/src/generated/types/channel_security_token.rs +++ b/async-opcua-types/src/generated/types/channel_security_token.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ChannelSecurityToken { pub channel_id: u32, diff --git a/async-opcua-types/src/generated/types/close_secure_channel_request.rs b/async-opcua-types/src/generated/types/close_secure_channel_request.rs index e2860012..b87f4646 100644 --- a/async-opcua-types/src/generated/types/close_secure_channel_request.rs +++ b/async-opcua-types/src/generated/types/close_secure_channel_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CloseSecureChannelRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/close_secure_channel_response.rs b/async-opcua-types/src/generated/types/close_secure_channel_response.rs index 548088d3..b8b4e5ee 100644 --- a/async-opcua-types/src/generated/types/close_secure_channel_response.rs +++ b/async-opcua-types/src/generated/types/close_secure_channel_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CloseSecureChannelResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/close_session_request.rs b/async-opcua-types/src/generated/types/close_session_request.rs index a50cc317..78c9448d 100644 --- a/async-opcua-types/src/generated/types/close_session_request.rs +++ b/async-opcua-types/src/generated/types/close_session_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CloseSessionRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/close_session_response.rs b/async-opcua-types/src/generated/types/close_session_response.rs index a3cb4be0..65942f95 100644 --- a/async-opcua-types/src/generated/types/close_session_response.rs +++ b/async-opcua-types/src/generated/types/close_session_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CloseSessionResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/complex_number_type.rs b/async-opcua-types/src/generated/types/complex_number_type.rs index 04d9bbca..2ed4402f 100644 --- a/async-opcua-types/src/generated/types/complex_number_type.rs +++ b/async-opcua-types/src/generated/types/complex_number_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ComplexNumberType { pub real: f32, diff --git a/async-opcua-types/src/generated/types/configuration_version_data_type.rs b/async-opcua-types/src/generated/types/configuration_version_data_type.rs index 5c6a26bb..9ec23b96 100644 --- a/async-opcua-types/src/generated/types/configuration_version_data_type.rs +++ b/async-opcua-types/src/generated/types/configuration_version_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ConfigurationVersionDataType { pub major_version: u32, diff --git a/async-opcua-types/src/generated/types/connection_transport_data_type.rs b/async-opcua-types/src/generated/types/connection_transport_data_type.rs index b68bf5fd..71a4cec1 100644 --- a/async-opcua-types/src/generated/types/connection_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/connection_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ConnectionTransportDataType {} impl opcua::types::MessageInfo for ConnectionTransportDataType { diff --git a/async-opcua-types/src/generated/types/content_filter.rs b/async-opcua-types/src/generated/types/content_filter.rs index 66a3d91a..738b6250 100644 --- a/async-opcua-types/src/generated/types/content_filter.rs +++ b/async-opcua-types/src/generated/types/content_filter.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ContentFilter { pub elements: Option>, diff --git a/async-opcua-types/src/generated/types/content_filter_element.rs b/async-opcua-types/src/generated/types/content_filter_element.rs index b0e74337..01956818 100644 --- a/async-opcua-types/src/generated/types/content_filter_element.rs +++ b/async-opcua-types/src/generated/types/content_filter_element.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ContentFilterElement { pub filter_operator: super::enums::FilterOperator, diff --git a/async-opcua-types/src/generated/types/content_filter_element_result.rs b/async-opcua-types/src/generated/types/content_filter_element_result.rs index d6d18ce8..9a1268b5 100644 --- a/async-opcua-types/src/generated/types/content_filter_element_result.rs +++ b/async-opcua-types/src/generated/types/content_filter_element_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ContentFilterElementResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/content_filter_result.rs b/async-opcua-types/src/generated/types/content_filter_result.rs index 9f587178..549747c5 100644 --- a/async-opcua-types/src/generated/types/content_filter_result.rs +++ b/async-opcua-types/src/generated/types/content_filter_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ContentFilterResult { pub element_results: diff --git a/async-opcua-types/src/generated/types/create_monitored_items_request.rs b/async-opcua-types/src/generated/types/create_monitored_items_request.rs index 483223a5..b973d6f1 100644 --- a/async-opcua-types/src/generated/types/create_monitored_items_request.rs +++ b/async-opcua-types/src/generated/types/create_monitored_items_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CreateMonitoredItemsRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/create_monitored_items_response.rs b/async-opcua-types/src/generated/types/create_monitored_items_response.rs index 4df76a33..4e208954 100644 --- a/async-opcua-types/src/generated/types/create_monitored_items_response.rs +++ b/async-opcua-types/src/generated/types/create_monitored_items_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CreateMonitoredItemsResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/create_session_request.rs b/async-opcua-types/src/generated/types/create_session_request.rs index 527028d7..ea5e2c06 100644 --- a/async-opcua-types/src/generated/types/create_session_request.rs +++ b/async-opcua-types/src/generated/types/create_session_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CreateSessionRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/create_session_response.rs b/async-opcua-types/src/generated/types/create_session_response.rs index 62ba4898..d1864f8c 100644 --- a/async-opcua-types/src/generated/types/create_session_response.rs +++ b/async-opcua-types/src/generated/types/create_session_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CreateSessionResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/create_subscription_request.rs b/async-opcua-types/src/generated/types/create_subscription_request.rs index 09dccca3..602e0130 100644 --- a/async-opcua-types/src/generated/types/create_subscription_request.rs +++ b/async-opcua-types/src/generated/types/create_subscription_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CreateSubscriptionRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/create_subscription_response.rs b/async-opcua-types/src/generated/types/create_subscription_response.rs index 4398b0ae..bafa1e34 100644 --- a/async-opcua-types/src/generated/types/create_subscription_response.rs +++ b/async-opcua-types/src/generated/types/create_subscription_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CreateSubscriptionResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/currency_unit_type.rs b/async-opcua-types/src/generated/types/currency_unit_type.rs index 658340a8..db5a8b6a 100644 --- a/async-opcua-types/src/generated/types/currency_unit_type.rs +++ b/async-opcua-types/src/generated/types/currency_unit_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct CurrencyUnitType { pub numeric_code: i16, diff --git a/async-opcua-types/src/generated/types/data_change_filter.rs b/async-opcua-types/src/generated/types/data_change_filter.rs index 49fcc9c0..39193c5f 100644 --- a/async-opcua-types/src/generated/types/data_change_filter.rs +++ b/async-opcua-types/src/generated/types/data_change_filter.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataChangeFilter { pub trigger: super::enums::DataChangeTrigger, diff --git a/async-opcua-types/src/generated/types/data_change_notification.rs b/async-opcua-types/src/generated/types/data_change_notification.rs index efe879cb..d194d366 100644 --- a/async-opcua-types/src/generated/types/data_change_notification.rs +++ b/async-opcua-types/src/generated/types/data_change_notification.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataChangeNotification { pub monitored_items: Option>, diff --git a/async-opcua-types/src/generated/types/data_set_meta_data_type.rs b/async-opcua-types/src/generated/types/data_set_meta_data_type.rs index 7985737d..ac96decd 100644 --- a/async-opcua-types/src/generated/types/data_set_meta_data_type.rs +++ b/async-opcua-types/src/generated/types/data_set_meta_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataSetMetaDataType { pub namespaces: Option>, diff --git a/async-opcua-types/src/generated/types/data_set_reader_data_type.rs b/async-opcua-types/src/generated/types/data_set_reader_data_type.rs index f0e3a698..14cfc210 100644 --- a/async-opcua-types/src/generated/types/data_set_reader_data_type.rs +++ b/async-opcua-types/src/generated/types/data_set_reader_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataSetReaderDataType { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/data_set_reader_message_data_type.rs b/async-opcua-types/src/generated/types/data_set_reader_message_data_type.rs index c53f30fa..ae397199 100644 --- a/async-opcua-types/src/generated/types/data_set_reader_message_data_type.rs +++ b/async-opcua-types/src/generated/types/data_set_reader_message_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataSetReaderMessageDataType {} impl opcua::types::MessageInfo for DataSetReaderMessageDataType { diff --git a/async-opcua-types/src/generated/types/data_set_reader_transport_data_type.rs b/async-opcua-types/src/generated/types/data_set_reader_transport_data_type.rs index 0c0f893d..3ec9379a 100644 --- a/async-opcua-types/src/generated/types/data_set_reader_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/data_set_reader_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataSetReaderTransportDataType {} impl opcua::types::MessageInfo for DataSetReaderTransportDataType { diff --git a/async-opcua-types/src/generated/types/data_set_writer_data_type.rs b/async-opcua-types/src/generated/types/data_set_writer_data_type.rs index 842421d7..b558737d 100644 --- a/async-opcua-types/src/generated/types/data_set_writer_data_type.rs +++ b/async-opcua-types/src/generated/types/data_set_writer_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataSetWriterDataType { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/data_set_writer_message_data_type.rs b/async-opcua-types/src/generated/types/data_set_writer_message_data_type.rs index 1ae8cc75..8b1141c5 100644 --- a/async-opcua-types/src/generated/types/data_set_writer_message_data_type.rs +++ b/async-opcua-types/src/generated/types/data_set_writer_message_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataSetWriterMessageDataType {} impl opcua::types::MessageInfo for DataSetWriterMessageDataType { diff --git a/async-opcua-types/src/generated/types/data_set_writer_transport_data_type.rs b/async-opcua-types/src/generated/types/data_set_writer_transport_data_type.rs index ed5fcade..7addaa97 100644 --- a/async-opcua-types/src/generated/types/data_set_writer_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/data_set_writer_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataSetWriterTransportDataType {} impl opcua::types::MessageInfo for DataSetWriterTransportDataType { diff --git a/async-opcua-types/src/generated/types/data_type_attributes.rs b/async-opcua-types/src/generated/types/data_type_attributes.rs index cd045e6d..9c6f6c89 100644 --- a/async-opcua-types/src/generated/types/data_type_attributes.rs +++ b/async-opcua-types/src/generated/types/data_type_attributes.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataTypeAttributes { pub specified_attributes: u32, diff --git a/async-opcua-types/src/generated/types/data_type_description.rs b/async-opcua-types/src/generated/types/data_type_description.rs index 7ab4049b..df04f5bb 100644 --- a/async-opcua-types/src/generated/types/data_type_description.rs +++ b/async-opcua-types/src/generated/types/data_type_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataTypeDescription { pub data_type_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/data_type_schema_header.rs b/async-opcua-types/src/generated/types/data_type_schema_header.rs index cf91a9d5..d8c960c1 100644 --- a/async-opcua-types/src/generated/types/data_type_schema_header.rs +++ b/async-opcua-types/src/generated/types/data_type_schema_header.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DataTypeSchemaHeader { pub namespaces: Option>, diff --git a/async-opcua-types/src/generated/types/datagram_connection_transport_2_data_type.rs b/async-opcua-types/src/generated/types/datagram_connection_transport_2_data_type.rs index 0d34f05c..b9477056 100644 --- a/async-opcua-types/src/generated/types/datagram_connection_transport_2_data_type.rs +++ b/async-opcua-types/src/generated/types/datagram_connection_transport_2_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DatagramConnectionTransport2DataType { pub discovery_address: opcua::types::extension_object::ExtensionObject, diff --git a/async-opcua-types/src/generated/types/datagram_connection_transport_data_type.rs b/async-opcua-types/src/generated/types/datagram_connection_transport_data_type.rs index 6a368b6c..8facc153 100644 --- a/async-opcua-types/src/generated/types/datagram_connection_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/datagram_connection_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DatagramConnectionTransportDataType { pub discovery_address: opcua::types::extension_object::ExtensionObject, diff --git a/async-opcua-types/src/generated/types/datagram_data_set_reader_transport_data_type.rs b/async-opcua-types/src/generated/types/datagram_data_set_reader_transport_data_type.rs index 56f257e3..76ab5b2e 100644 --- a/async-opcua-types/src/generated/types/datagram_data_set_reader_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/datagram_data_set_reader_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DatagramDataSetReaderTransportDataType { pub address: opcua::types::extension_object::ExtensionObject, diff --git a/async-opcua-types/src/generated/types/datagram_writer_group_transport_2_data_type.rs b/async-opcua-types/src/generated/types/datagram_writer_group_transport_2_data_type.rs index bc9e9a15..3c198be9 100644 --- a/async-opcua-types/src/generated/types/datagram_writer_group_transport_2_data_type.rs +++ b/async-opcua-types/src/generated/types/datagram_writer_group_transport_2_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DatagramWriterGroupTransport2DataType { pub message_repeat_count: u8, diff --git a/async-opcua-types/src/generated/types/datagram_writer_group_transport_data_type.rs b/async-opcua-types/src/generated/types/datagram_writer_group_transport_data_type.rs index d7c089a2..ddbb0267 100644 --- a/async-opcua-types/src/generated/types/datagram_writer_group_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/datagram_writer_group_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DatagramWriterGroupTransportDataType { pub message_repeat_count: u8, diff --git a/async-opcua-types/src/generated/types/delete_at_time_details.rs b/async-opcua-types/src/generated/types/delete_at_time_details.rs index f34ac6b6..4c037d4b 100644 --- a/async-opcua-types/src/generated/types/delete_at_time_details.rs +++ b/async-opcua-types/src/generated/types/delete_at_time_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteAtTimeDetails { pub node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/delete_event_details.rs b/async-opcua-types/src/generated/types/delete_event_details.rs index 38f92806..30a1ae52 100644 --- a/async-opcua-types/src/generated/types/delete_event_details.rs +++ b/async-opcua-types/src/generated/types/delete_event_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteEventDetails { pub node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/delete_monitored_items_request.rs b/async-opcua-types/src/generated/types/delete_monitored_items_request.rs index 9f7e9ee9..da17c023 100644 --- a/async-opcua-types/src/generated/types/delete_monitored_items_request.rs +++ b/async-opcua-types/src/generated/types/delete_monitored_items_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteMonitoredItemsRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/delete_monitored_items_response.rs b/async-opcua-types/src/generated/types/delete_monitored_items_response.rs index 2221c822..f89e8504 100644 --- a/async-opcua-types/src/generated/types/delete_monitored_items_response.rs +++ b/async-opcua-types/src/generated/types/delete_monitored_items_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteMonitoredItemsResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/delete_nodes_item.rs b/async-opcua-types/src/generated/types/delete_nodes_item.rs index 1b001473..0e19ed8f 100644 --- a/async-opcua-types/src/generated/types/delete_nodes_item.rs +++ b/async-opcua-types/src/generated/types/delete_nodes_item.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteNodesItem { pub node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/delete_nodes_request.rs b/async-opcua-types/src/generated/types/delete_nodes_request.rs index a3c42f08..269b674d 100644 --- a/async-opcua-types/src/generated/types/delete_nodes_request.rs +++ b/async-opcua-types/src/generated/types/delete_nodes_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteNodesRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/delete_nodes_response.rs b/async-opcua-types/src/generated/types/delete_nodes_response.rs index c4431981..7f013c7c 100644 --- a/async-opcua-types/src/generated/types/delete_nodes_response.rs +++ b/async-opcua-types/src/generated/types/delete_nodes_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteNodesResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/delete_raw_modified_details.rs b/async-opcua-types/src/generated/types/delete_raw_modified_details.rs index b29e784e..6aa69ce8 100644 --- a/async-opcua-types/src/generated/types/delete_raw_modified_details.rs +++ b/async-opcua-types/src/generated/types/delete_raw_modified_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteRawModifiedDetails { pub node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/delete_references_item.rs b/async-opcua-types/src/generated/types/delete_references_item.rs index 4c1f64ef..5c14058c 100644 --- a/async-opcua-types/src/generated/types/delete_references_item.rs +++ b/async-opcua-types/src/generated/types/delete_references_item.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteReferencesItem { pub source_node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/delete_references_request.rs b/async-opcua-types/src/generated/types/delete_references_request.rs index 7845b9ef..36519d86 100644 --- a/async-opcua-types/src/generated/types/delete_references_request.rs +++ b/async-opcua-types/src/generated/types/delete_references_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteReferencesRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/delete_references_response.rs b/async-opcua-types/src/generated/types/delete_references_response.rs index f061434c..8b3d836f 100644 --- a/async-opcua-types/src/generated/types/delete_references_response.rs +++ b/async-opcua-types/src/generated/types/delete_references_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteReferencesResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/delete_subscriptions_request.rs b/async-opcua-types/src/generated/types/delete_subscriptions_request.rs index 3c20514d..21558a47 100644 --- a/async-opcua-types/src/generated/types/delete_subscriptions_request.rs +++ b/async-opcua-types/src/generated/types/delete_subscriptions_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteSubscriptionsRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/delete_subscriptions_response.rs b/async-opcua-types/src/generated/types/delete_subscriptions_response.rs index a40548a7..62b3762d 100644 --- a/async-opcua-types/src/generated/types/delete_subscriptions_response.rs +++ b/async-opcua-types/src/generated/types/delete_subscriptions_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DeleteSubscriptionsResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/discovery_configuration.rs b/async-opcua-types/src/generated/types/discovery_configuration.rs index bad53402..08997bae 100644 --- a/async-opcua-types/src/generated/types/discovery_configuration.rs +++ b/async-opcua-types/src/generated/types/discovery_configuration.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DiscoveryConfiguration {} impl opcua::types::MessageInfo for DiscoveryConfiguration { diff --git a/async-opcua-types/src/generated/types/double_complex_number_type.rs b/async-opcua-types/src/generated/types/double_complex_number_type.rs index d38a9ba9..877eacb2 100644 --- a/async-opcua-types/src/generated/types/double_complex_number_type.rs +++ b/async-opcua-types/src/generated/types/double_complex_number_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct DoubleComplexNumberType { pub real: f64, diff --git a/async-opcua-types/src/generated/types/element_operand.rs b/async-opcua-types/src/generated/types/element_operand.rs index cebfe4fa..191fc3bc 100644 --- a/async-opcua-types/src/generated/types/element_operand.rs +++ b/async-opcua-types/src/generated/types/element_operand.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ElementOperand { pub index: u32, diff --git a/async-opcua-types/src/generated/types/endpoint_configuration.rs b/async-opcua-types/src/generated/types/endpoint_configuration.rs index 0c8e2e44..57a976e5 100644 --- a/async-opcua-types/src/generated/types/endpoint_configuration.rs +++ b/async-opcua-types/src/generated/types/endpoint_configuration.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EndpointConfiguration { pub operation_timeout: i32, diff --git a/async-opcua-types/src/generated/types/endpoint_description.rs b/async-opcua-types/src/generated/types/endpoint_description.rs index 86004a22..59e30fce 100644 --- a/async-opcua-types/src/generated/types/endpoint_description.rs +++ b/async-opcua-types/src/generated/types/endpoint_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EndpointDescription { pub endpoint_url: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/endpoint_type.rs b/async-opcua-types/src/generated/types/endpoint_type.rs index 65e2696c..c05a4f28 100644 --- a/async-opcua-types/src/generated/types/endpoint_type.rs +++ b/async-opcua-types/src/generated/types/endpoint_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EndpointType { pub endpoint_url: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/endpoint_url_list_data_type.rs b/async-opcua-types/src/generated/types/endpoint_url_list_data_type.rs index dd0ef2a9..4bd1654b 100644 --- a/async-opcua-types/src/generated/types/endpoint_url_list_data_type.rs +++ b/async-opcua-types/src/generated/types/endpoint_url_list_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EndpointUrlListDataType { pub endpoint_url_list: Option>, diff --git a/async-opcua-types/src/generated/types/enum_definition.rs b/async-opcua-types/src/generated/types/enum_definition.rs index 176503d7..48969cca 100644 --- a/async-opcua-types/src/generated/types/enum_definition.rs +++ b/async-opcua-types/src/generated/types/enum_definition.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EnumDefinition { pub fields: Option>, diff --git a/async-opcua-types/src/generated/types/enum_description.rs b/async-opcua-types/src/generated/types/enum_description.rs index 26c0eef7..417ccafc 100644 --- a/async-opcua-types/src/generated/types/enum_description.rs +++ b/async-opcua-types/src/generated/types/enum_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EnumDescription { pub data_type_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/enum_field.rs b/async-opcua-types/src/generated/types/enum_field.rs index d60887d4..7186667e 100644 --- a/async-opcua-types/src/generated/types/enum_field.rs +++ b/async-opcua-types/src/generated/types/enum_field.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EnumField { pub value: i64, diff --git a/async-opcua-types/src/generated/types/enum_value_type.rs b/async-opcua-types/src/generated/types/enum_value_type.rs index 7dcca970..53e58c0d 100644 --- a/async-opcua-types/src/generated/types/enum_value_type.rs +++ b/async-opcua-types/src/generated/types/enum_value_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EnumValueType { pub value: i64, diff --git a/async-opcua-types/src/generated/types/enums.rs b/async-opcua-types/src/generated/types/enums.rs index ec688070..ac962e10 100644 --- a/async-opcua-types/src/generated/types/enums.rs +++ b/async-opcua-types/src/generated/types/enums.rs @@ -48,15 +48,28 @@ impl opcua::types::IntoVariant for AccessLevelExType { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for AccessLevelExType { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for AccessLevelExType { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for AccessLevelExType { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for AccessLevelExType { + const TAG: &'static str = "AccessLevelExType"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for AccessLevelExType { fn decode( @@ -116,15 +129,28 @@ impl opcua::types::IntoVariant for AccessLevelType { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for AccessLevelType { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for AccessLevelType { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = u8::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(u8::decode(stream, ctx)?)) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for AccessLevelType { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for AccessLevelType { + const TAG: &'static str = "AccessLevelType"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for AccessLevelType { fn decode( @@ -183,15 +209,28 @@ impl opcua::types::IntoVariant for AccessRestrictionType { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for AccessRestrictionType { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for AccessRestrictionType { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i16::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i16::decode(stream, ctx)?)) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for AccessRestrictionType { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for AccessRestrictionType { + const TAG: &'static str = "AccessRestrictionType"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for AccessRestrictionType { fn decode( @@ -249,15 +288,28 @@ impl opcua::types::IntoVariant for AlarmMask { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for AlarmMask { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for AlarmMask { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i16::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i16::decode(stream, ctx)?)) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for AlarmMask { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for AlarmMask { + const TAG: &'static str = "AlarmMask"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for AlarmMask { fn decode( @@ -294,7 +346,14 @@ impl opcua::types::json::JsonEncodable for AlarmMask { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum ApplicationType { #[opcua(default)] @@ -347,15 +406,28 @@ impl opcua::types::IntoVariant for AttributeWriteMask { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for AttributeWriteMask { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for AttributeWriteMask { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for AttributeWriteMask { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for AttributeWriteMask { + const TAG: &'static str = "AttributeWriteMask"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for AttributeWriteMask { fn decode( @@ -392,7 +464,14 @@ impl opcua::types::json::JsonEncodable for AttributeWriteMask { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum AxisScaleEnumeration { #[opcua(default)] @@ -414,7 +493,14 @@ pub enum AxisScaleEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum BrokerTransportQualityOfService { #[opcua(default)] @@ -438,7 +524,14 @@ pub enum BrokerTransportQualityOfService { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum BrowseDirection { #[opcua(default)] @@ -461,7 +554,14 @@ pub enum BrowseDirection { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum BrowseResultMask { #[opcua(default)] @@ -490,7 +590,14 @@ pub enum BrowseResultMask { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum ConversionLimitEnum { #[opcua(default)] @@ -512,7 +619,14 @@ pub enum ConversionLimitEnum { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum DataChangeTrigger { #[opcua(default)] @@ -557,15 +671,28 @@ impl opcua::types::IntoVariant for DataSetFieldContentMask { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for DataSetFieldContentMask { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for DataSetFieldContentMask { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for DataSetFieldContentMask { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for DataSetFieldContentMask { + const TAG: &'static str = "DataSetFieldContentMask"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for DataSetFieldContentMask { fn decode( @@ -623,15 +750,28 @@ impl opcua::types::IntoVariant for DataSetFieldFlags { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for DataSetFieldFlags { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for DataSetFieldFlags { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i16::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i16::decode(stream, ctx)?)) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for DataSetFieldFlags { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for DataSetFieldFlags { + const TAG: &'static str = "DataSetFieldFlags"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for DataSetFieldFlags { fn decode( @@ -668,7 +808,14 @@ impl opcua::types::json::JsonEncodable for DataSetFieldFlags { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum DataSetOrderingType { #[opcua(default)] @@ -690,7 +837,14 @@ pub enum DataSetOrderingType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum DeadbandType { #[opcua(default)] @@ -712,7 +866,14 @@ pub enum DeadbandType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum DiagnosticsLevel { #[opcua(default)] @@ -736,7 +897,14 @@ pub enum DiagnosticsLevel { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum Duplex { #[opcua(default)] @@ -780,15 +948,28 @@ impl opcua::types::IntoVariant for EventNotifierType { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for EventNotifierType { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for EventNotifierType { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = u8::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(u8::decode(stream, ctx)?)) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for EventNotifierType { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for EventNotifierType { + const TAG: &'static str = "EventNotifierType"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for EventNotifierType { fn decode( @@ -825,7 +1006,14 @@ impl opcua::types::json::JsonEncodable for EventNotifierType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum ExceptionDeviationFormat { #[opcua(default)] @@ -849,7 +1037,14 @@ pub enum ExceptionDeviationFormat { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum FilterOperator { #[opcua(default)] @@ -886,7 +1081,14 @@ pub enum FilterOperator { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum HistoryUpdateType { Insert = 1i32, @@ -908,7 +1110,14 @@ pub enum HistoryUpdateType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum IdentityCriteriaType { UserName = 1i32, @@ -934,7 +1143,14 @@ pub enum IdentityCriteriaType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum IdType { #[opcua(default)] @@ -957,7 +1173,14 @@ pub enum IdType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum InterfaceAdminStatus { #[opcua(default)] @@ -979,7 +1202,14 @@ pub enum InterfaceAdminStatus { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum InterfaceOperStatus { #[opcua(default)] @@ -1030,15 +1260,28 @@ impl opcua::types::IntoVariant for JsonDataSetMessageContentMask { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for JsonDataSetMessageContentMask { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for JsonDataSetMessageContentMask { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for JsonDataSetMessageContentMask { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for JsonDataSetMessageContentMask { + const TAG: &'static str = "JsonDataSetMessageContentMask"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for JsonDataSetMessageContentMask { fn decode( @@ -1099,15 +1342,28 @@ impl opcua::types::IntoVariant for JsonNetworkMessageContentMask { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for JsonNetworkMessageContentMask { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for JsonNetworkMessageContentMask { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for JsonNetworkMessageContentMask { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for JsonNetworkMessageContentMask { + const TAG: &'static str = "JsonNetworkMessageContentMask"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for JsonNetworkMessageContentMask { fn decode( @@ -1144,7 +1400,14 @@ impl opcua::types::json::JsonEncodable for JsonNetworkMessageContentMask { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum MessageSecurityMode { #[opcua(default)] @@ -1167,7 +1430,14 @@ pub enum MessageSecurityMode { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum ModelChangeStructureVerbMask { NodeAdded = 1i32, @@ -1190,7 +1460,14 @@ pub enum ModelChangeStructureVerbMask { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum MonitoringMode { #[opcua(default)] @@ -1212,7 +1489,14 @@ pub enum MonitoringMode { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum NamingRuleType { Mandatory = 1i32, @@ -1233,7 +1517,14 @@ pub enum NamingRuleType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum NegotiationStatus { #[opcua(default)] @@ -1257,7 +1548,14 @@ pub enum NegotiationStatus { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum NodeAttributesMask { #[opcua(default)] @@ -1311,7 +1609,14 @@ pub enum NodeAttributesMask { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum NodeClass { #[opcua(default)] @@ -1340,7 +1645,14 @@ pub enum NodeClass { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(u8)] pub enum NodeIdType { #[opcua(default)] @@ -1365,7 +1677,14 @@ pub enum NodeIdType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum OpenFileMode { Read = 1i32, @@ -1387,7 +1706,14 @@ pub enum OpenFileMode { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum OverrideValueHandling { #[opcua(default)] @@ -1434,15 +1760,28 @@ impl opcua::types::IntoVariant for PasswordOptionsMask { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for PasswordOptionsMask { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for PasswordOptionsMask { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for PasswordOptionsMask { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for PasswordOptionsMask { + const TAG: &'static str = "PasswordOptionsMask"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for PasswordOptionsMask { fn decode( @@ -1479,7 +1818,14 @@ impl opcua::types::json::JsonEncodable for PasswordOptionsMask { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PerformUpdateType { Insert = 1i32, @@ -1527,15 +1873,28 @@ impl opcua::types::IntoVariant for PermissionType { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for PermissionType { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for PermissionType { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for PermissionType { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for PermissionType { + const TAG: &'static str = "PermissionType"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for PermissionType { fn decode( @@ -1598,15 +1957,28 @@ impl opcua::types::IntoVariant for PubSubConfigurationRefMask { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for PubSubConfigurationRefMask { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for PubSubConfigurationRefMask { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for PubSubConfigurationRefMask { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for PubSubConfigurationRefMask { + const TAG: &'static str = "PubSubConfigurationRefMask"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for PubSubConfigurationRefMask { fn decode( @@ -1643,7 +2015,14 @@ impl opcua::types::json::JsonEncodable for PubSubConfigurationRefMask { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PubSubDiagnosticsCounterClassification { #[opcua(default)] @@ -1664,7 +2043,14 @@ pub enum PubSubDiagnosticsCounterClassification { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PubSubState { #[opcua(default)] @@ -1688,7 +2074,14 @@ pub enum PubSubState { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum RedundancySupport { #[opcua(default)] @@ -1713,7 +2106,14 @@ pub enum RedundancySupport { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum RedundantServerMode { #[opcua(default)] @@ -1736,7 +2136,14 @@ pub enum RedundantServerMode { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum SecurityTokenRequestType { #[opcua(default)] @@ -1757,7 +2164,14 @@ pub enum SecurityTokenRequestType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum ServerState { #[opcua(default)] @@ -1784,7 +2198,14 @@ pub enum ServerState { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum StructureType { #[opcua(default)] @@ -1808,7 +2229,14 @@ pub enum StructureType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum TimestampsToReturn { #[opcua(default)] @@ -1832,7 +2260,14 @@ pub enum TimestampsToReturn { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum TrustListMasks { #[opcua(default)] @@ -1882,15 +2317,28 @@ impl opcua::types::IntoVariant for TrustListValidationOptions { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for TrustListValidationOptions { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for TrustListValidationOptions { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for TrustListValidationOptions { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for TrustListValidationOptions { + const TAG: &'static str = "TrustListValidationOptions"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for TrustListValidationOptions { fn decode( @@ -1927,7 +2375,14 @@ impl opcua::types::json::JsonEncodable for TrustListValidationOptions { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum TsnFailureCode { #[opcua(default)] @@ -1972,7 +2427,14 @@ pub enum TsnFailureCode { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum TsnListenerStatus { #[opcua(default)] @@ -1995,7 +2457,14 @@ pub enum TsnListenerStatus { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum TsnStreamState { #[opcua(default)] @@ -2019,7 +2488,14 @@ pub enum TsnStreamState { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum TsnTalkerStatus { #[opcua(default)] @@ -2064,15 +2540,28 @@ impl opcua::types::IntoVariant for UadpDataSetMessageContentMask { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for UadpDataSetMessageContentMask { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for UadpDataSetMessageContentMask { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for UadpDataSetMessageContentMask { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for UadpDataSetMessageContentMask { + const TAG: &'static str = "UadpDataSetMessageContentMask"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for UadpDataSetMessageContentMask { fn decode( @@ -2134,15 +2623,28 @@ impl opcua::types::IntoVariant for UadpNetworkMessageContentMask { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for UadpNetworkMessageContentMask { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for UadpNetworkMessageContentMask { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for UadpNetworkMessageContentMask { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for UadpNetworkMessageContentMask { + const TAG: &'static str = "UadpNetworkMessageContentMask"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for UadpNetworkMessageContentMask { fn decode( @@ -2201,15 +2703,28 @@ impl opcua::types::IntoVariant for UserConfigurationMask { } } #[cfg(feature = "xml")] -impl opcua::types::xml::FromXml for UserConfigurationMask { - fn from_xml( - element: &opcua::types::xml::XmlElement, +impl opcua::types::xml::XmlDecodable for UserConfigurationMask { + fn decode( + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> opcua::types::EncodingResult { - let val = i32::from_xml(element, ctx)?; - Ok(Self::from_bits_truncate(val)) + Ok(Self::from_bits_truncate(i32::decode(stream, ctx)?)) } } +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlEncodable for UserConfigurationMask { + fn encode( + &self, + stream: &mut opcua::types::xml::XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &opcua::types::Context<'_>, + ) -> opcua::types::EncodingResult<()> { + self.bits().encode(stream, ctx) + } +} +#[cfg(feature = "xml")] +impl opcua::types::xml::XmlType for UserConfigurationMask { + const TAG: &'static str = "UserConfigurationMask"; +} #[cfg(feature = "json")] impl opcua::types::json::JsonDecodable for UserConfigurationMask { fn decode( @@ -2246,7 +2761,14 @@ impl opcua::types::json::JsonEncodable for UserConfigurationMask { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum UserTokenType { #[opcua(default)] diff --git a/async-opcua-types/src/generated/types/ephemeral_key_type.rs b/async-opcua-types/src/generated/types/ephemeral_key_type.rs index 5eecb076..d0ba3977 100644 --- a/async-opcua-types/src/generated/types/ephemeral_key_type.rs +++ b/async-opcua-types/src/generated/types/ephemeral_key_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EphemeralKeyType { pub public_key: opcua::types::byte_string::ByteString, diff --git a/async-opcua-types/src/generated/types/eu_information.rs b/async-opcua-types/src/generated/types/eu_information.rs index 39c25a45..9712e694 100644 --- a/async-opcua-types/src/generated/types/eu_information.rs +++ b/async-opcua-types/src/generated/types/eu_information.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EUInformation { pub namespace_uri: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/event_field_list.rs b/async-opcua-types/src/generated/types/event_field_list.rs index 32f28acc..7adb724a 100644 --- a/async-opcua-types/src/generated/types/event_field_list.rs +++ b/async-opcua-types/src/generated/types/event_field_list.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EventFieldList { pub client_handle: u32, diff --git a/async-opcua-types/src/generated/types/event_filter.rs b/async-opcua-types/src/generated/types/event_filter.rs index f1f3c8b9..c941e13a 100644 --- a/async-opcua-types/src/generated/types/event_filter.rs +++ b/async-opcua-types/src/generated/types/event_filter.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EventFilter { pub select_clauses: Option>, diff --git a/async-opcua-types/src/generated/types/event_filter_result.rs b/async-opcua-types/src/generated/types/event_filter_result.rs index e71dc0b5..2c89cc55 100644 --- a/async-opcua-types/src/generated/types/event_filter_result.rs +++ b/async-opcua-types/src/generated/types/event_filter_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EventFilterResult { pub select_clause_results: Option>, diff --git a/async-opcua-types/src/generated/types/event_notification_list.rs b/async-opcua-types/src/generated/types/event_notification_list.rs index 26db077a..aae9a6bb 100644 --- a/async-opcua-types/src/generated/types/event_notification_list.rs +++ b/async-opcua-types/src/generated/types/event_notification_list.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct EventNotificationList { pub events: Option>, diff --git a/async-opcua-types/src/generated/types/field_meta_data.rs b/async-opcua-types/src/generated/types/field_meta_data.rs index d4411e1a..f47ec518 100644 --- a/async-opcua-types/src/generated/types/field_meta_data.rs +++ b/async-opcua-types/src/generated/types/field_meta_data.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct FieldMetaData { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/field_target_data_type.rs b/async-opcua-types/src/generated/types/field_target_data_type.rs index f07d48ff..bc96806e 100644 --- a/async-opcua-types/src/generated/types/field_target_data_type.rs +++ b/async-opcua-types/src/generated/types/field_target_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct FieldTargetDataType { pub data_set_field_id: opcua::types::guid::Guid, diff --git a/async-opcua-types/src/generated/types/filter_operand.rs b/async-opcua-types/src/generated/types/filter_operand.rs index ef944ebe..cc41e952 100644 --- a/async-opcua-types/src/generated/types/filter_operand.rs +++ b/async-opcua-types/src/generated/types/filter_operand.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct FilterOperand {} impl opcua::types::MessageInfo for FilterOperand { diff --git a/async-opcua-types/src/generated/types/find_servers_on_network_request.rs b/async-opcua-types/src/generated/types/find_servers_on_network_request.rs index f8907d87..831fef58 100644 --- a/async-opcua-types/src/generated/types/find_servers_on_network_request.rs +++ b/async-opcua-types/src/generated/types/find_servers_on_network_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct FindServersOnNetworkRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/find_servers_on_network_response.rs b/async-opcua-types/src/generated/types/find_servers_on_network_response.rs index 4b12cc00..c2a20007 100644 --- a/async-opcua-types/src/generated/types/find_servers_on_network_response.rs +++ b/async-opcua-types/src/generated/types/find_servers_on_network_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct FindServersOnNetworkResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/find_servers_request.rs b/async-opcua-types/src/generated/types/find_servers_request.rs index 07c88fbf..83b2df50 100644 --- a/async-opcua-types/src/generated/types/find_servers_request.rs +++ b/async-opcua-types/src/generated/types/find_servers_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct FindServersRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/find_servers_response.rs b/async-opcua-types/src/generated/types/find_servers_response.rs index 7b660a76..2004b572 100644 --- a/async-opcua-types/src/generated/types/find_servers_response.rs +++ b/async-opcua-types/src/generated/types/find_servers_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct FindServersResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/frame.rs b/async-opcua-types/src/generated/types/frame.rs index dc15c368..a0b8017e 100644 --- a/async-opcua-types/src/generated/types/frame.rs +++ b/async-opcua-types/src/generated/types/frame.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct Frame {} impl opcua::types::MessageInfo for Frame { diff --git a/async-opcua-types/src/generated/types/generic_attribute_value.rs b/async-opcua-types/src/generated/types/generic_attribute_value.rs index 783344c7..d79af1ac 100644 --- a/async-opcua-types/src/generated/types/generic_attribute_value.rs +++ b/async-opcua-types/src/generated/types/generic_attribute_value.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct GenericAttributeValue { pub attribute_id: u32, diff --git a/async-opcua-types/src/generated/types/generic_attributes.rs b/async-opcua-types/src/generated/types/generic_attributes.rs index 1272a202..9d0bd185 100644 --- a/async-opcua-types/src/generated/types/generic_attributes.rs +++ b/async-opcua-types/src/generated/types/generic_attributes.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct GenericAttributes { pub specified_attributes: u32, diff --git a/async-opcua-types/src/generated/types/get_endpoints_request.rs b/async-opcua-types/src/generated/types/get_endpoints_request.rs index eaf16818..fa4c4238 100644 --- a/async-opcua-types/src/generated/types/get_endpoints_request.rs +++ b/async-opcua-types/src/generated/types/get_endpoints_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct GetEndpointsRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/get_endpoints_response.rs b/async-opcua-types/src/generated/types/get_endpoints_response.rs index 51b3a359..5477c69c 100644 --- a/async-opcua-types/src/generated/types/get_endpoints_response.rs +++ b/async-opcua-types/src/generated/types/get_endpoints_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct GetEndpointsResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/history_data.rs b/async-opcua-types/src/generated/types/history_data.rs index 4ceb13e3..f187d1ce 100644 --- a/async-opcua-types/src/generated/types/history_data.rs +++ b/async-opcua-types/src/generated/types/history_data.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryData { pub data_values: Option>, diff --git a/async-opcua-types/src/generated/types/history_event.rs b/async-opcua-types/src/generated/types/history_event.rs index 1fb8857a..4dc91ebe 100644 --- a/async-opcua-types/src/generated/types/history_event.rs +++ b/async-opcua-types/src/generated/types/history_event.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryEvent { pub events: Option>, diff --git a/async-opcua-types/src/generated/types/history_event_field_list.rs b/async-opcua-types/src/generated/types/history_event_field_list.rs index e184d6ef..17c876e3 100644 --- a/async-opcua-types/src/generated/types/history_event_field_list.rs +++ b/async-opcua-types/src/generated/types/history_event_field_list.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryEventFieldList { pub event_fields: Option>, diff --git a/async-opcua-types/src/generated/types/history_modified_data.rs b/async-opcua-types/src/generated/types/history_modified_data.rs index 0585264a..f58e0d14 100644 --- a/async-opcua-types/src/generated/types/history_modified_data.rs +++ b/async-opcua-types/src/generated/types/history_modified_data.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryModifiedData { pub data_values: Option>, diff --git a/async-opcua-types/src/generated/types/history_modified_event.rs b/async-opcua-types/src/generated/types/history_modified_event.rs index d8938354..83294e8a 100644 --- a/async-opcua-types/src/generated/types/history_modified_event.rs +++ b/async-opcua-types/src/generated/types/history_modified_event.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryModifiedEvent { pub events: Option>, diff --git a/async-opcua-types/src/generated/types/history_read_details.rs b/async-opcua-types/src/generated/types/history_read_details.rs index bd1075f7..bbe1938c 100644 --- a/async-opcua-types/src/generated/types/history_read_details.rs +++ b/async-opcua-types/src/generated/types/history_read_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryReadDetails {} impl opcua::types::MessageInfo for HistoryReadDetails { diff --git a/async-opcua-types/src/generated/types/history_read_request.rs b/async-opcua-types/src/generated/types/history_read_request.rs index 75782218..2815e643 100644 --- a/async-opcua-types/src/generated/types/history_read_request.rs +++ b/async-opcua-types/src/generated/types/history_read_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryReadRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/history_read_response.rs b/async-opcua-types/src/generated/types/history_read_response.rs index 9b77eb67..be0f7b1c 100644 --- a/async-opcua-types/src/generated/types/history_read_response.rs +++ b/async-opcua-types/src/generated/types/history_read_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryReadResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/history_read_result.rs b/async-opcua-types/src/generated/types/history_read_result.rs index 683566ae..f6c47599 100644 --- a/async-opcua-types/src/generated/types/history_read_result.rs +++ b/async-opcua-types/src/generated/types/history_read_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryReadResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/history_read_value_id.rs b/async-opcua-types/src/generated/types/history_read_value_id.rs index 17845b63..69ac0028 100644 --- a/async-opcua-types/src/generated/types/history_read_value_id.rs +++ b/async-opcua-types/src/generated/types/history_read_value_id.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryReadValueId { pub node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/history_update_details.rs b/async-opcua-types/src/generated/types/history_update_details.rs index 18e5d412..9711beb1 100644 --- a/async-opcua-types/src/generated/types/history_update_details.rs +++ b/async-opcua-types/src/generated/types/history_update_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryUpdateDetails {} impl opcua::types::MessageInfo for HistoryUpdateDetails { diff --git a/async-opcua-types/src/generated/types/history_update_request.rs b/async-opcua-types/src/generated/types/history_update_request.rs index 3046cb67..703b6a2a 100644 --- a/async-opcua-types/src/generated/types/history_update_request.rs +++ b/async-opcua-types/src/generated/types/history_update_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryUpdateRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/history_update_response.rs b/async-opcua-types/src/generated/types/history_update_response.rs index 5003a556..9f2968ea 100644 --- a/async-opcua-types/src/generated/types/history_update_response.rs +++ b/async-opcua-types/src/generated/types/history_update_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryUpdateResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/history_update_result.rs b/async-opcua-types/src/generated/types/history_update_result.rs index 57a7ab77..3f2a14f8 100644 --- a/async-opcua-types/src/generated/types/history_update_result.rs +++ b/async-opcua-types/src/generated/types/history_update_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct HistoryUpdateResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/identity_mapping_rule_type.rs b/async-opcua-types/src/generated/types/identity_mapping_rule_type.rs index c8ff2a90..97c8c7c9 100644 --- a/async-opcua-types/src/generated/types/identity_mapping_rule_type.rs +++ b/async-opcua-types/src/generated/types/identity_mapping_rule_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] pub struct IdentityMappingRuleType { pub criteria_type: super::enums::IdentityCriteriaType, pub criteria: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/issued_identity_token.rs b/async-opcua-types/src/generated/types/issued_identity_token.rs index d3a7ca76..a23f87bb 100644 --- a/async-opcua-types/src/generated/types/issued_identity_token.rs +++ b/async-opcua-types/src/generated/types/issued_identity_token.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct IssuedIdentityToken { pub policy_id: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/json_data_set_reader_message_data_type.rs b/async-opcua-types/src/generated/types/json_data_set_reader_message_data_type.rs index d8a24d1c..c8085c07 100644 --- a/async-opcua-types/src/generated/types/json_data_set_reader_message_data_type.rs +++ b/async-opcua-types/src/generated/types/json_data_set_reader_message_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct JsonDataSetReaderMessageDataType { pub network_message_content_mask: super::enums::JsonNetworkMessageContentMask, diff --git a/async-opcua-types/src/generated/types/json_data_set_writer_message_data_type.rs b/async-opcua-types/src/generated/types/json_data_set_writer_message_data_type.rs index 940c84af..8794c9cf 100644 --- a/async-opcua-types/src/generated/types/json_data_set_writer_message_data_type.rs +++ b/async-opcua-types/src/generated/types/json_data_set_writer_message_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct JsonDataSetWriterMessageDataType { pub data_set_message_content_mask: super::enums::JsonDataSetMessageContentMask, diff --git a/async-opcua-types/src/generated/types/json_writer_group_message_data_type.rs b/async-opcua-types/src/generated/types/json_writer_group_message_data_type.rs index 0b960416..dab8b616 100644 --- a/async-opcua-types/src/generated/types/json_writer_group_message_data_type.rs +++ b/async-opcua-types/src/generated/types/json_writer_group_message_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct JsonWriterGroupMessageDataType { pub network_message_content_mask: super::enums::JsonNetworkMessageContentMask, diff --git a/async-opcua-types/src/generated/types/key_value_pair.rs b/async-opcua-types/src/generated/types/key_value_pair.rs index f8311439..338ff10a 100644 --- a/async-opcua-types/src/generated/types/key_value_pair.rs +++ b/async-opcua-types/src/generated/types/key_value_pair.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct KeyValuePair { pub key: opcua::types::qualified_name::QualifiedName, diff --git a/async-opcua-types/src/generated/types/linear_conversion_data_type.rs b/async-opcua-types/src/generated/types/linear_conversion_data_type.rs index 09a6aefb..e046d00a 100644 --- a/async-opcua-types/src/generated/types/linear_conversion_data_type.rs +++ b/async-opcua-types/src/generated/types/linear_conversion_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct LinearConversionDataType { pub initial_addend: f32, diff --git a/async-opcua-types/src/generated/types/literal_operand.rs b/async-opcua-types/src/generated/types/literal_operand.rs index e26c9777..59c066bc 100644 --- a/async-opcua-types/src/generated/types/literal_operand.rs +++ b/async-opcua-types/src/generated/types/literal_operand.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct LiteralOperand { pub value: opcua::types::variant::Variant, diff --git a/async-opcua-types/src/generated/types/mdns_discovery_configuration.rs b/async-opcua-types/src/generated/types/mdns_discovery_configuration.rs index 595a2dc4..b4583254 100644 --- a/async-opcua-types/src/generated/types/mdns_discovery_configuration.rs +++ b/async-opcua-types/src/generated/types/mdns_discovery_configuration.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct MdnsDiscoveryConfiguration { pub mdns_server_name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/method_attributes.rs b/async-opcua-types/src/generated/types/method_attributes.rs index 2ed1f10a..5b496ce0 100644 --- a/async-opcua-types/src/generated/types/method_attributes.rs +++ b/async-opcua-types/src/generated/types/method_attributes.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct MethodAttributes { pub specified_attributes: u32, diff --git a/async-opcua-types/src/generated/types/mod.rs b/async-opcua-types/src/generated/types/mod.rs index 82ca48af..4acc21d1 100644 --- a/async-opcua-types/src/generated/types/mod.rs +++ b/async-opcua-types/src/generated/types/mod.rs @@ -5319,16 +5319,16 @@ impl opcua::types::TypeLoader for GeneratedTypeLoader { fn load_from_xml( &self, node_id: &opcua::types::NodeId, - stream: &opcua::types::xml::XmlElement, + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> Option>> { if node_id.namespace != 0 { return None; } let Some(num_id) = node_id.as_u32() else { - return Some(Err(opcua::types::Error::decoding(format!( - "Unsupported encoding ID {node_id}, we only support numeric IDs" - )))); + return Some(Err(opcua::types::Error::decoding( + "Unsupported encoding ID. Only numeric encoding IDs are currently supported", + ))); }; TYPES.decode_xml(num_id, stream, ctx) } diff --git a/async-opcua-types/src/generated/types/model_change_structure_data_type.rs b/async-opcua-types/src/generated/types/model_change_structure_data_type.rs index 1a65079a..bee4c703 100644 --- a/async-opcua-types/src/generated/types/model_change_structure_data_type.rs +++ b/async-opcua-types/src/generated/types/model_change_structure_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ModelChangeStructureDataType { pub affected: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/modification_info.rs b/async-opcua-types/src/generated/types/modification_info.rs index 3ec1c164..02274e4d 100644 --- a/async-opcua-types/src/generated/types/modification_info.rs +++ b/async-opcua-types/src/generated/types/modification_info.rs @@ -14,7 +14,15 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] +#[derive(Default)] pub struct ModificationInfo { pub modification_time: opcua::types::date_time::DateTime, pub update_type: super::enums::HistoryUpdateType, diff --git a/async-opcua-types/src/generated/types/modify_monitored_items_request.rs b/async-opcua-types/src/generated/types/modify_monitored_items_request.rs index 4fa6e341..a0908f21 100644 --- a/async-opcua-types/src/generated/types/modify_monitored_items_request.rs +++ b/async-opcua-types/src/generated/types/modify_monitored_items_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ModifyMonitoredItemsRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/modify_monitored_items_response.rs b/async-opcua-types/src/generated/types/modify_monitored_items_response.rs index 54c92f31..d6910227 100644 --- a/async-opcua-types/src/generated/types/modify_monitored_items_response.rs +++ b/async-opcua-types/src/generated/types/modify_monitored_items_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ModifyMonitoredItemsResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/modify_subscription_request.rs b/async-opcua-types/src/generated/types/modify_subscription_request.rs index 46db843c..05903e4b 100644 --- a/async-opcua-types/src/generated/types/modify_subscription_request.rs +++ b/async-opcua-types/src/generated/types/modify_subscription_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ModifySubscriptionRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/modify_subscription_response.rs b/async-opcua-types/src/generated/types/modify_subscription_response.rs index 41fa4adf..a0c8c58e 100644 --- a/async-opcua-types/src/generated/types/modify_subscription_response.rs +++ b/async-opcua-types/src/generated/types/modify_subscription_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ModifySubscriptionResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/monitored_item_create_request.rs b/async-opcua-types/src/generated/types/monitored_item_create_request.rs index 076ea3ca..e900cc71 100644 --- a/async-opcua-types/src/generated/types/monitored_item_create_request.rs +++ b/async-opcua-types/src/generated/types/monitored_item_create_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct MonitoredItemCreateRequest { pub item_to_monitor: super::read_value_id::ReadValueId, diff --git a/async-opcua-types/src/generated/types/monitored_item_create_result.rs b/async-opcua-types/src/generated/types/monitored_item_create_result.rs index 67932ad6..4e36e4fc 100644 --- a/async-opcua-types/src/generated/types/monitored_item_create_result.rs +++ b/async-opcua-types/src/generated/types/monitored_item_create_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct MonitoredItemCreateResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/monitored_item_modify_request.rs b/async-opcua-types/src/generated/types/monitored_item_modify_request.rs index ad9fe2b5..05940e75 100644 --- a/async-opcua-types/src/generated/types/monitored_item_modify_request.rs +++ b/async-opcua-types/src/generated/types/monitored_item_modify_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct MonitoredItemModifyRequest { pub monitored_item_id: u32, diff --git a/async-opcua-types/src/generated/types/monitored_item_modify_result.rs b/async-opcua-types/src/generated/types/monitored_item_modify_result.rs index 80c97b76..09a72f6c 100644 --- a/async-opcua-types/src/generated/types/monitored_item_modify_result.rs +++ b/async-opcua-types/src/generated/types/monitored_item_modify_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct MonitoredItemModifyResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/monitored_item_notification.rs b/async-opcua-types/src/generated/types/monitored_item_notification.rs index 3786fbcb..31ac2167 100644 --- a/async-opcua-types/src/generated/types/monitored_item_notification.rs +++ b/async-opcua-types/src/generated/types/monitored_item_notification.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct MonitoredItemNotification { pub client_handle: u32, diff --git a/async-opcua-types/src/generated/types/monitoring_filter.rs b/async-opcua-types/src/generated/types/monitoring_filter.rs index bde5d9d4..d0969a78 100644 --- a/async-opcua-types/src/generated/types/monitoring_filter.rs +++ b/async-opcua-types/src/generated/types/monitoring_filter.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct MonitoringFilter {} impl opcua::types::MessageInfo for MonitoringFilter { diff --git a/async-opcua-types/src/generated/types/monitoring_filter_result.rs b/async-opcua-types/src/generated/types/monitoring_filter_result.rs index 18f6ff5a..89e92ff0 100644 --- a/async-opcua-types/src/generated/types/monitoring_filter_result.rs +++ b/async-opcua-types/src/generated/types/monitoring_filter_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct MonitoringFilterResult {} impl opcua::types::MessageInfo for MonitoringFilterResult { diff --git a/async-opcua-types/src/generated/types/monitoring_parameters.rs b/async-opcua-types/src/generated/types/monitoring_parameters.rs index 86b3ca5d..5c983d09 100644 --- a/async-opcua-types/src/generated/types/monitoring_parameters.rs +++ b/async-opcua-types/src/generated/types/monitoring_parameters.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct MonitoringParameters { pub client_handle: u32, diff --git a/async-opcua-types/src/generated/types/network_address_data_type.rs b/async-opcua-types/src/generated/types/network_address_data_type.rs index 587bcab3..cbadbda2 100644 --- a/async-opcua-types/src/generated/types/network_address_data_type.rs +++ b/async-opcua-types/src/generated/types/network_address_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct NetworkAddressDataType { pub network_interface: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/network_address_url_data_type.rs b/async-opcua-types/src/generated/types/network_address_url_data_type.rs index 530752c1..dce90b32 100644 --- a/async-opcua-types/src/generated/types/network_address_url_data_type.rs +++ b/async-opcua-types/src/generated/types/network_address_url_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct NetworkAddressUrlDataType { pub network_interface: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/network_group_data_type.rs b/async-opcua-types/src/generated/types/network_group_data_type.rs index 79bf573d..e27d21d8 100644 --- a/async-opcua-types/src/generated/types/network_group_data_type.rs +++ b/async-opcua-types/src/generated/types/network_group_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct NetworkGroupDataType { pub server_uri: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/node_attributes.rs b/async-opcua-types/src/generated/types/node_attributes.rs index 6b9b4adc..573368fb 100644 --- a/async-opcua-types/src/generated/types/node_attributes.rs +++ b/async-opcua-types/src/generated/types/node_attributes.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct NodeAttributes { pub specified_attributes: u32, diff --git a/async-opcua-types/src/generated/types/node_reference.rs b/async-opcua-types/src/generated/types/node_reference.rs index 87785186..38bf03fc 100644 --- a/async-opcua-types/src/generated/types/node_reference.rs +++ b/async-opcua-types/src/generated/types/node_reference.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct NodeReference { pub node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/node_type_description.rs b/async-opcua-types/src/generated/types/node_type_description.rs index fb9c4f7a..27f0853e 100644 --- a/async-opcua-types/src/generated/types/node_type_description.rs +++ b/async-opcua-types/src/generated/types/node_type_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct NodeTypeDescription { pub type_definition_node: opcua::types::expanded_node_id::ExpandedNodeId, diff --git a/async-opcua-types/src/generated/types/notification_data.rs b/async-opcua-types/src/generated/types/notification_data.rs index f7ccca12..00e2fdc4 100644 --- a/async-opcua-types/src/generated/types/notification_data.rs +++ b/async-opcua-types/src/generated/types/notification_data.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct NotificationData {} impl opcua::types::MessageInfo for NotificationData { diff --git a/async-opcua-types/src/generated/types/notification_message.rs b/async-opcua-types/src/generated/types/notification_message.rs index 84304a78..2c95d5d1 100644 --- a/async-opcua-types/src/generated/types/notification_message.rs +++ b/async-opcua-types/src/generated/types/notification_message.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct NotificationMessage { pub sequence_number: u32, diff --git a/async-opcua-types/src/generated/types/object_attributes.rs b/async-opcua-types/src/generated/types/object_attributes.rs index e9d211c5..86398d00 100644 --- a/async-opcua-types/src/generated/types/object_attributes.rs +++ b/async-opcua-types/src/generated/types/object_attributes.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ObjectAttributes { pub specified_attributes: u32, diff --git a/async-opcua-types/src/generated/types/object_type_attributes.rs b/async-opcua-types/src/generated/types/object_type_attributes.rs index 5e9338ff..50986c48 100644 --- a/async-opcua-types/src/generated/types/object_type_attributes.rs +++ b/async-opcua-types/src/generated/types/object_type_attributes.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ObjectTypeAttributes { pub specified_attributes: u32, diff --git a/async-opcua-types/src/generated/types/open_secure_channel_request.rs b/async-opcua-types/src/generated/types/open_secure_channel_request.rs index 257385f3..d1bff64b 100644 --- a/async-opcua-types/src/generated/types/open_secure_channel_request.rs +++ b/async-opcua-types/src/generated/types/open_secure_channel_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct OpenSecureChannelRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/open_secure_channel_response.rs b/async-opcua-types/src/generated/types/open_secure_channel_response.rs index 24babde5..a8efd6c2 100644 --- a/async-opcua-types/src/generated/types/open_secure_channel_response.rs +++ b/async-opcua-types/src/generated/types/open_secure_channel_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct OpenSecureChannelResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/option_set.rs b/async-opcua-types/src/generated/types/option_set.rs index 954beb1c..52148202 100644 --- a/async-opcua-types/src/generated/types/option_set.rs +++ b/async-opcua-types/src/generated/types/option_set.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct OptionSet { pub value: opcua::types::byte_string::ByteString, diff --git a/async-opcua-types/src/generated/types/orientation.rs b/async-opcua-types/src/generated/types/orientation.rs index 59962854..5b1c0368 100644 --- a/async-opcua-types/src/generated/types/orientation.rs +++ b/async-opcua-types/src/generated/types/orientation.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct Orientation {} impl opcua::types::MessageInfo for Orientation { diff --git a/async-opcua-types/src/generated/types/parsing_result.rs b/async-opcua-types/src/generated/types/parsing_result.rs index 6ba19ea1..a4ef0e73 100644 --- a/async-opcua-types/src/generated/types/parsing_result.rs +++ b/async-opcua-types/src/generated/types/parsing_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ParsingResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/portable_node_id.rs b/async-opcua-types/src/generated/types/portable_node_id.rs index d1b84ef4..a6d67d8d 100644 --- a/async-opcua-types/src/generated/types/portable_node_id.rs +++ b/async-opcua-types/src/generated/types/portable_node_id.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PortableNodeId { pub namespace_uri: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/portable_qualified_name.rs b/async-opcua-types/src/generated/types/portable_qualified_name.rs index cbd63bbe..e986f9ca 100644 --- a/async-opcua-types/src/generated/types/portable_qualified_name.rs +++ b/async-opcua-types/src/generated/types/portable_qualified_name.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PortableQualifiedName { pub namespace_uri: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/priority_mapping_entry_type.rs b/async-opcua-types/src/generated/types/priority_mapping_entry_type.rs index 049fd4af..c0191971 100644 --- a/async-opcua-types/src/generated/types/priority_mapping_entry_type.rs +++ b/async-opcua-types/src/generated/types/priority_mapping_entry_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PriorityMappingEntryType { pub mapping_uri: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/program_diagnostic_2_data_type.rs b/async-opcua-types/src/generated/types/program_diagnostic_2_data_type.rs index 1ac7c17f..a6b1d111 100644 --- a/async-opcua-types/src/generated/types/program_diagnostic_2_data_type.rs +++ b/async-opcua-types/src/generated/types/program_diagnostic_2_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ProgramDiagnostic2DataType { pub create_session_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/program_diagnostic_data_type.rs b/async-opcua-types/src/generated/types/program_diagnostic_data_type.rs index 451d6a3e..387cc39f 100644 --- a/async-opcua-types/src/generated/types/program_diagnostic_data_type.rs +++ b/async-opcua-types/src/generated/types/program_diagnostic_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ProgramDiagnosticDataType { pub create_session_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/pub_sub_configuration_2_data_type.rs b/async-opcua-types/src/generated/types/pub_sub_configuration_2_data_type.rs index b06ff805..81875b43 100644 --- a/async-opcua-types/src/generated/types/pub_sub_configuration_2_data_type.rs +++ b/async-opcua-types/src/generated/types/pub_sub_configuration_2_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PubSubConfiguration2DataType { pub published_data_sets: diff --git a/async-opcua-types/src/generated/types/pub_sub_configuration_data_type.rs b/async-opcua-types/src/generated/types/pub_sub_configuration_data_type.rs index 59c7790b..9b5b3411 100644 --- a/async-opcua-types/src/generated/types/pub_sub_configuration_data_type.rs +++ b/async-opcua-types/src/generated/types/pub_sub_configuration_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PubSubConfigurationDataType { pub published_data_sets: diff --git a/async-opcua-types/src/generated/types/pub_sub_configuration_ref_data_type.rs b/async-opcua-types/src/generated/types/pub_sub_configuration_ref_data_type.rs index 44e67b16..64c6ca05 100644 --- a/async-opcua-types/src/generated/types/pub_sub_configuration_ref_data_type.rs +++ b/async-opcua-types/src/generated/types/pub_sub_configuration_ref_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PubSubConfigurationRefDataType { pub configuration_mask: super::enums::PubSubConfigurationRefMask, diff --git a/async-opcua-types/src/generated/types/pub_sub_configuration_value_data_type.rs b/async-opcua-types/src/generated/types/pub_sub_configuration_value_data_type.rs index 6d53aec4..a4c97d8c 100644 --- a/async-opcua-types/src/generated/types/pub_sub_configuration_value_data_type.rs +++ b/async-opcua-types/src/generated/types/pub_sub_configuration_value_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PubSubConfigurationValueDataType { pub configuration_element: diff --git a/async-opcua-types/src/generated/types/pub_sub_connection_data_type.rs b/async-opcua-types/src/generated/types/pub_sub_connection_data_type.rs index 85ce410a..a0c767a7 100644 --- a/async-opcua-types/src/generated/types/pub_sub_connection_data_type.rs +++ b/async-opcua-types/src/generated/types/pub_sub_connection_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PubSubConnectionDataType { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/pub_sub_group_data_type.rs b/async-opcua-types/src/generated/types/pub_sub_group_data_type.rs index 7873244f..af9c2a9e 100644 --- a/async-opcua-types/src/generated/types/pub_sub_group_data_type.rs +++ b/async-opcua-types/src/generated/types/pub_sub_group_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PubSubGroupDataType { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/pub_sub_key_push_target_data_type.rs b/async-opcua-types/src/generated/types/pub_sub_key_push_target_data_type.rs index 4124219c..9a3cb228 100644 --- a/async-opcua-types/src/generated/types/pub_sub_key_push_target_data_type.rs +++ b/async-opcua-types/src/generated/types/pub_sub_key_push_target_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PubSubKeyPushTargetDataType { pub application_uri: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/publish_request.rs b/async-opcua-types/src/generated/types/publish_request.rs index df7b56ad..a81c7759 100644 --- a/async-opcua-types/src/generated/types/publish_request.rs +++ b/async-opcua-types/src/generated/types/publish_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PublishRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/publish_response.rs b/async-opcua-types/src/generated/types/publish_response.rs index f35c8333..681b4cc8 100644 --- a/async-opcua-types/src/generated/types/publish_response.rs +++ b/async-opcua-types/src/generated/types/publish_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PublishResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/published_data_items_data_type.rs b/async-opcua-types/src/generated/types/published_data_items_data_type.rs index 63ff5df1..5abae754 100644 --- a/async-opcua-types/src/generated/types/published_data_items_data_type.rs +++ b/async-opcua-types/src/generated/types/published_data_items_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PublishedDataItemsDataType { pub published_data: Option>, diff --git a/async-opcua-types/src/generated/types/published_data_set_custom_source_data_type.rs b/async-opcua-types/src/generated/types/published_data_set_custom_source_data_type.rs index e93cce94..f3825c9d 100644 --- a/async-opcua-types/src/generated/types/published_data_set_custom_source_data_type.rs +++ b/async-opcua-types/src/generated/types/published_data_set_custom_source_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PublishedDataSetCustomSourceDataType { pub cyclic_data_set: bool, diff --git a/async-opcua-types/src/generated/types/published_data_set_data_type.rs b/async-opcua-types/src/generated/types/published_data_set_data_type.rs index 041f1079..f5f4baa3 100644 --- a/async-opcua-types/src/generated/types/published_data_set_data_type.rs +++ b/async-opcua-types/src/generated/types/published_data_set_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PublishedDataSetDataType { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/published_data_set_source_data_type.rs b/async-opcua-types/src/generated/types/published_data_set_source_data_type.rs index 63746e70..737b58ae 100644 --- a/async-opcua-types/src/generated/types/published_data_set_source_data_type.rs +++ b/async-opcua-types/src/generated/types/published_data_set_source_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PublishedDataSetSourceDataType {} impl opcua::types::MessageInfo for PublishedDataSetSourceDataType { diff --git a/async-opcua-types/src/generated/types/published_events_data_type.rs b/async-opcua-types/src/generated/types/published_events_data_type.rs index 6e09eb2e..7fec6b86 100644 --- a/async-opcua-types/src/generated/types/published_events_data_type.rs +++ b/async-opcua-types/src/generated/types/published_events_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PublishedEventsDataType { pub event_notifier: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/published_variable_data_type.rs b/async-opcua-types/src/generated/types/published_variable_data_type.rs index 86365a96..8355dd85 100644 --- a/async-opcua-types/src/generated/types/published_variable_data_type.rs +++ b/async-opcua-types/src/generated/types/published_variable_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PublishedVariableDataType { pub published_variable: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/qos_data_type.rs b/async-opcua-types/src/generated/types/qos_data_type.rs index 81ee3fc6..f6ebe195 100644 --- a/async-opcua-types/src/generated/types/qos_data_type.rs +++ b/async-opcua-types/src/generated/types/qos_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct QosDataType {} impl opcua::types::MessageInfo for QosDataType { diff --git a/async-opcua-types/src/generated/types/quantity_dimension.rs b/async-opcua-types/src/generated/types/quantity_dimension.rs index 9c3e82ae..e378b086 100644 --- a/async-opcua-types/src/generated/types/quantity_dimension.rs +++ b/async-opcua-types/src/generated/types/quantity_dimension.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct QuantityDimension { pub mass_exponent: i8, diff --git a/async-opcua-types/src/generated/types/query_data_description.rs b/async-opcua-types/src/generated/types/query_data_description.rs index d07b8c8e..b4c30895 100644 --- a/async-opcua-types/src/generated/types/query_data_description.rs +++ b/async-opcua-types/src/generated/types/query_data_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct QueryDataDescription { pub relative_path: super::relative_path::RelativePath, diff --git a/async-opcua-types/src/generated/types/query_data_set.rs b/async-opcua-types/src/generated/types/query_data_set.rs index 631352cb..3eaac873 100644 --- a/async-opcua-types/src/generated/types/query_data_set.rs +++ b/async-opcua-types/src/generated/types/query_data_set.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct QueryDataSet { pub node_id: opcua::types::expanded_node_id::ExpandedNodeId, diff --git a/async-opcua-types/src/generated/types/query_first_request.rs b/async-opcua-types/src/generated/types/query_first_request.rs index 382c0443..ea788c8b 100644 --- a/async-opcua-types/src/generated/types/query_first_request.rs +++ b/async-opcua-types/src/generated/types/query_first_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct QueryFirstRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/query_first_response.rs b/async-opcua-types/src/generated/types/query_first_response.rs index 03197697..5d1d9119 100644 --- a/async-opcua-types/src/generated/types/query_first_response.rs +++ b/async-opcua-types/src/generated/types/query_first_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct QueryFirstResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/query_next_request.rs b/async-opcua-types/src/generated/types/query_next_request.rs index ca3dc58c..a109e299 100644 --- a/async-opcua-types/src/generated/types/query_next_request.rs +++ b/async-opcua-types/src/generated/types/query_next_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct QueryNextRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/query_next_response.rs b/async-opcua-types/src/generated/types/query_next_response.rs index 0c1f7fe0..7b7e3855 100644 --- a/async-opcua-types/src/generated/types/query_next_response.rs +++ b/async-opcua-types/src/generated/types/query_next_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct QueryNextResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/range.rs b/async-opcua-types/src/generated/types/range.rs index d4af4d5c..d81ef515 100644 --- a/async-opcua-types/src/generated/types/range.rs +++ b/async-opcua-types/src/generated/types/range.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct Range { pub low: f64, diff --git a/async-opcua-types/src/generated/types/rational_number.rs b/async-opcua-types/src/generated/types/rational_number.rs index 362e77d0..a24fcacd 100644 --- a/async-opcua-types/src/generated/types/rational_number.rs +++ b/async-opcua-types/src/generated/types/rational_number.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RationalNumber { pub numerator: i32, diff --git a/async-opcua-types/src/generated/types/read_annotation_data_details.rs b/async-opcua-types/src/generated/types/read_annotation_data_details.rs index c8f7021e..87fc4394 100644 --- a/async-opcua-types/src/generated/types/read_annotation_data_details.rs +++ b/async-opcua-types/src/generated/types/read_annotation_data_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReadAnnotationDataDetails { pub req_times: Option>, diff --git a/async-opcua-types/src/generated/types/read_at_time_details.rs b/async-opcua-types/src/generated/types/read_at_time_details.rs index 1276ec80..1499dbad 100644 --- a/async-opcua-types/src/generated/types/read_at_time_details.rs +++ b/async-opcua-types/src/generated/types/read_at_time_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReadAtTimeDetails { pub req_times: Option>, diff --git a/async-opcua-types/src/generated/types/read_event_details.rs b/async-opcua-types/src/generated/types/read_event_details.rs index fc6c420f..4f43e433 100644 --- a/async-opcua-types/src/generated/types/read_event_details.rs +++ b/async-opcua-types/src/generated/types/read_event_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReadEventDetails { pub num_values_per_node: u32, diff --git a/async-opcua-types/src/generated/types/read_event_details_2.rs b/async-opcua-types/src/generated/types/read_event_details_2.rs index 2d3d9349..50126d42 100644 --- a/async-opcua-types/src/generated/types/read_event_details_2.rs +++ b/async-opcua-types/src/generated/types/read_event_details_2.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReadEventDetails2 { pub num_values_per_node: u32, diff --git a/async-opcua-types/src/generated/types/read_processed_details.rs b/async-opcua-types/src/generated/types/read_processed_details.rs index 62323851..77596462 100644 --- a/async-opcua-types/src/generated/types/read_processed_details.rs +++ b/async-opcua-types/src/generated/types/read_processed_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReadProcessedDetails { pub start_time: opcua::types::date_time::DateTime, diff --git a/async-opcua-types/src/generated/types/read_raw_modified_details.rs b/async-opcua-types/src/generated/types/read_raw_modified_details.rs index 13b18d22..047c27b5 100644 --- a/async-opcua-types/src/generated/types/read_raw_modified_details.rs +++ b/async-opcua-types/src/generated/types/read_raw_modified_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReadRawModifiedDetails { pub is_read_modified: bool, diff --git a/async-opcua-types/src/generated/types/read_request.rs b/async-opcua-types/src/generated/types/read_request.rs index 516342a2..a7226dde 100644 --- a/async-opcua-types/src/generated/types/read_request.rs +++ b/async-opcua-types/src/generated/types/read_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReadRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/read_response.rs b/async-opcua-types/src/generated/types/read_response.rs index f0a80fd5..be62df23 100644 --- a/async-opcua-types/src/generated/types/read_response.rs +++ b/async-opcua-types/src/generated/types/read_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReadResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/read_value_id.rs b/async-opcua-types/src/generated/types/read_value_id.rs index c7720294..2b0d4590 100644 --- a/async-opcua-types/src/generated/types/read_value_id.rs +++ b/async-opcua-types/src/generated/types/read_value_id.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReadValueId { pub node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/reader_group_data_type.rs b/async-opcua-types/src/generated/types/reader_group_data_type.rs index b636980c..fe0575ca 100644 --- a/async-opcua-types/src/generated/types/reader_group_data_type.rs +++ b/async-opcua-types/src/generated/types/reader_group_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReaderGroupDataType { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/reader_group_message_data_type.rs b/async-opcua-types/src/generated/types/reader_group_message_data_type.rs index 5a32a63f..e5f2de5a 100644 --- a/async-opcua-types/src/generated/types/reader_group_message_data_type.rs +++ b/async-opcua-types/src/generated/types/reader_group_message_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReaderGroupMessageDataType {} impl opcua::types::MessageInfo for ReaderGroupMessageDataType { diff --git a/async-opcua-types/src/generated/types/reader_group_transport_data_type.rs b/async-opcua-types/src/generated/types/reader_group_transport_data_type.rs index 1cd1e180..5b3409b6 100644 --- a/async-opcua-types/src/generated/types/reader_group_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/reader_group_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReaderGroupTransportDataType {} impl opcua::types::MessageInfo for ReaderGroupTransportDataType { diff --git a/async-opcua-types/src/generated/types/receive_qos_data_type.rs b/async-opcua-types/src/generated/types/receive_qos_data_type.rs index 95cc9657..ced3a92a 100644 --- a/async-opcua-types/src/generated/types/receive_qos_data_type.rs +++ b/async-opcua-types/src/generated/types/receive_qos_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReceiveQosDataType {} impl opcua::types::MessageInfo for ReceiveQosDataType { diff --git a/async-opcua-types/src/generated/types/receive_qos_priority_data_type.rs b/async-opcua-types/src/generated/types/receive_qos_priority_data_type.rs index 77d8741f..f33f4bdd 100644 --- a/async-opcua-types/src/generated/types/receive_qos_priority_data_type.rs +++ b/async-opcua-types/src/generated/types/receive_qos_priority_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReceiveQosPriorityDataType { pub priority_label: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/redundant_server_data_type.rs b/async-opcua-types/src/generated/types/redundant_server_data_type.rs index 978ed5e1..a165a5de 100644 --- a/async-opcua-types/src/generated/types/redundant_server_data_type.rs +++ b/async-opcua-types/src/generated/types/redundant_server_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RedundantServerDataType { pub server_id: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/reference_description.rs b/async-opcua-types/src/generated/types/reference_description.rs index 0666b822..08029686 100644 --- a/async-opcua-types/src/generated/types/reference_description.rs +++ b/async-opcua-types/src/generated/types/reference_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReferenceDescription { pub reference_type_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/reference_description_data_type.rs b/async-opcua-types/src/generated/types/reference_description_data_type.rs index 00053724..fb707eea 100644 --- a/async-opcua-types/src/generated/types/reference_description_data_type.rs +++ b/async-opcua-types/src/generated/types/reference_description_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReferenceDescriptionDataType { pub source_node: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/reference_list_entry_data_type.rs b/async-opcua-types/src/generated/types/reference_list_entry_data_type.rs index f305d61a..64db3790 100644 --- a/async-opcua-types/src/generated/types/reference_list_entry_data_type.rs +++ b/async-opcua-types/src/generated/types/reference_list_entry_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReferenceListEntryDataType { pub reference_type: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/reference_type_attributes.rs b/async-opcua-types/src/generated/types/reference_type_attributes.rs index 15c06afc..421d35e8 100644 --- a/async-opcua-types/src/generated/types/reference_type_attributes.rs +++ b/async-opcua-types/src/generated/types/reference_type_attributes.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ReferenceTypeAttributes { pub specified_attributes: u32, diff --git a/async-opcua-types/src/generated/types/register_nodes_request.rs b/async-opcua-types/src/generated/types/register_nodes_request.rs index 1eb8de84..3dfe54d9 100644 --- a/async-opcua-types/src/generated/types/register_nodes_request.rs +++ b/async-opcua-types/src/generated/types/register_nodes_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RegisterNodesRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/register_nodes_response.rs b/async-opcua-types/src/generated/types/register_nodes_response.rs index d0f6145e..ad923a90 100644 --- a/async-opcua-types/src/generated/types/register_nodes_response.rs +++ b/async-opcua-types/src/generated/types/register_nodes_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RegisterNodesResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/register_server_2_request.rs b/async-opcua-types/src/generated/types/register_server_2_request.rs index a6017900..475d042c 100644 --- a/async-opcua-types/src/generated/types/register_server_2_request.rs +++ b/async-opcua-types/src/generated/types/register_server_2_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RegisterServer2Request { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/register_server_2_response.rs b/async-opcua-types/src/generated/types/register_server_2_response.rs index 75f8e9af..139ad77b 100644 --- a/async-opcua-types/src/generated/types/register_server_2_response.rs +++ b/async-opcua-types/src/generated/types/register_server_2_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RegisterServer2Response { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/register_server_request.rs b/async-opcua-types/src/generated/types/register_server_request.rs index e9bdd0f6..5f65a473 100644 --- a/async-opcua-types/src/generated/types/register_server_request.rs +++ b/async-opcua-types/src/generated/types/register_server_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RegisterServerRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/register_server_response.rs b/async-opcua-types/src/generated/types/register_server_response.rs index 7e5bf1bb..a5b14382 100644 --- a/async-opcua-types/src/generated/types/register_server_response.rs +++ b/async-opcua-types/src/generated/types/register_server_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RegisterServerResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/registered_server.rs b/async-opcua-types/src/generated/types/registered_server.rs index ccd9df26..19137a57 100644 --- a/async-opcua-types/src/generated/types/registered_server.rs +++ b/async-opcua-types/src/generated/types/registered_server.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RegisteredServer { pub server_uri: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/relative_path.rs b/async-opcua-types/src/generated/types/relative_path.rs index b8ee13f7..38dbf252 100644 --- a/async-opcua-types/src/generated/types/relative_path.rs +++ b/async-opcua-types/src/generated/types/relative_path.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RelativePath { pub elements: Option>, diff --git a/async-opcua-types/src/generated/types/relative_path_element.rs b/async-opcua-types/src/generated/types/relative_path_element.rs index 39616a9b..8a7c3aa8 100644 --- a/async-opcua-types/src/generated/types/relative_path_element.rs +++ b/async-opcua-types/src/generated/types/relative_path_element.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RelativePathElement { pub reference_type_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/republish_request.rs b/async-opcua-types/src/generated/types/republish_request.rs index 6aaee63c..89c76d5a 100644 --- a/async-opcua-types/src/generated/types/republish_request.rs +++ b/async-opcua-types/src/generated/types/republish_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RepublishRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/republish_response.rs b/async-opcua-types/src/generated/types/republish_response.rs index 78418e87..05f84e6e 100644 --- a/async-opcua-types/src/generated/types/republish_response.rs +++ b/async-opcua-types/src/generated/types/republish_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RepublishResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/role_permission_type.rs b/async-opcua-types/src/generated/types/role_permission_type.rs index 7ddf357e..ad4daa5d 100644 --- a/async-opcua-types/src/generated/types/role_permission_type.rs +++ b/async-opcua-types/src/generated/types/role_permission_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct RolePermissionType { pub role_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/sampling_interval_diagnostics_data_type.rs b/async-opcua-types/src/generated/types/sampling_interval_diagnostics_data_type.rs index e9b1502b..fd3541a3 100644 --- a/async-opcua-types/src/generated/types/sampling_interval_diagnostics_data_type.rs +++ b/async-opcua-types/src/generated/types/sampling_interval_diagnostics_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SamplingIntervalDiagnosticsDataType { pub sampling_interval: f64, diff --git a/async-opcua-types/src/generated/types/security_group_data_type.rs b/async-opcua-types/src/generated/types/security_group_data_type.rs index 10ce0d7f..1558469e 100644 --- a/async-opcua-types/src/generated/types/security_group_data_type.rs +++ b/async-opcua-types/src/generated/types/security_group_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SecurityGroupDataType { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/semantic_change_structure_data_type.rs b/async-opcua-types/src/generated/types/semantic_change_structure_data_type.rs index 7670a092..4a7bd66d 100644 --- a/async-opcua-types/src/generated/types/semantic_change_structure_data_type.rs +++ b/async-opcua-types/src/generated/types/semantic_change_structure_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SemanticChangeStructureDataType { pub affected: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/server_diagnostics_summary_data_type.rs b/async-opcua-types/src/generated/types/server_diagnostics_summary_data_type.rs index 20bc3d06..ccd2b8b7 100644 --- a/async-opcua-types/src/generated/types/server_diagnostics_summary_data_type.rs +++ b/async-opcua-types/src/generated/types/server_diagnostics_summary_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ServerDiagnosticsSummaryDataType { pub server_view_count: u32, diff --git a/async-opcua-types/src/generated/types/server_on_network.rs b/async-opcua-types/src/generated/types/server_on_network.rs index 5448ea3d..39767033 100644 --- a/async-opcua-types/src/generated/types/server_on_network.rs +++ b/async-opcua-types/src/generated/types/server_on_network.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ServerOnNetwork { pub record_id: u32, diff --git a/async-opcua-types/src/generated/types/server_status_data_type.rs b/async-opcua-types/src/generated/types/server_status_data_type.rs index 65286cb8..78295f02 100644 --- a/async-opcua-types/src/generated/types/server_status_data_type.rs +++ b/async-opcua-types/src/generated/types/server_status_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ServerStatusDataType { pub start_time: opcua::types::date_time::DateTime, diff --git a/async-opcua-types/src/generated/types/service_counter_data_type.rs b/async-opcua-types/src/generated/types/service_counter_data_type.rs index 8a30cdaf..4d277daa 100644 --- a/async-opcua-types/src/generated/types/service_counter_data_type.rs +++ b/async-opcua-types/src/generated/types/service_counter_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ServiceCounterDataType { pub total_count: u32, diff --git a/async-opcua-types/src/generated/types/service_fault.rs b/async-opcua-types/src/generated/types/service_fault.rs index 97c8e130..a1dc0465 100644 --- a/async-opcua-types/src/generated/types/service_fault.rs +++ b/async-opcua-types/src/generated/types/service_fault.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ServiceFault { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/session_diagnostics_data_type.rs b/async-opcua-types/src/generated/types/session_diagnostics_data_type.rs index 6846da40..11174480 100644 --- a/async-opcua-types/src/generated/types/session_diagnostics_data_type.rs +++ b/async-opcua-types/src/generated/types/session_diagnostics_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SessionDiagnosticsDataType { pub session_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/session_security_diagnostics_data_type.rs b/async-opcua-types/src/generated/types/session_security_diagnostics_data_type.rs index f9fb6f39..428b30f4 100644 --- a/async-opcua-types/src/generated/types/session_security_diagnostics_data_type.rs +++ b/async-opcua-types/src/generated/types/session_security_diagnostics_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SessionSecurityDiagnosticsDataType { pub session_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/sessionless_invoke_request_type.rs b/async-opcua-types/src/generated/types/sessionless_invoke_request_type.rs index faedd844..bdef18e3 100644 --- a/async-opcua-types/src/generated/types/sessionless_invoke_request_type.rs +++ b/async-opcua-types/src/generated/types/sessionless_invoke_request_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SessionlessInvokeRequestType { pub uris_version: u32, diff --git a/async-opcua-types/src/generated/types/sessionless_invoke_response_type.rs b/async-opcua-types/src/generated/types/sessionless_invoke_response_type.rs index 675db9d6..73f185fe 100644 --- a/async-opcua-types/src/generated/types/sessionless_invoke_response_type.rs +++ b/async-opcua-types/src/generated/types/sessionless_invoke_response_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SessionlessInvokeResponseType { pub namespace_uris: Option>, diff --git a/async-opcua-types/src/generated/types/set_monitoring_mode_request.rs b/async-opcua-types/src/generated/types/set_monitoring_mode_request.rs index 7acb1e1c..ef9230e7 100644 --- a/async-opcua-types/src/generated/types/set_monitoring_mode_request.rs +++ b/async-opcua-types/src/generated/types/set_monitoring_mode_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SetMonitoringModeRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/set_monitoring_mode_response.rs b/async-opcua-types/src/generated/types/set_monitoring_mode_response.rs index 048e2222..02d536b7 100644 --- a/async-opcua-types/src/generated/types/set_monitoring_mode_response.rs +++ b/async-opcua-types/src/generated/types/set_monitoring_mode_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SetMonitoringModeResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/set_publishing_mode_request.rs b/async-opcua-types/src/generated/types/set_publishing_mode_request.rs index 48217dda..112fb671 100644 --- a/async-opcua-types/src/generated/types/set_publishing_mode_request.rs +++ b/async-opcua-types/src/generated/types/set_publishing_mode_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SetPublishingModeRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/set_publishing_mode_response.rs b/async-opcua-types/src/generated/types/set_publishing_mode_response.rs index 447e16ac..1750a16d 100644 --- a/async-opcua-types/src/generated/types/set_publishing_mode_response.rs +++ b/async-opcua-types/src/generated/types/set_publishing_mode_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SetPublishingModeResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/set_triggering_request.rs b/async-opcua-types/src/generated/types/set_triggering_request.rs index 4aa59530..8e95491b 100644 --- a/async-opcua-types/src/generated/types/set_triggering_request.rs +++ b/async-opcua-types/src/generated/types/set_triggering_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SetTriggeringRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/set_triggering_response.rs b/async-opcua-types/src/generated/types/set_triggering_response.rs index 6a3ddcbf..030906b3 100644 --- a/async-opcua-types/src/generated/types/set_triggering_response.rs +++ b/async-opcua-types/src/generated/types/set_triggering_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SetTriggeringResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/signature_data.rs b/async-opcua-types/src/generated/types/signature_data.rs index d0d2b79a..b7815a83 100644 --- a/async-opcua-types/src/generated/types/signature_data.rs +++ b/async-opcua-types/src/generated/types/signature_data.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SignatureData { pub algorithm: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/signed_software_certificate.rs b/async-opcua-types/src/generated/types/signed_software_certificate.rs index 33a3dcca..6da4cf8e 100644 --- a/async-opcua-types/src/generated/types/signed_software_certificate.rs +++ b/async-opcua-types/src/generated/types/signed_software_certificate.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SignedSoftwareCertificate { pub certificate_data: opcua::types::byte_string::ByteString, diff --git a/async-opcua-types/src/generated/types/simple_attribute_operand.rs b/async-opcua-types/src/generated/types/simple_attribute_operand.rs index f03d4273..f2770d44 100644 --- a/async-opcua-types/src/generated/types/simple_attribute_operand.rs +++ b/async-opcua-types/src/generated/types/simple_attribute_operand.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SimpleAttributeOperand { pub type_definition_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/simple_type_description.rs b/async-opcua-types/src/generated/types/simple_type_description.rs index 5fc5e71c..b06a4ad1 100644 --- a/async-opcua-types/src/generated/types/simple_type_description.rs +++ b/async-opcua-types/src/generated/types/simple_type_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SimpleTypeDescription { pub data_type_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/standalone_subscribed_data_set_data_type.rs b/async-opcua-types/src/generated/types/standalone_subscribed_data_set_data_type.rs index f63c5c55..ff2e5dee 100644 --- a/async-opcua-types/src/generated/types/standalone_subscribed_data_set_data_type.rs +++ b/async-opcua-types/src/generated/types/standalone_subscribed_data_set_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct StandaloneSubscribedDataSetDataType { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/standalone_subscribed_data_set_ref_data_type.rs b/async-opcua-types/src/generated/types/standalone_subscribed_data_set_ref_data_type.rs index 7cb684b7..63b59291 100644 --- a/async-opcua-types/src/generated/types/standalone_subscribed_data_set_ref_data_type.rs +++ b/async-opcua-types/src/generated/types/standalone_subscribed_data_set_ref_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct StandaloneSubscribedDataSetRefDataType { pub data_set_name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/status_change_notification.rs b/async-opcua-types/src/generated/types/status_change_notification.rs index 9a472aff..415e47ec 100644 --- a/async-opcua-types/src/generated/types/status_change_notification.rs +++ b/async-opcua-types/src/generated/types/status_change_notification.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct StatusChangeNotification { pub status: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/status_result.rs b/async-opcua-types/src/generated/types/status_result.rs index 358e8243..0a6403b3 100644 --- a/async-opcua-types/src/generated/types/status_result.rs +++ b/async-opcua-types/src/generated/types/status_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct StatusResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/structure_definition.rs b/async-opcua-types/src/generated/types/structure_definition.rs index dfa2d4e6..27788069 100644 --- a/async-opcua-types/src/generated/types/structure_definition.rs +++ b/async-opcua-types/src/generated/types/structure_definition.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct StructureDefinition { pub default_encoding_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/structure_description.rs b/async-opcua-types/src/generated/types/structure_description.rs index 65d063d6..357d7ed2 100644 --- a/async-opcua-types/src/generated/types/structure_description.rs +++ b/async-opcua-types/src/generated/types/structure_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct StructureDescription { pub data_type_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/structure_field.rs b/async-opcua-types/src/generated/types/structure_field.rs index 358f5e11..f48c2c55 100644 --- a/async-opcua-types/src/generated/types/structure_field.rs +++ b/async-opcua-types/src/generated/types/structure_field.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct StructureField { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/subscribed_data_set_data_type.rs b/async-opcua-types/src/generated/types/subscribed_data_set_data_type.rs index f93341b4..976087cb 100644 --- a/async-opcua-types/src/generated/types/subscribed_data_set_data_type.rs +++ b/async-opcua-types/src/generated/types/subscribed_data_set_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SubscribedDataSetDataType {} impl opcua::types::MessageInfo for SubscribedDataSetDataType { diff --git a/async-opcua-types/src/generated/types/subscribed_data_set_mirror_data_type.rs b/async-opcua-types/src/generated/types/subscribed_data_set_mirror_data_type.rs index 16f2842c..d1c80d99 100644 --- a/async-opcua-types/src/generated/types/subscribed_data_set_mirror_data_type.rs +++ b/async-opcua-types/src/generated/types/subscribed_data_set_mirror_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SubscribedDataSetMirrorDataType { pub parent_node_name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/subscription_acknowledgement.rs b/async-opcua-types/src/generated/types/subscription_acknowledgement.rs index c88b83a4..bd01accd 100644 --- a/async-opcua-types/src/generated/types/subscription_acknowledgement.rs +++ b/async-opcua-types/src/generated/types/subscription_acknowledgement.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SubscriptionAcknowledgement { pub subscription_id: u32, diff --git a/async-opcua-types/src/generated/types/subscription_diagnostics_data_type.rs b/async-opcua-types/src/generated/types/subscription_diagnostics_data_type.rs index 5bea54db..006d9522 100644 --- a/async-opcua-types/src/generated/types/subscription_diagnostics_data_type.rs +++ b/async-opcua-types/src/generated/types/subscription_diagnostics_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct SubscriptionDiagnosticsDataType { pub session_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/target_variables_data_type.rs b/async-opcua-types/src/generated/types/target_variables_data_type.rs index e04c7e6f..a1dbc99e 100644 --- a/async-opcua-types/src/generated/types/target_variables_data_type.rs +++ b/async-opcua-types/src/generated/types/target_variables_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TargetVariablesDataType { pub target_variables: Option>, diff --git a/async-opcua-types/src/generated/types/three_d_cartesian_coordinates.rs b/async-opcua-types/src/generated/types/three_d_cartesian_coordinates.rs index 6f66d756..5b90281d 100644 --- a/async-opcua-types/src/generated/types/three_d_cartesian_coordinates.rs +++ b/async-opcua-types/src/generated/types/three_d_cartesian_coordinates.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ThreeDCartesianCoordinates { pub x: f64, diff --git a/async-opcua-types/src/generated/types/three_d_frame.rs b/async-opcua-types/src/generated/types/three_d_frame.rs index 0b61c064..250f5d80 100644 --- a/async-opcua-types/src/generated/types/three_d_frame.rs +++ b/async-opcua-types/src/generated/types/three_d_frame.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ThreeDFrame { pub cartesian_coordinates: super::three_d_cartesian_coordinates::ThreeDCartesianCoordinates, diff --git a/async-opcua-types/src/generated/types/three_d_orientation.rs b/async-opcua-types/src/generated/types/three_d_orientation.rs index 87e9eaa5..a4b23383 100644 --- a/async-opcua-types/src/generated/types/three_d_orientation.rs +++ b/async-opcua-types/src/generated/types/three_d_orientation.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ThreeDOrientation { pub a: f64, diff --git a/async-opcua-types/src/generated/types/three_d_vector.rs b/async-opcua-types/src/generated/types/three_d_vector.rs index dd56c854..ab89a73f 100644 --- a/async-opcua-types/src/generated/types/three_d_vector.rs +++ b/async-opcua-types/src/generated/types/three_d_vector.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ThreeDVector { pub x: f64, diff --git a/async-opcua-types/src/generated/types/time_zone_data_type.rs b/async-opcua-types/src/generated/types/time_zone_data_type.rs index f92c505d..a398c787 100644 --- a/async-opcua-types/src/generated/types/time_zone_data_type.rs +++ b/async-opcua-types/src/generated/types/time_zone_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TimeZoneDataType { pub offset: i16, diff --git a/async-opcua-types/src/generated/types/transaction_error_type.rs b/async-opcua-types/src/generated/types/transaction_error_type.rs index 250fe360..f083f01b 100644 --- a/async-opcua-types/src/generated/types/transaction_error_type.rs +++ b/async-opcua-types/src/generated/types/transaction_error_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TransactionErrorType { pub target_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/transfer_result.rs b/async-opcua-types/src/generated/types/transfer_result.rs index 9be7a316..bd37081f 100644 --- a/async-opcua-types/src/generated/types/transfer_result.rs +++ b/async-opcua-types/src/generated/types/transfer_result.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TransferResult { pub status_code: opcua::types::status_code::StatusCode, diff --git a/async-opcua-types/src/generated/types/transfer_subscriptions_request.rs b/async-opcua-types/src/generated/types/transfer_subscriptions_request.rs index 9c84364e..c1ac882a 100644 --- a/async-opcua-types/src/generated/types/transfer_subscriptions_request.rs +++ b/async-opcua-types/src/generated/types/transfer_subscriptions_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TransferSubscriptionsRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/transfer_subscriptions_response.rs b/async-opcua-types/src/generated/types/transfer_subscriptions_response.rs index ed0d64bf..bb41a133 100644 --- a/async-opcua-types/src/generated/types/transfer_subscriptions_response.rs +++ b/async-opcua-types/src/generated/types/transfer_subscriptions_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TransferSubscriptionsResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/translate_browse_paths_to_node_ids_request.rs b/async-opcua-types/src/generated/types/translate_browse_paths_to_node_ids_request.rs index 77a54c64..fe0ac562 100644 --- a/async-opcua-types/src/generated/types/translate_browse_paths_to_node_ids_request.rs +++ b/async-opcua-types/src/generated/types/translate_browse_paths_to_node_ids_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TranslateBrowsePathsToNodeIdsRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/translate_browse_paths_to_node_ids_response.rs b/async-opcua-types/src/generated/types/translate_browse_paths_to_node_ids_response.rs index 18460e4b..a7fb0c51 100644 --- a/async-opcua-types/src/generated/types/translate_browse_paths_to_node_ids_response.rs +++ b/async-opcua-types/src/generated/types/translate_browse_paths_to_node_ids_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TranslateBrowsePathsToNodeIdsResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/transmit_qos_data_type.rs b/async-opcua-types/src/generated/types/transmit_qos_data_type.rs index c87b9d37..860301dc 100644 --- a/async-opcua-types/src/generated/types/transmit_qos_data_type.rs +++ b/async-opcua-types/src/generated/types/transmit_qos_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TransmitQosDataType {} impl opcua::types::MessageInfo for TransmitQosDataType { diff --git a/async-opcua-types/src/generated/types/transmit_qos_priority_data_type.rs b/async-opcua-types/src/generated/types/transmit_qos_priority_data_type.rs index 06a9b2ae..ead02426 100644 --- a/async-opcua-types/src/generated/types/transmit_qos_priority_data_type.rs +++ b/async-opcua-types/src/generated/types/transmit_qos_priority_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TransmitQosPriorityDataType { pub priority_label: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/trust_list_data_type.rs b/async-opcua-types/src/generated/types/trust_list_data_type.rs index b90b794f..68393ea6 100644 --- a/async-opcua-types/src/generated/types/trust_list_data_type.rs +++ b/async-opcua-types/src/generated/types/trust_list_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct TrustListDataType { pub specified_lists: u32, diff --git a/async-opcua-types/src/generated/types/ua_binary_file_data_type.rs b/async-opcua-types/src/generated/types/ua_binary_file_data_type.rs index b2639974..e98615ea 100644 --- a/async-opcua-types/src/generated/types/ua_binary_file_data_type.rs +++ b/async-opcua-types/src/generated/types/ua_binary_file_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UABinaryFileDataType { pub namespaces: Option>, diff --git a/async-opcua-types/src/generated/types/uadp_data_set_reader_message_data_type.rs b/async-opcua-types/src/generated/types/uadp_data_set_reader_message_data_type.rs index f3f216b6..86f79d58 100644 --- a/async-opcua-types/src/generated/types/uadp_data_set_reader_message_data_type.rs +++ b/async-opcua-types/src/generated/types/uadp_data_set_reader_message_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UadpDataSetReaderMessageDataType { pub group_version: u32, diff --git a/async-opcua-types/src/generated/types/uadp_data_set_writer_message_data_type.rs b/async-opcua-types/src/generated/types/uadp_data_set_writer_message_data_type.rs index a273b4e0..ac1f16e5 100644 --- a/async-opcua-types/src/generated/types/uadp_data_set_writer_message_data_type.rs +++ b/async-opcua-types/src/generated/types/uadp_data_set_writer_message_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UadpDataSetWriterMessageDataType { pub data_set_message_content_mask: super::enums::UadpDataSetMessageContentMask, diff --git a/async-opcua-types/src/generated/types/uadp_writer_group_message_data_type.rs b/async-opcua-types/src/generated/types/uadp_writer_group_message_data_type.rs index f181a6f6..d3bf76d1 100644 --- a/async-opcua-types/src/generated/types/uadp_writer_group_message_data_type.rs +++ b/async-opcua-types/src/generated/types/uadp_writer_group_message_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UadpWriterGroupMessageDataType { pub group_version: u32, diff --git a/async-opcua-types/src/generated/types/unregister_nodes_request.rs b/async-opcua-types/src/generated/types/unregister_nodes_request.rs index cbbb76e9..65b19394 100644 --- a/async-opcua-types/src/generated/types/unregister_nodes_request.rs +++ b/async-opcua-types/src/generated/types/unregister_nodes_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UnregisterNodesRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/unregister_nodes_response.rs b/async-opcua-types/src/generated/types/unregister_nodes_response.rs index b21c0282..d8723519 100644 --- a/async-opcua-types/src/generated/types/unregister_nodes_response.rs +++ b/async-opcua-types/src/generated/types/unregister_nodes_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UnregisterNodesResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/unsigned_rational_number.rs b/async-opcua-types/src/generated/types/unsigned_rational_number.rs index 9be79b07..c1a6797e 100644 --- a/async-opcua-types/src/generated/types/unsigned_rational_number.rs +++ b/async-opcua-types/src/generated/types/unsigned_rational_number.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UnsignedRationalNumber { pub numerator: u32, diff --git a/async-opcua-types/src/generated/types/update_data_details.rs b/async-opcua-types/src/generated/types/update_data_details.rs index a9b70f9b..8f49ac46 100644 --- a/async-opcua-types/src/generated/types/update_data_details.rs +++ b/async-opcua-types/src/generated/types/update_data_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] pub struct UpdateDataDetails { pub node_id: opcua::types::node_id::NodeId, pub perform_insert_replace: super::enums::PerformUpdateType, diff --git a/async-opcua-types/src/generated/types/update_event_details.rs b/async-opcua-types/src/generated/types/update_event_details.rs index ecd1a2d4..7894f480 100644 --- a/async-opcua-types/src/generated/types/update_event_details.rs +++ b/async-opcua-types/src/generated/types/update_event_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] pub struct UpdateEventDetails { pub node_id: opcua::types::node_id::NodeId, pub perform_insert_replace: super::enums::PerformUpdateType, diff --git a/async-opcua-types/src/generated/types/update_structure_data_details.rs b/async-opcua-types/src/generated/types/update_structure_data_details.rs index 2fc40a6e..cf45ff27 100644 --- a/async-opcua-types/src/generated/types/update_structure_data_details.rs +++ b/async-opcua-types/src/generated/types/update_structure_data_details.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] pub struct UpdateStructureDataDetails { pub node_id: opcua::types::node_id::NodeId, pub perform_insert_replace: super::enums::PerformUpdateType, diff --git a/async-opcua-types/src/generated/types/user_identity_token.rs b/async-opcua-types/src/generated/types/user_identity_token.rs index c93d5db7..5d71a2fa 100644 --- a/async-opcua-types/src/generated/types/user_identity_token.rs +++ b/async-opcua-types/src/generated/types/user_identity_token.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UserIdentityToken { pub policy_id: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/user_management_data_type.rs b/async-opcua-types/src/generated/types/user_management_data_type.rs index 528887bb..50841149 100644 --- a/async-opcua-types/src/generated/types/user_management_data_type.rs +++ b/async-opcua-types/src/generated/types/user_management_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UserManagementDataType { pub user_name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/user_name_identity_token.rs b/async-opcua-types/src/generated/types/user_name_identity_token.rs index 6106b385..719d28e4 100644 --- a/async-opcua-types/src/generated/types/user_name_identity_token.rs +++ b/async-opcua-types/src/generated/types/user_name_identity_token.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UserNameIdentityToken { pub policy_id: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/user_token_policy.rs b/async-opcua-types/src/generated/types/user_token_policy.rs index 95dfccb5..c3cd87c9 100644 --- a/async-opcua-types/src/generated/types/user_token_policy.rs +++ b/async-opcua-types/src/generated/types/user_token_policy.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct UserTokenPolicy { pub policy_id: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/variable_attributes.rs b/async-opcua-types/src/generated/types/variable_attributes.rs index 07fa264d..fbda6f22 100644 --- a/async-opcua-types/src/generated/types/variable_attributes.rs +++ b/async-opcua-types/src/generated/types/variable_attributes.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct VariableAttributes { pub specified_attributes: u32, diff --git a/async-opcua-types/src/generated/types/variable_type_attributes.rs b/async-opcua-types/src/generated/types/variable_type_attributes.rs index 0dd4d0d7..7961f4eb 100644 --- a/async-opcua-types/src/generated/types/variable_type_attributes.rs +++ b/async-opcua-types/src/generated/types/variable_type_attributes.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct VariableTypeAttributes { pub specified_attributes: u32, diff --git a/async-opcua-types/src/generated/types/vector.rs b/async-opcua-types/src/generated/types/vector.rs index ca2f41ab..87fd6eed 100644 --- a/async-opcua-types/src/generated/types/vector.rs +++ b/async-opcua-types/src/generated/types/vector.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct Vector {} impl opcua::types::MessageInfo for Vector { diff --git a/async-opcua-types/src/generated/types/view_attributes.rs b/async-opcua-types/src/generated/types/view_attributes.rs index 9876c4b3..67611443 100644 --- a/async-opcua-types/src/generated/types/view_attributes.rs +++ b/async-opcua-types/src/generated/types/view_attributes.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ViewAttributes { pub specified_attributes: u32, diff --git a/async-opcua-types/src/generated/types/view_description.rs b/async-opcua-types/src/generated/types/view_description.rs index 5641c3fb..9d24c01d 100644 --- a/async-opcua-types/src/generated/types/view_description.rs +++ b/async-opcua-types/src/generated/types/view_description.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ViewDescription { pub view_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/write_request.rs b/async-opcua-types/src/generated/types/write_request.rs index 354d9ba6..05f30315 100644 --- a/async-opcua-types/src/generated/types/write_request.rs +++ b/async-opcua-types/src/generated/types/write_request.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct WriteRequest { pub request_header: opcua::types::request_header::RequestHeader, diff --git a/async-opcua-types/src/generated/types/write_response.rs b/async-opcua-types/src/generated/types/write_response.rs index c2ca0ea5..cc7dac42 100644 --- a/async-opcua-types/src/generated/types/write_response.rs +++ b/async-opcua-types/src/generated/types/write_response.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct WriteResponse { pub response_header: opcua::types::response_header::ResponseHeader, diff --git a/async-opcua-types/src/generated/types/write_value.rs b/async-opcua-types/src/generated/types/write_value.rs index b91f829f..d3f61af4 100644 --- a/async-opcua-types/src/generated/types/write_value.rs +++ b/async-opcua-types/src/generated/types/write_value.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct WriteValue { pub node_id: opcua::types::node_id::NodeId, diff --git a/async-opcua-types/src/generated/types/writer_group_data_type.rs b/async-opcua-types/src/generated/types/writer_group_data_type.rs index b1eb2b2a..ebb3fd8e 100644 --- a/async-opcua-types/src/generated/types/writer_group_data_type.rs +++ b/async-opcua-types/src/generated/types/writer_group_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct WriterGroupDataType { pub name: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/writer_group_message_data_type.rs b/async-opcua-types/src/generated/types/writer_group_message_data_type.rs index 4451ead7..cc837439 100644 --- a/async-opcua-types/src/generated/types/writer_group_message_data_type.rs +++ b/async-opcua-types/src/generated/types/writer_group_message_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct WriterGroupMessageDataType {} impl opcua::types::MessageInfo for WriterGroupMessageDataType { diff --git a/async-opcua-types/src/generated/types/writer_group_transport_data_type.rs b/async-opcua-types/src/generated/types/writer_group_transport_data_type.rs index 7e36b82a..3d3a34d9 100644 --- a/async-opcua-types/src/generated/types/writer_group_transport_data_type.rs +++ b/async-opcua-types/src/generated/types/writer_group_transport_data_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct WriterGroupTransportDataType {} impl opcua::types::MessageInfo for WriterGroupTransportDataType { diff --git a/async-opcua-types/src/generated/types/x_509_identity_token.rs b/async-opcua-types/src/generated/types/x_509_identity_token.rs index 3154cf35..0dd9d7ef 100644 --- a/async-opcua-types/src/generated/types/x_509_identity_token.rs +++ b/async-opcua-types/src/generated/types/x_509_identity_token.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct X509IdentityToken { pub policy_id: opcua::types::string::UAString, diff --git a/async-opcua-types/src/generated/types/xv_type.rs b/async-opcua-types/src/generated/types/xv_type.rs index ce0a01ac..88aaa382 100644 --- a/async-opcua-types/src/generated/types/xv_type.rs +++ b/async-opcua-types/src/generated/types/xv_type.rs @@ -14,7 +14,14 @@ mod opcua { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct XVType { pub x: f64, diff --git a/async-opcua-types/src/guid.rs b/async-opcua-types/src/guid.rs index d478ec4e..7bacabfe 100644 --- a/async-opcua-types/src/guid.rs +++ b/async-opcua-types/src/guid.rs @@ -67,6 +67,10 @@ mod xml { use super::Guid; + impl XmlType for Guid { + const TAG: &'static str = "Guid"; + } + impl XmlEncodable for Guid { fn encode( &self, diff --git a/async-opcua-types/src/lib.rs b/async-opcua-types/src/lib.rs index f06fec03..368fcc15 100644 --- a/async-opcua-types/src/lib.rs +++ b/async-opcua-types/src/lib.rs @@ -279,9 +279,10 @@ pub mod xml; pub use opcua_macros::FromXml; #[cfg(feature = "json")] -pub use opcua_macros::JsonDecodable; -#[cfg(feature = "json")] -pub use opcua_macros::JsonEncodable; +pub use opcua_macros::{JsonDecodable, JsonEncodable}; + +#[cfg(feature = "xml")] +pub use opcua_macros::{XmlDecodable, XmlEncodable, XmlType}; pub use opcua_macros::BinaryDecodable; pub use opcua_macros::BinaryEncodable; diff --git a/async-opcua-types/src/localized_text.rs b/async-opcua-types/src/localized_text.rs index 06bb25eb..614440a5 100644 --- a/async-opcua-types/src/localized_text.rs +++ b/async-opcua-types/src/localized_text.rs @@ -23,6 +23,10 @@ mod opcua { feature = "json", derive(opcua_macros::JsonEncodable, opcua_macros::JsonDecodable) )] +#[cfg_attr( + feature = "xml", + derive(crate::XmlEncodable, crate::XmlDecodable, crate::XmlType) +)] pub struct LocalizedText { /// The locale. Omitted from stream if null or empty pub locale: UAString, diff --git a/async-opcua-types/src/node_id.rs b/async-opcua-types/src/node_id.rs index 2b49111c..eda0a659 100644 --- a/async-opcua-types/src/node_id.rs +++ b/async-opcua-types/src/node_id.rs @@ -337,14 +337,24 @@ mod xml { use super::NodeId; + impl XmlType for NodeId { + const TAG: &'static str = "NodeId"; + } + impl XmlEncodable for NodeId { fn encode( &self, writer: &mut XmlStreamWriter<&mut dyn Write>, ctx: &crate::xml::Context<'_>, ) -> Result<(), Error> { - let self_str = self.to_string(); - let val = ctx.resolve_alias(&self_str); + let namespace_index = ctx.resolve_namespace_index_inverse(self.namespace)?; + + let self_str = if namespace_index > 0 { + format!("ns={};{}", namespace_index, self.identifier) + } else { + self.identifier.to_string() + }; + let val = ctx.resolve_alias_inverse(&self_str); writer.encode_child("Identifier", val, ctx) } } @@ -363,8 +373,10 @@ mod xml { }; let val_str = context.resolve_alias(&val); - NodeId::from_str(val_str) - .map_err(|e| Error::new(e, format!("Invalid node ID: {val_str}"))) + let mut id = NodeId::from_str(val_str) + .map_err(|e| Error::new(e, format!("Invalid node ID: {val_str}")))?; + id.namespace = context.resolve_namespace_index(id.namespace)?; + Ok(id) } } } diff --git a/async-opcua-types/src/qualified_name.rs b/async-opcua-types/src/qualified_name.rs index c054bfde..c88048a3 100644 --- a/async-opcua-types/src/qualified_name.rs +++ b/async-opcua-types/src/qualified_name.rs @@ -3,11 +3,19 @@ // Copyright (C) 2017-2024 Adam Lock //! Contains the definition of `QualifiedName`. -use std::io::{Read, Write}; +use std::{ + fmt::Display, + io::{Read, Write}, + sync::LazyLock, +}; + +use percent_encoding_rfc3986::percent_decode_str; +use regex::Regex; use crate::{ encoding::{BinaryDecodable, BinaryEncodable, EncodingResult}, string::*, + NamespaceMap, }; #[allow(unused)] @@ -31,18 +39,117 @@ mod opcua { /// JSON string unless the NamespaceIndexis 1 or if NamespaceUriis unknown. In these cases, /// the NamespaceIndexis encoded as a JSON number. #[derive(PartialEq, Debug, Clone, Eq, Hash)] -#[cfg_attr( - feature = "json", - derive(opcua_macros::JsonEncodable, opcua_macros::JsonDecodable) -)] pub struct QualifiedName { /// The namespace index - #[cfg_attr(feature = "json", opcua(rename = "Uri"))] pub namespace_index: u16, /// The name. pub name: UAString, } +#[cfg(feature = "xml")] +mod xml { + use crate::{xml::*, UAString}; + + use super::QualifiedName; + + impl XmlType for QualifiedName { + const TAG: &'static str = "QualifiedName"; + } + + impl XmlEncodable for QualifiedName { + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn std::io::Write>, + context: &Context<'_>, + ) -> EncodingResult<()> { + let namespace_index = context.resolve_namespace_index_inverse(self.namespace_index)?; + writer.encode_child("NamespaceIndex", &namespace_index, context)?; + writer.encode_child("Name", &self.name, context)?; + Ok(()) + } + } + + impl XmlDecodable for QualifiedName { + fn decode( + read: &mut XmlStreamReader<&mut dyn std::io::Read>, + context: &Context<'_>, + ) -> Result { + let mut namespace_index = None; + let mut name: Option = None; + + read.iter_children( + |key, stream, ctx| { + match key.as_str() { + "NamespaceIndex" => { + namespace_index = Some(XmlDecodable::decode(stream, ctx)?) + } + "Name" => name = Some(XmlDecodable::decode(stream, ctx)?), + _ => { + stream.skip_value()?; + } + } + Ok(()) + }, + context, + )?; + + let Some(name) = name else { + return Ok(QualifiedName::null()); + }; + + if let Some(namespace_index) = namespace_index { + Ok(QualifiedName { + namespace_index: context.resolve_namespace_index(namespace_index)?, + name, + }) + } else { + Ok(QualifiedName::new(0, name)) + } + } + } +} + +#[cfg(feature = "json")] +mod json { + use super::QualifiedName; + + use crate::json::*; + + // JSON encoding for QualifiedName is special, see 5.3.1.14. + impl JsonEncodable for QualifiedName { + fn encode( + &self, + stream: &mut JsonStreamWriter<&mut dyn std::io::Write>, + _ctx: &crate::Context<'_>, + ) -> crate::EncodingResult<()> { + if self.is_null() { + stream.null_value()?; + return Ok(()); + } + stream.string_value(&self.to_string())?; + Ok(()) + } + + fn is_null_json(&self) -> bool { + self.name.is_null_json() + } + } + + impl JsonDecodable for QualifiedName { + fn decode( + stream: &mut JsonStreamReader<&mut dyn std::io::Read>, + ctx: &Context<'_>, + ) -> crate::EncodingResult { + if matches!(stream.peek()?, ValueType::Null) { + return Ok(QualifiedName::null()); + } + + let raw = stream.next_str()?; + Ok(QualifiedName::parse(raw, ctx.namespaces())) + } + } +} + impl Default for QualifiedName { fn default() -> Self { Self::null() @@ -104,6 +211,19 @@ impl BinaryDecodable for QualifiedName { } } +impl Display for QualifiedName { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + if self.namespace_index > 0 { + write!(f, "{}:{}", self.namespace_index, self.name) + } else { + write!(f, "{}", self.name) + } + } +} + +static NUMERIC_QNAME_REGEX: LazyLock = + LazyLock::new(|| Regex::new(r#"^(\d+):(.*)$"#).unwrap()); + impl QualifiedName { /// Create a new qualified name from namespace index and name. pub fn new(namespace_index: u16, name: T) -> QualifiedName @@ -128,4 +248,36 @@ impl QualifiedName { pub fn is_null(&self) -> bool { self.namespace_index == 0 && self.name.is_null() } + + /// Parse a QualifiedName from a string. + /// Note that QualifiedName parsing is unsolvable. This does a best-effort. + /// If parsing fails, we will capture the string as a name with namespace index 0. + pub fn parse(raw: &str, namespaces: &NamespaceMap) -> QualifiedName { + // First, try parsing the string as a numeric QualifiedName. + if let Some(caps) = NUMERIC_QNAME_REGEX.captures(raw) { + // Ignore errors here, if we fail we fall back on other options. + if let Ok(namespace_index) = caps.get(1).unwrap().as_str().parse::() { + let name = caps.get(2).unwrap().as_str(); + if namespaces + .known_namespaces() + .iter() + .any(|n| n.1 == &namespace_index) + { + return QualifiedName::new(namespace_index, name); + } + } + } + + // Next, see if the string contains a semicolon, and if it does, try treating the first half as a URI. + if let Some((l, r)) = raw.split_once(";") { + if let Ok(l) = percent_decode_str(l) { + if let Some(namespace_index) = namespaces.get_index(l.decode_utf8_lossy().as_ref()) + { + return QualifiedName::new(namespace_index, r); + } + } + } + + QualifiedName::new(0, raw) + } } diff --git a/async-opcua-types/src/request_header.rs b/async-opcua-types/src/request_header.rs index 6d8906a7..3e7670d4 100644 --- a/async-opcua-types/src/request_header.rs +++ b/async-opcua-types/src/request_header.rs @@ -31,7 +31,10 @@ mod opcua { feature = "json", derive(opcua_macros::JsonEncodable, opcua_macros::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(crate::FromXml))] +#[cfg_attr( + feature = "xml", + derive(crate::XmlEncodable, crate::XmlDecodable, crate::XmlType) +)] pub struct RequestHeader { /// The secret Session identifier used to verify that the request is associated with /// the Session. The SessionAuthenticationToken type is defined in 7.31. diff --git a/async-opcua-types/src/response_header.rs b/async-opcua-types/src/response_header.rs index a6411ec9..54c64e45 100644 --- a/async-opcua-types/src/response_header.rs +++ b/async-opcua-types/src/response_header.rs @@ -32,7 +32,10 @@ mod opcua { feature = "json", derive(opcua_macros::JsonEncodable, opcua_macros::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(crate::FromXml))] +#[cfg_attr( + feature = "xml", + derive(crate::XmlEncodable, crate::XmlDecodable, crate::XmlType) +)] pub struct ResponseHeader { /// Response timestamp. pub timestamp: UtcTime, diff --git a/async-opcua-types/src/status_code.rs b/async-opcua-types/src/status_code.rs index ccd87cfb..ab38c21b 100644 --- a/async-opcua-types/src/status_code.rs +++ b/async-opcua-types/src/status_code.rs @@ -51,6 +51,10 @@ mod xml { use super::StatusCode; + impl XmlType for StatusCode { + const TAG: &'static str = "StatusCode"; + } + impl XmlEncodable for StatusCode { fn encode( &self, @@ -175,7 +179,7 @@ impl StatusCode { /// Set the info type, this will clear the info bits if set to NotUsed. #[must_use = "Status code is copied, not modified in place."] pub fn set_info_type(mut self, value: StatusCodeInfoType) -> Self { - self.0 = self.0 & !(1 << 10) | ((value as u32) & 1) << 10; + self.0 = self.0 & !(1 << 10) | (((value as u32) & 1) << 10); // Clear the info bits if we are setting info type to not used. if matches!(value, StatusCodeInfoType::NotUsed) { self.0 &= !INFO_BITS_MASK; diff --git a/async-opcua-types/src/string.rs b/async-opcua-types/src/string.rs index 4de42c2e..3ae97784 100644 --- a/async-opcua-types/src/string.rs +++ b/async-opcua-types/src/string.rs @@ -143,6 +143,10 @@ mod xml { use super::UAString; + impl XmlType for UAString { + const TAG: &'static str = "String"; + } + impl XmlEncodable for UAString { fn encode( &self, diff --git a/async-opcua-types/src/tests/json.rs b/async-opcua-types/src/tests/json.rs index d0059966..3eef67e6 100644 --- a/async-opcua-types/src/tests/json.rs +++ b/async-opcua-types/src/tests/json.rs @@ -287,11 +287,11 @@ fn serialize_localized_text() { fn serialize_qualified_name() { let v = QualifiedName::new(0, "Test"); let json = to_value(&v).unwrap(); - assert_eq!(json, json!({"Name": "Test"})); + assert_eq!(json, json!("Test")); let v = QualifiedName::new(2, "Test"); let json = to_value(&v).unwrap(); - assert_eq!(json, json!({"Uri": 2, "Name": "Test"})); + assert_eq!(json, json!("2:Test")); } /// Serializes and deserializes a variant. The input json should match @@ -545,7 +545,7 @@ fn serialize_variant_qualified_name() { // QualifiedName (20) test_ser_de_variant( Variant::QualifiedName(Box::new(QualifiedName::null())), - json!({"Type": 20, "Body": {}}), + json!({"Type": 20, "Body": null}), ); } diff --git a/async-opcua-types/src/tests/xml.rs b/async-opcua-types/src/tests/xml.rs index bd947758..134ee529 100644 --- a/async-opcua-types/src/tests/xml.rs +++ b/async-opcua-types/src/tests/xml.rs @@ -1,12 +1,14 @@ +use std::io::{Cursor, Read, Write}; use std::str::FromStr; -use opcua_xml::{from_str, XmlElement}; +use opcua_xml::XmlStreamReader; +use crate::xml::{XmlDecodable, XmlEncodable}; use crate::{ - xml::FromXml, Argument, ByteString, DataTypeId, DataValue, DateTime, ExpandedNodeId, + Argument, Array, ByteString, DataTypeId, DataValue, DateTime, EUInformation, ExpandedNodeId, ExtensionObject, Guid, LocalizedText, NodeId, QualifiedName, StatusCode, UAString, Variant, }; -use crate::{Context, ContextOwned, DecodingOptions, EncodingResult, Error}; +use crate::{Context, ContextOwned, DecodingOptions, EncodingResult}; use crate::{NamespaceMap, NodeSetNamespaceMapper}; @@ -24,106 +26,121 @@ fn context<'a>(mapper: &'a NodeSetNamespaceMapper<'a>, owned: &'a ContextOwned) ctx } -fn from_xml_str(data: &str) -> EncodingResult { - let ctx = ContextOwned::new_default(namespaces(), DecodingOptions::default()); - let ctx_ref = ctx.context(); - from_xml_str_ctx(data, &ctx_ref) +fn from_xml_str_ctx(data: &str, ctx: &Context<'_>) -> EncodingResult { + let mut cursor = Cursor::new(data.as_bytes()); + let mut reader = XmlStreamReader::new(&mut cursor as &mut dyn Read); + T::decode(&mut reader, ctx) +} + +fn encode_xml_ctx(data: &T, ctx: &Context<'_>) -> EncodingResult { + let mut buf = Vec::new(); + let mut writer = opcua_xml::XmlStreamWriter::new(&mut buf as &mut dyn Write); + data.encode(&mut writer, ctx)?; + Ok(String::from_utf8(buf).unwrap()) +} + +fn xml_round_trip_ctx( + cmp: &T, + data: &str, + ctx: &Context<'_>, +) { + let decoded = from_xml_str_ctx::(data, ctx).unwrap(); + let encoded = encode_xml_ctx(&decoded, ctx).unwrap(); + println!("{encoded}"); + let decoded2 = from_xml_str_ctx::(&encoded, ctx).unwrap(); + assert_eq!(decoded, decoded2); + assert_eq!(&decoded, cmp); } -fn from_xml_str_ctx(data: &str, ctx: &Context<'_>) -> EncodingResult { - let element: Option = from_str(data).map_err(Error::decoding)?; - let Some(element) = element else { - return Err(Error::decoding("Missing root element")); - }; - T::from_xml(&element, ctx) +fn xml_round_trip( + cmp: &T, + data: &str, +) { + let ctx = ContextOwned::new_default(namespaces(), DecodingOptions::default()); + let ctx_ref = ctx.context(); + xml_round_trip_ctx(cmp, data, &ctx_ref); } #[test] fn from_xml_u8() { - assert_eq!(5u8, from_xml_str::("5").unwrap()); + xml_round_trip(&5u8, "5"); } #[test] fn from_xml_i8() { - assert_eq!(5i8, from_xml_str::("5").unwrap()); + xml_round_trip(&5i8, "5"); } #[test] fn from_xml_u16() { - assert_eq!(5u16, from_xml_str::("5").unwrap()); + xml_round_trip(&5u16, "5"); } #[test] fn from_xml_i16() { - assert_eq!(5i16, from_xml_str::("5").unwrap()); + xml_round_trip(&5i16, "5"); } #[test] fn from_xml_u32() { - assert_eq!(5u32, from_xml_str::("5").unwrap()); + xml_round_trip(&5u32, "5"); } #[test] fn from_xml_i32() { - assert_eq!(5i32, from_xml_str::("5").unwrap()); + xml_round_trip(&5i32, "5"); } #[test] fn from_xml_u64() { - assert_eq!(5u64, from_xml_str::("5").unwrap()); + xml_round_trip(&5u64, "5"); } #[test] fn from_xml_i64() { - assert_eq!(5i64, from_xml_str::("5").unwrap()); + xml_round_trip(&5i64, "5"); } #[test] fn from_xml_f32() { - assert_eq!(5.5f32, from_xml_str::("5.5").unwrap()); + xml_round_trip(&5.5f32, "5.5"); } #[test] fn from_xml_f64() { - assert_eq!(5.5f64, from_xml_str::("5.5").unwrap()); + xml_round_trip(&5.5f64, "5.5"); } #[test] fn from_xml_bool() { - assert!(from_xml_str::("true").unwrap()); - assert!(!from_xml_str::("false").unwrap()); + xml_round_trip(&true, "true"); + xml_round_trip(&false, "false"); } #[test] fn from_xml_uastring() { - assert_eq!( - UAString::from("test string"), - from_xml_str::("test string").unwrap() - ); + xml_round_trip(&UAString::from("test string"), "test string"); } #[test] fn from_xml_localized_text() { - assert_eq!( - LocalizedText::new("en", "Some text"), - from_xml_str("enSome text").unwrap() + xml_round_trip( + &LocalizedText::new("en", "Some text"), + "enSome text", ); } #[test] fn from_xml_guid() { - assert_eq!( - Guid::from_str("f6aae0c0-455f-4285-82a7-d492ea4ef434").unwrap(), - from_xml_str("f6aae0c0-455f-4285-82a7-d492ea4ef434").unwrap() + xml_round_trip( + &Guid::from_str("f6aae0c0-455f-4285-82a7-d492ea4ef434").unwrap(), + "f6aae0c0-455f-4285-82a7-d492ea4ef434", ); } #[test] fn from_xml_node_id() { - assert_eq!( - NodeId::new(0, "test"), - from_xml_str::("s=test").unwrap() - ); + xml_round_trip(&NodeId::new(0, "test"), "s=test"); let mut ns = namespaces(); let ctx_owned = ContextOwned::new_default(ns.clone(), DecodingOptions::default()); ns.add_namespace("opc.tcp://my-server.server"); @@ -131,109 +148,91 @@ fn from_xml_node_id() { mp.add_namespace("opc.tcp://my-server.server", 2); let ctx = context(&mp, &ctx_owned); - assert_eq!( - NodeId::new(1, ByteString::from_base64("aGVsbG8=").unwrap()), - from_xml_str_ctx::( - "ns=2;b=aGVsbG8=", - &ctx - ) - .unwrap() + xml_round_trip_ctx( + &NodeId::new(1, ByteString::from_base64("aGVsbG8=").unwrap()), + "ns=2;b=aGVsbG8=", + &ctx, ); - assert_eq!( - NodeId::new(1, 123), - from_xml_str_ctx::("ns=2;i=123", &ctx) - .unwrap() + xml_round_trip_ctx( + &NodeId::new(1, 123), + "ns=2;i=123", + &ctx, ); - assert_eq!( - NodeId::new( + xml_round_trip_ctx( + &NodeId::new( 1, - Guid::from_str("f6aae0c0-455f-4285-82a7-d492ea4ef434").unwrap() + Guid::from_str("f6aae0c0-455f-4285-82a7-d492ea4ef434").unwrap(), ), - from_xml_str_ctx::( - "ns=2;g=f6aae0c0-455f-4285-82a7-d492ea4ef434", - &ctx - ) - .unwrap() + "ns=2;g=f6aae0c0-455f-4285-82a7-d492ea4ef434", + &ctx, ); } #[test] fn from_xml_expanded_node_id() { - assert_eq!( - ExpandedNodeId::new(NodeId::new(0, "test")), - from_xml_str::("s=test").unwrap() + xml_round_trip( + &ExpandedNodeId::new(NodeId::new(0, "test")), + "s=test", ); } #[test] fn from_xml_status_code() { - assert_eq!( - StatusCode::GoodCallAgain, - from_xml_str::("11075584").unwrap() - ); + xml_round_trip(&StatusCode::GoodCallAgain, "11075584"); } #[test] fn from_xml_extension_object() { - assert_eq!( - ExtensionObject::from_message(Argument { + xml_round_trip( + &ExtensionObject::from_message(Argument { name: "Some name".into(), data_type: DataTypeId::Double.into(), value_rank: 1, array_dimensions: Some(vec![3]), - description: LocalizedText::new("en", "Some desc") + description: LocalizedText::new("en", "Some desc"), }), - from_xml_str::( - r#" - + r#" + i=297 Some name i=11 1 - 3 + 3 en Some desc - - "# - ) - .unwrap() + + "#, ) } #[test] fn from_xml_date_time() { - assert_eq!( - DateTime::from_str("2020-12-24T20:15:01Z").unwrap(), - from_xml_str("2020-12-24T20:15:01+0000").unwrap() + xml_round_trip( + &DateTime::from_str("2020-12-24T20:15:01Z").unwrap(), + "2020-12-24T20:15:01+00:00", ); } #[test] fn from_xml_byte_string() { - assert_eq!( - ByteString::from_base64("aGVsbG8=").unwrap(), - from_xml_str("aGVsbG8=").unwrap() - ); + xml_round_trip(&ByteString::from_base64("aGVsbG8=").unwrap(), "aGVsbG8="); } #[test] fn from_xml_qualified_name() { - assert_eq!( - QualifiedName::new(0, "Some name"), - from_xml_str( - r#" - + xml_round_trip( + &QualifiedName::new(0, "Some name"), + r#" + Some name - - "# - ) - .unwrap() + + "#, ); let mut ns = namespaces(); ns.add_namespace("opc.tcp://my-server.server"); @@ -242,154 +241,158 @@ fn from_xml_qualified_name() { mp.add_namespace("opc.tcp://my-server.server", 2); let ctx = context(&mp, &ctx_owned); - assert_eq!( - QualifiedName::new(1, "Some name"), - from_xml_str_ctx( - r#" - + xml_round_trip_ctx( + &QualifiedName::new(1, "Some name"), + r#" + 2 Some name - + "#, - &ctx - ) - .unwrap() + &ctx, ) } #[test] fn from_xml_data_value() { - assert_eq!( - DataValue::new_at_status( + xml_round_trip( + &DataValue::new_at_status( 123i32, DateTime::from_str("2020-01-01T15:00:00Z").unwrap(), - StatusCode::Bad + StatusCode::Bad, ), - from_xml_str::( - r#" - + r#" 123 2147483648 2020-01-01T15:00:00Z 0 2020-01-01T15:00:00Z 0 - "# - ) - .unwrap() + "#, ) } #[test] fn from_xml_variant() { - assert_eq!( - Variant::from(1u8), - from_xml_str("1").unwrap() - ); - assert_eq!( - Variant::from(vec![1u8, 2u8]), - from_xml_str("12").unwrap() - ); - assert_eq!( - Variant::from(1i8), - from_xml_str("1").unwrap() - ); - assert_eq!( - Variant::from(vec![1i8, 2i8]), - from_xml_str("12") - .unwrap() - ); - assert_eq!( - Variant::from(1u16), - from_xml_str("1").unwrap() - ); - assert_eq!( - Variant::from(vec![1u16, 2u16]), - from_xml_str( - "12" - ) - .unwrap() - ); - assert_eq!( - Variant::from(1i16), - from_xml_str("1").unwrap() - ); - assert_eq!( - Variant::from(vec![1i16, 2i16]), - from_xml_str("12") - .unwrap() - ); - assert_eq!( - Variant::from(1u32), - from_xml_str("1").unwrap() - ); - assert_eq!( - Variant::from(vec![1u32, 2u32]), - from_xml_str( - "12" - ) - .unwrap() - ); - assert_eq!( - Variant::from(1i32), - from_xml_str("1").unwrap() - ); - assert_eq!( - Variant::from(vec![1i32, 2i32]), - from_xml_str("12") - .unwrap() - ); - assert_eq!( - Variant::from(1u64), - from_xml_str("1").unwrap() - ); - assert_eq!( - Variant::from(vec![1u64, 2u64]), - from_xml_str( - "12" - ) - .unwrap() - ); - assert_eq!( - Variant::from(1i64), - from_xml_str("1").unwrap() - ); - assert_eq!( - Variant::from(vec![1i64, 2i64]), - from_xml_str("12") - .unwrap() - ); - assert_eq!( - Variant::from(1.5f32), - from_xml_str("1.5").unwrap() - ); - assert_eq!( - Variant::from(vec![1.5f32, 2.5f32]), - from_xml_str( - "1.52.5" - ) - .unwrap() - ); - assert_eq!( - Variant::from(1.5f64), - from_xml_str("1.5").unwrap() - ); - assert_eq!( - Variant::from(vec![1.5f64, 2.5f64]), - from_xml_str( - "1.52.5" - ) - .unwrap() - ); - assert_eq!( - Variant::from("foo"), - from_xml_str("foo").unwrap() - ); - assert_eq!( - Variant::from(vec!["foo", "bar"]), - from_xml_str( - "foobar" - ) - .unwrap() + xml_round_trip(&Variant::from(1u8), "1"); + xml_round_trip( + &Variant::from(vec![1u8, 2u8]), + "12", + ); + xml_round_trip(&Variant::from(1i8), "1"); + xml_round_trip( + &Variant::from(vec![1i8, 2i8]), + "12", + ); + xml_round_trip(&Variant::from(1u16), "1"); + xml_round_trip( + &Variant::from(vec![1u16, 2u16]), + "12", + ); + xml_round_trip(&Variant::from(1i16), "1"); + xml_round_trip( + &Variant::from(vec![1i16, 2i16]), + "12", + ); + xml_round_trip(&Variant::from(1u32), "1"); + xml_round_trip( + &Variant::from(vec![1u32, 2u32]), + "12", + ); + xml_round_trip(&Variant::from(1i32), "1"); + xml_round_trip( + &Variant::from(vec![1i32, 2i32]), + "12", + ); + xml_round_trip(&Variant::from(1u64), "1"); + xml_round_trip( + &Variant::from(vec![1u64, 2u64]), + "12", + ); + xml_round_trip(&Variant::from(1i64), "1"); + xml_round_trip( + &Variant::from(vec![1i64, 2i64]), + "12", + ); + xml_round_trip(&Variant::from(1.5f32), "1.5"); + xml_round_trip( + &Variant::from(vec![1.5f32, 2.5f32]), + "1.52.5", + ); + xml_round_trip(&Variant::from(1.5f64), "1.5"); + xml_round_trip( + &Variant::from(vec![1.5f64, 2.5f64]), + "1.52.5", + ); + xml_round_trip(&Variant::from("foo"), "foo"); + xml_round_trip( + &Variant::from(vec!["foo", "bar"]), + "foobar", + ); + xml_round_trip( + &Variant::from(DateTime::parse_from_rfc3339("2020-01-01T00:00:00Z").unwrap()), + "2020-01-01T00:00:00Z", + ); + xml_round_trip( + &Variant::from(vec![DateTime::parse_from_rfc3339("2020-01-01T00:00:00Z").unwrap(), DateTime::parse_from_rfc3339("2020-01-02T00:00:00Z").unwrap()]), + "2020-01-01T00:00:00Z2020-01-02T00:00:00Z", + ); + let guid = Guid::from_str("f6aae0c0-455f-4285-82a7-d492ea4ef434").unwrap(); + xml_round_trip( + &Variant::from(guid.clone()), + "f6aae0c0-455f-4285-82a7-d492ea4ef434", + ); + xml_round_trip( + &Variant::from(vec![guid.clone(), guid.clone()]), + "f6aae0c0-455f-4285-82a7-d492ea4ef434 + f6aae0c0-455f-4285-82a7-d492ea4ef434", + ); + xml_round_trip( + &Variant::from(StatusCode::Bad), + "2147483648", + ); + xml_round_trip( + &Variant::from(vec![StatusCode::Bad, StatusCode::Good]), + "21474836480", + ); + xml_round_trip( + &Variant::from(EUInformation { + namespace_uri: "https://my.namespace.uri".into(), + unit_id: 1, + display_name: LocalizedText::new("en", "MyUnit"), + description: LocalizedText::new("en", "MyDesc"), + }), + r#" + + i=888 + + + https://my.namespace.uri + 1 + enMyUnit + enMyDesc + + + + "#, + ); + xml_round_trip( + &Variant::from( + Array::new_multi( + crate::VariantScalarTypeId::Int32, + vec![1.into(), 2.into(), 3.into(), 4.into()], + vec![2, 2], + ) + .unwrap(), + ), + r#" + + 22 + + 12 + 34 + + + "#, ); } diff --git a/async-opcua-types/src/type_loader.rs b/async-opcua-types/src/type_loader.rs index 75aeac52..f01058c6 100644 --- a/async-opcua-types/src/type_loader.rs +++ b/async-opcua-types/src/type_loader.rs @@ -19,7 +19,10 @@ use crate::{ type BinaryLoadFun = fn(&mut dyn Read, &Context<'_>) -> EncodingResult>; #[cfg(feature = "xml")] -type XmlLoadFun = fn(&opcua_xml::XmlElement, &Context<'_>) -> EncodingResult>; +type XmlLoadFun = fn( + &mut crate::xml::XmlStreamReader<&mut dyn std::io::Read>, + &Context<'_>, +) -> EncodingResult>; #[cfg(feature = "json")] type JsonLoadFun = fn( @@ -58,11 +61,11 @@ pub fn json_decode_to_enc( #[cfg(feature = "xml")] /// Convenience method to decode a type into a DynEncodable. -pub fn xml_decode_to_enc( - body: &opcua_xml::XmlElement, +pub fn xml_decode_to_enc( + stream: &mut crate::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &Context<'_>, ) -> EncodingResult> { - Ok(Box::new(T::from_xml(body, ctx)?)) + Ok(Box::new(T::decode(stream, ctx)?)) } impl TypeLoaderInstance { @@ -107,11 +110,11 @@ impl TypeLoaderInstance { pub fn decode_xml( &self, ty: u32, - body: &opcua_xml::XmlElement, + stream: &mut crate::xml::XmlStreamReader<&mut dyn std::io::Read>, context: &Context<'_>, ) -> Option>> { let fun = self.xml_types.get(&ty)?; - Some(fun(body, context)) + Some(fun(stream, context)) } #[cfg(feature = "json")] @@ -333,7 +336,7 @@ pub trait TypeLoader: Send + Sync { fn load_from_xml( &self, node_id: &crate::NodeId, - body: &opcua_xml::XmlElement, + stream: &mut crate::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &Context<'_>, ) -> Option>>; @@ -420,10 +423,10 @@ impl<'a> Context<'a> { pub fn load_from_xml( &self, node_id: &NodeId, - body: &opcua_xml::XmlElement, + stream: &mut crate::xml::XmlStreamReader<&mut dyn std::io::Read>, ) -> crate::EncodingResult { for loader in self.loaders { - if let Some(r) = loader.load_from_xml(node_id, body, self) { + if let Some(r) = loader.load_from_xml(node_id, stream, self) { return Ok(crate::ExtensionObject { body: Some(r?) }); } } @@ -471,6 +474,25 @@ impl<'a> Context<'a> { Ok(*idx) } + /// Look up namespace index in reverse, finding the index in the node set + /// given the index in the server. + pub fn resolve_namespace_index_inverse( + &self, + index_in_server: u16, + ) -> Result { + if index_in_server == 0 { + return Ok(0); + } + + let Some(index_map) = self.index_map else { + return Ok(index_in_server); + }; + let Some((idx, _)) = index_map.iter().find(|(_, &v)| v == index_in_server) else { + return Err(UninitializedIndex(index_in_server)); + }; + Ok(*idx) + } + /// Resolve a node ID alias, if the alias table is registered. /// Only used for XML decoding when loading nodeset files. pub fn resolve_alias<'b>(&self, node_id_str: &'b str) -> &'b str @@ -485,6 +507,21 @@ impl<'a> Context<'a> { node_id_str } + /// Resolve a node ID alias in inverse, getting the alias value given the node ID. + pub fn resolve_alias_inverse<'b>(&self, node_id_str: &'b str) -> &'b str + where + 'a: 'b, + { + if let Some(aliases) = self.aliases { + for (k, v) in aliases.iter() { + if v == node_id_str { + return k.as_str(); + } + } + } + node_id_str + } + /// Produce a copy of self with zero client_offset, or a borrow if /// the offset is already zero. pub fn with_zero_offset(&self) -> Cow<'_, Self> { diff --git a/async-opcua-types/src/variant/mod.rs b/async-opcua-types/src/variant/mod.rs index 64d2ec9b..9025f6fa 100644 --- a/async-opcua-types/src/variant/mod.rs +++ b/async-opcua-types/src/variant/mod.rs @@ -10,6 +10,8 @@ mod into; #[cfg(feature = "json")] mod json; mod type_id; +#[cfg(feature = "xml")] +mod xml; pub use from::TryFromVariant; pub use into::IntoVariant; diff --git a/async-opcua-types/src/variant/xml.rs b/async-opcua-types/src/variant/xml.rs new file mode 100644 index 00000000..03badd78 --- /dev/null +++ b/async-opcua-types/src/variant/xml.rs @@ -0,0 +1,296 @@ +use crate::{ + xml::*, Array, ByteString, DataValue, DateTime, DiagnosticInfo, ExpandedNodeId, + ExtensionObject, Guid, LocalizedText, NodeId, QualifiedName, StatusCode, UAString, +}; + +use super::{Variant, VariantScalarTypeId}; + +impl XmlType for Variant { + const TAG: &'static str = "Variant"; +} +impl VariantScalarTypeId { + /// Get the XML name of a variant type. + pub fn xml_name(&self) -> &'static str { + match self { + VariantScalarTypeId::Boolean => "Boolean", + VariantScalarTypeId::SByte => "SByte", + VariantScalarTypeId::Byte => "Byte", + VariantScalarTypeId::Int16 => "Int16", + VariantScalarTypeId::UInt16 => "UInt16", + VariantScalarTypeId::Int32 => "Int32", + VariantScalarTypeId::UInt32 => "UInt32", + VariantScalarTypeId::Int64 => "Int64", + VariantScalarTypeId::UInt64 => "UInt64", + VariantScalarTypeId::Float => "Float", + VariantScalarTypeId::Double => "Double", + VariantScalarTypeId::String => "String", + VariantScalarTypeId::DateTime => "DateTime", + VariantScalarTypeId::Guid => "Guid", + VariantScalarTypeId::ByteString => "ByteString", + VariantScalarTypeId::XmlElement => "XmlElement", + VariantScalarTypeId::NodeId => "NodeId", + VariantScalarTypeId::ExpandedNodeId => "ExpandedNodeId", + VariantScalarTypeId::StatusCode => "StatusCode", + VariantScalarTypeId::QualifiedName => "QualifiedName", + VariantScalarTypeId::LocalizedText => "LocalizedText", + VariantScalarTypeId::ExtensionObject => "ExtensionObject", + VariantScalarTypeId::DataValue => "DataValue", + VariantScalarTypeId::Variant => "Variant", + VariantScalarTypeId::DiagnosticInfo => "DiagnosticInfo", + } + } + + /// Get a variant type ID from the XML name of the variant type. + pub fn from_xml_name(name: &str) -> Option { + Some(match name { + "Boolean" => VariantScalarTypeId::Boolean, + "SByte" => VariantScalarTypeId::SByte, + "Byte" => VariantScalarTypeId::Byte, + "Int16" => VariantScalarTypeId::Int16, + "UInt16" => VariantScalarTypeId::UInt16, + "Int32" => VariantScalarTypeId::Int32, + "UInt32" => VariantScalarTypeId::UInt32, + "Int64" => VariantScalarTypeId::Int64, + "UInt64" => VariantScalarTypeId::UInt64, + "Float" => VariantScalarTypeId::Float, + "Double" => VariantScalarTypeId::Double, + "String" => VariantScalarTypeId::String, + "DateTime" => VariantScalarTypeId::DateTime, + "Guid" => VariantScalarTypeId::Guid, + "ByteString" => VariantScalarTypeId::ByteString, + "XmlElement" => VariantScalarTypeId::XmlElement, + "NodeId" => VariantScalarTypeId::NodeId, + "ExpandedNodeId" => VariantScalarTypeId::ExpandedNodeId, + "StatusCode" => VariantScalarTypeId::StatusCode, + "QualifiedName" => VariantScalarTypeId::QualifiedName, + "LocalizedText" => VariantScalarTypeId::LocalizedText, + "ExtensionObject" => VariantScalarTypeId::ExtensionObject, + "DataValue" => VariantScalarTypeId::DataValue, + "Variant" => VariantScalarTypeId::Variant, + "DiagnosticInfo" => VariantScalarTypeId::DiagnosticInfo, + _ => return None, + }) + } +} + +impl Variant { + /// Get a default variant of the given type. + pub fn get_variant_default(ty: VariantScalarTypeId) -> Variant { + match ty { + VariantScalarTypeId::Boolean => Variant::Boolean(Default::default()), + VariantScalarTypeId::SByte => Variant::SByte(Default::default()), + VariantScalarTypeId::Byte => Variant::Byte(Default::default()), + VariantScalarTypeId::Int16 => Variant::Int16(Default::default()), + VariantScalarTypeId::UInt16 => Variant::UInt16(Default::default()), + VariantScalarTypeId::Int32 => Variant::Int32(Default::default()), + VariantScalarTypeId::UInt32 => Variant::UInt32(Default::default()), + VariantScalarTypeId::Int64 => Variant::Int64(Default::default()), + VariantScalarTypeId::UInt64 => Variant::UInt64(Default::default()), + VariantScalarTypeId::Float => Variant::Float(Default::default()), + VariantScalarTypeId::Double => Variant::Double(Default::default()), + VariantScalarTypeId::String => Variant::String(Default::default()), + VariantScalarTypeId::DateTime => Variant::DateTime(Default::default()), + VariantScalarTypeId::Guid => Variant::Guid(Default::default()), + VariantScalarTypeId::ByteString => Variant::ByteString(Default::default()), + VariantScalarTypeId::XmlElement => Variant::XmlElement(Default::default()), + VariantScalarTypeId::NodeId => Variant::NodeId(Default::default()), + VariantScalarTypeId::ExpandedNodeId => Variant::ExpandedNodeId(Default::default()), + VariantScalarTypeId::StatusCode => Variant::StatusCode(Default::default()), + VariantScalarTypeId::QualifiedName => Variant::QualifiedName(Default::default()), + VariantScalarTypeId::LocalizedText => Variant::LocalizedText(Default::default()), + VariantScalarTypeId::ExtensionObject => Variant::ExtensionObject(Default::default()), + VariantScalarTypeId::DataValue => Variant::DataValue(Default::default()), + VariantScalarTypeId::Variant => Variant::Variant(Default::default()), + VariantScalarTypeId::DiagnosticInfo => Variant::DiagnosticInfo(Default::default()), + } + } + + /// Decode an XML variant value from stream, consuming the rest of the current element. + pub fn xml_decode_variant_value( + stream: &mut XmlStreamReader<&mut dyn std::io::Read>, + context: &Context<'_>, + key: &str, + ) -> EncodingResult { + if let Some(ty) = key.strip_prefix("ListOf") { + let ty = VariantScalarTypeId::from_xml_name(ty) + .ok_or_else(|| Error::decoding(format!("Invalid variant contents: {key}")))?; + let mut vec = Vec::new(); + stream.iter_children_include_empty( + |key, stream, context| { + let Some(stream) = stream else { + let ty = VariantScalarTypeId::from_xml_name(&key).ok_or_else(|| { + Error::decoding(format!("Invalid variant contents: {key}")) + })?; + vec.push(Self::get_variant_default(ty)); + return Ok(()); + }; + let r = Variant::xml_decode_variant_value(stream, context, &key)?; + vec.push(r); + Ok(()) + }, + context, + )?; + Ok(Self::Array(Box::new( + Array::new(ty, vec).map_err(Error::decoding)?, + ))) + } else if key == "Matrix" { + let mut dims = Vec::new(); + let mut elems = Vec::new(); + stream.iter_children( + |key, stream, context| match key.as_str() { + "Dimensions" => { + dims = Vec::::decode(stream, context)?; + Ok(()) + } + "Elements" => stream.iter_children_include_empty( + |key, stream, context| { + let Some(stream) = stream else { + let ty = + VariantScalarTypeId::from_xml_name(&key).ok_or_else(|| { + Error::decoding(format!("Invalid variant contents: {key}")) + })?; + elems.push(Self::get_variant_default(ty)); + return Ok(()); + }; + let r = Variant::xml_decode_variant_value(stream, context, &key)?; + elems.push(r); + Ok(()) + }, + context, + ), + r => Err(Error::decoding(format!( + "Invalid field in Matrix content: {r}" + ))), + }, + context, + )?; + // If you have an empty matrix there's no actual way to determine the type. + let scalar_type = elems + .first() + .and_then(|v| v.scalar_type_id()) + .unwrap_or(VariantScalarTypeId::Int32); + Ok(Self::Array(Box::new( + Array::new_multi( + scalar_type, + elems, + dims.into_iter() + .map(|d| d.try_into()) + .collect::, _>>() + .map_err(|_| { + Error::decoding("Invalid array dimensions, must all be non-negative") + })?, + ) + .map_err(Error::decoding)?, + ))) + } else { + Ok(match key { + "Boolean" => Self::Boolean(XmlDecodable::decode(stream, context)?), + "SByte" => Self::SByte(XmlDecodable::decode(stream, context)?), + "Byte" => Self::Byte(XmlDecodable::decode(stream, context)?), + "Int16" => Self::Int16(XmlDecodable::decode(stream, context)?), + "UInt16" => Self::UInt16(XmlDecodable::decode(stream, context)?), + "Int32" => Self::Int32(XmlDecodable::decode(stream, context)?), + "UInt32" => Self::UInt32(XmlDecodable::decode(stream, context)?), + "Int64" => Self::Int64(XmlDecodable::decode(stream, context)?), + "UInt64" => Self::UInt64(XmlDecodable::decode(stream, context)?), + "Float" => Self::Float(XmlDecodable::decode(stream, context)?), + "Double" => Self::Double(XmlDecodable::decode(stream, context)?), + "String" => Self::String(XmlDecodable::decode(stream, context)?), + "DateTime" => Self::DateTime(XmlDecodable::decode(stream, context)?), + "Guid" => Self::Guid(XmlDecodable::decode(stream, context)?), + "ByteString" => Self::ByteString(XmlDecodable::decode(stream, context)?), + "XmlElement" => Self::XmlElement(XmlDecodable::decode(stream, context)?), + "NodeId" => Self::NodeId(XmlDecodable::decode(stream, context)?), + "ExpandedNodeId" => Self::ExpandedNodeId(XmlDecodable::decode(stream, context)?), + "StatusCode" => Self::StatusCode(XmlDecodable::decode(stream, context)?), + "QualifiedName" => Self::QualifiedName(XmlDecodable::decode(stream, context)?), + "LocalizedText" => Self::LocalizedText(XmlDecodable::decode(stream, context)?), + "ExtensionObject" => Self::ExtensionObject(XmlDecodable::decode(stream, context)?), + "DataValue" => Self::DataValue(XmlDecodable::decode(stream, context)?), + "Variant" => Self::Variant(XmlDecodable::decode(stream, context)?), + "DiagnosticInfo" => Self::DiagnosticInfo(XmlDecodable::decode(stream, context)?), + r => return Err(Error::decoding(format!("Invalid variant type {r}"))), + }) + } + } +} + +impl XmlEncodable for Variant { + fn encode( + &self, + stream: &mut XmlStreamWriter<&mut dyn std::io::Write>, + ctx: &Context<'_>, + ) -> EncodingResult<()> { + match self { + Variant::Empty => return Ok(()), + Variant::Boolean(v) => stream.encode_child(bool::TAG, v, ctx)?, + Variant::SByte(v) => stream.encode_child(i8::TAG, v, ctx)?, + Variant::Byte(v) => stream.encode_child(u8::TAG, v, ctx)?, + Variant::Int16(v) => stream.encode_child(i16::TAG, v, ctx)?, + Variant::UInt16(v) => stream.encode_child(u16::TAG, v, ctx)?, + Variant::Int32(v) => stream.encode_child(i32::TAG, v, ctx)?, + Variant::UInt32(v) => stream.encode_child(u32::TAG, v, ctx)?, + Variant::Int64(v) => stream.encode_child(i64::TAG, v, ctx)?, + Variant::UInt64(v) => stream.encode_child(u64::TAG, v, ctx)?, + Variant::Float(v) => stream.encode_child(f32::TAG, v, ctx)?, + Variant::Double(v) => stream.encode_child(f64::TAG, v, ctx)?, + Variant::String(v) => stream.encode_child(UAString::TAG, v, ctx)?, + Variant::DateTime(v) => stream.encode_child(DateTime::TAG, v, ctx)?, + Variant::Guid(v) => stream.encode_child(Guid::TAG, v, ctx)?, + Variant::StatusCode(v) => stream.encode_child(StatusCode::TAG, v, ctx)?, + Variant::ByteString(v) => stream.encode_child(ByteString::TAG, v, ctx)?, + Variant::XmlElement(v) => stream.encode_child("XmlElement", v, ctx)?, + Variant::QualifiedName(v) => stream.encode_child(QualifiedName::TAG, v, ctx)?, + Variant::LocalizedText(v) => stream.encode_child(LocalizedText::TAG, v, ctx)?, + Variant::NodeId(v) => stream.encode_child(NodeId::TAG, v, ctx)?, + Variant::ExpandedNodeId(v) => stream.encode_child(ExpandedNodeId::TAG, v, ctx)?, + Variant::ExtensionObject(v) => stream.encode_child(ExtensionObject::TAG, v, ctx)?, + Variant::Variant(v) => stream.encode_child(Variant::TAG, v, ctx)?, + Variant::DataValue(v) => stream.encode_child(DataValue::TAG, v, ctx)?, + Variant::DiagnosticInfo(v) => stream.encode_child(DiagnosticInfo::TAG, v, ctx)?, + Variant::Array(v) => { + let xml_name = v.value_type.xml_name(); + if let Some(dims) = v.dimensions.as_ref() { + if dims.len() > 1 { + stream.write_start("Matrix")?; + // For some incredibly annoying reason, OPC-UA insists that dimensions be + // encoded as _signed_ integers. For other encoders it's irrelevant, + // but it matters for XML. + let dims: Vec<_> = dims.iter().map(|d| *d as i32).collect(); + stream.encode_child("Dimensions", &dims, ctx)?; + + stream.write_start("Elements")?; + for item in &v.values { + item.encode(stream, ctx)?; + } + stream.write_end("Elements")?; + stream.write_end("Matrix")?; + return Ok(()); + } + } + let tag_name = format!("ListOf{}", xml_name); + stream.write_start(&tag_name)?; + for item in &v.values { + item.encode(stream, ctx)?; + } + stream.write_end(&tag_name)?; + } + } + + Ok(()) + } +} + +impl XmlDecodable for Variant { + fn decode( + stream: &mut XmlStreamReader<&mut dyn std::io::Read>, + context: &Context<'_>, + ) -> Result { + stream + .get_first_child( + |key, stream, ctx| Self::xml_decode_variant_value(stream, ctx, &key), + context, + ) + .map(|v| v.unwrap_or(Variant::Empty)) + } +} diff --git a/async-opcua-types/src/xml/builtins.rs b/async-opcua-types/src/xml/builtins.rs index 84f04a4a..3cb93c76 100644 --- a/async-opcua-types/src/xml/builtins.rs +++ b/async-opcua-types/src/xml/builtins.rs @@ -1,10 +1,17 @@ -use super::encoding::{XmlDecodable, XmlEncodable}; +use super::{ + encoding::{XmlDecodable, XmlEncodable, XmlType}, + XmlReadExt, XmlWriteExt, +}; use crate::{Context, Error}; use opcua_xml::{XmlStreamReader, XmlStreamWriter}; use std::io::{Read, Write}; macro_rules! xml_enc_number { - ($t:ty) => { + ($t:ty, $name:expr) => { + impl XmlType for $t { + const TAG: &'static str = $name; + } + impl XmlEncodable for $t { fn encode( &self, @@ -32,7 +39,11 @@ const VALUE_NEG_INFINITY: &str = "-INF"; const VALUE_NAN: &str = "NaN"; macro_rules! xml_enc_float { - ($t:ty) => { + ($t:ty, $name:expr) => { + impl XmlType for $t { + const TAG: &'static str = $name; + } + impl XmlEncodable for $t { fn encode( &self, @@ -71,16 +82,20 @@ macro_rules! xml_enc_float { }; } -xml_enc_number!(u8); -xml_enc_number!(u16); -xml_enc_number!(u32); -xml_enc_number!(u64); -xml_enc_number!(i8); -xml_enc_number!(i16); -xml_enc_number!(i32); -xml_enc_number!(i64); -xml_enc_float!(f32); -xml_enc_float!(f64); +xml_enc_number!(u8, "Byte"); +xml_enc_number!(u16, "UInt16"); +xml_enc_number!(u32, "UInt32"); +xml_enc_number!(u64, "UInt64"); +xml_enc_number!(i8, "SByte"); +xml_enc_number!(i16, "Int16"); +xml_enc_number!(i32, "Int32"); +xml_enc_number!(i64, "Int64"); +xml_enc_float!(f32, "Float"); +xml_enc_float!(f64, "Double"); + +impl XmlType for String { + const TAG: &'static str = "String"; +} impl XmlDecodable for String { fn decode( @@ -105,6 +120,10 @@ impl XmlEncodable for String { } } +impl XmlType for str { + const TAG: &'static str = "String"; +} + impl XmlEncodable for str { fn encode( &self, @@ -116,6 +135,10 @@ impl XmlEncodable for str { } } +impl XmlType for bool { + const TAG: &'static str = "Boolean"; +} + impl XmlDecodable for bool { fn decode( read: &mut XmlStreamReader<&mut dyn Read>, @@ -144,6 +167,16 @@ impl XmlEncodable for bool { } } +impl XmlType for Box +where + T: XmlType, +{ + const TAG: &'static str = T::TAG; + fn tag(&self) -> &str { + self.as_ref().tag() + } +} + impl XmlDecodable for Box where T: XmlDecodable, @@ -168,3 +201,95 @@ where self.as_ref().encode(writer, context) } } + +impl XmlType for Vec +where + T: XmlType, +{ + // Could be ListOf... but there's no static way to do so, and it isn't + // strictly necessary. + const TAG: &'static str = T::TAG; + fn tag(&self) -> &str { + self.first().map(|v| v.tag()).unwrap_or(Self::TAG) + } +} + +impl XmlDecodable for Vec +where + T: XmlDecodable + Default, +{ + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + context: &Context<'_>, + ) -> Result { + let mut vec = Vec::new(); + read.iter_children_include_empty( + |_, reader, context| { + let Some(reader) = reader else { + vec.push(T::default()); + return Ok(()); + }; + vec.push(T::decode(reader, context)?); + Ok(()) + }, + context, + )?; + Ok(vec) + } +} + +impl XmlEncodable for Vec +where + T: XmlEncodable, +{ + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + context: &Context<'_>, + ) -> super::EncodingResult<()> { + for item in self { + writer.encode_child(item.tag(), item, context)?; + } + Ok(()) + } +} + +impl XmlType for Option +where + T: XmlType, +{ + const TAG: &'static str = T::TAG; + fn tag(&self) -> &str { + self.as_ref().map(|v| v.tag()).unwrap_or(Self::TAG) + } +} + +impl XmlDecodable for Option +where + T: XmlDecodable, +{ + fn decode( + read: &mut XmlStreamReader<&mut dyn Read>, + context: &Context<'_>, + ) -> Result { + // Effectively we treat missing fields as None, so here we just pass along + // to the decoder, since getting here means the field is present. + Ok(Some(T::decode(read, context)?)) + } +} + +impl XmlEncodable for Option +where + T: XmlEncodable, +{ + fn encode( + &self, + writer: &mut XmlStreamWriter<&mut dyn Write>, + context: &Context<'_>, + ) -> super::EncodingResult<()> { + if let Some(value) = self { + value.encode(writer, context)?; + } + Ok(()) + } +} diff --git a/async-opcua-types/src/xml/encoding.rs b/async-opcua-types/src/xml/encoding.rs index 7382f856..11417147 100644 --- a/async-opcua-types/src/xml/encoding.rs +++ b/async-opcua-types/src/xml/encoding.rs @@ -25,8 +25,19 @@ impl From for Error { } } +/// Trait for XML type name. Used by both XmlDecodable and XmlEncodable. +pub trait XmlType { + /// The static fallback tag for this type. + /// Convenience feature, but also used in nested types. + const TAG: &'static str; + /// The XML tag name for this type. + fn tag(&self) -> &str { + Self::TAG + } +} + /// Trait for types that can be decoded from XML. -pub trait XmlDecodable { +pub trait XmlDecodable: XmlType { /// Decode a value from an XML stream. fn decode( read: &mut XmlStreamReader<&mut dyn Read>, @@ -37,7 +48,7 @@ pub trait XmlDecodable { } /// Trait for types that can be encoded to XML. -pub trait XmlEncodable { +pub trait XmlEncodable: XmlType { /// Encode a value to an XML stream. fn encode( &self, @@ -74,6 +85,14 @@ impl XmlWriteExt for XmlStreamWriter<&mut dyn Write> { /// Extensions for XmlStreamReader. pub trait XmlReadExt { + /// Iterate over children, calling the provided callback for each tag. + /// The callback must consume the tag, unless no reader is provided, + /// in which case the tag is already closed. + fn iter_children_include_empty( + &mut self, + process: impl FnMut(String, Option<&mut Self>, &Context<'_>) -> EncodingResult<()>, + context: &Context<'_>, + ) -> EncodingResult<()>; /// Iterate over children, calling the provided callback for each tag. /// The callback must consume the tag. fn iter_children( @@ -98,9 +117,42 @@ pub trait XmlReadExt { tag: &str, context: &Context<'_>, ) -> Result, Error>; + + /// Call a callback for the first child element, then skip the rest. This will + /// consume the current node. + fn get_first_child( + &mut self, + cb: impl FnOnce(String, &mut Self, &Context<'_>) -> Result, + context: &Context<'_>, + ) -> EncodingResult>; } impl XmlReadExt for XmlStreamReader<&mut dyn Read> { + fn iter_children_include_empty( + &mut self, + mut process: impl FnMut(String, Option<&mut Self>, &Context<'_>) -> EncodingResult<()>, + context: &Context<'_>, + ) -> EncodingResult<()> { + loop { + match self.next_event()? { + opcua_xml::events::Event::Start(s) => { + let local_name = s.local_name(); + let name = from_utf8(local_name.as_ref())?; + process(name.to_owned(), Some(self), context)?; + } + opcua_xml::events::Event::Empty(s) => { + let local_name = s.local_name(); + let name = from_utf8(local_name.as_ref())?; + process(name.to_owned(), None, context)?; + } + opcua_xml::events::Event::End(_) | opcua_xml::events::Event::Eof => { + return Ok(()); + } + _ => (), + } + } + } + fn iter_children( &mut self, mut process: impl FnMut(String, &mut Self, &Context<'_>) -> EncodingResult<()>, @@ -109,15 +161,13 @@ impl XmlReadExt for XmlStreamReader<&mut dyn Read> { loop { match self.next_event()? { opcua_xml::events::Event::Start(s) => { - let name = from_utf8(s.name().0)?; + let local_name = s.local_name(); + let name = from_utf8(local_name.as_ref())?; process(name.to_owned(), self, context)?; } - opcua_xml::events::Event::End(_) => { + opcua_xml::events::Event::End(_) | opcua_xml::events::Event::Eof => { return Ok(()); } - opcua_xml::events::Event::Eof => { - return Err(Error::decoding(XmlReadError::UnexpectedEof)); - } _ => (), } } @@ -136,10 +186,10 @@ impl XmlReadExt for XmlStreamReader<&mut dyn Read> { if tag == key { if let Some(cb) = cb.take() { res = Some(cb(reader, ctx)?); + return Ok(()); } - } else { - reader.skip_value()?; } + reader.skip_value()?; Ok(()) }, context, @@ -154,4 +204,25 @@ impl XmlReadExt for XmlStreamReader<&mut dyn Read> { ) -> EncodingResult> { self.get_single_child(tag, |reader, ctx| T::decode(reader, ctx), context) } + + fn get_first_child( + &mut self, + cb: impl FnOnce(String, &mut Self, &Context<'_>) -> Result, + context: &Context<'_>, + ) -> EncodingResult> { + let mut cb = Some(cb); + let mut res = None; + self.iter_children( + |key, reader, ctx| { + if let Some(cb) = cb.take() { + res = Some(cb(key, reader, ctx)?); + return Ok(()); + } + reader.skip_value()?; + Ok(()) + }, + context, + )?; + Ok(res) + } } diff --git a/async-opcua-types/src/xml/mod.rs b/async-opcua-types/src/xml/mod.rs index d9ea22f7..cc188bff 100644 --- a/async-opcua-types/src/xml/mod.rs +++ b/async-opcua-types/src/xml/mod.rs @@ -6,17 +6,20 @@ mod builtins; mod encoding; pub use crate::{Context, EncodingResult, Error}; -pub use encoding::{XmlDecodable, XmlEncodable, XmlReadExt, XmlWriteExt}; +pub use encoding::{XmlDecodable, XmlEncodable, XmlReadExt, XmlType, XmlWriteExt}; pub use opcua_xml::{XmlStreamReader, XmlStreamWriter}; -use std::str::FromStr; +use std::{ + io::{Cursor, Read}, + str::FromStr, +}; use log::warn; pub use opcua_xml::schema::opc_ua_types::XmlElement; use crate::{ - Array, ByteString, DataValue, DateTime, ExpandedNodeId, ExtensionObject, Guid, LocalizedText, - NodeId, QualifiedName, StatusCode, UAString, UninitializedIndex, Variant, VariantScalarTypeId, + Array, ByteString, ExpandedNodeId, ExtensionObject, LocalizedText, NodeId, QualifiedName, + StatusCode, UninitializedIndex, Variant, VariantScalarTypeId, }; impl From for Error { @@ -25,407 +28,6 @@ impl From for Error { } } -macro_rules! from_xml_number { - ($n:ty) => { - impl FromXml for $n { - fn from_xml(element: &XmlElement, _ctx: &Context<'_>) -> EncodingResult { - let Some(c) = element.text.as_ref() else { - return Ok(Self::default()); - }; - c.parse::<$n>().map_err(Error::decoding) - } - } - }; -} - -from_xml_number!(u8); -from_xml_number!(i8); -from_xml_number!(u16); -from_xml_number!(i16); -from_xml_number!(u32); -from_xml_number!(i32); -from_xml_number!(u64); -from_xml_number!(i64); -from_xml_number!(f32); -from_xml_number!(f64); -from_xml_number!(bool); - -/// `FromXml` is implemented by types that can be loaded from a NodeSet2 XML node. -pub trait FromXml: Sized { - /// Attempt to load the type from the given XML node. - fn from_xml(element: &XmlElement, ctx: &Context<'_>) -> EncodingResult; - /// Get the default value of the field, or fail with a `MissingRequired` error. - /// Workaround for specialization. - fn default_or_required(name: &'static str) -> EncodingResult { - Err(Error::decoding(format!("Missing required field: {name}"))) - } -} - -impl FromXml for UAString { - fn from_xml(element: &XmlElement, _ctx: &Context<'_>) -> EncodingResult { - Ok(element.text.clone().into()) - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::null()) - } -} - -impl FromXml for LocalizedText { - fn from_xml(element: &XmlElement, _ctx: &Context<'_>) -> EncodingResult { - Ok(LocalizedText::new( - element.child_content("Locale").unwrap_or("").trim(), - element.child_content("Text").unwrap_or("").trim(), - )) - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::null()) - } -} - -impl FromXml for Guid { - fn from_xml(element: &XmlElement, _ctx: &Context<'_>) -> EncodingResult { - if let Some(data) = element.child_content("String") { - Guid::from_str(data).map_err(Error::decoding) - } else { - Ok(Guid::null()) - } - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::null()) - } -} - -impl FromXml for NodeId { - fn from_xml(element: &XmlElement, ctx: &Context<'_>) -> EncodingResult { - let Some(id) = element.child_content("Identifier") else { - return Ok(NodeId::null()); - }; - let id = ctx.resolve_alias(id); - let mut node_id = NodeId::from_str(id) - .map_err(|e| Error::new(e, format!("Failed to parse node ID from string {id}")))?; - // Update the namespace index, the index in the XML nodeset will probably not match the one - // in the server. - node_id.namespace = ctx.resolve_namespace_index(node_id.namespace)?; - Ok(node_id) - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::null()) - } -} - -impl FromXml for ExpandedNodeId { - fn from_xml(element: &XmlElement, ctx: &Context<'_>) -> EncodingResult { - Ok(ExpandedNodeId::new(NodeId::from_xml(element, ctx)?)) - } -} - -impl FromXml for StatusCode { - fn from_xml(element: &XmlElement, ctx: &Context<'_>) -> EncodingResult { - let code = element - .first_child_with_name("Code") - .map(|v| u32::from_xml(v, ctx)) - .transpose()? - .unwrap_or_default(); - Ok(StatusCode::from(code)) - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::Good) - } -} - -impl FromXml for ExtensionObject { - fn from_xml(element: &XmlElement, ctx: &Context<'_>) -> EncodingResult { - let type_id = element - .first_child_with_name("TypeId") - .ok_or_else(|| Error::decoding("Missing required field TypeId"))?; - let type_id = NodeId::from_xml(type_id, ctx)?; - let body = element - .first_child_with_name("Body") - // Extension objects always contain the name of the type wrapping the actual type, we need to - // unwrap that to get to the type FromXml expects. - .and_then(|b| b.children.iter().next().and_then(|m| m.1.iter().next())); - let Some(body) = body else { - return Ok(ExtensionObject::null()); - }; - ctx.load_from_xml(&type_id, body) - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::null()) - } -} - -impl FromXml for DateTime { - fn from_xml(element: &XmlElement, _ctx: &Context<'_>) -> EncodingResult { - DateTime::from_str( - element - .text - .as_deref() - .ok_or_else(|| Error::decoding("DateTime is missing required content"))?, - ) - .map_err(Error::decoding) - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::null()) - } -} - -impl FromXml for ByteString { - fn from_xml(element: &XmlElement, _ctx: &Context<'_>) -> EncodingResult { - let Some(c) = element.text.as_ref() else { - return Ok(ByteString::null()); - }; - ByteString::from_base64(c) - .ok_or_else(|| Error::decoding("Failed to parse bytestring from string")) - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::null()) - } -} - -impl FromXml for QualifiedName { - fn from_xml(element: &XmlElement, ctx: &Context<'_>) -> EncodingResult { - let index = element.child_content("NamespaceIndex"); - let index = if let Some(index) = index { - index.parse::().map_err(Error::decoding)? - } else { - 0 - }; - let index = ctx.resolve_namespace_index(index)?; - let name = element.child_content("Name").unwrap_or(""); - Ok(QualifiedName::new(index, name)) - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::null()) - } -} - -impl FromXml for DataValue { - fn from_xml(element: &XmlElement, ctx: &Context<'_>) -> EncodingResult { - let value = XmlField::get_xml_field(element, "Value", ctx)?; - let status = XmlField::get_xml_field(element, "StatusCode", ctx)?; - let source_timestamp = XmlField::get_xml_field(element, "SourceTimestamp", ctx)?; - let source_picoseconds = XmlField::get_xml_field(element, "SourcePicoseconds", ctx)?; - let server_timestamp = XmlField::get_xml_field(element, "ServerTimestamp", ctx)?; - let server_picoseconds = XmlField::get_xml_field(element, "ServerPicoseconds", ctx)?; - Ok(DataValue { - value, - status, - source_timestamp, - source_picoseconds, - server_timestamp, - server_picoseconds, - }) - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::null()) - } -} - -fn children_with_name( - element: &XmlElement, - ctx: &Context<'_>, - name: &str, -) -> Result, Error> { - element - .children_with_name(name) - .map(|n| T::from_xml(n, ctx)) - .collect() -} - -impl FromXml for Variant { - fn from_xml(element: &XmlElement, ctx: &Context<'_>) -> EncodingResult { - let Some((_, body)) = element.children.iter().next() else { - return Ok(Variant::Empty); - }; - let Some(body) = body.first() else { - return Ok(Variant::Empty); - }; - Ok(match body.tag.as_str() { - "Boolean" => Variant::Boolean(FromXml::from_xml(body, ctx)?), - "ListOfBoolean" => Variant::from(children_with_name::(body, ctx, "Boolean")?), - "SByte" => Variant::SByte(FromXml::from_xml(body, ctx)?), - "ListOfSByte" => Variant::from(children_with_name::(body, ctx, "SByte")?), - "Byte" => Variant::Byte(FromXml::from_xml(body, ctx)?), - "ListOfByte" => Variant::from(children_with_name::(body, ctx, "Byte")?), - "Int16" => Variant::Int16(FromXml::from_xml(body, ctx)?), - "ListOfInt16" => Variant::from(children_with_name::(body, ctx, "Int16")?), - "UInt16" => Variant::UInt16(FromXml::from_xml(body, ctx)?), - "ListOfUInt16" => Variant::from(children_with_name::(body, ctx, "UInt16")?), - "Int32" => Variant::Int32(FromXml::from_xml(body, ctx)?), - "ListOfInt32" => Variant::from(children_with_name::(body, ctx, "Int32")?), - "UInt32" => Variant::UInt32(FromXml::from_xml(body, ctx)?), - "ListOfUInt32" => Variant::from(children_with_name::(body, ctx, "UInt32")?), - "Int64" => Variant::Int64(FromXml::from_xml(body, ctx)?), - "ListOfInt64" => Variant::from(children_with_name::(body, ctx, "Int64")?), - "UInt64" => Variant::UInt64(FromXml::from_xml(body, ctx)?), - "ListOfUInt64" => Variant::from(children_with_name::(body, ctx, "UInt64")?), - "Float" => Variant::Float(FromXml::from_xml(body, ctx)?), - "ListOfFloat" => Variant::from(children_with_name::(body, ctx, "Float")?), - "Double" => Variant::Double(FromXml::from_xml(body, ctx)?), - "ListOfDouble" => Variant::from(children_with_name::(body, ctx, "Double")?), - "String" => Variant::String(FromXml::from_xml(body, ctx)?), - "ListOfString" => Variant::from(children_with_name::(body, ctx, "String")?), - "DateTime" => Variant::DateTime(FromXml::from_xml(body, ctx)?), - "ListOfDateTime" => { - Variant::from(children_with_name::(body, ctx, "DateTime")?) - } - "Guid" => Variant::Guid(FromXml::from_xml(body, ctx)?), - "ListOfGuid" => Variant::from(children_with_name::(body, ctx, "Guid")?), - "ByteString" => Variant::ByteString(FromXml::from_xml(body, ctx)?), - "ListOfByteString" => { - Variant::from(children_with_name::(body, ctx, "ByteString")?) - } - "XmlElement" => Variant::XmlElement(body.to_string().into()), - "ListOfXmlElement" => Variant::from( - body.children_with_name("XmlElement") - .map(|v| UAString::from(v.to_string())) - .collect::>(), - ), - "QualifiedName" => Variant::QualifiedName(FromXml::from_xml(body, ctx)?), - "ListOfQualifiedName" => Variant::from(children_with_name::( - body, - ctx, - "QualifiedName", - )?), - "LocalizedText" => Variant::LocalizedText(FromXml::from_xml(body, ctx)?), - "ListOfLocalizedText" => Variant::from(children_with_name::( - body, - ctx, - "LocalizedText", - )?), - "NodeId" => Variant::NodeId(FromXml::from_xml(body, ctx)?), - "ListOfNodeId" => Variant::from(children_with_name::(body, ctx, "NodeId")?), - "ExpandedNodeId" => Variant::ExpandedNodeId(FromXml::from_xml(body, ctx)?), - "ListOfExpandedNodeId" => Variant::from(children_with_name::( - body, - ctx, - "ExpandedNodeId", - )?), - "ExtensionObject" => Variant::ExtensionObject(FromXml::from_xml(body, ctx)?), - "ListOfExtensionObject" => Variant::from(children_with_name::( - body, - ctx, - "ExtensionObject", - )?), - "Variant" => Variant::Variant(FromXml::from_xml(body, ctx)?), - "ListOfVariant" => Variant::from(children_with_name::(body, ctx, "Variant")?), - "StatusCode" => Variant::StatusCode(FromXml::from_xml(body, ctx)?), - "ListOfStatusCode" => { - Variant::from(children_with_name::(body, ctx, "StatusCode")?) - } - r => return Err(Error::decoding(format!("Unexpected variant type: {r}"))), - }) - } - - fn default_or_required(_name: &'static str) -> EncodingResult { - Ok(Self::Empty) - } -} - -impl FromXml for Box -where - T: FromXml, -{ - fn from_xml(element: &XmlElement, ctx: &Context<'_>) -> EncodingResult { - Ok(Box::new(T::from_xml(element, ctx)?)) - } - - fn default_or_required(name: &'static str) -> EncodingResult { - Ok(Box::new(T::default_or_required(name)?)) - } -} - -/// `XmlField` is a convenience trait that wraps [`FromXml`] when the -/// XML node to extract is one or more fields of a parent node. -/// It is implemented for `T`, `Vec`, `Option`, and `Option>`, notably. -pub trait XmlField: Sized { - /// Get the child of `parent` with name `name` as `Self`. - fn get_xml_field( - parent: &XmlElement, - name: &'static str, - ctx: &Context<'_>, - ) -> EncodingResult; -} - -impl XmlField for T -where - T: FromXml, -{ - fn get_xml_field( - parent: &XmlElement, - name: &'static str, - ctx: &Context<'_>, - ) -> EncodingResult { - let Some(own) = parent.first_child_with_name(name) else { - return T::default_or_required(name); - }; - FromXml::from_xml(own, ctx) - } -} - -impl XmlField for Option -where - T: FromXml, -{ - fn get_xml_field( - parent: &XmlElement, - name: &'static str, - ctx: &Context<'_>, - ) -> EncodingResult { - let Some(own) = parent.first_child_with_name(name) else { - return Ok(None); - }; - Ok(Some(FromXml::from_xml(own, ctx)?)) - } -} - -impl XmlField for Vec -where - T: FromXml, -{ - fn get_xml_field( - parent: &XmlElement, - name: &'static str, - ctx: &Context<'_>, - ) -> EncodingResult { - parent - .children_with_name(name) - .map(|n| FromXml::from_xml(n, ctx)) - .collect() - } -} - -impl XmlField for Option> -where - T: FromXml, -{ - fn get_xml_field( - parent: &XmlElement, - name: &'static str, - ctx: &Context<'_>, - ) -> EncodingResult { - let v: Vec = parent - .children_with_name(name) - .map(|n| ::from_xml(n, ctx)) - .collect::, _>>()?; - if v.is_empty() { - Ok(None) - } else { - Ok(Some(v)) - } - } -} - fn mk_node_id(node_id: &opc_ua_types::NodeId, ctx: &Context<'_>) -> Result { let Some(idf) = &node_id.identifier else { return Ok(NodeId::null()); @@ -437,25 +39,40 @@ fn mk_node_id(node_id: &opc_ua_types::NodeId, ctx: &Context<'_>) -> Result, -) -> Result { - let Some(b) = ext_obj.body.as_ref() else { +) -> EncodingResult { + let Some(body) = &val.body else { return Ok(ExtensionObject::null()); }; - - let Some(type_id) = ext_obj.type_id.as_ref() else { + let Some(data) = &body.data else { return Ok(ExtensionObject::null()); }; - + let Some(type_id) = &val.type_id else { + return Err(Error::decoding("Extension object missing type ID")); + }; let node_id = mk_node_id(type_id, ctx)?; - - ctx.load_from_xml(&node_id, &b.data) + let mut cursor = Cursor::new(data.as_bytes()); + let mut stream = XmlStreamReader::new(&mut cursor as &mut dyn Read); + // Read the entry tag, as this is how extension objects are parsed + loop { + match stream.next_event()? { + Event::Start(_) => break, + Event::End(_) | Event::Eof | Event::Empty(_) => { + return Ok(ExtensionObject::null()); + } + _ => (), + } + } + ctx.load_from_xml(&node_id, &mut stream) } -use opcua_xml::schema::opc_ua_types::{self, Variant as XmlVariant}; - impl Variant { /// Create a Variant value from a NodeSet2 variant object. /// Note that this is different from the `FromXml` implementation of `Variant`, diff --git a/async-opcua-xml/src/encoding/reader.rs b/async-opcua-xml/src/encoding/reader.rs index 79b3e53d..7b2a8b41 100644 --- a/async-opcua-xml/src/encoding/reader.rs +++ b/async-opcua-xml/src/encoding/reader.rs @@ -45,10 +45,7 @@ impl XmlStreamReader { /// Get the next event from the stream. pub fn next_event(&mut self) -> Result { self.buffer.clear(); - match self.reader.read_event_into(&mut self.buffer)? { - Event::Eof => Err(XmlReadError::UnexpectedEof), - e => Ok(e), - } + Ok(self.reader.read_event_into(&mut self.buffer)?) } /// Skip the current value. This should be called after encountering a @@ -67,7 +64,13 @@ impl XmlStreamReader { return Ok(()); } } - Event::Eof => return Err(XmlReadError::UnexpectedEof), + Event::Eof => { + if depth == 1 { + return Ok(()); + } else { + return Err(XmlReadError::UnexpectedEof); + } + } _ => {} } } @@ -108,7 +111,20 @@ impl XmlStreamReader { } } - Event::Eof => return Err(XmlReadError::UnexpectedEof), + Event::Eof => { + println!("Eof {depth}"); + if depth == 1 { + if let Some(mut text) = text { + let trimmed = text.trim_ascii_end(); + text.truncate(trimmed.len()); + return Ok(text); + } else { + return Ok(String::new()); + } + } else { + return Err(XmlReadError::UnexpectedEof); + } + } _ => continue, } } diff --git a/async-opcua-xml/src/error.rs b/async-opcua-xml/src/error.rs index d722b461..dd2a5098 100644 --- a/async-opcua-xml/src/error.rs +++ b/async-opcua-xml/src/error.rs @@ -53,6 +53,15 @@ pub struct XmlError { pub error: XmlErrorInner, } +impl From for XmlError { + fn from(value: roxmltree::Error) -> Self { + Self { + span: 0..0, + error: XmlErrorInner::Xml(value), + } + } +} + impl XmlError { /// Create an error for a node with a missing field with name `name`. pub fn missing_field(node: &Node<'_, '_>, name: &str) -> Self { diff --git a/async-opcua-xml/src/schema/opc_ua_types.rs b/async-opcua-xml/src/schema/opc_ua_types.rs index 1cd200df..646258a3 100644 --- a/async-opcua-xml/src/schema/opc_ua_types.rs +++ b/async-opcua-xml/src/schema/opc_ua_types.rs @@ -10,8 +10,7 @@ use uuid::Uuid; use crate::{ ext::{ - children_of_type, children_with_name, first_child_of_type_req, first_child_with_name_opt, - value_from_contents_opt, + children_of_type, children_with_name, first_child_with_name_opt, value_from_contents_opt, }, XmlError, XmlLoad, }; @@ -313,6 +312,13 @@ impl XmlElement { .and_then(|c| c.text.as_ref()) .map(|c| c.as_str()) } + + /// Parse the XML element from a string. + pub fn parse(input: &str) -> Result, XmlError> { + let doc = roxmltree::Document::parse(input)?; + let root = doc.root_element(); + XmlLoad::load(&root) + } } #[derive(Debug)] @@ -355,13 +361,15 @@ impl<'input> XmlLoad<'input> for LocalizedText { /// Body of an extension object. pub struct ExtensionObjectBody { /// Raw extension object body, just an XML node. - pub data: XmlElement, + pub data: Option, } impl<'input> XmlLoad<'input> for ExtensionObjectBody { fn load(node: &Node<'_, 'input>) -> Result { Ok(Self { - data: first_child_of_type_req(node, "Body")?, + data: node + .first_element_child() + .map(|n| n.document().input_text()[n.range()].to_owned()), }) } } diff --git a/code_gen_config.yml b/code_gen_config.yml index 95d4aaff..de81b1cd 100644 --- a/code_gen_config.yml +++ b/code_gen_config.yml @@ -23,6 +23,7 @@ targets: mod opcua { pub use crate as types; } default_excluded: - AnonymousIdentityToken + - HistoryUpdateType - type: nodes file_path: schemas/1.05/Opc.Ua.NodeSet2.xml output_dir: async-opcua-core-namespace/src/generated diff --git a/samples/custom-codegen/src/generated/types/enums.rs b/samples/custom-codegen/src/generated/types/enums.rs index e454f646..32d18771 100644 --- a/samples/custom-codegen/src/generated/types/enums.rs +++ b/samples/custom-codegen/src/generated/types/enums.rs @@ -21,7 +21,14 @@ feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum IMTagSelectorEnumeration { #[opcua(default)] @@ -43,7 +50,14 @@ pub enum IMTagSelectorEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnARStateEnumeration { #[opcua(default)] @@ -67,7 +81,14 @@ pub enum PnARStateEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnARTypeEnumeration { #[opcua(default)] @@ -90,7 +111,14 @@ pub enum PnARTypeEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnAssetChangeEnumeration { #[opcua(default)] @@ -112,7 +140,14 @@ pub enum PnAssetChangeEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnAssetTypeEnumeration { #[opcua(default)] @@ -135,7 +170,14 @@ pub enum PnAssetTypeEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnChannelAccumulativeEnumeration { #[opcua(default)] @@ -156,7 +198,14 @@ pub enum PnChannelAccumulativeEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnChannelDirectionEnumeration { #[opcua(default)] @@ -179,7 +228,14 @@ pub enum PnChannelDirectionEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnChannelMaintenanceEnumeration { #[opcua(default)] @@ -202,7 +258,14 @@ pub enum PnChannelMaintenanceEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnChannelSpecifierEnumeration { #[opcua(default)] @@ -225,7 +288,14 @@ pub enum PnChannelSpecifierEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnChannelTypeEnumeration { #[opcua(default)] @@ -252,7 +322,14 @@ pub enum PnChannelTypeEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnDeviceStateEnumeration { #[opcua(default)] @@ -275,7 +352,14 @@ pub enum PnDeviceStateEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnLinkStateEnumeration { UP = 1i32, @@ -300,7 +384,14 @@ pub enum PnLinkStateEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnModuleStateEnumeration { #[opcua(default)] @@ -324,7 +415,14 @@ pub enum PnModuleStateEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnPortStateEnumeration { #[opcua(default)] @@ -350,7 +448,14 @@ pub enum PnPortStateEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnSubmoduleAddInfoEnumeration { #[opcua(default)] @@ -371,7 +476,14 @@ pub enum PnSubmoduleAddInfoEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnSubmoduleARInfoEnumeration { #[opcua(default)] @@ -395,7 +507,14 @@ pub enum PnSubmoduleARInfoEnumeration { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[repr(i32)] pub enum PnSubmoduleIdentInfoEnumeration { #[opcua(default)] diff --git a/samples/custom-codegen/src/generated/types/mod.rs b/samples/custom-codegen/src/generated/types/mod.rs index b0b88615..951b0b81 100644 --- a/samples/custom-codegen/src/generated/types/mod.rs +++ b/samples/custom-codegen/src/generated/types/mod.rs @@ -95,7 +95,7 @@ impl opcua::types::TypeLoader for GeneratedTypeLoader { fn load_from_xml( &self, node_id: &opcua::types::NodeId, - stream: &opcua::types::xml::XmlElement, + stream: &mut opcua::types::xml::XmlStreamReader<&mut dyn std::io::Read>, ctx: &opcua::types::Context<'_>, ) -> Option>> { let idx = ctx @@ -105,9 +105,9 @@ impl opcua::types::TypeLoader for GeneratedTypeLoader { return None; } let Some(num_id) = node_id.as_u32() else { - return Some(Err(opcua::types::Error::decoding(format!( - "Unsupported encoding ID {node_id}, we only support numeric IDs" - )))); + return Some(Err(opcua::types::Error::decoding( + "Unsupported encoding ID. Only numeric encoding IDs are currently supported", + ))); }; TYPES.decode_xml(num_id, stream, ctx) } diff --git a/samples/custom-codegen/src/generated/types/structs.rs b/samples/custom-codegen/src/generated/types/structs.rs index 67b3c193..a2a10e5c 100644 --- a/samples/custom-codegen/src/generated/types/structs.rs +++ b/samples/custom-codegen/src/generated/types/structs.rs @@ -12,7 +12,14 @@ feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PnDeviceDiagnosisDataType { pub api: u32, @@ -60,7 +67,14 @@ impl opcua::types::ExpandedMessageInfo for PnDeviceDiagnosisDataType { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PnDeviceRoleOptionSet { pub value: opcua::types::byte_string::ByteString, @@ -93,7 +107,14 @@ impl opcua::types::ExpandedMessageInfo for PnDeviceRoleOptionSet { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct PnIM5DataType { pub annotation: opcua::types::string::UAString, diff --git a/samples/demo-server/src/customs.rs b/samples/demo-server/src/customs.rs index 2f8b998a..da4b18f4 100644 --- a/samples/demo-server/src/customs.rs +++ b/samples/demo-server/src/customs.rs @@ -133,7 +133,14 @@ fn add_custom_data_type(nm: &SimpleNodeManager, ns: u16, e_state_id: &NodeId) -> feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] #[repr(i32)] pub enum AxisState { @@ -150,7 +157,14 @@ pub enum AxisState { feature = "json", derive(opcua::types::JsonEncodable, opcua::types::JsonDecodable) )] -#[cfg_attr(feature = "xml", derive(opcua::types::FromXml))] +#[cfg_attr( + feature = "xml", + derive( + opcua::types::XmlEncodable, + opcua::types::XmlDecodable, + opcua::types::XmlType + ) +)] #[derive(Default)] pub struct ErrorData { message: opcua::types::UAString,