1use std::{
2 collections::HashMap,
3 ops::{Index, IndexMut},
4 sync::{Arc, RwLock},
5};
6
7use num::traits::FromPrimitive;
8
9#[derive(Clone, Debug, PartialEq)]
10pub enum Variant {
11 None,
12 Bool(bool),
13 Int8(i8),
14 UInt8(u8),
15 Int16(i16),
16 UInt16(u16),
17 Int32(i32),
18 UInt32(u32),
19 Int64(i64),
20 UInt64(u64),
21 Float(f32),
22 Double(f64),
23 String(String),
24 Buffer(Vec<u8>),
25 Array(Vec<Variant>),
26 Dict(HashMap<String, Variant>),
27}
28
29macro_rules! variant_from_traits {
30 ($(($vtype:ident, $value_type:ty)),+) => {
31 $(
32 impl From<$value_type> for Variant {
33 fn from(value: $value_type) -> Self {
34 Variant::$vtype(value)
35 }
36 }
37
38 impl From<Variant> for $value_type {
39 fn from(value: Variant) -> Self {
40 match value {
41 Variant::$vtype(v) => v,
42 _ => Self::default(),
43 }
44 }
45 }
46 )+
47 };
48}
49
50macro_rules! variant_number_from_traits {
51 ($(($vtype:ident, $value_type:ty)),+) => {
52 $(
53 impl From<$value_type> for Variant {
54 fn from(value: $value_type) -> Self {
55 Variant::$vtype(value)
56 }
57 }
58
59 impl From<Variant> for $value_type {
60 fn from(value: Variant) -> Self {
61 match value {
62 Variant::$vtype(v) => v,
63 _ => value.get_number::<Self>().unwrap_or_default(),
64 }
65 }
66 }
67 )+
68 };
69}
70
71variant_from_traits! {
72 (Bool, bool),
73 (String, String),
74 (Buffer, Vec<u8>),
75 (Array, Vec<Variant>),
76 (Dict, HashMap<String, Variant>)
77}
78
79variant_number_from_traits! {
80 (Int8, i8),
81 (UInt8, u8),
82 (Int16, i16),
83 (UInt16, u16),
84 (Int32, i32),
85 (UInt32, u32),
86 (Int64, i64),
87 (UInt64, u64),
88 (Float, f32),
89 (Double, f64)
90}
91
92impl From<&str> for Variant {
93 fn from(value: &str) -> Self {
94 Variant::String(value.to_string())
95 }
96}
97
98macro_rules! variant_getters {
99 ($(($get:ident, $vtype:ident, $value_type:ty)),+) => {
100 $(
101 pub fn $get(&self) -> Option<$value_type> {
102 match self {
103 Variant::$vtype(v) => Some(v.clone()),
104 _ => None,
105 }
106 }
107 )+
108 };
109}
110
111macro_rules! variant_number_getters {
112 ($(($get:ident, $vtype:ident, $value_type:ty)),+) => {
113 $(
114 pub fn $get(&self) -> Option<$value_type> {
115 match self {
116 Variant::$vtype(v) => Some(v.clone()),
117 _ => self.get_number::<$value_type>(),
118 }
119 }
120 )+
121 };
122}
123
124macro_rules! variant_methods {
125 ($(($get:ident, $set:ident, $array_add:ident, $array_get:ident, $array_set:ident, $dict_set:ident, $dict_get:ident, $vtype:ident, $value_type:ty)),+) => {
126 $(
127 pub fn $set(&mut self, value: $value_type) {
128 *self = Variant::from(value);
129 }
130
131 pub fn $array_add(&mut self, value: $value_type) {
132 match self {
133 Variant::Array(v) => {
134 v.push(Variant::from(value));
135 },
136 _ => (),
137 }
138 }
139
140 pub fn $array_get(&self, index: usize) -> Option<$value_type> {
141 match self {
142 Variant::Array(array) => {
143 array.get(index)?.$get()
144 },
145 _ => None,
146 }
147 }
148
149 pub fn $array_set(&mut self, index: usize, value: $value_type) {
150 match self {
151 Variant::Array(array) => {
152 if index >= array.len() {
153 array.resize(index + 1, Variant::None);
154 }
155 array[index] = Variant::from(value);
156 },
157 _ => (),
158 }
159 }
160
161 pub fn $dict_get(&self, key: &str) -> Option<$value_type> {
162 match self {
163 Variant::Dict(dict) => {
164 dict.get(key)?.$get()
165 }
166 _ => None,
167 }
168 }
169
170 pub fn $dict_set(&mut self, key: &str, value: $value_type) {
171 match self {
172 Variant::Dict(v) => {
173 v.insert(key.to_string(), Variant::from(value));
174 },
175 _ => (),
176 }
177 }
178 )+
179 };
180}
181
182impl Variant {
183 pub fn new() -> Self {
184 Variant::None
185 }
186
187 pub fn new_array() -> Self {
188 Variant::Array(Vec::new())
189 }
190
191 pub fn new_dict() -> Variant {
192 Variant::Dict(HashMap::new())
193 }
194
195 pub fn len(&self) -> usize {
196 match self {
197 Variant::String(v) => v.len(),
198 Variant::Buffer(v) => v.len(),
199 Variant::Array(v) => v.len(),
200 Variant::Dict(v) => v.len(),
201 _ => 0,
202 }
203 }
204
205 fn reset_value(&mut self) {
206 match self {
207 Variant::Bool(v) => *v = false,
208 Variant::Int8(v) => *v = 0,
209 Variant::UInt8(v) => *v = 0,
210 Variant::Int16(v) => *v = 0,
211 Variant::UInt16(v) => *v = 0,
212 Variant::Int32(v) => *v = 0,
213 Variant::UInt32(v) => *v = 0,
214 Variant::Int64(v) => *v = 0,
215 Variant::UInt64(v) => *v = 0,
216 Variant::Float(v) => *v = 0.0,
217 Variant::Double(v) => *v = 0.0,
218 Variant::String(v) => v.clear(),
219 Variant::Buffer(v) => v.clear(),
220 Variant::Array(v) => v.clear(),
221 Variant::Dict(v) => v.clear(),
222 _ => (),
223 }
224 }
225
226 pub fn clear(&mut self) {
227 match self {
228 Variant::String(v) => v.clear(),
229 Variant::Buffer(v) => v.clear(),
230 Variant::Array(v) => v.clear(),
231 Variant::Dict(v) => v.clear(),
232 _ => self.reset_value(),
233 }
234 }
235
236 pub fn concat(&mut self, other: &Self) -> bool {
237 match (self, other) {
238 (Variant::String(v1), Variant::String(v2)) => {
239 v1.push_str(v2);
240 true
241 }
242 (Variant::Buffer(v1), Variant::Buffer(v2)) => {
243 v1.append(&mut v2.clone());
244 true
245 }
246 (Variant::Array(v1), Variant::Array(v2)) => {
247 v1.append(&mut v2.clone());
248 true
249 }
250 (Variant::Dict(v1), Variant::Dict(v2)) => {
251 v1.extend(v2.clone());
252 true
253 }
254 _ => false,
255 }
256 }
257
258 pub fn is_empty(&self) -> bool {
259 if self.is_number() {
260 return false;
261 }
262 self.len() == 0
263 }
264
265 pub fn is_number(&self) -> bool {
266 match self {
267 Variant::Int8(_) |
268 Variant::UInt8(_) |
269 Variant::Int16(_) |
270 Variant::UInt16(_) |
271 Variant::Int32(_) |
272 Variant::UInt32(_) |
273 Variant::Int64(_) |
274 Variant::UInt64(_) |
275 Variant::Float(_) |
276 Variant::Double(_) => true,
277 _ => false,
278 }
279 }
280
281 pub fn set<T: Into<Self>>(&mut self, value: T) {
282 *self = value.into();
283 }
284
285 pub fn get<T: From<Self>>(&self) -> T {
286 T::from(self.clone())
287 }
288
289 pub fn get_number<T>(&self) -> Option<T>
290 where
291 T: FromPrimitive,
292 {
293 match self {
294 Variant::Int8(value) => T::from_i8(*value),
295 Variant::UInt8(value) => T::from_u8(*value),
296 Variant::Int16(value) => T::from_i16(*value),
297 Variant::UInt16(value) => T::from_u16(*value),
298 Variant::Int32(value) => T::from_i32(*value),
299 Variant::UInt32(value) => T::from_u32(*value),
300 Variant::Int64(value) => T::from_i64(*value),
301 Variant::UInt64(value) => T::from_u64(*value),
302 Variant::Float(value) => T::from_f32(*value),
303 Variant::Double(value) => T::from_f64(*value),
304 _ => None,
305 }
306 }
307
308 pub fn array_add(&mut self, value: Variant) {
309 match self {
310 Variant::Array(v) => {
311 v.push(value);
312 }
313 _ => (),
314 }
315 }
316
317 pub fn array_get(&self, index: usize) -> Option<Variant> {
318 match self {
319 Variant::Array(v) => v.get(index).cloned(),
320 _ => None,
321 }
322 }
323
324 pub fn array_set(&mut self, index: usize, value: Variant) {
325 match self {
326 Variant::Array(v) => {
327 if index >= v.len() {
328 v.resize(index + 1, Variant::None);
329 }
330 v[index] = value;
331 }
332 _ => (),
333 }
334 }
335
336 pub fn array_remove(&mut self, index: usize) -> bool {
337 match self {
338 Variant::Array(v) => {
339 if index < v.len() {
340 v.remove(index);
341 true
342 } else {
343 false
344 }
345 }
346 _ => false,
347 }
348 }
349
350 pub fn dict_get(&self, key: &str) -> Option<Variant> {
351 match self {
352 Variant::Dict(dict) => dict.get(key).cloned(),
353 _ => None,
354 }
355 }
356
357 pub fn dict_set(&mut self, key: &str, value: Variant) {
358 match self {
359 Variant::Dict(v) => {
360 v.insert(key.to_string(), value);
361 }
362 _ => (),
363 }
364 }
365
366 pub fn dict_remove(&mut self, key: &str) -> bool {
367 match self {
368 Variant::Dict(v) => v.remove(key).is_some(),
369 _ => false,
370 }
371 }
372
373 pub fn dict_contains(&self, key: &str) -> bool {
374 match self {
375 Variant::Dict(dict) => dict.contains_key(key),
376 _ => false,
377 }
378 }
379
380 pub fn array_iter(&self) -> Option<impl Iterator<Item = &Variant> + '_> {
381 match self {
382 Variant::Array(array) => Some(array.iter()),
383 _ => None,
384 }
385 }
386
387 pub fn array_iter_mut(&mut self) -> Option<impl Iterator<Item = &mut Variant> + '_> {
388 match self {
389 Variant::Array(array) => Some(array.iter_mut()),
390 _ => None,
391 }
392 }
393
394 pub fn dict_iter(&self) -> Option<impl Iterator<Item = (&String, &Variant)> + '_> {
395 match self {
396 Variant::Dict(dict) => Some(dict.iter()),
397 _ => None,
398 }
399 }
400
401 pub fn dict_iter_mut(&mut self) -> Option<impl Iterator<Item = (&String, &mut Variant)> + '_> {
402 match self {
403 Variant::Dict(dict) => Some(dict.iter_mut()),
404 _ => None,
405 }
406 }
407
408 variant_getters! {
409 (get_bool, Bool, bool),
410 (get_string, String, String),
411 (get_buffer, Buffer, Vec<u8>)
412 }
413
414 variant_number_getters! {
415 (get_int8, Int8, i8),
416 (get_uint8, UInt8, u8),
417 (get_int16, Int16, i16),
418 (get_uint16, UInt16, u16),
419 (get_int32, Int32, i32),
420 (get_uint32, UInt32, u32),
421 (get_int64, Int64, i64),
422 (get_uint64, UInt64, u64),
423 (get_float, Float, f32),
424 (get_double, Double, f64)
425 }
426
427 variant_methods! {
428 (get_bool, set_bool, array_add_bool, array_get_bool, array_set_bool, dict_set_bool, dict_get_bool, Bool, bool),
429 (get_int8, set_int8, array_add_int8, array_get_int8, array_set_int8, dict_set_int8, dict_get_int8, Int8, i8),
430 (get_uint8, set_uint8, array_add_uint8, array_get_uint8, array_set_uint8, dict_set_uint8, dict_get_uint8, UInt8, u8),
431 (get_int16, set_int16, array_add_int16, array_get_int16, array_set_int16, dict_set_int16, dict_get_int16, Int16, i16),
432 (get_uint16, set_uint16, array_add_uint16, array_get_uint16, array_set_uint16, dict_set_uint16, dict_get_uint16, UInt16, u16),
433 (get_int32, set_int32, array_add_int32, array_get_int32, array_set_int32, dict_set_int32, dict_get_int32, Int32, i32),
434 (get_uint32, set_uint32, array_add_uint32, array_get_uint32, array_set_uint32, dict_set_uint32, dict_get_uint32, UInt32, u32),
435 (get_int64, set_int64, array_add_int64, array_get_int64, array_set_int64, dict_set_int64, dict_get_int64, Int64, i64),
436 (get_uint64, set_uint64, array_add_uint64, array_get_uint64, array_set_uint64, dict_set_uint64, dict_get_uint64, UInt64, u64),
437 (get_float, set_float, array_add_float, array_get_float, array_set_float, dict_set_float, dict_get_float, Float, f32),
438 (get_double, set_double, array_add_double, array_get_double, array_set_double, dict_set_double, dict_get_double, Double, f64),
439 (get_string, set_string, array_add_string, array_get_string, array_set_string, dict_set_string, dict_get_string, String, String),
440 (get_buffer, set_buffer, array_add_buffer, array_get_buffer, array_set_buffer, dict_set_buffer, dict_get_buffer, Buffer, Vec<u8>)
441 }
442}
443
444impl Index<usize> for Variant {
445 type Output = Variant;
446
447 fn index(&self, index: usize) -> &Self::Output {
448 match self {
449 Variant::Array(v) => v.get(index).unwrap_or(&Variant::None),
450 _ => &Variant::None,
451 }
452 }
453}
454
455impl IndexMut<usize> for Variant {
456 fn index_mut(&mut self, index: usize) -> &mut Self::Output {
457 match self {
458 Variant::Array(array) => {
459 if index >= array.len() {
460 array.resize(index + 1, Variant::None);
461 }
462 &mut array[index]
463 }
464 _ => {
465 *self = Variant::Array(Vec::new());
466 self.index_mut(index)
467 }
468 }
469 }
470}
471
472impl Index<&str> for Variant {
473 type Output = Variant;
474
475 fn index(&self, index: &str) -> &Self::Output {
476 match self {
477 Variant::Dict(v) => v.get(index).unwrap_or(&Variant::None),
478 _ => &Variant::None,
479 }
480 }
481}
482
483impl IndexMut<&str> for Variant {
484 fn index_mut(&mut self, index: &str) -> &mut Self::Output {
485 match self {
486 Variant::Dict(dict) => dict.entry(index.to_string()).or_insert(Variant::None),
487 _ => {
488 *self = Variant::Dict(HashMap::new());
489 self.index_mut(index)
490 }
491 }
492 }
493}
494
495impl FromIterator<Variant> for Variant {
496 fn from_iter<I: IntoIterator<Item = Variant>>(iter: I) -> Self {
497 Variant::Array(iter.into_iter().collect())
498 }
499}
500
501impl FromIterator<(String, Variant)> for Variant {
502 fn from_iter<I: IntoIterator<Item = (String, Variant)>>(iter: I) -> Self {
503 Variant::Dict(iter.into_iter().collect())
504 }
505}
506
507#[derive(Clone)]
508pub struct SharedVariant {
509 inner: Arc<RwLock<Variant>>,
510}
511
512impl From<Variant> for SharedVariant {
513 fn from(variant: Variant) -> Self {
514 SharedVariant {
515 inner: Arc::new(RwLock::new(variant)),
516 }
517 }
518}
519
520macro_rules! shared_variant_from_traits {
521 ($(($value_type:ty)),+) => {
522 $(
523 impl From<$value_type> for SharedVariant {
524 fn from(value: $value_type) -> Self {
525 Variant::from(value).into()
526 }
527 }
528 )+
529 };
530}
531
532shared_variant_from_traits! {
533 (bool),
534 (i8),
535 (u8),
536 (i16),
537 (u16),
538 (i32),
539 (u32),
540 (i64),
541 (u64),
542 (f32),
543 (f64),
544 (String),
545 (Vec<u8>),
546 (Vec<Variant>),
547 (HashMap<String, Variant>)
548}
549
550impl SharedVariant {
551 pub fn inner(&self) -> Arc<RwLock<Variant>> {
552 self.inner.clone()
553 }
554}