Skip to main content

radiate_utils/datatype/
value.rs

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