Skip to main content

qubit_value/multi_values/
multi_values_converters.rs

1use std::collections::HashMap;
2use std::time::Duration;
3
4use bigdecimal::BigDecimal;
5use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
6use num_bigint::BigInt;
7use qubit_common::lang::DataType;
8use url::Url;
9
10use crate::Value;
11use crate::value_error::{ValueError, ValueResult};
12
13use super::multi_values::MultiValues;
14use super::multi_values_add_arg::MultiValuesAddArg;
15use super::multi_values_adder::MultiValuesAdder;
16use super::multi_values_constructor::MultiValuesConstructor;
17use super::multi_values_first_getter::MultiValuesFirstGetter;
18use super::multi_values_getter::MultiValuesGetter;
19use super::multi_values_multi_adder::MultiValuesMultiAdder;
20use super::multi_values_multi_adder_slice::MultiValuesMultiAdderSlice;
21use super::multi_values_set_arg::MultiValuesSetArg;
22use super::multi_values_setter::MultiValuesSetter;
23use super::multi_values_setter_slice::MultiValuesSetterSlice;
24use super::multi_values_single_setter::MultiValuesSingleSetter;
25
26// ============================================================================
27// Internal trait implementations (simplified using macros)
28// ============================================================================
29
30macro_rules! impl_multi_value_traits {
31    ($type:ty, $variant:ident, $data_type:expr) => {
32        impl MultiValuesGetter<$type> for MultiValues {
33            #[inline]
34            fn get_values(&self) -> ValueResult<Vec<$type>> {
35                match self {
36                    MultiValues::$variant(v) => Ok(v.clone()),
37                    MultiValues::Empty(dt) if *dt == $data_type => Ok(Vec::new()),
38                    _ => Err(ValueError::TypeMismatch {
39                        expected: $data_type,
40                        actual: self.data_type(),
41                    }),
42                }
43            }
44        }
45
46        impl MultiValuesFirstGetter<$type> for MultiValues {
47            #[inline]
48            fn get_first_value(&self) -> ValueResult<$type> {
49                match self {
50                    MultiValues::$variant(v) if !v.is_empty() => Ok(v[0].clone()),
51                    MultiValues::$variant(_) => Err(ValueError::NoValue),
52                    MultiValues::Empty(dt) if *dt == $data_type => Err(ValueError::NoValue),
53                    _ => Err(ValueError::TypeMismatch {
54                        expected: $data_type,
55                        actual: self.data_type(),
56                    }),
57                }
58            }
59        }
60
61        impl MultiValuesSetter<$type> for MultiValues {
62            #[inline]
63            fn set_values(&mut self, values: Vec<$type>) -> ValueResult<()> {
64                *self = MultiValues::$variant(values);
65                Ok(())
66            }
67        }
68
69        // Generic From implementation for SetParam is at the top level, not
70        // repeated here for specific types.
71
72        impl MultiValuesSetterSlice<$type> for MultiValues {
73            #[inline]
74            fn set_values_slice(&mut self, values: &[$type]) -> ValueResult<()> {
75                // Equivalent to set_[xxx]s_slice: replace entire list with slice
76                *self = MultiValues::$variant(values.to_vec());
77                Ok(())
78            }
79        }
80
81        impl MultiValuesSingleSetter<$type> for MultiValues {
82            #[inline]
83            fn set_single_value(&mut self, value: $type) -> ValueResult<()> {
84                *self = MultiValues::$variant(vec![value]);
85                Ok(())
86            }
87        }
88
89        impl MultiValuesAdder<$type> for MultiValues {
90            #[inline]
91            fn add_value(&mut self, value: $type) -> ValueResult<()> {
92                match self {
93                    MultiValues::$variant(v) => {
94                        v.push(value);
95                        Ok(())
96                    }
97                    MultiValues::Empty(dt) if *dt == $data_type => {
98                        *self = MultiValues::$variant(vec![value]);
99                        Ok(())
100                    }
101                    _ => Err(ValueError::TypeMismatch {
102                        expected: $data_type,
103                        actual: self.data_type(),
104                    }),
105                }
106            }
107        }
108
109        // Three types of implementations for local dispatch trait
110        impl<'a> MultiValuesSetArg<'a> for Vec<$type> {
111            type Item = $type;
112
113            #[inline]
114            fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
115                <MultiValues as MultiValuesSetter<$type>>::set_values(target, self)
116            }
117        }
118
119        impl<'a> MultiValuesSetArg<'a> for &'a [$type]
120        where
121            $type: Clone,
122        {
123            type Item = $type;
124
125            #[inline]
126            fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
127                <MultiValues as MultiValuesSetterSlice<$type>>::set_values_slice(target, self)
128            }
129        }
130
131        impl<'a> MultiValuesSetArg<'a> for $type {
132            type Item = $type;
133
134            #[inline]
135            fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
136                <MultiValues as MultiValuesSingleSetter<$type>>::set_single_value(target, self)
137            }
138        }
139
140        impl MultiValuesMultiAdder<$type> for MultiValues {
141            #[inline]
142            fn add_values(&mut self, values: Vec<$type>) -> ValueResult<()> {
143                match self {
144                    MultiValues::$variant(v) => {
145                        v.extend(values);
146                        Ok(())
147                    }
148                    MultiValues::Empty(dt) if *dt == $data_type => {
149                        *self = MultiValues::$variant(values);
150                        Ok(())
151                    }
152                    _ => Err(ValueError::TypeMismatch {
153                        expected: $data_type,
154                        actual: self.data_type(),
155                    }),
156                }
157            }
158        }
159
160        impl MultiValuesMultiAdderSlice<$type> for MultiValues {
161            #[inline]
162            fn add_values_slice(&mut self, values: &[$type]) -> ValueResult<()> {
163                match self {
164                    MultiValues::$variant(v) => {
165                        v.extend_from_slice(values);
166                        Ok(())
167                    }
168                    MultiValues::Empty(dt) if *dt == $data_type => {
169                        *self = MultiValues::$variant(values.to_vec());
170                        Ok(())
171                    }
172                    _ => Err(ValueError::TypeMismatch {
173                        expected: $data_type,
174                        actual: self.data_type(),
175                    }),
176                }
177            }
178        }
179
180        // add dispatch: T / Vec<T> / &[T]
181        impl<'a> MultiValuesAddArg<'a> for $type {
182            type Item = $type;
183
184            #[inline]
185            fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
186                <MultiValues as MultiValuesAdder<$type>>::add_value(target, self)
187            }
188        }
189
190        impl<'a> MultiValuesAddArg<'a> for Vec<$type> {
191            type Item = $type;
192
193            #[inline]
194            fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
195                <MultiValues as MultiValuesMultiAdder<$type>>::add_values(target, self)
196            }
197        }
198
199        impl<'a> MultiValuesAddArg<'a> for &'a [$type]
200        where
201            $type: Clone,
202        {
203            type Item = $type;
204
205            #[inline]
206            fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
207                <MultiValues as MultiValuesMultiAdderSlice<$type>>::add_values_slice(target, self)
208            }
209        }
210
211        impl MultiValuesConstructor<$type> for MultiValues {
212            #[inline]
213            fn from_vec(values: Vec<$type>) -> Self {
214                MultiValues::$variant(values)
215            }
216        }
217    };
218}
219
220// Implementation for Copy types
221impl_multi_value_traits!(bool, Bool, DataType::Bool);
222impl_multi_value_traits!(char, Char, DataType::Char);
223impl_multi_value_traits!(i8, Int8, DataType::Int8);
224impl_multi_value_traits!(i16, Int16, DataType::Int16);
225impl_multi_value_traits!(i32, Int32, DataType::Int32);
226impl_multi_value_traits!(i64, Int64, DataType::Int64);
227impl_multi_value_traits!(i128, Int128, DataType::Int128);
228impl_multi_value_traits!(u8, UInt8, DataType::UInt8);
229impl_multi_value_traits!(u16, UInt16, DataType::UInt16);
230impl_multi_value_traits!(u32, UInt32, DataType::UInt32);
231impl_multi_value_traits!(u64, UInt64, DataType::UInt64);
232impl_multi_value_traits!(u128, UInt128, DataType::UInt128);
233impl_multi_value_traits!(f32, Float32, DataType::Float32);
234impl_multi_value_traits!(f64, Float64, DataType::Float64);
235impl_multi_value_traits!(String, String, DataType::String);
236impl_multi_value_traits!(NaiveDate, Date, DataType::Date);
237impl_multi_value_traits!(NaiveTime, Time, DataType::Time);
238impl_multi_value_traits!(NaiveDateTime, DateTime, DataType::DateTime);
239impl_multi_value_traits!(DateTime<Utc>, Instant, DataType::Instant);
240impl_multi_value_traits!(BigInt, BigInteger, DataType::BigInteger);
241impl_multi_value_traits!(BigDecimal, BigDecimal, DataType::BigDecimal);
242impl_multi_value_traits!(isize, IntSize, DataType::IntSize);
243impl_multi_value_traits!(usize, UIntSize, DataType::UIntSize);
244impl_multi_value_traits!(Duration, Duration, DataType::Duration);
245impl_multi_value_traits!(Url, Url, DataType::Url);
246impl_multi_value_traits!(HashMap<String, String>, StringMap, DataType::StringMap);
247impl_multi_value_traits!(serde_json::Value, Json, DataType::Json);
248
249// Convenience adaptation: &str supported as input type for String
250impl MultiValuesSetArg<'_> for &str {
251    type Item = String;
252
253    #[inline]
254    fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
255        <MultiValues as MultiValuesSingleSetter<String>>::set_single_value(target, self.to_string())
256    }
257}
258
259impl MultiValuesSetArg<'_> for Vec<&str> {
260    type Item = String;
261
262    #[inline]
263    fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
264        let owned: Vec<String> = self.into_iter().map(|s| s.to_string()).collect();
265        <MultiValues as MultiValuesSetter<String>>::set_values(target, owned)
266    }
267}
268
269impl<'b> MultiValuesSetArg<'_> for &'b [&'b str] {
270    type Item = String;
271
272    #[inline]
273    fn apply(self, target: &mut MultiValues) -> ValueResult<()> {
274        let owned: Vec<String> = self.iter().map(|s| (*s).to_string()).collect();
275        <MultiValues as MultiValuesSetter<String>>::set_values(target, owned)
276    }
277}
278
279impl MultiValuesAddArg<'_> for &str {
280    type Item = String;
281
282    #[inline]
283    fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
284        <MultiValues as MultiValuesAdder<String>>::add_value(target, self.to_string())
285    }
286}
287
288impl MultiValuesAddArg<'_> for Vec<&str> {
289    type Item = String;
290
291    #[inline]
292    fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
293        let owned: Vec<String> = self.into_iter().map(|s| s.to_string()).collect();
294        <MultiValues as MultiValuesMultiAdder<String>>::add_values(target, owned)
295    }
296}
297
298impl<'b> MultiValuesAddArg<'_> for &'b [&'b str] {
299    type Item = String;
300
301    #[inline]
302    fn apply_add(self, target: &mut MultiValues) -> ValueResult<()> {
303        let owned: Vec<String> = self.iter().map(|s| (*s).to_string()).collect();
304        <MultiValues as MultiValuesMultiAdder<String>>::add_values(target, owned)
305    }
306}
307
308// ============================================================================
309// Inherent conversion APIs and `Value` interop
310// ============================================================================
311
312impl MultiValues {
313    /// Convert to a single [`Value`] by taking the first element.
314    ///
315    /// If there is no element, returns `Value::Empty(self.data_type())`.
316    ///
317    /// # Returns
318    ///
319    /// Returns the first element wrapped as [`Value`], or an empty value
320    /// preserving the current data type.
321    pub fn to_value(&self) -> Value {
322        match self {
323            MultiValues::Empty(dt) => Value::Empty(*dt),
324            MultiValues::Bool(v) => v
325                .first()
326                .copied()
327                .map(Value::Bool)
328                .unwrap_or(Value::Empty(DataType::Bool)),
329            MultiValues::Char(v) => v
330                .first()
331                .copied()
332                .map(Value::Char)
333                .unwrap_or(Value::Empty(DataType::Char)),
334            MultiValues::Int8(v) => v
335                .first()
336                .copied()
337                .map(Value::Int8)
338                .unwrap_or(Value::Empty(DataType::Int8)),
339            MultiValues::Int16(v) => v
340                .first()
341                .copied()
342                .map(Value::Int16)
343                .unwrap_or(Value::Empty(DataType::Int16)),
344            MultiValues::Int32(v) => v
345                .first()
346                .copied()
347                .map(Value::Int32)
348                .unwrap_or(Value::Empty(DataType::Int32)),
349            MultiValues::Int64(v) => v
350                .first()
351                .copied()
352                .map(Value::Int64)
353                .unwrap_or(Value::Empty(DataType::Int64)),
354            MultiValues::Int128(v) => v
355                .first()
356                .copied()
357                .map(Value::Int128)
358                .unwrap_or(Value::Empty(DataType::Int128)),
359            MultiValues::UInt8(v) => v
360                .first()
361                .copied()
362                .map(Value::UInt8)
363                .unwrap_or(Value::Empty(DataType::UInt8)),
364            MultiValues::UInt16(v) => v
365                .first()
366                .copied()
367                .map(Value::UInt16)
368                .unwrap_or(Value::Empty(DataType::UInt16)),
369            MultiValues::UInt32(v) => v
370                .first()
371                .copied()
372                .map(Value::UInt32)
373                .unwrap_or(Value::Empty(DataType::UInt32)),
374            MultiValues::UInt64(v) => v
375                .first()
376                .copied()
377                .map(Value::UInt64)
378                .unwrap_or(Value::Empty(DataType::UInt64)),
379            MultiValues::UInt128(v) => v
380                .first()
381                .copied()
382                .map(Value::UInt128)
383                .unwrap_or(Value::Empty(DataType::UInt128)),
384            MultiValues::IntSize(v) => v
385                .first()
386                .copied()
387                .map(Value::IntSize)
388                .unwrap_or(Value::Empty(DataType::IntSize)),
389            MultiValues::UIntSize(v) => v
390                .first()
391                .copied()
392                .map(Value::UIntSize)
393                .unwrap_or(Value::Empty(DataType::UIntSize)),
394            MultiValues::Float32(v) => v
395                .first()
396                .copied()
397                .map(Value::Float32)
398                .unwrap_or(Value::Empty(DataType::Float32)),
399            MultiValues::Float64(v) => v
400                .first()
401                .copied()
402                .map(Value::Float64)
403                .unwrap_or(Value::Empty(DataType::Float64)),
404            MultiValues::BigInteger(v) => v
405                .first()
406                .cloned()
407                .map(Value::BigInteger)
408                .unwrap_or(Value::Empty(DataType::BigInteger)),
409            MultiValues::BigDecimal(v) => v
410                .first()
411                .cloned()
412                .map(Value::BigDecimal)
413                .unwrap_or(Value::Empty(DataType::BigDecimal)),
414            MultiValues::String(v) => v
415                .first()
416                .cloned()
417                .map(Value::String)
418                .unwrap_or(Value::Empty(DataType::String)),
419            MultiValues::Date(v) => v
420                .first()
421                .copied()
422                .map(Value::Date)
423                .unwrap_or(Value::Empty(DataType::Date)),
424            MultiValues::Time(v) => v
425                .first()
426                .copied()
427                .map(Value::Time)
428                .unwrap_or(Value::Empty(DataType::Time)),
429            MultiValues::DateTime(v) => v
430                .first()
431                .copied()
432                .map(Value::DateTime)
433                .unwrap_or(Value::Empty(DataType::DateTime)),
434            MultiValues::Instant(v) => v
435                .first()
436                .copied()
437                .map(Value::Instant)
438                .unwrap_or(Value::Empty(DataType::Instant)),
439            MultiValues::Duration(v) => v
440                .first()
441                .copied()
442                .map(Value::Duration)
443                .unwrap_or(Value::Empty(DataType::Duration)),
444            MultiValues::Url(v) => v
445                .first()
446                .cloned()
447                .map(Value::Url)
448                .unwrap_or(Value::Empty(DataType::Url)),
449            MultiValues::StringMap(v) => v
450                .first()
451                .cloned()
452                .map(Value::StringMap)
453                .unwrap_or(Value::Empty(DataType::StringMap)),
454            MultiValues::Json(v) => v
455                .first()
456                .cloned()
457                .map(Value::Json)
458                .unwrap_or(Value::Empty(DataType::Json)),
459        }
460    }
461
462    /// Merge another multiple values
463    ///
464    /// Append all values from another multiple values to the current multiple values
465    ///
466    /// # Parameters
467    ///
468    /// * `other` - The multiple values to merge
469    ///
470    /// # Returns
471    ///
472    /// If types match, returns `Ok(())`; otherwise returns an error
473    ///
474    /// # Example
475    ///
476    /// ```rust
477    /// use qubit_value::MultiValues;
478    ///
479    /// let mut a = MultiValues::Int32(vec![1, 2]);
480    /// let b = MultiValues::Int32(vec![3, 4]);
481    /// a.merge(&b).unwrap();
482    /// assert_eq!(a.get_int32s().unwrap(), &[1, 2, 3, 4]);
483    /// ```
484    pub fn merge(&mut self, other: &MultiValues) -> ValueResult<()> {
485        if self.data_type() != other.data_type() {
486            return Err(ValueError::TypeMismatch {
487                expected: self.data_type(),
488                actual: other.data_type(),
489            });
490        }
491        if other.count() == 0 {
492            return Ok(());
493        }
494
495        match (self, other) {
496            (MultiValues::Bool(v), MultiValues::Bool(o)) => v.extend_from_slice(o),
497            (MultiValues::Char(v), MultiValues::Char(o)) => v.extend_from_slice(o),
498            (MultiValues::Int8(v), MultiValues::Int8(o)) => v.extend_from_slice(o),
499            (MultiValues::Int16(v), MultiValues::Int16(o)) => v.extend_from_slice(o),
500            (MultiValues::Int32(v), MultiValues::Int32(o)) => v.extend_from_slice(o),
501            (MultiValues::Int64(v), MultiValues::Int64(o)) => v.extend_from_slice(o),
502            (MultiValues::Int128(v), MultiValues::Int128(o)) => v.extend_from_slice(o),
503            (MultiValues::UInt8(v), MultiValues::UInt8(o)) => v.extend_from_slice(o),
504            (MultiValues::UInt16(v), MultiValues::UInt16(o)) => v.extend_from_slice(o),
505            (MultiValues::UInt32(v), MultiValues::UInt32(o)) => v.extend_from_slice(o),
506            (MultiValues::UInt64(v), MultiValues::UInt64(o)) => v.extend_from_slice(o),
507            (MultiValues::UInt128(v), MultiValues::UInt128(o)) => v.extend_from_slice(o),
508            (MultiValues::Float32(v), MultiValues::Float32(o)) => v.extend_from_slice(o),
509            (MultiValues::Float64(v), MultiValues::Float64(o)) => v.extend_from_slice(o),
510            (MultiValues::String(v), MultiValues::String(o)) => v.extend_from_slice(o),
511            (MultiValues::Date(v), MultiValues::Date(o)) => v.extend_from_slice(o),
512            (MultiValues::Time(v), MultiValues::Time(o)) => v.extend_from_slice(o),
513            (MultiValues::DateTime(v), MultiValues::DateTime(o)) => v.extend_from_slice(o),
514            (MultiValues::Instant(v), MultiValues::Instant(o)) => v.extend_from_slice(o),
515            (MultiValues::BigInteger(v), MultiValues::BigInteger(o)) => v.extend_from_slice(o),
516            (MultiValues::BigDecimal(v), MultiValues::BigDecimal(o)) => v.extend_from_slice(o),
517            (MultiValues::IntSize(v), MultiValues::IntSize(o)) => v.extend_from_slice(o),
518            (MultiValues::UIntSize(v), MultiValues::UIntSize(o)) => v.extend_from_slice(o),
519            (MultiValues::Duration(v), MultiValues::Duration(o)) => v.extend_from_slice(o),
520            (MultiValues::Url(v), MultiValues::Url(o)) => v.extend_from_slice(o),
521            (MultiValues::StringMap(v), MultiValues::StringMap(o)) => v.extend(o.iter().cloned()),
522            (MultiValues::Json(v), MultiValues::Json(o)) => v.extend(o.iter().cloned()),
523            (slot @ MultiValues::Empty(_), other_values) => *slot = other_values.clone(),
524            _ => unreachable!(),
525        }
526
527        Ok(())
528    }
529}
530
531impl Default for MultiValues {
532    #[inline]
533    fn default() -> Self {
534        MultiValues::Empty(DataType::String)
535    }
536}
537
538impl From<Value> for MultiValues {
539    fn from(value: Value) -> Self {
540        match value {
541            Value::Empty(dt) => MultiValues::Empty(dt),
542            Value::Bool(v) => MultiValues::Bool(vec![v]),
543            Value::Char(v) => MultiValues::Char(vec![v]),
544            Value::Int8(v) => MultiValues::Int8(vec![v]),
545            Value::Int16(v) => MultiValues::Int16(vec![v]),
546            Value::Int32(v) => MultiValues::Int32(vec![v]),
547            Value::Int64(v) => MultiValues::Int64(vec![v]),
548            Value::Int128(v) => MultiValues::Int128(vec![v]),
549            Value::UInt8(v) => MultiValues::UInt8(vec![v]),
550            Value::UInt16(v) => MultiValues::UInt16(vec![v]),
551            Value::UInt32(v) => MultiValues::UInt32(vec![v]),
552            Value::UInt64(v) => MultiValues::UInt64(vec![v]),
553            Value::UInt128(v) => MultiValues::UInt128(vec![v]),
554            Value::Float32(v) => MultiValues::Float32(vec![v]),
555            Value::Float64(v) => MultiValues::Float64(vec![v]),
556            Value::String(v) => MultiValues::String(vec![v]),
557            Value::Date(v) => MultiValues::Date(vec![v]),
558            Value::Time(v) => MultiValues::Time(vec![v]),
559            Value::DateTime(v) => MultiValues::DateTime(vec![v]),
560            Value::Instant(v) => MultiValues::Instant(vec![v]),
561            Value::BigInteger(v) => MultiValues::BigInteger(vec![v]),
562            Value::BigDecimal(v) => MultiValues::BigDecimal(vec![v]),
563            Value::IntSize(v) => MultiValues::IntSize(vec![v]),
564            Value::UIntSize(v) => MultiValues::UIntSize(vec![v]),
565            Value::Duration(v) => MultiValues::Duration(vec![v]),
566            Value::Url(v) => MultiValues::Url(vec![v]),
567            Value::StringMap(v) => MultiValues::StringMap(vec![v]),
568            Value::Json(v) => MultiValues::Json(vec![v]),
569        }
570    }
571}