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}