Skip to main content

qubit_value/multi_values/
multi_values.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//! # Multiple Values Container
9//!
10//! Provides type-safe storage and access functionality for multiple values.
11// qubit-style: allow source-test-pair
12// Tests are intentionally distributed across behavior-specific files under
13// tests/multi_values/ rather than collected in multi_values_tests.rs.
14// qubit-style: allow multiple-public-types
15use std::collections::HashMap;
16use std::fmt;
17#[cfg(feature = "json")]
18use std::hash::Hash;
19#[cfg(feature = "json")]
20use std::hash::Hasher;
21use std::time::Duration;
22
23#[cfg(feature = "big-decimal")]
24use bigdecimal::BigDecimal;
25#[cfg(feature = "chrono")]
26use chrono::DateTime;
27#[cfg(feature = "chrono")]
28use chrono::NaiveDate;
29#[cfg(feature = "chrono")]
30use chrono::NaiveDateTime;
31#[cfg(feature = "chrono")]
32use chrono::NaiveTime;
33#[cfg(feature = "chrono")]
34use chrono::Utc;
35#[cfg(feature = "big-integer")]
36use num_bigint::BigInt;
37#[cfg(feature = "json")]
38use qubit_budget::MeasuredBudgetError;
39#[cfg(feature = "json")]
40use qubit_budget::ResourceQuantity;
41#[cfg(feature = "json")]
42use qubit_budget::json::JsonValueBudget;
43#[cfg(feature = "converter")]
44use qubit_datatype::ConversionLimits;
45#[cfg(feature = "converter")]
46use qubit_datatype::ConversionPolicy;
47#[cfg(feature = "converter")]
48use qubit_datatype::ConversionSession;
49#[cfg(feature = "converter")]
50use qubit_datatype::DataConversionError;
51#[cfg(feature = "converter")]
52use qubit_datatype::DataConversionTarget;
53#[cfg(feature = "converter")]
54use qubit_datatype::DataConverter;
55#[cfg(feature = "converter")]
56use qubit_datatype::DataConverters;
57use qubit_datatype::DataType;
58#[cfg(feature = "url")]
59use url::Url;
60
61use super::internal::MultiValuesRepr;
62#[cfg(feature = "json")]
63use super::multi_values_identity::hash_multi_values_payload_with_json_budget;
64use super::multi_values_ref::MultiValuesRef;
65use crate::IntoValueDefault;
66use crate::Value;
67use crate::ValueError;
68use crate::ValueResult;
69#[cfg(feature = "json")]
70use crate::identity::hash_json;
71#[cfg(feature = "json")]
72use crate::identity::preflight_json;
73use crate::value::ValueRepr;
74
75/// Multiple typed runtime values with private storage representation.
76///
77/// # Examples
78///
79/// ```
80/// use qubit_value::MultiValues;
81///
82/// let values = MultiValues::from(vec![1_i32, 2, 3]);
83/// assert_eq!(values.get_int32s().unwrap(), &[1, 2, 3]);
84/// ```
85#[must_use]
86#[derive(Clone)]
87pub struct MultiValues {
88    /// Private homogeneous storage backing the stable public accessor API.
89    pub(crate) repr: MultiValuesRepr,
90}
91
92impl fmt::Debug for MultiValues {
93    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
94        self.view().fmt(formatter)
95    }
96}
97
98/// Implements named collection constructors from the shared value table.
99macro_rules! impl_multi_values_constructors {
100    (
101        ;
102        $(
103            (
104                [$($cfg:meta),*],
105                $variant:ident,
106                $type:ty,
107                $data_type:expr,
108                $materialization:ident,
109                $json_class:ident,
110                $number_projection:ident,
111                $value_doc:literal,
112                $multi_doc:literal
113                $(, $_wire:tt)*
114            )
115        ),+ $(,)?
116    ) => {
117        impl MultiValues {
118            /// Creates an unset collection with an explicit element type.
119            ///
120            /// # Parameters
121            ///
122            /// * `data_type` - Element type retained while the collection is unset.
123            ///
124            /// # Returns
125            ///
126            /// An unset collection retaining `data_type`.
127            #[allow(non_snake_case)]
128            #[inline(always)]
129            pub const fn Unset(data_type: DataType) -> Self {
130                Self::new_unset(data_type)
131            }
132
133            /// Creates an unset collection with an explicit element type.
134            ///
135            /// # Parameters
136            ///
137            /// * `data_type` - Element type retained while the collection is unset.
138            ///
139            /// # Returns
140            ///
141            /// An unset collection retaining `data_type`.
142            #[inline(always)]
143            pub const fn new_unset(data_type: DataType) -> Self {
144                Self { repr: MultiValuesRepr::Unset(data_type) }
145            }
146
147            $(
148                #[doc = concat!("Creates a collection of ", $multi_doc, ".")]
149                ///
150                /// # Parameters
151                ///
152                /// * `values` - Homogeneous elements stored by the collection.
153                ///
154                /// # Returns
155                ///
156                /// A typed collection containing `values` in their original order.
157                $(#[$cfg])*
158                #[allow(non_snake_case)]
159                #[inline(always)]
160                pub fn $variant(values: Vec<$type>) -> Self {
161                    Self { repr: MultiValuesRepr::$variant(values) }
162                }
163            )+
164        }
165    };
166}
167
168/// Borrows owned storage through the shared type table.
169macro_rules! owned_view_match {
170    ($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 $(, $_wire:tt)*)),+ $(,)?) => {
171        match &$value.repr {
172            MultiValuesRepr::Unset(data_type) => MultiValuesRef::Unset(*data_type),
173            $($(#[$cfg])* MultiValuesRepr::$variant(value) => MultiValuesRef::$variant(
174                value.as_slice()
175            ),)+
176        }
177    };
178}
179
180for_each_value_type!(impl_multi_values_constructors);
181
182impl MultiValues {
183    /// Strictly borrows the first stored item without allocating.
184    #[must_use = "the borrowed first-value result should be handled"]
185    #[inline(always)]
186    pub fn get_first_ref<'a, T: ?Sized>(&'a self) -> ValueResult<&'a T>
187    where
188        &'a T: TryFrom<&'a Self, Error = ValueError>,
189    {
190        <&'a T>::try_from(self)
191    }
192
193    /// Strictly borrows the complete collection without allocating.
194    #[must_use = "the borrowed collection result should be handled"]
195    #[inline(always)]
196    pub fn get_slice<'a, T>(&'a self) -> ValueResult<&'a [T]>
197    where
198        &'a [T]: TryFrom<&'a Self, Error = ValueError>,
199    {
200        <&'a [T]>::try_from(self)
201    }
202
203    /// Hashes this collection while applying `budget` to JSON elements.
204    ///
205    /// # Type Parameters
206    ///
207    /// * `H` - Hasher receiving the semantic collection identity.
208    /// * `R` - Resource identifier used by the JSON budget.
209    /// * `Q` - Quantity type used by the JSON budget.
210    ///
211    /// # Parameters
212    ///
213    /// * `state` - Hasher that receives the same identity representation as
214    ///   [`Hash::hash`].
215    /// * `budget` - Mutable JSON traversal budget, used only for JSON elements.
216    ///
217    /// # Returns
218    ///
219    /// `Ok(())` after the complete semantic identity is hashed.
220    ///
221    /// # Errors
222    ///
223    /// Returns [`qubit_budget::MeasuredBudgetError`] when a JSON element
224    /// exceeds a configured limit.
225    /// On error, neither `state` nor the committed portion of `budget` is
226    /// modified. A hasher panic also drops the staged budget transaction.
227    ///
228    /// # Examples
229    ///
230    /// ```
231    /// use std::collections::hash_map::DefaultHasher;
232    ///
233    /// use qubit_budget::{ResourceLimit, StructureLimits};
234    /// use qubit_budget::json::{JsonResource, JsonValueBudget, JsonValueLimits};
235    /// use qubit_value::MultiValues;
236    ///
237    /// let values = MultiValues::Json(vec![serde_json::json!([null])]);
238    /// let structure = StructureLimits::<JsonResource, usize>::builder().nodes_limit(
239    ///     ResourceLimit::new(JsonResource::Nodes, 1_usize),
240    /// ).build();
241    /// let mut budget = JsonValueBudget::new(
242    ///     JsonValueLimits::builder().structure_limits(structure).build(),
243    /// );
244    /// let mut hasher = DefaultHasher::new();
245    ///
246    /// assert!(values.hash_with_json_budget(&mut hasher, &mut budget).is_err());
247    /// drop(hasher);
248    /// // The rejected values did not consume committed budget state.
249    /// ```
250    #[cfg(feature = "json")]
251    pub fn hash_with_json_budget<H, R, Q>(
252        &self,
253        state: &mut H,
254        budget: &mut JsonValueBudget<R, Q>,
255    ) -> Result<(), MeasuredBudgetError<R, Q>>
256    where
257        H: Hasher,
258        R: Clone,
259        Q: ResourceQuantity,
260    {
261        match &self.repr {
262            MultiValuesRepr::Json(values) => {
263                let mut transaction = budget.transaction();
264                for value in values {
265                    preflight_json(value, &mut transaction)?;
266                }
267                std::mem::discriminant(&self.repr).hash(state);
268                values.len().hash(state);
269                for value in values {
270                    hash_json(value, state);
271                }
272                transaction.commit()
273            }
274            _ => {
275                std::mem::discriminant(&self.repr).hash(state);
276                hash_multi_values_payload_with_json_budget(&self.repr, state, budget)
277            }
278        }
279    }
280
281    /// Borrows the stable semantic view of this collection.
282    ///
283    /// # Returns
284    ///
285    /// A non-owning homogeneous view that hides private storage details.
286    #[must_use = "the borrowed collection view should be used"]
287    #[inline(always)]
288    pub fn view(&self) -> MultiValuesRef<'_> {
289        for_each_value_type!(owned_view_match, self)
290    }
291}
292
293// ============================================================================
294// Getter method generation macros
295// ============================================================================
296
297/// Unified multiple values getter generation macro
298///
299/// Generates `get_[xxx]s` methods for `MultiValues`, returning a reference to
300/// value slices.
301///
302/// # Documentation Comment Support
303///
304/// The macro automatically extracts preceding documentation comments, so you
305/// can add `///` comments before macro invocations.
306macro_rules! impl_get_multi_values {
307    // Simple type: return slice reference
308    ($(#[$attr:meta])* slice: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
309        $(#[$attr])*
310        #[doc = ""]
311        #[doc = "# Errors"]
312        #[doc = ""]
313        #[doc = "Returns [`ValueError::Missing`] when the container is unset"]
314        #[doc = "with the requested type, or [`ValueError::TypeMismatch`] when"]
315        #[doc = "the stored data type differs. A concrete empty vector returns"]
316        #[doc = "an empty slice."]
317        #[must_use = "the strict collection read result should be handled"]
318        #[inline(always)]
319        pub fn $method(&self) -> ValueResult<&[$type]> {
320            match &self.repr {
321                MultiValuesRepr::$variant(v) => Ok(v),
322                MultiValuesRepr::Unset(dt) if *dt == $data_type => {
323                    Err(ValueError::Missing($crate::ValueMissing::unset_collection(*dt, *dt)))
324                }
325                _ => Err(ValueError::TypeMismatch {
326                    expected: $data_type,
327                    actual: self.data_type(),
328                }),
329            }
330        }
331    };
332
333    // Complex type: return Vec reference (e.g., Vec<String>, Vec<Vec<u8>>)
334    ($(#[$attr:meta])* vec: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
335        $(#[$attr])*
336        #[doc = ""]
337        #[doc = "# Errors"]
338        #[doc = ""]
339        #[doc = "Returns [`ValueError::Missing`] when the container is unset"]
340        #[doc = "with the requested type, or [`ValueError::TypeMismatch`] when"]
341        #[doc = "the stored data type differs. A concrete empty vector returns"]
342        #[doc = "an empty slice."]
343        #[must_use = "the strict collection read result should be handled"]
344        #[inline(always)]
345        pub fn $method(&self) -> ValueResult<&[$type]> {
346            match &self.repr {
347                MultiValuesRepr::$variant(v) => Ok(v.as_slice()),
348                MultiValuesRepr::Unset(dt) if *dt == $data_type => {
349                    Err(ValueError::Missing($crate::ValueMissing::unset_collection(*dt, *dt)))
350                }
351                _ => Err(ValueError::TypeMismatch {
352                    expected: $data_type,
353                    actual: self.data_type(),
354                }),
355            }
356        }
357    };
358}
359
360/// Unified multiple values get_first method generation macro
361///
362/// Generates `get_first_[xxx]` methods for `MultiValues`, used to get the first
363/// value.
364///
365/// # Documentation Comment Support
366///
367/// The macro automatically extracts preceding documentation comments, so you
368/// can add `///` comments before macro invocations.
369macro_rules! impl_get_first_value {
370    // Copy type: directly return value
371    ($(#[$attr:meta])* copy: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
372        $(#[$attr])*
373        #[doc = ""]
374        #[doc = "# Errors"]
375        #[doc = ""]
376        #[doc = "Returns [`ValueError::Missing`] when the requested type matches"]
377        #[doc = "but no value is stored, or [`ValueError::TypeMismatch`] when"]
378        #[doc = "the stored data type differs."]
379        #[must_use = "the strict first-value result should be handled"]
380        #[inline(always)]
381        pub fn $method(&self) -> ValueResult<$type> {
382            match &self.repr {
383                MultiValuesRepr::$variant(v) if !v.is_empty() => Ok(v[0]),
384                MultiValuesRepr::$variant(_) => {
385                    Err(ValueError::Missing($crate::ValueMissing::empty_collection($data_type, $data_type)))
386                }
387                MultiValuesRepr::Unset(dt) if *dt == $data_type => {
388                    Err(ValueError::Missing($crate::ValueMissing::unset_collection(*dt, *dt)))
389                }
390                _ => Err(ValueError::TypeMismatch {
391                    expected: $data_type,
392                    actual: self.data_type(),
393                }),
394            }
395        }
396    };
397
398    // Reference type: return reference
399    ($(#[$attr:meta])* ref: $method:ident, $variant:ident, $ret_type:ty, $data_type:expr, $conversion:expr) => {
400        $(#[$attr])*
401        #[doc = ""]
402        #[doc = "# Errors"]
403        #[doc = ""]
404        #[doc = "Returns [`ValueError::Missing`] when the requested type matches"]
405        #[doc = "but no value is stored, or [`ValueError::TypeMismatch`] when"]
406        #[doc = "the stored data type differs."]
407        #[must_use = "the strict first-value result should be handled"]
408        #[inline(always)]
409        pub fn $method(&self) -> ValueResult<$ret_type> {
410            match &self.repr {
411                MultiValuesRepr::$variant(v) if !v.is_empty() => {
412                    let conv_fn: fn(&_) -> $ret_type = $conversion;
413                    Ok(conv_fn(&v[0]))
414                },
415                MultiValuesRepr::$variant(_) => {
416                    Err(ValueError::Missing($crate::ValueMissing::empty_collection($data_type, $data_type)))
417                }
418                MultiValuesRepr::Unset(dt) if *dt == $data_type => {
419                    Err(ValueError::Missing($crate::ValueMissing::unset_collection(*dt, *dt)))
420                }
421                _ => Err(ValueError::TypeMismatch {
422                    expected: $data_type,
423                    actual: self.data_type(),
424                }),
425            }
426        }
427    };
428}
429
430#[cfg(all(feature = "converter", feature = "json"))]
431impl MultiValues {
432    /// Projects this collection to its natural JSON representation.
433    ///
434    /// Unset is `null`; every concrete collection is an array, including empty
435    /// and one-item collections.
436    ///
437    /// # Returns
438    ///
439    /// The natural JSON representation of this collection.
440    ///
441    /// # Errors
442    ///
443    /// Returns a list conversion error containing the zero-based source index
444    /// when an item cannot be represented as JSON.
445    #[inline(always)]
446    pub fn to_json_value(&self) -> ValueResult<serde_json::Value> {
447        self.to_json_value_with(ConversionPolicy::default_ref(), ConversionLimits::default_ref())
448    }
449
450    /// Projects this collection using explicit conversion policy and limits.
451    ///
452    /// # Parameters
453    ///
454    /// * `policy` - Controls duration units and precision-loss behavior.
455    /// * `limits` - Bounds conversion resource consumption.
456    ///
457    /// # Returns
458    ///
459    /// The natural JSON representation of this collection.
460    ///
461    /// # Errors
462    ///
463    /// Returns an indexed list conversion error when an item cannot be
464    /// represented under the requested policy and limits.
465    #[inline(always)]
466    pub fn to_json_value_with(
467        &self,
468        policy: &ConversionPolicy,
469        limits: &ConversionLimits,
470    ) -> ValueResult<serde_json::Value> {
471        crate::json::multi_values_to_json_value_with(self, policy, limits)
472    }
473}
474
475/// Maps private collection storage variants to their runtime data types.
476macro_rules! multi_values_data_type_match {
477    ($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 $(, $_wire:tt)*)),+ $(,)?) => {
478        match &$value.repr {
479            MultiValuesRepr::Unset(dt) => *dt,
480            $($(#[$cfg])* MultiValuesRepr::$variant(_) => $data_type,)+
481        }
482    };
483}
484
485/// Returns the concrete element count for each collection storage variant.
486macro_rules! multi_values_count_match {
487    ($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 $(, $_wire:tt)*)),+ $(,)?) => {
488        match &$value.repr {
489            MultiValuesRepr::Unset(_) => 0,
490            $($(#[$cfg])* MultiValuesRepr::$variant(values) => values.len(),)+
491        }
492    };
493}
494
495/// Clears the concrete elements of each collection storage variant.
496macro_rules! multi_values_clear_match {
497    ($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 $(, $_wire:tt)*)),+ $(,)?) => {
498        match &mut $value.repr {
499            MultiValuesRepr::Unset(_) => {}
500            $($(#[$cfg])* MultiValuesRepr::$variant(values) => values.clear(),)+
501        }
502    };
503}
504
505/// Appends same-typed elements to an existing collection storage variant.
506macro_rules! multi_values_append_match {
507    ($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 $(, $_wire:tt)*)),+ $(,)?) => {
508        match (&mut $left.repr, &mut $right.repr) {
509            $(
510                $(#[$cfg])*
511                (MultiValuesRepr::$variant(values), MultiValuesRepr::$variant(other_values)) => {
512                    values.append(other_values);
513                }
514            )+
515            (slot @ MultiValuesRepr::Unset(_), other_values) => {
516                *slot = std::mem::replace(other_values, MultiValuesRepr::Unset(DataType::String));
517            }
518            _ => unreachable!(),
519        }
520    };
521}
522
523/// Clones the first collection element into a scalar value.
524macro_rules! multi_values_first_value_match {
525    ($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 $(, $_wire:tt)*)),+ $(,)?) => {
526        match &$value.repr {
527            MultiValuesRepr::Unset(data_type) => Value::new_unset(*data_type),
528            $(
529                $(#[$cfg])*
530                MultiValuesRepr::$variant(values) => values
531                    .first()
532                    .map(|value| materialize_stored!($materialization, value))
533                    .map(Value::$variant)
534                    .unwrap_or(Value::new_unset($data_type)),
535            )+
536        }
537    };
538}
539
540/// Moves the first collection element into a scalar value.
541macro_rules! multi_values_into_first_value_match {
542    ($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 $(, $_wire:tt)*)),+ $(,)?) => {
543        match $value.repr {
544            MultiValuesRepr::Unset(data_type) => Value::new_unset(data_type),
545            $(
546                $(#[$cfg])*
547                MultiValuesRepr::$variant(values) => values
548                    .into_iter()
549                    .next()
550                    .map(Value::$variant)
551                    .unwrap_or(Value::new_unset($data_type)),
552            )+
553        }
554    };
555}
556
557/// Merges same-typed collection storage while preserving element order.
558macro_rules! multi_values_merge_match {
559    ($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 $(, $_wire:tt)*)),+ $(,)?) => {
560        match (&mut $left.repr, &$right.repr) {
561            $(
562                $(#[$cfg])*
563                (MultiValuesRepr::$variant(values), MultiValuesRepr::$variant(other_values)) => {
564                    values.extend_from_slice(other_values)
565                }
566            )+
567            (slot @ MultiValuesRepr::Unset(_), other_values) => *slot = other_values.clone(),
568            _ => unreachable!(),
569        }
570    };
571}
572
573/// Converts one private scalar storage variant into collection storage.
574macro_rules! value_into_multi_values_match {
575    ($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 $(, $_wire:tt)*)),+ $(,)?) => {
576        match $value.repr {
577            ValueRepr::Unset(data_type) => MultiValues::new_unset(data_type),
578            $($(#[$cfg])* ValueRepr::$variant(value) => {
579                MultiValues::$variant(vec![value_storage_into_multi!($variant, value)])
580            },)+
581        }
582    };
583}
584
585impl MultiValues {
586    /// Generic constructor method
587    ///
588    /// Creates `MultiValues` from any supported input form, avoiding direct
589    /// use of enum variants at call sites.
590    ///
591    /// Supported input forms include single values, vectors, slices, arrays,
592    /// borrowed vectors, and borrowed string collections for supported element
593    /// types.
594    ///
595    /// # Type Parameters
596    ///
597    /// * `S` - Input type convertible into [`MultiValues`].
598    ///
599    /// # Parameters
600    ///
601    /// * `values` - Values to convert into a collection.
602    ///
603    /// # Returns
604    ///
605    /// Returns `MultiValues` wrapping the converted input values.
606    ///
607    /// # Examples
608    ///
609    /// ```rust
610    /// use qubit_value::MultiValues;
611    ///
612    /// // Basic types
613    /// let mv = MultiValues::new(vec![1, 2, 3]);
614    /// assert_eq!(mv.len(), 3);
615    ///
616    /// // Strings
617    /// let mv = MultiValues::new(vec!["a".to_string(), "b".to_string()]);
618    /// assert_eq!(mv.len(), 2);
619    /// ```
620    #[inline(always)]
621    pub fn new<S>(values: S) -> Self
622    where
623        S: Into<Self>,
624    {
625        values.into()
626    }
627
628    /// Generic getter method for multiple values.
629    ///
630    /// Performs a strict typed read of all stored values as `Vec<T>`.
631    ///
632    /// # Type Parameters
633    ///
634    /// * `T` - The target element type to retrieve.
635    ///
636    /// # Returns
637    ///
638    /// Returns the list of values when the stored type matches `T`.
639    ///
640    /// # Errors
641    ///
642    /// Returns [`ValueError::Missing`] when the container is unset with the
643    /// requested type, or [`ValueError::TypeMismatch`] when the stored type
644    /// differs from `T`.
645    ///
646    /// # Examples
647    ///
648    /// ```rust
649    /// use qubit_value::MultiValues;
650    ///
651    /// let multi = MultiValues::Int32(vec![1, 2, 3]);
652    ///
653    /// // Through type inference
654    /// let nums: Vec<i32> = multi.get().unwrap();
655    /// assert_eq!(nums, vec![1, 2, 3]);
656    ///
657    /// // Explicitly specify type parameter
658    /// let nums = multi.get::<i32>().unwrap();
659    /// assert_eq!(nums, vec![1, 2, 3]);
660    /// ```
661    #[must_use = "the strict collection read result should be handled"]
662    #[inline(always)]
663    pub fn get<T>(&self) -> ValueResult<Vec<T>>
664    where
665        for<'a> Vec<T>: TryFrom<&'a Self, Error = ValueError>,
666    {
667        Vec::<T>::try_from(self)
668    }
669
670    /// Generic getter method with a default value list.
671    ///
672    /// Returns the supplied default only when this container is unset. A
673    /// concrete empty vector remains an empty result.
674    ///
675    /// # Type Parameters
676    ///
677    /// * `T` - Target element type for the strict read.
678    ///
679    /// # Parameters
680    ///
681    /// * `default` - Lazily materialized list used only for unset storage.
682    ///
683    /// # Returns
684    ///
685    /// The concrete stored list, or `default` for unset storage.
686    ///
687    /// # Errors
688    ///
689    /// Returns [`ValueError::TypeMismatch`] when the stored type differs from
690    /// `T`.
691    #[must_use = "the strict collection read result should be handled"]
692    #[inline(always)]
693    pub fn get_or<T>(&self, default: impl IntoValueDefault<Vec<T>>) -> ValueResult<Vec<T>>
694    where
695        for<'a> Vec<T>: TryFrom<&'a Self, Error = ValueError>,
696    {
697        match self.get() {
698            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_strict_read() => {
699                Ok(default.into_value_default())
700            }
701            result => result,
702        }
703    }
704
705    /// Strictly reads all values or calls `default` only when storage is unset.
706    ///
707    /// A concrete empty collection is returned unchanged and type mismatches
708    /// are preserved without invoking the callback.
709    ///
710    /// # Type Parameters
711    ///
712    /// * `T` - Target element type.
713    /// * `F` - Deferred fallback producing the complete list.
714    ///
715    /// # Parameters
716    ///
717    /// * `default` - Callback invoked only for unset storage.
718    ///
719    /// # Returns
720    ///
721    /// The stored list or the callback result.
722    ///
723    /// # Errors
724    ///
725    /// Returns [`ValueError::TypeMismatch`] for an incompatible concrete
726    /// collection without invoking the callback.
727    #[must_use = "the strict collection read result should be handled"]
728    #[inline(always)]
729    pub fn get_or_else<T, F>(&self, default: F) -> ValueResult<Vec<T>>
730    where
731        for<'a> Vec<T>: TryFrom<&'a Self, Error = ValueError>,
732        F: FnOnce() -> Vec<T>,
733    {
734        match self.get() {
735            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_strict_read() => Ok(default()),
736            result => result,
737        }
738    }
739
740    /// Generic getter method for the first value
741    ///
742    /// Reads the first stored value as `T`, performing strict type checking.
743    ///
744    /// `get_first<T>()` does not do cross-type conversion. When the `converter`
745    /// feature is enabled, use `to<T>()` for compatible cross-type conversion.
746    ///
747    /// # Type Parameters
748    ///
749    /// * `T` - The target element type to retrieve.
750    ///
751    /// # Returns
752    ///
753    /// Returns the first value when the stored type matches `T` and at least
754    /// one value exists.
755    ///
756    /// # Errors
757    ///
758    /// Returns [`ValueError::Missing`] when the requested type matches but no
759    /// value is stored, or [`ValueError::TypeMismatch`] when the stored type
760    /// differs from `T`.
761    ///
762    /// # Examples
763    ///
764    /// ```rust
765    /// use qubit_value::MultiValues;
766    ///
767    /// let multi = MultiValues::Int32(vec![42, 100, 200]);
768    ///
769    /// // Through type inference
770    /// let first: i32 = multi.get_first().unwrap();
771    /// assert_eq!(first, 42);
772    ///
773    /// // Explicitly specify type parameter
774    /// let first = multi.get_first::<i32>().unwrap();
775    /// assert_eq!(first, 42);
776    ///
777    /// // String type
778    /// let multi = MultiValues::String(vec!["hello".to_string(), "world".to_string()]);
779    /// let first: String = multi.get_first().unwrap();
780    /// assert_eq!(first, "hello");
781    /// ```
782    #[must_use = "the strict first-value result should be handled"]
783    #[inline(always)]
784    pub fn get_first<T>(&self) -> ValueResult<T>
785    where
786        for<'a> T: TryFrom<&'a Self, Error = ValueError>,
787    {
788        T::try_from(self)
789    }
790
791    /// Generic first-value getter with a default value.
792    ///
793    /// Returns the supplied default only when the container is unset. A
794    /// concrete empty vector returns [`ValueError::Missing`]; type mismatches
795    /// are also preserved.
796    ///
797    /// # Type Parameters
798    ///
799    /// * `T` - Target type for the strict first-item read.
800    ///
801    /// # Parameters
802    ///
803    /// * `default` - Lazily materialized value used only for unset storage.
804    ///
805    /// # Returns
806    ///
807    /// The first concrete item, or `default` for unset storage.
808    ///
809    /// # Errors
810    ///
811    /// Returns [`ValueError::Missing`] for a concrete empty collection or
812    /// [`ValueError::TypeMismatch`] when the stored type differs from `T`.
813    #[must_use = "the strict first-value result should be handled"]
814    #[inline(always)]
815    pub fn get_first_or<T>(&self, default: impl IntoValueDefault<T>) -> ValueResult<T>
816    where
817        for<'a> T: TryFrom<&'a Self, Error = ValueError>,
818    {
819        match self.get_first() {
820            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_strict_read() => {
821                Ok(default.into_value_default())
822            }
823            result => result,
824        }
825    }
826
827    /// Strictly reads the first value or calls `default` only when unset.
828    ///
829    /// # Type Parameters
830    ///
831    /// * `T` - Target element type.
832    /// * `F` - Deferred fallback producing one element.
833    ///
834    /// # Parameters
835    ///
836    /// * `default` - Callback invoked only for unset storage.
837    ///
838    /// # Returns
839    ///
840    /// The first stored item or the callback result.
841    ///
842    /// # Errors
843    ///
844    /// Preserves empty-collection and type-mismatch errors without invoking
845    /// the callback.
846    #[must_use = "the strict first-value result should be handled"]
847    #[inline(always)]
848    pub fn get_first_or_else<T, F>(&self, default: F) -> ValueResult<T>
849    where
850        for<'a> T: TryFrom<&'a Self, Error = ValueError>,
851        F: FnOnce() -> T,
852    {
853        match self.get_first() {
854            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_strict_read() => Ok(default()),
855            result => result,
856        }
857    }
858
859    /// Generic setter method
860    ///
861    /// Replaces the entire list with the converted input values.
862    ///
863    /// This operation updates the stored type to the input element type and
864    /// does not validate runtime compatibility with the previous variant.
865    ///
866    /// Supports any input that can be converted into [`MultiValues`], including
867    /// single values, vectors, slices, arrays, and borrowed vectors for
868    /// supported element types.
869    ///
870    /// Existing values are replaced, and the stored type becomes the converted
871    /// input type.
872    ///
873    /// # Type Parameters
874    ///
875    /// * `S` - Input type convertible into [`MultiValues`].
876    ///
877    /// # Parameters
878    ///
879    /// * `values` - The values to set.
880    ///
881    /// # Compile-time restriction
882    ///
883    /// Unsupported input types fail to compile because they do not implement
884    /// `Into<MultiValues>`.
885    ///
886    /// # Examples
887    ///
888    /// ```rust
889    /// use qubit_datatype::DataType;
890    /// use qubit_value::MultiValues;
891    ///
892    /// // 1) Vec<T>
893    /// let mut mv = MultiValues::Unset(DataType::Int32);
894    /// mv.set(vec![42, 100, 200]);
895    /// assert_eq!(mv.get_int32s().unwrap(), &[42, 100, 200]);
896    ///
897    /// // 2) &[T]
898    /// let mut mv = MultiValues::Unset(DataType::Int32);
899    /// let slice = &[7, 8, 9][..];
900    /// mv.set(slice);
901    /// assert_eq!(mv.get_int32s().unwrap(), &[7, 8, 9]);
902    ///
903    /// // 3) Single T
904    /// let mut mv = MultiValues::Unset(DataType::Int32);
905    /// mv.set(42);
906    /// assert_eq!(mv.get_int32s().unwrap(), &[42]);
907    ///
908    /// // String example
909    /// let mut mv = MultiValues::Unset(DataType::String);
910    /// mv.set(vec!["hello".to_string(), "world".to_string()]);
911    /// assert_eq!(mv.get_strings().unwrap(), &["hello", "world"]);
912    /// ```
913    #[inline(always)]
914    pub fn set<S>(&mut self, values: S)
915    where
916        S: Into<Self>,
917    {
918        *self = values.into();
919    }
920
921    /// Generic add method
922    ///
923    /// Appends converted input values to the existing list with strict type
924    /// checking.
925    ///
926    /// Supports any input that can be converted into [`MultiValues`], including
927    /// single values, vectors, slices, arrays, and borrowed vectors for
928    /// supported element types.
929    ///
930    /// The converted input must have the same data type as the current
931    /// container. An empty container keeps its declared type until
932    /// non-empty values of the same type are appended.
933    ///
934    /// # Type Parameters
935    ///
936    /// * `S` - Input type convertible into [`MultiValues`].
937    ///
938    /// # Parameters
939    ///
940    /// * `values` - Values to append.
941    ///
942    /// # Returns
943    ///
944    /// `Ok(())` after appending, including when the input is empty.
945    ///
946    /// # Errors
947    ///
948    /// Returns [`ValueError::TypeMismatch`] when the converted input data type
949    /// differs from the current container data type.
950    ///
951    /// # Examples
952    ///
953    /// ```rust
954    /// use qubit_datatype::DataType;
955    /// use qubit_value::MultiValues;
956    ///
957    /// // 1) Single T
958    /// let mut mv = MultiValues::Int32(vec![42]);
959    /// mv.add(100).unwrap();
960    /// assert_eq!(mv.get_int32s().unwrap(), &[42, 100]);
961    ///
962    /// // 2) Vec<T>
963    /// mv.add(vec![200, 300]).unwrap();
964    /// assert_eq!(mv.get_int32s().unwrap(), &[42, 100, 200, 300]);
965    ///
966    /// // 3) &[T]
967    /// let slice = &[400, 500][..];
968    /// mv.add(slice).unwrap();
969    /// assert_eq!(mv.get_int32s().unwrap(), &[42, 100, 200, 300, 400, 500]);
970    /// ```
971    pub fn add<S>(&mut self, values: S) -> ValueResult<()>
972    where
973        S: Into<Self>,
974    {
975        let mut other = values.into();
976        if self.data_type() != other.data_type() {
977            return Err(ValueError::TypeMismatch {
978                expected: self.data_type(),
979                actual: other.data_type(),
980            });
981        }
982        if other.is_empty() {
983            return Ok(());
984        }
985
986        for_each_value_type!(multi_values_append_match, self, other);
987
988        Ok(())
989    }
990
991    /// Get the data type of the values
992    ///
993    /// # Returns
994    ///
995    /// Returns the data type corresponding to these multiple values
996    ///
997    /// # Examples
998    ///
999    /// ```rust
1000    /// use qubit_datatype::DataType;
1001    /// use qubit_value::MultiValues;
1002    ///
1003    /// let values = MultiValues::Int32(vec![1, 2, 3]);
1004    /// assert_eq!(values.data_type(), DataType::Int32);
1005    /// ```
1006    #[must_use = "the collection element type should be used"]
1007    #[inline(always)]
1008    pub fn data_type(&self) -> DataType {
1009        for_each_value_type!(multi_values_data_type_match, self)
1010    }
1011
1012    /// Returns the number of values.
1013    ///
1014    /// # Returns
1015    ///
1016    /// The number of values contained in these multiple values. An unset
1017    /// collection has length zero.
1018    ///
1019    /// # Examples
1020    ///
1021    /// ```rust
1022    /// use qubit_datatype::DataType;
1023    /// use qubit_value::MultiValues;
1024    ///
1025    /// let values = MultiValues::Int32(vec![1, 2, 3]);
1026    /// assert_eq!(values.len(), 3);
1027    ///
1028    /// let empty = MultiValues::Unset(DataType::String);
1029    /// assert_eq!(empty.len(), 0);
1030    /// ```
1031    #[inline(always)]
1032    #[must_use]
1033    pub fn len(&self) -> usize {
1034        for_each_value_type!(multi_values_count_match, self)
1035    }
1036
1037    /// Tests whether this collection contains no values.
1038    ///
1039    /// An unset collection and a concrete empty vector both have length zero.
1040    /// Use [`MultiValues::is_unset`] when the distinction between no collection
1041    /// and a concrete empty collection matters.
1042    ///
1043    /// # Returns
1044    ///
1045    /// `true` when [`Self::len`] is zero; otherwise, `false`.
1046    #[inline(always)]
1047    #[must_use]
1048    pub fn is_empty(&self) -> bool {
1049        self.len() == 0
1050    }
1051
1052    /// Tests whether this container has no concrete vector.
1053    ///
1054    /// # Returns
1055    ///
1056    /// Returns `true` only for [`MultiValues::Unset`]. A concrete empty vector
1057    /// returns `false`.
1058    ///
1059    /// # Examples
1060    ///
1061    /// ```rust
1062    /// use qubit_datatype::DataType;
1063    /// use qubit_value::MultiValues;
1064    ///
1065    /// let values = MultiValues::Int32(vec![]);
1066    /// assert!(!values.is_unset());
1067    ///
1068    /// let empty = MultiValues::Unset(DataType::String);
1069    /// assert!(empty.is_unset());
1070    /// ```
1071    #[inline(always)]
1072    #[must_use]
1073    pub fn is_unset(&self) -> bool {
1074        matches!(self.repr, MultiValuesRepr::Unset(_))
1075    }
1076
1077    /// Tests whether a concrete collection belongs to the numeric type family.
1078    ///
1079    /// A concrete empty numeric vector returns `true`; an unset collection
1080    /// returns `false`, even when its declared type is numeric.
1081    ///
1082    /// # Returns
1083    ///
1084    /// `true` for concrete collections with a numeric element type.
1085    #[inline(always)]
1086    #[must_use]
1087    pub fn is_numeric(&self) -> bool {
1088        !self.is_unset() && self.data_type().is_numeric()
1089    }
1090
1091    /// Removes the concrete vector while preserving its declared data type.
1092    #[inline(always)]
1093    pub fn unset(&mut self) {
1094        *self = MultiValues::new_unset(self.data_type());
1095    }
1096
1097    /// Clears all values while preserving a concrete collection and its type.
1098    /// An unset collection remains unset because it has no concrete vector to
1099    /// clear.
1100    ///
1101    /// # Examples
1102    ///
1103    /// ```rust
1104    /// use qubit_datatype::DataType;
1105    /// use qubit_value::MultiValues;
1106    ///
1107    /// let mut values = MultiValues::Int32(vec![1, 2, 3]);
1108    /// values.clear();
1109    /// assert_eq!(values.len(), 0);
1110    /// assert_eq!(values.data_type(), DataType::Int32);
1111    /// ```
1112    #[inline(always)]
1113    pub fn clear(&mut self) {
1114        for_each_value_type!(multi_values_clear_match, self)
1115    }
1116
1117    /// Set the data type
1118    ///
1119    /// If the new type differs from the current type, clears all values and
1120    /// sets the new type.
1121    ///
1122    /// # Parameters
1123    ///
1124    /// * `data_type` - The data type to set
1125    ///
1126    /// # Examples
1127    ///
1128    /// ```rust
1129    /// use qubit_datatype::DataType;
1130    /// use qubit_value::MultiValues;
1131    ///
1132    /// let mut values = MultiValues::Int32(vec![1, 2, 3]);
1133    /// values.set_type(DataType::String);
1134    /// assert!(values.is_unset());
1135    /// assert_eq!(values.data_type(), DataType::String);
1136    /// ```
1137    #[inline(always)]
1138    pub fn set_type(&mut self, data_type: DataType) {
1139        if self.data_type() != data_type {
1140            *self = MultiValues::new_unset(data_type);
1141        }
1142    }
1143
1144    /// Converts the first element to a single [`Value`].
1145    ///
1146    /// Returns `Value::Unset` with the same declared type when no element is
1147    /// stored.
1148    ///
1149    /// # Returns
1150    ///
1151    /// A cloned first item, or a typed unset value when no item exists.
1152    #[must_use = "the projected first value should be used"]
1153    #[inline(always)]
1154    pub fn first_value(&self) -> Value {
1155        for_each_value_type!(multi_values_first_value_match, self)
1156    }
1157
1158    /// Consumes this collection and returns its first item as a [`Value`].
1159    ///
1160    /// Empty and unset collections become [`Value::Unset`] with the same data
1161    /// type. Owned element storage is moved instead of cloned.
1162    ///
1163    /// # Returns
1164    ///
1165    /// The owned first item, or a typed unset value when no item exists.
1166    pub fn into_first_value(self) -> Value {
1167        for_each_value_type!(multi_values_into_first_value_match, self)
1168    }
1169
1170    /// Appends all values from another container with the same data type.
1171    ///
1172    /// # Parameters
1173    ///
1174    /// * `other` - Collection whose values are cloned and appended.
1175    ///
1176    /// # Returns
1177    ///
1178    /// `Ok(())` after appending, including when `other` is empty.
1179    ///
1180    /// # Errors
1181    ///
1182    /// Returns [`ValueError::TypeMismatch`] when `other` has a different data
1183    /// type.
1184    pub fn merge(&mut self, other: &MultiValues) -> ValueResult<()> {
1185        if self.data_type() != other.data_type() {
1186            return Err(ValueError::TypeMismatch {
1187                expected: self.data_type(),
1188                actual: other.data_type(),
1189            });
1190        }
1191        if other.is_empty() {
1192            return Ok(());
1193        }
1194        for_each_value_type!(multi_values_merge_match, self, other);
1195        Ok(())
1196    }
1197}
1198
1199impl From<Value> for MultiValues {
1200    fn from(value: Value) -> Self {
1201        for_each_value_type!(value_into_multi_values_match, value)
1202    }
1203}
1204
1205/// Converts the first collection element with a standalone policy and limits.
1206#[cfg(feature = "converter")]
1207macro_rules! multi_values_convert_first_match {
1208    ($value:expr, $policy:expr, $limits:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal $(, $_wire:tt)*)),+ $(,)?) => {
1209        match &$value.repr {
1210            MultiValuesRepr::Unset(from) => {
1211                Err(DataConversionError::missing(*from, T::DATA_TYPE).into())
1212            }
1213            $(
1214                $(#[$cfg])*
1215                MultiValuesRepr::$variant(values) => {
1216                    convert_first_with(DataConverters::from(values), $policy, $limits)
1217                }
1218            )+
1219        }
1220    };
1221}
1222
1223/// Converts every collection element with a standalone policy and limits.
1224#[cfg(feature = "converter")]
1225macro_rules! multi_values_convert_list_match {
1226    ($value:expr, $policy:expr, $limits:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal $(, $_wire:tt)*)),+ $(,)?) => {
1227        match &$value.repr {
1228            MultiValuesRepr::Unset(from) => {
1229                Err(DataConversionError::missing(*from, T::DATA_TYPE).into())
1230            }
1231            $(
1232                $(#[$cfg])*
1233                MultiValuesRepr::$variant(values) => {
1234                    convert_values_with(DataConverters::from(values), $policy, $limits)
1235                }
1236            )+
1237        }
1238    };
1239}
1240
1241/// Converts the first collection element through a caller-owned session.
1242#[cfg(feature = "converter")]
1243macro_rules! multi_values_convert_first_in_match {
1244    ($value:expr, $session:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal $(, $_wire:tt)*)),+ $(,)?) => {
1245        match &$value.repr {
1246            MultiValuesRepr::Unset(from) => {
1247                Err(DataConversionError::missing(*from, T::DATA_TYPE).into())
1248            }
1249            $(
1250                $(#[$cfg])*
1251                MultiValuesRepr::$variant(values) => {
1252                    DataConverters::from(values)
1253                        .to_first_in($session)
1254                        .map_err(ValueError::from)
1255                }
1256            )+
1257        }
1258    };
1259}
1260
1261/// Converts every collection element through a caller-owned session.
1262#[cfg(feature = "converter")]
1263macro_rules! multi_values_convert_list_in_match {
1264    ($value:expr, $session:expr; $(([$($cfg:meta),*], $variant:ident, $type:ty, $data_type:expr, $materialization:ident, $json_class:ident, $number_projection:ident, $value_doc:literal, $multi_doc:literal $(, $_wire:tt)*)),+ $(,)?) => {
1265        match &$value.repr {
1266            MultiValuesRepr::Unset(from) => {
1267                Err(DataConversionError::missing(*from, T::DATA_TYPE).into())
1268            }
1269            $(
1270                $(#[$cfg])*
1271                MultiValuesRepr::$variant(values) => {
1272                    DataConverters::from(values)
1273                        .to_vec_in($session)
1274                        .map_err(ValueError::from)
1275                }
1276            )+
1277        }
1278    };
1279}
1280
1281// ============================================================================
1282// Inherent conversion APIs
1283// ============================================================================
1284
1285/// Converts the first item from a batch converter using conversion policy and
1286/// limits.
1287///
1288/// # Type Parameters
1289///
1290/// * `T` - Target type.
1291/// * `I` - Iterator type wrapped by `DataConverters`.
1292///
1293/// # Parameters
1294///
1295/// * `values` - Batch converter containing source values.
1296/// * `policy` - Conversion policy forwarded to `qubit_datatype`.
1297/// * `limits` - Conversion limits forwarded to `qubit_datatype`.
1298///
1299/// # Returns
1300///
1301/// Returns the converted first value.
1302///
1303/// # Errors
1304///
1305/// Returns the mapped single-value conversion error for an empty source or an
1306/// invalid first source value.
1307#[inline(always)]
1308#[cfg(feature = "converter")]
1309fn convert_first_with<'a, T, I>(
1310    values: DataConverters<I>,
1311    policy: &ConversionPolicy,
1312    limits: &ConversionLimits,
1313) -> ValueResult<T>
1314where
1315    T: DataConversionTarget,
1316    I: Iterator,
1317    I::Item: Into<DataConverter<'a>>,
1318{
1319    values.to_first_with(policy, limits).map_err(ValueError::from)
1320}
1321
1322/// Converts every item from a batch converter using conversion policy and
1323/// limits.
1324///
1325/// # Type Parameters
1326///
1327/// * `T` - Target element type.
1328/// * `I` - Iterator type wrapped by `DataConverters`.
1329///
1330/// # Parameters
1331///
1332/// * `values` - Batch converter containing source values.
1333/// * `policy` - Conversion policy forwarded to `qubit_datatype`.
1334/// * `limits` - Conversion limits forwarded to `qubit_datatype`.
1335///
1336/// # Returns
1337///
1338/// Returns converted values in the original order.
1339///
1340/// # Errors
1341///
1342/// Returns a mapped batch conversion error containing the failing source index.
1343#[inline(always)]
1344#[cfg(feature = "converter")]
1345fn convert_values_with<'a, T, I>(
1346    values: DataConverters<I>,
1347    policy: &ConversionPolicy,
1348    limits: &ConversionLimits,
1349) -> ValueResult<Vec<T>>
1350where
1351    T: DataConversionTarget,
1352    I: Iterator,
1353    I::Item: Into<DataConverter<'a>>,
1354{
1355    values.to_vec_with(policy, limits).map_err(ValueError::from)
1356}
1357
1358#[cfg(feature = "converter")]
1359impl MultiValues {
1360    /// Enriches only missing failures after conversion, retaining
1361    /// resource-error priority.
1362    fn contextual_conversion_error(&self, error: ValueError, first: bool) -> ValueError {
1363        let ValueError::Missing(missing) = error else {
1364            return error;
1365        };
1366        let reason = if self.is_unset() {
1367            crate::ValueMissingReason::UnsetCollection
1368        } else if self.is_empty() {
1369            crate::ValueMissingReason::EmptyCollection
1370        } else {
1371            crate::ValueMissingReason::Conversion
1372        };
1373        let missing = missing.with_storage(self.data_type(), reason);
1374        ValueError::Missing(if first { missing.with_first_index() } else { missing })
1375    }
1376
1377    /// Converts the first stored value to `T`.
1378    ///
1379    /// Unlike [`Self::get_first`], this method uses shared `DataConverter`
1380    /// conversion rules instead of strict type matching. For example, a stored
1381    /// `String("1")` can be converted to `bool`.
1382    ///
1383    /// # Type Parameters
1384    ///
1385    /// * `T` - Target type.
1386    ///
1387    /// # Returns
1388    ///
1389    /// The converted first value.
1390    ///
1391    /// # Errors
1392    ///
1393    /// Returns a structured missing-value conversion error when the container
1394    /// is unset, an empty-collection error for a concrete empty vector, or a
1395    /// conversion error when the first value cannot be converted to `T`.
1396    #[inline(always)]
1397    pub fn to_first<T>(&self) -> ValueResult<T>
1398    where
1399        T: DataConversionTarget,
1400    {
1401        self.to_first_with(ConversionPolicy::default_ref(), ConversionLimits::default_ref())
1402    }
1403
1404    /// Converts the first stored value to `T`, or returns `default` when the
1405    /// container is unset or conversion reports a missing value.
1406    ///
1407    /// An unset collection can use the default. A concrete empty collection
1408    /// and a policy-missing collection item (including the first item) remain
1409    /// errors and do not use the default; ordinary conversion errors are also
1410    /// preserved.
1411    ///
1412    /// # Type Parameters
1413    ///
1414    /// * `T` - Target type.
1415    ///
1416    /// # Parameters
1417    ///
1418    /// * `default` - Value returned for unset storage or a policy-missing
1419    ///   scalar; collection-item and ordinary conversion errors are returned.
1420    ///
1421    /// # Returns
1422    ///
1423    /// The converted first value, or `default` for unset or conversion-missing
1424    /// storage.
1425    ///
1426    /// # Errors
1427    ///
1428    /// Returns an empty-collection error for a concrete empty vector, or a
1429    /// conversion error when the first value cannot be converted to `T`.
1430    #[inline]
1431    pub fn to_first_or<T>(&self, default: impl IntoValueDefault<T>) -> ValueResult<T>
1432    where
1433        T: DataConversionTarget,
1434    {
1435        match self.to_first() {
1436            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_conversion() => {
1437                Ok(default.into_value_default())
1438            }
1439            result => result,
1440        }
1441    }
1442
1443    /// Converts the first value or calls `default` when storage is unset or
1444    /// conversion reports a missing value.
1445    ///
1446    /// # Type Parameters
1447    ///
1448    /// * `T` - Target conversion type.
1449    /// * `F` - Deferred fallback producing `T`.
1450    ///
1451    /// # Parameters
1452    ///
1453    /// * `default` - Callback invoked for unset storage or a policy-missing
1454    ///   scalar; it is not invoked for a missing collection item or ordinary
1455    ///   conversion error.
1456    ///
1457    /// # Returns
1458    ///
1459    /// The converted first item or the callback result.
1460    ///
1461    /// # Errors
1462    ///
1463    /// Preserves empty-collection, policy-missing-item, and ordinary
1464    /// concrete-value conversion errors without invoking the callback.
1465    #[inline]
1466    pub fn to_first_or_else<T, F>(&self, default: F) -> ValueResult<T>
1467    where
1468        T: DataConversionTarget,
1469        F: FnOnce() -> T,
1470    {
1471        match self.to_first() {
1472            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_conversion() => Ok(default()),
1473            result => result,
1474        }
1475    }
1476
1477    /// Converts the first stored value to `T` using conversion policy and
1478    /// limits.
1479    ///
1480    /// Stored strings are collection items and are never split again by scalar
1481    /// string collection policy.
1482    ///
1483    /// # Type Parameters
1484    ///
1485    /// * `T` - Target type.
1486    ///
1487    /// # Parameters
1488    ///
1489    /// * `policy` - Conversion policy forwarded to `qubit_datatype`.
1490    /// * `limits` - Conversion limits forwarded to `qubit_datatype`.
1491    ///
1492    /// # Returns
1493    ///
1494    /// The converted first value.
1495    ///
1496    /// # Errors
1497    ///
1498    /// Returns a structured missing-value conversion error when the container
1499    /// is unset, an empty-collection error for a concrete empty vector, or a
1500    /// conversion error when the first value cannot be converted to `T`.
1501    pub fn to_first_with<T>(&self, policy: &ConversionPolicy, limits: &ConversionLimits) -> ValueResult<T>
1502    where
1503        T: DataConversionTarget,
1504    {
1505        for_each_value_type!(multi_values_convert_first_match, self, policy, limits)
1506            .map_err(|error| self.contextual_conversion_error(error, true))
1507    }
1508
1509    /// Converts the first stored value using an existing conversion session.
1510    ///
1511    /// # Type Parameters
1512    ///
1513    /// * `T` - Target element type supported by the shared conversion layer.
1514    ///
1515    /// # Parameters
1516    ///
1517    /// * `session` - Caller-owned session providing policy, limits, and budget.
1518    ///
1519    /// # Returns
1520    ///
1521    /// The converted first element.
1522    ///
1523    /// # Errors
1524    ///
1525    /// Returns a structured missing, conversion, or budget error when the
1526    /// first element cannot be produced as `T`.
1527    pub fn to_first_in<T>(&self, session: &mut ConversionSession<'_>) -> ValueResult<T>
1528    where
1529        T: DataConversionTarget,
1530    {
1531        for_each_value_type!(multi_values_convert_first_in_match, self, session)
1532            .map_err(|error| self.contextual_conversion_error(error, true))
1533    }
1534
1535    /// Converts the first stored value to `T` using conversion policy and
1536    /// limits, or returns `default` when storage is unset or conversion
1537    /// reports a missing value.
1538    ///
1539    /// # Type Parameters
1540    ///
1541    /// * `T` - Target conversion type.
1542    ///
1543    /// # Parameters
1544    ///
1545    /// * `default` - Lazily materialized value used for unset storage or a
1546    ///   conversion-missing result.
1547    /// * `policy` - Conversion policy forwarded to `qubit_datatype`.
1548    /// * `limits` - Conversion limits forwarded to `qubit_datatype`.
1549    ///
1550    /// # Returns
1551    ///
1552    /// The converted first item, or `default` for an unset collection or a
1553    /// policy-missing scalar. A missing collection item, including index zero,
1554    /// never uses the default.
1555    ///
1556    /// # Errors
1557    ///
1558    /// Returns an empty-collection error, a missing collection-item error, or
1559    /// an ordinary conversion error for concrete values that cannot be
1560    /// converted under the provided policy and limits. None invokes the
1561    /// fallback.
1562    #[inline]
1563    pub fn to_first_or_with<T>(
1564        &self,
1565        default: impl IntoValueDefault<T>,
1566        policy: &ConversionPolicy,
1567        limits: &ConversionLimits,
1568    ) -> ValueResult<T>
1569    where
1570        T: DataConversionTarget,
1571    {
1572        match self.to_first_with(policy, limits) {
1573            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_conversion() => {
1574                Ok(default.into_value_default())
1575            }
1576            result => result,
1577        }
1578    }
1579
1580    /// Converts the first value with the provided policy and limits, or calls
1581    /// `default` when storage is unset or conversion reports a missing
1582    /// value.
1583    ///
1584    /// # Type Parameters
1585    ///
1586    /// * `T` - Target conversion type.
1587    /// * `F` - Deferred fallback producing `T`.
1588    ///
1589    /// # Parameters
1590    ///
1591    /// * `default` - Callback invoked for unset storage or a conversion-missing
1592    ///   result.
1593    /// * `policy` - Conversion policy forwarded to the shared converter.
1594    /// * `limits` - Conversion limits forwarded to the shared converter.
1595    ///
1596    /// # Returns
1597    ///
1598    /// The converted first item or the callback result.
1599    ///
1600    /// # Errors
1601    ///
1602    /// Preserves concrete-value conversion errors, including policy-missing
1603    /// collection items, without invoking the callback.
1604    #[inline]
1605    pub fn to_first_or_else_with<T, F>(
1606        &self,
1607        default: F,
1608        policy: &ConversionPolicy,
1609        limits: &ConversionLimits,
1610    ) -> ValueResult<T>
1611    where
1612        T: DataConversionTarget,
1613        F: FnOnce() -> T,
1614    {
1615        match self.to_first_with(policy, limits) {
1616            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_conversion() => Ok(default()),
1617            result => result,
1618        }
1619    }
1620
1621    /// Converts all stored values to `T`.
1622    ///
1623    /// Unlike [`Self::get`], this method uses shared `DataConverter` conversion
1624    /// rules for every element instead of strict type matching. A concrete
1625    /// empty vector returns an empty vector; an unset container reports a
1626    /// missing-value conversion error.
1627    ///
1628    /// # Type Parameters
1629    ///
1630    /// * `T` - Target element type.
1631    ///
1632    /// # Returns
1633    ///
1634    /// A vector containing all converted values in the original order.
1635    ///
1636    /// # Errors
1637    ///
1638    /// Returns the first conversion error encountered while converting an
1639    /// element.
1640    pub fn to_list<T>(&self) -> ValueResult<Vec<T>>
1641    where
1642        T: DataConversionTarget,
1643    {
1644        self.to_list_with(ConversionPolicy::default_ref(), ConversionLimits::default_ref())
1645    }
1646
1647    /// Converts all stored values to `T`, or returns `default` when storage is
1648    /// unset or conversion reports a missing value.
1649    ///
1650    /// # Type Parameters
1651    ///
1652    /// * `T` - Target element type.
1653    ///
1654    /// # Parameters
1655    ///
1656    /// * `default` - Lazily materialized list used for unset storage or a
1657    ///   policy-missing scalar; collection-item and ordinary conversion errors
1658    ///   are returned.
1659    ///
1660    /// # Returns
1661    ///
1662    /// All converted items, or `default` for an unset collection or a
1663    /// policy-missing outer scalar. A policy-missing collection item and an
1664    /// ordinary conversion error never use the default.
1665    ///
1666    /// # Errors
1667    ///
1668    /// Returns the first item conversion error for concrete storage. A
1669    /// policy-missing collection item is preserved and does not use the
1670    /// fallback.
1671    #[inline]
1672    pub fn to_list_or<T>(&self, default: impl IntoValueDefault<Vec<T>>) -> ValueResult<Vec<T>>
1673    where
1674        T: DataConversionTarget,
1675    {
1676        match self.to_list() {
1677            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_conversion() => {
1678                Ok(default.into_value_default())
1679            }
1680            result => result,
1681        }
1682    }
1683
1684    /// Converts all values or calls `default` when storage is unset or
1685    /// conversion reports a missing value.
1686    ///
1687    /// # Type Parameters
1688    ///
1689    /// * `T` - Target element conversion type.
1690    /// * `F` - Deferred fallback producing the complete list.
1691    ///
1692    /// # Parameters
1693    ///
1694    /// * `default` - Callback invoked for unset storage or a policy-missing
1695    ///   scalar; it is not invoked for a missing collection item or ordinary
1696    ///   conversion error.
1697    ///
1698    /// # Returns
1699    ///
1700    /// The converted list or the callback result.
1701    ///
1702    /// # Errors
1703    ///
1704    /// Preserves concrete-value conversion errors, including policy-missing
1705    /// collection items, without invoking the callback.
1706    #[inline]
1707    pub fn to_list_or_else<T, F>(&self, default: F) -> ValueResult<Vec<T>>
1708    where
1709        T: DataConversionTarget,
1710        F: FnOnce() -> Vec<T>,
1711    {
1712        match self.to_list() {
1713            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_conversion() => Ok(default()),
1714            result => result,
1715        }
1716    }
1717
1718    /// Converts all stored values to `T` using conversion policy and limits.
1719    ///
1720    /// Stored strings are collection items and are never split again by scalar
1721    /// string collection policy.
1722    ///
1723    /// # Type Parameters
1724    ///
1725    /// * `T` - Target element type.
1726    ///
1727    /// # Parameters
1728    ///
1729    /// * `policy` - Conversion policy forwarded to `qubit_datatype`.
1730    /// * `limits` - Conversion limits forwarded to `qubit_datatype`.
1731    ///
1732    /// # Returns
1733    ///
1734    /// A vector containing all converted values in the original order.
1735    ///
1736    /// # Errors
1737    ///
1738    /// Returns the first conversion error encountered while converting an
1739    /// element.
1740    pub fn to_list_with<T>(&self, policy: &ConversionPolicy, limits: &ConversionLimits) -> ValueResult<Vec<T>>
1741    where
1742        T: DataConversionTarget,
1743    {
1744        for_each_value_type!(multi_values_convert_list_match, self, policy, limits)
1745            .map_err(|error| self.contextual_conversion_error(error, false))
1746    }
1747
1748    /// Converts every stored value using an existing conversion session.
1749    ///
1750    /// # Type Parameters
1751    ///
1752    /// * `T` - Target element type supported by the shared conversion layer.
1753    ///
1754    /// # Parameters
1755    ///
1756    /// * `session` - Caller-owned session providing policy, limits, and budget.
1757    ///
1758    /// # Returns
1759    ///
1760    /// Converted elements in their original order.
1761    ///
1762    /// # Errors
1763    ///
1764    /// Returns the first structured missing, conversion, or budget error.
1765    pub fn to_list_in<T>(&self, session: &mut ConversionSession<'_>) -> ValueResult<Vec<T>>
1766    where
1767        T: DataConversionTarget,
1768    {
1769        for_each_value_type!(multi_values_convert_list_in_match, self, session)
1770            .map_err(|error| self.contextual_conversion_error(error, false))
1771    }
1772
1773    /// Converts all stored values to `T` using conversion policy and limits, or
1774    /// returns `default` when storage is unset or conversion reports a
1775    /// missing value.
1776    ///
1777    /// # Type Parameters
1778    ///
1779    /// * `T` - Target element type.
1780    ///
1781    /// # Parameters
1782    ///
1783    /// * `default` - Lazily materialized list used for unset storage or a
1784    ///   conversion-missing result.
1785    /// * `policy` - Conversion policy forwarded to `qubit_datatype`.
1786    /// * `limits` - Conversion limits forwarded to `qubit_datatype`.
1787    ///
1788    /// # Returns
1789    ///
1790    /// All converted items, or `default` for an unset collection or a
1791    /// policy-missing scalar. A missing collection item and an ordinary
1792    /// conversion error never use the default.
1793    ///
1794    /// # Errors
1795    ///
1796    /// Returns the first item conversion error for concrete storage. Missing
1797    /// collection items and ordinary conversion errors are preserved.
1798    #[inline]
1799    pub fn to_list_or_with<T>(
1800        &self,
1801        default: impl IntoValueDefault<Vec<T>>,
1802        policy: &ConversionPolicy,
1803        limits: &ConversionLimits,
1804    ) -> ValueResult<Vec<T>>
1805    where
1806        T: DataConversionTarget,
1807    {
1808        match self.to_list_with(policy, limits) {
1809            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_conversion() => {
1810                Ok(default.into_value_default())
1811            }
1812            result => result,
1813        }
1814    }
1815
1816    /// Converts all values with the provided policy and limits, or calls
1817    /// `default` when storage is unset or conversion reports a missing
1818    /// value.
1819    ///
1820    /// # Type Parameters
1821    ///
1822    /// * `T` - Target element conversion type.
1823    /// * `F` - Deferred fallback producing the complete list.
1824    ///
1825    /// # Parameters
1826    ///
1827    /// * `default` - Callback invoked for unset storage or a policy-missing
1828    ///   scalar; it is not invoked for a missing collection item or ordinary
1829    ///   conversion error.
1830    /// * `policy` - Conversion policy forwarded to the shared converter.
1831    /// * `limits` - Conversion limits forwarded to the shared converter.
1832    ///
1833    /// # Returns
1834    ///
1835    /// The converted list or the callback result.
1836    ///
1837    /// # Errors
1838    ///
1839    /// Preserves concrete-value conversion errors, including policy-missing
1840    /// collection items, without invoking the callback.
1841    #[inline]
1842    pub fn to_list_or_else_with<T, F>(
1843        &self,
1844        default: F,
1845        policy: &ConversionPolicy,
1846        limits: &ConversionLimits,
1847    ) -> ValueResult<Vec<T>>
1848    where
1849        T: DataConversionTarget,
1850        F: FnOnce() -> Vec<T>,
1851    {
1852        match self.to_list_with(policy, limits) {
1853            Err(ValueError::Missing(missing)) if missing.is_defaultable_for_conversion() => Ok(default()),
1854            result => result,
1855        }
1856    }
1857}
1858
1859impl MultiValues {
1860    // ========================================================================
1861    // Get first value (as single value access)
1862    // ========================================================================
1863
1864    impl_get_first_value! {
1865        /// Get the first boolean value.
1866        ///
1867        /// # Returns
1868        ///
1869        /// If types match and a value exists, returns the first boolean value; see `# Errors`.
1870        ///
1871        /// # Examples
1872        ///
1873        /// ```rust
1874        /// use qubit_value::MultiValues;
1875        ///
1876        /// let values = MultiValues::Bool(vec![true, false]);
1877        /// assert_eq!(values.get_first_bool().unwrap(), true);
1878        /// ```
1879        copy: get_first_bool, Bool, bool, DataType::Bool
1880    }
1881
1882    impl_get_first_value! {
1883        /// Get the first character value
1884        ///
1885        /// # Returns
1886        ///
1887        /// If types match and a value exists, returns the first character value; see `# Errors`.
1888        copy: get_first_char, Char, char, DataType::Char
1889    }
1890
1891    impl_get_first_value! {
1892        /// Get the first int8 value
1893        ///
1894        /// # Returns
1895        ///
1896        /// If types match and a value exists, returns the first int8 value; see `# Errors`.
1897        copy: get_first_int8, Int8, i8, DataType::Int8
1898    }
1899
1900    impl_get_first_value! {
1901        /// Get the first int16 value
1902        ///
1903        /// # Returns
1904        ///
1905        /// If types match and a value exists, returns the first int16 value; see `# Errors`.
1906        copy: get_first_int16, Int16, i16, DataType::Int16
1907    }
1908
1909    impl_get_first_value! {
1910        /// Get the first int32 value
1911        ///
1912        /// # Returns
1913        ///
1914        /// If types match and a value exists, returns the first int32 value; see `# Errors`.
1915        copy: get_first_int32, Int32, i32, DataType::Int32
1916    }
1917
1918    impl_get_first_value! {
1919        /// Get the first int64 value
1920        ///
1921        /// # Returns
1922        ///
1923        /// If types match and a value exists, returns the first int64 value; see `# Errors`.
1924        copy: get_first_int64, Int64, i64, DataType::Int64
1925    }
1926
1927    impl_get_first_value! {
1928        /// Get the first int128 value
1929        ///
1930        /// # Returns
1931        ///
1932        /// If types match and a value exists, returns the first int128 value; see `# Errors`.
1933        copy: get_first_int128, Int128, i128, DataType::Int128
1934    }
1935
1936    impl_get_first_value! {
1937        /// Get the first uint8 value
1938        ///
1939        /// # Returns
1940        ///
1941        /// If types match and a value exists, returns the first uint8 value; see `# Errors`.
1942        copy: get_first_uint8, UInt8, u8, DataType::UInt8
1943    }
1944
1945    impl_get_first_value! {
1946        /// Get the first uint16 value
1947        ///
1948        /// # Returns
1949        ///
1950        /// If types match and a value exists, returns the first uint16 value; see `# Errors`.
1951        copy: get_first_uint16, UInt16, u16, DataType::UInt16
1952    }
1953
1954    impl_get_first_value! {
1955        /// Get the first uint32 value
1956        ///
1957        /// # Returns
1958        ///
1959        /// If types match and a value exists, returns the first uint32 value; see `# Errors`.
1960        copy: get_first_uint32, UInt32, u32, DataType::UInt32
1961    }
1962
1963    impl_get_first_value! {
1964        /// Get the first uint64 value
1965        ///
1966        /// # Returns
1967        ///
1968        /// If types match and a value exists, returns the first uint64 value; see `# Errors`.
1969        copy: get_first_uint64, UInt64, u64, DataType::UInt64
1970    }
1971
1972    impl_get_first_value! {
1973        /// Get the first uint128 value
1974        ///
1975        /// # Returns
1976        ///
1977        /// If types match and a value exists, returns the first uint128 value; see `# Errors`.
1978        copy: get_first_uint128, UInt128, u128, DataType::UInt128
1979    }
1980
1981    impl_get_first_value! {
1982        /// Get the first float32 value
1983        ///
1984        /// # Returns
1985        ///
1986        /// If types match and a value exists, returns the first float32 value; see `# Errors`.
1987        copy: get_first_float32, Float32, f32, DataType::Float32
1988    }
1989
1990    impl_get_first_value! {
1991        /// Get the first float64 value
1992        ///
1993        /// # Returns
1994        ///
1995        /// If types match and a value exists, returns the first float64 value; see `# Errors`.
1996        copy: get_first_float64, Float64, f64, DataType::Float64
1997    }
1998
1999    impl_get_first_value! {
2000        /// Get the first string reference
2001        ///
2002        /// # Returns
2003        ///
2004        /// If types match and a value exists, returns a reference to the first
2005        /// string; see `# Errors`.
2006        ref: get_first_string, String, &str, DataType::String, |s: &String| s.as_str()
2007    }
2008
2009    impl_get_first_value! {
2010        /// Get the first date value
2011        ///
2012        /// # Returns
2013        ///
2014        /// If types match and a value exists, returns the first date value; see `# Errors`.
2015        #[cfg(feature = "chrono")]
2016        copy: get_first_date, Date, NaiveDate, DataType::Date
2017    }
2018
2019    impl_get_first_value! {
2020        /// Get the first time value
2021        ///
2022        /// # Returns
2023        ///
2024        /// If types match and a value exists, returns the first time value; see `# Errors`.
2025        #[cfg(feature = "chrono")]
2026        copy: get_first_time, Time, NaiveTime, DataType::Time
2027    }
2028
2029    impl_get_first_value! {
2030        /// Get the first datetime value
2031        ///
2032        /// # Returns
2033        ///
2034        /// If types match and a value exists, returns the first datetime value; see `# Errors`.
2035        #[cfg(feature = "chrono")]
2036        copy: get_first_datetime, DateTime, NaiveDateTime, DataType::DateTime
2037    }
2038
2039    impl_get_first_value! {
2040        /// Get the first UTC instant value
2041        ///
2042        /// # Returns
2043        ///
2044        /// If types match and a value exists, returns the first UTC instant
2045        /// value; see `# Errors`.
2046        #[cfg(feature = "chrono")]
2047        copy: get_first_instant, Instant, DateTime<Utc>, DataType::Instant
2048    }
2049
2050    impl_get_first_value! {
2051        /// Get the first big integer value
2052        ///
2053        /// # Returns
2054        ///
2055        /// If types match and a value exists, returns the first big integer
2056        /// value; see `# Errors`.
2057        #[cfg(feature = "big-integer")]
2058        ref: get_first_biginteger, BigInteger, BigInt, DataType::BigInteger, |v: &BigInt| v.clone()
2059    }
2060
2061    impl_get_first_value! {
2062        /// Get the first big decimal value
2063        ///
2064        /// # Returns
2065        ///
2066        /// If types match and a value exists, returns the first big decimal
2067        /// value; see `# Errors`.
2068        #[cfg(feature = "big-decimal")]
2069        ref: get_first_bigdecimal, BigDecimal, BigDecimal, DataType::BigDecimal, |v: &BigDecimal| v.clone()
2070    }
2071
2072    impl_get_first_value! {
2073        /// Get the first Duration value
2074        ///
2075        /// # Returns
2076        ///
2077        /// The first duration when the stored type matches.
2078        copy: get_first_duration, Duration, Duration, DataType::Duration
2079    }
2080
2081    impl_get_first_value! {
2082        /// Get the first Url value
2083        ///
2084        /// # Returns
2085        ///
2086        /// A clone of the first URL when the stored type matches.
2087        #[cfg(feature = "url")]
2088        ref: get_first_url, Url, Url, DataType::Url, |v: &Url| v.clone()
2089    }
2090
2091    impl_get_first_value! {
2092        /// Get the first StringMap value
2093        ///
2094        /// # Returns
2095        ///
2096        /// A clone of the first string map when the stored type matches.
2097        ref: get_first_string_map, StringMap, HashMap<String, String>, DataType::StringMap, |v: &HashMap<String, String>| v.clone()
2098    }
2099
2100    impl_get_first_value! {
2101        /// Get the first Json value
2102        ///
2103        /// # Returns
2104        ///
2105        /// A clone of the first JSON value when the stored type matches.
2106        #[cfg(feature = "json")]
2107        ref: get_first_json, Json, serde_json::Value, DataType::Json, |v: &serde_json::Value| v.clone()
2108    }
2109
2110    // ========================================================================
2111    // Get all values (type checking)
2112    // ========================================================================
2113
2114    impl_get_multi_values! {
2115        /// Get reference to all boolean values
2116        ///
2117        /// # Returns
2118        ///
2119        /// If types match, returns a reference to the boolean value array; see `# Errors`.
2120        ///
2121        /// # Examples
2122        ///
2123        /// ```rust
2124        /// use qubit_value::MultiValues;
2125        ///
2126        /// let values = MultiValues::Bool(vec![true, false, true]);
2127        /// assert_eq!(values.get_bools().unwrap(), &[true, false, true]);
2128        /// ```
2129        slice: get_bools, Bool, bool, DataType::Bool
2130    }
2131
2132    impl_get_multi_values! {
2133        /// Get reference to all character values
2134        ///
2135        /// # Returns
2136        ///
2137        /// If types match, returns a reference to the character value array; see `# Errors`.
2138        slice: get_chars, Char, char, DataType::Char
2139    }
2140
2141    impl_get_multi_values! {
2142        /// Get reference to all int8 values
2143        ///
2144        /// # Returns
2145        ///
2146        /// If types match, returns a reference to the int8 value array; see `# Errors`.
2147        slice: get_int8s, Int8, i8, DataType::Int8
2148    }
2149
2150    impl_get_multi_values! {
2151        /// Get reference to all int16 values
2152        ///
2153        /// # Returns
2154        ///
2155        /// If types match, returns a reference to the int16 value array; see `# Errors`.
2156        slice: get_int16s, Int16, i16, DataType::Int16
2157    }
2158
2159    impl_get_multi_values! {
2160        /// Get reference to all int32 values
2161        ///
2162        /// # Returns
2163        ///
2164        /// If types match, returns a reference to the int32 value array; see `# Errors`.
2165        slice: get_int32s, Int32, i32, DataType::Int32
2166    }
2167
2168    impl_get_multi_values! {
2169        /// Get reference to all int64 values
2170        ///
2171        /// # Returns
2172        ///
2173        /// If types match, returns a reference to the int64 value array; see `# Errors`.
2174        slice: get_int64s, Int64, i64, DataType::Int64
2175    }
2176
2177    impl_get_multi_values! {
2178        /// Get reference to all int128 values
2179        ///
2180        /// # Returns
2181        ///
2182        /// If types match, returns a reference to the int128 value array; see `# Errors`.
2183        slice: get_int128s, Int128, i128, DataType::Int128
2184    }
2185
2186    impl_get_multi_values! {
2187        /// Get reference to all uint8 values
2188        ///
2189        /// # Returns
2190        ///
2191        /// If types match, returns a reference to the uint8 value array; see `# Errors`.
2192        slice: get_uint8s, UInt8, u8, DataType::UInt8
2193    }
2194
2195    impl_get_multi_values! {
2196        /// Get reference to all uint16 values
2197        ///
2198        /// # Returns
2199        ///
2200        /// If types match, returns a reference to the uint16 value array; see `# Errors`.
2201        slice: get_uint16s, UInt16, u16, DataType::UInt16
2202    }
2203
2204    impl_get_multi_values! {
2205        /// Get reference to all uint32 values
2206        ///
2207        /// # Returns
2208        ///
2209        /// If types match, returns a reference to the uint32 value array; see `# Errors`.
2210        slice: get_uint32s, UInt32, u32, DataType::UInt32
2211    }
2212
2213    impl_get_multi_values! {
2214        /// Get reference to all uint64 values
2215        ///
2216        /// # Returns
2217        ///
2218        /// If types match, returns a reference to the uint64 value array; see `# Errors`.
2219        slice: get_uint64s, UInt64, u64, DataType::UInt64
2220    }
2221
2222    impl_get_multi_values! {
2223        /// Get reference to all uint128 values
2224        ///
2225        /// # Returns
2226        ///
2227        /// If types match, returns a reference to the uint128 value array; see `# Errors`.
2228        slice: get_uint128s, UInt128, u128, DataType::UInt128
2229    }
2230
2231    impl_get_multi_values! {
2232        /// Get reference to all float32 values
2233        ///
2234        /// # Returns
2235        ///
2236        /// If types match, returns a reference to the float32 value array; see `# Errors`.
2237        slice: get_float32s, Float32, f32, DataType::Float32
2238    }
2239
2240    impl_get_multi_values! {
2241        /// Get reference to all float64 values
2242        ///
2243        /// # Returns
2244        ///
2245        /// If types match, returns a reference to the float64 value array; see `# Errors`.
2246        slice: get_float64s, Float64, f64, DataType::Float64
2247    }
2248
2249    impl_get_multi_values! {
2250        /// Get reference to all strings
2251        ///
2252        /// # Returns
2253        ///
2254        /// If types match, returns a reference to the string array; otherwise
2255        /// returns an error
2256        vec: get_strings, String, String, DataType::String
2257    }
2258
2259    impl_get_multi_values! {
2260        /// Get reference to all date values
2261        ///
2262        /// # Returns
2263        ///
2264        /// If types match, returns a reference to the date value array; see `# Errors`.
2265        #[cfg(feature = "chrono")]
2266        slice: get_dates, Date, NaiveDate, DataType::Date
2267    }
2268
2269    impl_get_multi_values! {
2270        /// Get reference to all time values
2271        ///
2272        /// # Returns
2273        ///
2274        /// If types match, returns a reference to the time value array; see `# Errors`.
2275        #[cfg(feature = "chrono")]
2276        slice: get_times, Time, NaiveTime, DataType::Time
2277    }
2278
2279    impl_get_multi_values! {
2280        /// Get reference to all datetime values
2281        ///
2282        /// # Returns
2283        ///
2284        /// If types match, returns a reference to the datetime value array; see `# Errors`.
2285        #[cfg(feature = "chrono")]
2286        slice: get_datetimes, DateTime, NaiveDateTime, DataType::DateTime
2287    }
2288
2289    impl_get_multi_values! {
2290        /// Get reference to all UTC instant values
2291        ///
2292        /// # Returns
2293        ///
2294        /// If types match, returns a reference to the UTC instant value array; see `# Errors`.
2295        #[cfg(feature = "chrono")]
2296        slice: get_instants, Instant, DateTime<Utc>, DataType::Instant
2297    }
2298
2299    impl_get_multi_values! {
2300        /// Get reference to all big integers
2301        ///
2302        /// # Returns
2303        ///
2304        /// If types match, returns a reference to the big integer array; see `# Errors`.
2305        #[cfg(feature = "big-integer")]
2306        vec: get_bigintegers, BigInteger, BigInt, DataType::BigInteger
2307    }
2308
2309    impl_get_multi_values! {
2310        /// Get reference to all big decimals
2311        ///
2312        /// # Returns
2313        ///
2314        /// If types match, returns a reference to the big decimal array; see `# Errors`.
2315        #[cfg(feature = "big-decimal")]
2316        vec: get_bigdecimals, BigDecimal, BigDecimal, DataType::BigDecimal
2317    }
2318
2319    impl_get_multi_values! {
2320        /// Get reference to all Duration values
2321        ///
2322        /// # Returns
2323        ///
2324        /// A slice containing all stored durations.
2325        slice: get_durations, Duration, Duration, DataType::Duration
2326    }
2327
2328    impl_get_multi_values! {
2329        /// Get reference to all Url values
2330        ///
2331        /// # Returns
2332        ///
2333        /// A reference to the vector containing all stored URLs.
2334        #[cfg(feature = "url")]
2335        vec: get_urls, Url, Url, DataType::Url
2336    }
2337
2338    impl_get_multi_values! {
2339        /// Get reference to all StringMap values
2340        ///
2341        /// # Returns
2342        ///
2343        /// A reference to the vector containing all stored string maps.
2344        vec: get_string_maps, StringMap, HashMap<String, String>, DataType::StringMap
2345    }
2346
2347    impl_get_multi_values! {
2348        /// Get reference to all Json values
2349        ///
2350        /// # Returns
2351        ///
2352        /// A reference to the vector containing all stored JSON values.
2353        #[cfg(feature = "json")]
2354        vec: get_jsons, Json, serde_json::Value, DataType::Json
2355    }
2356}