Skip to main content

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#[doc(hidden)]
137pub use super::value_constructor::ValueConstructor;
138#[doc(hidden)]
139pub use super::value_converter::ValueConverter;
140#[doc(hidden)]
141pub use super::value_getter::ValueGetter;
142#[doc(hidden)]
143pub use super::value_setter::ValueSetter;
144
145// ============================================================================
146// Getter method generation macro
147// ============================================================================
148
149/// Unified getter generation macro
150///
151/// Supports two modes:
152/// 1. `copy:` - For types implementing the Copy trait, directly returns the value
153/// 2. `ref:` - For non-Copy types, returns a reference
154///
155/// # Documentation Comment Support
156///
157/// The macro automatically extracts preceding documentation comments, so
158/// you can add `///` comments before macro invocations.
159///
160///
161impl Value {
162    /// Generic constructor method
163    ///
164    /// Creates a `Value` from any supported type, avoiding direct use of
165    /// enum variants.
166    ///
167    /// # Supported Generic Types
168    ///
169    /// `Value::new<T>(value)` currently supports the following `T`:
170    ///
171    /// - `bool`
172    /// - `char`
173    /// - `i8`, `i16`, `i32`, `i64`, `i128`
174    /// - `u8`, `u16`, `u32`, `u64`, `u128`
175    /// - `f32`, `f64`
176    /// - `String`, `&str`
177    /// - `NaiveDate`, `NaiveTime`, `NaiveDateTime`, `DateTime<Utc>`
178    /// - `BigInt`, `BigDecimal`
179    /// - `isize`, `usize`
180    /// - `Duration`
181    /// - `Url`
182    /// - `HashMap<String, String>`
183    /// - `serde_json::Value`
184    ///
185    /// # Type Parameters
186    ///
187    /// * `T` - The type of the value to wrap
188    ///
189    /// # Returns
190    ///
191    /// Returns a `Value` wrapping the given value
192    ///
193    /// # Example
194    ///
195    /// ```rust
196    /// use qubit_value::Value;
197    ///
198    /// // Basic types
199    /// let v = Value::new(42i32);
200    /// assert_eq!(v.get_int32().unwrap(), 42);
201    ///
202    /// let v = Value::new(true);
203    /// assert_eq!(v.get_bool().unwrap(), true);
204    ///
205    /// // String
206    /// let v = Value::new("hello".to_string());
207    /// assert_eq!(v.get_string().unwrap(), "hello");
208    /// ```
209    #[inline]
210    pub fn new<T>(value: T) -> Self
211    where
212        Self: ValueConstructor<T>,
213    {
214        <Self as ValueConstructor<T>>::from_type(value)
215    }
216
217    /// Generic getter method
218    ///
219    /// Automatically selects the correct getter method based on the target
220    /// type, performing strict type checking.
221    ///
222    /// `get<T>()` performs strict type matching. It does not do cross-type
223    /// conversion.
224    ///
225    /// For example, `Value::Int32(42).get::<i64>()` fails, while
226    /// `Value::Int32(42).to::<i64>()` succeeds.
227    ///
228    /// # Supported Generic Types
229    ///
230    /// `Value::get<T>()` currently supports the following `T`:
231    ///
232    /// - `bool`
233    /// - `char`
234    /// - `i8`, `i16`, `i32`, `i64`, `i128`
235    /// - `u8`, `u16`, `u32`, `u64`, `u128`
236    /// - `f32`, `f64`
237    /// - `String`
238    /// - `NaiveDate`, `NaiveTime`, `NaiveDateTime`, `DateTime<Utc>`
239    /// - `BigInt`, `BigDecimal`
240    /// - `isize`, `usize`
241    /// - `Duration`
242    /// - `Url`
243    /// - `HashMap<String, String>`
244    /// - `serde_json::Value`
245    ///
246    /// # Type Parameters
247    ///
248    /// * `T` - The target type to retrieve
249    ///
250    /// # Returns
251    ///
252    /// If types match, returns the value of the corresponding type;
253    /// otherwise returns an error
254    ///
255    /// # Example
256    ///
257    /// ```rust
258    /// use qubit_value::Value;
259    ///
260    /// let value = Value::Int32(42);
261    ///
262    /// // Through type inference
263    /// let num: i32 = value.get().unwrap();
264    /// assert_eq!(num, 42);
265    ///
266    /// // Explicitly specify type parameter
267    /// let num = value.get::<i32>().unwrap();
268    /// assert_eq!(num, 42);
269    ///
270    /// // Different type
271    /// let text = Value::String("hello".to_string());
272    /// let s: String = text.get().unwrap();
273    /// assert_eq!(s, "hello");
274    ///
275    /// // Boolean value
276    /// let flag = Value::Bool(true);
277    /// let b: bool = flag.get().unwrap();
278    /// assert_eq!(b, true);
279    /// ```
280    #[inline]
281    pub fn get<T>(&self) -> ValueResult<T>
282    where
283        Self: ValueGetter<T>,
284    {
285        <Self as ValueGetter<T>>::get_value(self)
286    }
287
288    /// Generic getter method with a default value.
289    ///
290    /// Returns the supplied default only when this value is empty. Type
291    /// mismatches and conversion errors are still returned as errors.
292    #[inline]
293    pub fn get_or<T>(&self, default: impl IntoValueDefault<T>) -> ValueResult<T>
294    where
295        Self: ValueGetter<T>,
296    {
297        match self.get() {
298            Err(ValueError::NoValue) => Ok(default.into_value_default()),
299            result => result,
300        }
301    }
302
303    /// Generic conversion method
304    ///
305    /// Converts the current value to the target type according to the conversion
306    /// rules defined by [`ValueConverter<T>`].
307    ///
308    /// # Supported Target Types And Source Variants
309    ///
310    /// `Value::to<T>()` currently supports the following target types:
311    ///
312    /// - `bool`
313    ///   - `Value::Bool`
314    ///   - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
315    ///     `Value::Int128`
316    ///   - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
317    ///     `Value::UInt64`, `Value::UInt128`
318    ///   - `Value::String`, parsed as `1`, `0`, or ASCII case-insensitive
319    ///     `true` / `false`
320    /// - `char`
321    ///   - `Value::Char`
322    /// - `i8`
323    ///   - `Value::Int8`
324    ///   - `Value::Bool`
325    ///   - `Value::Char`
326    ///   - all integer variants
327    ///   - `Value::Float32`, `Value::Float64`
328    ///   - `Value::String`, parsed as `i8`
329    ///   - `Value::BigInteger`, `Value::BigDecimal`
330    /// - `i16`
331    ///   - `Value::Int16`
332    ///   - `Value::Bool`
333    ///   - `Value::Char`
334    ///   - all integer variants
335    ///   - `Value::Float32`, `Value::Float64`
336    ///   - `Value::String`, parsed as `i16`
337    ///   - `Value::BigInteger`, `Value::BigDecimal`
338    /// - `i32`
339    ///   - `Value::Int32`
340    ///   - `Value::Bool`
341    ///   - `Value::Char`
342    ///   - `Value::Int8`, `Value::Int16`, `Value::Int64`, `Value::Int128`
343    ///   - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
344    ///     `Value::UInt64`, `Value::UInt128`
345    ///   - `Value::Float32`, `Value::Float64`
346    ///   - `Value::String`, parsed as `i32`
347    ///   - `Value::BigInteger`, `Value::BigDecimal`
348    /// - `i64`
349    ///   - `Value::Int64`
350    ///   - `Value::Bool`
351    ///   - `Value::Char`
352    ///   - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int128`
353    ///   - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
354    ///     `Value::UInt64`, `Value::UInt128`
355    ///   - `Value::Float32`, `Value::Float64`
356    ///   - `Value::String`, parsed as `i64`
357    ///   - `Value::BigInteger`, `Value::BigDecimal`
358    /// - `i128`
359    ///   - `Value::Int128`
360    ///   - `Value::Bool`
361    ///   - `Value::Char`
362    ///   - all integer variants
363    ///   - `Value::Float32`, `Value::Float64`
364    ///   - `Value::String`, parsed as `i128`
365    ///   - `Value::BigInteger`, `Value::BigDecimal`
366    /// - `u8`
367    ///   - `Value::UInt8`
368    ///   - `Value::Bool`
369    ///   - `Value::Char`
370    ///   - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
371    ///     `Value::Int128`
372    ///   - `Value::UInt16`, `Value::UInt32`, `Value::UInt64`,
373    ///     `Value::UInt128`
374    ///   - `Value::String`, parsed as `u8`
375    /// - `u16`
376    ///   - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
377    ///     `Value::UInt64`, `Value::UInt128`
378    ///   - `Value::Bool`
379    ///   - `Value::Char`
380    ///   - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
381    ///     `Value::Int128`
382    ///   - `Value::String`, parsed as `u16`
383    /// - `u32`
384    ///   - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
385    ///     `Value::UInt64`, `Value::UInt128`
386    ///   - `Value::Bool`
387    ///   - `Value::Char`
388    ///   - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
389    ///     `Value::Int128`
390    ///   - `Value::String`, parsed as `u32`
391    /// - `u64`
392    ///   - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
393    ///     `Value::UInt64`, `Value::UInt128`
394    ///   - `Value::Bool`
395    ///   - `Value::Char`
396    ///   - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
397    ///     `Value::Int128`
398    ///   - `Value::String`, parsed as `u64`
399    /// - `u128`
400    ///   - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
401    ///     `Value::UInt64`, `Value::UInt128`
402    ///   - `Value::Bool`
403    ///   - `Value::Char`
404    ///   - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
405    ///     `Value::Int128`
406    ///   - `Value::String`, parsed as `u128`
407    /// - `f32`
408    ///   - `Value::Float32`, `Value::Float64`
409    ///   - `Value::Bool`
410    ///   - `Value::Char`
411    ///   - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
412    ///     `Value::Int128`
413    ///   - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
414    ///     `Value::UInt64`, `Value::UInt128`
415    ///   - `Value::String`, parsed as `f32`
416    ///   - `Value::BigInteger`, `Value::BigDecimal`
417    /// - `f64`
418    ///   - `Value::Float64`
419    ///   - `Value::Bool`
420    ///   - `Value::Char`
421    ///   - `Value::Int8`, `Value::Int16`, `Value::Int32`, `Value::Int64`,
422    ///     `Value::Int128`
423    ///   - `Value::UInt8`, `Value::UInt16`, `Value::UInt32`,
424    ///     `Value::UInt64`, `Value::UInt128`
425    ///   - `Value::Float32`
426    ///   - `Value::String`, parsed as `f64`
427    ///   - `Value::BigInteger`, `Value::BigDecimal`
428    /// - `String`
429    ///   - `Value::String`
430    ///   - `Value::Bool`, `Value::Char`
431    ///   - all integer and floating-point variants
432    ///   - `Value::Date`, `Value::Time`, `Value::DateTime`, `Value::Instant`
433    ///   - `Value::BigInteger`, `Value::BigDecimal`
434    ///   - `Value::IntSize`, `Value::UIntSize`
435    ///   - `Value::Duration`, formatted as `<nanoseconds>ns`
436    ///   - `Value::Url`
437    ///   - `Value::StringMap`, serialized as JSON text
438    ///   - `Value::Json`, serialized as JSON text
439    /// - `NaiveDate`
440    ///   - `Value::Date`
441    /// - `NaiveTime`
442    ///   - `Value::Time`
443    /// - `NaiveDateTime`
444    ///   - `Value::DateTime`
445    /// - `DateTime<Utc>`
446    ///   - `Value::Instant`
447    /// - `BigInt`
448    ///   - `Value::BigInteger`
449    /// - `BigDecimal`
450    ///   - `Value::BigDecimal`
451    /// - `isize`
452    ///   - `Value::IntSize`
453    ///   - `Value::Bool`
454    ///   - `Value::Char`
455    ///   - all integer variants
456    ///   - `Value::Float32`, `Value::Float64`
457    ///   - `Value::String`, parsed as `isize`
458    ///   - `Value::BigInteger`, `Value::BigDecimal`
459    /// - `usize`
460    ///   - `Value::UIntSize`
461    ///   - `Value::Bool`
462    ///   - `Value::Char`
463    ///   - all integer variants
464    ///   - `Value::String`, parsed as `usize`
465    /// - `Duration`
466    ///   - `Value::Duration`
467    ///   - `Value::String`, parsed from `<nanoseconds>ns`
468    /// - `Url`
469    ///   - `Value::Url`
470    ///   - `Value::String`, parsed as URL text
471    /// - `HashMap<String, String>`
472    ///   - `Value::StringMap`
473    /// - `serde_json::Value`
474    ///   - `Value::Json`
475    ///   - `Value::String`, parsed as JSON text
476    ///   - `Value::StringMap`, converted to a JSON object
477    ///
478    /// Any target type not listed above is not supported by `Value::to<T>()`.
479    ///
480    /// # Type Parameters
481    ///
482    /// * `T` - The target type to convert to
483    ///
484    /// # Returns
485    ///
486    /// Returns the converted value on success, or an error if conversion is not
487    /// supported or fails.
488    ///
489    /// # Example
490    ///
491    /// ```rust
492    /// use qubit_value::Value;
493    ///
494    /// let value = Value::Int32(42);
495    ///
496    /// let num: i64 = value.to().unwrap();
497    /// assert_eq!(num, 42);
498    ///
499    /// let text: String = value.to().unwrap();
500    /// assert_eq!(text, "42");
501    /// ```
502    #[inline]
503    pub fn to<T>(&self) -> ValueResult<T>
504    where
505        Self: ValueConverter<T>,
506    {
507        <Self as ValueConverter<T>>::convert(self)
508    }
509
510    /// Converts this value to `T`, or returns `default` when it is empty.
511    ///
512    /// Conversion failures from non-empty values are preserved.
513    #[inline]
514    pub fn to_or<T>(&self, default: impl IntoValueDefault<T>) -> ValueResult<T>
515    where
516        Self: ValueConverter<T>,
517    {
518        match self.to() {
519            Err(ValueError::NoValue) => Ok(default.into_value_default()),
520            result => result,
521        }
522    }
523
524    /// Converts this value to `T` using the provided conversion options.
525    ///
526    /// This method uses the shared [`qubit_datatype`] conversion layer directly,
527    /// so options such as string trimming, blank string handling, and boolean
528    /// aliases are applied consistently with other value containers.
529    ///
530    /// # Type Parameters
531    ///
532    /// * `T` - The target type to convert to.
533    ///
534    /// # Parameters
535    ///
536    /// * `options` - Conversion options forwarded to the shared converter.
537    ///
538    /// # Returns
539    ///
540    /// Returns the converted value on success.
541    ///
542    /// # Errors
543    ///
544    /// Returns a [`crate::ValueError`] when the value is missing, unsupported, or
545    /// invalid for `T` under the provided options.
546    #[inline]
547    pub fn to_with<T>(&self, options: &DataConversionOptions) -> ValueResult<T>
548    where
549        for<'a> DataConverter<'a>: DataConvertTo<T>,
550    {
551        super::value_converters::convert_with_data_converter_with(self, options)
552    }
553
554    /// Converts this value to `T` using conversion options, or returns
555    /// `default` when it is empty.
556    ///
557    /// Conversion failures from non-empty values are preserved.
558    #[inline]
559    pub fn to_or_with<T>(
560        &self,
561        default: impl IntoValueDefault<T>,
562        options: &DataConversionOptions,
563    ) -> ValueResult<T>
564    where
565        for<'a> DataConverter<'a>: DataConvertTo<T>,
566    {
567        match self.to_with(options) {
568            Err(ValueError::NoValue) => Ok(default.into_value_default()),
569            result => result,
570        }
571    }
572
573    /// Generic setter method
574    ///
575    /// Automatically selects the correct setter method based on the target
576    /// type and replaces the current 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` - The target type to set
602    ///
603    /// # Parameters
604    ///
605    /// * `value` - The value to set
606    ///
607    /// # Returns
608    ///
609    /// If setting succeeds, returns `Ok(())`; otherwise returns an error
610    ///
611    /// # Example
612    ///
613    /// ```rust
614    /// use qubit_datatype::DataType;
615    /// use qubit_value::Value;
616    ///
617    /// let mut value = Value::Empty(DataType::Int32);
618    ///
619    /// // Through type inference
620    /// value.set(42i32).unwrap();
621    /// assert_eq!(value.get_int32().unwrap(), 42);
622    ///
623    /// // Explicitly specify type parameter
624    /// value.set::<i32>(100).unwrap();
625    /// assert_eq!(value.get_int32().unwrap(), 100);
626    ///
627    /// // String type
628    /// let mut text = Value::Empty(DataType::String);
629    /// text.set("hello".to_string()).unwrap();
630    /// assert_eq!(text.get_string().unwrap(), "hello");
631    /// ```
632    #[inline]
633    pub fn set<T>(&mut self, value: T) -> ValueResult<()>
634    where
635        Self: ValueSetter<T>,
636    {
637        <Self as ValueSetter<T>>::set_value(self, value)
638    }
639
640    /// Get the data type of the value
641    ///
642    /// # Returns
643    ///
644    /// Returns the data type corresponding to this value
645    ///
646    /// # Example
647    ///
648    /// ```rust
649    /// use qubit_datatype::DataType;
650    /// use qubit_value::Value;
651    ///
652    /// let value = Value::Int32(42);
653    /// assert_eq!(value.data_type(), DataType::Int32);
654    ///
655    /// let empty = Value::Empty(DataType::String);
656    /// assert_eq!(empty.data_type(), DataType::String);
657    /// ```
658    #[inline]
659    pub fn data_type(&self) -> DataType {
660        match self {
661            Value::Empty(dt) => *dt,
662            Value::Bool(_) => DataType::Bool,
663            Value::Char(_) => DataType::Char,
664            Value::Int8(_) => DataType::Int8,
665            Value::Int16(_) => DataType::Int16,
666            Value::Int32(_) => DataType::Int32,
667            Value::Int64(_) => DataType::Int64,
668            Value::Int128(_) => DataType::Int128,
669            Value::UInt8(_) => DataType::UInt8,
670            Value::UInt16(_) => DataType::UInt16,
671            Value::UInt32(_) => DataType::UInt32,
672            Value::UInt64(_) => DataType::UInt64,
673            Value::UInt128(_) => DataType::UInt128,
674            Value::Float32(_) => DataType::Float32,
675            Value::Float64(_) => DataType::Float64,
676            Value::String(_) => DataType::String,
677            Value::Date(_) => DataType::Date,
678            Value::Time(_) => DataType::Time,
679            Value::DateTime(_) => DataType::DateTime,
680            Value::Instant(_) => DataType::Instant,
681            Value::BigInteger(_) => DataType::BigInteger,
682            Value::BigDecimal(_) => DataType::BigDecimal,
683            Value::IntSize(_) => DataType::IntSize,
684            Value::UIntSize(_) => DataType::UIntSize,
685            Value::Duration(_) => DataType::Duration,
686            Value::Url(_) => DataType::Url,
687            Value::StringMap(_) => DataType::StringMap,
688            Value::Json(_) => DataType::Json,
689        }
690    }
691
692    /// Check if the value is empty
693    ///
694    /// # Returns
695    ///
696    /// Returns `true` if the value is empty
697    ///
698    /// # Example
699    ///
700    /// ```rust
701    /// use qubit_datatype::DataType;
702    /// use qubit_value::Value;
703    ///
704    /// let value = Value::Int32(42);
705    /// assert!(!value.is_empty());
706    ///
707    /// let empty = Value::Empty(DataType::String);
708    /// assert!(empty.is_empty());
709    /// ```
710    #[inline]
711    pub fn is_empty(&self) -> bool {
712        matches!(self, Value::Empty(_))
713    }
714
715    /// Clear the value while preserving the type
716    ///
717    /// Sets the current value to empty but retains its data type.
718    ///
719    /// # Example
720    ///
721    /// ```rust
722    /// use qubit_datatype::DataType;
723    /// use qubit_value::Value;
724    ///
725    /// let mut value = Value::Int32(42);
726    /// value.clear();
727    /// assert!(value.is_empty());
728    /// assert_eq!(value.data_type(), DataType::Int32);
729    /// ```
730    #[inline]
731    pub fn clear(&mut self) {
732        let dt = self.data_type();
733        *self = Value::Empty(dt);
734    }
735
736    /// Set the data type
737    ///
738    /// If the new type differs from the current type, clears the value
739    /// and sets the new type.
740    ///
741    /// # Parameters
742    ///
743    /// * `data_type` - The data type to set
744    ///
745    /// # Example
746    ///
747    /// ```rust
748    /// use qubit_datatype::DataType;
749    /// use qubit_value::Value;
750    ///
751    /// let mut value = Value::Int32(42);
752    /// value.set_type(DataType::String);
753    /// assert!(value.is_empty());
754    /// assert_eq!(value.data_type(), DataType::String);
755    /// ```
756    #[inline]
757    pub fn set_type(&mut self, data_type: DataType) {
758        if self.data_type() != data_type {
759            *self = Value::Empty(data_type);
760        }
761    }
762}
763
764impl Default for Value {
765    #[inline]
766    fn default() -> Self {
767        Value::Empty(DataType::String)
768    }
769}