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