diff --git a/async-opcua-types/src/json.rs b/async-opcua-types/src/json.rs index 43323c96..189fa514 100644 --- a/async-opcua-types/src/json.rs +++ b/async-opcua-types/src/json.rs @@ -303,3 +303,35 @@ pub fn write_raw_value( reader.transfer_to(r)?; Ok(()) } + +/// Utility method to encode an OPC-UA encodable type to a JSON string as UTF-8. +/// +/// `ctx` can be obtained by constructing a [ContextOwned](crate::ContextOwned), +/// and calling [context](crate::ContextOwned::context) on it. +pub fn to_bytes(value: &T, ctx: &Context<'_>) -> EncodingResult> { + let mut res = Vec::new(); + let mut stream = Cursor::new(&mut res); + let mut writer = JsonStreamWriter::new(&mut stream as &mut dyn Write); + value.encode(&mut writer, ctx)?; + writer.finish_document()?; + Ok(res) +} + +/// Utility method to encode an OPC-UA encodable type to a JSON string. +/// +/// `ctx` can be obtained by constructing a [ContextOwned](crate::ContextOwned), +/// and calling [context](crate::ContextOwned::context) on it. +pub fn to_string(value: &T, ctx: &Context<'_>) -> EncodingResult { + let bytes = to_bytes(value, ctx)?; + String::from_utf8(bytes).map_err(Error::decoding) +} + +/// Utility method to decode an OPC-UA decodable type from a JSON string as UTF-8. +/// +/// `ctx` can be obtained by constructing a [ContextOwned](crate::ContextOwned), +/// and calling [context](crate::ContextOwned::context) on it. +pub fn from_bytes(data: &[u8], ctx: &Context<'_>) -> EncodingResult { + let mut cursor = Cursor::new(data); + let mut reader = JsonStreamReader::new(&mut cursor as &mut dyn Read); + T::decode(&mut reader, ctx) +} diff --git a/async-opcua-types/src/tests/json.rs b/async-opcua-types/src/tests/json.rs index 17cfca24..616492f7 100644 --- a/async-opcua-types/src/tests/json.rs +++ b/async-opcua-types/src/tests/json.rs @@ -30,33 +30,17 @@ use crate::{ use crate::{ContextOwned, EncodingResult, ExtensionObject}; -fn ctx() -> ContextOwned { - ContextOwned::default() -} - fn from_value(v: Value) -> EncodingResult { let v = serde_json::to_string(&v).unwrap(); - let ctx = ctx(); - let stream = &mut v.as_bytes() as &mut dyn Read; - let mut reader = JsonStreamReader::new(stream); - T::decode(&mut reader, &ctx.context()) + from_str(&v) } fn from_str(v: &str) -> EncodingResult { - let ctx = ctx(); - let stream = &mut v.as_bytes() as &mut dyn Read; - let mut reader = JsonStreamReader::new(stream); - T::decode(&mut reader, &ctx.context()) + crate::json::from_bytes(v.as_bytes(), &ContextOwned::default().context()) } fn to_string(v: &T) -> EncodingResult { - let mut target = Vec::new(); - let mut stream = Cursor::new(&mut target); - let mut writer = JsonStreamWriter::new(&mut stream as &mut dyn Write); - let ctx = ctx(); - v.encode(&mut writer, &ctx.context())?; - writer.finish_document().unwrap(); - Ok(String::from_utf8(target).unwrap()) + crate::json::to_string(v, &ContextOwned::default().context()) } fn to_value(v: &T) -> EncodingResult { diff --git a/async-opcua-types/src/tests/xml.rs b/async-opcua-types/src/tests/xml.rs index 91a9b00c..10588929 100644 --- a/async-opcua-types/src/tests/xml.rs +++ b/async-opcua-types/src/tests/xml.rs @@ -1,8 +1,6 @@ -use std::io::{Cursor, Read, Write}; use std::str::FromStr; use opcua_macros::{XmlDecodable, XmlEncodable, XmlType}; -use opcua_xml::XmlStreamReader; use crate::xml::{XmlDecodable, XmlEncodable}; use crate::{ @@ -29,16 +27,11 @@ fn context<'a>(mapper: &'a NodeSetNamespaceMapper<'a>, owned: &'a ContextOwned) } 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) + crate::xml::from_bytes(data.as_bytes(), 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()) + crate::xml::to_string(data, ctx) } fn xml_round_trip_ctx( diff --git a/async-opcua-types/src/xml/encoding.rs b/async-opcua-types/src/xml/encoding.rs index 818d8cc7..2edea9d6 100644 --- a/async-opcua-types/src/xml/encoding.rs +++ b/async-opcua-types/src/xml/encoding.rs @@ -1,5 +1,5 @@ use std::{ - io::{Read, Write}, + io::{Cursor, Read, Write}, str::{from_utf8, Utf8Error}, }; @@ -226,3 +226,34 @@ impl XmlReadExt for XmlStreamReader<&mut dyn Read> { Ok(res) } } + +/// Utility method to encode an OPC-UA encodable type to an XML string as UTF-8. +/// +/// `ctx` can be obtained by constructing a [ContextOwned](crate::ContextOwned), +/// and calling [context](crate::ContextOwned::context) on it. +pub fn to_bytes(value: &T, ctx: &Context<'_>) -> EncodingResult> { + let mut res = Vec::new(); + let mut stream = Cursor::new(&mut res); + let mut writer = XmlStreamWriter::new(&mut stream as &mut dyn Write); + value.encode(&mut writer, ctx)?; + Ok(res) +} + +/// Utility method to encode an OPC-UA encodable type to an XML string. +/// +/// `ctx` can be obtained by constructing a [ContextOwned](crate::ContextOwned), +/// and calling [context](crate::ContextOwned::context) on it. +pub fn to_string(value: &T, ctx: &Context<'_>) -> EncodingResult { + let bytes = to_bytes(value, ctx)?; + String::from_utf8(bytes).map_err(Error::decoding) +} + +/// Utility method to decode an OPC-UA decodable type from an XML string as UTF-8. +/// +/// `ctx` can be obtained by constructing a [ContextOwned](crate::ContextOwned), +/// and calling [context](crate::ContextOwned::context) on it. +pub fn from_bytes(data: &[u8], ctx: &Context<'_>) -> EncodingResult { + let mut cursor = Cursor::new(data); + let mut reader = XmlStreamReader::new(&mut cursor as &mut dyn Read); + T::decode(&mut reader, ctx) +} diff --git a/async-opcua-types/src/xml/mod.rs b/async-opcua-types/src/xml/mod.rs index 5ba35c09..83d3957f 100644 --- a/async-opcua-types/src/xml/mod.rs +++ b/async-opcua-types/src/xml/mod.rs @@ -6,7 +6,9 @@ mod builtins; mod encoding; pub use crate::{Context, EncodingResult, Error}; -pub use encoding::{XmlDecodable, XmlEncodable, XmlReadExt, XmlType, XmlWriteExt}; +pub use encoding::{ + from_bytes, to_bytes, to_string, XmlDecodable, XmlEncodable, XmlReadExt, XmlType, XmlWriteExt, +}; pub use opcua_xml::{XmlStreamReader, XmlStreamWriter}; use std::{