opcua_types/variant/
into.rs1use uuid::Uuid;
2
3use crate::{
4 ByteString, DataValue, DateTime, DateTimeUtc, DiagnosticInfo, DynEncodable, ExpandedNodeId,
5 ExtensionObject, Guid, LocalizedText, NodeId, QualifiedName, StatusCode, UAString,
6};
7
8use super::{Array, Variant, VariantScalarTypeId, VariantType, XmlElement};
9
10pub trait IntoVariant {
18 fn into_variant(self) -> Variant;
20}
21
22macro_rules! impl_into_variant {
23 ($tp:ty, $venum:ident) => {
24 impl IntoVariant for $tp {
25 fn into_variant(self) -> Variant {
26 Variant::$venum(self)
27 }
28 }
29 };
30}
31
32macro_rules! impl_into_variant_boxed {
33 ($tp:ty, $venum:ident) => {
34 impl IntoVariant for $tp {
35 fn into_variant(self) -> Variant {
36 Variant::$venum(Box::new(self))
37 }
38 }
39
40 impl IntoVariant for Box<$tp> {
41 fn into_variant(self) -> Variant {
42 Variant::$venum(self)
43 }
44 }
45 };
46}
47
48impl From<()> for Variant {
49 fn from(_: ()) -> Self {
50 Variant::Empty
51 }
52}
53
54impl_into_variant!(bool, Boolean);
55impl_into_variant!(i8, SByte);
56impl_into_variant!(u8, Byte);
57impl_into_variant!(i16, Int16);
58impl_into_variant!(u16, UInt16);
59impl_into_variant!(i32, Int32);
60impl_into_variant!(u32, UInt32);
61impl_into_variant!(i64, Int64);
62impl_into_variant!(u64, UInt64);
63impl_into_variant!(f32, Float);
64impl_into_variant!(f64, Double);
65impl_into_variant!(UAString, String);
66impl_into_variant!(XmlElement, XmlElement);
67impl_into_variant_boxed!(DateTime, DateTime);
68impl_into_variant_boxed!(Guid, Guid);
69impl_into_variant!(StatusCode, StatusCode);
70impl_into_variant!(ByteString, ByteString);
71impl_into_variant_boxed!(QualifiedName, QualifiedName);
72impl_into_variant_boxed!(LocalizedText, LocalizedText);
73impl_into_variant_boxed!(NodeId, NodeId);
74impl_into_variant_boxed!(ExpandedNodeId, ExpandedNodeId);
75impl_into_variant!(ExtensionObject, ExtensionObject);
76impl_into_variant_boxed!(DataValue, DataValue);
77impl_into_variant_boxed!(DiagnosticInfo, DiagnosticInfo);
78impl_into_variant_boxed!(Array, Array);
79
80impl IntoVariant for &str {
81 fn into_variant(self) -> Variant {
82 Variant::String(UAString::from(self))
83 }
84}
85
86impl IntoVariant for String {
87 fn into_variant(self) -> Variant {
88 Variant::String(UAString::from(self))
89 }
90}
91
92impl IntoVariant for Uuid {
93 fn into_variant(self) -> Variant {
94 Variant::Guid(Box::new(self.into()))
95 }
96}
97
98impl IntoVariant for DateTimeUtc {
99 fn into_variant(self) -> Variant {
100 Variant::DateTime(Box::new(self.into()))
101 }
102}
103
104impl<T> IntoVariant for T
105where
106 T: DynEncodable,
107{
108 fn into_variant(self) -> Variant {
109 Variant::ExtensionObject(ExtensionObject::new(self))
110 }
111}
112
113impl<T> From<T> for Variant
114where
115 T: IntoVariant,
116{
117 fn from(value: T) -> Self {
118 value.into_variant()
119 }
120}
121
122impl<T> From<Option<T>> for Variant
123where
124 T: Into<Variant>,
125{
126 fn from(value: Option<T>) -> Self {
127 match value {
128 Some(v) => v.into(),
129 None => Variant::Empty,
130 }
131 }
132}
133
134impl<'a, T> From<&'a Vec<T>> for Variant
135where
136 T: Into<Variant> + VariantType + Clone,
137{
138 fn from(value: &'a Vec<T>) -> Self {
139 Self::from(value.as_slice())
140 }
141}
142
143impl<T> From<Vec<T>> for Variant
144where
145 T: Into<Variant> + VariantType,
146{
147 fn from(value: Vec<T>) -> Self {
148 let array: Vec<Variant> = value.into_iter().map(|v| v.into()).collect();
149 Variant::from((T::variant_type_id(), array))
150 }
151}
152
153impl<'a, T> From<&'a [T]> for Variant
154where
155 T: Into<Variant> + VariantType + Clone,
156{
157 fn from(value: &'a [T]) -> Self {
158 let array: Vec<Variant> = value.iter().map(|v| v.clone().into()).collect();
159 Variant::from((T::variant_type_id(), array))
160 }
161}
162
163impl<'a, 'b> From<(VariantScalarTypeId, &'a [&'b str])> for Variant {
164 fn from(v: (VariantScalarTypeId, &'a [&'b str])) -> Self {
165 let values: Vec<Variant> = v.1.iter().map(|v| Variant::from(*v)).collect();
166 let value = Array::new(v.0, values).unwrap();
167 Variant::from(value)
168 }
169}
170
171impl<T: Into<Variant>> From<(VariantScalarTypeId, Vec<T>)> for Variant {
172 fn from(v: (VariantScalarTypeId, Vec<T>)) -> Self {
173 let value = Array::new(v.0, v.1.into_iter().map(|v| v.into()).collect::<Vec<_>>()).unwrap();
174 Variant::from(value)
175 }
176}
177
178impl<T: Into<Variant>> From<(VariantScalarTypeId, Vec<T>, Vec<u32>)> for Variant {
179 fn from(v: (VariantScalarTypeId, Vec<T>, Vec<u32>)) -> Self {
180 let value = Array::new_multi(
181 v.0,
182 v.1.into_iter().map(|v| v.into()).collect::<Vec<_>>(),
183 v.2,
184 )
185 .unwrap();
186 Variant::from(value)
187 }
188}