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.
10// qubit-style: allow multiple-public-types
11
12use crate::{
13    MultiValues,
14    Value,
15    ValueError,
16    ValueResult,
17};
18
19mod sealed {
20    use super::{
21        MultiValues,
22        Value,
23        ValueError,
24    };
25
26    pub trait Sealed {}
27
28    impl<T> Sealed for T
29    where
30        for<'a> T: TryFrom<&'a Value, Error = ValueError>
31            + TryFrom<&'a MultiValues, Error = ValueError>,
32        for<'a> Vec<T>: TryFrom<&'a MultiValues, Error = ValueError>,
33    {
34    }
35}
36
37/// Marks target types supported by exact, non-converting reads.
38///
39/// This trait is sealed because supported types are determined by the closed
40/// runtime [`qubit_datatype::DataType`] family. Domain conversions belong in
41/// explicit conversion boundaries, rather than changing strict-read semantics.
42pub trait StrictValueRead: Sized + sealed::Sealed {
43    /// Strictly reads a scalar runtime value.
44    #[doc(hidden)]
45    fn read_scalar(value: &Value) -> ValueResult<Self>;
46
47    /// Strictly reads the first item from a runtime collection.
48    #[doc(hidden)]
49    fn read_collection_first(values: &MultiValues) -> ValueResult<Self>;
50
51    /// Strictly reads every item from a runtime collection.
52    #[doc(hidden)]
53    fn read_collection_list(values: &MultiValues) -> ValueResult<Vec<Self>>;
54}
55
56impl<T> StrictValueRead for T
57where
58    for<'a> T: TryFrom<&'a Value, Error = ValueError>
59        + TryFrom<&'a MultiValues, Error = ValueError>,
60    for<'a> Vec<T>: TryFrom<&'a MultiValues, Error = ValueError>,
61{
62    #[inline(always)]
63    fn read_scalar(value: &Value) -> ValueResult<Self> {
64        value.get()
65    }
66
67    #[inline(always)]
68    fn read_collection_first(values: &MultiValues) -> ValueResult<Self> {
69        values.get_first()
70    }
71
72    #[inline(always)]
73    fn read_collection_list(values: &MultiValues) -> ValueResult<Vec<Self>> {
74        values.get()
75    }
76}