Skip to main content

qubit_value/multi_values/
multi_values_core.rs

1// =============================================================================
2//    Copyright (c) 2025 - 2026 Haixing Hu.
3//
4//    SPDX-License-Identifier: Apache-2.0
5//
6//    Licensed under the Apache License, Version 2.0.
7// =============================================================================
8
9//! Core generic accessors and state methods for `MultiValues`.
10
11use qubit_datatype::DataType;
12
13use crate::value_error::{
14    ValueError,
15    ValueResult,
16};
17use crate::{
18    IntoValueDefault,
19    Value,
20};
21
22use super::multi_values::{
23    MultiValues,
24    MultiValuesRepr,
25};
26use crate::value::ValueRepr;
27
28macro_rules! multi_values_data_type_match {
29    ($value:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?) => {
30        match &$value.repr {
31            MultiValuesRepr::Unset(dt) => *dt,
32            $($(#[$cfg])* MultiValuesRepr::$variant(_) => $data_type,)+
33        }
34    };
35}
36
37macro_rules! multi_values_count_match {
38    ($value:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?) => {
39        match &$value.repr {
40            MultiValuesRepr::Unset(_) => 0,
41            $($(#[$cfg])* MultiValuesRepr::$variant(values) => values.len(),)+
42        }
43    };
44}
45
46macro_rules! multi_values_clear_match {
47    ($value:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?) => {
48        match &mut $value.repr {
49            MultiValuesRepr::Unset(_) => {}
50            $($(#[$cfg])* MultiValuesRepr::$variant(values) => values.clear(),)+
51        }
52    };
53}
54
55macro_rules! multi_values_append_match {
56    ($left:expr, $right:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?) => {
57        match (&mut $left.repr, &mut $right.repr) {
58            $(
59                $(#[$cfg])*
60                (MultiValuesRepr::$variant(values), MultiValuesRepr::$variant(other_values)) => {
61                    values.append(other_values);
62                }
63            )+
64            (slot @ MultiValuesRepr::Unset(_), other_values) => {
65                *slot = std::mem::replace(other_values, MultiValuesRepr::Unset(DataType::String));
66            }
67            _ => unreachable!(),
68        }
69    };
70}
71
72macro_rules! multi_values_first_value_match {
73    ($value:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?) => {
74        match &$value.repr {
75            MultiValuesRepr::Unset(data_type) => Value::new_unset(*data_type),
76            $(
77                $(#[$cfg])*
78                MultiValuesRepr::$variant(values) => values
79                    .first()
80                    .map(|value| materialize_stored!($materialization, value))
81                    .map(Value::$variant)
82                    .unwrap_or(Value::new_unset($data_type)),
83            )+
84        }
85    };
86}
87
88macro_rules! multi_values_into_first_value_match {
89    ($value:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?) => {
90        match $value.repr {
91            MultiValuesRepr::Unset(data_type) => Value::new_unset(data_type),
92            $(
93                $(#[$cfg])*
94                MultiValuesRepr::$variant(values) => values
95                    .into_iter()
96                    .next()
97                    .map(Value::$variant)
98                    .unwrap_or(Value::new_unset($data_type)),
99            )+
100        }
101    };
102}
103
104macro_rules! multi_values_merge_match {
105    ($left:expr, $right:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?) => {
106        match (&mut $left.repr, &$right.repr) {
107            $(
108                $(#[$cfg])*
109                (MultiValuesRepr::$variant(values), MultiValuesRepr::$variant(other_values)) => {
110                    values.extend_from_slice(other_values)
111                }
112            )+
113            (slot @ MultiValuesRepr::Unset(_), other_values) => *slot = other_values.clone(),
114            _ => unreachable!(),
115        }
116    };
117}
118
119macro_rules! value_into_multi_values_match {
120    ($value:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal)),+ $(,)?) => {
121        match $value.repr {
122            ValueRepr::Unset(data_type) => MultiValues::new_unset(data_type),
123            $($(#[$cfg])* ValueRepr::$variant(value) => {
124                MultiValues::$variant(vec![value_storage_into_multi!($variant, value)])
125            },)+
126        }
127    };
128}
129
130impl MultiValues {
131    /// Generic constructor method
132    ///
133    /// Creates `MultiValues` from any supported input form, avoiding direct
134    /// use of enum variants at call sites.
135    ///
136    /// Supported input forms include single values, vectors, slices, arrays,
137    /// borrowed vectors, and borrowed string collections for supported element
138    /// types.
139    ///
140    /// # Type Parameters
141    ///
142    /// * `S` - Input type convertible into [`MultiValues`].
143    ///
144    /// # Parameters
145    ///
146    /// * `values` - Values to convert into a collection.
147    ///
148    /// # Returns
149    ///
150    /// Returns `MultiValues` wrapping the converted input values.
151    ///
152    /// # Examples
153    ///
154    /// ```rust
155    /// use qubit_value::MultiValues;
156    ///
157    /// // Basic types
158    /// let mv = MultiValues::new(vec![1, 2, 3]);
159    /// assert_eq!(mv.len(), 3);
160    ///
161    /// // Strings
162    /// let mv = MultiValues::new(vec!["a".to_string(), "b".to_string()]);
163    /// assert_eq!(mv.len(), 2);
164    /// ```
165    #[inline(always)]
166    pub fn new<S>(values: S) -> Self
167    where
168        S: Into<Self>,
169    {
170        values.into()
171    }
172
173    /// Generic getter method for multiple values.
174    ///
175    /// Performs a strict typed read of all stored values as `Vec<T>`.
176    ///
177    /// # Type Parameters
178    ///
179    /// * `T` - The target element type to retrieve.
180    ///
181    /// # Returns
182    ///
183    /// Returns the list of values when the stored type matches `T`.
184    ///
185    /// # Errors
186    ///
187    /// Returns [`ValueError::Missing`] when the container is unset with the
188    /// requested type, or [`ValueError::TypeMismatch`] when the stored type
189    /// differs from `T`.
190    ///
191    /// # Examples
192    ///
193    /// ```rust
194    /// use qubit_value::MultiValues;
195    ///
196    /// let multi = MultiValues::Int32(vec![1, 2, 3]);
197    ///
198    /// // Through type inference
199    /// let nums: Vec<i32> = multi.get().unwrap();
200    /// assert_eq!(nums, vec![1, 2, 3]);
201    ///
202    /// // Explicitly specify type parameter
203    /// let nums = multi.get::<i32>().unwrap();
204    /// assert_eq!(nums, vec![1, 2, 3]);
205    /// ```
206    #[inline(always)]
207    pub fn get<T>(&self) -> ValueResult<Vec<T>>
208    where
209        for<'a> Vec<T>: TryFrom<&'a Self, Error = ValueError>,
210    {
211        Vec::<T>::try_from(self)
212    }
213
214    /// Generic getter method with a default value list.
215    ///
216    /// Returns the supplied default only when this container is unset. A
217    /// concrete empty vector remains an empty result.
218    ///
219    /// # Type Parameters
220    ///
221    /// * `T` - Target element type for the strict read.
222    ///
223    /// # Parameters
224    ///
225    /// * `default` - Lazily materialized list used only for unset storage.
226    ///
227    /// # Returns
228    ///
229    /// The concrete stored list, or `default` for unset storage.
230    ///
231    /// # Errors
232    ///
233    /// Returns [`ValueError::TypeMismatch`] when the stored type differs from
234    /// `T`.
235    #[inline]
236    pub fn get_or<T>(
237        &self,
238        default: impl IntoValueDefault<Vec<T>>,
239    ) -> ValueResult<Vec<T>>
240    where
241        for<'a> Vec<T>: TryFrom<&'a Self, Error = ValueError>,
242    {
243        match self.get() {
244            Err(ValueError::Missing(missing)) if missing.is_unset() => {
245                Ok(default.into_value_default())
246            }
247            result => result,
248        }
249    }
250
251    /// Strictly reads all values or calls `default` only when storage is unset.
252    ///
253    /// A concrete empty collection is returned unchanged and type mismatches
254    /// are preserved without invoking the callback.
255    ///
256    /// # Type Parameters
257    ///
258    /// * `T` - Target element type.
259    /// * `F` - Deferred fallback producing the complete list.
260    ///
261    /// # Parameters
262    ///
263    /// * `default` - Callback invoked only for unset storage.
264    ///
265    /// # Returns
266    ///
267    /// The stored list or the callback result.
268    ///
269    /// # Errors
270    ///
271    /// Returns [`ValueError::TypeMismatch`] for an incompatible concrete
272    /// collection without invoking the callback.
273    #[inline]
274    pub fn get_or_else<T, F>(&self, default: F) -> ValueResult<Vec<T>>
275    where
276        for<'a> Vec<T>: TryFrom<&'a Self, Error = ValueError>,
277        F: FnOnce() -> Vec<T>,
278    {
279        match self.get() {
280            Err(ValueError::Missing(missing)) if missing.is_unset() => {
281                Ok(default())
282            }
283            result => result,
284        }
285    }
286
287    /// Generic getter method for the first value
288    ///
289    /// Reads the first stored value as `T`, performing strict type checking.
290    ///
291    /// `get_first<T>()` does not do cross-type conversion. When the `converter`
292    /// feature is enabled, use `to<T>()` for compatible cross-type conversion.
293    ///
294    /// # Type Parameters
295    ///
296    /// * `T` - The target element type to retrieve.
297    ///
298    /// # Returns
299    ///
300    /// Returns the first value when the stored type matches `T` and at least
301    /// one value exists.
302    ///
303    /// # Errors
304    ///
305    /// Returns [`ValueError::Missing`] when the requested type matches but no
306    /// value is stored, or [`ValueError::TypeMismatch`] when the stored type
307    /// differs from `T`.
308    ///
309    /// # Examples
310    ///
311    /// ```rust
312    /// use qubit_value::MultiValues;
313    ///
314    /// let multi = MultiValues::Int32(vec![42, 100, 200]);
315    ///
316    /// // Through type inference
317    /// let first: i32 = multi.get_first().unwrap();
318    /// assert_eq!(first, 42);
319    ///
320    /// // Explicitly specify type parameter
321    /// let first = multi.get_first::<i32>().unwrap();
322    /// assert_eq!(first, 42);
323    ///
324    /// // String type
325    /// let multi = MultiValues::String(vec!["hello".to_string(), "world".to_string()]);
326    /// let first: String = multi.get_first().unwrap();
327    /// assert_eq!(first, "hello");
328    /// ```
329    #[inline(always)]
330    pub fn get_first<T>(&self) -> ValueResult<T>
331    where
332        for<'a> T: TryFrom<&'a Self, Error = ValueError>,
333    {
334        T::try_from(self)
335    }
336
337    /// Generic first-value getter with a default value.
338    ///
339    /// Returns the supplied default only when the container is unset. A
340    /// concrete empty vector returns [`ValueError::Missing`]; type mismatches
341    /// are also preserved.
342    ///
343    /// # Type Parameters
344    ///
345    /// * `T` - Target type for the strict first-item read.
346    ///
347    /// # Parameters
348    ///
349    /// * `default` - Lazily materialized value used only for unset storage.
350    ///
351    /// # Returns
352    ///
353    /// The first concrete item, or `default` for unset storage.
354    ///
355    /// # Errors
356    ///
357    /// Returns [`ValueError::Missing`] for a concrete empty collection or
358    /// [`ValueError::TypeMismatch`] when the stored type differs from `T`.
359    #[inline]
360    pub fn get_first_or<T>(
361        &self,
362        default: impl IntoValueDefault<T>,
363    ) -> ValueResult<T>
364    where
365        for<'a> T: TryFrom<&'a Self, Error = ValueError>,
366    {
367        match self.get_first() {
368            Err(ValueError::Missing(missing)) if missing.is_unset() => {
369                Ok(default.into_value_default())
370            }
371            result => result,
372        }
373    }
374
375    /// Strictly reads the first value or calls `default` only when unset.
376    ///
377    /// # Type Parameters
378    ///
379    /// * `T` - Target element type.
380    /// * `F` - Deferred fallback producing one element.
381    ///
382    /// # Parameters
383    ///
384    /// * `default` - Callback invoked only for unset storage.
385    ///
386    /// # Returns
387    ///
388    /// The first stored item or the callback result.
389    ///
390    /// # Errors
391    ///
392    /// Preserves empty-collection and type-mismatch errors without invoking
393    /// the callback.
394    #[inline]
395    pub fn get_first_or_else<T, F>(&self, default: F) -> ValueResult<T>
396    where
397        for<'a> T: TryFrom<&'a Self, Error = ValueError>,
398        F: FnOnce() -> T,
399    {
400        match self.get_first() {
401            Err(ValueError::Missing(missing)) if missing.is_unset() => {
402                Ok(default())
403            }
404            result => result,
405        }
406    }
407
408    /// Generic setter method
409    ///
410    /// Replaces the entire list with the converted input values.
411    ///
412    /// This operation updates the stored type to the input element type and
413    /// does not validate runtime compatibility with the previous variant.
414    ///
415    /// Supports any input that can be converted into [`MultiValues`], including
416    /// single values, vectors, slices, arrays, and borrowed vectors for
417    /// supported element types.
418    ///
419    /// Existing values are replaced, and the stored type becomes the converted
420    /// input type.
421    ///
422    /// # Type Parameters
423    ///
424    /// * `S` - Input type convertible into [`MultiValues`].
425    ///
426    /// # Parameters
427    ///
428    /// * `values` - The values to set.
429    ///
430    /// # Compile-time restriction
431    ///
432    /// Unsupported input types fail to compile because they do not implement
433    /// `Into<MultiValues>`.
434    ///
435    /// # Examples
436    ///
437    /// ```rust
438    /// use qubit_datatype::DataType;
439    /// use qubit_value::MultiValues;
440    ///
441    /// // 1) Vec<T>
442    /// let mut mv = MultiValues::Unset(DataType::Int32);
443    /// mv.set(vec![42, 100, 200]);
444    /// assert_eq!(mv.get_int32s().unwrap(), &[42, 100, 200]);
445    ///
446    /// // 2) &[T]
447    /// let mut mv = MultiValues::Unset(DataType::Int32);
448    /// let slice = &[7, 8, 9][..];
449    /// mv.set(slice);
450    /// assert_eq!(mv.get_int32s().unwrap(), &[7, 8, 9]);
451    ///
452    /// // 3) Single T
453    /// let mut mv = MultiValues::Unset(DataType::Int32);
454    /// mv.set(42);
455    /// assert_eq!(mv.get_int32s().unwrap(), &[42]);
456    ///
457    /// // String example
458    /// let mut mv = MultiValues::Unset(DataType::String);
459    /// mv.set(vec!["hello".to_string(), "world".to_string()]);
460    /// assert_eq!(mv.get_strings().unwrap(), &["hello", "world"]);
461    /// ```
462    #[inline(always)]
463    pub fn set<S>(&mut self, values: S)
464    where
465        S: Into<Self>,
466    {
467        *self = values.into();
468    }
469
470    /// Generic add method
471    ///
472    /// Appends converted input values to the existing list with strict type
473    /// checking.
474    ///
475    /// Supports any input that can be converted into [`MultiValues`], including
476    /// single values, vectors, slices, arrays, and borrowed vectors for
477    /// supported element types.
478    ///
479    /// The converted input must have the same data type as the current
480    /// container. An empty container keeps its declared type until
481    /// non-empty values of the same type are appended.
482    ///
483    /// # Type Parameters
484    ///
485    /// * `S` - Input type convertible into [`MultiValues`].
486    ///
487    /// # Parameters
488    ///
489    /// * `values` - Values to append.
490    ///
491    /// # Returns
492    ///
493    /// `Ok(())` after appending, including when the input is empty.
494    ///
495    /// # Errors
496    ///
497    /// Returns [`ValueError::TypeMismatch`] when the converted input data type
498    /// differs from the current container data type.
499    ///
500    /// # Examples
501    ///
502    /// ```rust
503    /// use qubit_datatype::DataType;
504    /// use qubit_value::MultiValues;
505    ///
506    /// // 1) Single T
507    /// let mut mv = MultiValues::Int32(vec![42]);
508    /// mv.add(100).unwrap();
509    /// assert_eq!(mv.get_int32s().unwrap(), &[42, 100]);
510    ///
511    /// // 2) Vec<T>
512    /// mv.add(vec![200, 300]).unwrap();
513    /// assert_eq!(mv.get_int32s().unwrap(), &[42, 100, 200, 300]);
514    ///
515    /// // 3) &[T]
516    /// let slice = &[400, 500][..];
517    /// mv.add(slice).unwrap();
518    /// assert_eq!(mv.get_int32s().unwrap(), &[42, 100, 200, 300, 400, 500]);
519    /// ```
520    pub fn add<S>(&mut self, values: S) -> ValueResult<()>
521    where
522        S: Into<Self>,
523    {
524        let mut other = values.into();
525        if self.data_type() != other.data_type() {
526            return Err(ValueError::TypeMismatch {
527                expected: self.data_type(),
528                actual: other.data_type(),
529            });
530        }
531        if other.is_empty() {
532            return Ok(());
533        }
534
535        for_each_value_type!(multi_values_append_match, self, other);
536
537        Ok(())
538    }
539
540    /// Get the data type of the values
541    ///
542    /// # Returns
543    ///
544    /// Returns the data type corresponding to these multiple values
545    ///
546    /// # Examples
547    ///
548    /// ```rust
549    /// use qubit_datatype::DataType;
550    /// use qubit_value::MultiValues;
551    ///
552    /// let values = MultiValues::Int32(vec![1, 2, 3]);
553    /// assert_eq!(values.data_type(), DataType::Int32);
554    /// ```
555    #[inline(always)]
556    pub fn data_type(&self) -> DataType {
557        for_each_value_type!(multi_values_data_type_match, self)
558    }
559
560    /// Returns the number of values.
561    ///
562    /// # Returns
563    ///
564    /// The number of values contained in these multiple values. An unset
565    /// collection has length zero.
566    ///
567    /// # Examples
568    ///
569    /// ```rust
570    /// use qubit_datatype::DataType;
571    /// use qubit_value::MultiValues;
572    ///
573    /// let values = MultiValues::Int32(vec![1, 2, 3]);
574    /// assert_eq!(values.len(), 3);
575    ///
576    /// let empty = MultiValues::Unset(DataType::String);
577    /// assert_eq!(empty.len(), 0);
578    /// ```
579    #[inline(always)]
580    #[must_use]
581    pub fn len(&self) -> usize {
582        for_each_value_type!(multi_values_count_match, self)
583    }
584
585    /// Tests whether this collection contains no values.
586    ///
587    /// An unset collection and a concrete empty vector both have length zero.
588    /// Use [`MultiValues::is_unset`] when the distinction between no collection
589    /// and a concrete empty collection matters.
590    ///
591    /// # Returns
592    ///
593    /// `true` when [`Self::len`] is zero; otherwise, `false`.
594    #[inline(always)]
595    #[must_use]
596    pub fn is_empty(&self) -> bool {
597        self.len() == 0
598    }
599
600    /// Tests whether this container has no concrete vector.
601    ///
602    /// # Returns
603    ///
604    /// Returns `true` only for [`MultiValues::Unset`]. A concrete empty vector
605    /// returns `false`.
606    ///
607    /// # Examples
608    ///
609    /// ```rust
610    /// use qubit_datatype::DataType;
611    /// use qubit_value::MultiValues;
612    ///
613    /// let values = MultiValues::Int32(vec![]);
614    /// assert!(!values.is_unset());
615    ///
616    /// let empty = MultiValues::Unset(DataType::String);
617    /// assert!(empty.is_unset());
618    /// ```
619    #[inline(always)]
620    #[must_use]
621    pub fn is_unset(&self) -> bool {
622        matches!(self.repr, MultiValuesRepr::Unset(_))
623    }
624
625    /// Tests whether a concrete collection belongs to the numeric type family.
626    ///
627    /// A concrete empty numeric vector returns `true`; an unset collection
628    /// returns `false`, even when its declared type is numeric.
629    ///
630    /// # Returns
631    ///
632    /// `true` for concrete collections with a numeric element type.
633    #[inline(always)]
634    #[must_use]
635    pub fn is_numeric(&self) -> bool {
636        !self.is_unset() && self.data_type().is_numeric()
637    }
638
639    /// Removes the concrete vector while preserving its declared data type.
640    #[inline(always)]
641    pub fn unset(&mut self) {
642        *self = MultiValues::new_unset(self.data_type());
643    }
644
645    /// Clears all values while preserving a concrete collection and its type.
646    /// An unset collection remains unset because it has no concrete vector to
647    /// clear.
648    ///
649    /// # Examples
650    ///
651    /// ```rust
652    /// use qubit_datatype::DataType;
653    /// use qubit_value::MultiValues;
654    ///
655    /// let mut values = MultiValues::Int32(vec![1, 2, 3]);
656    /// values.clear();
657    /// assert_eq!(values.len(), 0);
658    /// assert_eq!(values.data_type(), DataType::Int32);
659    /// ```
660    #[inline(always)]
661    pub fn clear(&mut self) {
662        for_each_value_type!(multi_values_clear_match, self)
663    }
664
665    /// Set the data type
666    ///
667    /// If the new type differs from the current type, clears all values and
668    /// sets the new type.
669    ///
670    /// # Parameters
671    ///
672    /// * `data_type` - The data type to set
673    ///
674    /// # Examples
675    ///
676    /// ```rust
677    /// use qubit_datatype::DataType;
678    /// use qubit_value::MultiValues;
679    ///
680    /// let mut values = MultiValues::Int32(vec![1, 2, 3]);
681    /// values.set_type(DataType::String);
682    /// assert!(values.is_unset());
683    /// assert_eq!(values.data_type(), DataType::String);
684    /// ```
685    #[inline]
686    pub fn set_type(&mut self, data_type: DataType) {
687        if self.data_type() != data_type {
688            *self = MultiValues::new_unset(data_type);
689        }
690    }
691
692    /// Converts the first element to a single [`Value`].
693    ///
694    /// Returns `Value::Unset` with the same declared type when no element is
695    /// stored.
696    ///
697    /// # Returns
698    ///
699    /// A cloned first item, or a typed unset value when no item exists.
700    pub fn first_value(&self) -> Value {
701        for_each_value_type!(multi_values_first_value_match, self)
702    }
703
704    /// Consumes this collection and returns its first item as a [`Value`].
705    ///
706    /// Empty and unset collections become [`Value::Unset`] with the same data
707    /// type. Owned element storage is moved instead of cloned.
708    ///
709    /// # Returns
710    ///
711    /// The owned first item, or a typed unset value when no item exists.
712    pub fn into_first_value(self) -> Value {
713        for_each_value_type!(multi_values_into_first_value_match, self)
714    }
715
716    /// Appends all values from another container with the same data type.
717    ///
718    /// # Parameters
719    ///
720    /// * `other` - Collection whose values are cloned and appended.
721    ///
722    /// # Returns
723    ///
724    /// `Ok(())` after appending, including when `other` is empty.
725    ///
726    /// # Errors
727    ///
728    /// Returns [`ValueError::TypeMismatch`] when `other` has a different data
729    /// type.
730    pub fn merge(&mut self, other: &MultiValues) -> ValueResult<()> {
731        if self.data_type() != other.data_type() {
732            return Err(ValueError::TypeMismatch {
733                expected: self.data_type(),
734                actual: other.data_type(),
735            });
736        }
737        if other.is_empty() {
738            return Ok(());
739        }
740        for_each_value_type!(multi_values_merge_match, self, other);
741        Ok(())
742    }
743}
744
745impl From<Value> for MultiValues {
746    fn from(value: Value) -> Self {
747        for_each_value_type!(value_into_multi_values_match, value)
748    }
749}