qubit_value/value/value.rs
1/*******************************************************************************
2 *
3 * Copyright (c) 2025 - 2026 Haixing Hu.
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 *
7 * Licensed under the Apache License, Version 2.0.
8 *
9 ******************************************************************************/
10//! # Single Value Container
11//!
12//! Provides type-safe storage and access functionality for single values.
13//!
14
15use bigdecimal::BigDecimal;
16use chrono::{
17 DateTime,
18 NaiveDate,
19 NaiveDateTime,
20 NaiveTime,
21 Utc,
22};
23use num_bigint::BigInt;
24use serde::{
25 Deserialize,
26 Serialize,
27};
28use std::collections::HashMap;
29use std::time::Duration;
30use url::Url;
31
32use qubit_datatype::{
33 DataConversionOptions,
34 DataConvertTo,
35 DataConverter,
36 DataType,
37};
38
39use crate::value_error::ValueResult;
40use crate::{
41 IntoValueDefault,
42 ValueError,
43};
44
45/// Single value container
46///
47/// Uses an enum to represent different types of values, providing
48/// type-safe value storage and access.
49///
50/// # Features
51///
52/// - Zero-cost abstraction with compile-time type checking
53/// - Supports multiple basic data types
54/// - Provides two sets of APIs for type checking and type conversion
55/// - Automatic memory management
56///
57/// # Example
58///
59/// ```rust
60/// use qubit_value::Value;
61///
62/// // Create an integer value
63/// let value = Value::Int32(42);
64/// assert_eq!(value.get_int32().unwrap(), 42);
65///
66/// // Type conversion
67/// let converted = value.to::<i64>().unwrap();
68/// assert_eq!(converted, 42i64);
69///
70/// // String value
71/// let text = Value::String("hello".to_string());
72/// assert_eq!(text.get_string().unwrap(), "hello");
73/// ```
74///
75///
76#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
77pub enum Value {
78 /// Empty value (has type but no value)
79 Empty(DataType),
80 /// Boolean value
81 Bool(bool),
82 /// Character value
83 Char(char),
84 /// 8-bit signed integer
85 Int8(i8),
86 /// 16-bit signed integer
87 Int16(i16),
88 /// 32-bit signed integer
89 Int32(i32),
90 /// 64-bit signed integer
91 Int64(i64),
92 /// 128-bit signed integer
93 Int128(i128),
94 /// 8-bit unsigned integer
95 UInt8(u8),
96 /// 16-bit unsigned integer
97 UInt16(u16),
98 /// 32-bit unsigned integer
99 UInt32(u32),
100 /// 64-bit unsigned integer
101 UInt64(u64),
102 /// 128-bit unsigned integer
103 UInt128(u128),
104 /// Platform-dependent signed integer (isize)
105 IntSize(isize),
106 /// Platform-dependent unsigned integer (usize)
107 UIntSize(usize),
108 /// 32-bit floating point number
109 Float32(f32),
110 /// 64-bit floating point number
111 Float64(f64),
112 /// Big integer type
113 BigInteger(BigInt),
114 /// Big decimal type
115 BigDecimal(BigDecimal),
116 /// String
117 String(String),
118 /// Date
119 Date(NaiveDate),
120 /// Time
121 Time(NaiveTime),
122 /// Date and time
123 DateTime(NaiveDateTime),
124 /// UTC instant
125 Instant(DateTime<Utc>),
126 /// Duration type (std::time::Duration)
127 Duration(Duration),
128 /// URL type (url::Url)
129 Url(Url),
130 /// String map type (HashMap<String, String>)
131 StringMap(HashMap<String, String>),
132 /// JSON value type (serde_json::Value)
133 Json(serde_json::Value),
134}
135
136// ============================================================================
137// Getter method generation macro
138// ============================================================================
139
140/// Unified getter generation macro
141///
142/// Supports two modes:
143/// 1. `copy:` - For types implementing the Copy trait, directly returns the value
144/// 2. `ref:` - For non-Copy types, returns a reference
145///
146/// # Documentation Comment Support
147///
148/// The macro automatically extracts preceding documentation comments, so
149/// you can add `///` comments before macro invocations.
150///
151///
152impl Value {
153 /// Generic constructor method
154 ///
155 /// Creates a `Value` from any supported type, avoiding direct use of
156 /// enum variants.
157 ///
158 /// # Supported Generic Types
159 ///
160 /// `Value::new<T>(value)` currently supports the following `T`:
161 ///
162 /// - `bool`
163 /// - `char`
164 /// - `i8`, `i16`, `i32`, `i64`, `i128`
165 /// - `u8`, `u16`, `u32`, `u64`, `u128`
166 /// - `f32`, `f64`
167 /// - `String`, `&str`
168 /// - `NaiveDate`, `NaiveTime`, `NaiveDateTime`, `DateTime<Utc>`
169 /// - `BigInt`, `BigDecimal`
170 /// - `isize`, `usize`
171 /// - `Duration`
172 /// - `Url`
173 /// - `HashMap<String, String>`
174 /// - `serde_json::Value`
175 ///
176 /// # Type Parameters
177 ///
178 /// * `T` - The type of the value to wrap
179 ///
180 /// # Returns
181 ///
182 /// Returns a `Value` wrapping the given value
183 ///
184 /// # Example
185 ///
186 /// ```rust
187 /// use qubit_value::Value;
188 ///
189 /// // Basic types
190 /// let v = Value::new(42i32);
191 /// assert_eq!(v.get_int32().unwrap(), 42);
192 ///
193 /// let v = Value::new(true);
194 /// assert_eq!(v.get_bool().unwrap(), true);
195 ///
196 /// // String
197 /// let v = Value::new("hello".to_string());
198 /// assert_eq!(v.get_string().unwrap(), "hello");
199 /// ```
200 #[inline]
201 pub fn new<T>(value: T) -> Self
202 where
203 T: Into<Self>,
204 {
205 value.into()
206 }
207
208 /// Generic getter method.
209 ///
210 /// Performs a strict typed read of the stored value as `T`.
211 ///
212 /// `get<T>()` performs strict type matching. It does not do cross-type
213 /// conversion.
214 ///
215 /// For example, `Value::Int32(42).get::<i64>()` fails, while
216 /// `Value::Int32(42).to::<i64>()` succeeds.
217 ///
218 /// # Supported Generic Types
219 ///
220 /// `Value::get<T>()` currently supports the following `T`:
221 ///
222 /// - `bool`
223 /// - `char`
224 /// - `i8`, `i16`, `i32`, `i64`, `i128`
225 /// - `u8`, `u16`, `u32`, `u64`, `u128`
226 /// - `f32`, `f64`
227 /// - `String`
228 /// - `NaiveDate`, `NaiveTime`, `NaiveDateTime`, `DateTime<Utc>`
229 /// - `BigInt`, `BigDecimal`
230 /// - `isize`, `usize`
231 /// - `Duration`
232 /// - `Url`
233 /// - `HashMap<String, String>`
234 /// - `serde_json::Value`
235 ///
236 /// # Type Parameters
237 ///
238 /// * `T` - The target type to retrieve
239 ///
240 /// # Returns
241 ///
242 /// Returns the stored value when its type matches `T`.
243 ///
244 /// # Errors
245 ///
246 /// Returns [`ValueError::NoValue`] when the value is empty with the
247 /// requested type, or [`ValueError::TypeMismatch`] when the stored type
248 /// differs from `T`.
249 ///
250 /// # Example
251 ///
252 /// ```rust
253 /// use qubit_value::Value;
254 ///
255 /// let value = Value::Int32(42);
256 ///
257 /// // Through type inference
258 /// let num: i32 = value.get().unwrap();
259 /// assert_eq!(num, 42);
260 ///
261 /// // Explicitly specify type parameter
262 /// let num = value.get::<i32>().unwrap();
263 /// assert_eq!(num, 42);
264 ///
265 /// // Different type
266 /// let text = Value::String("hello".to_string());
267 /// let s: String = text.get().unwrap();
268 /// assert_eq!(s, "hello");
269 ///
270 /// // Boolean value
271 /// let flag = Value::Bool(true);
272 /// let b: bool = flag.get().unwrap();
273 /// assert_eq!(b, true);
274 /// ```
275 #[inline]
276 pub fn get<T>(&self) -> ValueResult<T>
277 where
278 for<'a> T: TryFrom<&'a Self, Error = ValueError>,
279 {
280 T::try_from(self)
281 }
282
283 /// Generic getter method with a default value.
284 ///
285 /// Returns the supplied default only when this value is empty. Type
286 /// mismatches and conversion errors are still returned as errors.
287 #[inline]
288 pub fn get_or<T>(&self, default: impl IntoValueDefault<T>) -> ValueResult<T>
289 where
290 for<'a> T: TryFrom<&'a Self, Error = ValueError>,
291 {
292 match self.get() {
293 Err(ValueError::NoValue) => Ok(default.into_value_default()),
294 result => result,
295 }
296 }
297
298 /// Generic conversion method
299 ///
300 /// Converts the current value to the target type according to the shared
301 /// value conversion rules.
302 ///
303 /// # Supported Target Types And Source Variants
304 ///
305 /// `Value::to<T>()` currently supports the following target types:
306 ///
307 /// - `bool`
308 /// - `Value::Bool`
309 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
310 /// `Value::Int128`
311 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
312 /// `Value::UInt64`, `Value::UInt128`
313 /// - `Value::String`, parsed as `1`, `0`, or ASCII case-insensitive
314 /// `true` / `false`
315 /// - `char`
316 /// - `Value::Char`
317 /// - `i8`
318 /// - `Value::Int8`
319 /// - `Value::Bool`
320 /// - `Value::Char`
321 /// - all integer variants
322 /// - `Value::Float32`, `Value::Float64`
323 /// - `Value::String`, parsed as `i8`
324 /// - `Value::BigInteger`, `Value::BigDecimal`
325 /// - `i16`
326 /// - `Value::Int16`
327 /// - `Value::Bool`
328 /// - `Value::Char`
329 /// - all integer variants
330 /// - `Value::Float32`, `Value::Float64`
331 /// - `Value::String`, parsed as `i16`
332 /// - `Value::BigInteger`, `Value::BigDecimal`
333 /// - `i32`
334 /// - `Value::Int32`
335 /// - `Value::Bool`
336 /// - `Value::Char`
337 /// - `Value::Int8`, `Value::Int16`, `Value::Int64`, `Value::Int128`
338 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
339 /// `Value::UInt64`, `Value::UInt128`
340 /// - `Value::Float32`, `Value::Float64`
341 /// - `Value::String`, parsed as `i32`
342 /// - `Value::BigInteger`, `Value::BigDecimal`
343 /// - `i64`
344 /// - `Value::Int64`
345 /// - `Value::Bool`
346 /// - `Value::Char`
347 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int128`
348 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
349 /// `Value::UInt64`, `Value::UInt128`
350 /// - `Value::Float32`, `Value::Float64`
351 /// - `Value::String`, parsed as `i64`
352 /// - `Value::BigInteger`, `Value::BigDecimal`
353 /// - `i128`
354 /// - `Value::Int128`
355 /// - `Value::Bool`
356 /// - `Value::Char`
357 /// - all integer variants
358 /// - `Value::Float32`, `Value::Float64`
359 /// - `Value::String`, parsed as `i128`
360 /// - `Value::BigInteger`, `Value::BigDecimal`
361 /// - `u8`
362 /// - `Value::UInt8`
363 /// - `Value::Bool`
364 /// - `Value::Char`
365 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
366 /// `Value::Int128`
367 /// - `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
368 /// `Value::UInt128`
369 /// - `Value::String`, parsed as `u8`
370 /// - `u16`
371 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
372 /// `Value::UInt64`, `Value::UInt128`
373 /// - `Value::Bool`
374 /// - `Value::Char`
375 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
376 /// `Value::Int128`
377 /// - `Value::String`, parsed as `u16`
378 /// - `u32`
379 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
380 /// `Value::UInt64`, `Value::UInt128`
381 /// - `Value::Bool`
382 /// - `Value::Char`
383 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
384 /// `Value::Int128`
385 /// - `Value::String`, parsed as `u32`
386 /// - `u64`
387 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
388 /// `Value::UInt64`, `Value::UInt128`
389 /// - `Value::Bool`
390 /// - `Value::Char`
391 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
392 /// `Value::Int128`
393 /// - `Value::String`, parsed as `u64`
394 /// - `u128`
395 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
396 /// `Value::UInt64`, `Value::UInt128`
397 /// - `Value::Bool`
398 /// - `Value::Char`
399 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
400 /// `Value::Int128`
401 /// - `Value::String`, parsed as `u128`
402 /// - `f32`
403 /// - `Value::Float32`, `Value::Float64`
404 /// - `Value::Bool`
405 /// - `Value::Char`
406 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
407 /// `Value::Int128`
408 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
409 /// `Value::UInt64`, `Value::UInt128`
410 /// - `Value::String`, parsed as `f32`
411 /// - `Value::BigInteger`, `Value::BigDecimal`
412 /// - `f64`
413 /// - `Value::Float64`
414 /// - `Value::Bool`
415 /// - `Value::Char`
416 /// - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
417 /// `Value::Int128`
418 /// - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
419 /// `Value::UInt64`, `Value::UInt128`
420 /// - `Value::Float32`
421 /// - `Value::String`, parsed as `f64`
422 /// - `Value::BigInteger`, `Value::BigDecimal`
423 /// - `String`
424 /// - `Value::String`
425 /// - `Value::Bool`, `Value::Char`
426 /// - all integer and floating-point variants
427 /// - `Value::Date`, `Value::Time`, `Value::DateTime`, `Value::Instant`
428 /// - `Value::BigInteger`, `Value::BigDecimal`
429 /// - `Value::IntSize`, `Value::UIntSize`
430 /// - `Value::Duration`, formatted with the configured duration unit.
431 /// The default conversion options use milliseconds and append the
432 /// unit suffix, for example `1500ms`.
433 /// - `Value::Url`
434 /// - `Value::StringMap`, serialized as JSON text
435 /// - `Value::Json`, serialized as JSON text
436 /// - `NaiveDate`
437 /// - `Value::Date`
438 /// - `NaiveTime`
439 /// - `Value::Time`
440 /// - `NaiveDateTime`
441 /// - `Value::DateTime`
442 /// - `DateTime<Utc>`
443 /// - `Value::Instant`
444 /// - `BigInt`
445 /// - `Value::BigInteger`
446 /// - `BigDecimal`
447 /// - `Value::BigDecimal`
448 /// - `isize`
449 /// - `Value::IntSize`
450 /// - `Value::Bool`
451 /// - `Value::Char`
452 /// - all integer variants
453 /// - `Value::Float32`, `Value::Float64`
454 /// - `Value::String`, parsed as `isize`
455 /// - `Value::BigInteger`, `Value::BigDecimal`
456 /// - `usize`
457 /// - `Value::UIntSize`
458 /// - `Value::Bool`
459 /// - `Value::Char`
460 /// - all integer variants
461 /// - `Value::String`, parsed as `usize`
462 /// - `Duration`
463 /// - `Value::Duration`
464 /// - integer variants and `Value::BigInteger`, interpreted in the
465 /// configured duration unit
466 /// - `Value::String`, parsed as duration text. Explicit suffixes
467 /// `ns`, `us`, `ms`, `s`, `m`, `h`, and `d` are supported; text
468 /// without a suffix uses the configured duration unit.
469 /// - `Url`
470 /// - `Value::Url`
471 /// - `Value::String`, parsed as URL text
472 /// - `HashMap<String, String>`
473 /// - `Value::StringMap`
474 /// - `serde_json::Value`
475 /// - `Value::Json`
476 /// - `Value::String`, parsed as JSON text
477 /// - `Value::StringMap`, converted to a JSON object
478 ///
479 /// Any target type not listed above is not supported by `Value::to<T>()`.
480 ///
481 /// # Type Parameters
482 ///
483 /// * `T` - The target type to convert to
484 ///
485 /// # Returns
486 ///
487 /// Returns the converted value on success, or an error if conversion is not
488 /// supported or fails.
489 ///
490 /// # Example
491 ///
492 /// ```rust
493 /// use qubit_value::Value;
494 ///
495 /// let value = Value::Int32(42);
496 ///
497 /// let num: i64 = value.to().unwrap();
498 /// assert_eq!(num, 42);
499 ///
500 /// let text: String = value.to().unwrap();
501 /// assert_eq!(text, "42");
502 /// ```
503 #[inline]
504 pub fn to<T>(&self) -> ValueResult<T>
505 where
506 for<'a> DataConverter<'a>: DataConvertTo<T>,
507 {
508 self.to_with(&DataConversionOptions::default())
509 }
510
511 /// Converts this value to `T`, or returns `default` when it is empty.
512 ///
513 /// Conversion failures from non-empty values are preserved.
514 #[inline]
515 pub fn to_or<T>(&self, default: impl IntoValueDefault<T>) -> ValueResult<T>
516 where
517 for<'a> DataConverter<'a>: DataConvertTo<T>,
518 {
519 match self.to() {
520 Err(ValueError::NoValue) => Ok(default.into_value_default()),
521 result => result,
522 }
523 }
524
525 /// Converts this value to `T` using the provided conversion options.
526 ///
527 /// This method uses the shared [`qubit_datatype`] conversion layer directly,
528 /// so options such as string trimming, blank string handling, and boolean
529 /// aliases are applied consistently with other value containers.
530 ///
531 /// # Type Parameters
532 ///
533 /// * `T` - The target type to convert to.
534 ///
535 /// # Parameters
536 ///
537 /// * `options` - Conversion options forwarded to the shared converter.
538 ///
539 /// # Returns
540 ///
541 /// Returns the converted value on success.
542 ///
543 /// # Errors
544 ///
545 /// Returns a [`crate::ValueError`] when the value is missing, unsupported, or
546 /// invalid for `T` under the provided options.
547 #[inline]
548 pub fn to_with<T>(&self, options: &DataConversionOptions) -> ValueResult<T>
549 where
550 for<'a> DataConverter<'a>: DataConvertTo<T>,
551 {
552 super::value_converters::convert_with_data_converter_with(self, options)
553 }
554
555 /// Converts this value to `T` using conversion options, or returns
556 /// `default` when it is empty.
557 ///
558 /// Conversion failures from non-empty values are preserved.
559 #[inline]
560 pub fn to_or_with<T>(
561 &self,
562 default: impl IntoValueDefault<T>,
563 options: &DataConversionOptions,
564 ) -> ValueResult<T>
565 where
566 for<'a> DataConverter<'a>: DataConvertTo<T>,
567 {
568 match self.to_with(options) {
569 Err(ValueError::NoValue) => Ok(default.into_value_default()),
570 result => result,
571 }
572 }
573
574 /// Generic setter method
575 ///
576 /// Replaces the current value with any supported input value.
577 ///
578 /// This operation updates the stored type to `T` when needed. It does not
579 /// perform runtime type-mismatch validation against the previous variant.
580 ///
581 /// # Supported Generic Types
582 ///
583 /// `Value::set<T>(value)` currently supports the following `T`:
584 ///
585 /// - `bool`
586 /// - `char`
587 /// - `i8`, `i16`, `i32`, `i64`, `i128`
588 /// - `u8`, `u16`, `u32`, `u64`, `u128`
589 /// - `f32`, `f64`
590 /// - `String`, `&str`
591 /// - `NaiveDate`, `NaiveTime`, `NaiveDateTime`, `DateTime<Utc>`
592 /// - `BigInt`, `BigDecimal`
593 /// - `isize`, `usize`
594 /// - `Duration`
595 /// - `Url`
596 /// - `HashMap<String, String>`
597 /// - `serde_json::Value`
598 ///
599 /// # Type Parameters
600 ///
601 /// * `T` - Input type convertible into [`Value`].
602 ///
603 /// # Parameters
604 ///
605 /// * `value` - The value to set
606 ///
607 /// # Returns
608 ///
609 /// Always returns `Ok(())` for supported input types. Unsupported input
610 /// types fail to compile because they do not implement `Into<Value>`.
611 ///
612 /// # Example
613 ///
614 /// ```rust
615 /// use qubit_datatype::DataType;
616 /// use qubit_value::Value;
617 ///
618 /// let mut value = Value::Empty(DataType::Int32);
619 ///
620 /// // Through type inference
621 /// value.set(42i32).unwrap();
622 /// assert_eq!(value.get_int32().unwrap(), 42);
623 ///
624 /// // Explicitly specify type parameter
625 /// value.set::<i32>(100).unwrap();
626 /// assert_eq!(value.get_int32().unwrap(), 100);
627 ///
628 /// // String type
629 /// let mut text = Value::Empty(DataType::String);
630 /// text.set("hello".to_string()).unwrap();
631 /// assert_eq!(text.get_string().unwrap(), "hello");
632 /// ```
633 #[inline]
634 pub fn set<T>(&mut self, value: T) -> ValueResult<()>
635 where
636 T: Into<Self>,
637 {
638 *self = value.into();
639 Ok(())
640 }
641
642 /// Get the data type of the value
643 ///
644 /// # Returns
645 ///
646 /// Returns the data type corresponding to this value
647 ///
648 /// # Example
649 ///
650 /// ```rust
651 /// use qubit_datatype::DataType;
652 /// use qubit_value::Value;
653 ///
654 /// let value = Value::Int32(42);
655 /// assert_eq!(value.data_type(), DataType::Int32);
656 ///
657 /// let empty = Value::Empty(DataType::String);
658 /// assert_eq!(empty.data_type(), DataType::String);
659 /// ```
660 #[inline]
661 pub fn data_type(&self) -> DataType {
662 match self {
663 Value::Empty(dt) => *dt,
664 Value::Bool(_) => DataType::Bool,
665 Value::Char(_) => DataType::Char,
666 Value::Int8(_) => DataType::Int8,
667 Value::Int16(_) => DataType::Int16,
668 Value::Int32(_) => DataType::Int32,
669 Value::Int64(_) => DataType::Int64,
670 Value::Int128(_) => DataType::Int128,
671 Value::UInt8(_) => DataType::UInt8,
672 Value::UInt16(_) => DataType::UInt16,
673 Value::UInt32(_) => DataType::UInt32,
674 Value::UInt64(_) => DataType::UInt64,
675 Value::UInt128(_) => DataType::UInt128,
676 Value::Float32(_) => DataType::Float32,
677 Value::Float64(_) => DataType::Float64,
678 Value::String(_) => DataType::String,
679 Value::Date(_) => DataType::Date,
680 Value::Time(_) => DataType::Time,
681 Value::DateTime(_) => DataType::DateTime,
682 Value::Instant(_) => DataType::Instant,
683 Value::BigInteger(_) => DataType::BigInteger,
684 Value::BigDecimal(_) => DataType::BigDecimal,
685 Value::IntSize(_) => DataType::IntSize,
686 Value::UIntSize(_) => DataType::UIntSize,
687 Value::Duration(_) => DataType::Duration,
688 Value::Url(_) => DataType::Url,
689 Value::StringMap(_) => DataType::StringMap,
690 Value::Json(_) => DataType::Json,
691 }
692 }
693
694 /// Check if the value is empty
695 ///
696 /// # Returns
697 ///
698 /// Returns `true` if the value is empty
699 ///
700 /// # Example
701 ///
702 /// ```rust
703 /// use qubit_datatype::DataType;
704 /// use qubit_value::Value;
705 ///
706 /// let value = Value::Int32(42);
707 /// assert!(!value.is_empty());
708 ///
709 /// let empty = Value::Empty(DataType::String);
710 /// assert!(empty.is_empty());
711 /// ```
712 #[inline]
713 pub fn is_empty(&self) -> bool {
714 matches!(self, Value::Empty(_))
715 }
716
717 /// Clear the value while preserving the type
718 ///
719 /// Sets the current value to empty but retains its data type.
720 ///
721 /// # Example
722 ///
723 /// ```rust
724 /// use qubit_datatype::DataType;
725 /// use qubit_value::Value;
726 ///
727 /// let mut value = Value::Int32(42);
728 /// value.clear();
729 /// assert!(value.is_empty());
730 /// assert_eq!(value.data_type(), DataType::Int32);
731 /// ```
732 #[inline]
733 pub fn clear(&mut self) {
734 let dt = self.data_type();
735 *self = Value::Empty(dt);
736 }
737
738 /// Set the data type
739 ///
740 /// If the new type differs from the current type, clears the value
741 /// and sets the new type.
742 ///
743 /// # Parameters
744 ///
745 /// * `data_type` - The data type to set
746 ///
747 /// # Example
748 ///
749 /// ```rust
750 /// use qubit_datatype::DataType;
751 /// use qubit_value::Value;
752 ///
753 /// let mut value = Value::Int32(42);
754 /// value.set_type(DataType::String);
755 /// assert!(value.is_empty());
756 /// assert_eq!(value.data_type(), DataType::String);
757 /// ```
758 #[inline]
759 pub fn set_type(&mut self, data_type: DataType) {
760 if self.data_type() != data_type {
761 *self = Value::Empty(data_type);
762 }
763 }
764}
765
766impl Default for Value {
767 #[inline]
768 fn default() -> Self {
769 Value::Empty(DataType::String)
770 }
771}