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}