Skip to main content

qubit_value/multi_values/
multi_values_ref.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//! Borrowed semantic views for [`crate::MultiValues`].
10
11use qubit_datatype::DataType;
12
13use crate::ValueRef;
14
15/// Generates semantic views from the same closed table as owned storage.
16macro_rules! define_view {
17    (; $(([$($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)*)),+ $(,)?) => {
18        /// Borrowed semantic view preserving source types without owning payloads.
19        ///
20        /// The lifetime is that of the source storage; copying this view does
21        /// not clone strings, maps, JSON, or other rich payloads.
22        ///
23        /// # Type Parameters
24        ///
25        /// * `'a` - Lifetime of the source slices borrowed by this view.
26        ///
27        /// # Examples
28        ///
29        /// ```
30        /// use qubit_datatype::DataType;
31        /// use qubit_value::MultiValues;
32        ///
33        /// let values = MultiValues::Int32(vec![1, 2, 3]);
34        /// let view = values.view();
35        /// assert_eq!(view.data_type(), DataType::Int32);
36        /// assert_eq!(view.len(), 3);
37        /// ```
38        #[must_use]
39        #[non_exhaustive]
40        #[derive(Debug, Clone, Copy)]
41        pub enum MultiValuesRef<'a> {
42            /// Unset storage retaining its declared type.
43            Unset(#[doc = "Declared source type."] DataType),
44            $(
45                #[doc = $multi_doc]
46                $(#[$cfg])*
47                $(#[cfg_attr(docsrs, doc($cfg))])*
48                $variant(#[doc = "Borrowed or copied source payload."] &'a [$type]),
49            )+
50        }
51
52        impl<'a> MultiValuesRef<'a> {
53            /// Returns the element type, including for unset or empty storage.
54            ///
55            /// # Returns
56            ///
57            /// The declared runtime element type.
58            #[inline(always)]
59            pub fn data_type(self) -> DataType {
60                match self {
61                    Self::Unset(data_type) => data_type,
62                    $($(#[$cfg])* Self::$variant(_) => $data_type,)+
63                }
64            }
65
66            /// Returns the number of stored elements; unset storage has length zero.
67            ///
68            /// # Returns
69            ///
70            /// The number of concrete elements, or zero for unset storage.
71            #[must_use]
72            #[inline(always)]
73            pub fn len(self) -> usize {
74                match self {
75                    Self::Unset(_) => 0,
76                    $($(#[$cfg])* Self::$variant(values) => values.len(),)+
77                }
78            }
79
80            /// Reports whether no concrete elements are available.
81            ///
82            /// # Returns
83            ///
84            /// `true` for unset or empty storage; otherwise `false`.
85            #[must_use]
86            #[inline(always)]
87            pub fn is_empty(self) -> bool { self.len() == 0 }
88
89            /// Borrows the indexed element, returning None for unset or out-of-range reads.
90            ///
91            /// Numeric and boolean payloads are copied. Text and rich payloads
92            /// retain the original storage lifetime and are never cloned.
93            ///
94            /// # Parameters
95            ///
96            /// * `index` - Zero-based element position to borrow.
97            ///
98            /// # Returns
99            ///
100            /// `Some` with the indexed element, or `None` when storage is unset
101            /// or `index` is out of bounds.
102            #[must_use]
103            #[inline(always)]
104            pub fn get(self, index: usize) -> Option<ValueRef<'a>> {
105                match self {
106                    Self::Unset(_) => None,
107                    $($(#[$cfg])* Self::$variant(values) => values.get(index)
108                        .map(|value| ValueRef::$variant(value_view_payload!($variant, $number_projection, value))),)+
109                }
110            }
111        }
112
113    };
114}
115
116for_each_value_type!(define_view);