1mod from;
9mod into;
10#[cfg(feature = "json")]
11mod json;
12mod type_id;
13#[cfg(feature = "xml")]
14mod xml;
15
16mod xml_element;
17
18pub use xml_element::XmlElement;
19
20pub use from::TryFromVariant;
21pub use into::IntoVariant;
22pub use type_id::*;
23
24use std::{
25 convert::TryFrom,
26 fmt,
27 io::{Read, Write},
28 str::FromStr,
29};
30
31use tracing::error;
32use uuid::Uuid;
33
34use crate::{
35 array::*,
36 byte_string::ByteString,
37 date_time::DateTime,
38 encoding::{BinaryDecodable, BinaryEncodable, EncodingResult},
39 expanded_node_id::ExpandedNodeId,
40 extension_object::ExtensionObject,
41 guid::Guid,
42 localized_text::LocalizedText,
43 node_id::NodeId,
44 numeric_range::NumericRange,
45 qualified_name::QualifiedName,
46 status_code::StatusCode,
47 string::UAString,
48 write_i32, write_u8, DataTypeId, DataValue, DiagnosticInfo, DynEncodable, Error, UaNullable,
49};
50#[derive(PartialEq, Debug, Clone, Default)]
56pub enum Variant {
57 #[default]
59 Empty,
60 Boolean(bool),
62 SByte(i8),
64 Byte(u8),
66 Int16(i16),
68 UInt16(u16),
70 Int32(i32),
72 UInt32(u32),
74 Int64(i64),
76 UInt64(u64),
78 Float(f32),
80 Double(f64),
82 String(UAString),
84 DateTime(Box<DateTime>),
86 Guid(Box<Guid>),
88 StatusCode(StatusCode),
90 ByteString(ByteString),
92 XmlElement(XmlElement),
94 QualifiedName(Box<QualifiedName>),
96 LocalizedText(Box<LocalizedText>),
98 NodeId(Box<NodeId>),
100 ExpandedNodeId(Box<ExpandedNodeId>),
102 ExtensionObject(ExtensionObject),
104 Variant(Box<Variant>),
106 DataValue(Box<DataValue>),
108 DiagnosticInfo(Box<DiagnosticInfo>),
110 Array(Box<Array>),
115}
116
117pub trait VariantType {
122 fn variant_type_id() -> VariantScalarTypeId;
124}
125
126impl<T> VariantType for T
128where
129 T: DynEncodable,
130{
131 fn variant_type_id() -> VariantScalarTypeId {
132 VariantScalarTypeId::ExtensionObject
133 }
134}
135
136macro_rules! impl_variant_type_for {
137 ($tp: ty, $vt: expr) => {
138 impl VariantType for $tp {
139 fn variant_type_id() -> VariantScalarTypeId {
140 $vt
141 }
142 }
143 };
144}
145impl_variant_type_for!(bool, VariantScalarTypeId::Boolean);
146impl_variant_type_for!(i8, VariantScalarTypeId::SByte);
147impl_variant_type_for!(u8, VariantScalarTypeId::Byte);
148impl_variant_type_for!(i16, VariantScalarTypeId::Int16);
149impl_variant_type_for!(u16, VariantScalarTypeId::UInt16);
150impl_variant_type_for!(i32, VariantScalarTypeId::Int32);
151impl_variant_type_for!(u32, VariantScalarTypeId::UInt32);
152impl_variant_type_for!(i64, VariantScalarTypeId::Int64);
153impl_variant_type_for!(u64, VariantScalarTypeId::UInt64);
154impl_variant_type_for!(f32, VariantScalarTypeId::Float);
155impl_variant_type_for!(f64, VariantScalarTypeId::Double);
156impl_variant_type_for!(UAString, VariantScalarTypeId::String);
157impl_variant_type_for!(String, VariantScalarTypeId::String);
158impl_variant_type_for!(&str, VariantScalarTypeId::String);
159impl_variant_type_for!(DateTime, VariantScalarTypeId::DateTime);
160impl_variant_type_for!(Guid, VariantScalarTypeId::Guid);
161impl_variant_type_for!(StatusCode, VariantScalarTypeId::StatusCode);
162impl_variant_type_for!(ByteString, VariantScalarTypeId::ByteString);
163impl_variant_type_for!(XmlElement, VariantScalarTypeId::XmlElement);
164impl_variant_type_for!(QualifiedName, VariantScalarTypeId::QualifiedName);
165impl_variant_type_for!(LocalizedText, VariantScalarTypeId::LocalizedText);
166impl_variant_type_for!(NodeId, VariantScalarTypeId::NodeId);
167impl_variant_type_for!(ExpandedNodeId, VariantScalarTypeId::ExpandedNodeId);
168impl_variant_type_for!(ExtensionObject, VariantScalarTypeId::ExtensionObject);
169impl_variant_type_for!(Variant, VariantScalarTypeId::Variant);
170impl_variant_type_for!(DataValue, VariantScalarTypeId::DataValue);
171impl_variant_type_for!(DiagnosticInfo, VariantScalarTypeId::DiagnosticInfo);
172impl_variant_type_for!(chrono::DateTime<chrono::Utc>, VariantScalarTypeId::DateTime);
173impl_variant_type_for!(Uuid, VariantScalarTypeId::Guid);
174
175macro_rules! cast_to_bool {
176 ($value: expr) => {
177 if $value == 1 {
178 true.into()
179 } else if $value == 0 {
180 false.into()
181 } else {
182 Variant::Empty
183 }
184 };
185}
186
187macro_rules! cast_to_integer {
188 ($value: expr, $from: ident, $to: ident) => {
189 {
190 let valid = if $value < 0 as $from {
193 $to::MIN != 0 && $value as i64 >= $to::MIN as i64
196 } else {
197 $value as u64 <= $to::MAX as u64
200 };
201 if !valid {
202 Variant::Empty
205 } else {
206 ($value as $to).into()
207 }
208 }
209 }
210}
211
212impl Variant {
213 pub fn value_byte_len(&self, ctx: &crate::Context<'_>) -> usize {
219 match self {
220 Variant::Empty => 0,
221 Variant::Boolean(value) => value.byte_len(ctx),
222 Variant::SByte(value) => value.byte_len(ctx),
223 Variant::Byte(value) => value.byte_len(ctx),
224 Variant::Int16(value) => value.byte_len(ctx),
225 Variant::UInt16(value) => value.byte_len(ctx),
226 Variant::Int32(value) => value.byte_len(ctx),
227 Variant::UInt32(value) => value.byte_len(ctx),
228 Variant::Int64(value) => value.byte_len(ctx),
229 Variant::UInt64(value) => value.byte_len(ctx),
230 Variant::Float(value) => value.byte_len(ctx),
231 Variant::Double(value) => value.byte_len(ctx),
232 Variant::String(value) => value.byte_len(ctx),
233 Variant::DateTime(value) => value.byte_len(ctx),
234 Variant::Guid(value) => value.byte_len(ctx),
235 Variant::ByteString(value) => value.byte_len(ctx),
236 Variant::XmlElement(value) => value.byte_len(ctx),
237 Variant::NodeId(value) => value.byte_len(ctx),
238 Variant::ExpandedNodeId(value) => value.byte_len(ctx),
239 Variant::StatusCode(value) => value.byte_len(ctx),
240 Variant::QualifiedName(value) => value.byte_len(ctx),
241 Variant::LocalizedText(value) => value.byte_len(ctx),
242 Variant::ExtensionObject(value) => value.byte_len(ctx),
243 Variant::DataValue(value) => value.byte_len(ctx),
244 Variant::Variant(value) => value.byte_len(ctx),
245 Variant::DiagnosticInfo(value) => value.byte_len(ctx),
246 Variant::Array(array) => {
247 let mut size = 4;
249 size += array
251 .values
252 .iter()
253 .map(|v| Variant::byte_len_variant_value(v, ctx))
254 .sum::<usize>();
255 if let Some(ref dimensions) = array.dimensions {
256 size += 4 + dimensions.len() * 4;
258 }
259 size
260 }
261 }
262 }
263
264 pub fn encode_value<S: Write + ?Sized>(
269 &self,
270 stream: &mut S,
271 ctx: &crate::Context<'_>,
272 ) -> EncodingResult<()> {
273 match self {
274 Variant::Empty => Ok(()),
275 Variant::Boolean(value) => value.encode(stream, ctx),
276 Variant::SByte(value) => value.encode(stream, ctx),
277 Variant::Byte(value) => value.encode(stream, ctx),
278 Variant::Int16(value) => value.encode(stream, ctx),
279 Variant::UInt16(value) => value.encode(stream, ctx),
280 Variant::Int32(value) => value.encode(stream, ctx),
281 Variant::UInt32(value) => value.encode(stream, ctx),
282 Variant::Int64(value) => value.encode(stream, ctx),
283 Variant::UInt64(value) => value.encode(stream, ctx),
284 Variant::Float(value) => value.encode(stream, ctx),
285 Variant::Double(value) => value.encode(stream, ctx),
286 Variant::String(value) => value.encode(stream, ctx),
287 Variant::DateTime(value) => value.encode(stream, ctx),
288 Variant::Guid(value) => value.encode(stream, ctx),
289 Variant::ByteString(value) => value.encode(stream, ctx),
290 Variant::XmlElement(value) => value.encode(stream, ctx),
291 Variant::NodeId(value) => value.encode(stream, ctx),
292 Variant::ExpandedNodeId(value) => value.encode(stream, ctx),
293 Variant::StatusCode(value) => value.encode(stream, ctx),
294 Variant::QualifiedName(value) => value.encode(stream, ctx),
295 Variant::LocalizedText(value) => value.encode(stream, ctx),
296 Variant::ExtensionObject(value) => value.encode(stream, ctx),
297 Variant::DataValue(value) => value.encode(stream, ctx),
298 Variant::Variant(value) => value.encode(stream, ctx),
299 Variant::DiagnosticInfo(value) => value.encode(stream, ctx),
300 Variant::Array(array) => {
301 write_i32(stream, array.values.len() as i32)?;
302 for value in array.values.iter() {
303 Variant::encode_variant_value(stream, value, ctx)?;
304 }
305 if let Some(ref dimensions) = array.dimensions {
306 write_i32(stream, dimensions.len() as i32)?;
311 for dimension in dimensions {
313 write_i32(stream, *dimension as i32)?;
314 }
315 }
316 Ok(())
317 }
318 }
319 }
320}
321
322impl UaNullable for Variant {
323 fn is_ua_null(&self) -> bool {
324 self.is_empty()
325 }
326}
327
328impl BinaryEncodable for Variant {
329 fn byte_len(&self, ctx: &crate::Context<'_>) -> usize {
330 let mut size: usize = 0;
331
332 size += 1;
334
335 size += self.value_byte_len(ctx);
337
338 size
339 }
340
341 fn encode<S: Write + ?Sized>(
342 &self,
343 stream: &mut S,
344 ctx: &crate::Context<'_>,
345 ) -> EncodingResult<()> {
346 let encoding_mask = self.encoding_mask();
348 write_u8(stream, encoding_mask)?;
349
350 self.encode_value(stream, ctx)
351 }
352}
353
354impl BinaryDecodable for Variant {
355 fn decode<S: Read + ?Sized>(stream: &mut S, ctx: &crate::Context<'_>) -> EncodingResult<Self> {
356 let encoding_mask = u8::decode(stream, ctx)?;
357 let element_encoding_mask = encoding_mask & !EncodingMask::ARRAY_MASK;
358
359 let array_length = if encoding_mask & EncodingMask::ARRAY_VALUES_BIT != 0 {
366 let array_length = i32::decode(stream, ctx)?;
367 if array_length < -1 {
368 return Err(Error::decoding(format!(
369 "Invalid array_length {array_length}"
370 )));
371 }
372
373 if array_length <= 0 {
375 let value_type_id = VariantScalarTypeId::from_encoding_mask(element_encoding_mask)
376 .ok_or_else(|| {
377 Error::decoding(format!(
378 "Unrecognized encoding mask: {element_encoding_mask}"
379 ))
380 })?;
381 return Array::new_multi(value_type_id, Vec::new(), Vec::new())
382 .map(Variant::from)
383 .map_err(Error::decoding);
384 }
385 array_length
386 } else {
387 -1
388 };
389
390 if array_length > 0 {
392 let array_length = array_length as usize;
394 if array_length > ctx.options().max_array_length {
395 return Err(Error::new(StatusCode::BadEncodingLimitsExceeded, format!(
396 "Variant array has length {} which exceeds configured array length limit {}", array_length, ctx.options().max_array_length
397 )));
398 }
399
400 let mut values: Vec<Variant> = Vec::with_capacity(array_length);
401 for _ in 0..array_length {
402 values.push(Variant::decode_variant_value(
403 stream,
404 element_encoding_mask,
405 ctx,
406 )?);
407 }
408 let value_type_id = VariantScalarTypeId::from_encoding_mask(element_encoding_mask)
409 .ok_or_else(|| {
410 Error::decoding(format!(
411 "Unrecognized encoding mask: {element_encoding_mask}"
412 ))
413 })?;
414 if encoding_mask & EncodingMask::ARRAY_DIMENSIONS_BIT != 0 {
415 if let Some(dimensions) = <Option<Vec<_>>>::decode(stream, ctx)? {
416 if dimensions.contains(&0) {
417 Err(Error::decoding(
418 "Invalid variant array dimensions, one or more dimensions are 0",
419 ))
420 } else {
421 let mut array_dimensions_length = 1u32;
424 for d in &dimensions {
425 if let Some(v) = array_dimensions_length.checked_mul(*d) {
426 array_dimensions_length = v;
427 } else {
428 return Err(Error::decoding("Array dimension overflow"));
429 }
430 }
431 if array_dimensions_length != array_length as u32 {
432 Err(Error::decoding(format!(
433 "Array dimensions does not match array length {array_length}"
434 )))
435 } else {
436 Ok(Array::new_multi(value_type_id, values, dimensions)
438 .map(Variant::from)
439 .map_err(Error::decoding)?)
440 }
441 }
442 } else {
443 Err(Error::decoding(
444 "No array dimensions despite the bit flag being set",
445 ))
446 }
447 } else {
448 Ok(Array::new(value_type_id, values)
450 .map(Variant::from)
451 .map_err(Error::decoding)?)
452 }
453 } else if encoding_mask & EncodingMask::ARRAY_DIMENSIONS_BIT != 0 {
454 Err(Error::decoding(
455 "Array dimensions bit specified without any values",
456 ))
457 } else {
458 Variant::decode_variant_value(stream, element_encoding_mask, ctx)
460 }
461 }
462}
463
464impl fmt::Display for Variant {
467 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
468 match self {
469 Variant::SByte(v) => write!(f, "{v}"),
470 Variant::Byte(v) => write!(f, "{v}"),
471 Variant::Int16(v) => write!(f, "{v}"),
472 Variant::UInt16(v) => write!(f, "{v}"),
473 Variant::Int32(v) => write!(f, "{v}"),
474 Variant::UInt32(v) => write!(f, "{v}"),
475 Variant::Int64(v) => write!(f, "{v}"),
476 Variant::UInt64(v) => write!(f, "{v}"),
477 Variant::Float(v) => write!(f, "{v}"),
478 Variant::Double(v) => write!(f, "{v}"),
479 Variant::Boolean(v) => write!(f, "{v}"),
480 Variant::String(ref v) => write!(f, "{v}"),
481 Variant::Guid(ref v) => write!(f, "{v}"),
482 Variant::DateTime(ref v) => write!(f, "{v}"),
483 Variant::NodeId(ref v) => write!(f, "{v}"),
484 Variant::ExpandedNodeId(ref v) => write!(f, "{v}"),
485 Variant::Variant(ref v) => write!(f, "Variant({v})"),
486 value => write!(f, "{value:?}"),
487 }
488 }
489}
490
491impl Variant {
492 pub fn test_encoding_flag(encoding_mask: u8, flag: u8) -> bool {
494 encoding_mask == flag
495 }
496
497 fn byte_len_variant_value(value: &Variant, ctx: &crate::Context<'_>) -> usize {
499 match value {
500 Variant::Empty => 0,
501 Variant::Boolean(value) => value.byte_len(ctx),
502 Variant::SByte(value) => value.byte_len(ctx),
503 Variant::Byte(value) => value.byte_len(ctx),
504 Variant::Int16(value) => value.byte_len(ctx),
505 Variant::UInt16(value) => value.byte_len(ctx),
506 Variant::Int32(value) => value.byte_len(ctx),
507 Variant::UInt32(value) => value.byte_len(ctx),
508 Variant::Int64(value) => value.byte_len(ctx),
509 Variant::UInt64(value) => value.byte_len(ctx),
510 Variant::Float(value) => value.byte_len(ctx),
511 Variant::Double(value) => value.byte_len(ctx),
512 Variant::String(value) => value.byte_len(ctx),
513 Variant::DateTime(value) => value.byte_len(ctx),
514 Variant::Guid(value) => value.byte_len(ctx),
515 Variant::ByteString(value) => value.byte_len(ctx),
516 Variant::XmlElement(value) => value.byte_len(ctx),
517 Variant::NodeId(value) => value.byte_len(ctx),
518 Variant::ExpandedNodeId(value) => value.byte_len(ctx),
519 Variant::StatusCode(value) => value.byte_len(ctx),
520 Variant::QualifiedName(value) => value.byte_len(ctx),
521 Variant::LocalizedText(value) => value.byte_len(ctx),
522 Variant::ExtensionObject(value) => value.byte_len(ctx),
523 Variant::Variant(value) => value.byte_len(ctx),
524 Variant::DataValue(value) => value.byte_len(ctx),
525 Variant::DiagnosticInfo(value) => value.byte_len(ctx),
526 _ => {
527 error!("Cannot compute length of this type (probably nested array)");
528 0
529 }
530 }
531 }
532
533 fn encode_variant_value<S: Write + ?Sized>(
535 stream: &mut S,
536 value: &Variant,
537 ctx: &crate::Context<'_>,
538 ) -> EncodingResult<()> {
539 match value {
540 Variant::Empty => Ok(()),
541 Variant::Boolean(value) => value.encode(stream, ctx),
542 Variant::SByte(value) => value.encode(stream, ctx),
543 Variant::Byte(value) => value.encode(stream, ctx),
544 Variant::Int16(value) => value.encode(stream, ctx),
545 Variant::UInt16(value) => value.encode(stream, ctx),
546 Variant::Int32(value) => value.encode(stream, ctx),
547 Variant::UInt32(value) => value.encode(stream, ctx),
548 Variant::Int64(value) => value.encode(stream, ctx),
549 Variant::UInt64(value) => value.encode(stream, ctx),
550 Variant::Float(value) => value.encode(stream, ctx),
551 Variant::Double(value) => value.encode(stream, ctx),
552 Variant::String(value) => value.encode(stream, ctx),
553 Variant::DateTime(value) => value.encode(stream, ctx),
554 Variant::Guid(value) => value.encode(stream, ctx),
555 Variant::ByteString(value) => value.encode(stream, ctx),
556 Variant::XmlElement(value) => value.encode(stream, ctx),
557 Variant::NodeId(value) => value.encode(stream, ctx),
558 Variant::ExpandedNodeId(value) => value.encode(stream, ctx),
559 Variant::StatusCode(value) => value.encode(stream, ctx),
560 Variant::QualifiedName(value) => value.encode(stream, ctx),
561 Variant::LocalizedText(value) => value.encode(stream, ctx),
562 Variant::ExtensionObject(value) => value.encode(stream, ctx),
563 Variant::Variant(value) => value.encode(stream, ctx),
564 Variant::DataValue(value) => value.encode(stream, ctx),
565 Variant::DiagnosticInfo(value) => value.encode(stream, ctx),
566 _ => Err(Error::encoding(
567 "Cannot encode this variant value type (probably nested array)",
568 )),
569 }
570 }
571
572 fn decode_variant_value<S: Read + ?Sized>(
574 stream: &mut S,
575 encoding_mask: u8,
576 ctx: &crate::Context<'_>,
577 ) -> EncodingResult<Self> {
578 let result = if encoding_mask == 0 {
579 Variant::Empty
580 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::BOOLEAN) {
581 Self::from(bool::decode(stream, ctx)?)
582 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::SBYTE) {
583 Self::from(i8::decode(stream, ctx)?)
584 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::BYTE) {
585 Self::from(u8::decode(stream, ctx)?)
586 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::INT16) {
587 Self::from(i16::decode(stream, ctx)?)
588 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::UINT16) {
589 Self::from(u16::decode(stream, ctx)?)
590 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::INT32) {
591 Self::from(i32::decode(stream, ctx)?)
592 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::UINT32) {
593 Self::from(u32::decode(stream, ctx)?)
594 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::INT64) {
595 Self::from(i64::decode(stream, ctx)?)
596 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::UINT64) {
597 Self::from(u64::decode(stream, ctx)?)
598 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::FLOAT) {
599 Self::from(f32::decode(stream, ctx)?)
600 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::DOUBLE) {
601 Self::from(f64::decode(stream, ctx)?)
602 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::STRING) {
603 Self::from(UAString::decode(stream, ctx)?)
604 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::DATE_TIME) {
605 Self::from(DateTime::decode(stream, ctx)?)
606 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::GUID) {
607 Self::from(Guid::decode(stream, ctx)?)
608 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::BYTE_STRING) {
609 Self::from(ByteString::decode(stream, ctx)?)
610 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::XML_ELEMENT) {
611 Variant::XmlElement(XmlElement::decode(stream, ctx)?)
613 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::NODE_ID) {
614 Self::from(NodeId::decode(stream, ctx)?)
615 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::EXPANDED_NODE_ID) {
616 Self::from(ExpandedNodeId::decode(stream, ctx)?)
617 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::STATUS_CODE) {
618 Self::from(StatusCode::decode(stream, ctx)?)
619 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::QUALIFIED_NAME) {
620 Self::from(QualifiedName::decode(stream, ctx)?)
621 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::LOCALIZED_TEXT) {
622 Self::from(LocalizedText::decode(stream, ctx)?)
623 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::EXTENSION_OBJECT) {
624 Self::from(ExtensionObject::decode(stream, ctx)?)
626 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::VARIANT) {
627 let _depth_lock = ctx.options().depth_lock()?;
629 Variant::Variant(Box::new(Variant::decode(stream, ctx)?))
630 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::DATA_VALUE) {
631 Self::from(DataValue::decode(stream, ctx)?)
632 } else if Self::test_encoding_flag(encoding_mask, EncodingMask::DIAGNOSTIC_INFO) {
633 Self::from(DiagnosticInfo::decode(stream, ctx)?)
634 } else {
635 Variant::Empty
636 };
637 Ok(result)
638 }
639
640 fn cast_scalar(&self, target_type: VariantScalarTypeId) -> Variant {
641 match *self {
642 Variant::Boolean(v) => match target_type {
643 VariantScalarTypeId::Byte => Variant::Byte(u8::from(v)),
644 VariantScalarTypeId::SByte => Variant::SByte(i8::from(v)),
645 VariantScalarTypeId::Float => Variant::Float(f32::from(v)),
646 VariantScalarTypeId::Int16 => Variant::Int16(i16::from(v)),
647 VariantScalarTypeId::Int32 => Variant::Int32(i32::from(v)),
648 VariantScalarTypeId::Int64 => Variant::Int64(i64::from(v)),
649 VariantScalarTypeId::UInt16 => Variant::UInt16(u16::from(v)),
650 VariantScalarTypeId::UInt32 => Variant::UInt32(u32::from(v)),
651 VariantScalarTypeId::UInt64 => Variant::UInt64(u64::from(v)),
652 VariantScalarTypeId::Double => Variant::Double(f64::from(v)),
653 VariantScalarTypeId::String => {
654 UAString::from(if v { "true" } else { "false" }).into()
655 }
656 _ => Variant::Empty,
657 },
658 Variant::Byte(v) => match target_type {
659 VariantScalarTypeId::Boolean => cast_to_bool!(v),
660 VariantScalarTypeId::String => format!("{v}").into(),
661 _ => Variant::Empty,
662 },
663 Variant::Double(v) => {
664 let vt = f64::trunc(v + 0.5);
666 match target_type {
667 VariantScalarTypeId::Boolean => cast_to_bool!(v as i64),
668 VariantScalarTypeId::Byte => cast_to_integer!(vt, f64, u8),
669 VariantScalarTypeId::Float => (v as f32).into(),
670 VariantScalarTypeId::Int16 => cast_to_integer!(vt, f64, i16),
671 VariantScalarTypeId::Int32 => cast_to_integer!(vt, f64, i32),
672 VariantScalarTypeId::Int64 => cast_to_integer!(vt, f64, i64),
673 VariantScalarTypeId::SByte => cast_to_integer!(vt, f64, i8),
674 VariantScalarTypeId::String => format!("{v}").into(),
675 VariantScalarTypeId::UInt16 => cast_to_integer!(vt, f64, u16),
676 VariantScalarTypeId::UInt32 => cast_to_integer!(vt, f64, u32),
677 VariantScalarTypeId::UInt64 => cast_to_integer!(vt, f64, u64),
678 _ => Variant::Empty,
679 }
680 }
681 Variant::ByteString(ref v) => match target_type {
682 VariantScalarTypeId::Guid => Guid::try_from(v)
683 .map(|v| v.into())
684 .unwrap_or(Variant::Empty),
685 _ => Variant::Empty,
686 },
687 Variant::DateTime(ref v) => match target_type {
688 VariantScalarTypeId::String => format!("{}", *v).into(),
689 _ => Variant::Empty,
690 },
691 Variant::ExpandedNodeId(ref v) => match target_type {
692 VariantScalarTypeId::NodeId => v.node_id.clone().into(),
693 _ => Variant::Empty,
694 },
695 Variant::Float(v) => {
696 let vt = f32::trunc(v + 0.5);
697 match target_type {
698 VariantScalarTypeId::Boolean => cast_to_bool!(v as i64),
699 VariantScalarTypeId::Byte => cast_to_integer!(vt, f32, u8),
700 VariantScalarTypeId::Int16 => cast_to_integer!(vt, f32, i16),
701 VariantScalarTypeId::Int32 => cast_to_integer!(vt, f32, i32),
702 VariantScalarTypeId::Int64 => cast_to_integer!(vt, f32, i64),
703 VariantScalarTypeId::SByte => cast_to_integer!(vt, f32, i8),
704 VariantScalarTypeId::String => format!("{v}").into(),
705 VariantScalarTypeId::UInt16 => cast_to_integer!(vt, f32, u16),
706 VariantScalarTypeId::UInt32 => cast_to_integer!(vt, f32, u32),
707 VariantScalarTypeId::UInt64 => cast_to_integer!(vt, f32, u64),
708 _ => Variant::Empty,
709 }
710 }
711 Variant::Guid(ref v) => match target_type {
712 VariantScalarTypeId::String => format!("{}", *v).into(),
713 VariantScalarTypeId::ByteString => ByteString::from(v.as_ref().clone()).into(),
714 _ => Variant::Empty,
715 },
716 Variant::Int16(v) => match target_type {
717 VariantScalarTypeId::Boolean => cast_to_bool!(v),
718 VariantScalarTypeId::Byte => cast_to_integer!(v, i16, u8),
719 VariantScalarTypeId::SByte => cast_to_integer!(v, i16, i8),
720 VariantScalarTypeId::String => format!("{v}").into(),
721 VariantScalarTypeId::UInt16 => cast_to_integer!(v, i16, u16),
722 _ => Variant::Empty,
723 },
724 Variant::Int32(v) => match target_type {
725 VariantScalarTypeId::Boolean => cast_to_bool!(v),
726 VariantScalarTypeId::Byte => cast_to_integer!(v, i32, u8),
727 VariantScalarTypeId::Int16 => cast_to_integer!(v, i32, i16),
728 VariantScalarTypeId::SByte => cast_to_integer!(v, i32, i8),
729 VariantScalarTypeId::StatusCode => (StatusCode::from(v as u32)).into(),
730 VariantScalarTypeId::String => format!("{v}").into(),
731 VariantScalarTypeId::UInt16 => cast_to_integer!(v, i32, u16),
732 VariantScalarTypeId::UInt32 => cast_to_integer!(v, i32, u32),
733 _ => Variant::Empty,
734 },
735 Variant::Int64(v) => match target_type {
736 VariantScalarTypeId::Boolean => cast_to_bool!(v),
737 VariantScalarTypeId::Byte => cast_to_integer!(v, i64, u8),
738 VariantScalarTypeId::Int16 => cast_to_integer!(v, i64, i16),
739 VariantScalarTypeId::Int32 => cast_to_integer!(v, i64, i32),
740 VariantScalarTypeId::SByte => cast_to_integer!(v, i64, i8),
741 VariantScalarTypeId::StatusCode => StatusCode::from(v as u32).into(),
742 VariantScalarTypeId::String => format!("{v}").into(),
743 VariantScalarTypeId::UInt16 => cast_to_integer!(v, i64, u16),
744 VariantScalarTypeId::UInt32 => cast_to_integer!(v, i64, u32),
745 VariantScalarTypeId::UInt64 => cast_to_integer!(v, i64, u64),
746 _ => Variant::Empty,
747 },
748 Variant::SByte(v) => match target_type {
749 VariantScalarTypeId::Boolean => cast_to_bool!(v),
750 VariantScalarTypeId::Byte => cast_to_integer!(v, i8, u8),
751 VariantScalarTypeId::String => format!("{v}").into(),
752 _ => Variant::Empty,
753 },
754 Variant::StatusCode(v) => match target_type {
755 VariantScalarTypeId::UInt16 => (((v.bits() & 0xffff_0000) >> 16) as u16).into(),
756 _ => Variant::Empty,
757 },
758 Variant::String(ref v) => match target_type {
759 VariantScalarTypeId::NodeId => {
760 if v.is_null() {
761 Variant::Empty
762 } else {
763 NodeId::from_str(v.as_ref())
764 .map(|v| v.into())
765 .unwrap_or(Variant::Empty)
766 }
767 }
768 VariantScalarTypeId::ExpandedNodeId => {
769 if v.is_null() {
770 Variant::Empty
771 } else {
772 ExpandedNodeId::from_str(v.as_ref())
773 .map(|v| v.into())
774 .unwrap_or(Variant::Empty)
775 }
776 }
777 VariantScalarTypeId::DateTime => {
778 if v.is_null() {
779 Variant::Empty
780 } else {
781 DateTime::from_str(v.as_ref())
782 .map(|v| v.into())
783 .unwrap_or(Variant::Empty)
784 }
785 }
786 VariantScalarTypeId::LocalizedText => {
787 if v.is_null() {
788 LocalizedText::null().into()
789 } else {
790 LocalizedText::new("", v.as_ref()).into()
791 }
792 }
793 VariantScalarTypeId::QualifiedName => {
794 if v.is_null() {
795 QualifiedName::null().into()
796 } else {
797 QualifiedName::new(0, v.as_ref()).into()
798 }
799 }
800 _ => Variant::Empty,
801 },
802 Variant::UInt16(v) => match target_type {
803 VariantScalarTypeId::Boolean => cast_to_bool!(v),
804 VariantScalarTypeId::Byte => cast_to_integer!(v, u16, u8),
805 VariantScalarTypeId::SByte => cast_to_integer!(v, u16, i8),
806 VariantScalarTypeId::String => format!("{v}").into(),
807 _ => Variant::Empty,
808 },
809 Variant::UInt32(v) => match target_type {
810 VariantScalarTypeId::Boolean => cast_to_bool!(v),
811 VariantScalarTypeId::Byte => cast_to_integer!(v, u32, u8),
812 VariantScalarTypeId::Int16 => cast_to_integer!(v, u32, i16),
813 VariantScalarTypeId::SByte => cast_to_integer!(v, u32, i8),
814 VariantScalarTypeId::StatusCode => StatusCode::from(v).into(),
815 VariantScalarTypeId::String => format!("{v}").into(),
816 VariantScalarTypeId::UInt16 => cast_to_integer!(v, u32, u16),
817 _ => Variant::Empty,
818 },
819 Variant::UInt64(v) => match target_type {
820 VariantScalarTypeId::Boolean => cast_to_bool!(v),
821 VariantScalarTypeId::Byte => cast_to_integer!(v, u64, u8),
822 VariantScalarTypeId::Int16 => cast_to_integer!(v, u64, i16),
823 VariantScalarTypeId::SByte => cast_to_integer!(v, u64, i8),
824 VariantScalarTypeId::StatusCode => {
825 StatusCode::from((v & 0x0000_0000_ffff_ffff) as u32).into()
826 }
827 VariantScalarTypeId::String => format!("{v}").into(),
828 VariantScalarTypeId::UInt16 => cast_to_integer!(v, u64, u16),
829 VariantScalarTypeId::UInt32 => cast_to_integer!(v, u64, u32),
830 _ => Variant::Empty,
831 },
832
833 _ => Variant::Empty,
835 }
836 }
837
838 fn cast_array(&self, target_type: VariantScalarTypeId, dims: Option<&[u32]>) -> Variant {
839 match self {
840 Variant::Array(a) => {
841 if let Some(dim) = dims {
843 let len: usize = dim
844 .iter()
845 .map(|v| *v as usize)
846 .reduce(|l, r| l * r)
847 .unwrap_or(0);
848 if len != a.values.len() {
849 return Variant::Empty;
850 }
851 }
852
853 let mut res = Vec::with_capacity(a.values.len());
854 for v in a.values.iter() {
855 let conv = v.cast(target_type);
856 if matches!(conv, Variant::Empty) {
857 return Variant::Empty;
858 }
859 res.push(conv);
860 }
861
862 Variant::Array(Box::new(Array {
863 value_type: target_type,
864 values: res,
865 dimensions: dims.map(|d| d.to_vec()).or_else(|| a.dimensions.clone()),
866 }))
867 }
868 scalar => {
869 if let Some(dims) = dims {
870 if dims.len() != 1 || dims[0] != 1 {
871 return Variant::Empty;
872 }
873 }
874 let converted = scalar.cast(target_type);
875 if matches!(converted, Variant::Empty) {
876 return converted;
877 }
878 Self::Array(Box::new(Array {
879 value_type: target_type,
880 values: vec![converted],
881 dimensions: dims.map(|d| d.to_vec()),
882 }))
883 }
884 }
885 }
886
887 pub fn cast<'a>(&self, target_type: impl Into<VariantTypeId<'a>>) -> Variant {
890 let target_type: VariantTypeId = target_type.into();
891 let self_type = self.type_id();
892 if self_type == target_type {
893 return self.clone();
894 }
895
896 let result = self.convert(target_type);
897 if !matches!(result, Variant::Empty) {
898 return result;
899 }
900
901 match target_type {
902 VariantTypeId::Empty => Variant::Empty,
903 VariantTypeId::Scalar(s) => self.cast_scalar(s),
904 VariantTypeId::Array(s, d) => self.cast_array(s, d),
905 }
906 }
907
908 fn convert_scalar(&self, target_type: VariantScalarTypeId) -> Variant {
909 match *self {
911 Variant::Boolean(v) => {
912 match target_type {
914 VariantScalarTypeId::Byte => (v as u8).into(),
915 VariantScalarTypeId::Double => ((v as u8) as f64).into(),
916 VariantScalarTypeId::Float => ((v as u8) as f32).into(),
917 VariantScalarTypeId::Int16 => (v as i16).into(),
918 VariantScalarTypeId::Int32 => (v as i32).into(),
919 VariantScalarTypeId::Int64 => (v as i64).into(),
920 VariantScalarTypeId::SByte => (v as i8).into(),
921 VariantScalarTypeId::UInt16 => (v as u16).into(),
922 VariantScalarTypeId::UInt32 => (v as u32).into(),
923 VariantScalarTypeId::UInt64 => (v as u64).into(),
924 _ => Variant::Empty,
925 }
926 }
927 Variant::Byte(v) => match target_type {
928 VariantScalarTypeId::Double => (v as f64).into(),
929 VariantScalarTypeId::Float => (v as f32).into(),
930 VariantScalarTypeId::Int16 => (v as i16).into(),
931 VariantScalarTypeId::Int32 => (v as i32).into(),
932 VariantScalarTypeId::Int64 => (v as i64).into(),
933 VariantScalarTypeId::SByte => (v as i8).into(),
934 VariantScalarTypeId::UInt16 => (v as u16).into(),
935 VariantScalarTypeId::UInt32 => (v as u32).into(),
936 VariantScalarTypeId::UInt64 => (v as u64).into(),
937 _ => Variant::Empty,
938 },
939
940 Variant::ExpandedNodeId(ref v) => {
944 match target_type {
946 VariantScalarTypeId::String => format!("{v}").into(),
947 _ => Variant::Empty,
948 }
949 }
950 Variant::Float(v) => {
951 match target_type {
953 VariantScalarTypeId::Double => (v as f64).into(),
954 _ => Variant::Empty,
955 }
956 }
957
958 Variant::Int16(v) => match target_type {
960 VariantScalarTypeId::Double => (v as f64).into(),
961 VariantScalarTypeId::Float => (v as f32).into(),
962 VariantScalarTypeId::Int32 => (v as i32).into(),
963 VariantScalarTypeId::Int64 => (v as i64).into(),
964 VariantScalarTypeId::UInt32 => {
965 if v < 0 {
966 Variant::Empty
967 } else {
968 (v as u32).into()
969 }
970 }
971 VariantScalarTypeId::UInt64 => {
972 if v < 0 {
973 Variant::Empty
974 } else {
975 (v as u64).into()
976 }
977 }
978 _ => Variant::Empty,
979 },
980 Variant::Int32(v) => match target_type {
981 VariantScalarTypeId::Double => (v as f64).into(),
982 VariantScalarTypeId::Float => (v as f32).into(),
983 VariantScalarTypeId::Int64 => (v as i64).into(),
984 VariantScalarTypeId::UInt64 => {
985 if v < 0 {
986 Variant::Empty
987 } else {
988 (v as u64).into()
989 }
990 }
991 _ => Variant::Empty,
992 },
993 Variant::Int64(v) => match target_type {
994 VariantScalarTypeId::Double => (v as f64).into(),
995 VariantScalarTypeId::Float => (v as f32).into(),
996 _ => Variant::Empty,
997 },
998 Variant::NodeId(ref v) => {
999 match target_type {
1001 VariantScalarTypeId::ExpandedNodeId => ExpandedNodeId::from(*v.clone()).into(),
1002 VariantScalarTypeId::String => format!("{v}").into(),
1003 _ => Variant::Empty,
1004 }
1005 }
1006 Variant::SByte(v) => match target_type {
1007 VariantScalarTypeId::Double => (v as f64).into(),
1008 VariantScalarTypeId::Float => (v as f32).into(),
1009 VariantScalarTypeId::Int16 => (v as i16).into(),
1010 VariantScalarTypeId::Int32 => (v as i32).into(),
1011 VariantScalarTypeId::Int64 => (v as i64).into(),
1012 VariantScalarTypeId::UInt16 => {
1013 if v < 0 {
1014 Variant::Empty
1015 } else {
1016 (v as u16).into()
1017 }
1018 }
1019 VariantScalarTypeId::UInt32 => {
1020 if v < 0 {
1021 Variant::Empty
1022 } else {
1023 (v as u32).into()
1024 }
1025 }
1026 VariantScalarTypeId::UInt64 => {
1027 if v < 0 {
1028 Variant::Empty
1029 } else {
1030 (v as u64).into()
1031 }
1032 }
1033 _ => Variant::Empty,
1034 },
1035 Variant::StatusCode(v) => match target_type {
1036 VariantScalarTypeId::Int32 => (v.bits() as i32).into(),
1037 VariantScalarTypeId::Int64 => (v.bits() as i64).into(),
1038 VariantScalarTypeId::UInt32 => v.bits().into(),
1039 VariantScalarTypeId::UInt64 => (v.bits() as u64).into(),
1040 _ => Variant::Empty,
1041 },
1042 Variant::String(ref v) => {
1043 if v.is_empty() {
1044 Variant::Empty
1045 } else {
1046 let v = v.as_ref();
1047 match target_type {
1048 VariantScalarTypeId::Boolean => {
1049 if v == "true" || v == "1" {
1053 true.into()
1054 } else if v == "false" || v == "0" {
1055 false.into()
1056 } else {
1057 Variant::Empty
1058 }
1059 }
1060 VariantScalarTypeId::Byte => {
1061 u8::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1062 }
1063 VariantScalarTypeId::Double => {
1064 f64::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1065 }
1066 VariantScalarTypeId::Float => {
1067 f32::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1068 }
1069 VariantScalarTypeId::Guid => Guid::from_str(v)
1070 .map(|v| v.into())
1071 .unwrap_or(Variant::Empty),
1072 VariantScalarTypeId::Int16 => {
1073 i16::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1074 }
1075 VariantScalarTypeId::Int32 => {
1076 i32::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1077 }
1078 VariantScalarTypeId::Int64 => {
1079 i64::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1080 }
1081 VariantScalarTypeId::NodeId => NodeId::from_str(v)
1082 .map(|v| v.into())
1083 .unwrap_or(Variant::Empty),
1084 VariantScalarTypeId::SByte => {
1085 i8::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1086 }
1087 VariantScalarTypeId::UInt16 => {
1088 u16::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1089 }
1090 VariantScalarTypeId::UInt32 => {
1091 u32::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1092 }
1093 VariantScalarTypeId::UInt64 => {
1094 u64::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1095 }
1096 _ => Variant::Empty,
1097 }
1098 }
1099 }
1100 Variant::LocalizedText(ref v) => match target_type {
1101 VariantScalarTypeId::String => v.text.clone().into(),
1102 _ => Variant::Empty,
1103 },
1104 Variant::QualifiedName(ref v) => {
1105 match target_type {
1106 VariantScalarTypeId::String => {
1107 if v.is_null() {
1108 UAString::null().into()
1109 } else {
1110 v.name.clone().into()
1112 }
1113 }
1114 VariantScalarTypeId::LocalizedText => {
1115 if v.is_null() {
1116 LocalizedText::null().into()
1117 } else {
1118 LocalizedText::new("", v.name.as_ref()).into()
1120 }
1121 }
1122 _ => Variant::Empty,
1123 }
1124 }
1125 Variant::UInt16(v) => {
1126 match target_type {
1127 VariantScalarTypeId::Double => (v as f64).into(),
1128 VariantScalarTypeId::Float => (v as f32).into(),
1129 VariantScalarTypeId::Int16 => (v as i16).into(),
1130 VariantScalarTypeId::Int32 => (v as i32).into(),
1131 VariantScalarTypeId::Int64 => (v as i64).into(),
1132 VariantScalarTypeId::StatusCode => {
1133 StatusCode::from((v as u32) << 16).into()
1135 }
1136 VariantScalarTypeId::UInt32 => (v as u32).into(),
1137 VariantScalarTypeId::UInt64 => (v as u64).into(),
1138 _ => Variant::Empty,
1139 }
1140 }
1141 Variant::UInt32(v) => match target_type {
1142 VariantScalarTypeId::Double => (v as f64).into(),
1143 VariantScalarTypeId::Float => (v as f32).into(),
1144 VariantScalarTypeId::Int32 => (v as i32).into(),
1145 VariantScalarTypeId::Int64 => (v as i64).into(),
1146 VariantScalarTypeId::UInt64 => (v as u64).into(),
1147 _ => Variant::Empty,
1148 },
1149 Variant::UInt64(v) => match target_type {
1150 VariantScalarTypeId::Double => (v as f64).into(),
1151 VariantScalarTypeId::Float => (v as f32).into(),
1152 VariantScalarTypeId::Int64 => (v as i64).into(),
1153 _ => Variant::Empty,
1154 },
1155 Variant::Array(ref s) => {
1156 if s.values.len() != 1 {
1157 return Variant::Empty;
1158 }
1159 let val = &s.values[0];
1160 val.convert(target_type)
1161 }
1162 _ => Variant::Empty,
1164 }
1165 }
1166
1167 fn convert_array(&self, target_type: VariantScalarTypeId, dims: Option<&[u32]>) -> Variant {
1168 match self {
1169 Variant::Array(a) => {
1170 if dims.is_some() && dims != a.dimensions.as_deref() {
1172 return Variant::Empty;
1173 }
1174
1175 let mut res = Vec::with_capacity(a.values.len());
1176 for v in a.values.iter() {
1177 let conv = v.convert(target_type);
1178 if matches!(conv, Variant::Empty) {
1179 return Variant::Empty;
1180 }
1181 res.push(conv);
1182 }
1183
1184 Variant::Array(Box::new(Array {
1185 value_type: target_type,
1186 values: res,
1187 dimensions: a.dimensions.clone(),
1188 }))
1189 }
1190 scalar => {
1191 if let Some(dims) = dims {
1192 if dims.len() != 1 || dims[0] != 1 {
1193 return Variant::Empty;
1194 }
1195 }
1196 let converted = scalar.convert(target_type);
1197 if matches!(converted, Variant::Empty) {
1198 return converted;
1199 }
1200 Self::Array(Box::new(Array {
1201 value_type: target_type,
1202 values: vec![converted],
1203 dimensions: dims.map(|d| d.to_vec()),
1204 }))
1205 }
1206 }
1207 }
1208
1209 pub fn convert<'a>(&self, target_type: impl Into<VariantTypeId<'a>>) -> Variant {
1211 let target_type: VariantTypeId = target_type.into();
1212 if self.type_id() == target_type {
1213 return self.clone();
1214 }
1215
1216 match target_type {
1217 VariantTypeId::Empty => Variant::Empty,
1218 VariantTypeId::Scalar(s) => self.convert_scalar(s),
1219 VariantTypeId::Array(s, d) => self.convert_array(s, d),
1220 }
1221 }
1222
1223 pub fn type_id(&self) -> VariantTypeId<'_> {
1227 match self {
1228 Variant::Empty => VariantTypeId::Empty,
1229 Variant::Boolean(_) => VariantTypeId::Scalar(VariantScalarTypeId::Boolean),
1230 Variant::SByte(_) => VariantTypeId::Scalar(VariantScalarTypeId::SByte),
1231 Variant::Byte(_) => VariantTypeId::Scalar(VariantScalarTypeId::Byte),
1232 Variant::Int16(_) => VariantTypeId::Scalar(VariantScalarTypeId::Int16),
1233 Variant::UInt16(_) => VariantTypeId::Scalar(VariantScalarTypeId::UInt16),
1234 Variant::Int32(_) => VariantTypeId::Scalar(VariantScalarTypeId::Int32),
1235 Variant::UInt32(_) => VariantTypeId::Scalar(VariantScalarTypeId::UInt32),
1236 Variant::Int64(_) => VariantTypeId::Scalar(VariantScalarTypeId::Int64),
1237 Variant::UInt64(_) => VariantTypeId::Scalar(VariantScalarTypeId::UInt64),
1238 Variant::Float(_) => VariantTypeId::Scalar(VariantScalarTypeId::Float),
1239 Variant::Double(_) => VariantTypeId::Scalar(VariantScalarTypeId::Double),
1240 Variant::String(_) => VariantTypeId::Scalar(VariantScalarTypeId::String),
1241 Variant::DateTime(_) => VariantTypeId::Scalar(VariantScalarTypeId::DateTime),
1242 Variant::Guid(_) => VariantTypeId::Scalar(VariantScalarTypeId::Guid),
1243 Variant::ByteString(_) => VariantTypeId::Scalar(VariantScalarTypeId::ByteString),
1244 Variant::XmlElement(_) => VariantTypeId::Scalar(VariantScalarTypeId::XmlElement),
1245 Variant::NodeId(_) => VariantTypeId::Scalar(VariantScalarTypeId::NodeId),
1246 Variant::ExpandedNodeId(_) => {
1247 VariantTypeId::Scalar(VariantScalarTypeId::ExpandedNodeId)
1248 }
1249 Variant::StatusCode(_) => VariantTypeId::Scalar(VariantScalarTypeId::StatusCode),
1250 Variant::QualifiedName(_) => VariantTypeId::Scalar(VariantScalarTypeId::QualifiedName),
1251 Variant::LocalizedText(_) => VariantTypeId::Scalar(VariantScalarTypeId::LocalizedText),
1252 Variant::ExtensionObject(_) => {
1253 VariantTypeId::Scalar(VariantScalarTypeId::ExtensionObject)
1254 }
1255 Variant::Variant(_) => VariantTypeId::Scalar(VariantScalarTypeId::Variant),
1256 Variant::DataValue(_) => VariantTypeId::Scalar(VariantScalarTypeId::DataValue),
1257 Variant::DiagnosticInfo(_) => {
1258 VariantTypeId::Scalar(VariantScalarTypeId::DiagnosticInfo)
1259 }
1260 Variant::Array(v) => VariantTypeId::Array(v.value_type, v.dimensions.as_deref()),
1261 }
1262 }
1263
1264 pub fn scalar_type_id(&self) -> Option<VariantScalarTypeId> {
1268 match self.type_id() {
1269 VariantTypeId::Empty => None,
1270 VariantTypeId::Scalar(s) => Some(s),
1271 VariantTypeId::Array(s, _) => Some(s),
1272 }
1273 }
1274
1275 pub fn is_empty(&self) -> bool {
1277 matches!(self, Self::Empty)
1278 }
1279
1280 pub fn is_numeric(&self) -> bool {
1282 matches!(
1283 self,
1284 Variant::SByte(_)
1285 | Variant::Byte(_)
1286 | Variant::Int16(_)
1287 | Variant::UInt16(_)
1288 | Variant::Int32(_)
1289 | Variant::UInt32(_)
1290 | Variant::Int64(_)
1291 | Variant::UInt64(_)
1292 | Variant::Float(_)
1293 | Variant::Double(_)
1294 )
1295 }
1296
1297 pub fn is_array(&self) -> bool {
1299 matches!(self, Variant::Array(_))
1300 }
1301
1302 pub fn as_array(&self) -> Option<&Vec<Variant>> {
1304 match self {
1305 Variant::Array(a) => Some(&a.values),
1306 _ => None,
1307 }
1308 }
1309
1310 pub fn is_array_of_type(&self, variant_type: VariantScalarTypeId) -> bool {
1312 match self {
1313 Variant::Array(array) => values_are_of_type(array.values.as_slice(), variant_type),
1314 _ => false,
1315 }
1316 }
1317
1318 pub fn is_valid(&self) -> bool {
1322 match self {
1323 Variant::Array(array) => array.is_valid(),
1324 _ => true,
1325 }
1326 }
1327
1328 pub fn as_f64(&self) -> Option<f64> {
1330 match *self {
1331 Variant::SByte(value) => Some(value as f64),
1332 Variant::Byte(value) => Some(value as f64),
1333 Variant::Int16(value) => Some(value as f64),
1334 Variant::UInt16(value) => Some(value as f64),
1335 Variant::Int32(value) => Some(value as f64),
1336 Variant::UInt32(value) => Some(value as f64),
1337 Variant::Int64(value) => {
1338 Some(value as f64)
1340 }
1341 Variant::UInt64(value) => {
1342 Some(value as f64)
1344 }
1345 Variant::Float(value) => Some(value as f64),
1346 Variant::Double(value) => Some(value),
1347 _ => None,
1348 }
1349 }
1350
1351 pub fn data_type(&self) -> Option<ExpandedNodeId> {
1353 match self {
1354 Variant::Boolean(_) => Some(DataTypeId::Boolean.into()),
1355 Variant::SByte(_) => Some(DataTypeId::SByte.into()),
1356 Variant::Byte(_) => Some(DataTypeId::Byte.into()),
1357 Variant::Int16(_) => Some(DataTypeId::Int16.into()),
1358 Variant::UInt16(_) => Some(DataTypeId::UInt16.into()),
1359 Variant::Int32(_) => Some(DataTypeId::Int32.into()),
1360 Variant::UInt32(_) => Some(DataTypeId::UInt32.into()),
1361 Variant::Int64(_) => Some(DataTypeId::Int64.into()),
1362 Variant::UInt64(_) => Some(DataTypeId::UInt64.into()),
1363 Variant::Float(_) => Some(DataTypeId::Float.into()),
1364 Variant::Double(_) => Some(DataTypeId::Double.into()),
1365 Variant::String(_) => Some(DataTypeId::String.into()),
1366 Variant::DateTime(_) => Some(DataTypeId::DateTime.into()),
1367 Variant::Guid(_) => Some(DataTypeId::Guid.into()),
1368 Variant::ByteString(_) => Some(DataTypeId::ByteString.into()),
1369 Variant::XmlElement(_) => Some(DataTypeId::XmlElement.into()),
1370 Variant::NodeId(_) => Some(DataTypeId::NodeId.into()),
1371 Variant::ExpandedNodeId(_) => Some(DataTypeId::ExpandedNodeId.into()),
1372 Variant::StatusCode(_) => Some(DataTypeId::StatusCode.into()),
1373 Variant::QualifiedName(_) => Some(DataTypeId::QualifiedName.into()),
1374 Variant::LocalizedText(_) => Some(DataTypeId::LocalizedText.into()),
1375 Variant::Variant(_) => Some(DataTypeId::BaseDataType.into()),
1376 Variant::DataValue(_) => Some(DataTypeId::DataValue.into()),
1377 Variant::DiagnosticInfo(_) => Some(DataTypeId::DiagnosticInfo.into()),
1378 Variant::ExtensionObject(extension_object) => extension_object.data_type(),
1379 Variant::Array(array) => {
1380 if array.values.is_empty() {
1381 return None;
1382 }
1383 array.values[0].data_type()
1384 }
1385 Variant::Empty => None,
1386 }
1387 }
1388
1389 pub(crate) fn encoding_mask(&self) -> u8 {
1391 match self {
1392 Variant::Empty => 0,
1393 Variant::Boolean(_) => EncodingMask::BOOLEAN,
1394 Variant::SByte(_) => EncodingMask::SBYTE,
1395 Variant::Byte(_) => EncodingMask::BYTE,
1396 Variant::Int16(_) => EncodingMask::INT16,
1397 Variant::UInt16(_) => EncodingMask::UINT16,
1398 Variant::Int32(_) => EncodingMask::INT32,
1399 Variant::UInt32(_) => EncodingMask::UINT32,
1400 Variant::Int64(_) => EncodingMask::INT64,
1401 Variant::UInt64(_) => EncodingMask::UINT64,
1402 Variant::Float(_) => EncodingMask::FLOAT,
1403 Variant::Double(_) => EncodingMask::DOUBLE,
1404 Variant::String(_) => EncodingMask::STRING,
1405 Variant::DateTime(_) => EncodingMask::DATE_TIME,
1406 Variant::Guid(_) => EncodingMask::GUID,
1407 Variant::ByteString(_) => EncodingMask::BYTE_STRING,
1408 Variant::XmlElement(_) => EncodingMask::XML_ELEMENT,
1409 Variant::NodeId(_) => EncodingMask::NODE_ID,
1410 Variant::ExpandedNodeId(_) => EncodingMask::EXPANDED_NODE_ID,
1411 Variant::StatusCode(_) => EncodingMask::STATUS_CODE,
1412 Variant::QualifiedName(_) => EncodingMask::QUALIFIED_NAME,
1413 Variant::LocalizedText(_) => EncodingMask::LOCALIZED_TEXT,
1414 Variant::ExtensionObject(_) => EncodingMask::EXTENSION_OBJECT,
1415 Variant::Variant(_) => EncodingMask::VARIANT,
1416 Variant::DataValue(_) => EncodingMask::DATA_VALUE,
1417 Variant::DiagnosticInfo(_) => EncodingMask::DIAGNOSTIC_INFO,
1418 Variant::Array(array) => array.encoding_mask(),
1419 }
1420 }
1421
1422 pub fn to_byte_array(&self) -> Result<Self, ArrayError> {
1425 let array = match self {
1426 Variant::ByteString(values) => match &values.value {
1427 None => Array::new(VariantScalarTypeId::Byte, vec![])?,
1428 Some(values) => {
1429 let values: Vec<Variant> = values.iter().map(|v| Variant::Byte(*v)).collect();
1430 Array::new(VariantScalarTypeId::Byte, values)?
1431 }
1432 },
1433 _ => panic!(),
1434 };
1435 Ok(Variant::from(array))
1436 }
1437
1438 fn substring(&self, min: usize, max: usize) -> Result<Variant, StatusCode> {
1440 match self {
1441 Variant::ByteString(v) => v
1442 .substring(min, max)
1443 .map(Variant::from)
1444 .map_err(|_| StatusCode::BadIndexRangeNoData),
1445 Variant::String(v) => v
1446 .substring(min, max)
1447 .map(Variant::from)
1448 .map_err(|_| StatusCode::BadIndexRangeNoData),
1449 _ => panic!("Should not be calling substring on other types"),
1450 }
1451 }
1452 pub fn set_range_of(
1454 &mut self,
1455 range: &NumericRange,
1456 other: &Variant,
1457 ) -> Result<(), StatusCode> {
1458 if self.data_type() != other.data_type() {
1461 return Err(StatusCode::BadIndexRangeDataMismatch);
1462 }
1463
1464 let other_array = if let Variant::Array(other) = other {
1465 other
1466 } else {
1467 return Err(StatusCode::BadIndexRangeNoData);
1468 };
1469 let other_values = &other_array.values;
1470
1471 match self {
1473 Variant::Array(ref mut array) => {
1474 let values = &mut array.values;
1475 match range {
1476 NumericRange::None => Err(StatusCode::BadIndexRangeNoData),
1477 NumericRange::Index(idx) => {
1478 let idx = (*idx) as usize;
1479 if idx >= values.len() || other_values.is_empty() {
1480 Err(StatusCode::BadIndexRangeNoData)
1481 } else {
1482 values[idx] = other_values[0].clone();
1483 Ok(())
1484 }
1485 }
1486 NumericRange::Range(min, max) => {
1487 let (min, max) = ((*min) as usize, (*max) as usize);
1488 if min >= values.len() {
1489 Err(StatusCode::BadIndexRangeNoData)
1490 } else {
1491 let mut idx = min;
1494 while idx < values.len() && idx <= max && idx - min < other_values.len()
1495 {
1496 values[idx] = other_values[idx - min].clone();
1497 idx += 1;
1498 }
1499 Ok(())
1500 }
1501 }
1502 NumericRange::MultipleRanges(_ranges) => {
1503 error!("Multiple ranges not supported");
1505 Err(StatusCode::BadIndexRangeNoData)
1506 }
1507 }
1508 }
1509 _ => {
1510 error!("Writing a range is not supported when the recipient is not an array");
1511 Err(StatusCode::BadWriteNotSupported)
1512 }
1513 }
1514 }
1515
1516 pub fn range_of_owned(self, range: &NumericRange) -> Result<Variant, StatusCode> {
1519 match range {
1520 NumericRange::None => Ok(self),
1521 r => self.range_of(r),
1522 }
1523 }
1524
1525 pub fn range_of(&self, range: &NumericRange) -> Result<Variant, StatusCode> {
1528 match range {
1529 NumericRange::None => Ok(self.clone()),
1530 NumericRange::Index(idx) => {
1531 let idx = (*idx) as usize;
1532 match self {
1533 Variant::String(_) | Variant::ByteString(_) => self.substring(idx, idx),
1534 Variant::Array(array) => {
1535 let values = &array.values;
1537 if let Some(v) = values.get(idx) {
1538 let values = vec![v.clone()];
1539 Ok(Variant::from((array.value_type, values)))
1540 } else {
1541 Err(StatusCode::BadIndexRangeNoData)
1542 }
1543 }
1544 _ => Err(StatusCode::BadIndexRangeDataMismatch),
1545 }
1546 }
1547 NumericRange::Range(min, max) => {
1548 let (min, max) = ((*min) as usize, (*max) as usize);
1549 match self {
1550 Variant::String(_) | Variant::ByteString(_) => self.substring(min, max),
1551 Variant::Array(array) => {
1552 let values = &array.values;
1553 if min >= values.len() {
1554 Err(StatusCode::BadIndexRangeNoData)
1556 } else {
1557 let max = if max >= values.len() {
1558 values.len() - 1
1559 } else {
1560 max
1561 };
1562 let values = &values[min..=max];
1563 let values: Vec<Variant> = values.to_vec();
1564 Ok(Variant::from((array.value_type, values)))
1565 }
1566 }
1567 _ => Err(StatusCode::BadIndexRangeDataMismatch),
1568 }
1569 }
1570 NumericRange::MultipleRanges(ranges) => {
1571 let mut res = Vec::new();
1572 for range in ranges {
1573 let v = self.range_of(range)?;
1574 match v {
1575 Variant::Array(a) => {
1576 res.extend(a.values.into_iter());
1577 }
1578 r => res.push(r),
1579 }
1580 }
1581 let type_id = if !res.is_empty() {
1582 let VariantTypeId::Scalar(s) = res[0].type_id() else {
1583 return Err(StatusCode::BadIndexRangeNoData);
1584 };
1585 s
1586 } else {
1587 match self.type_id() {
1588 VariantTypeId::Array(s, _) => s,
1589 VariantTypeId::Scalar(s) => s,
1590 VariantTypeId::Empty => return Ok(Variant::Empty),
1591 }
1592 };
1593
1594 Ok(Self::Array(Box::new(
1595 Array::new(type_id, res).map_err(|_| StatusCode::BadInvalidArgument)?,
1596 )))
1597 }
1598 }
1599 }
1600
1601 pub fn try_cast_to<T: TryFromVariant>(self) -> Result<T, Error> {
1603 T::try_from_variant(self)
1604 }
1605}