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);