Skip to main content

radiate_expr/datatype/
value.rs

1use super::{DataType, Field};
2use num_traits::NumCast;
3#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5use std::{collections::HashMap, fmt::Debug, hash::Hash, time::Duration};
6
7#[derive(Clone, Default, Debug)]
8pub enum AnyValue<'a> {
9    #[default]
10    Null,
11
12    Bool(bool),
13
14    UInt8(u8),
15    UInt16(u16),
16    UInt32(u32),
17    UInt64(u64),
18    UInt128(u128),
19
20    Int8(i8),
21    Int16(i16),
22    Int32(i32),
23    Int64(i64),
24    Int128(i128),
25
26    Float32(f32),
27    Float64(f64),
28
29    Duration(Duration),
30
31    Char(char),
32    Str(&'a str),
33    StrOwned(String),
34
35    Slice(&'a [AnyValue<'a>]),
36    Vector(Vec<AnyValue<'a>>),
37
38    Struct(Vec<(Field, AnyValue<'a>)>),
39}
40
41impl<'a> AnyValue<'a> {
42    #[inline]
43    pub fn is_null(&self) -> bool {
44        matches!(self, Self::Null)
45    }
46
47    #[inline]
48    pub fn is_boolean(&self) -> bool {
49        matches!(self, Self::Bool(_))
50    }
51
52    #[inline]
53    pub fn is_float(&self) -> bool {
54        matches!(self, Self::Float32(_) | Self::Float64(_))
55    }
56
57    #[inline]
58    pub fn is_int(&self) -> bool {
59        matches!(
60            self,
61            Self::Int8(_)
62                | Self::Int16(_)
63                | Self::Int32(_)
64                | Self::Int64(_)
65                | Self::Int128(_)
66                | Self::UInt8(_)
67                | Self::UInt16(_)
68                | Self::UInt32(_)
69                | Self::UInt64(_)
70                | Self::UInt128(_)
71        )
72    }
73
74    #[inline]
75    pub fn is_string(&self) -> bool {
76        matches!(self, Self::Str(_) | Self::StrOwned(_))
77    }
78
79    #[inline]
80    pub fn is_nested(&self) -> bool {
81        matches!(self, Self::Struct(_) | Self::Vector(_) | Self::Slice(_))
82    }
83
84    #[inline]
85    pub fn len(&self) -> Option<usize> {
86        match self {
87            Self::Slice(vals) => Some(vals.len()),
88            Self::Vector(vals) => Some(vals.len()),
89            Self::Struct(vals) => Some(vals.len()),
90            _ => None,
91        }
92    }
93
94    #[inline]
95    pub fn is_numeric(&self) -> bool {
96        matches!(
97            self,
98            Self::UInt8(_)
99                | Self::UInt16(_)
100                | Self::UInt32(_)
101                | Self::UInt64(_)
102                | Self::Int8(_)
103                | Self::Int16(_)
104                | Self::Int32(_)
105                | Self::Int64(_)
106                | Self::Int128(_)
107                | Self::Float32(_)
108                | Self::Float64(_)
109        )
110    }
111
112    #[inline]
113    pub fn type_name(&self) -> &'static str {
114        match self {
115            Self::Null => "null",
116            Self::Bool(_) => "bool",
117            Self::UInt8(_) => "u8",
118            Self::UInt16(_) => "u16",
119            Self::UInt32(_) => "u32",
120            Self::UInt64(_) => "u64",
121            Self::UInt128(_) => "u128",
122            Self::Int8(_) => "i8",
123            Self::Int16(_) => "i16",
124            Self::Int32(_) => "i32",
125            Self::Int64(_) => "i64",
126            Self::Int128(_) => "i128",
127            Self::Float32(_) => "f32",
128            Self::Float64(_) => "f64",
129            Self::Char(_) => "char",
130            Self::Str(_) => "string",
131            Self::StrOwned(_) => "string",
132            Self::Slice(_) => "list",
133            Self::Vector(_) => "list",
134            Self::Struct(_) => "struct",
135            Self::Duration(_) => "duration",
136        }
137    }
138
139    #[inline]
140    pub fn dtype(&self) -> DataType {
141        match self {
142            Self::Null => DataType::Null,
143
144            Self::Bool(_) => DataType::Boolean,
145
146            Self::UInt8(_) => DataType::UInt8,
147            Self::UInt16(_) => DataType::UInt16,
148            Self::UInt32(_) => DataType::UInt32,
149            Self::UInt64(_) => DataType::UInt64,
150            Self::UInt128(_) => DataType::UInt128,
151
152            Self::Int8(_) => DataType::Int8,
153            Self::Int16(_) => DataType::Int16,
154            Self::Int32(_) => DataType::Int32,
155            Self::Int64(_) => DataType::Int64,
156            Self::Int128(_) => DataType::Int128,
157
158            Self::Float32(_) => DataType::Float32,
159            Self::Float64(_) => DataType::Float64,
160
161            Self::Duration(_) => DataType::Duration,
162
163            Self::Char(_) => DataType::Char,
164            Self::Str(_) => DataType::String,
165            Self::StrOwned(_) => DataType::String,
166
167            Self::Slice(vals) => DataType::List(
168                vals.iter()
169                    .map(|v| v.dtype())
170                    .next()
171                    .unwrap_or(DataType::Null)
172                    .into(),
173            ),
174            Self::Vector(vals) => DataType::List(
175                vals.iter()
176                    .map(|v| v.dtype())
177                    .next()
178                    .unwrap_or(DataType::Null)
179                    .into(),
180            ),
181
182            Self::Struct(vals) => DataType::Struct(vals.iter().map(|(f, _)| f.clone()).collect()),
183        }
184    }
185
186    pub fn cast(self, to: &DataType) -> Option<AnyValue<'a>> {
187        use DataType as D;
188
189        if self.dtype() == *to {
190            return Some(self);
191        }
192
193        match (self, to) {
194            (_, D::Null) => Some(AnyValue::Null),
195            (AnyValue::Bool(v), D::Boolean) => Some(AnyValue::Bool(v)),
196            (v, D::UInt8) => v.extract().map(AnyValue::UInt8),
197            (v, D::UInt16) => v.extract().map(AnyValue::UInt16),
198            (v, D::UInt32) => v.extract().map(AnyValue::UInt32),
199            (v, D::UInt64) => v.extract().map(AnyValue::UInt64),
200            (v, D::UInt128) => v.extract().map(AnyValue::UInt128),
201            (v, D::Int8) => v.extract().map(AnyValue::Int8),
202            (v, D::Int16) => v.extract().map(AnyValue::Int16),
203            (v, D::Int32) => v.extract().map(AnyValue::Int32),
204            (v, D::Int64) => v.extract().map(AnyValue::Int64),
205            (v, D::Int128) => v.extract().map(AnyValue::Int128),
206            (v, D::Float32) => v.extract().map(AnyValue::Float32),
207            (v, D::Float64) => v.extract().map(AnyValue::Float64),
208            (v, D::Duration) => v
209                .extract()
210                .map(|ms| AnyValue::Duration(Duration::from_millis(ms))),
211            (v, D::Char) => v.extract::<u8>().map(|b| AnyValue::Char(b as char)),
212            (v @ AnyValue::Str(_), D::String) | (v @ AnyValue::StrOwned(_), D::String) => {
213                Some(v.into_static())
214            }
215            _ => None,
216        }
217    }
218
219    /// Try to coerce to an AnyValue with static lifetime.
220    /// This can be done if it does not borrow any values.
221    #[inline]
222    pub fn into_static(self) -> AnyValue<'static> {
223        use AnyValue::*;
224        match self {
225            Null => Null,
226            Int8(v) => Int8(v),
227            Int16(v) => Int16(v),
228            Int32(v) => Int32(v),
229            Int64(v) => Int64(v),
230            Int128(v) => Int128(v),
231            UInt8(v) => UInt8(v),
232            UInt16(v) => UInt16(v),
233            UInt32(v) => UInt32(v),
234            UInt64(v) => UInt64(v),
235            UInt128(v) => UInt128(v),
236            Bool(v) => Bool(v),
237            Float32(v) => Float32(v),
238            Float64(v) => Float64(v),
239            Duration(d) => Duration(d),
240            Char(v) => Char(v),
241            Str(v) => StrOwned(v.to_string()),
242            StrOwned(v) => StrOwned(v),
243            Slice(v) => Vector(v.into_iter().map(|v| v.clone().into_static()).collect()),
244            Vector(v) => Vector(v.into_iter().map(AnyValue::into_static).collect()),
245            Struct(v) => Struct(
246                v.into_iter()
247                    .map(|(field, val)| (field, val.into_static()))
248                    .collect(),
249            ),
250        }
251    }
252
253    pub fn extract<T: NumCast>(&self) -> Option<T> {
254        match self {
255            AnyValue::UInt8(v) => NumCast::from(*v),
256            AnyValue::UInt16(v) => NumCast::from(*v),
257            AnyValue::UInt32(v) => NumCast::from(*v),
258            AnyValue::UInt64(v) => NumCast::from(*v),
259            AnyValue::UInt128(v) => NumCast::from(*v),
260            AnyValue::Int8(v) => NumCast::from(*v),
261            AnyValue::Int16(v) => NumCast::from(*v),
262            AnyValue::Int32(v) => NumCast::from(*v),
263            AnyValue::Int64(v) => NumCast::from(*v),
264            AnyValue::Int128(v) => NumCast::from(*v),
265            AnyValue::Float32(v) => NumCast::from(*v),
266            AnyValue::Float64(v) => NumCast::from(*v),
267            AnyValue::Duration(d) => NumCast::from(d.as_millis()),
268            _ => None,
269        }
270    }
271
272    pub fn into_string(self) -> Option<String> {
273        match self {
274            AnyValue::Str(s) => Some(s.to_string()),
275            AnyValue::StrOwned(s) => Some(s),
276            _ => None,
277        }
278    }
279
280    pub fn as_str(&self) -> Option<&str> {
281        match self {
282            AnyValue::Str(s) => Some(*s),
283            AnyValue::StrOwned(s) => Some(s.as_str()),
284            _ => None,
285        }
286    }
287}
288
289impl<'a> AnyValue<'a> {
290    pub fn get_index(&self, index: usize) -> Option<AnyValue<'a>> {
291        match self {
292            AnyValue::Vector(values) => values.get(index).cloned(),
293            AnyValue::Slice(values) => values.get(index).cloned(),
294            _ => None,
295        }
296    }
297
298    pub fn get_key(&self, key: &AnyValue<'a>) -> Option<AnyValue<'a>> {
299        match self {
300            AnyValue::Struct(fields) => {
301                let key_str = match key {
302                    AnyValue::Str(s) => *s,
303                    AnyValue::StrOwned(s) => s.as_str(),
304                    _ => return None,
305                };
306
307                fields
308                    .iter()
309                    .find(|(field, _)| field.name() == key_str)
310                    .map(|(_, value)| value.clone())
311            }
312            _ => None,
313        }
314    }
315
316    pub fn get_field(&self, field: &Field) -> Option<AnyValue<'a>> {
317        match self {
318            AnyValue::Struct(fields) => fields
319                .iter()
320                .find(|(f, _)| f.name() == field.name())
321                .map(|(_, value)| value.clone()),
322            _ => None,
323        }
324    }
325}
326
327impl<'a> PartialEq for AnyValue<'a> {
328    #[inline]
329    fn eq(&self, other: &Self) -> bool {
330        use AnyValue::*;
331        match (self, other) {
332            (Null, Null) => true,
333            (Bool(a), Bool(b)) => a == b,
334            (UInt8(a), UInt8(b)) => a == b,
335            (UInt16(a), UInt16(b)) => a == b,
336            (UInt32(a), UInt32(b)) => a == b,
337            (UInt64(a), UInt64(b)) => a == b,
338            (Int8(a), Int8(b)) => a == b,
339            (Int16(a), Int16(b)) => a == b,
340            (Int32(a), Int32(b)) => a == b,
341            (Int64(a), Int64(b)) => a == b,
342            (Int128(a), Int128(b)) => a == b,
343            (Float32(a), Float32(b)) => a == b,
344            (Float64(a), Float64(b)) => a == b,
345            (Duration(a), Duration(b)) => a == b,
346            (Char(a), Char(b)) => a == b,
347            (Str(a), Str(b)) => a == b,
348            (Str(a), StrOwned(b)) => *a == b.as_str(),
349            (StrOwned(a), Str(b)) => a.as_str() == *b,
350            (StrOwned(a), StrOwned(b)) => a == b,
351            (Vector(a), Vector(b)) if a.len() == b.len() => {
352                a.iter().zip(b.iter()).all(|(x, y)| x == y)
353            }
354            (Struct(a), Struct(b))
355                if a.len() == b.len()
356                    && a.iter()
357                        .map(|(f, _)| f.name())
358                        .eq(b.iter().map(|(f, _)| f.name())) =>
359            {
360                a.iter()
361                    .zip(b.iter())
362                    .all(|((f1, v1), (f2, v2))| f1.name() == f2.name() && v1 == v2)
363            }
364            _ => false,
365        }
366    }
367}
368
369impl<'a> Eq for AnyValue<'a> {}
370
371impl<'a> Hash for AnyValue<'a> {
372    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
373        use AnyValue::*;
374        match self {
375            Null => 0.hash(state),
376            Bool(v) => v.hash(state),
377
378            Int8(v) => v.hash(state),
379            Int16(v) => v.hash(state),
380            Int32(v) => v.hash(state),
381            Int64(v) => v.hash(state),
382            Int128(v) => v.hash(state),
383
384            UInt8(v) => v.hash(state),
385            UInt16(v) => v.hash(state),
386            UInt32(v) => v.hash(state),
387            UInt64(v) => v.hash(state),
388            UInt128(v) => v.hash(state),
389
390            Float32(v) => v.to_ne_bytes().hash(state),
391            Float64(v) => v.to_ne_bytes().hash(state),
392
393            Duration(v) => v.hash(state),
394
395            Char(v) => v.hash(state),
396            Str(v) => v.hash(state),
397            StrOwned(v) => v.hash(state),
398
399            Vector(v) => v.hash(state),
400            Slice(v) => v.hash(state),
401
402            Struct(v) => v.iter().for_each(|(k, v)| {
403                k.hash(state);
404                v.hash(state);
405            }),
406        }
407    }
408}
409
410impl<'a> From<&'a str> for AnyValue<'a> {
411    fn from(s: &'a str) -> Self {
412        AnyValue::Str(s)
413    }
414}
415
416impl<'a> From<String> for AnyValue<'a> {
417    fn from(s: String) -> Self {
418        AnyValue::StrOwned(s)
419    }
420}
421
422impl From<f32> for AnyValue<'_> {
423    fn from(f: f32) -> Self {
424        AnyValue::Float32(f)
425    }
426}
427
428impl From<f64> for AnyValue<'_> {
429    fn from(f: f64) -> Self {
430        AnyValue::Float64(f)
431    }
432}
433
434impl From<bool> for AnyValue<'_> {
435    fn from(b: bool) -> Self {
436        AnyValue::Bool(b)
437    }
438}
439
440impl From<char> for AnyValue<'_> {
441    fn from(c: char) -> Self {
442        AnyValue::Char(c)
443    }
444}
445
446impl<'a> From<Duration> for AnyValue<'a> {
447    fn from(d: Duration) -> Self {
448        AnyValue::Duration(d)
449    }
450}
451
452impl<'a> From<Vec<AnyValue<'a>>> for AnyValue<'a> {
453    fn from(v: Vec<AnyValue<'a>>) -> Self {
454        AnyValue::Vector(v)
455    }
456}
457
458impl From<i32> for AnyValue<'_> {
459    fn from(i: i32) -> Self {
460        AnyValue::Int32(i)
461    }
462}
463
464impl<T, K> From<HashMap<T, K>> for AnyValue<'_>
465where
466    T: Into<String> + Clone,
467    K: Into<AnyValue<'static>> + Clone,
468{
469    fn from(map: HashMap<T, K>) -> Self {
470        AnyValue::Struct(
471            map.into_iter()
472                .map(|(k, v)| {
473                    let cloned_value = v.clone().into();
474                    (
475                        Field::new(k.into().into(), cloned_value.dtype()),
476                        cloned_value,
477                    )
478                })
479                .collect(),
480        )
481    }
482}
483
484#[inline]
485pub(crate) fn apply_zipped_slice(
486    one: &[AnyValue<'_>],
487    two: &[AnyValue<'_>],
488    f: impl Fn(&AnyValue<'_>, &AnyValue<'_>) -> Option<AnyValue<'static>>,
489) -> Option<AnyValue<'static>> {
490    if one.len() != two.len() {
491        return None;
492    }
493
494    Some(AnyValue::Vector(
495        one.iter()
496            .zip(two.iter())
497            .map(|pair| match f(pair.0, pair.1) {
498                Some(v) => v,
499                None => AnyValue::Null,
500            })
501            .collect::<Vec<AnyValue>>(),
502    ))
503}
504
505#[inline]
506pub(crate) fn apply_zipped_struct_slice(
507    one: &[(Field, AnyValue<'_>)],
508    two: &[(Field, AnyValue<'_>)],
509    f: impl Fn(&AnyValue<'_>, &AnyValue<'_>) -> Option<AnyValue<'static>>,
510) -> Option<AnyValue<'static>> {
511    if one.len() != two.len() {
512        return None;
513    }
514
515    if !one
516        .iter()
517        .map(|(f, _)| f.name())
518        .eq(two.iter().map(|(f, _)| f.name()))
519    {
520        return None;
521    }
522
523    let mut out = Vec::with_capacity(one.len());
524    for ((fa, va), (_, vb)) in one.iter().zip(two.iter()) {
525        if va.is_null() || vb.is_null() {
526            out.push((fa.clone(), AnyValue::Null));
527            continue;
528        }
529
530        out.push((fa.clone(), f(va, vb)?));
531    }
532
533    Some(AnyValue::Struct(out))
534}
535
536#[inline]
537pub(crate) fn dedup_slice<'a>(value: &[AnyValue<'a>]) -> AnyValue<'a> {
538    let mut sorted_buff = Vec::with_capacity(value.len());
539    for v in value.iter() {
540        match sorted_buff.binary_search(v) {
541            Ok(_) => {}
542            Err(pos) => sorted_buff.insert(pos, v.clone()),
543        }
544    }
545
546    AnyValue::Vector(sorted_buff)
547}
548
549#[cfg(feature = "serde")]
550impl<'a> Serialize for AnyValue<'a> {
551    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
552    where
553        S: serde::Serializer,
554    {
555        use AnyValue::*;
556        match self {
557            Null => serializer.serialize_unit_variant("AnyValue", 0, "Null"),
558            Bool(v) => serializer.serialize_bool(*v),
559            UInt8(v) => serializer.serialize_u8(*v),
560            UInt16(v) => serializer.serialize_u16(*v),
561            UInt32(v) => serializer.serialize_u32(*v),
562            UInt64(v) => serializer.serialize_u64(*v),
563            UInt128(v) => serializer.serialize_u128(*v),
564            Int8(v) => serializer.serialize_i8(*v),
565            Int16(v) => serializer.serialize_i16(*v),
566            Int32(v) => serializer.serialize_i32(*v),
567            Int64(v) => serializer.serialize_i64(*v),
568            Int128(v) => serializer.serialize_i128(*v),
569            Float32(v) => serializer.serialize_f32(*v),
570            Float64(v) => serializer.serialize_f64(*v),
571            Duration(v) => serializer.serialize_u64(v.as_millis() as u64),
572            Char(v) => serializer.serialize_char(*v),
573            Str(v) => serializer.serialize_str(v),
574            StrOwned(v) => serializer.serialize_str(v),
575            Slice(vals) => vals.serialize(serializer),
576            Vector(vals) => vals.serialize(serializer),
577            Struct(vals) => vals.serialize(serializer),
578        }
579    }
580}
581
582#[cfg(feature = "serde")]
583impl<'a, 'de> Deserialize<'de> for AnyValue<'a> {
584    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
585    where
586        D: serde::Deserializer<'de>,
587    {
588        use AnyValue::*;
589        #[derive(Deserialize)]
590        #[serde(tag = "type", content = "value")]
591        enum AnyValueDef {
592            Null,
593            Bool(bool),
594            UInt8(u8),
595            UInt16(u16),
596            UInt32(u32),
597            UInt64(u64),
598            UInt128(u128),
599            Int8(i8),
600            Int16(i16),
601            Int32(i32),
602            Int64(i64),
603            Int128(i128),
604            Float32(f32),
605            Float64(f64),
606            Duration(u64),
607            Char(char),
608            Str(String),
609            StrOwned(String),
610            Slice(Vec<AnyValueDef>),
611            Vector(Vec<AnyValueDef>),
612            Struct(Vec<(Field, AnyValueDef)>),
613        }
614
615        impl From<AnyValueDef> for AnyValue<'_> {
616            fn from(def: AnyValueDef) -> Self {
617                match def {
618                    AnyValueDef::Null => Null,
619                    AnyValueDef::Bool(v) => Bool(v),
620                    AnyValueDef::UInt8(v) => UInt8(v),
621                    AnyValueDef::UInt16(v) => UInt16(v),
622                    AnyValueDef::UInt32(v) => UInt32(v),
623                    AnyValueDef::UInt64(v) => UInt64(v),
624                    AnyValueDef::UInt128(v) => UInt128(v),
625                    AnyValueDef::Int8(v) => Int8(v),
626                    AnyValueDef::Int16(v) => Int16(v),
627                    AnyValueDef::Int32(v) => Int32(v),
628                    AnyValueDef::Int64(v) => Int64(v),
629                    AnyValueDef::Int128(v) => Int128(v),
630                    AnyValueDef::Float32(v) => Float32(v),
631                    AnyValueDef::Float64(v) => Float64(v),
632                    AnyValueDef::Duration(ms) => Duration(std::time::Duration::from_millis(ms)),
633                    AnyValueDef::Char(v) => Char(v),
634                    AnyValueDef::Str(s) | AnyValueDef::StrOwned(s) => StrOwned(s),
635                    AnyValueDef::Slice(vals) => {
636                        Vector(vals.into_iter().map(AnyValue::from).collect())
637                    }
638                    AnyValueDef::Vector(vals) => {
639                        Vector(vals.into_iter().map(AnyValue::from).collect())
640                    }
641                    AnyValueDef::Struct(vals) => {
642                        Struct(vals.into_iter().map(|(f, v)| (f, v.into())).collect())
643                    }
644                }
645            }
646        }
647
648        let def = AnyValueDef::deserialize(deserializer)?;
649        Ok(match def {
650            AnyValueDef::Null => Null,
651            AnyValueDef::Bool(v) => Bool(v),
652            AnyValueDef::UInt8(v) => UInt8(v),
653            AnyValueDef::UInt16(v) => UInt16(v),
654            AnyValueDef::UInt32(v) => UInt32(v),
655            AnyValueDef::UInt64(v) => UInt64(v),
656            AnyValueDef::UInt128(v) => UInt128(v),
657            AnyValueDef::Int8(v) => Int8(v),
658            AnyValueDef::Int16(v) => Int16(v),
659            AnyValueDef::Int32(v) => Int32(v),
660            AnyValueDef::Int64(v) => Int64(v),
661            AnyValueDef::Int128(v) => Int128(v),
662            AnyValueDef::Float32(v) => Float32(v),
663            AnyValueDef::Float64(v) => Float64(v),
664            AnyValueDef::Char(v) => Char(v),
665            AnyValueDef::Str(v) => StrOwned(v), // Deserialize as owned string
666            AnyValueDef::StrOwned(v) => StrOwned(v), // Deserialize as owned string
667            AnyValueDef::Duration(ms) => Duration(std::time::Duration::from_millis(ms)),
668            AnyValueDef::Slice(vals) => Vector(vals.into_iter().map(|v| v.into()).collect()),
669            AnyValueDef::Vector(vals) => Vector(vals.into_iter().map(|v| v.into()).collect()),
670            AnyValueDef::Struct(vals) => {
671                Struct(vals.into_iter().map(|(f, v)| (f, v.into())).collect())
672            }
673        })
674    }
675}
676
677#[cfg(test)]
678mod tests {
679    use super::{DataType, Field};
680
681    use super::AnyValue;
682
683    #[test]
684    fn test_anyvalue_equality() {
685        let v1 = AnyValue::Struct(vec![
686            (
687                Field::from(("field1", DataType::Int32)),
688                AnyValue::Int32(42),
689            ),
690            (
691                Field::from(("field2", DataType::String)),
692                AnyValue::Str("hello"),
693            ),
694        ]);
695
696        let v2 = AnyValue::Struct(vec![
697            (
698                Field::from(("field1", DataType::Int32)),
699                AnyValue::Int32(42),
700            ),
701            (
702                Field::from(("field2", DataType::String)),
703                AnyValue::Str("hello"),
704            ),
705        ]);
706
707        let v3 = AnyValue::Struct(vec![
708            (
709                Field::from(("field1", DataType::Int32)),
710                AnyValue::Int32(43),
711            ),
712            (
713                Field::from(("field2", DataType::String)),
714                AnyValue::Str("hello"),
715            ),
716        ]);
717
718        assert_eq!(v1, v2);
719        assert_ne!(v1, v3);
720    }
721
722    #[test]
723    fn test_anyvalue_type_name() {
724        let v = AnyValue::Float64(3.14);
725        assert_eq!(v.type_name(), "f64");
726    }
727}