Skip to main content

qubit_value/
strict_value_read.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//! Sealed public bound for strict reads from runtime value storage.
10use crate::MultiValues;
11use crate::Value;
12use crate::ValueError;
13use crate::ValueResult;
14
15mod internal;
16
17use self::internal::sealed::Sealed;
18
19/// Marks target types supported by exact, non-converting reads.
20///
21/// This trait is sealed because supported types are determined by the closed
22/// runtime [`qubit_datatype::DataType`] family. Domain conversions belong in
23/// explicit conversion boundaries, rather than changing strict-read semantics.
24///
25/// # Examples
26///
27/// ```
28/// use qubit_value::{StrictValueRead, Value, ValueResult};
29///
30/// fn read_exact<T: StrictValueRead>(value: &Value) -> ValueResult<T> {
31///     T::read_scalar(value)
32/// }
33///
34/// assert_eq!(read_exact::<i32>(&Value::from(42_i32)).unwrap(), 42);
35/// ```
36pub trait StrictValueRead: Sized + Sealed {
37    /// Strictly reads a scalar runtime value.
38    ///
39    /// # Parameters
40    ///
41    /// * `value` - Scalar runtime value to read without conversion.
42    ///
43    /// # Returns
44    ///
45    /// The exact stored scalar represented as `Self`.
46    ///
47    /// # Errors
48    ///
49    /// Returns [`ValueError::Missing`] for unset storage or
50    /// [`ValueError::TypeMismatch`] for a different runtime type.
51    #[doc(hidden)]
52    fn read_scalar(value: &Value) -> ValueResult<Self>;
53
54    /// Strictly reads the first item from a runtime collection.
55    ///
56    /// # Parameters
57    ///
58    /// * `values` - Runtime collection whose first item is read exactly.
59    ///
60    /// # Returns
61    ///
62    /// The first stored element represented as `Self`.
63    ///
64    /// # Errors
65    ///
66    /// Returns [`ValueError::Missing`] for unset or empty storage, or
67    /// [`ValueError::TypeMismatch`] for a different element type.
68    #[doc(hidden)]
69    fn read_collection_first(values: &MultiValues) -> ValueResult<Self>;
70
71    /// Strictly reads every item from a runtime collection.
72    ///
73    /// # Parameters
74    ///
75    /// * `values` - Runtime collection whose elements are cloned exactly.
76    ///
77    /// # Returns
78    ///
79    /// Every stored element in original order.
80    ///
81    /// # Errors
82    ///
83    /// Returns [`ValueError::Missing`] for unset storage or
84    /// [`ValueError::TypeMismatch`] for a different element type.
85    #[doc(hidden)]
86    fn read_collection_list(values: &MultiValues) -> ValueResult<Vec<Self>>;
87}
88
89impl<T> StrictValueRead for T
90where
91    for<'a> T: TryFrom<&'a Value, Error = ValueError> + TryFrom<&'a MultiValues, Error = ValueError>,
92    for<'a> Vec<T>: TryFrom<&'a MultiValues, Error = ValueError>,
93{
94    /// Delegates to the scalar's strict conversion without consuming its
95    /// storage.
96    ///
97    /// # Parameters
98    ///
99    /// * `value` - Borrowed scalar storage to read without type conversion.
100    ///
101    /// # Returns
102    ///
103    /// An owned value of the exact stored type.
104    ///
105    /// # Errors
106    ///
107    /// Propagates missing-storage and type-mismatch errors from the strict
108    /// read.
109    #[inline(always)]
110    fn read_scalar(value: &Value) -> ValueResult<Self> {
111        value.get()
112    }
113
114    /// Delegates to the strict first-element conversion, preserving the
115    /// collection.
116    ///
117    /// # Parameters
118    ///
119    /// * `values` - Borrowed collection whose first element is read exactly.
120    ///
121    /// # Returns
122    ///
123    /// An owned copy or clone of the first stored element.
124    ///
125    /// # Errors
126    ///
127    /// Propagates missing-storage, empty-collection, and type-mismatch errors.
128    #[inline(always)]
129    fn read_collection_first(values: &MultiValues) -> ValueResult<Self> {
130        Self::try_from(values)
131    }
132
133    /// Delegates to the strict list conversion, cloning elements in stored
134    /// order.
135    ///
136    /// # Parameters
137    ///
138    /// * `values` - Borrowed collection to read without element conversion.
139    ///
140    /// # Returns
141    ///
142    /// An owned vector containing every stored element in its original order.
143    ///
144    /// # Errors
145    ///
146    /// Propagates missing-storage and element-type-mismatch errors.
147    #[inline(always)]
148    fn read_collection_list(values: &MultiValues) -> ValueResult<Vec<Self>> {
149        values.get()
150    }
151}