Skip to main content

qubit_value/multi_values/
multi_values_getter.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//! `TryFrom<&MultiValues>` implementations for strict typed reads.
10
11use super::multi_values::{
12    MultiValues,
13    MultiValuesRepr,
14};
15use crate::ValueMissing;
16use crate::value_error::{
17    ValueError,
18    ValueResult,
19};
20
21macro_rules! impl_multi_values_try_from_table {
22    (
23        ;
24        $(
25            (
26                [$($cfg:meta),*],
27                $variant:ident,
28                $type:ty,
29                $data_type:expr,
30                $materialization:ident,
31                $json_class:ident,
32                $number_projection:ident,
33                $value_doc:literal,
34                $multi_doc:literal
35            )
36        ),+ $(,)?
37    ) => {
38        $(
39            $(#[$cfg])*
40            impl TryFrom<&MultiValues> for $type {
41                type Error = ValueError;
42
43                #[inline(always)]
44                fn try_from(values: &MultiValues) -> ValueResult<$type> {
45                    match &values.repr {
46                        MultiValuesRepr::$variant(values) => values
47                            .first()
48                            .map(|value| materialize_stored!($materialization, value))
49                            .ok_or(ValueError::Missing(ValueMissing::EmptyCollection {
50                                data_type: $data_type,
51                            })),
52                        MultiValuesRepr::Unset(actual) if *actual == $data_type => {
53                            Err(ValueError::Missing(ValueMissing::UnsetCollection {
54                                data_type: *actual,
55                            }))
56                        }
57                        _ => Err(ValueError::TypeMismatch {
58                            expected: $data_type,
59                            actual: values.data_type(),
60                        }),
61                    }
62                }
63            }
64
65            $(#[$cfg])*
66            impl TryFrom<&MultiValues> for Vec<$type> {
67                type Error = ValueError;
68
69                #[inline(always)]
70                fn try_from(values: &MultiValues) -> ValueResult<Vec<$type>> {
71                    match &values.repr {
72                        MultiValuesRepr::$variant(values) => Ok(values
73                            .iter()
74                            .map(|value| materialize_stored!($materialization, value))
75                            .collect()),
76                        MultiValuesRepr::Unset(actual) if *actual == $data_type => {
77                            Err(ValueError::Missing(ValueMissing::UnsetCollection {
78                                data_type: *actual,
79                            }))
80                        }
81                        _ => Err(ValueError::TypeMismatch {
82                            expected: $data_type,
83                            actual: values.data_type(),
84                        }),
85                    }
86                }
87            }
88        )+
89    };
90}
91
92for_each_value_type!(impl_multi_values_try_from_table);