1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
use crate::{
variant::*,
};
pub(crate) const ARRAY_DIMENSIONS_BIT: u8 = 1 << 6;
pub(crate) const ARRAY_VALUES_BIT: u8 = 1 << 7;
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct Array {
pub values: Vec<Variant>,
pub dimensions: Vec<u32>,
}
impl Array {
pub fn new_single<V>(values: V) -> Array where V: Into<Vec<Variant>> {
Array {
values: values.into(),
dimensions: Vec::new(),
}
}
pub fn new_multi<V, D>(values: V, dimensions: D) -> Array
where V: Into<Vec<Variant>>, D: Into<Vec<u32>> {
Array {
values: values.into(),
dimensions: dimensions.into(),
}
}
pub fn is_valid(&self) -> bool {
self.is_valid_dimensions() && Self::array_is_valid(&self.values)
}
pub fn has_dimensions(&self) -> bool {
!self.dimensions.is_empty()
}
pub fn encoding_mask(&self) -> u8 {
let mut encoding_mask = if self.values.is_empty() {
0u8
} else {
self.values[0].encoding_mask()
};
encoding_mask |= ARRAY_VALUES_BIT;
if self.has_dimensions() {
encoding_mask |= ARRAY_DIMENSIONS_BIT;
}
encoding_mask
}
fn array_is_valid(values: &[Variant]) -> bool {
if values.is_empty() {
true
} else {
let expected_type_id = values[0].type_id();
if expected_type_id == VariantTypeId::Array {
error!("Variant array contains nested array {:?}", expected_type_id);
false
} else if values.len() > 1 {
values_are_of_type(&values[1..], expected_type_id)
} else {
true
}
}
}
fn is_valid_dimensions(&self) -> bool {
let mut length: usize = 1;
for d in &self.dimensions {
if *d == 0 {
continue;
}
length *= *d as usize;
}
length <= self.values.len()
}
}
pub fn values_are_of_type(values: &[Variant], expected_type: VariantTypeId) -> bool {
let found_unexpected = values.iter().any(|v| v.type_id() != expected_type);
if found_unexpected {
error!("Variant array's type is expected to be {:?} but found other types in it", expected_type);
};
!found_unexpected
}