qubit_value/value.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026.
4 * Haixing Hu, Qubit Co. Ltd.
5 *
6 * All rights reserved.
7 *
8 ******************************************************************************/
9//! # Single Value Container
10//!
11//! Provides type-safe storage and access functionality for single values.
12//!
13//! # Author
14//!
15//! Haixing Hu
16
17use bigdecimal::BigDecimal;
18use chrono::{DateTime, NaiveDate, NaiveDateTime, NaiveTime, Utc};
19use num_bigint::BigInt;
20use num_traits::ToPrimitive;
21use serde::de::DeserializeOwned;
22use serde::{Deserialize, Serialize};
23use std::collections::HashMap;
24use std::time::Duration;
25use url::Url;
26
27use qubit_common::lang::DataType;
28use qubit_common::lang::argument::NumericArgument;
29
30use super::error::{ValueError, ValueResult};
31
32/// Single value container
33///
34/// Uses an enum to represent different types of values, providing
35/// type-safe value storage and access.
36///
37/// # Features
38///
39/// - Zero-cost abstraction with compile-time type checking
40/// - Supports multiple basic data types
41/// - Provides two sets of APIs for type checking and type conversion
42/// - Automatic memory management
43///
44/// # Example
45///
46/// ```rust
47/// use qubit_value::Value;
48///
49/// // Create an integer value
50/// let value = Value::Int32(42);
51/// assert_eq!(value.get_int32().unwrap(), 42);
52///
53/// // Type conversion
54/// let converted = value.to::<i64>().unwrap();
55/// assert_eq!(converted, 42i64);
56///
57/// // String value
58/// let text = Value::String("hello".to_string());
59/// assert_eq!(text.get_string().unwrap(), "hello");
60/// ```
61///
62/// # Author
63///
64/// Haixing Hu
65///
66#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
67pub enum Value {
68 /// Empty value (has type but no value)
69 Empty(DataType),
70 /// Boolean value
71 Bool(bool),
72 /// Character value
73 Char(char),
74 /// 8-bit signed integer
75 Int8(i8),
76 /// 16-bit signed integer
77 Int16(i16),
78 /// 32-bit signed integer
79 Int32(i32),
80 /// 64-bit signed integer
81 Int64(i64),
82 /// 128-bit signed integer
83 Int128(i128),
84 /// 8-bit unsigned integer
85 UInt8(u8),
86 /// 16-bit unsigned integer
87 UInt16(u16),
88 /// 32-bit unsigned integer
89 UInt32(u32),
90 /// 64-bit unsigned integer
91 UInt64(u64),
92 /// 128-bit unsigned integer
93 UInt128(u128),
94 /// Platform-dependent signed integer (isize)
95 IntSize(isize),
96 /// Platform-dependent unsigned integer (usize)
97 UIntSize(usize),
98 /// 32-bit floating point number
99 Float32(f32),
100 /// 64-bit floating point number
101 Float64(f64),
102 /// Big integer type
103 BigInteger(BigInt),
104 /// Big decimal type
105 BigDecimal(BigDecimal),
106 /// String
107 String(String),
108 /// Date
109 Date(NaiveDate),
110 /// Time
111 Time(NaiveTime),
112 /// Date and time
113 DateTime(NaiveDateTime),
114 /// UTC instant
115 Instant(DateTime<Utc>),
116 /// Duration type (std::time::Duration)
117 Duration(Duration),
118 /// URL type (url::Url)
119 Url(Url),
120 /// String map type (HashMap<String, String>)
121 StringMap(HashMap<String, String>),
122 /// JSON value type (serde_json::Value)
123 Json(serde_json::Value),
124}
125
126// ============================================================================
127// Getter method generation macro
128// ============================================================================
129
130/// Unified getter generation macro
131///
132/// Supports two modes:
133/// 1. `copy:` - For types implementing the Copy trait, directly returns the value
134/// 2. `ref:` - For non-Copy types, returns a reference
135///
136/// # Documentation Comment Support
137///
138/// The macro automatically extracts preceding documentation comments, so
139/// you can add `///` comments before macro invocations.
140///
141/// # Author
142///
143/// Haixing Hu
144///
145macro_rules! impl_get_value {
146 // Copy type: directly dereference and return
147 ($(#[$attr:meta])* copy: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
148 $(#[$attr])*
149 #[inline]
150 pub fn $method(&self) -> ValueResult<$type> {
151 match self {
152 Value::$variant(v) => Ok(*v),
153 Value::Empty(_) => Err(ValueError::NoValue),
154 _ => Err(ValueError::TypeMismatch {
155 expected: $data_type,
156 actual: self.data_type(),
157 }),
158 }
159 }
160 };
161
162 // Reference type: use conversion function to return reference,
163 // fixing lifetime issues
164 ($(#[$attr:meta])* ref: $method:ident, $variant:ident, $ret_type:ty, $data_type:expr, $conversion:expr) => {
165 $(#[$attr])*
166 #[inline]
167 pub fn $method(&self) -> ValueResult<$ret_type> {
168 match self {
169 Value::$variant(v) => {
170 let conv_fn: fn(&_) -> $ret_type = $conversion;
171 Ok(conv_fn(v))
172 },
173 Value::Empty(_) => Err(ValueError::NoValue),
174 _ => Err(ValueError::TypeMismatch {
175 expected: $data_type,
176 actual: self.data_type(),
177 }),
178 }
179 }
180 };
181}
182
183/// Unified setter generation macro
184///
185/// Supports two modes:
186/// 1. `copy:` - For types implementing the Copy trait, directly sets the value
187/// 2. `owned:` - For non-Copy types, requires owning the value
188///
189/// # Documentation Comment Support
190///
191/// The macro automatically extracts preceding documentation comments, so
192/// you can add `///` comments before macro invocations.
193///
194/// # Author
195///
196/// Haixing Hu
197///
198macro_rules! impl_set_value {
199 // Copy type: directly set the value
200 ($(#[$attr:meta])* copy: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
201 $(#[$attr])*
202 #[inline]
203 pub fn $method(&mut self, value: $type) -> ValueResult<()> {
204 *self = Value::$variant(value);
205 Ok(())
206 }
207 };
208
209 // Owned type: set the owned value
210 ($(#[$attr:meta])* owned: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
211 $(#[$attr])*
212 #[inline]
213 pub fn $method(&mut self, value: $type) -> ValueResult<()> {
214 *self = Value::$variant(value);
215 Ok(())
216 }
217 };
218}
219
220impl Value {
221 /// Generic constructor method
222 ///
223 /// Creates a `Value` from any supported type, avoiding direct use of
224 /// enum variants.
225 ///
226 /// # Supported Generic Types
227 ///
228 /// `Value::new<T>(value)` currently supports the following `T`:
229 ///
230 /// - `bool`
231 /// - `char`
232 /// - `i8`, `i16`, `i32`, `i64`, `i128`
233 /// - `u8`, `u16`, `u32`, `u64`, `u128`
234 /// - `f32`, `f64`
235 /// - `String`, `&str`
236 /// - `NaiveDate`, `NaiveTime`, `NaiveDateTime`, `DateTime<Utc>`
237 /// - `BigInt`, `BigDecimal`
238 /// - `isize`, `usize`
239 /// - `Duration`
240 /// - `Url`
241 /// - `HashMap<String, String>`
242 /// - `serde_json::Value`
243 ///
244 /// # Type Parameters
245 ///
246 /// * `T` - The type of the value to wrap
247 ///
248 /// # Returns
249 ///
250 /// Returns a `Value` wrapping the given value
251 ///
252 /// # Example
253 ///
254 /// ```rust
255 /// use qubit_value::Value;
256 ///
257 /// // Basic types
258 /// let v = Value::new(42i32);
259 /// assert_eq!(v.get_int32().unwrap(), 42);
260 ///
261 /// let v = Value::new(true);
262 /// assert_eq!(v.get_bool().unwrap(), true);
263 ///
264 /// // String
265 /// let v = Value::new("hello".to_string());
266 /// assert_eq!(v.get_string().unwrap(), "hello");
267 /// ```
268 #[inline]
269 pub fn new<T>(value: T) -> Self
270 where
271 Self: ValueConstructor<T>,
272 {
273 <Self as ValueConstructor<T>>::from_type(value)
274 }
275
276 /// Generic getter method
277 ///
278 /// Automatically selects the correct getter method based on the target
279 /// type, performing strict type checking.
280 ///
281 /// `get<T>()` performs strict type matching. It does not do cross-type
282 /// conversion.
283 ///
284 /// For example, `Value::Int32(42).get::<i64>()` fails, while
285 /// `Value::Int32(42).to::<i64>()` succeeds.
286 ///
287 /// # Supported Generic Types
288 ///
289 /// `Value::get<T>()` currently supports the following `T`:
290 ///
291 /// - `bool`
292 /// - `char`
293 /// - `i8`, `i16`, `i32`, `i64`, `i128`
294 /// - `u8`, `u16`, `u32`, `u64`, `u128`
295 /// - `f32`, `f64`
296 /// - `String`
297 /// - `NaiveDate`, `NaiveTime`, `NaiveDateTime`, `DateTime<Utc>`
298 /// - `BigInt`, `BigDecimal`
299 /// - `isize`, `usize`
300 /// - `Duration`
301 /// - `Url`
302 /// - `HashMap<String, String>`
303 /// - `serde_json::Value`
304 ///
305 /// # Type Parameters
306 ///
307 /// * `T` - The target type to retrieve
308 ///
309 /// # Returns
310 ///
311 /// If types match, returns the value of the corresponding type;
312 /// otherwise returns an error
313 ///
314 /// # Example
315 ///
316 /// ```rust
317 /// use qubit_value::Value;
318 ///
319 /// let value = Value::Int32(42);
320 ///
321 /// // Through type inference
322 /// let num: i32 = value.get().unwrap();
323 /// assert_eq!(num, 42);
324 ///
325 /// // Explicitly specify type parameter
326 /// let num = value.get::<i32>().unwrap();
327 /// assert_eq!(num, 42);
328 ///
329 /// // Different type
330 /// let text = Value::String("hello".to_string());
331 /// let s: String = text.get().unwrap();
332 /// assert_eq!(s, "hello");
333 ///
334 /// // Boolean value
335 /// let flag = Value::Bool(true);
336 /// let b: bool = flag.get().unwrap();
337 /// assert_eq!(b, true);
338 /// ```
339 #[inline]
340 pub fn get<T>(&self) -> ValueResult<T>
341 where
342 Self: ValueGetter<T>,
343 {
344 <Self as ValueGetter<T>>::get_value(self)
345 }
346
347 /// Generic conversion method
348 ///
349 /// Converts the current value to the target type according to the conversion
350 /// rules defined by [`ValueConverter<T>`].
351 ///
352 /// # Supported Target Types And Source Variants
353 ///
354 /// `Value::to<T>()` currently supports the following target types:
355 ///
356 /// - `bool`
357 /// - `Value::Bool`
358 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
359 /// `Value::Int128`
360 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
361 /// `Value::UInt64`, `Value::UInt128`
362 /// - `Value::String`, parsed as `bool`
363 /// - `char`
364 /// - `Value::Char`
365 /// - `i8`
366 /// - `Value::Int8`
367 /// - `i16`
368 /// - `Value::Int16`
369 /// - `i32`
370 /// - `Value::Int32`
371 /// - `Value::Bool`
372 /// - `Value::Char`
373 /// - `Value::Int8`, `Value::Int16`, `Value::Int64`, `Value::Int128`
374 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
375 /// `Value::UInt64`, `Value::UInt128`
376 /// - `Value::Float32`, `Value::Float64`
377 /// - `Value::String`, parsed as `i32`
378 /// - `Value::BigInteger`, `Value::BigDecimal`
379 /// - `i64`
380 /// - `Value::Int64`
381 /// - `Value::Bool`
382 /// - `Value::Char`
383 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int128`
384 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
385 /// `Value::UInt64`, `Value::UInt128`
386 /// - `Value::Float32`, `Value::Float64`
387 /// - `Value::String`, parsed as `i64`
388 /// - `Value::BigInteger`, `Value::BigDecimal`
389 /// - `i128`
390 /// - `Value::Int128`
391 /// - `u8`
392 /// - `Value::UInt8`
393 /// - `Value::Bool`
394 /// - `Value::Char`
395 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
396 /// `Value::Int128`
397 /// - `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
398 /// `Value::UInt128`
399 /// - `Value::String`, parsed as `u8`
400 /// - `u16`
401 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
402 /// `Value::UInt64`, `Value::UInt128`
403 /// - `Value::Bool`
404 /// - `Value::Char`
405 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
406 /// `Value::Int128`
407 /// - `Value::String`, parsed as `u16`
408 /// - `u32`
409 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
410 /// `Value::UInt64`, `Value::UInt128`
411 /// - `Value::Bool`
412 /// - `Value::Char`
413 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
414 /// `Value::Int128`
415 /// - `Value::String`, parsed as `u32`
416 /// - `u64`
417 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
418 /// `Value::UInt64`, `Value::UInt128`
419 /// - `Value::Bool`
420 /// - `Value::Char`
421 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
422 /// `Value::Int128`
423 /// - `Value::String`, parsed as `u64`
424 /// - `u128`
425 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
426 /// `Value::UInt64`, `Value::UInt128`
427 /// - `Value::Bool`
428 /// - `Value::Char`
429 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
430 /// `Value::Int128`
431 /// - `Value::String`, parsed as `u128`
432 /// - `f32`
433 /// - `Value::Float32`, `Value::Float64`
434 /// - `Value::Bool`
435 /// - `Value::Char`
436 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
437 /// `Value::Int128`
438 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
439 /// `Value::UInt64`, `Value::UInt128`
440 /// - `Value::String`, parsed as `f32`
441 /// - `Value::BigInteger`, `Value::BigDecimal`
442 /// - `f64`
443 /// - `Value::Float64`
444 /// - `Value::Bool`
445 /// - `Value::Char`
446 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
447 /// `Value::Int128`
448 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
449 /// `Value::UInt64`, `Value::UInt128`
450 /// - `Value::Float32`
451 /// - `Value::String`, parsed as `f64`
452 /// - `Value::BigInteger`, `Value::BigDecimal`
453 /// - `String`
454 /// - `Value::String`
455 /// - `Value::Bool`, `Value::Char`
456 /// - all integer and floating-point variants
457 /// - `Value::Date`, `Value::Time`, `Value::DateTime`, `Value::Instant`
458 /// - `Value::BigInteger`, `Value::BigDecimal`
459 /// - `Value::IntSize`, `Value::UIntSize`
460 /// - `Value::Duration`, formatted as `<nanoseconds>ns`
461 /// - `Value::Url`
462 /// - `Value::StringMap`, serialized as JSON text
463 /// - `Value::Json`, serialized as JSON text
464 /// - `NaiveDate`
465 /// - `Value::Date`
466 /// - `NaiveTime`
467 /// - `Value::Time`
468 /// - `NaiveDateTime`
469 /// - `Value::DateTime`
470 /// - `DateTime<Utc>`
471 /// - `Value::Instant`
472 /// - `BigInt`
473 /// - `Value::BigInteger`
474 /// - `BigDecimal`
475 /// - `Value::BigDecimal`
476 /// - `isize`
477 /// - `Value::IntSize`
478 /// - `usize`
479 /// - `Value::UIntSize`
480 /// - `Duration`
481 /// - `Value::Duration`
482 /// - `Value::String`, parsed from `<nanoseconds>ns`
483 /// - `Url`
484 /// - `Value::Url`
485 /// - `Value::String`, parsed as URL text
486 /// - `HashMap<String, String>`
487 /// - `Value::StringMap`
488 /// - `serde_json::Value`
489 /// - `Value::Json`
490 /// - `Value::String`, parsed as JSON text
491 /// - `Value::StringMap`, converted to a JSON object
492 ///
493 /// Any target type not listed above is not supported by `Value::to<T>()`.
494 ///
495 /// # Type Parameters
496 ///
497 /// * `T` - The target type to convert to
498 ///
499 /// # Returns
500 ///
501 /// Returns the converted value on success, or an error if conversion is not
502 /// supported or fails.
503 ///
504 /// # Example
505 ///
506 /// ```rust
507 /// use qubit_value::Value;
508 ///
509 /// let value = Value::Int32(42);
510 ///
511 /// let num: i64 = value.to().unwrap();
512 /// assert_eq!(num, 42);
513 ///
514 /// let text: String = value.to().unwrap();
515 /// assert_eq!(text, "42");
516 /// ```
517 #[inline]
518 pub fn to<T>(&self) -> ValueResult<T>
519 where
520 Self: ValueConverter<T>,
521 {
522 <Self as ValueConverter<T>>::convert(self)
523 }
524
525 /// Generic setter method
526 ///
527 /// Automatically selects the correct setter method based on the target
528 /// type and replaces the current value.
529 ///
530 /// This operation updates the stored type to `T` when needed. It does not
531 /// perform runtime type-mismatch validation against the previous variant.
532 ///
533 /// # Supported Generic Types
534 ///
535 /// `Value::set<T>(value)` currently supports the following `T`:
536 ///
537 /// - `bool`
538 /// - `char`
539 /// - `i8`, `i16`, `i32`, `i64`, `i128`
540 /// - `u8`, `u16`, `u32`, `u64`, `u128`
541 /// - `f32`, `f64`
542 /// - `String`, `&str`
543 /// - `NaiveDate`, `NaiveTime`, `NaiveDateTime`, `DateTime<Utc>`
544 /// - `BigInt`, `BigDecimal`
545 /// - `isize`, `usize`
546 /// - `Duration`
547 /// - `Url`
548 /// - `HashMap<String, String>`
549 /// - `serde_json::Value`
550 ///
551 /// # Type Parameters
552 ///
553 /// * `T` - The target type to set
554 ///
555 /// # Parameters
556 ///
557 /// * `value` - The value to set
558 ///
559 /// # Returns
560 ///
561 /// If setting succeeds, returns `Ok(())`; otherwise returns an error
562 ///
563 /// # Example
564 ///
565 /// ```rust
566 /// use qubit_common::lang::DataType;
567 /// use qubit_value::Value;
568 ///
569 /// let mut value = Value::Empty(DataType::Int32);
570 ///
571 /// // Through type inference
572 /// value.set(42i32).unwrap();
573 /// assert_eq!(value.get_int32().unwrap(), 42);
574 ///
575 /// // Explicitly specify type parameter
576 /// value.set::<i32>(100).unwrap();
577 /// assert_eq!(value.get_int32().unwrap(), 100);
578 ///
579 /// // String type
580 /// let mut text = Value::Empty(DataType::String);
581 /// text.set("hello".to_string()).unwrap();
582 /// assert_eq!(text.get_string().unwrap(), "hello");
583 /// ```
584 #[inline]
585 pub fn set<T>(&mut self, value: T) -> ValueResult<()>
586 where
587 Self: ValueSetter<T>,
588 {
589 <Self as ValueSetter<T>>::set_value(self, value)
590 }
591
592 /// Get the data type of the value
593 ///
594 /// # Returns
595 ///
596 /// Returns the data type corresponding to this value
597 ///
598 /// # Example
599 ///
600 /// ```rust
601 /// use qubit_common::lang::DataType;
602 /// use qubit_value::Value;
603 ///
604 /// let value = Value::Int32(42);
605 /// assert_eq!(value.data_type(), DataType::Int32);
606 ///
607 /// let empty = Value::Empty(DataType::String);
608 /// assert_eq!(empty.data_type(), DataType::String);
609 /// ```
610 #[inline]
611 pub fn data_type(&self) -> DataType {
612 match self {
613 Value::Empty(dt) => *dt,
614 Value::Bool(_) => DataType::Bool,
615 Value::Char(_) => DataType::Char,
616 Value::Int8(_) => DataType::Int8,
617 Value::Int16(_) => DataType::Int16,
618 Value::Int32(_) => DataType::Int32,
619 Value::Int64(_) => DataType::Int64,
620 Value::Int128(_) => DataType::Int128,
621 Value::UInt8(_) => DataType::UInt8,
622 Value::UInt16(_) => DataType::UInt16,
623 Value::UInt32(_) => DataType::UInt32,
624 Value::UInt64(_) => DataType::UInt64,
625 Value::UInt128(_) => DataType::UInt128,
626 Value::Float32(_) => DataType::Float32,
627 Value::Float64(_) => DataType::Float64,
628 Value::String(_) => DataType::String,
629 Value::Date(_) => DataType::Date,
630 Value::Time(_) => DataType::Time,
631 Value::DateTime(_) => DataType::DateTime,
632 Value::Instant(_) => DataType::Instant,
633 Value::BigInteger(_) => DataType::BigInteger,
634 Value::BigDecimal(_) => DataType::BigDecimal,
635 Value::IntSize(_) => DataType::IntSize,
636 Value::UIntSize(_) => DataType::UIntSize,
637 Value::Duration(_) => DataType::Duration,
638 Value::Url(_) => DataType::Url,
639 Value::StringMap(_) => DataType::StringMap,
640 Value::Json(_) => DataType::Json,
641 }
642 }
643
644 /// Check if the value is empty
645 ///
646 /// # Returns
647 ///
648 /// Returns `true` if the value is empty
649 ///
650 /// # Example
651 ///
652 /// ```rust
653 /// use qubit_common::lang::DataType;
654 /// use qubit_value::Value;
655 ///
656 /// let value = Value::Int32(42);
657 /// assert!(!value.is_empty());
658 ///
659 /// let empty = Value::Empty(DataType::String);
660 /// assert!(empty.is_empty());
661 /// ```
662 #[inline]
663 pub fn is_empty(&self) -> bool {
664 matches!(self, Value::Empty(_))
665 }
666
667 /// Clear the value while preserving the type
668 ///
669 /// Sets the current value to empty but retains its data type.
670 ///
671 /// # Example
672 ///
673 /// ```rust
674 /// use qubit_common::lang::DataType;
675 /// use qubit_value::Value;
676 ///
677 /// let mut value = Value::Int32(42);
678 /// value.clear();
679 /// assert!(value.is_empty());
680 /// assert_eq!(value.data_type(), DataType::Int32);
681 /// ```
682 #[inline]
683 pub fn clear(&mut self) {
684 let dt = self.data_type();
685 *self = Value::Empty(dt);
686 }
687
688 /// Set the data type
689 ///
690 /// If the new type differs from the current type, clears the value
691 /// and sets the new type.
692 ///
693 /// # Parameters
694 ///
695 /// * `data_type` - The data type to set
696 ///
697 /// # Example
698 ///
699 /// ```rust
700 /// use qubit_common::lang::DataType;
701 /// use qubit_value::Value;
702 ///
703 /// let mut value = Value::Int32(42);
704 /// value.set_type(DataType::String);
705 /// assert!(value.is_empty());
706 /// assert_eq!(value.data_type(), DataType::String);
707 /// ```
708 #[inline]
709 pub fn set_type(&mut self, data_type: DataType) {
710 if self.data_type() != data_type {
711 *self = Value::Empty(data_type);
712 }
713 }
714
715 // ========================================================================
716 // Type-checking getters (strict type matching)
717 // ========================================================================
718
719 impl_get_value! {
720 /// Get boolean value
721 ///
722 /// # Returns
723 ///
724 /// If types match, returns the boolean value; otherwise returns an
725 /// error.
726 ///
727 /// # Example
728 ///
729 /// ```rust
730 /// use qubit_value::Value;
731 ///
732 /// let value = Value::Bool(true);
733 /// assert_eq!(value.get_bool().unwrap(), true);
734 /// ```
735 copy: get_bool, Bool, bool, DataType::Bool
736 }
737
738 impl_get_value! {
739 /// Get character value
740 ///
741 /// # Returns
742 ///
743 /// If types match, returns the character value; otherwise returns an
744 /// error.
745 ///
746 /// # Example
747 ///
748 /// ```rust
749 /// use qubit_value::Value;
750 ///
751 /// let value = Value::Char('A');
752 /// assert_eq!(value.get_char().unwrap(), 'A');
753 /// ```
754 copy: get_char, Char, char, DataType::Char
755 }
756
757 impl_get_value! {
758 /// Get int8 value
759 ///
760 /// # Returns
761 ///
762 /// If types match, returns the int8 value; otherwise returns an error.
763 copy: get_int8, Int8, i8, DataType::Int8
764 }
765
766 impl_get_value! {
767 /// Get int16 value
768 ///
769 /// # Returns
770 ///
771 /// If types match, returns the int16 value; otherwise returns an error
772 copy: get_int16, Int16, i16, DataType::Int16
773 }
774
775 impl_get_value! {
776 /// Get int32 value
777 ///
778 /// # Returns
779 ///
780 /// If types match, returns the int32 value; otherwise returns an error.
781 copy: get_int32, Int32, i32, DataType::Int32
782 }
783
784 impl_get_value! {
785 /// Get int64 value
786 ///
787 /// # Returns
788 ///
789 /// If types match, returns the int64 value; otherwise returns an error
790 copy: get_int64, Int64, i64, DataType::Int64
791 }
792
793 impl_get_value! {
794 /// Get int128 value
795 ///
796 /// # Returns
797 ///
798 /// If types match, returns the int128 value; otherwise returns an error.
799 copy: get_int128, Int128, i128, DataType::Int128
800 }
801
802 impl_get_value! {
803 /// Get uint8 value
804 ///
805 /// # Returns
806 ///
807 /// If types match, returns the uint8 value; otherwise returns an error
808 copy: get_uint8, UInt8, u8, DataType::UInt8
809 }
810
811 impl_get_value! {
812 /// Get uint16 value
813 ///
814 /// # Returns
815 ///
816 /// If types match, returns the uint16 value; otherwise returns an error.
817 copy: get_uint16, UInt16, u16, DataType::UInt16
818 }
819
820 impl_get_value! {
821 /// Get uint32 value
822 ///
823 /// # Returns
824 ///
825 /// If types match, returns the uint32 value; otherwise returns an error.
826 copy: get_uint32, UInt32, u32, DataType::UInt32
827 }
828
829 impl_get_value! {
830 /// Get uint64 value
831 ///
832 /// # Returns
833 ///
834 /// If types match, returns the uint64 value; otherwise returns an error.
835 copy: get_uint64, UInt64, u64, DataType::UInt64
836 }
837
838 impl_get_value! {
839 /// Get uint128 value
840 ///
841 /// # Returns
842 ///
843 /// If types match, returns the uint128 value; otherwise returns an error
844 copy: get_uint128, UInt128, u128, DataType::UInt128
845 }
846
847 impl_get_value! {
848 /// Get float32 value
849 ///
850 /// # Returns
851 ///
852 /// If types match, returns the float32 value; otherwise returns an error.
853 copy: get_float32, Float32, f32, DataType::Float32
854 }
855
856 impl_get_value! {
857 /// Get float64 value
858 ///
859 /// # Returns
860 ///
861 /// If types match, returns the float64 value; otherwise returns an error
862 copy: get_float64, Float64, f64, DataType::Float64
863 }
864
865 impl_get_value! {
866 /// Get string reference
867 ///
868 /// # Returns
869 ///
870 /// If types match, returns a reference to the string; otherwise returns
871 /// an error.
872 ///
873 /// # Example
874 ///
875 /// ```rust
876 /// use qubit_value::Value;
877 ///
878 /// let value = Value::String("hello".to_string());
879 /// assert_eq!(value.get_string().unwrap(), "hello");
880 /// ```
881 ref: get_string, String, &str, DataType::String, |s: &String| s.as_str()
882 }
883
884 impl_get_value! {
885 /// Get date value
886 ///
887 /// # Returns
888 ///
889 /// If types match, returns the date value; otherwise returns an error.
890 copy: get_date, Date, NaiveDate, DataType::Date
891 }
892
893 impl_get_value! {
894 /// Get time value
895 ///
896 /// # Returns
897 ///
898 /// If types match, returns the time value; otherwise returns an error.
899 copy: get_time, Time, NaiveTime, DataType::Time
900 }
901
902 impl_get_value! {
903 /// Get datetime value
904 ///
905 /// # Returns
906 ///
907 /// If types match, returns the datetime value; otherwise returns an error.
908 copy: get_datetime, DateTime, NaiveDateTime, DataType::DateTime
909 }
910
911 impl_get_value! {
912 /// Get UTC instant value
913 ///
914 /// # Returns
915 ///
916 /// If types match, returns the UTC instant value; otherwise returns an error.
917 copy: get_instant, Instant, DateTime<Utc>, DataType::Instant
918 }
919
920 impl_get_value! {
921 /// Get big integer value
922 ///
923 /// # Returns
924 ///
925 /// If types match, returns the big integer value; otherwise returns an error.
926 ///
927 /// # Example
928 ///
929 /// ```rust
930 /// use qubit_value::Value;
931 /// use num_bigint::BigInt;
932 ///
933 /// let value = Value::BigInteger(BigInt::from(123456789));
934 /// assert_eq!(value.get_biginteger().unwrap(), BigInt::from(123456789));
935 /// ```
936 ref: get_biginteger, BigInteger, BigInt, DataType::BigInteger, |v: &BigInt| v.clone()
937 }
938
939 impl_get_value! {
940 /// Get big decimal value
941 ///
942 /// # Returns
943 ///
944 /// If types match, returns the big decimal value; otherwise returns an
945 /// error.
946 ///
947 /// # Example
948 ///
949 /// ```rust
950 /// use std::str::FromStr;
951 ///
952 /// use bigdecimal::BigDecimal;
953 /// use qubit_value::Value;
954 ///
955 /// let bd = BigDecimal::from_str("123.456").unwrap();
956 /// let value = Value::BigDecimal(bd.clone());
957 /// assert_eq!(value.get_bigdecimal().unwrap(), bd);
958 /// ```
959 ref: get_bigdecimal, BigDecimal, BigDecimal, DataType::BigDecimal, |v: &BigDecimal| v.clone()
960 }
961
962 // ========================================================================
963 // Type-setting setters (strict type matching)
964 // ========================================================================
965
966 impl_set_value! {
967 /// Set boolean value
968 ///
969 /// # Parameters
970 ///
971 /// * `value` - The boolean value to set
972 ///
973 /// # Returns
974 ///
975 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
976 ///
977 /// # Example
978 ///
979 /// ```rust
980 /// use qubit_common::lang::DataType;
981 /// use qubit_value::Value;
982 ///
983 /// let mut value = Value::Empty(DataType::Bool);
984 /// value.set_bool(true).unwrap();
985 /// assert_eq!(value.get_bool().unwrap(), true);
986 /// ```
987 copy: set_bool, Bool, bool, DataType::Bool
988 }
989
990 impl_set_value! {
991 /// Set character value
992 ///
993 /// # Parameters
994 ///
995 /// * `value` - The character value to set
996 ///
997 /// # Returns
998 ///
999 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1000 copy: set_char, Char, char, DataType::Char
1001 }
1002
1003 impl_set_value! {
1004 /// Set int8 value
1005 ///
1006 /// # Parameters
1007 ///
1008 /// * `value` - The int8 value to set
1009 ///
1010 /// # Returns
1011 ///
1012 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1013 copy: set_int8, Int8, i8, DataType::Int8
1014 }
1015
1016 impl_set_value! {
1017 /// Set int16 value
1018 ///
1019 /// # Parameters
1020 ///
1021 /// * `value` - The int16 value to set
1022 ///
1023 /// # Returns
1024 ///
1025 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1026 copy: set_int16, Int16, i16, DataType::Int16
1027 }
1028
1029 impl_set_value! {
1030 /// Set int32 value
1031 ///
1032 /// # Parameters
1033 ///
1034 /// * `value` - The int32 value to set
1035 ///
1036 /// # Returns
1037 ///
1038 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1039 copy: set_int32, Int32, i32, DataType::Int32
1040 }
1041
1042 impl_set_value! {
1043 /// Set int64 value
1044 ///
1045 /// # Parameters
1046 ///
1047 /// * `value` - The int64 value to set
1048 ///
1049 /// # Returns
1050 ///
1051 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1052 copy: set_int64, Int64, i64, DataType::Int64
1053 }
1054
1055 impl_set_value! {
1056 /// Set int128 value
1057 ///
1058 /// # Parameters
1059 ///
1060 /// * `value` - The int128 value to set
1061 ///
1062 /// # Returns
1063 ///
1064 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1065 copy: set_int128, Int128, i128, DataType::Int128
1066 }
1067
1068 impl_set_value! {
1069 /// Set uint8 value
1070 ///
1071 /// # Parameters
1072 ///
1073 /// * `value` - The uint8 value to set
1074 ///
1075 /// # Returns
1076 ///
1077 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1078 copy: set_uint8, UInt8, u8, DataType::UInt8
1079 }
1080
1081 impl_set_value! {
1082 /// Set uint16 value
1083 ///
1084 /// # Parameters
1085 ///
1086 /// * `value` - The uint16 value to set
1087 ///
1088 /// # Returns
1089 ///
1090 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1091 copy: set_uint16, UInt16, u16, DataType::UInt16
1092 }
1093
1094 impl_set_value! {
1095 /// Set uint32 value
1096 ///
1097 /// # Parameters
1098 ///
1099 /// * `value` - The uint32 value to set
1100 ///
1101 /// # Returns
1102 ///
1103 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1104 copy: set_uint32, UInt32, u32, DataType::UInt32
1105 }
1106
1107 impl_set_value! {
1108 /// Set uint64 value
1109 ///
1110 /// # Parameters
1111 ///
1112 /// * `value` - The uint64 value to set
1113 ///
1114 /// # Returns
1115 ///
1116 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1117 copy: set_uint64, UInt64, u64, DataType::UInt64
1118 }
1119
1120 impl_set_value! {
1121 /// Set uint128 value
1122 ///
1123 /// # Parameters
1124 ///
1125 /// * `value` - The uint128 value to set
1126 ///
1127 /// # Returns
1128 ///
1129 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1130 copy: set_uint128, UInt128, u128, DataType::UInt128
1131 }
1132
1133 impl_set_value! {
1134 /// Set float32 value
1135 ///
1136 /// # Parameters
1137 ///
1138 /// * `value` - The float32 value to set
1139 ///
1140 /// # Returns
1141 ///
1142 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1143 copy: set_float32, Float32, f32, DataType::Float32
1144 }
1145
1146 impl_set_value! {
1147 /// Set float64 value
1148 ///
1149 /// # Parameters
1150 ///
1151 /// * `value` - The float64 value to set
1152 ///
1153 /// # Returns
1154 ///
1155 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1156 copy: set_float64, Float64, f64, DataType::Float64
1157 }
1158
1159 impl_set_value! {
1160 /// Set string value
1161 ///
1162 /// # Parameters
1163 ///
1164 /// * `value` - The string value to set
1165 ///
1166 /// # Returns
1167 ///
1168 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1169 ///
1170 /// # Example
1171 ///
1172 /// ```rust
1173 /// use qubit_common::lang::DataType;
1174 /// use qubit_value::Value;
1175 ///
1176 /// let mut value = Value::Empty(DataType::String);
1177 /// value.set_string("hello".to_string()).unwrap();
1178 /// assert_eq!(value.get_string().unwrap(), "hello");
1179 /// ```
1180 owned: set_string, String, String, DataType::String
1181 }
1182
1183 impl_set_value! {
1184 /// Set date value
1185 ///
1186 /// # Parameters
1187 ///
1188 /// * `value` - The date value to set
1189 ///
1190 /// # Returns
1191 ///
1192 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1193 copy: set_date, Date, NaiveDate, DataType::Date
1194 }
1195
1196 impl_set_value! {
1197 /// Set time value
1198 ///
1199 /// # Parameters
1200 ///
1201 /// * `value` - The time value to set
1202 ///
1203 /// # Returns
1204 ///
1205 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1206 copy: set_time, Time, NaiveTime, DataType::Time
1207 }
1208
1209 impl_set_value! {
1210 /// Set datetime value
1211 ///
1212 /// # Parameters
1213 ///
1214 /// * `value` - The datetime value to set
1215 ///
1216 /// # Returns
1217 ///
1218 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1219 copy: set_datetime, DateTime, NaiveDateTime, DataType::DateTime
1220 }
1221
1222 impl_set_value! {
1223 /// Set UTC instant value
1224 ///
1225 /// # Parameters
1226 ///
1227 /// * `value` - The UTC instant value to set
1228 ///
1229 /// # Returns
1230 ///
1231 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1232 copy: set_instant, Instant, DateTime<Utc>, DataType::Instant
1233 }
1234
1235 impl_set_value! {
1236 /// Set big integer value
1237 ///
1238 /// # Parameters
1239 ///
1240 /// * `value` - The big integer value to set
1241 ///
1242 /// # Returns
1243 ///
1244 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1245 ///
1246 /// # Example
1247 ///
1248 /// ```rust
1249 /// use num_bigint::BigInt;
1250 /// use qubit_common::lang::DataType;
1251 /// use qubit_value::Value;
1252 ///
1253 /// let mut value = Value::Empty(DataType::BigInteger);
1254 /// value.set_biginteger(BigInt::from(123456789)).unwrap();
1255 /// assert_eq!(value.get_biginteger().unwrap(), BigInt::from(123456789));
1256 /// ```
1257 owned: set_biginteger, BigInteger, BigInt, DataType::BigInteger
1258 }
1259
1260 impl_set_value! {
1261 /// Set big decimal value
1262 ///
1263 /// # Parameters
1264 ///
1265 /// * `value` - The big decimal value to set
1266 ///
1267 /// # Returns
1268 ///
1269 /// If setting succeeds, returns `Ok(())`; otherwise returns an error.
1270 ///
1271 /// # Example
1272 ///
1273 /// ```rust
1274 /// use std::str::FromStr;
1275 ///
1276 /// use bigdecimal::BigDecimal;
1277 /// use qubit_common::lang::DataType;
1278 /// use qubit_value::Value;
1279 ///
1280 /// let mut value = Value::Empty(DataType::BigDecimal);
1281 /// let bd = BigDecimal::from_str("123.456").unwrap();
1282 /// value.set_bigdecimal(bd.clone()).unwrap();
1283 /// assert_eq!(value.get_bigdecimal().unwrap(), bd);
1284 /// ```
1285 owned: set_bigdecimal, BigDecimal, BigDecimal, DataType::BigDecimal
1286 }
1287
1288 impl_get_value! {
1289 /// Get isize value
1290 ///
1291 /// # Returns
1292 ///
1293 /// If types match, returns the isize value; otherwise returns an error.
1294 copy: get_intsize, IntSize, isize, DataType::IntSize
1295 }
1296
1297 impl_get_value! {
1298 /// Get usize value
1299 ///
1300 /// # Returns
1301 ///
1302 /// If types match, returns the usize value; otherwise returns an error.
1303 copy: get_uintsize, UIntSize, usize, DataType::UIntSize
1304 }
1305
1306 impl_get_value! {
1307 /// Get Duration value
1308 ///
1309 /// # Returns
1310 ///
1311 /// If types match, returns the Duration value; otherwise returns an
1312 /// error.
1313 copy: get_duration, Duration, Duration, DataType::Duration
1314 }
1315
1316 impl_get_value! {
1317 /// Get Url reference
1318 ///
1319 /// # Returns
1320 ///
1321 /// If types match, returns a reference to the Url; otherwise returns an
1322 /// error.
1323 ref: get_url, Url, Url, DataType::Url, |v: &Url| v.clone()
1324 }
1325
1326 impl_get_value! {
1327 /// Get StringMap reference
1328 ///
1329 /// # Returns
1330 ///
1331 /// If types match, returns a reference to the `HashMap<String, String>`;
1332 /// otherwise returns an error.
1333 ref: get_string_map, StringMap, HashMap<String, String>, DataType::StringMap,
1334 |v: &HashMap<String, String>| v.clone()
1335 }
1336
1337 impl_get_value! {
1338 /// Get Json value reference
1339 ///
1340 /// # Returns
1341 ///
1342 /// If types match, returns a reference to the `serde_json::Value`;
1343 /// otherwise returns an error.
1344 ref: get_json, Json, serde_json::Value, DataType::Json,
1345 |v: &serde_json::Value| v.clone()
1346 }
1347
1348 /// Borrow the inner `BigInt` without cloning.
1349 pub fn get_biginteger_ref(&self) -> ValueResult<&BigInt> {
1350 match self {
1351 Value::BigInteger(v) => Ok(v),
1352 Value::Empty(_) => Err(ValueError::NoValue),
1353 _ => Err(ValueError::TypeMismatch {
1354 expected: DataType::BigInteger,
1355 actual: self.data_type(),
1356 }),
1357 }
1358 }
1359
1360 /// Borrow the inner `BigDecimal` without cloning.
1361 pub fn get_bigdecimal_ref(&self) -> ValueResult<&BigDecimal> {
1362 match self {
1363 Value::BigDecimal(v) => Ok(v),
1364 Value::Empty(_) => Err(ValueError::NoValue),
1365 _ => Err(ValueError::TypeMismatch {
1366 expected: DataType::BigDecimal,
1367 actual: self.data_type(),
1368 }),
1369 }
1370 }
1371
1372 /// Borrow the inner `Url` without cloning.
1373 pub fn get_url_ref(&self) -> ValueResult<&Url> {
1374 match self {
1375 Value::Url(v) => Ok(v),
1376 Value::Empty(_) => Err(ValueError::NoValue),
1377 _ => Err(ValueError::TypeMismatch {
1378 expected: DataType::Url,
1379 actual: self.data_type(),
1380 }),
1381 }
1382 }
1383
1384 /// Borrow the inner `HashMap<String, String>` without cloning.
1385 pub fn get_string_map_ref(&self) -> ValueResult<&HashMap<String, String>> {
1386 match self {
1387 Value::StringMap(v) => Ok(v),
1388 Value::Empty(_) => Err(ValueError::NoValue),
1389 _ => Err(ValueError::TypeMismatch {
1390 expected: DataType::StringMap,
1391 actual: self.data_type(),
1392 }),
1393 }
1394 }
1395
1396 /// Borrow the inner JSON value without cloning.
1397 pub fn get_json_ref(&self) -> ValueResult<&serde_json::Value> {
1398 match self {
1399 Value::Json(v) => Ok(v),
1400 Value::Empty(_) => Err(ValueError::NoValue),
1401 _ => Err(ValueError::TypeMismatch {
1402 expected: DataType::Json,
1403 actual: self.data_type(),
1404 }),
1405 }
1406 }
1407
1408 impl_set_value! {
1409 /// Set isize value
1410 copy: set_intsize, IntSize, isize, DataType::IntSize
1411 }
1412
1413 impl_set_value! {
1414 /// Set usize value
1415 copy: set_uintsize, UIntSize, usize, DataType::UIntSize
1416 }
1417
1418 impl_set_value! {
1419 /// Set Duration value
1420 copy: set_duration, Duration, Duration, DataType::Duration
1421 }
1422
1423 impl_set_value! {
1424 /// Set Url value
1425 owned: set_url, Url, Url, DataType::Url
1426 }
1427
1428 impl_set_value! {
1429 /// Set StringMap value
1430 owned: set_string_map, StringMap, HashMap<String, String>, DataType::StringMap
1431 }
1432
1433 impl_set_value! {
1434 /// Set Json value
1435 owned: set_json, Json, serde_json::Value, DataType::Json
1436 }
1437
1438 /// Create a `Value` from a `serde_json::Value`.
1439 ///
1440 /// # Parameters
1441 ///
1442 /// * `json` - The JSON value to wrap.
1443 ///
1444 /// # Returns
1445 ///
1446 /// Returns a `Value::Json` wrapping the given JSON value.
1447 #[inline]
1448 pub fn from_json_value(json: serde_json::Value) -> Self {
1449 Value::Json(json)
1450 }
1451
1452 /// Create a `Value` from any serializable value by converting it to JSON.
1453 ///
1454 /// # Type Parameters
1455 ///
1456 /// * `T` - Any type implementing `Serialize`.
1457 ///
1458 /// # Parameters
1459 ///
1460 /// * `value` - The value to serialize into JSON.
1461 ///
1462 /// # Returns
1463 ///
1464 /// Returns `Ok(Value::Json(...))` on success, or an error if
1465 /// serialization fails.
1466 pub fn from_serializable<T: Serialize>(value: &T) -> ValueResult<Self> {
1467 let json = serde_json::to_value(value)
1468 .map_err(|e| ValueError::JsonSerializationError(e.to_string()))?;
1469 Ok(Value::Json(json))
1470 }
1471
1472 /// Deserialize the inner JSON value into a target type.
1473 ///
1474 /// Only works when `self` is `Value::Json(...)`.
1475 ///
1476 /// # Type Parameters
1477 ///
1478 /// * `T` - The target type implementing `DeserializeOwned`.
1479 ///
1480 /// # Returns
1481 ///
1482 /// Returns `Ok(T)` on success, or an error if the value is not JSON
1483 /// or deserialization fails.
1484 pub fn deserialize_json<T: DeserializeOwned>(&self) -> ValueResult<T> {
1485 match self {
1486 Value::Json(v) => serde_json::from_value(v.clone())
1487 .map_err(|e| ValueError::JsonDeserializationError(e.to_string())),
1488 Value::Empty(_) => Err(ValueError::NoValue),
1489 _ => Err(ValueError::ConversionFailed {
1490 from: self.data_type(),
1491 to: DataType::Json,
1492 }),
1493 }
1494 }
1495}
1496
1497impl Default for Value {
1498 #[inline]
1499 fn default() -> Self {
1500 Value::Empty(DataType::String)
1501 }
1502}
1503
1504fn parse_duration_string(s: &str) -> ValueResult<Duration> {
1505 let trimmed = s.trim();
1506 let nanos_text = trimmed.strip_suffix("ns").ok_or_else(|| {
1507 ValueError::ConversionError(format!(
1508 "Cannot convert '{}' to Duration: expected '<nanoseconds>ns'",
1509 s
1510 ))
1511 })?;
1512 let total_nanos = nanos_text.parse::<u128>().map_err(|_| {
1513 ValueError::ConversionError(format!(
1514 "Cannot convert '{}' to Duration: invalid nanoseconds value",
1515 s
1516 ))
1517 })?;
1518 let secs = total_nanos / 1_000_000_000;
1519 if secs > u64::MAX as u128 {
1520 return Err(ValueError::ConversionError(format!(
1521 "Cannot convert '{}' to Duration: value out of range",
1522 s
1523 )));
1524 }
1525 let nanos = (total_nanos % 1_000_000_000) as u32;
1526 Ok(Duration::new(secs as u64, nanos))
1527}
1528
1529fn range_check<T>(value: T, min: T, max: T, target: &str) -> ValueResult<T>
1530where
1531 T: NumericArgument + Copy,
1532{
1533 value
1534 .require_in_closed_range("value", min, max)
1535 .map_err(|e| {
1536 ValueError::ConversionError(format!("Cannot convert value to {}: {}", target, e))
1537 })
1538}
1539
1540fn checked_float_to_i32(value: f64, source: &str) -> ValueResult<i32> {
1541 if !value.is_finite() {
1542 return Err(ValueError::ConversionError(format!(
1543 "Cannot convert non-finite {} value to i32",
1544 source
1545 )));
1546 }
1547 if value < i32::MIN as f64 || value > i32::MAX as f64 {
1548 return Err(ValueError::ConversionError(format!(
1549 "{} value out of i32 range",
1550 source
1551 )));
1552 }
1553 Ok(value as i32)
1554}
1555
1556fn checked_float_to_i64(value: f64, source: &str) -> ValueResult<i64> {
1557 if !value.is_finite() {
1558 return Err(ValueError::ConversionError(format!(
1559 "Cannot convert non-finite {} value to i64",
1560 source
1561 )));
1562 }
1563 if value < i64::MIN as f64 || value > i64::MAX as f64 {
1564 return Err(ValueError::ConversionError(format!(
1565 "{} value out of i64 range",
1566 source
1567 )));
1568 }
1569 Ok(value as i64)
1570}
1571
1572fn checked_bigint_to_f32(value: &BigInt) -> ValueResult<f32> {
1573 let converted = value.to_f32().ok_or_else(|| {
1574 ValueError::ConversionError("BigInteger value cannot be converted to f32".to_string())
1575 })?;
1576 if converted.is_finite() {
1577 Ok(converted)
1578 } else {
1579 Err(ValueError::ConversionError(
1580 "BigInteger value out of f32 range".to_string(),
1581 ))
1582 }
1583}
1584
1585fn checked_bigdecimal_to_f32(value: &BigDecimal) -> ValueResult<f32> {
1586 let converted = value.to_f32().ok_or_else(|| {
1587 ValueError::ConversionError("BigDecimal value cannot be converted to f32".to_string())
1588 })?;
1589 if converted.is_finite() {
1590 Ok(converted)
1591 } else {
1592 Err(ValueError::ConversionError(
1593 "BigDecimal value out of f32 range".to_string(),
1594 ))
1595 }
1596}
1597
1598fn checked_bigint_to_f64(value: &BigInt) -> ValueResult<f64> {
1599 let converted = value.to_f64().ok_or_else(|| {
1600 ValueError::ConversionError("BigInteger value cannot be converted to f64".to_string())
1601 })?;
1602 if converted.is_finite() {
1603 Ok(converted)
1604 } else {
1605 Err(ValueError::ConversionError(
1606 "BigInteger value out of f64 range".to_string(),
1607 ))
1608 }
1609}
1610
1611fn checked_bigdecimal_to_f64(value: &BigDecimal) -> ValueResult<f64> {
1612 let converted = value.to_f64().ok_or_else(|| {
1613 ValueError::ConversionError("BigDecimal value cannot be converted to f64".to_string())
1614 })?;
1615 if converted.is_finite() {
1616 Ok(converted)
1617 } else {
1618 Err(ValueError::ConversionError(
1619 "BigDecimal value out of f64 range".to_string(),
1620 ))
1621 }
1622}
1623
1624// ============================================================================
1625// Internal generic conversion traits (private, not exported, to avoid
1626// polluting the standard type namespace)
1627// ============================================================================
1628
1629/// Internal trait: used to extract specific types from Value.
1630///
1631/// This trait is not exported in mod.rs, only used for internal
1632/// implementation, to avoid polluting the standard type namespace.
1633#[doc(hidden)]
1634pub trait ValueGetter<T> {
1635 fn get_value(&self) -> ValueResult<T>;
1636}
1637
1638/// Internal trait: used to create Value from types.
1639///
1640/// This trait is not exported in mod.rs, only used for internal
1641/// implementation, to avoid polluting the standard type namespace.
1642#[doc(hidden)]
1643pub trait ValueConstructor<T> {
1644 fn from_type(value: T) -> Self;
1645}
1646
1647/// Internal trait: used to set specific types in Value.
1648///
1649/// This trait is not exported in mod.rs, only used for internal
1650/// implementation, to avoid polluting the standard type namespace.
1651#[doc(hidden)]
1652pub trait ValueSetter<T> {
1653 fn set_value(&mut self, value: T) -> ValueResult<()>;
1654}
1655
1656/// Internal trait: used to convert Value to target types
1657///
1658/// This trait powers `Value::to<T>()`. Each implementation must clearly define
1659/// which source variants are accepted for the target type.
1660#[doc(hidden)]
1661pub trait ValueConverter<T> {
1662 fn convert(&self) -> ValueResult<T>;
1663}
1664
1665// ============================================================================
1666// Implementation of internal traits (simplified using macros)
1667// ============================================================================
1668
1669macro_rules! impl_value_traits {
1670 ($type:ty, $variant:ident, $get_method:ident, $set_method:ident) => {
1671 impl ValueGetter<$type> for Value {
1672 #[inline]
1673 fn get_value(&self) -> ValueResult<$type> {
1674 self.$get_method()
1675 }
1676 }
1677
1678 impl ValueSetter<$type> for Value {
1679 #[inline]
1680 fn set_value(&mut self, value: $type) -> ValueResult<()> {
1681 self.$set_method(value)
1682 }
1683 }
1684
1685 impl ValueConstructor<$type> for Value {
1686 #[inline]
1687 fn from_type(value: $type) -> Self {
1688 Value::$variant(value)
1689 }
1690 }
1691 };
1692}
1693
1694macro_rules! impl_strict_value_converter {
1695 ($(#[$attr:meta])* $type:ty, $get_method:ident) => {
1696 $(#[$attr])*
1697 impl ValueConverter<$type> for Value {
1698 #[inline]
1699 fn convert(&self) -> ValueResult<$type> {
1700 self.$get_method()
1701 }
1702 }
1703 };
1704}
1705
1706// Implementation for Copy types
1707impl_value_traits!(bool, Bool, get_bool, set_bool);
1708impl_value_traits!(char, Char, get_char, set_char);
1709impl_value_traits!(i8, Int8, get_int8, set_int8);
1710impl_value_traits!(i16, Int16, get_int16, set_int16);
1711impl_value_traits!(i32, Int32, get_int32, set_int32);
1712impl_value_traits!(i64, Int64, get_int64, set_int64);
1713impl_value_traits!(i128, Int128, get_int128, set_int128);
1714impl_value_traits!(u8, UInt8, get_uint8, set_uint8);
1715impl_value_traits!(u16, UInt16, get_uint16, set_uint16);
1716impl_value_traits!(u32, UInt32, get_uint32, set_uint32);
1717impl_value_traits!(u64, UInt64, get_uint64, set_uint64);
1718impl_value_traits!(u128, UInt128, get_uint128, set_uint128);
1719impl_value_traits!(f32, Float32, get_float32, set_float32);
1720impl_value_traits!(f64, Float64, get_float64, set_float64);
1721impl_value_traits!(NaiveDate, Date, get_date, set_date);
1722impl_value_traits!(NaiveTime, Time, get_time, set_time);
1723impl_value_traits!(NaiveDateTime, DateTime, get_datetime, set_datetime);
1724impl_value_traits!(DateTime<Utc>, Instant, get_instant, set_instant);
1725impl_value_traits!(BigInt, BigInteger, get_biginteger, set_biginteger);
1726impl_value_traits!(BigDecimal, BigDecimal, get_bigdecimal, set_bigdecimal);
1727impl_value_traits!(isize, IntSize, get_intsize, set_intsize);
1728impl_value_traits!(usize, UIntSize, get_uintsize, set_uintsize);
1729impl_value_traits!(Duration, Duration, get_duration, set_duration);
1730
1731// String needs cloning
1732impl ValueGetter<String> for Value {
1733 #[inline]
1734 fn get_value(&self) -> ValueResult<String> {
1735 self.get_string().map(|s| s.to_string())
1736 }
1737}
1738
1739impl ValueSetter<String> for Value {
1740 #[inline]
1741 fn set_value(&mut self, value: String) -> ValueResult<()> {
1742 self.set_string(value)
1743 }
1744}
1745
1746impl ValueConstructor<String> for Value {
1747 #[inline]
1748 fn from_type(value: String) -> Self {
1749 Value::String(value)
1750 }
1751}
1752
1753/// Target type `String` supports conversion from:
1754///
1755/// - `Value::String`
1756/// - `Value::Bool`, `Value::Char`
1757/// - all integer and floating-point variants
1758/// - `Value::Date`, `Value::Time`, `Value::DateTime`, `Value::Instant`
1759/// - `Value::BigInteger`, `Value::BigDecimal`
1760/// - `Value::IntSize`, `Value::UIntSize`
1761/// - `Value::Duration`, formatted as `<nanoseconds>ns`
1762/// - `Value::Url`
1763/// - `Value::StringMap`, serialized as JSON text
1764/// - `Value::Json`, serialized as JSON text
1765impl ValueConverter<String> for Value {
1766 fn convert(&self) -> ValueResult<String> {
1767 match self {
1768 Value::String(v) => Ok(v.clone()),
1769 Value::Bool(v) => Ok(v.to_string()),
1770 Value::Char(v) => Ok(v.to_string()),
1771 Value::Int8(v) => Ok(v.to_string()),
1772 Value::Int16(v) => Ok(v.to_string()),
1773 Value::Int32(v) => Ok(v.to_string()),
1774 Value::Int64(v) => Ok(v.to_string()),
1775 Value::Int128(v) => Ok(v.to_string()),
1776 Value::UInt8(v) => Ok(v.to_string()),
1777 Value::UInt16(v) => Ok(v.to_string()),
1778 Value::UInt32(v) => Ok(v.to_string()),
1779 Value::UInt64(v) => Ok(v.to_string()),
1780 Value::UInt128(v) => Ok(v.to_string()),
1781 Value::Float32(v) => Ok(v.to_string()),
1782 Value::Float64(v) => Ok(v.to_string()),
1783 Value::Date(v) => Ok(v.to_string()),
1784 Value::Time(v) => Ok(v.to_string()),
1785 Value::DateTime(v) => Ok(v.to_string()),
1786 Value::Instant(v) => Ok(v.to_rfc3339()),
1787 Value::BigInteger(v) => Ok(v.to_string()),
1788 Value::BigDecimal(v) => Ok(v.to_string()),
1789 Value::IntSize(v) => Ok(v.to_string()),
1790 Value::UIntSize(v) => Ok(v.to_string()),
1791 Value::Duration(v) => Ok(format!("{}ns", v.as_nanos())),
1792 Value::Url(v) => Ok(v.to_string()),
1793 Value::StringMap(v) => serde_json::to_string(v)
1794 .map_err(|e| ValueError::JsonSerializationError(e.to_string())),
1795 Value::Json(v) => serde_json::to_string(v)
1796 .map_err(|e| ValueError::JsonSerializationError(e.to_string())),
1797 Value::Empty(_) => Err(ValueError::NoValue),
1798 }
1799 }
1800}
1801
1802// Special handling for &str - convert to String
1803impl ValueSetter<&str> for Value {
1804 #[inline]
1805 fn set_value(&mut self, value: &str) -> ValueResult<()> {
1806 self.set_string(value.to_string())
1807 }
1808}
1809
1810impl ValueConstructor<&str> for Value {
1811 #[inline]
1812 fn from_type(value: &str) -> Self {
1813 Value::String(value.to_string())
1814 }
1815}
1816
1817/// Target type `bool` supports conversion from:
1818///
1819/// - `Value::Bool`
1820/// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
1821/// `Value::Int128`
1822/// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
1823/// `Value::UInt128`
1824/// - `Value::String`, parsed as `bool`
1825impl ValueConverter<bool> for Value {
1826 fn convert(&self) -> ValueResult<bool> {
1827 match self {
1828 Value::Bool(v) => Ok(*v),
1829 Value::Int8(v) => Ok(*v != 0),
1830 Value::Int16(v) => Ok(*v != 0),
1831 Value::Int32(v) => Ok(*v != 0),
1832 Value::Int64(v) => Ok(*v != 0),
1833 Value::Int128(v) => Ok(*v != 0),
1834 Value::UInt8(v) => Ok(*v != 0),
1835 Value::UInt16(v) => Ok(*v != 0),
1836 Value::UInt32(v) => Ok(*v != 0),
1837 Value::UInt64(v) => Ok(*v != 0),
1838 Value::UInt128(v) => Ok(*v != 0),
1839 Value::String(s) => s.parse::<bool>().map_err(|_| {
1840 ValueError::ConversionError(format!("Cannot convert '{}' to boolean", s))
1841 }),
1842 Value::Empty(_) => Err(ValueError::NoValue),
1843 _ => Err(ValueError::ConversionFailed {
1844 from: self.data_type(),
1845 to: DataType::Bool,
1846 }),
1847 }
1848 }
1849}
1850
1851/// Target type `i32` supports conversion from:
1852///
1853/// - `Value::Int32`
1854/// - `Value::Bool`
1855/// - `Value::Char`
1856/// - `Value::Int8`, `Value::Int16`, `Value::Int64`, `Value::Int128`
1857/// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
1858/// `Value::UInt128`
1859/// - `Value::Float32`, `Value::Float64`
1860/// - `Value::String`, parsed as `i32`
1861/// - `Value::BigInteger`, `Value::BigDecimal`
1862impl ValueConverter<i32> for Value {
1863 fn convert(&self) -> ValueResult<i32> {
1864 match self {
1865 Value::Int32(v) => Ok(*v),
1866 Value::Bool(v) => Ok(if *v { 1 } else { 0 }),
1867 Value::Char(v) => Ok(*v as i32),
1868 Value::Int8(v) => Ok(*v as i32),
1869 Value::Int16(v) => Ok(*v as i32),
1870 Value::Int64(v) => (*v)
1871 .try_into()
1872 .map_err(|_| ValueError::ConversionError("i64 value out of i32 range".to_string())),
1873 Value::Int128(v) => (*v).try_into().map_err(|_| {
1874 ValueError::ConversionError("i128 value out of i32 range".to_string())
1875 }),
1876 Value::UInt8(v) => Ok(*v as i32),
1877 Value::UInt16(v) => Ok(*v as i32),
1878 Value::UInt32(v) => (*v)
1879 .try_into()
1880 .map_err(|_| ValueError::ConversionError("u32 value out of i32 range".to_string())),
1881 Value::UInt64(v) => (*v)
1882 .try_into()
1883 .map_err(|_| ValueError::ConversionError("u64 value out of i32 range".to_string())),
1884 Value::UInt128(v) => (*v).try_into().map_err(|_| {
1885 ValueError::ConversionError("u128 value out of i32 range".to_string())
1886 }),
1887 Value::Float32(v) => checked_float_to_i32(*v as f64, "f32"),
1888 Value::Float64(v) => checked_float_to_i32(*v, "f64"),
1889 Value::String(s) => s
1890 .parse::<i32>()
1891 .map_err(|_| ValueError::ConversionError(format!("Cannot convert '{}' to i32", s))),
1892 Value::Empty(_) => Err(ValueError::NoValue),
1893 Value::BigInteger(v) => v.to_i32().ok_or_else(|| {
1894 ValueError::ConversionError("BigInteger value out of i32 range".to_string())
1895 }),
1896 Value::BigDecimal(v) => v.to_i32().ok_or_else(|| {
1897 ValueError::ConversionError(
1898 "BigDecimal value cannot be converted to i32".to_string(),
1899 )
1900 }),
1901 _ => Err(ValueError::ConversionFailed {
1902 from: self.data_type(),
1903 to: DataType::Int32,
1904 }),
1905 }
1906 }
1907}
1908
1909/// Target type `i64` supports conversion from:
1910///
1911/// - `Value::Int64`
1912/// - `Value::Bool`
1913/// - `Value::Char`
1914/// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int128`
1915/// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
1916/// `Value::UInt128`
1917/// - `Value::Float32`, `Value::Float64`
1918/// - `Value::String`, parsed as `i64`
1919/// - `Value::BigInteger`, `Value::BigDecimal`
1920impl ValueConverter<i64> for Value {
1921 fn convert(&self) -> ValueResult<i64> {
1922 match self {
1923 Value::Int64(v) => Ok(*v),
1924 Value::Bool(v) => Ok(if *v { 1 } else { 0 }),
1925 Value::Char(v) => Ok(*v as i64),
1926 Value::Int8(v) => Ok(*v as i64),
1927 Value::Int16(v) => Ok(*v as i64),
1928 Value::Int32(v) => Ok(*v as i64),
1929 Value::Int128(v) => (*v).try_into().map_err(|_| {
1930 ValueError::ConversionError("i128 value out of i64 range".to_string())
1931 }),
1932 Value::UInt8(v) => Ok(*v as i64),
1933 Value::UInt16(v) => Ok(*v as i64),
1934 Value::UInt32(v) => Ok(*v as i64),
1935 Value::UInt64(v) => (*v)
1936 .try_into()
1937 .map_err(|_| ValueError::ConversionError("u64 value out of i64 range".to_string())),
1938 Value::UInt128(v) => (*v).try_into().map_err(|_| {
1939 ValueError::ConversionError("u128 value out of i64 range".to_string())
1940 }),
1941 Value::Float32(v) => checked_float_to_i64(*v as f64, "f32"),
1942 Value::Float64(v) => checked_float_to_i64(*v, "f64"),
1943 Value::String(s) => s
1944 .parse::<i64>()
1945 .map_err(|_| ValueError::ConversionError(format!("Cannot convert '{}' to i64", s))),
1946 Value::Empty(_) => Err(ValueError::NoValue),
1947 Value::BigInteger(v) => v.to_i64().ok_or_else(|| {
1948 ValueError::ConversionError("BigInteger value out of i64 range".to_string())
1949 }),
1950 Value::BigDecimal(v) => v.to_i64().ok_or_else(|| {
1951 ValueError::ConversionError(
1952 "BigDecimal value cannot be converted to i64".to_string(),
1953 )
1954 }),
1955 _ => Err(ValueError::ConversionFailed {
1956 from: self.data_type(),
1957 to: DataType::Int64,
1958 }),
1959 }
1960 }
1961}
1962
1963/// Target type `f64` supports conversion from:
1964///
1965/// - `Value::Float64`
1966/// - `Value::Bool`
1967/// - `Value::Char`
1968/// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
1969/// `Value::Int128`
1970/// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
1971/// `Value::UInt128`
1972/// - `Value::Float32`
1973/// - `Value::String`, parsed as `f64`
1974/// - `Value::BigInteger`, `Value::BigDecimal`
1975impl ValueConverter<f64> for Value {
1976 fn convert(&self) -> ValueResult<f64> {
1977 match self {
1978 Value::Float64(v) => Ok(*v),
1979 Value::Bool(v) => Ok(if *v { 1.0 } else { 0.0 }),
1980 Value::Char(v) => Ok(*v as u32 as f64),
1981 Value::Float32(v) => Ok(*v as f64),
1982 Value::Int8(v) => Ok(*v as f64),
1983 Value::Int16(v) => Ok(*v as f64),
1984 Value::Int32(v) => Ok(*v as f64),
1985 Value::Int64(v) => Ok(*v as f64),
1986 Value::Int128(v) => Ok(*v as f64),
1987 Value::UInt8(v) => Ok(*v as f64),
1988 Value::UInt16(v) => Ok(*v as f64),
1989 Value::UInt32(v) => Ok(*v as f64),
1990 Value::UInt64(v) => Ok(*v as f64),
1991 Value::UInt128(v) => Ok(*v as f64),
1992 Value::String(s) => s
1993 .parse::<f64>()
1994 .map_err(|_| ValueError::ConversionError(format!("Cannot convert '{}' to f64", s))),
1995 Value::Empty(_) => Err(ValueError::NoValue),
1996 Value::BigInteger(v) => checked_bigint_to_f64(v),
1997 Value::BigDecimal(v) => checked_bigdecimal_to_f64(v),
1998 _ => Err(ValueError::ConversionFailed {
1999 from: self.data_type(),
2000 to: DataType::Float64,
2001 }),
2002 }
2003 }
2004}
2005
2006// Url
2007impl ValueGetter<Url> for Value {
2008 #[inline]
2009 fn get_value(&self) -> ValueResult<Url> {
2010 self.get_url()
2011 }
2012}
2013
2014impl ValueSetter<Url> for Value {
2015 #[inline]
2016 fn set_value(&mut self, value: Url) -> ValueResult<()> {
2017 self.set_url(value)
2018 }
2019}
2020
2021impl ValueConstructor<Url> for Value {
2022 #[inline]
2023 fn from_type(value: Url) -> Self {
2024 Value::Url(value)
2025 }
2026}
2027
2028/// Target type `Duration` supports conversion from:
2029///
2030/// - `Value::Duration`
2031/// - `Value::String`, parsed from `<nanoseconds>ns`
2032impl ValueConverter<Duration> for Value {
2033 fn convert(&self) -> ValueResult<Duration> {
2034 match self {
2035 Value::Duration(v) => Ok(*v),
2036 Value::String(s) => parse_duration_string(s),
2037 Value::Empty(_) => Err(ValueError::NoValue),
2038 _ => Err(ValueError::ConversionFailed {
2039 from: self.data_type(),
2040 to: DataType::Duration,
2041 }),
2042 }
2043 }
2044}
2045
2046/// Target type `Url` supports conversion from:
2047///
2048/// - `Value::Url`
2049/// - `Value::String`, parsed as URL text
2050impl ValueConverter<Url> for Value {
2051 fn convert(&self) -> ValueResult<Url> {
2052 match self {
2053 Value::Url(v) => Ok(v.clone()),
2054 Value::String(s) => Url::parse(s).map_err(|e| {
2055 ValueError::ConversionError(format!("Cannot convert '{}' to Url: {}", s, e))
2056 }),
2057 Value::Empty(_) => Err(ValueError::NoValue),
2058 _ => Err(ValueError::ConversionFailed {
2059 from: self.data_type(),
2060 to: DataType::Url,
2061 }),
2062 }
2063 }
2064}
2065
2066// HashMap<String, String>
2067impl ValueGetter<HashMap<String, String>> for Value {
2068 #[inline]
2069 fn get_value(&self) -> ValueResult<HashMap<String, String>> {
2070 self.get_string_map()
2071 }
2072}
2073
2074impl ValueSetter<HashMap<String, String>> for Value {
2075 #[inline]
2076 fn set_value(&mut self, value: HashMap<String, String>) -> ValueResult<()> {
2077 self.set_string_map(value)
2078 }
2079}
2080
2081impl ValueConstructor<HashMap<String, String>> for Value {
2082 #[inline]
2083 fn from_type(value: HashMap<String, String>) -> Self {
2084 Value::StringMap(value)
2085 }
2086}
2087
2088// serde_json::Value
2089impl ValueGetter<serde_json::Value> for Value {
2090 #[inline]
2091 fn get_value(&self) -> ValueResult<serde_json::Value> {
2092 self.get_json()
2093 }
2094}
2095
2096impl ValueSetter<serde_json::Value> for Value {
2097 #[inline]
2098 fn set_value(&mut self, value: serde_json::Value) -> ValueResult<()> {
2099 self.set_json(value)
2100 }
2101}
2102
2103impl ValueConstructor<serde_json::Value> for Value {
2104 #[inline]
2105 fn from_type(value: serde_json::Value) -> Self {
2106 Value::Json(value)
2107 }
2108}
2109
2110/// Target type `serde_json::Value` supports conversion from:
2111///
2112/// - `Value::Json`
2113/// - `Value::String`, parsed as JSON text
2114/// - `Value::StringMap`, converted to a JSON object
2115impl ValueConverter<serde_json::Value> for Value {
2116 fn convert(&self) -> ValueResult<serde_json::Value> {
2117 match self {
2118 Value::Json(v) => Ok(v.clone()),
2119 Value::String(s) => serde_json::from_str(s)
2120 .map_err(|e| ValueError::JsonDeserializationError(e.to_string())),
2121 Value::StringMap(v) => serde_json::to_value(v)
2122 .map_err(|e| ValueError::JsonSerializationError(e.to_string())),
2123 Value::Empty(_) => Err(ValueError::NoValue),
2124 _ => Err(ValueError::ConversionFailed {
2125 from: self.data_type(),
2126 to: DataType::Json,
2127 }),
2128 }
2129 }
2130}
2131
2132impl_strict_value_converter!(
2133 /// Target type `char` supports conversion from:
2134 ///
2135 /// - `Value::Char`
2136 char,
2137 get_char
2138);
2139impl_strict_value_converter!(
2140 /// Target type `i8` supports conversion from:
2141 ///
2142 /// - `Value::Int8`
2143 i8,
2144 get_int8
2145);
2146impl_strict_value_converter!(
2147 /// Target type `i16` supports conversion from:
2148 ///
2149 /// - `Value::Int16`
2150 i16,
2151 get_int16
2152);
2153impl_strict_value_converter!(
2154 /// Target type `i128` supports conversion from:
2155 ///
2156 /// - `Value::Int128`
2157 i128,
2158 get_int128
2159);
2160/// Target type `u8` supports conversion from:
2161///
2162/// - `Value::UInt8`
2163/// - `Value::Bool`
2164/// - `Value::Char`
2165/// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
2166/// `Value::Int128`
2167/// - `Value::UInt16`, `Value::UInt32`, `Value::UInt64`, `Value::UInt128`
2168/// - `Value::String`, parsed as `u8`
2169impl ValueConverter<u8> for Value {
2170 fn convert(&self) -> ValueResult<u8> {
2171 match self {
2172 Value::UInt8(v) => Ok(*v),
2173 Value::Bool(v) => Ok(if *v { 1 } else { 0 }),
2174 Value::Char(v) => {
2175 let code = range_check(*v as u32, u8::MIN as u32, u8::MAX as u32, "u8")?;
2176 Ok(code as u8)
2177 }
2178 Value::Int8(v) => {
2179 let n = range_check(*v, 0i8, i8::MAX, "u8")?;
2180 Ok(n as u8)
2181 }
2182 Value::Int16(v) => {
2183 let n = range_check(*v, u8::MIN as i16, u8::MAX as i16, "u8")?;
2184 Ok(n as u8)
2185 }
2186 Value::Int32(v) => {
2187 let n = range_check(*v, u8::MIN as i32, u8::MAX as i32, "u8")?;
2188 Ok(n as u8)
2189 }
2190 Value::Int64(v) => {
2191 let n = range_check(*v, u8::MIN as i64, u8::MAX as i64, "u8")?;
2192 Ok(n as u8)
2193 }
2194 Value::Int128(v) => {
2195 let n = range_check(*v, u8::MIN as i128, u8::MAX as i128, "u8")?;
2196 Ok(n as u8)
2197 }
2198 Value::UInt16(v) => {
2199 let n = range_check(*v, u8::MIN as u16, u8::MAX as u16, "u8")?;
2200 Ok(n as u8)
2201 }
2202 Value::UInt32(v) => {
2203 let n = range_check(*v, u8::MIN as u32, u8::MAX as u32, "u8")?;
2204 Ok(n as u8)
2205 }
2206 Value::UInt64(v) => {
2207 let n = range_check(*v, u8::MIN as u64, u8::MAX as u64, "u8")?;
2208 Ok(n as u8)
2209 }
2210 Value::UInt128(v) => {
2211 let n = range_check(*v, u8::MIN as u128, u8::MAX as u128, "u8")?;
2212 Ok(n as u8)
2213 }
2214 Value::String(s) => s
2215 .parse::<u8>()
2216 .map_err(|_| ValueError::ConversionError(format!("Cannot convert '{}' to u8", s))),
2217 Value::Empty(_) => Err(ValueError::NoValue),
2218 _ => Err(ValueError::ConversionFailed {
2219 from: self.data_type(),
2220 to: DataType::UInt8,
2221 }),
2222 }
2223 }
2224}
2225
2226/// Target type `u16` supports conversion from:
2227///
2228/// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
2229/// `Value::UInt128`
2230/// - `Value::Bool`
2231/// - `Value::Char`
2232/// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
2233/// `Value::Int128`
2234/// - `Value::String`, parsed as `u16`
2235impl ValueConverter<u16> for Value {
2236 fn convert(&self) -> ValueResult<u16> {
2237 match self {
2238 Value::UInt8(v) => Ok((*v).into()),
2239 Value::UInt16(v) => Ok(*v),
2240 Value::Bool(v) => Ok(if *v { 1 } else { 0 }),
2241 Value::Char(v) => {
2242 let code = range_check(*v as u32, u16::MIN as u32, u16::MAX as u32, "u16")?;
2243 Ok(code as u16)
2244 }
2245 Value::Int8(v) => {
2246 let n = range_check(*v, 0i8, i8::MAX, "u16")?;
2247 Ok(n as u16)
2248 }
2249 Value::Int16(v) => {
2250 let n = range_check(*v, 0i16, i16::MAX, "u16")?;
2251 Ok(n as u16)
2252 }
2253 Value::Int32(v) => {
2254 let n = range_check(*v, u16::MIN as i32, u16::MAX as i32, "u16")?;
2255 Ok(n as u16)
2256 }
2257 Value::Int64(v) => {
2258 let n = range_check(*v, u16::MIN as i64, u16::MAX as i64, "u16")?;
2259 Ok(n as u16)
2260 }
2261 Value::Int128(v) => {
2262 let n = range_check(*v, u16::MIN as i128, u16::MAX as i128, "u16")?;
2263 Ok(n as u16)
2264 }
2265 Value::UInt32(v) => {
2266 let n = range_check(*v, u16::MIN as u32, u16::MAX as u32, "u16")?;
2267 Ok(n as u16)
2268 }
2269 Value::UInt64(v) => {
2270 let n = range_check(*v, u16::MIN as u64, u16::MAX as u64, "u16")?;
2271 Ok(n as u16)
2272 }
2273 Value::UInt128(v) => {
2274 let n = range_check(*v, u16::MIN as u128, u16::MAX as u128, "u16")?;
2275 Ok(n as u16)
2276 }
2277 Value::String(s) => s
2278 .parse::<u16>()
2279 .map_err(|_| ValueError::ConversionError(format!("Cannot convert '{}' to u16", s))),
2280 Value::Empty(_) => Err(ValueError::NoValue),
2281 _ => Err(ValueError::ConversionFailed {
2282 from: self.data_type(),
2283 to: DataType::UInt16,
2284 }),
2285 }
2286 }
2287}
2288
2289/// Target type `u32` supports conversion from:
2290///
2291/// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
2292/// `Value::UInt128`
2293/// - `Value::Bool`
2294/// - `Value::Char`
2295/// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
2296/// `Value::Int128`
2297/// - `Value::String`, parsed as `u32`
2298impl ValueConverter<u32> for Value {
2299 fn convert(&self) -> ValueResult<u32> {
2300 match self {
2301 Value::UInt8(v) => Ok((*v).into()),
2302 Value::UInt16(v) => Ok((*v).into()),
2303 Value::UInt32(v) => Ok(*v),
2304 Value::Bool(v) => Ok(if *v { 1 } else { 0 }),
2305 Value::Char(v) => Ok(*v as u32),
2306 Value::Int8(v) => {
2307 let n = range_check(*v, 0i8, i8::MAX, "u32")?;
2308 Ok(n as u32)
2309 }
2310 Value::Int16(v) => {
2311 let n = range_check(*v, 0i16, i16::MAX, "u32")?;
2312 Ok(n as u32)
2313 }
2314 Value::Int32(v) => {
2315 let n = range_check(*v, 0i32, i32::MAX, "u32")?;
2316 Ok(n as u32)
2317 }
2318 Value::Int64(v) => {
2319 let n = range_check(*v, u32::MIN as i64, u32::MAX as i64, "u32")?;
2320 Ok(n as u32)
2321 }
2322 Value::Int128(v) => {
2323 let n = range_check(*v, u32::MIN as i128, u32::MAX as i128, "u32")?;
2324 Ok(n as u32)
2325 }
2326 Value::UInt64(v) => {
2327 let n = range_check(*v, u32::MIN as u64, u32::MAX as u64, "u32")?;
2328 Ok(n as u32)
2329 }
2330 Value::UInt128(v) => {
2331 let n = range_check(*v, u32::MIN as u128, u32::MAX as u128, "u32")?;
2332 Ok(n as u32)
2333 }
2334 Value::String(s) => s
2335 .parse::<u32>()
2336 .map_err(|_| ValueError::ConversionError(format!("Cannot convert '{}' to u32", s))),
2337 Value::Empty(_) => Err(ValueError::NoValue),
2338 _ => Err(ValueError::ConversionFailed {
2339 from: self.data_type(),
2340 to: DataType::UInt32,
2341 }),
2342 }
2343 }
2344}
2345
2346/// Target type `u64` supports conversion from:
2347///
2348/// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
2349/// `Value::UInt128`
2350/// - `Value::Bool`
2351/// - `Value::Char`
2352/// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
2353/// `Value::Int128`
2354/// - `Value::String`, parsed as `u64`
2355impl ValueConverter<u64> for Value {
2356 fn convert(&self) -> ValueResult<u64> {
2357 match self {
2358 Value::UInt8(v) => Ok((*v).into()),
2359 Value::UInt16(v) => Ok((*v).into()),
2360 Value::UInt32(v) => Ok((*v).into()),
2361 Value::UInt64(v) => Ok(*v),
2362 Value::Bool(v) => Ok(if *v { 1 } else { 0 }),
2363 Value::Char(v) => Ok((*v as u32).into()),
2364 Value::Int8(v) => {
2365 let n = range_check(*v, 0i8, i8::MAX, "u64")?;
2366 Ok(n as u64)
2367 }
2368 Value::Int16(v) => {
2369 let n = range_check(*v, 0i16, i16::MAX, "u64")?;
2370 Ok(n as u64)
2371 }
2372 Value::Int32(v) => {
2373 let n = range_check(*v, 0i32, i32::MAX, "u64")?;
2374 Ok(n as u64)
2375 }
2376 Value::Int64(v) => {
2377 let n = range_check(*v, 0i64, i64::MAX, "u64")?;
2378 Ok(n as u64)
2379 }
2380 Value::Int128(v) => {
2381 let n = range_check(*v, 0i128, u64::MAX as i128, "u64")?;
2382 Ok(n as u64)
2383 }
2384 Value::UInt128(v) => {
2385 let n = range_check(*v, u64::MIN as u128, u64::MAX as u128, "u64")?;
2386 Ok(n as u64)
2387 }
2388 Value::String(s) => s
2389 .parse::<u64>()
2390 .map_err(|_| ValueError::ConversionError(format!("Cannot convert '{}' to u64", s))),
2391 Value::Empty(_) => Err(ValueError::NoValue),
2392 _ => Err(ValueError::ConversionFailed {
2393 from: self.data_type(),
2394 to: DataType::UInt64,
2395 }),
2396 }
2397 }
2398}
2399
2400/// Target type `u128` supports conversion from:
2401///
2402/// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
2403/// `Value::UInt128`
2404/// - `Value::Bool`
2405/// - `Value::Char`
2406/// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
2407/// `Value::Int128`
2408/// - `Value::String`, parsed as `u128`
2409impl ValueConverter<u128> for Value {
2410 fn convert(&self) -> ValueResult<u128> {
2411 match self {
2412 Value::UInt8(v) => Ok((*v).into()),
2413 Value::UInt16(v) => Ok((*v).into()),
2414 Value::UInt32(v) => Ok((*v).into()),
2415 Value::UInt64(v) => Ok((*v).into()),
2416 Value::UInt128(v) => Ok(*v),
2417 Value::Bool(v) => Ok(if *v { 1 } else { 0 }),
2418 Value::Char(v) => Ok((*v as u32).into()),
2419 Value::Int8(v) => {
2420 let n = range_check(*v, 0i8, i8::MAX, "u128")?;
2421 Ok(n as u128)
2422 }
2423 Value::Int16(v) => {
2424 let n = range_check(*v, 0i16, i16::MAX, "u128")?;
2425 Ok(n as u128)
2426 }
2427 Value::Int32(v) => {
2428 let n = range_check(*v, 0i32, i32::MAX, "u128")?;
2429 Ok(n as u128)
2430 }
2431 Value::Int64(v) => {
2432 let n = range_check(*v, 0i64, i64::MAX, "u128")?;
2433 Ok(n as u128)
2434 }
2435 Value::Int128(v) => {
2436 let n = range_check(*v, 0i128, i128::MAX, "u128")?;
2437 Ok(n as u128)
2438 }
2439 Value::String(s) => s.parse::<u128>().map_err(|_| {
2440 ValueError::ConversionError(format!("Cannot convert '{}' to u128", s))
2441 }),
2442 Value::Empty(_) => Err(ValueError::NoValue),
2443 _ => Err(ValueError::ConversionFailed {
2444 from: self.data_type(),
2445 to: DataType::UInt128,
2446 }),
2447 }
2448 }
2449}
2450
2451/// Target type `f32` supports conversion from:
2452///
2453/// - `Value::Float32`, `Value::Float64`
2454/// - `Value::Bool`
2455/// - `Value::Char`
2456/// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
2457/// `Value::Int128`
2458/// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
2459/// `Value::UInt128`
2460/// - `Value::String`, parsed as `f32`
2461/// - `Value::BigInteger`, `Value::BigDecimal`
2462impl ValueConverter<f32> for Value {
2463 fn convert(&self) -> ValueResult<f32> {
2464 match self {
2465 Value::Float32(v) => Ok(*v),
2466 Value::Float64(v) => {
2467 if v.is_nan() || v.is_infinite() {
2468 Ok(*v as f32)
2469 } else {
2470 let n = range_check(*v, f32::MIN as f64, f32::MAX as f64, "f32")?;
2471 Ok(n as f32)
2472 }
2473 }
2474 Value::Bool(v) => Ok(if *v { 1.0 } else { 0.0 }),
2475 Value::Char(v) => Ok(*v as u32 as f32),
2476 Value::Int8(v) => Ok(*v as f32),
2477 Value::Int16(v) => Ok(*v as f32),
2478 Value::Int32(v) => Ok(*v as f32),
2479 Value::Int64(v) => Ok(*v as f32),
2480 Value::Int128(v) => Ok(*v as f32),
2481 Value::UInt8(v) => Ok(*v as f32),
2482 Value::UInt16(v) => Ok(*v as f32),
2483 Value::UInt32(v) => Ok(*v as f32),
2484 Value::UInt64(v) => Ok(*v as f32),
2485 Value::UInt128(v) => Ok(*v as f32),
2486 Value::String(s) => s
2487 .parse::<f32>()
2488 .map_err(|_| ValueError::ConversionError(format!("Cannot convert '{}' to f32", s))),
2489 Value::Empty(_) => Err(ValueError::NoValue),
2490 Value::BigInteger(v) => checked_bigint_to_f32(v),
2491 Value::BigDecimal(v) => checked_bigdecimal_to_f32(v),
2492 _ => Err(ValueError::ConversionFailed {
2493 from: self.data_type(),
2494 to: DataType::Float32,
2495 }),
2496 }
2497 }
2498}
2499impl_strict_value_converter!(
2500 /// Target type `NaiveDate` supports conversion from:
2501 ///
2502 /// - `Value::Date`
2503 NaiveDate,
2504 get_date
2505);
2506impl_strict_value_converter!(
2507 /// Target type `NaiveTime` supports conversion from:
2508 ///
2509 /// - `Value::Time`
2510 NaiveTime,
2511 get_time
2512);
2513impl_strict_value_converter!(
2514 /// Target type `NaiveDateTime` supports conversion from:
2515 ///
2516 /// - `Value::DateTime`
2517 NaiveDateTime,
2518 get_datetime
2519);
2520impl_strict_value_converter!(
2521 /// Target type `DateTime<Utc>` supports conversion from:
2522 ///
2523 /// - `Value::Instant`
2524 DateTime<Utc>,
2525 get_instant
2526);
2527impl_strict_value_converter!(
2528 /// Target type `BigInt` supports conversion from:
2529 ///
2530 /// - `Value::BigInteger`
2531 BigInt,
2532 get_biginteger
2533);
2534impl_strict_value_converter!(
2535 /// Target type `BigDecimal` supports conversion from:
2536 ///
2537 /// - `Value::BigDecimal`
2538 BigDecimal,
2539 get_bigdecimal
2540);
2541impl_strict_value_converter!(
2542 /// Target type `isize` supports conversion from:
2543 ///
2544 /// - `Value::IntSize`
2545 isize,
2546 get_intsize
2547);
2548impl_strict_value_converter!(
2549 /// Target type `usize` supports conversion from:
2550 ///
2551 /// - `Value::UIntSize`
2552 usize,
2553 get_uintsize
2554);
2555impl_strict_value_converter!(
2556 /// Target type `HashMap<String, String>` supports conversion from:
2557 ///
2558 /// - `Value::StringMap`
2559 HashMap<String, String>,
2560 get_string_map
2561);