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 #[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 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), AnyValueDef::StrOwned(v) => StrOwned(v), 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}