Skip to main content

qubit_value/multi_values/
multi_values_getters.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//! Type-specific read accessors for `MultiValues`.
10
11use std::collections::HashMap;
12use std::time::Duration;
13
14#[cfg(feature = "big-decimal")]
15use bigdecimal::BigDecimal;
16#[cfg(feature = "chrono")]
17use chrono::{
18    DateTime,
19    NaiveDate,
20    NaiveDateTime,
21    NaiveTime,
22    Utc,
23};
24#[cfg(feature = "big-integer")]
25use num_bigint::BigInt;
26#[cfg(feature = "url")]
27use url::Url;
28
29use qubit_datatype::DataType;
30
31use crate::value_error::{
32    ValueError,
33    ValueResult,
34};
35
36use super::multi_values::{
37    MultiValues,
38    MultiValuesRepr,
39};
40
41impl MultiValues {
42    // ========================================================================
43    // Get first value (as single value access)
44    // ========================================================================
45
46    impl_get_first_value! {
47        /// Get the first boolean value.
48        ///
49        /// # Returns
50        ///
51        /// If types match and a value exists, returns the first boolean value; see `# Errors`.
52        ///
53        /// # Examples
54        ///
55        /// ```rust
56        /// use qubit_value::MultiValues;
57        ///
58        /// let values = MultiValues::Bool(vec![true, false]);
59        /// assert_eq!(values.get_first_bool().unwrap(), true);
60        /// ```
61        copy: get_first_bool, Bool, bool, DataType::Bool
62    }
63
64    impl_get_first_value! {
65        /// Get the first character value
66        ///
67        /// # Returns
68        ///
69        /// If types match and a value exists, returns the first character value; see `# Errors`.
70        copy: get_first_char, Char, char, DataType::Char
71    }
72
73    impl_get_first_value! {
74        /// Get the first int8 value
75        ///
76        /// # Returns
77        ///
78        /// If types match and a value exists, returns the first int8 value; see `# Errors`.
79        copy: get_first_int8, Int8, i8, DataType::Int8
80    }
81
82    impl_get_first_value! {
83        /// Get the first int16 value
84        ///
85        /// # Returns
86        ///
87        /// If types match and a value exists, returns the first int16 value; see `# Errors`.
88        copy: get_first_int16, Int16, i16, DataType::Int16
89    }
90
91    impl_get_first_value! {
92        /// Get the first int32 value
93        ///
94        /// # Returns
95        ///
96        /// If types match and a value exists, returns the first int32 value; see `# Errors`.
97        copy: get_first_int32, Int32, i32, DataType::Int32
98    }
99
100    impl_get_first_value! {
101        /// Get the first int64 value
102        ///
103        /// # Returns
104        ///
105        /// If types match and a value exists, returns the first int64 value; see `# Errors`.
106        copy: get_first_int64, Int64, i64, DataType::Int64
107    }
108
109    impl_get_first_value! {
110        /// Get the first int128 value
111        ///
112        /// # Returns
113        ///
114        /// If types match and a value exists, returns the first int128 value; see `# Errors`.
115        copy: get_first_int128, Int128, i128, DataType::Int128
116    }
117
118    impl_get_first_value! {
119        /// Get the first uint8 value
120        ///
121        /// # Returns
122        ///
123        /// If types match and a value exists, returns the first uint8 value; see `# Errors`.
124        copy: get_first_uint8, UInt8, u8, DataType::UInt8
125    }
126
127    impl_get_first_value! {
128        /// Get the first uint16 value
129        ///
130        /// # Returns
131        ///
132        /// If types match and a value exists, returns the first uint16 value; see `# Errors`.
133        copy: get_first_uint16, UInt16, u16, DataType::UInt16
134    }
135
136    impl_get_first_value! {
137        /// Get the first uint32 value
138        ///
139        /// # Returns
140        ///
141        /// If types match and a value exists, returns the first uint32 value; see `# Errors`.
142        copy: get_first_uint32, UInt32, u32, DataType::UInt32
143    }
144
145    impl_get_first_value! {
146        /// Get the first uint64 value
147        ///
148        /// # Returns
149        ///
150        /// If types match and a value exists, returns the first uint64 value; see `# Errors`.
151        copy: get_first_uint64, UInt64, u64, DataType::UInt64
152    }
153
154    impl_get_first_value! {
155        /// Get the first uint128 value
156        ///
157        /// # Returns
158        ///
159        /// If types match and a value exists, returns the first uint128 value; see `# Errors`.
160        copy: get_first_uint128, UInt128, u128, DataType::UInt128
161    }
162
163    impl_get_first_value! {
164        /// Get the first float32 value
165        ///
166        /// # Returns
167        ///
168        /// If types match and a value exists, returns the first float32 value; see `# Errors`.
169        copy: get_first_float32, Float32, f32, DataType::Float32
170    }
171
172    impl_get_first_value! {
173        /// Get the first float64 value
174        ///
175        /// # Returns
176        ///
177        /// If types match and a value exists, returns the first float64 value; see `# Errors`.
178        copy: get_first_float64, Float64, f64, DataType::Float64
179    }
180
181    impl_get_first_value! {
182        /// Get the first string reference
183        ///
184        /// # Returns
185        ///
186        /// If types match and a value exists, returns a reference to the first
187        /// string; see `# Errors`.
188        ref: get_first_string, String, &str, DataType::String, |s: &String| s.as_str()
189    }
190
191    impl_get_first_value! {
192        /// Get the first date value
193        ///
194        /// # Returns
195        ///
196        /// If types match and a value exists, returns the first date value; see `# Errors`.
197        #[cfg(feature = "chrono")]
198        copy: get_first_date, Date, NaiveDate, DataType::Date
199    }
200
201    impl_get_first_value! {
202        /// Get the first time value
203        ///
204        /// # Returns
205        ///
206        /// If types match and a value exists, returns the first time value; see `# Errors`.
207        #[cfg(feature = "chrono")]
208        copy: get_first_time, Time, NaiveTime, DataType::Time
209    }
210
211    impl_get_first_value! {
212        /// Get the first datetime value
213        ///
214        /// # Returns
215        ///
216        /// If types match and a value exists, returns the first datetime value; see `# Errors`.
217        #[cfg(feature = "chrono")]
218        copy: get_first_datetime, DateTime, NaiveDateTime, DataType::DateTime
219    }
220
221    impl_get_first_value! {
222        /// Get the first UTC instant value
223        ///
224        /// # Returns
225        ///
226        /// If types match and a value exists, returns the first UTC instant
227        /// value; see `# Errors`.
228        #[cfg(feature = "chrono")]
229        copy: get_first_instant, Instant, DateTime<Utc>, DataType::Instant
230    }
231
232    impl_get_first_value! {
233        /// Get the first big integer value
234        ///
235        /// # Returns
236        ///
237        /// If types match and a value exists, returns the first big integer
238        /// value; see `# Errors`.
239        #[cfg(feature = "big-integer")]
240        ref: get_first_biginteger, BigInteger, BigInt, DataType::BigInteger, |v: &BigInt| v.clone()
241    }
242
243    impl_get_first_value! {
244        /// Get the first big decimal value
245        ///
246        /// # Returns
247        ///
248        /// If types match and a value exists, returns the first big decimal
249        /// value; see `# Errors`.
250        #[cfg(feature = "big-decimal")]
251        ref: get_first_bigdecimal, BigDecimal, BigDecimal, DataType::BigDecimal, |v: &BigDecimal| v.clone()
252    }
253
254    impl_get_first_value! {
255        /// Get the first Duration value
256        ///
257        /// # Returns
258        ///
259        /// The first duration when the stored type matches.
260        copy: get_first_duration, Duration, Duration, DataType::Duration
261    }
262
263    impl_get_first_value! {
264        /// Get the first Url value
265        ///
266        /// # Returns
267        ///
268        /// A clone of the first URL when the stored type matches.
269        #[cfg(feature = "url")]
270        ref: get_first_url, Url, Url, DataType::Url, |v: &Url| v.clone()
271    }
272
273    impl_get_first_value! {
274        /// Get the first StringMap value
275        ///
276        /// # Returns
277        ///
278        /// A clone of the first string map when the stored type matches.
279        ref: get_first_string_map, StringMap, HashMap<String, String>, DataType::StringMap, |v: &HashMap<String, String>| v.clone()
280    }
281
282    impl_get_first_value! {
283        /// Get the first Json value
284        ///
285        /// # Returns
286        ///
287        /// A clone of the first JSON value when the stored type matches.
288        #[cfg(feature = "json")]
289        ref: get_first_json, Json, serde_json::Value, DataType::Json, |v: &serde_json::Value| v.clone()
290    }
291
292    // ========================================================================
293    // Get all values (type checking)
294    // ========================================================================
295
296    impl_get_multi_values! {
297        /// Get reference to all boolean values
298        ///
299        /// # Returns
300        ///
301        /// If types match, returns a reference to the boolean value array; see `# Errors`.
302        ///
303        /// # Examples
304        ///
305        /// ```rust
306        /// use qubit_value::MultiValues;
307        ///
308        /// let values = MultiValues::Bool(vec![true, false, true]);
309        /// assert_eq!(values.get_bools().unwrap(), &[true, false, true]);
310        /// ```
311        slice: get_bools, Bool, bool, DataType::Bool
312    }
313
314    impl_get_multi_values! {
315        /// Get reference to all character values
316        ///
317        /// # Returns
318        ///
319        /// If types match, returns a reference to the character value array; see `# Errors`.
320        slice: get_chars, Char, char, DataType::Char
321    }
322
323    impl_get_multi_values! {
324        /// Get reference to all int8 values
325        ///
326        /// # Returns
327        ///
328        /// If types match, returns a reference to the int8 value array; see `# Errors`.
329        slice: get_int8s, Int8, i8, DataType::Int8
330    }
331
332    impl_get_multi_values! {
333        /// Get reference to all int16 values
334        ///
335        /// # Returns
336        ///
337        /// If types match, returns a reference to the int16 value array; see `# Errors`.
338        slice: get_int16s, Int16, i16, DataType::Int16
339    }
340
341    impl_get_multi_values! {
342        /// Get reference to all int32 values
343        ///
344        /// # Returns
345        ///
346        /// If types match, returns a reference to the int32 value array; see `# Errors`.
347        slice: get_int32s, Int32, i32, DataType::Int32
348    }
349
350    impl_get_multi_values! {
351        /// Get reference to all int64 values
352        ///
353        /// # Returns
354        ///
355        /// If types match, returns a reference to the int64 value array; see `# Errors`.
356        slice: get_int64s, Int64, i64, DataType::Int64
357    }
358
359    impl_get_multi_values! {
360        /// Get reference to all int128 values
361        ///
362        /// # Returns
363        ///
364        /// If types match, returns a reference to the int128 value array; see `# Errors`.
365        slice: get_int128s, Int128, i128, DataType::Int128
366    }
367
368    impl_get_multi_values! {
369        /// Get reference to all uint8 values
370        ///
371        /// # Returns
372        ///
373        /// If types match, returns a reference to the uint8 value array; see `# Errors`.
374        slice: get_uint8s, UInt8, u8, DataType::UInt8
375    }
376
377    impl_get_multi_values! {
378        /// Get reference to all uint16 values
379        ///
380        /// # Returns
381        ///
382        /// If types match, returns a reference to the uint16 value array; see `# Errors`.
383        slice: get_uint16s, UInt16, u16, DataType::UInt16
384    }
385
386    impl_get_multi_values! {
387        /// Get reference to all uint32 values
388        ///
389        /// # Returns
390        ///
391        /// If types match, returns a reference to the uint32 value array; see `# Errors`.
392        slice: get_uint32s, UInt32, u32, DataType::UInt32
393    }
394
395    impl_get_multi_values! {
396        /// Get reference to all uint64 values
397        ///
398        /// # Returns
399        ///
400        /// If types match, returns a reference to the uint64 value array; see `# Errors`.
401        slice: get_uint64s, UInt64, u64, DataType::UInt64
402    }
403
404    impl_get_multi_values! {
405        /// Get reference to all uint128 values
406        ///
407        /// # Returns
408        ///
409        /// If types match, returns a reference to the uint128 value array; see `# Errors`.
410        slice: get_uint128s, UInt128, u128, DataType::UInt128
411    }
412
413    impl_get_multi_values! {
414        /// Get reference to all float32 values
415        ///
416        /// # Returns
417        ///
418        /// If types match, returns a reference to the float32 value array; see `# Errors`.
419        slice: get_float32s, Float32, f32, DataType::Float32
420    }
421
422    impl_get_multi_values! {
423        /// Get reference to all float64 values
424        ///
425        /// # Returns
426        ///
427        /// If types match, returns a reference to the float64 value array; see `# Errors`.
428        slice: get_float64s, Float64, f64, DataType::Float64
429    }
430
431    impl_get_multi_values! {
432        /// Get reference to all strings
433        ///
434        /// # Returns
435        ///
436        /// If types match, returns a reference to the string array; otherwise
437        /// returns an error
438        vec: get_strings, String, String, DataType::String
439    }
440
441    impl_get_multi_values! {
442        /// Get reference to all date values
443        ///
444        /// # Returns
445        ///
446        /// If types match, returns a reference to the date value array; see `# Errors`.
447        #[cfg(feature = "chrono")]
448        slice: get_dates, Date, NaiveDate, DataType::Date
449    }
450
451    impl_get_multi_values! {
452        /// Get reference to all time values
453        ///
454        /// # Returns
455        ///
456        /// If types match, returns a reference to the time value array; see `# Errors`.
457        #[cfg(feature = "chrono")]
458        slice: get_times, Time, NaiveTime, DataType::Time
459    }
460
461    impl_get_multi_values! {
462        /// Get reference to all datetime values
463        ///
464        /// # Returns
465        ///
466        /// If types match, returns a reference to the datetime value array; see `# Errors`.
467        #[cfg(feature = "chrono")]
468        slice: get_datetimes, DateTime, NaiveDateTime, DataType::DateTime
469    }
470
471    impl_get_multi_values! {
472        /// Get reference to all UTC instant values
473        ///
474        /// # Returns
475        ///
476        /// If types match, returns a reference to the UTC instant value array; see `# Errors`.
477        #[cfg(feature = "chrono")]
478        slice: get_instants, Instant, DateTime<Utc>, DataType::Instant
479    }
480
481    impl_get_multi_values! {
482        /// Get reference to all big integers
483        ///
484        /// # Returns
485        ///
486        /// If types match, returns a reference to the big integer array; see `# Errors`.
487        #[cfg(feature = "big-integer")]
488        vec: get_bigintegers, BigInteger, BigInt, DataType::BigInteger
489    }
490
491    impl_get_multi_values! {
492        /// Get reference to all big decimals
493        ///
494        /// # Returns
495        ///
496        /// If types match, returns a reference to the big decimal array; see `# Errors`.
497        #[cfg(feature = "big-decimal")]
498        vec: get_bigdecimals, BigDecimal, BigDecimal, DataType::BigDecimal
499    }
500
501    impl_get_multi_values! {
502        /// Get reference to all Duration values
503        ///
504        /// # Returns
505        ///
506        /// A slice containing all stored durations.
507        slice: get_durations, Duration, Duration, DataType::Duration
508    }
509
510    impl_get_multi_values! {
511        /// Get reference to all Url values
512        ///
513        /// # Returns
514        ///
515        /// A reference to the vector containing all stored URLs.
516        #[cfg(feature = "url")]
517        vec: get_urls, Url, Url, DataType::Url
518    }
519
520    impl_get_multi_values! {
521        /// Get reference to all StringMap values
522        ///
523        /// # Returns
524        ///
525        /// A reference to the vector containing all stored string maps.
526        vec: get_string_maps, StringMap, HashMap<String, String>, DataType::StringMap
527    }
528
529    impl_get_multi_values! {
530        /// Get reference to all Json values
531        ///
532        /// # Returns
533        ///
534        /// A reference to the vector containing all stored JSON values.
535        #[cfg(feature = "json")]
536        vec: get_jsons, Json, serde_json::Value, DataType::Json
537    }
538}