opcua_types/
variant.rs

1// OPCUA for Rust
2// SPDX-License-Identifier: MPL-2.0
3// Copyright (C) 2017-2022 Adam Lock
4
5//! Contains the implementation of `Variant`.
6
7use std::{
8    convert::TryFrom,
9    fmt,
10    io::{Read, Write},
11    str::FromStr,
12    {i16, i32, i64, i8, u16, u32, u64, u8},
13};
14
15use crate::{
16    array::*,
17    byte_string::ByteString,
18    date_time::DateTime,
19    encoding::*,
20    extension_object::ExtensionObject,
21    guid::Guid,
22    localized_text::LocalizedText,
23    node_id::{ExpandedNodeId, Identifier, NodeId},
24    node_ids::DataTypeId,
25    numeric_range::NumericRange,
26    qualified_name::QualifiedName,
27    status_codes::StatusCode,
28    string::{UAString, XmlElement},
29    DataValue, DiagnosticInfo,
30};
31
32pub(crate) struct EncodingMask {}
33
34impl EncodingMask {
35    // These are values, not bits
36    pub const BOOLEAN: u8 = DataTypeId::Boolean as u8;
37    pub const SBYTE: u8 = DataTypeId::SByte as u8;
38    pub const BYTE: u8 = DataTypeId::Byte as u8;
39    pub const INT16: u8 = DataTypeId::Int16 as u8;
40    pub const UINT16: u8 = DataTypeId::UInt16 as u8;
41    pub const INT32: u8 = DataTypeId::Int32 as u8;
42    pub const UINT32: u8 = DataTypeId::UInt32 as u8;
43    pub const INT64: u8 = DataTypeId::Int64 as u8;
44    pub const UINT64: u8 = DataTypeId::UInt64 as u8;
45    pub const FLOAT: u8 = DataTypeId::Float as u8;
46    pub const DOUBLE: u8 = DataTypeId::Double as u8;
47    pub const STRING: u8 = DataTypeId::String as u8;
48    pub const DATE_TIME: u8 = DataTypeId::DateTime as u8;
49    pub const GUID: u8 = DataTypeId::Guid as u8;
50    pub const BYTE_STRING: u8 = DataTypeId::ByteString as u8;
51    pub const XML_ELEMENT: u8 = DataTypeId::XmlElement as u8;
52    pub const NODE_ID: u8 = DataTypeId::NodeId as u8;
53    pub const EXPANDED_NODE_ID: u8 = DataTypeId::ExpandedNodeId as u8;
54    pub const STATUS_CODE: u8 = DataTypeId::StatusCode as u8;
55    pub const QUALIFIED_NAME: u8 = DataTypeId::QualifiedName as u8;
56    pub const LOCALIZED_TEXT: u8 = DataTypeId::LocalizedText as u8;
57    pub const EXTENSION_OBJECT: u8 = 22; // DataTypeId::ExtensionObject as u8;
58    pub const DATA_VALUE: u8 = DataTypeId::DataValue as u8;
59    pub const VARIANT: u8 = 24;
60    pub const DIAGNOSTIC: u8 = DataTypeId::DiagnosticInfo as u8;
61    /// Bit indicates an array with dimensions
62    pub const ARRAY_DIMENSIONS_BIT: u8 = 1 << 6;
63    /// Bit indicates an array with values
64    pub const ARRAY_VALUES_BIT: u8 = 1 << 7;
65
66    pub const ARRAY_MASK: u8 = EncodingMask::ARRAY_DIMENSIONS_BIT | EncodingMask::ARRAY_VALUES_BIT;
67}
68
69/// A `Variant` holds built-in OPC UA data types, including single and multi dimensional arrays,
70/// data values and extension objects.
71///
72/// As variants may be passed around a lot on the stack, Boxes are used for more complex types to
73/// keep the size of this type down a bit, especially when used in arrays.
74///
75#[derive(PartialEq, Debug, Clone, Serialize, Deserialize)]
76pub enum Variant {
77    /// Empty type has no value. It is equivalent to a Null value (part 6 5.1.6)
78    Empty,
79    /// Boolean
80    Boolean(bool),
81    /// Signed byte
82    SByte(i8),
83    /// Unsigned byte
84    Byte(u8),
85    /// Signed 16-bit int
86    Int16(i16),
87    /// Unsigned 16-bit int
88    UInt16(u16),
89    /// Signed 32-bit int
90    Int32(i32),
91    /// Unsigned 32-bit int
92    UInt32(u32),
93    /// Signed 64-bit int
94    Int64(i64),
95    /// Unsigned 64-bit int
96    UInt64(u64),
97    /// Float
98    Float(f32),
99    /// Double
100    Double(f64),
101    /// String
102    String(UAString),
103    /// DateTime
104    DateTime(Box<DateTime>),
105    /// Guid
106    Guid(Box<Guid>),
107    /// StatusCode
108    StatusCode(StatusCode),
109    /// ByteString
110    ByteString(ByteString),
111    /// XmlElement
112    XmlElement(XmlElement),
113    /// QualifiedName
114    QualifiedName(Box<QualifiedName>),
115    /// LocalizedText
116    LocalizedText(Box<LocalizedText>),
117    /// NodeId
118    NodeId(Box<NodeId>),
119    /// ExpandedNodeId
120    ExpandedNodeId(Box<ExpandedNodeId>),
121    /// ExtensionObject
122    ExtensionObject(Box<ExtensionObject>),
123    // Variant
124    Variant(Box<Variant>),
125    // DataValue
126    DataValue(Box<DataValue>),
127    // Diagnostics
128    Diagnostics(Box<DiagnosticInfo>),
129    /// Single dimension array which can contain any scalar type, all the same type. Nested
130    /// arrays will be rejected.
131    Array(Box<Array>),
132}
133
134/// The variant type id is the type of the variant but without its payload.
135#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
136pub enum VariantTypeId {
137    // Null / Empty
138    Empty,
139    // Scalar types
140    Boolean,
141    SByte,
142    Byte,
143    Int16,
144    UInt16,
145    Int32,
146    UInt32,
147    Int64,
148    UInt64,
149    Float,
150    Double,
151    String,
152    DateTime,
153    Guid,
154    StatusCode,
155    ByteString,
156    XmlElement,
157    QualifiedName,
158    LocalizedText,
159    NodeId,
160    ExpandedNodeId,
161    ExtensionObject,
162    Variant,
163    DataValue,
164    Diagnostic,
165    Array,
166}
167
168impl TryFrom<&NodeId> for VariantTypeId {
169    type Error = ();
170    fn try_from(value: &NodeId) -> Result<Self, Self::Error> {
171        if value.namespace == 0 {
172            if let Identifier::Numeric(type_id) = value.identifier {
173                match type_id {
174                    type_id if type_id == DataTypeId::Boolean as u32 => Ok(VariantTypeId::Boolean),
175                    type_id if type_id == DataTypeId::Byte as u32 => Ok(VariantTypeId::Byte),
176                    type_id if type_id == DataTypeId::Int16 as u32 => Ok(VariantTypeId::Int16),
177                    type_id if type_id == DataTypeId::UInt16 as u32 => Ok(VariantTypeId::UInt16),
178                    type_id if type_id == DataTypeId::Int32 as u32 => Ok(VariantTypeId::Int32),
179                    type_id if type_id == DataTypeId::UInt32 as u32 => Ok(VariantTypeId::UInt32),
180                    type_id if type_id == DataTypeId::Int64 as u32 => Ok(VariantTypeId::Int64),
181                    type_id if type_id == DataTypeId::UInt64 as u32 => Ok(VariantTypeId::UInt64),
182                    type_id if type_id == DataTypeId::Float as u32 => Ok(VariantTypeId::Float),
183                    type_id if type_id == DataTypeId::Double as u32 => Ok(VariantTypeId::Double),
184                    type_id if type_id == DataTypeId::String as u32 => Ok(VariantTypeId::String),
185                    type_id if type_id == DataTypeId::DateTime as u32 => {
186                        Ok(VariantTypeId::DateTime)
187                    }
188                    type_id if type_id == DataTypeId::Guid as u32 => Ok(VariantTypeId::Guid),
189                    type_id if type_id == DataTypeId::ByteString as u32 => {
190                        Ok(VariantTypeId::ByteString)
191                    }
192                    type_id if type_id == DataTypeId::XmlElement as u32 => {
193                        Ok(VariantTypeId::XmlElement)
194                    }
195                    type_id if type_id == DataTypeId::NodeId as u32 => Ok(VariantTypeId::NodeId),
196                    type_id if type_id == DataTypeId::ExpandedNodeId as u32 => {
197                        Ok(VariantTypeId::ExpandedNodeId)
198                    }
199                    type_id if type_id == DataTypeId::XmlElement as u32 => {
200                        Ok(VariantTypeId::XmlElement)
201                    }
202                    type_id if type_id == DataTypeId::StatusCode as u32 => {
203                        Ok(VariantTypeId::StatusCode)
204                    }
205                    type_id if type_id == DataTypeId::QualifiedName as u32 => {
206                        Ok(VariantTypeId::QualifiedName)
207                    }
208                    type_id if type_id == DataTypeId::LocalizedText as u32 => {
209                        Ok(VariantTypeId::LocalizedText)
210                    }
211                    type_id if type_id == DataTypeId::DataValue as u32 => {
212                        Ok(VariantTypeId::DataValue)
213                    }
214                    type_id if type_id == DataTypeId::BaseDataType as u32 => {
215                        Ok(VariantTypeId::Variant)
216                    }
217                    type_id if type_id == DataTypeId::DiagnosticInfo as u32 => {
218                        Ok(VariantTypeId::Diagnostic)
219                    }
220                    _ => Err(()),
221                }
222            } else {
223                Err(())
224            }
225        } else {
226            Err(())
227        }
228    }
229}
230
231impl VariantTypeId {
232    pub fn encoding_mask(&self) -> u8 {
233        match self {
234            // Null / Empty
235            VariantTypeId::Empty => 0u8,
236            // Scalar types
237            VariantTypeId::Boolean => EncodingMask::BOOLEAN,
238            VariantTypeId::SByte => EncodingMask::SBYTE,
239            VariantTypeId::Byte => EncodingMask::BYTE,
240            VariantTypeId::Int16 => EncodingMask::INT16,
241            VariantTypeId::UInt16 => EncodingMask::UINT16,
242            VariantTypeId::Int32 => EncodingMask::INT32,
243            VariantTypeId::UInt32 => EncodingMask::UINT32,
244            VariantTypeId::Int64 => EncodingMask::INT64,
245            VariantTypeId::UInt64 => EncodingMask::UINT64,
246            VariantTypeId::Float => EncodingMask::FLOAT,
247            VariantTypeId::Double => EncodingMask::DOUBLE,
248            VariantTypeId::String => EncodingMask::STRING,
249            VariantTypeId::DateTime => EncodingMask::DATE_TIME,
250            VariantTypeId::Guid => EncodingMask::GUID,
251            VariantTypeId::StatusCode => EncodingMask::STATUS_CODE,
252            VariantTypeId::ByteString => EncodingMask::BYTE_STRING,
253            VariantTypeId::XmlElement => EncodingMask::XML_ELEMENT,
254            VariantTypeId::QualifiedName => EncodingMask::QUALIFIED_NAME,
255            VariantTypeId::LocalizedText => EncodingMask::LOCALIZED_TEXT,
256            VariantTypeId::NodeId => EncodingMask::NODE_ID,
257            VariantTypeId::ExpandedNodeId => EncodingMask::EXPANDED_NODE_ID,
258            VariantTypeId::ExtensionObject => EncodingMask::EXTENSION_OBJECT,
259            VariantTypeId::Variant => EncodingMask::VARIANT,
260            VariantTypeId::DataValue => EncodingMask::DATA_VALUE,
261            VariantTypeId::Diagnostic => EncodingMask::DIAGNOSTIC,
262            VariantTypeId::Array => panic!("Type of array is unknown"),
263        }
264    }
265
266    pub fn from_encoding_mask(encoding_mask: u8) -> Result<Self, StatusCode> {
267        match encoding_mask & !EncodingMask::ARRAY_MASK {
268            0u8 => Ok(VariantTypeId::Empty),
269            EncodingMask::BOOLEAN => Ok(VariantTypeId::Boolean),
270            EncodingMask::SBYTE => Ok(VariantTypeId::SByte),
271            EncodingMask::BYTE => Ok(VariantTypeId::Byte),
272            EncodingMask::INT16 => Ok(VariantTypeId::Int16),
273            EncodingMask::UINT16 => Ok(VariantTypeId::UInt16),
274            EncodingMask::INT32 => Ok(VariantTypeId::Int32),
275            EncodingMask::UINT32 => Ok(VariantTypeId::UInt32),
276            EncodingMask::INT64 => Ok(VariantTypeId::Int64),
277            EncodingMask::UINT64 => Ok(VariantTypeId::UInt64),
278            EncodingMask::FLOAT => Ok(VariantTypeId::Float),
279            EncodingMask::DOUBLE => Ok(VariantTypeId::Double),
280            EncodingMask::STRING => Ok(VariantTypeId::String),
281            EncodingMask::DATE_TIME => Ok(VariantTypeId::DateTime),
282            EncodingMask::GUID => Ok(VariantTypeId::Guid),
283            EncodingMask::STATUS_CODE => Ok(VariantTypeId::StatusCode),
284            EncodingMask::BYTE_STRING => Ok(VariantTypeId::ByteString),
285            EncodingMask::XML_ELEMENT => Ok(VariantTypeId::XmlElement),
286            EncodingMask::QUALIFIED_NAME => Ok(VariantTypeId::QualifiedName),
287            EncodingMask::LOCALIZED_TEXT => Ok(VariantTypeId::LocalizedText),
288            EncodingMask::NODE_ID => Ok(VariantTypeId::NodeId),
289            EncodingMask::EXPANDED_NODE_ID => Ok(VariantTypeId::ExpandedNodeId),
290            EncodingMask::EXTENSION_OBJECT => Ok(VariantTypeId::ExtensionObject),
291            EncodingMask::VARIANT => Ok(VariantTypeId::Variant),
292            EncodingMask::DATA_VALUE => Ok(VariantTypeId::DataValue),
293            EncodingMask::DIAGNOSTIC => Ok(VariantTypeId::Diagnostic),
294            _ => {
295                error!("Unrecognized encoding mask");
296                Err(StatusCode::BadDecodingError)
297            }
298        }
299    }
300
301    /// Tests and returns true if the variant holds a numeric type
302    pub fn is_numeric(&self) -> bool {
303        matches!(
304            self,
305            VariantTypeId::SByte
306                | VariantTypeId::Byte
307                | VariantTypeId::Int16
308                | VariantTypeId::UInt16
309                | VariantTypeId::Int32
310                | VariantTypeId::UInt32
311                | VariantTypeId::Int64
312                | VariantTypeId::UInt64
313                | VariantTypeId::Float
314                | VariantTypeId::Double
315        )
316    }
317
318    /// Returns a data precedence rank for scalar types, OPC UA part 4 table 119. This is used
319    /// when operators are comparing values of differing types. The type with
320    /// the highest precedence dictates how values are converted in order to be compared.
321    pub fn precedence(&self) -> u8 {
322        match self {
323            VariantTypeId::Double => 1,
324            VariantTypeId::Float => 2,
325            VariantTypeId::Int64 => 3,
326            VariantTypeId::UInt64 => 4,
327            VariantTypeId::Int32 => 5,
328            VariantTypeId::UInt32 => 6,
329            VariantTypeId::StatusCode => 7,
330            VariantTypeId::Int16 => 8,
331            VariantTypeId::UInt16 => 9,
332            VariantTypeId::SByte => 10,
333            VariantTypeId::Byte => 11,
334            VariantTypeId::Boolean => 12,
335            VariantTypeId::Guid => 13,
336            VariantTypeId::String => 14,
337            VariantTypeId::ExpandedNodeId => 15,
338            VariantTypeId::NodeId => 16,
339            VariantTypeId::LocalizedText => 17,
340            VariantTypeId::QualifiedName => 18,
341            _ => 100,
342        }
343    }
344}
345
346impl From<()> for Variant {
347    fn from(_: ()) -> Self {
348        Variant::Empty
349    }
350}
351
352impl From<bool> for Variant {
353    fn from(v: bool) -> Self {
354        Variant::Boolean(v)
355    }
356}
357
358impl From<u8> for Variant {
359    fn from(v: u8) -> Self {
360        Variant::Byte(v)
361    }
362}
363
364impl From<i8> for Variant {
365    fn from(v: i8) -> Self {
366        Variant::SByte(v)
367    }
368}
369
370impl From<i16> for Variant {
371    fn from(v: i16) -> Self {
372        Variant::Int16(v)
373    }
374}
375
376impl From<u16> for Variant {
377    fn from(v: u16) -> Self {
378        Variant::UInt16(v)
379    }
380}
381
382impl From<i32> for Variant {
383    fn from(v: i32) -> Self {
384        Variant::Int32(v)
385    }
386}
387
388impl From<u32> for Variant {
389    fn from(v: u32) -> Self {
390        Variant::UInt32(v)
391    }
392}
393
394impl From<i64> for Variant {
395    fn from(v: i64) -> Self {
396        Variant::Int64(v)
397    }
398}
399
400impl From<u64> for Variant {
401    fn from(v: u64) -> Self {
402        Variant::UInt64(v)
403    }
404}
405
406impl From<f32> for Variant {
407    fn from(v: f32) -> Self {
408        Variant::Float(v)
409    }
410}
411
412impl From<f64> for Variant {
413    fn from(v: f64) -> Self {
414        Variant::Double(v)
415    }
416}
417
418impl<'a> From<&'a str> for Variant {
419    fn from(v: &'a str) -> Self {
420        Variant::String(UAString::from(v))
421    }
422}
423
424impl From<String> for Variant {
425    fn from(v: String) -> Self {
426        Variant::String(UAString::from(v))
427    }
428}
429
430impl From<UAString> for Variant {
431    fn from(v: UAString) -> Self {
432        Variant::String(v)
433    }
434}
435
436impl From<DateTime> for Variant {
437    fn from(v: DateTime) -> Self {
438        Variant::DateTime(Box::new(v))
439    }
440}
441
442impl From<Guid> for Variant {
443    fn from(v: Guid) -> Self {
444        Variant::Guid(Box::new(v))
445    }
446}
447
448impl From<StatusCode> for Variant {
449    fn from(v: StatusCode) -> Self {
450        Variant::StatusCode(v)
451    }
452}
453
454impl From<ByteString> for Variant {
455    fn from(v: ByteString) -> Self {
456        Variant::ByteString(v)
457    }
458}
459
460impl From<QualifiedName> for Variant {
461    fn from(v: QualifiedName) -> Self {
462        Variant::QualifiedName(Box::new(v))
463    }
464}
465
466impl From<LocalizedText> for Variant {
467    fn from(v: LocalizedText) -> Self {
468        Variant::LocalizedText(Box::new(v))
469    }
470}
471
472impl From<NodeId> for Variant {
473    fn from(v: NodeId) -> Self {
474        Variant::NodeId(Box::new(v))
475    }
476}
477
478impl From<ExpandedNodeId> for Variant {
479    fn from(v: ExpandedNodeId) -> Self {
480        Variant::ExpandedNodeId(Box::new(v))
481    }
482}
483
484impl From<ExtensionObject> for Variant {
485    fn from(v: ExtensionObject) -> Self {
486        Variant::ExtensionObject(Box::new(v))
487    }
488}
489
490impl From<DataValue> for Variant {
491    fn from(v: DataValue) -> Self {
492        Variant::DataValue(Box::new(v))
493    }
494}
495
496impl From<DiagnosticInfo> for Variant {
497    fn from(v: DiagnosticInfo) -> Self {
498        Variant::Diagnostics(Box::new(v))
499    }
500}
501
502impl<'a, 'b> From<(VariantTypeId, &'a [&'b str])> for Variant {
503    fn from(v: (VariantTypeId, &'a [&'b str])) -> Self {
504        let values: Vec<Variant> = v.1.iter().map(|v| Variant::from(*v)).collect();
505        let value = Array::new_single(v.0, values).unwrap();
506        Variant::from(value)
507    }
508}
509
510impl From<(VariantTypeId, Vec<Variant>)> for Variant {
511    fn from(v: (VariantTypeId, Vec<Variant>)) -> Self {
512        let value = Array::new_single(v.0, v.1).unwrap();
513        Variant::from(value)
514    }
515}
516
517impl From<(VariantTypeId, Vec<Variant>, Vec<u32>)> for Variant {
518    fn from(v: (VariantTypeId, Vec<Variant>, Vec<u32>)) -> Self {
519        let value = Array::new_multi(v.0, v.1, v.2).unwrap();
520        Variant::from(value)
521    }
522}
523
524impl From<Array> for Variant {
525    fn from(v: Array) -> Self {
526        Variant::Array(Box::new(v))
527    }
528}
529
530macro_rules! cast_to_bool {
531    ($value: expr) => {
532        if $value == 1 {
533            true.into()
534        } else if $value == 0 {
535            false.into()
536        } else {
537            Variant::Empty
538        }
539    };
540}
541
542macro_rules! cast_to_integer {
543    ($value: expr, $from: ident, $to: ident) => {
544        {
545            // 64-bit values are the highest supported by OPC UA, so this code will cast
546            // and compare values using signed / unsigned types to determine if they're in range.
547            let valid = if $value < 0 as $from {
548                // Negative values can only go into a signed type and only when the value is greater
549                // or equal to the MIN
550                $to::MIN != 0 && $value as i64 >= $to::MIN as i64
551            } else {
552                // Positive values can only go into the type only when the value is less than or equal
553                // to the MAX.
554                $value as u64 <= $to::MAX as u64
555            };
556            if !valid {
557                // Value is out of range
558                // error!("Value {} is outside of the range of receiving in type {}..{}", $value, $to::MIN, $to::MAX);
559                Variant::Empty
560            } else {
561                ($value as $to).into()
562            }
563        }
564    }
565}
566
567macro_rules! from_array_to_variant_impl {
568    ($encoding_mask: expr, $rtype: ident) => {
569        impl<'a> From<&'a Vec<$rtype>> for Variant {
570            fn from(v: &'a Vec<$rtype>) -> Self {
571                Variant::from(v.as_slice())
572            }
573        }
574
575        impl From<Vec<$rtype>> for Variant {
576            fn from(v: Vec<$rtype>) -> Self {
577                Variant::from(v.as_slice())
578            }
579        }
580
581        impl<'a> From<&'a [$rtype]> for Variant {
582            fn from(v: &'a [$rtype]) -> Self {
583                let array: Vec<Variant> = v.iter().map(|v| Variant::from(v.clone())).collect();
584                Variant::try_from(($encoding_mask, array)).unwrap()
585            }
586        }
587    };
588}
589
590from_array_to_variant_impl!(VariantTypeId::String, String);
591from_array_to_variant_impl!(VariantTypeId::Boolean, bool);
592from_array_to_variant_impl!(VariantTypeId::SByte, i8);
593from_array_to_variant_impl!(VariantTypeId::Byte, u8);
594from_array_to_variant_impl!(VariantTypeId::Int16, i16);
595from_array_to_variant_impl!(VariantTypeId::UInt16, u16);
596from_array_to_variant_impl!(VariantTypeId::Int32, i32);
597from_array_to_variant_impl!(VariantTypeId::UInt32, u32);
598from_array_to_variant_impl!(VariantTypeId::Int64, i64);
599from_array_to_variant_impl!(VariantTypeId::UInt64, u64);
600from_array_to_variant_impl!(VariantTypeId::Float, f32);
601from_array_to_variant_impl!(VariantTypeId::Double, f64);
602
603/// This macro tries to return a `Vec<foo>` from a `Variant::Array<Variant::Foo>>`, e.g.
604/// If the Variant holds
605macro_rules! try_from_variant_to_array_impl {
606    ($rtype: ident, $vtype: ident) => {
607        impl TryFrom<&Variant> for Vec<$rtype> {
608            type Error = ();
609
610            fn try_from(value: &Variant) -> Result<Self, Self::Error> {
611                match value {
612                    Variant::Array(ref array) => {
613                        let values = &array.values;
614                        if !values_are_of_type(values, VariantTypeId::$vtype) {
615                            Err(())
616                        } else {
617                            Ok(values
618                                .iter()
619                                .map(|v| {
620                                    if let Variant::$vtype(v) = v {
621                                        *v
622                                    } else {
623                                        panic!()
624                                    }
625                                })
626                                .collect())
627                        }
628                    }
629                    _ => Err(()),
630                }
631            }
632        }
633    };
634}
635
636// These are implementations of TryFrom which will attempt to transform a single dimension array
637// in a Variant to the respective Vec<T> defined in the macro. All the variants must be of the correct
638// type or the impl will return with an error.
639
640try_from_variant_to_array_impl!(bool, Boolean);
641try_from_variant_to_array_impl!(i8, SByte);
642try_from_variant_to_array_impl!(u8, Byte);
643try_from_variant_to_array_impl!(i16, Int16);
644try_from_variant_to_array_impl!(u16, UInt16);
645try_from_variant_to_array_impl!(i32, Int32);
646try_from_variant_to_array_impl!(u32, UInt32);
647try_from_variant_to_array_impl!(i64, Int64);
648try_from_variant_to_array_impl!(u64, UInt64);
649try_from_variant_to_array_impl!(f32, Float);
650try_from_variant_to_array_impl!(f64, Double);
651
652impl BinaryEncoder<Variant> for Variant {
653    fn byte_len(&self) -> usize {
654        let mut size: usize = 0;
655
656        // Encoding mask
657        size += 1;
658
659        // Value itself
660        size += match self {
661            Variant::Empty => 0,
662            Variant::Boolean(value) => value.byte_len(),
663            Variant::SByte(value) => value.byte_len(),
664            Variant::Byte(value) => value.byte_len(),
665            Variant::Int16(value) => value.byte_len(),
666            Variant::UInt16(value) => value.byte_len(),
667            Variant::Int32(value) => value.byte_len(),
668            Variant::UInt32(value) => value.byte_len(),
669            Variant::Int64(value) => value.byte_len(),
670            Variant::UInt64(value) => value.byte_len(),
671            Variant::Float(value) => value.byte_len(),
672            Variant::Double(value) => value.byte_len(),
673            Variant::String(value) => value.byte_len(),
674            Variant::DateTime(value) => value.byte_len(),
675            Variant::Guid(value) => value.byte_len(),
676            Variant::ByteString(value) => value.byte_len(),
677            Variant::XmlElement(value) => value.byte_len(),
678            Variant::NodeId(value) => value.byte_len(),
679            Variant::ExpandedNodeId(value) => value.byte_len(),
680            Variant::StatusCode(value) => value.byte_len(),
681            Variant::QualifiedName(value) => value.byte_len(),
682            Variant::LocalizedText(value) => value.byte_len(),
683            Variant::ExtensionObject(value) => value.byte_len(),
684            Variant::DataValue(value) => value.byte_len(),
685            Variant::Variant(value) => value.byte_len(),
686            Variant::Diagnostics(value) => value.byte_len(),
687            Variant::Array(array) => {
688                // Array length
689                let mut size = 4;
690                // Size of each value
691                size += array
692                    .values
693                    .iter()
694                    .map(Variant::byte_len_variant_value)
695                    .sum::<usize>();
696                if array.has_dimensions() {
697                    // Dimensions (size + num elements)
698                    size += 4 + array.dimensions.len() * 4;
699                }
700                size
701            }
702        };
703        size
704    }
705
706    fn encode<S: Write>(&self, stream: &mut S) -> EncodingResult<usize> {
707        let mut size: usize = 0;
708
709        // Encoding mask will include the array bits if applicable for the type
710        let encoding_mask = self.encoding_mask();
711        size += write_u8(stream, encoding_mask)?;
712
713        size += match self {
714            Variant::Empty => 0,
715            Variant::Boolean(value) => value.encode(stream)?,
716            Variant::SByte(value) => value.encode(stream)?,
717            Variant::Byte(value) => value.encode(stream)?,
718            Variant::Int16(value) => value.encode(stream)?,
719            Variant::UInt16(value) => value.encode(stream)?,
720            Variant::Int32(value) => value.encode(stream)?,
721            Variant::UInt32(value) => value.encode(stream)?,
722            Variant::Int64(value) => value.encode(stream)?,
723            Variant::UInt64(value) => value.encode(stream)?,
724            Variant::Float(value) => value.encode(stream)?,
725            Variant::Double(value) => value.encode(stream)?,
726            Variant::String(value) => value.encode(stream)?,
727            Variant::DateTime(value) => value.encode(stream)?,
728            Variant::Guid(value) => value.encode(stream)?,
729            Variant::ByteString(value) => value.encode(stream)?,
730            Variant::XmlElement(value) => value.encode(stream)?,
731            Variant::NodeId(value) => value.encode(stream)?,
732            Variant::ExpandedNodeId(value) => value.encode(stream)?,
733            Variant::StatusCode(value) => value.encode(stream)?,
734            Variant::QualifiedName(value) => value.encode(stream)?,
735            Variant::LocalizedText(value) => value.encode(stream)?,
736            Variant::ExtensionObject(value) => value.encode(stream)?,
737            Variant::DataValue(value) => value.encode(stream)?,
738            Variant::Variant(value) => value.encode(stream)?,
739            Variant::Diagnostics(value) => value.encode(stream)?,
740            Variant::Array(array) => {
741                let mut size = write_i32(stream, array.values.len() as i32)?;
742                for value in array.values.iter() {
743                    size += Variant::encode_variant_value(stream, value)?;
744                }
745                if array.has_dimensions() {
746                    // Note array dimensions are encoded as Int32 even though they are presented
747                    // as UInt32 through attribute.
748
749                    // Encode dimensions length
750                    size += write_i32(stream, array.dimensions.len() as i32)?;
751                    // Encode dimensions
752                    for dimension in &array.dimensions {
753                        size += write_i32(stream, *dimension as i32)?;
754                    }
755                }
756                size
757            }
758        };
759        assert_eq!(size, self.byte_len());
760        Ok(size)
761    }
762
763    fn decode<S: Read>(stream: &mut S, decoding_options: &DecodingOptions) -> EncodingResult<Self> {
764        let encoding_mask = u8::decode(stream, decoding_options)?;
765        let element_encoding_mask = encoding_mask & !EncodingMask::ARRAY_MASK;
766
767        // IMPORTANT NOTE: Arrays are constructed through Array::new_multi or Array::new_single
768        // to correctly process failures. Don't use Variant::from((value_type, values)) since
769        // this will panic & break the runtime. We don't want this when dealing with potentially
770        // malicious data.
771
772        // Read array length
773        let array_length = if encoding_mask & EncodingMask::ARRAY_VALUES_BIT != 0 {
774            let array_length = i32::decode(stream, decoding_options)?;
775            // null array of type
776            if array_length == -1 {
777                let value_type_id = VariantTypeId::from_encoding_mask(element_encoding_mask)?;
778                return Array::new_multi(value_type_id, Vec::new(), Vec::new()).map(Variant::from);
779            }
780            if array_length <= 0 {
781                error!("Invalid array_length {}", array_length);
782                return Err(StatusCode::BadDecodingError);
783            }
784            array_length
785        } else {
786            -1
787        };
788
789        // Read the value(s). If array length was specified, we assume a single or multi dimension array
790        if array_length > 0 {
791            // Array length in total cannot exceed max array length
792            if array_length > decoding_options.max_array_length as i32 {
793                return Err(StatusCode::BadEncodingLimitsExceeded);
794            }
795
796            let mut values: Vec<Variant> = Vec::with_capacity(array_length as usize);
797            for _ in 0..array_length {
798                values.push(Variant::decode_variant_value(
799                    stream,
800                    element_encoding_mask,
801                    decoding_options,
802                )?);
803            }
804            let value_type_id = VariantTypeId::from_encoding_mask(element_encoding_mask)?;
805            if encoding_mask & EncodingMask::ARRAY_DIMENSIONS_BIT != 0 {
806                if let Some(dimensions) = read_array(stream, decoding_options)? {
807                    if dimensions.iter().any(|d| *d == 0) {
808                        error!("Invalid array dimensions");
809                        Err(StatusCode::BadDecodingError)
810                    } else {
811                        // This looks clunky but it's to prevent a panic from malicious data
812                        // causing an overflow panic
813                        let mut array_dimensions_length = 1u32;
814                        for d in &dimensions {
815                            if let Some(v) = array_dimensions_length.checked_mul(*d) {
816                                array_dimensions_length = v;
817                            } else {
818                                error!("Array dimension overflow!");
819                                return Err(StatusCode::BadDecodingError);
820                            }
821                        }
822                        if array_dimensions_length != array_length as u32 {
823                            error!(
824                                "Array dimensions does not match array length {}",
825                                array_length
826                            );
827                            Err(StatusCode::BadDecodingError)
828                        } else {
829                            // Note Array::new_multi can fail
830                            Array::new_multi(value_type_id, values, dimensions).map(Variant::from)
831                        }
832                    }
833                } else {
834                    error!("No array dimensions despite the bit flag being set");
835                    Err(StatusCode::BadDecodingError)
836                }
837            } else {
838                // Note Array::new_single can fail
839                Array::new_single(value_type_id, values).map(Variant::from)
840            }
841        } else if encoding_mask & EncodingMask::ARRAY_DIMENSIONS_BIT != 0 {
842            error!("Array dimensions bit specified without any values");
843            Err(StatusCode::BadDecodingError)
844        } else {
845            // Read a single variant
846            Variant::decode_variant_value(stream, element_encoding_mask, decoding_options)
847        }
848    }
849}
850
851impl Default for Variant {
852    fn default() -> Self {
853        Variant::Empty
854    }
855}
856
857/// This implementation is mainly for debugging / convenience purposes, to eliminate some of the
858/// noise in common types from using the Debug trait.
859impl fmt::Display for Variant {
860    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
861        match self {
862            Variant::SByte(v) => write!(f, "{}", v),
863            Variant::Byte(v) => write!(f, "{}", v),
864            Variant::Int16(v) => write!(f, "{}", v),
865            Variant::UInt16(v) => write!(f, "{}", v),
866            Variant::Int32(v) => write!(f, "{}", v),
867            Variant::UInt32(v) => write!(f, "{}", v),
868            Variant::Int64(v) => write!(f, "{}", v),
869            Variant::UInt64(v) => write!(f, "{}", v),
870            Variant::Float(v) => write!(f, "{}", v),
871            Variant::Double(v) => write!(f, "{}", v),
872            Variant::Boolean(v) => write!(f, "{}", v),
873            Variant::String(ref v) => write!(f, "{}", v),
874            Variant::Guid(ref v) => write!(f, "{}", v),
875            Variant::DateTime(ref v) => write!(f, "{}", v),
876            Variant::NodeId(ref v) => write!(f, "{}", v),
877            Variant::ExpandedNodeId(ref v) => write!(f, "{}", v),
878            Variant::Variant(ref v) => write!(f, "Variant({})", v),
879            value => write!(f, "{:?}", value),
880        }
881    }
882}
883
884impl Variant {
885    /// Test the flag (convenience method)
886    pub fn test_encoding_flag(encoding_mask: u8, flag: u8) -> bool {
887        encoding_mask == flag as u8
888    }
889
890    /// Returns the length of just the value, not the encoding flag
891    fn byte_len_variant_value(value: &Variant) -> usize {
892        match value {
893            Variant::Empty => 0,
894            Variant::Boolean(value) => value.byte_len(),
895            Variant::SByte(value) => value.byte_len(),
896            Variant::Byte(value) => value.byte_len(),
897            Variant::Int16(value) => value.byte_len(),
898            Variant::UInt16(value) => value.byte_len(),
899            Variant::Int32(value) => value.byte_len(),
900            Variant::UInt32(value) => value.byte_len(),
901            Variant::Int64(value) => value.byte_len(),
902            Variant::UInt64(value) => value.byte_len(),
903            Variant::Float(value) => value.byte_len(),
904            Variant::Double(value) => value.byte_len(),
905            Variant::String(value) => value.byte_len(),
906            Variant::DateTime(value) => value.byte_len(),
907            Variant::Guid(value) => value.byte_len(),
908            Variant::ByteString(value) => value.byte_len(),
909            Variant::XmlElement(value) => value.byte_len(),
910            Variant::NodeId(value) => value.byte_len(),
911            Variant::ExpandedNodeId(value) => value.byte_len(),
912            Variant::StatusCode(value) => value.byte_len(),
913            Variant::QualifiedName(value) => value.byte_len(),
914            Variant::LocalizedText(value) => value.byte_len(),
915            Variant::ExtensionObject(value) => value.byte_len(),
916            Variant::Variant(value) => value.byte_len(),
917            Variant::DataValue(value) => value.byte_len(),
918            Variant::Diagnostics(value) => value.byte_len(),
919            _ => {
920                error!("Cannot compute length of this type (probably nested array)");
921                0
922            }
923        }
924    }
925
926    /// Encodes just the value, not the encoding flag
927    fn encode_variant_value<S: Write>(stream: &mut S, value: &Variant) -> EncodingResult<usize> {
928        match value {
929            Variant::Empty => Ok(0),
930            Variant::Boolean(value) => value.encode(stream),
931            Variant::SByte(value) => value.encode(stream),
932            Variant::Byte(value) => value.encode(stream),
933            Variant::Int16(value) => value.encode(stream),
934            Variant::UInt16(value) => value.encode(stream),
935            Variant::Int32(value) => value.encode(stream),
936            Variant::UInt32(value) => value.encode(stream),
937            Variant::Int64(value) => value.encode(stream),
938            Variant::UInt64(value) => value.encode(stream),
939            Variant::Float(value) => value.encode(stream),
940            Variant::Double(value) => value.encode(stream),
941            Variant::String(value) => value.encode(stream),
942            Variant::DateTime(value) => value.encode(stream),
943            Variant::Guid(value) => value.encode(stream),
944            Variant::ByteString(value) => value.encode(stream),
945            Variant::XmlElement(value) => value.encode(stream),
946            Variant::NodeId(value) => value.encode(stream),
947            Variant::ExpandedNodeId(value) => value.encode(stream),
948            Variant::StatusCode(value) => value.encode(stream),
949            Variant::QualifiedName(value) => value.encode(stream),
950            Variant::LocalizedText(value) => value.encode(stream),
951            Variant::ExtensionObject(value) => value.encode(stream),
952            Variant::Variant(value) => value.encode(stream),
953            Variant::DataValue(value) => value.encode(stream),
954            Variant::Diagnostics(value) => value.encode(stream),
955            _ => {
956                warn!("Cannot encode this variant value type (probably nested array)");
957                Err(StatusCode::BadEncodingError)
958            }
959        }
960    }
961
962    /// Reads just the variant value from the stream
963    fn decode_variant_value<S: Read>(
964        stream: &mut S,
965        encoding_mask: u8,
966        decoding_options: &DecodingOptions,
967    ) -> EncodingResult<Self> {
968        let result = if encoding_mask == 0 {
969            Variant::Empty
970        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::BOOLEAN) {
971            Self::from(bool::decode(stream, decoding_options)?)
972        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::SBYTE) {
973            Self::from(i8::decode(stream, decoding_options)?)
974        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::BYTE) {
975            Self::from(u8::decode(stream, decoding_options)?)
976        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::INT16) {
977            Self::from(i16::decode(stream, decoding_options)?)
978        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::UINT16) {
979            Self::from(u16::decode(stream, decoding_options)?)
980        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::INT32) {
981            Self::from(i32::decode(stream, decoding_options)?)
982        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::UINT32) {
983            Self::from(u32::decode(stream, decoding_options)?)
984        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::INT64) {
985            Self::from(i64::decode(stream, decoding_options)?)
986        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::UINT64) {
987            Self::from(u64::decode(stream, decoding_options)?)
988        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::FLOAT) {
989            Self::from(f32::decode(stream, decoding_options)?)
990        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::DOUBLE) {
991            Self::from(f64::decode(stream, decoding_options)?)
992        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::STRING) {
993            Self::from(UAString::decode(stream, decoding_options)?)
994        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::DATE_TIME) {
995            Self::from(DateTime::decode(stream, decoding_options)?)
996        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::GUID) {
997            Self::from(Guid::decode(stream, decoding_options)?)
998        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::BYTE_STRING) {
999            Self::from(ByteString::decode(stream, decoding_options)?)
1000        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::XML_ELEMENT) {
1001            // Force the type to be XmlElement since its typedef'd to UAString
1002            Variant::XmlElement(XmlElement::decode(stream, decoding_options)?)
1003        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::NODE_ID) {
1004            Self::from(NodeId::decode(stream, decoding_options)?)
1005        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::EXPANDED_NODE_ID) {
1006            Self::from(ExpandedNodeId::decode(stream, decoding_options)?)
1007        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::STATUS_CODE) {
1008            Self::from(StatusCode::decode(stream, decoding_options)?)
1009        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::QUALIFIED_NAME) {
1010            Self::from(QualifiedName::decode(stream, decoding_options)?)
1011        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::LOCALIZED_TEXT) {
1012            Self::from(LocalizedText::decode(stream, decoding_options)?)
1013        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::EXTENSION_OBJECT) {
1014            Self::from(ExtensionObject::decode(stream, decoding_options)?)
1015        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::VARIANT) {
1016            Variant::Variant(Box::new(Variant::decode(stream, decoding_options)?))
1017        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::DATA_VALUE) {
1018            Self::from(DataValue::decode(stream, decoding_options)?)
1019        } else if Self::test_encoding_flag(encoding_mask, EncodingMask::DIAGNOSTIC) {
1020            Self::from(DiagnosticInfo::decode(stream, decoding_options)?)
1021        } else {
1022            Variant::Empty
1023        };
1024        Ok(result)
1025    }
1026
1027    /// Performs an EXPLICIT cast from one type to another. This will first attempt an implicit
1028    /// conversion and only then attempt to cast. Casting is potentially lossy.
1029    pub fn cast(&self, target_type: VariantTypeId) -> Variant {
1030        let result = self.convert(target_type);
1031        if result == Variant::Empty {
1032            match *self {
1033                Variant::Boolean(v) => match target_type {
1034                    VariantTypeId::String => {
1035                        UAString::from(if v { "true" } else { "false" }).into()
1036                    }
1037                    _ => Variant::Empty,
1038                },
1039                Variant::Byte(v) => match target_type {
1040                    VariantTypeId::Boolean => cast_to_bool!(v),
1041                    VariantTypeId::String => format!("{}", v).into(),
1042                    _ => Variant::Empty,
1043                },
1044                Variant::Double(v) => {
1045                    // Truncated value used in integer conversions
1046                    let vt = f64::trunc(v + 0.5);
1047                    match target_type {
1048                        VariantTypeId::Boolean => cast_to_bool!(v as i64),
1049                        VariantTypeId::Byte => cast_to_integer!(vt, f64, u8),
1050                        VariantTypeId::Float => (v as f32).into(),
1051                        VariantTypeId::Int16 => cast_to_integer!(vt, f64, i16),
1052                        VariantTypeId::Int32 => cast_to_integer!(vt, f64, i32),
1053                        VariantTypeId::Int64 => cast_to_integer!(vt, f64, i64),
1054                        VariantTypeId::SByte => cast_to_integer!(vt, f64, i8),
1055                        VariantTypeId::String => format!("{}", v).into(),
1056                        VariantTypeId::UInt16 => cast_to_integer!(vt, f64, u16),
1057                        VariantTypeId::UInt32 => cast_to_integer!(vt, f64, u32),
1058                        VariantTypeId::UInt64 => cast_to_integer!(vt, f64, u64),
1059                        _ => Variant::Empty,
1060                    }
1061                }
1062                Variant::ByteString(ref v) => match target_type {
1063                    VariantTypeId::Guid => Guid::try_from(v)
1064                        .map(|v| v.into())
1065                        .unwrap_or(Variant::Empty),
1066                    _ => Variant::Empty,
1067                },
1068                Variant::DateTime(ref v) => match target_type {
1069                    VariantTypeId::String => format!("{}", *v).into(),
1070                    _ => Variant::Empty,
1071                },
1072                Variant::ExpandedNodeId(ref v) => match target_type {
1073                    VariantTypeId::NodeId => v.node_id.clone().into(),
1074                    _ => Variant::Empty,
1075                },
1076                Variant::Float(v) => {
1077                    let vt = f32::trunc(v + 0.5);
1078                    match target_type {
1079                        VariantTypeId::Boolean => cast_to_bool!(v as i64),
1080                        VariantTypeId::Byte => cast_to_integer!(vt, f32, u8),
1081                        VariantTypeId::Int16 => cast_to_integer!(vt, f32, i16),
1082                        VariantTypeId::Int32 => cast_to_integer!(vt, f32, i32),
1083                        VariantTypeId::Int64 => cast_to_integer!(vt, f32, i64),
1084                        VariantTypeId::SByte => cast_to_integer!(vt, f32, i8),
1085                        VariantTypeId::String => format!("{}", v).into(),
1086                        VariantTypeId::UInt16 => cast_to_integer!(vt, f32, u16),
1087                        VariantTypeId::UInt32 => cast_to_integer!(vt, f32, u32),
1088                        VariantTypeId::UInt64 => cast_to_integer!(vt, f32, u64),
1089                        _ => Variant::Empty,
1090                    }
1091                }
1092                Variant::Guid(ref v) => match target_type {
1093                    VariantTypeId::String => format!("{}", *v).into(),
1094                    VariantTypeId::ByteString => ByteString::from(v.as_ref().clone()).into(),
1095                    _ => Variant::Empty,
1096                },
1097                Variant::Int16(v) => match target_type {
1098                    VariantTypeId::Boolean => cast_to_bool!(v),
1099                    VariantTypeId::Byte => cast_to_integer!(v, i16, u8),
1100                    VariantTypeId::SByte => cast_to_integer!(v, i16, i8),
1101                    VariantTypeId::String => format!("{}", v).into(),
1102                    VariantTypeId::UInt16 => cast_to_integer!(v, i16, u16),
1103                    _ => Variant::Empty,
1104                },
1105                Variant::Int32(v) => match target_type {
1106                    VariantTypeId::Boolean => cast_to_bool!(v),
1107                    VariantTypeId::Byte => cast_to_integer!(v, i32, u8),
1108                    VariantTypeId::Int16 => cast_to_integer!(v, i32, i16),
1109                    VariantTypeId::SByte => cast_to_integer!(v, i32, i8),
1110                    VariantTypeId::StatusCode => (StatusCode::from_bits_truncate(v as u32)).into(),
1111                    VariantTypeId::String => format!("{}", v).into(),
1112                    VariantTypeId::UInt16 => cast_to_integer!(v, i32, u16),
1113                    VariantTypeId::UInt32 => cast_to_integer!(v, i32, u32),
1114                    _ => Variant::Empty,
1115                },
1116                Variant::Int64(v) => match target_type {
1117                    VariantTypeId::Boolean => cast_to_bool!(v),
1118                    VariantTypeId::Byte => cast_to_integer!(v, i64, u8),
1119                    VariantTypeId::Int16 => cast_to_integer!(v, i64, i16),
1120                    VariantTypeId::Int32 => cast_to_integer!(v, i64, i32),
1121                    VariantTypeId::SByte => cast_to_integer!(v, i64, i8),
1122                    VariantTypeId::StatusCode => StatusCode::from_bits_truncate(v as u32).into(),
1123                    VariantTypeId::String => format!("{}", v).into(),
1124                    VariantTypeId::UInt16 => cast_to_integer!(v, i64, u16),
1125                    VariantTypeId::UInt32 => cast_to_integer!(v, i64, u32),
1126                    VariantTypeId::UInt64 => cast_to_integer!(v, i64, u64),
1127                    _ => Variant::Empty,
1128                },
1129                Variant::SByte(v) => match target_type {
1130                    VariantTypeId::Boolean => cast_to_bool!(v),
1131                    VariantTypeId::Byte => cast_to_integer!(v, i8, u8),
1132                    VariantTypeId::String => format!("{}", v).into(),
1133                    _ => Variant::Empty,
1134                },
1135                Variant::StatusCode(v) => match target_type {
1136                    VariantTypeId::UInt16 => (((v.bits() & 0xffff_0000) >> 16) as u16).into(),
1137                    _ => Variant::Empty,
1138                },
1139                Variant::String(ref v) => match target_type {
1140                    VariantTypeId::NodeId => {
1141                        if v.is_null() {
1142                            Variant::Empty
1143                        } else {
1144                            NodeId::from_str(v.as_ref())
1145                                .map(|v| v.into())
1146                                .unwrap_or(Variant::Empty)
1147                        }
1148                    }
1149                    VariantTypeId::ExpandedNodeId => {
1150                        if v.is_null() {
1151                            Variant::Empty
1152                        } else {
1153                            ExpandedNodeId::from_str(v.as_ref())
1154                                .map(|v| v.into())
1155                                .unwrap_or(Variant::Empty)
1156                        }
1157                    }
1158                    VariantTypeId::DateTime => {
1159                        if v.is_null() {
1160                            Variant::Empty
1161                        } else {
1162                            DateTime::from_str(v.as_ref())
1163                                .map(|v| v.into())
1164                                .unwrap_or(Variant::Empty)
1165                        }
1166                    }
1167                    VariantTypeId::LocalizedText => {
1168                        if v.is_null() {
1169                            LocalizedText::null().into()
1170                        } else {
1171                            LocalizedText::new("", v.as_ref()).into()
1172                        }
1173                    }
1174                    VariantTypeId::QualifiedName => {
1175                        if v.is_null() {
1176                            QualifiedName::null().into()
1177                        } else {
1178                            QualifiedName::new(0, v.as_ref()).into()
1179                        }
1180                    }
1181                    _ => Variant::Empty,
1182                },
1183                Variant::UInt16(v) => match target_type {
1184                    VariantTypeId::Boolean => cast_to_bool!(v),
1185                    VariantTypeId::Byte => cast_to_integer!(v, u16, u8),
1186                    VariantTypeId::SByte => cast_to_integer!(v, u16, i8),
1187                    VariantTypeId::String => format!("{}", v).into(),
1188                    _ => Variant::Empty,
1189                },
1190                Variant::UInt32(v) => match target_type {
1191                    VariantTypeId::Boolean => cast_to_bool!(v),
1192                    VariantTypeId::Byte => cast_to_integer!(v, u32, u8),
1193                    VariantTypeId::Int16 => cast_to_integer!(v, u32, i16),
1194                    VariantTypeId::SByte => cast_to_integer!(v, u32, i8),
1195                    VariantTypeId::StatusCode => StatusCode::from_bits_truncate(v).into(),
1196                    VariantTypeId::String => format!("{}", v).into(),
1197                    VariantTypeId::UInt16 => cast_to_integer!(v, u32, u16),
1198                    _ => Variant::Empty,
1199                },
1200                Variant::UInt64(v) => match target_type {
1201                    VariantTypeId::Boolean => cast_to_bool!(v),
1202                    VariantTypeId::Byte => cast_to_integer!(v, u64, u8),
1203                    VariantTypeId::Int16 => cast_to_integer!(v, u64, i16),
1204                    VariantTypeId::SByte => cast_to_integer!(v, u64, i8),
1205                    VariantTypeId::StatusCode => {
1206                        StatusCode::from_bits_truncate((v & 0x0000_0000_ffff_ffff) as u32).into()
1207                    }
1208                    VariantTypeId::String => format!("{}", v).into(),
1209                    VariantTypeId::UInt16 => cast_to_integer!(v, u64, u16),
1210                    VariantTypeId::UInt32 => cast_to_integer!(v, u64, u32),
1211                    _ => Variant::Empty,
1212                },
1213
1214                // NodeId, LocalizedText, QualifiedName, XmlElement have no explicit cast
1215                _ => Variant::Empty,
1216            }
1217        } else {
1218            result
1219        }
1220    }
1221
1222    /// Performs an IMPLICIT conversion from one type to another
1223    pub fn convert(&self, target_type: VariantTypeId) -> Variant {
1224        if self.type_id() == target_type {
1225            return self.clone();
1226        }
1227
1228        // See OPC UA Part 4 table 118
1229        match *self {
1230            Variant::Boolean(v) => {
1231                // true == 1, false == 0
1232                match target_type {
1233                    VariantTypeId::Byte => (v as u8).into(),
1234                    VariantTypeId::Double => ((v as u8) as f64).into(),
1235                    VariantTypeId::Float => ((v as u8) as f32).into(),
1236                    VariantTypeId::Int16 => (v as i16).into(),
1237                    VariantTypeId::Int32 => (v as i32).into(),
1238                    VariantTypeId::Int64 => (v as i64).into(),
1239                    VariantTypeId::SByte => (v as i8).into(),
1240                    VariantTypeId::UInt16 => (v as u16).into(),
1241                    VariantTypeId::UInt32 => (v as u32).into(),
1242                    VariantTypeId::UInt64 => (v as u64).into(),
1243                    _ => Variant::Empty,
1244                }
1245            }
1246            Variant::Byte(v) => match target_type {
1247                VariantTypeId::Double => (v as f64).into(),
1248                VariantTypeId::Float => (v as f32).into(),
1249                VariantTypeId::Int16 => (v as i16).into(),
1250                VariantTypeId::Int32 => (v as i32).into(),
1251                VariantTypeId::Int64 => (v as i64).into(),
1252                VariantTypeId::SByte => (v as i8).into(),
1253                VariantTypeId::UInt16 => (v as u16).into(),
1254                VariantTypeId::UInt32 => (v as u32).into(),
1255                VariantTypeId::UInt64 => (v as u64).into(),
1256                _ => Variant::Empty,
1257            },
1258
1259            // ByteString - everything is X or E except to itself
1260            // DateTime - everything is X or E except to itself
1261            // Double - everything is X or E except to itself
1262            Variant::ExpandedNodeId(ref v) => {
1263                // Everything is X or E except to String
1264                match target_type {
1265                    VariantTypeId::String => format!("{}", v).into(),
1266                    _ => Variant::Empty,
1267                }
1268            }
1269            Variant::Float(v) => {
1270                // Everything is X or E except to Double
1271                match target_type {
1272                    VariantTypeId::Double => (v as f64).into(),
1273                    _ => Variant::Empty,
1274                }
1275            }
1276
1277            // Guid - everything is X or E except to itself
1278            Variant::Int16(v) => match target_type {
1279                VariantTypeId::Double => (v as f64).into(),
1280                VariantTypeId::Float => (v as f32).into(),
1281                VariantTypeId::Int32 => (v as i32).into(),
1282                VariantTypeId::Int64 => (v as i64).into(),
1283                VariantTypeId::UInt32 => {
1284                    if v < 0 {
1285                        Variant::Empty
1286                    } else {
1287                        (v as u32).into()
1288                    }
1289                }
1290                VariantTypeId::UInt64 => {
1291                    if v < 0 {
1292                        Variant::Empty
1293                    } else {
1294                        (v as u64).into()
1295                    }
1296                }
1297                _ => Variant::Empty,
1298            },
1299            Variant::Int32(v) => match target_type {
1300                VariantTypeId::Double => (v as f64).into(),
1301                VariantTypeId::Float => (v as f32).into(),
1302                VariantTypeId::Int64 => (v as i64).into(),
1303                VariantTypeId::UInt64 => {
1304                    if v < 0 {
1305                        Variant::Empty
1306                    } else {
1307                        (v as u64).into()
1308                    }
1309                }
1310                _ => Variant::Empty,
1311            },
1312            Variant::Int64(v) => match target_type {
1313                VariantTypeId::Double => (v as f64).into(),
1314                VariantTypeId::Float => (v as f32).into(),
1315                _ => Variant::Empty,
1316            },
1317            Variant::NodeId(ref v) => {
1318                // Guid - everything is X or E except to ExpandedNodeId and String
1319                match target_type {
1320                    VariantTypeId::ExpandedNodeId => ExpandedNodeId::from(*v.clone()).into(),
1321                    VariantTypeId::String => format!("{}", v).into(),
1322                    _ => Variant::Empty,
1323                }
1324            }
1325            Variant::SByte(v) => match target_type {
1326                VariantTypeId::Double => (v as f64).into(),
1327                VariantTypeId::Float => (v as f32).into(),
1328                VariantTypeId::Int16 => (v as i16).into(),
1329                VariantTypeId::Int32 => (v as i32).into(),
1330                VariantTypeId::Int64 => (v as i64).into(),
1331                VariantTypeId::UInt16 => {
1332                    if v < 0 {
1333                        Variant::Empty
1334                    } else {
1335                        (v as u16).into()
1336                    }
1337                }
1338                VariantTypeId::UInt32 => {
1339                    if v < 0 {
1340                        Variant::Empty
1341                    } else {
1342                        (v as u32).into()
1343                    }
1344                }
1345                VariantTypeId::UInt64 => {
1346                    if v < 0 {
1347                        Variant::Empty
1348                    } else {
1349                        (v as u64).into()
1350                    }
1351                }
1352                _ => Variant::Empty,
1353            },
1354            Variant::StatusCode(v) => match target_type {
1355                VariantTypeId::Int32 => (v.bits() as i32).into(),
1356                VariantTypeId::Int64 => (v.bits() as i64).into(),
1357                VariantTypeId::UInt32 => (v.bits() as u32).into(),
1358                VariantTypeId::UInt64 => (v.bits() as u64).into(),
1359                _ => Variant::Empty,
1360            },
1361            Variant::String(ref v) => {
1362                if v.is_empty() {
1363                    Variant::Empty
1364                } else {
1365                    let v = v.as_ref();
1366                    match target_type {
1367                        VariantTypeId::Boolean => {
1368                            // String values containing “true”, “false”, “1” or “0” can be converted
1369                            // to Boolean values. Other string values cause a conversion error. In
1370                            // this case Strings are case-insensitive.
1371                            if v == "true" || v == "1" {
1372                                true.into()
1373                            } else if v == "false" || v == "0" {
1374                                false.into()
1375                            } else {
1376                                Variant::Empty
1377                            }
1378                        }
1379                        VariantTypeId::Byte => {
1380                            u8::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1381                        }
1382                        VariantTypeId::Double => {
1383                            f64::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1384                        }
1385                        VariantTypeId::Float => {
1386                            f32::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1387                        }
1388                        VariantTypeId::Guid => Guid::from_str(v)
1389                            .map(|v| v.into())
1390                            .unwrap_or(Variant::Empty),
1391                        VariantTypeId::Int16 => {
1392                            i16::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1393                        }
1394                        VariantTypeId::Int32 => {
1395                            i32::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1396                        }
1397                        VariantTypeId::Int64 => {
1398                            i64::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1399                        }
1400                        VariantTypeId::NodeId => NodeId::from_str(v)
1401                            .map(|v| v.into())
1402                            .unwrap_or(Variant::Empty),
1403                        VariantTypeId::SByte => {
1404                            i8::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1405                        }
1406                        VariantTypeId::UInt16 => {
1407                            u16::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1408                        }
1409                        VariantTypeId::UInt32 => {
1410                            u32::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1411                        }
1412                        VariantTypeId::UInt64 => {
1413                            u64::from_str(v).map(|v| v.into()).unwrap_or(Variant::Empty)
1414                        }
1415                        _ => Variant::Empty,
1416                    }
1417                }
1418            }
1419            Variant::LocalizedText(ref v) => match target_type {
1420                VariantTypeId::String => v.text.clone().into(),
1421                _ => Variant::Empty,
1422            },
1423            Variant::QualifiedName(ref v) => {
1424                match target_type {
1425                    VariantTypeId::String => {
1426                        if v.is_null() {
1427                            UAString::null().into()
1428                        } else {
1429                            // drop the namespace index
1430                            v.name.clone().into()
1431                        }
1432                    }
1433                    VariantTypeId::LocalizedText => {
1434                        if v.is_null() {
1435                            LocalizedText::null().into()
1436                        } else {
1437                            // empty locale, drop namespace index
1438                            LocalizedText::new("", v.name.as_ref()).into()
1439                        }
1440                    }
1441                    _ => Variant::Empty,
1442                }
1443            }
1444            Variant::UInt16(v) => {
1445                match target_type {
1446                    VariantTypeId::Double => (v as f64).into(),
1447                    VariantTypeId::Float => (v as f32).into(),
1448                    VariantTypeId::Int16 => (v as i16).into(),
1449                    VariantTypeId::Int32 => (v as i32).into(),
1450                    VariantTypeId::Int64 => (v as i64).into(),
1451                    VariantTypeId::StatusCode => {
1452                        // The 16-bit value is treated as the top 16 bits of the status code
1453                        StatusCode::from_bits_truncate((v as u32) << 16).into()
1454                    }
1455                    VariantTypeId::UInt32 => (v as u32).into(),
1456                    VariantTypeId::UInt64 => (v as u64).into(),
1457                    _ => Variant::Empty,
1458                }
1459            }
1460            Variant::UInt32(v) => match target_type {
1461                VariantTypeId::Double => (v as f64).into(),
1462                VariantTypeId::Float => (v as f32).into(),
1463                VariantTypeId::Int32 => (v as i32).into(),
1464                VariantTypeId::Int64 => (v as i64).into(),
1465                VariantTypeId::UInt64 => (v as u64).into(),
1466                _ => Variant::Empty,
1467            },
1468            Variant::UInt64(v) => match target_type {
1469                VariantTypeId::Double => (v as f64).into(),
1470                VariantTypeId::Float => (v as f32).into(),
1471                VariantTypeId::Int64 => (v as i64).into(),
1472                _ => Variant::Empty,
1473            },
1474            Variant::Array(_) => {
1475                // TODO Arrays including converting array of length 1 to scalar of same type
1476                Variant::Empty
1477            }
1478            // XmlElement everything is X
1479            _ => Variant::Empty,
1480        }
1481    }
1482
1483    pub fn type_id(&self) -> VariantTypeId {
1484        match self {
1485            Variant::Empty => VariantTypeId::Empty,
1486            Variant::Boolean(_) => VariantTypeId::Boolean,
1487            Variant::SByte(_) => VariantTypeId::SByte,
1488            Variant::Byte(_) => VariantTypeId::Byte,
1489            Variant::Int16(_) => VariantTypeId::Int16,
1490            Variant::UInt16(_) => VariantTypeId::UInt16,
1491            Variant::Int32(_) => VariantTypeId::Int32,
1492            Variant::UInt32(_) => VariantTypeId::UInt32,
1493            Variant::Int64(_) => VariantTypeId::Int64,
1494            Variant::UInt64(_) => VariantTypeId::UInt64,
1495            Variant::Float(_) => VariantTypeId::Float,
1496            Variant::Double(_) => VariantTypeId::Double,
1497            Variant::String(_) => VariantTypeId::String,
1498            Variant::DateTime(_) => VariantTypeId::DateTime,
1499            Variant::Guid(_) => VariantTypeId::Guid,
1500            Variant::ByteString(_) => VariantTypeId::ByteString,
1501            Variant::XmlElement(_) => VariantTypeId::XmlElement,
1502            Variant::NodeId(_) => VariantTypeId::NodeId,
1503            Variant::ExpandedNodeId(_) => VariantTypeId::ExpandedNodeId,
1504            Variant::StatusCode(_) => VariantTypeId::StatusCode,
1505            Variant::QualifiedName(_) => VariantTypeId::QualifiedName,
1506            Variant::LocalizedText(_) => VariantTypeId::LocalizedText,
1507            Variant::ExtensionObject(_) => VariantTypeId::ExtensionObject,
1508            Variant::Variant(_) => VariantTypeId::Variant,
1509            Variant::DataValue(_) => VariantTypeId::DataValue,
1510            Variant::Diagnostics(_) => VariantTypeId::Diagnostic,
1511            Variant::Array(_) => VariantTypeId::Array,
1512        }
1513    }
1514
1515    /// Tests and returns true if the variant holds a numeric type
1516    pub fn is_numeric(&self) -> bool {
1517        matches!(
1518            self,
1519            Variant::SByte(_)
1520                | Variant::Byte(_)
1521                | Variant::Int16(_)
1522                | Variant::UInt16(_)
1523                | Variant::Int32(_)
1524                | Variant::UInt32(_)
1525                | Variant::Int64(_)
1526                | Variant::UInt64(_)
1527                | Variant::Float(_)
1528                | Variant::Double(_)
1529        )
1530    }
1531
1532    /// Test if the variant holds an array
1533    pub fn is_array(&self) -> bool {
1534        matches!(self, Variant::Array(_))
1535    }
1536
1537    pub fn is_array_of_type(&self, variant_type: VariantTypeId) -> bool {
1538        // A non-numeric value in the array means it is not numeric
1539        match self {
1540            Variant::Array(array) => values_are_of_type(array.values.as_slice(), variant_type),
1541            _ => false,
1542        }
1543    }
1544
1545    /// Tests that the variant is in a valid state. In particular for arrays ensuring that the
1546    /// values are all acceptable and for a multi dimensional array that the dimensions equal
1547    /// the actual values.
1548    pub fn is_valid(&self) -> bool {
1549        match self {
1550            Variant::Array(array) => array.is_valid(),
1551            _ => true,
1552        }
1553    }
1554
1555    /// Converts the numeric type to a double or returns None
1556    pub fn as_f64(&self) -> Option<f64> {
1557        match *self {
1558            Variant::SByte(value) => Some(value as f64),
1559            Variant::Byte(value) => Some(value as f64),
1560            Variant::Int16(value) => Some(value as f64),
1561            Variant::UInt16(value) => Some(value as f64),
1562            Variant::Int32(value) => Some(value as f64),
1563            Variant::UInt32(value) => Some(value as f64),
1564            Variant::Int64(value) => {
1565                // NOTE: Int64 could overflow
1566                Some(value as f64)
1567            }
1568            Variant::UInt64(value) => {
1569                // NOTE: UInt64 could overflow
1570                Some(value as f64)
1571            }
1572            Variant::Float(value) => Some(value as f64),
1573            Variant::Double(value) => Some(value),
1574            _ => None,
1575        }
1576    }
1577
1578    // Returns the data type of elements in array. Returns None if this is not an array or type
1579    // cannot be determined
1580    pub fn array_data_type(&self) -> Option<NodeId> {
1581        match self {
1582            Variant::Array(array) => {
1583                if array.values.is_empty() {
1584                    error!("Cannot get the data type of an empty array");
1585                    None
1586                } else {
1587                    array.values[0].scalar_data_type()
1588                }
1589            }
1590            _ => None,
1591        }
1592    }
1593
1594    // Returns the scalar data type. Returns None for arrays
1595    pub fn scalar_data_type(&self) -> Option<NodeId> {
1596        match self {
1597            Variant::Boolean(_) => Some(DataTypeId::Boolean.into()),
1598            Variant::SByte(_) => Some(DataTypeId::SByte.into()),
1599            Variant::Byte(_) => Some(DataTypeId::Byte.into()),
1600            Variant::Int16(_) => Some(DataTypeId::Int16.into()),
1601            Variant::UInt16(_) => Some(DataTypeId::UInt16.into()),
1602            Variant::Int32(_) => Some(DataTypeId::Int32.into()),
1603            Variant::UInt32(_) => Some(DataTypeId::UInt32.into()),
1604            Variant::Int64(_) => Some(DataTypeId::Int64.into()),
1605            Variant::UInt64(_) => Some(DataTypeId::UInt64.into()),
1606            Variant::Float(_) => Some(DataTypeId::Float.into()),
1607            Variant::Double(_) => Some(DataTypeId::Double.into()),
1608            Variant::String(_) => Some(DataTypeId::String.into()),
1609            Variant::DateTime(_) => Some(DataTypeId::DateTime.into()),
1610            Variant::Guid(_) => Some(DataTypeId::Guid.into()),
1611            Variant::ByteString(_) => Some(DataTypeId::ByteString.into()),
1612            Variant::XmlElement(_) => Some(DataTypeId::XmlElement.into()),
1613            Variant::NodeId(_) => Some(DataTypeId::NodeId.into()),
1614            Variant::ExpandedNodeId(_) => Some(DataTypeId::ExpandedNodeId.into()),
1615            Variant::StatusCode(_) => Some(DataTypeId::StatusCode.into()),
1616            Variant::QualifiedName(_) => Some(DataTypeId::QualifiedName.into()),
1617            Variant::LocalizedText(_) => Some(DataTypeId::LocalizedText.into()),
1618            Variant::Variant(_) => Some(DataTypeId::BaseDataType.into()),
1619            Variant::DataValue(_) => Some(DataTypeId::DataValue.into()),
1620            Variant::Diagnostics(_) => Some(DataTypeId::DiagnosticInfo.into()),
1621            _ => None,
1622        }
1623    }
1624
1625    // Gets the encoding mask to write the variant to disk
1626    pub(crate) fn encoding_mask(&self) -> u8 {
1627        match self {
1628            Variant::Empty => 0,
1629            Variant::Boolean(_) => EncodingMask::BOOLEAN,
1630            Variant::SByte(_) => EncodingMask::SBYTE,
1631            Variant::Byte(_) => EncodingMask::BYTE,
1632            Variant::Int16(_) => EncodingMask::INT16,
1633            Variant::UInt16(_) => EncodingMask::UINT16,
1634            Variant::Int32(_) => EncodingMask::INT32,
1635            Variant::UInt32(_) => EncodingMask::UINT32,
1636            Variant::Int64(_) => EncodingMask::INT64,
1637            Variant::UInt64(_) => EncodingMask::UINT64,
1638            Variant::Float(_) => EncodingMask::FLOAT,
1639            Variant::Double(_) => EncodingMask::DOUBLE,
1640            Variant::String(_) => EncodingMask::STRING,
1641            Variant::DateTime(_) => EncodingMask::DATE_TIME,
1642            Variant::Guid(_) => EncodingMask::GUID,
1643            Variant::ByteString(_) => EncodingMask::BYTE_STRING,
1644            Variant::XmlElement(_) => EncodingMask::XML_ELEMENT,
1645            Variant::NodeId(_) => EncodingMask::NODE_ID,
1646            Variant::ExpandedNodeId(_) => EncodingMask::EXPANDED_NODE_ID,
1647            Variant::StatusCode(_) => EncodingMask::STATUS_CODE,
1648            Variant::QualifiedName(_) => EncodingMask::QUALIFIED_NAME,
1649            Variant::LocalizedText(_) => EncodingMask::LOCALIZED_TEXT,
1650            Variant::ExtensionObject(_) => EncodingMask::EXTENSION_OBJECT,
1651            Variant::Variant(_) => EncodingMask::VARIANT,
1652            Variant::DataValue(_) => EncodingMask::DATA_VALUE,
1653            Variant::Diagnostics(_) => EncodingMask::DIAGNOSTIC,
1654            Variant::Array(array) => array.encoding_mask(),
1655        }
1656    }
1657
1658    /// This function is for a special edge case of converting a byte string to a
1659    /// single array of bytes
1660    pub fn to_byte_array(&self) -> Result<Self, StatusCode> {
1661        let array = match self {
1662            Variant::ByteString(values) => match &values.value {
1663                None => Array::new_single(VariantTypeId::Byte, vec![])?,
1664                Some(values) => {
1665                    let values: Vec<Variant> = values.iter().map(|v| Variant::Byte(*v)).collect();
1666                    Array::new_single(VariantTypeId::Byte, values)?
1667                }
1668            },
1669            _ => panic!(),
1670        };
1671        Ok(Variant::from(array))
1672    }
1673
1674    /// This function returns a substring of a ByteString or a UAString
1675    fn substring(&self, min: usize, max: usize) -> Result<Variant, StatusCode> {
1676        match self {
1677            Variant::ByteString(v) => v
1678                .substring(min, max)
1679                .map(Variant::from)
1680                .map_err(|_| StatusCode::BadIndexRangeNoData),
1681            Variant::String(v) => v
1682                .substring(min, max)
1683                .map(Variant::from)
1684                .map_err(|_| StatusCode::BadIndexRangeNoData),
1685            _ => panic!("Should not be calling substring on other types"),
1686        }
1687    }
1688
1689    pub fn eq_scalar_type(&self, other: &Variant) -> bool {
1690        let self_data_type = self.scalar_data_type();
1691        let other_data_type = other.scalar_data_type();
1692        if self_data_type.is_none() || other_data_type.is_none() {
1693            false
1694        } else {
1695            self_data_type == other_data_type
1696        }
1697    }
1698
1699    pub fn eq_array_type(&self, other: &Variant) -> bool {
1700        // array
1701        let self_data_type = self.array_data_type();
1702        let other_data_type = other.array_data_type();
1703        if self_data_type.is_none() || other_data_type.is_none() {
1704            false
1705        } else {
1706            self_data_type == other_data_type
1707        }
1708    }
1709
1710    pub fn set_range_of(&mut self, range: NumericRange, other: &Variant) -> Result<(), StatusCode> {
1711        // Types need to be the same
1712        if !self.eq_array_type(other) {
1713            return Err(StatusCode::BadIndexRangeNoData);
1714        }
1715
1716        let other_array = if let Variant::Array(other) = other {
1717            other
1718        } else {
1719            return Err(StatusCode::BadIndexRangeNoData);
1720        };
1721        let other_values = &other_array.values;
1722
1723        // Check value is same type as our array
1724        match self {
1725            Variant::Array(ref mut array) => {
1726                let values = &mut array.values;
1727                match range {
1728                    NumericRange::None => Err(StatusCode::BadIndexRangeNoData),
1729                    NumericRange::Index(idx) => {
1730                        let idx = idx as usize;
1731                        if idx >= values.len() || other_values.is_empty() {
1732                            Err(StatusCode::BadIndexRangeNoData)
1733                        } else {
1734                            values[idx] = other_values[0].clone();
1735                            Ok(())
1736                        }
1737                    }
1738                    NumericRange::Range(min, max) => {
1739                        let (min, max) = (min as usize, max as usize);
1740                        if min >= values.len() {
1741                            Err(StatusCode::BadIndexRangeNoData)
1742                        } else {
1743                            // Possibly this could splice or something but it's trying to copy elements
1744                            // until either the source or destination array is finished.
1745                            let mut idx = min;
1746                            while idx < values.len() && idx <= max && idx - min < other_values.len()
1747                            {
1748                                values[idx] = other_values[idx - min].clone();
1749                                idx += 1;
1750                            }
1751                            Ok(())
1752                        }
1753                    }
1754                    NumericRange::MultipleRanges(_ranges) => {
1755                        // Not yet supported
1756                        error!("Multiple ranges not supported");
1757                        Err(StatusCode::BadIndexRangeNoData)
1758                    }
1759                }
1760            }
1761            _ => {
1762                error!("Writing a range is not supported when the recipient is not an array");
1763                Err(StatusCode::BadWriteNotSupported)
1764            }
1765        }
1766    }
1767
1768    /// This function gets a range of values from the variant if it is an array, or returns a clone
1769    /// of the variant itself.
1770    pub fn range_of(&self, range: NumericRange) -> Result<Variant, StatusCode> {
1771        match range {
1772            NumericRange::None => Ok(self.clone()),
1773            NumericRange::Index(idx) => {
1774                let idx = idx as usize;
1775                match self {
1776                    Variant::String(_) | Variant::ByteString(_) => self.substring(idx, idx),
1777                    Variant::Array(array) => {
1778                        // Get value at the index (or not)
1779                        let values = &array.values;
1780                        if let Some(v) = values.get(idx) {
1781                            let values = vec![v.clone()];
1782                            Ok(Variant::from((array.value_type, values)))
1783                        } else {
1784                            Err(StatusCode::BadIndexRangeNoData)
1785                        }
1786                    }
1787                    _ => Err(StatusCode::BadIndexRangeNoData),
1788                }
1789            }
1790            NumericRange::Range(min, max) => {
1791                let (min, max) = (min as usize, max as usize);
1792                match self {
1793                    Variant::String(_) | Variant::ByteString(_) => self.substring(min, max),
1794                    Variant::Array(array) => {
1795                        let values = &array.values;
1796                        if min >= values.len() {
1797                            // Min must be in range
1798                            Err(StatusCode::BadIndexRangeNoData)
1799                        } else {
1800                            let max = if max >= values.len() {
1801                                values.len() - 1
1802                            } else {
1803                                max
1804                            };
1805                            let values = &values[min as usize..=max];
1806                            let values: Vec<Variant> = values.to_vec();
1807                            Ok(Variant::from((array.value_type, values)))
1808                        }
1809                    }
1810                    _ => Err(StatusCode::BadIndexRangeNoData),
1811                }
1812            }
1813            NumericRange::MultipleRanges(_ranges) => {
1814                // Not yet supported
1815                error!("Multiple ranges not supported");
1816                Err(StatusCode::BadIndexRangeNoData)
1817            }
1818        }
1819    }
1820}