1use crate::variant::*;
2use crate::StatusCode;
3
4#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
8pub struct Array {
9 pub value_type: VariantTypeId,
11
12 pub values: Vec<Variant>,
14
15 pub dimensions: Vec<u32>,
20}
21
22impl Array {
23 pub fn new_single<V>(value_type: VariantTypeId, values: V) -> Result<Array, StatusCode>
24 where
25 V: Into<Vec<Variant>>,
26 {
27 let values = values.into();
28 if Self::validate_array_type_to_values(value_type, &values) {
29 Ok(Array {
30 value_type,
31 values,
32 dimensions: Vec::new(),
33 })
34 } else {
35 Err(StatusCode::BadDecodingError)
36 }
37 }
38
39 pub fn new_multi<V, D>(
40 value_type: VariantTypeId,
41 values: V,
42 dimensions: D,
43 ) -> Result<Array, StatusCode>
44 where
45 V: Into<Vec<Variant>>,
46 D: Into<Vec<u32>>,
47 {
48 let values = values.into();
49 if Self::validate_array_type_to_values(value_type, &values) {
50 Ok(Array {
51 value_type,
52 values,
53 dimensions: dimensions.into(),
54 })
55 } else {
56 Err(StatusCode::BadDecodingError)
57 }
58 }
59
60 fn validate_array_type_to_values(value_type: VariantTypeId, values: &[Variant]) -> bool {
62 match value_type {
63 VariantTypeId::Array | VariantTypeId::Empty => {
64 error!("Invalid array type supplied");
65 false
66 }
67 _ => {
68 if !values_are_of_type(values, value_type) {
69 error!("Value type of array does not match contents");
71 false
72 } else {
73 true
74 }
75 }
76 }
77 }
78
79 pub fn is_valid(&self) -> bool {
80 self.is_valid_dimensions() && Self::array_is_valid(&self.values)
81 }
82
83 pub fn has_dimensions(&self) -> bool {
84 !self.dimensions.is_empty()
85 }
86
87 pub fn encoding_mask(&self) -> u8 {
88 let mut encoding_mask = self.value_type.encoding_mask();
89 encoding_mask |= EncodingMask::ARRAY_VALUES_BIT;
90 if self.has_dimensions() {
91 encoding_mask |= EncodingMask::ARRAY_DIMENSIONS_BIT;
92 }
93 encoding_mask
94 }
95
96 fn array_is_valid(values: &[Variant]) -> bool {
98 if values.is_empty() {
99 true
100 } else {
101 let expected_type_id = values[0].type_id();
102 if expected_type_id == VariantTypeId::Array {
103 error!("Variant array contains nested array {:?}", expected_type_id);
105 false
106 } else if values.len() > 1 {
107 values_are_of_type(&values[1..], expected_type_id)
108 } else {
109 true
111 }
112 }
113 }
114
115 fn is_valid_dimensions(&self) -> bool {
116 let mut length: usize = 1;
118 for d in &self.dimensions {
119 if *d == 0 {
121 continue;
123 }
124 length *= *d as usize;
125 }
126 length <= self.values.len()
127 }
128}
129
130pub fn values_are_of_type(values: &[Variant], expected_type: VariantTypeId) -> bool {
132 let found_unexpected = values.iter().any(|v| v.type_id() != expected_type);
134 if found_unexpected {
135 error!(
136 "Variant array's type is expected to be {:?} but found other types in it",
137 expected_type
138 );
139 };
140 !found_unexpected
141}