1#![warn(missing_docs)]
2
3use ext::NodeExt;
15use roxmltree::Node;
16
17mod encoding;
18mod error;
19mod ext;
20pub mod schema;
21
22pub use encoding::{XmlReadError, XmlStreamReader, XmlStreamWriter, XmlWriteError};
23pub use quick_xml::events;
24
25pub use error::{XmlError, XmlErrorInner};
26pub use schema::opc_binary_schema::load_bsd_file;
27pub use schema::ua_node_set::load_nodeset2_file;
28pub use schema::xml_schema::load_xsd_schema;
29
30pub use schema::opc_ua_types::XmlElement;
31
32pub fn from_str<'a, T: XmlLoad<'a>>(data: &'a str) -> Result<T, XmlError> {
34 let doc = roxmltree::Document::parse(data).map_err(|e| XmlError {
35 span: 0..data.len(),
36 error: e.into(),
37 })?;
38 T::load(&doc.root().first_child().ok_or_else(|| XmlError {
39 span: doc.root().range(),
40 error: error::XmlErrorInner::MissingField("Root".to_owned()),
41 })?)
42}
43
44pub trait XmlLoad<'input>: Sized {
46 fn load(node: &Node<'_, 'input>) -> Result<Self, XmlError>;
48}
49
50pub trait FromValue: Sized {
52 fn from_value(node: &Node<'_, '_>, attr: &str, v: &str) -> Result<Self, XmlError>;
55}
56
57macro_rules! from_int {
58 ($ty:ident) => {
59 impl FromValue for $ty {
60 fn from_value(node: &Node<'_, '_>, attr: &str, v: &str) -> Result<Self, XmlError> {
61 v.parse().map_err(|e| XmlError::parse_int(node, attr, e))
62 }
63 }
64 };
65}
66
67from_int!(i64);
68from_int!(u64);
69from_int!(i32);
70from_int!(u32);
71from_int!(i16);
72from_int!(u16);
73from_int!(i8);
74from_int!(u8);
75
76impl FromValue for String {
77 fn from_value(_node: &Node<'_, '_>, _attr: &str, v: &str) -> Result<Self, XmlError> {
78 Ok(v.to_owned())
79 }
80}
81
82impl FromValue for f64 {
83 fn from_value(node: &Node<'_, '_>, attr: &str, v: &str) -> Result<Self, XmlError> {
84 v.parse().map_err(|e| XmlError::parse_float(node, attr, e))
85 }
86}
87
88impl FromValue for f32 {
89 fn from_value(node: &Node<'_, '_>, attr: &str, v: &str) -> Result<Self, XmlError> {
90 v.parse().map_err(|e| XmlError::parse_float(node, attr, e))
91 }
92}
93
94impl FromValue for bool {
95 fn from_value(node: &Node<'_, '_>, attr: &str, v: &str) -> Result<Self, XmlError> {
96 v.parse().map_err(|e| XmlError::parse_bool(node, attr, e))
97 }
98}
99
100impl<'input, T> XmlLoad<'input> for T
101where
102 T: FromValue + Default,
103{
104 fn load(node: &Node<'_, 'input>) -> Result<Self, XmlError> {
105 T::from_value(node, "content", node.try_contents().unwrap_or_default())
106 }
107}