Skip to main content

qubit_value/multi_values/
multi_values_first_getter.rs

1/*******************************************************************************
2 *
3 *    Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 *    SPDX-License-Identifier: Apache-2.0
6 *
7 *    Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10
11//! Internal first-value getter trait implementations for `MultiValues`.
12
13use std::collections::HashMap;
14use std::time::Duration;
15
16use bigdecimal::BigDecimal;
17use chrono::{
18    DateTime,
19    NaiveDate,
20    NaiveDateTime,
21    NaiveTime,
22    Utc,
23};
24use num_bigint::BigInt;
25use url::Url;
26
27use crate::value_error::{
28    ValueError,
29    ValueResult,
30};
31
32use super::multi_values::MultiValues;
33use qubit_datatype::DataType;
34
35/// Internal trait used to extract the first value from `MultiValues`.
36///
37/// This trait backs `MultiValues::get_first<T>()`; downstream code should call
38/// the inherent method instead of implementing or naming this trait directly.
39pub trait MultiValuesFirstGetter<T>: super::sealed::MultiValuesFirstGetterSealed<T> {
40    /// Gets the first stored value as `T`.
41    ///
42    /// # Returns
43    ///
44    /// Returns the first value when present and typed as `T`, or a `ValueError`
45    /// describing the missing value or mismatch.
46    fn get_first_value(&self) -> ValueResult<T>;
47}
48
49macro_rules! impl_multi_values_first_getter {
50    ($type:ty, $variant:ident, $data_type:expr) => {
51        impl super::sealed::MultiValuesFirstGetterSealed<$type> for MultiValues {}
52
53        impl MultiValuesFirstGetter<$type> for MultiValues {
54            #[inline]
55            fn get_first_value(&self) -> ValueResult<$type> {
56                match self {
57                    MultiValues::$variant(v) if !v.is_empty() => Ok(v[0].clone()),
58                    MultiValues::$variant(_) => Err(ValueError::NoValue),
59                    MultiValues::Empty(dt) if *dt == $data_type => Err(ValueError::NoValue),
60                    _ => Err(ValueError::TypeMismatch {
61                        expected: $data_type,
62                        actual: self.data_type(),
63                    }),
64                }
65            }
66        }
67    };
68}
69
70impl_multi_values_first_getter!(bool, Bool, DataType::Bool);
71impl_multi_values_first_getter!(char, Char, DataType::Char);
72impl_multi_values_first_getter!(i8, Int8, DataType::Int8);
73impl_multi_values_first_getter!(i16, Int16, DataType::Int16);
74impl_multi_values_first_getter!(i32, Int32, DataType::Int32);
75impl_multi_values_first_getter!(i64, Int64, DataType::Int64);
76impl_multi_values_first_getter!(i128, Int128, DataType::Int128);
77impl_multi_values_first_getter!(u8, UInt8, DataType::UInt8);
78impl_multi_values_first_getter!(u16, UInt16, DataType::UInt16);
79impl_multi_values_first_getter!(u32, UInt32, DataType::UInt32);
80impl_multi_values_first_getter!(u64, UInt64, DataType::UInt64);
81impl_multi_values_first_getter!(u128, UInt128, DataType::UInt128);
82impl_multi_values_first_getter!(f32, Float32, DataType::Float32);
83impl_multi_values_first_getter!(f64, Float64, DataType::Float64);
84impl_multi_values_first_getter!(String, String, DataType::String);
85impl_multi_values_first_getter!(NaiveDate, Date, DataType::Date);
86impl_multi_values_first_getter!(NaiveTime, Time, DataType::Time);
87impl_multi_values_first_getter!(NaiveDateTime, DateTime, DataType::DateTime);
88impl_multi_values_first_getter!(DateTime<Utc>, Instant, DataType::Instant);
89impl_multi_values_first_getter!(BigInt, BigInteger, DataType::BigInteger);
90impl_multi_values_first_getter!(BigDecimal, BigDecimal, DataType::BigDecimal);
91impl_multi_values_first_getter!(isize, IntSize, DataType::IntSize);
92impl_multi_values_first_getter!(usize, UIntSize, DataType::UIntSize);
93impl_multi_values_first_getter!(Duration, Duration, DataType::Duration);
94impl_multi_values_first_getter!(Url, Url, DataType::Url);
95impl_multi_values_first_getter!(HashMap<String, String>, StringMap, DataType::StringMap);
96impl_multi_values_first_getter!(serde_json::Value, Json, DataType::Json);