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        #[must_use]
23        #[non_exhaustive]
24        #[derive(Debug, Clone, Copy)]
25        pub enum MultiValuesRef<'a> {
26            /// Unset storage retaining its declared type.
27            Unset(#[doc = "Declared source type."] DataType),
28            $(
29                $(#[$cfg])*
30                #[doc = $multi_doc]
31                $variant(#[doc = "Borrowed or copied source payload."] &'a [$type]),
32            )+
33        }
34
35        impl<'a> MultiValuesRef<'a> {
36            /// Returns the element type, including for unset or empty storage.
37            ///
38            /// # Returns
39            ///
40            /// The declared runtime element type.
41            #[must_use = "the declared element type should be inspected"]
42            #[inline(always)]
43            pub fn data_type(self) -> DataType {
44                match self {
45                    Self::Unset(data_type) => data_type,
46                    $($(#[$cfg])* Self::$variant(_) => $data_type,)+
47                }
48            }
49
50            /// Returns the number of stored elements; unset storage has length zero.
51            ///
52            /// # Returns
53            ///
54            /// The number of concrete elements, or zero for unset storage.
55            #[must_use]
56            #[inline(always)]
57            pub fn len(self) -> usize {
58                match self {
59                    Self::Unset(_) => 0,
60                    $($(#[$cfg])* Self::$variant(values) => values.len(),)+
61                }
62            }
63
64            /// Reports whether no concrete elements are available.
65            ///
66            /// # Returns
67            ///
68            /// `true` for unset or empty storage; otherwise `false`.
69            #[must_use]
70            #[inline(always)]
71            pub fn is_empty(self) -> bool { self.len() == 0 }
72
73            /// Borrows the indexed element, returning None for unset or out-of-range reads.
74            ///
75            /// Numeric and boolean payloads are copied. Text and rich payloads
76            /// retain the original storage lifetime and are never cloned.
77            ///
78            /// # Parameters
79            ///
80            /// * `index` - Zero-based element position to borrow.
81            ///
82            /// # Returns
83            ///
84            /// `Some` with the indexed element, or `None` when storage is unset
85            /// or `index` is out of bounds.
86            #[must_use]
87            #[inline(always)]
88            pub fn get(self, index: usize) -> Option<ValueRef<'a>> {
89                match self {
90                    Self::Unset(_) => None,
91                    $($(#[$cfg])* Self::$variant(values) => values.get(index)
92                        .map(|value| ValueRef::$variant(value_view_payload!($variant, $number_projection, value))),)+
93                }
94            }
95        }
96
97    };
98}
99
100for_each_value_type!(define_view);