• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

qubit-ltd / rs-value / 7bb4a305-cab1-4f73-ae1d-45fd12406bed

02 May 2026 05:05PM UTC coverage: 98.991% (-0.5%) from 99.488%
7bb4a305-cab1-4f73-ae1d-45fd12406bed

push

circleci

Haixing-Hu
docs: expand value README examples

1177 of 1189 relevant lines covered (98.99%)

31.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

97.92
/src/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

15
use bigdecimal::BigDecimal;
16
use chrono::{
17
    DateTime,
18
    NaiveDate,
19
    NaiveDateTime,
20
    NaiveTime,
21
    Utc,
22
};
23
use num_bigint::BigInt;
24
use serde::{
25
    Deserialize,
26
    Serialize,
27
};
28
use std::collections::HashMap;
29
use std::time::Duration;
30
use url::Url;
31

32
use qubit_datatype::{
33
    DataConversionOptions,
34
    DataConvertTo,
35
    DataConverter,
36
    DataType,
37
};
38

39
use crate::value_error::ValueResult;
40
use 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)]
77
pub 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)]
137
pub use super::value_constructor::ValueConstructor;
138
#[doc(hidden)]
139
pub use super::value_converter::ValueConverter;
140
#[doc(hidden)]
141
pub use super::value_getter::ValueGetter;
142
#[doc(hidden)]
143
pub 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
///
161
impl 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
25✔
211
    where
25✔
212
        Self: ValueConstructor<T>,
25✔
213
    {
214
        <Self as ValueConstructor<T>>::from_type(value)
25✔
215
    }
25✔
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>
55✔
282
    where
55✔
283
        Self: ValueGetter<T>,
55✔
284
    {
285
        <Self as ValueGetter<T>>::get_value(self)
55✔
286
    }
55✔
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>
1✔
294
    where
1✔
295
        Self: ValueGetter<T>,
1✔
296
    {
297
        match self.get() {
1✔
298
            Err(ValueError::NoValue) => Ok(default.into_value_default()),
1✔
299
            result => result,
×
300
        }
301
    }
1✔
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>
683✔
504
    where
683✔
505
        Self: ValueConverter<T>,
683✔
506
    {
507
        <Self as ValueConverter<T>>::convert(self)
683✔
508
    }
683✔
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>
3✔
515
    where
3✔
516
        Self: ValueConverter<T>,
3✔
517
    {
518
        match self.to() {
3✔
519
            Err(ValueError::NoValue) => Ok(default.into_value_default()),
1✔
520
            result => result,
2✔
521
        }
522
    }
3✔
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>
4✔
548
    where
4✔
549
        for<'a> DataConverter<'a>: DataConvertTo<T>,
4✔
550
    {
551
        super::value_converters::convert_with_data_converter_with(self, options)
4✔
552
    }
4✔
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>(
1✔
560
        &self,
1✔
561
        default: impl IntoValueDefault<T>,
1✔
562
        options: &DataConversionOptions,
1✔
563
    ) -> ValueResult<T>
1✔
564
    where
1✔
565
        for<'a> DataConverter<'a>: DataConvertTo<T>,
1✔
566
    {
567
        match self.to_with(options) {
1✔
568
            Err(ValueError::NoValue) => Ok(default.into_value_default()),
1✔
569
            result => result,
×
570
        }
571
    }
1✔
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<()>
38✔
634
    where
38✔
635
        Self: ValueSetter<T>,
38✔
636
    {
637
        <Self as ValueSetter<T>>::set_value(self, value)
38✔
638
    }
38✔
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 {
120✔
660
        match self {
120✔
661
            Value::Empty(dt) => *dt,
35✔
662
            Value::Bool(_) => DataType::Bool,
7✔
663
            Value::Char(_) => DataType::Char,
1✔
664
            Value::Int8(_) => DataType::Int8,
1✔
665
            Value::Int16(_) => DataType::Int16,
1✔
666
            Value::Int32(_) => DataType::Int32,
20✔
667
            Value::Int64(_) => DataType::Int64,
1✔
668
            Value::Int128(_) => DataType::Int128,
1✔
669
            Value::UInt8(_) => DataType::UInt8,
1✔
670
            Value::UInt16(_) => DataType::UInt16,
1✔
671
            Value::UInt32(_) => DataType::UInt32,
1✔
672
            Value::UInt64(_) => DataType::UInt64,
1✔
673
            Value::UInt128(_) => DataType::UInt128,
1✔
674
            Value::Float32(_) => DataType::Float32,
1✔
675
            Value::Float64(_) => DataType::Float64,
1✔
676
            Value::String(_) => DataType::String,
6✔
677
            Value::Date(_) => DataType::Date,
2✔
678
            Value::Time(_) => DataType::Time,
2✔
679
            Value::DateTime(_) => DataType::DateTime,
2✔
680
            Value::Instant(_) => DataType::Instant,
2✔
681
            Value::BigInteger(_) => DataType::BigInteger,
3✔
682
            Value::BigDecimal(_) => DataType::BigDecimal,
3✔
683
            Value::IntSize(_) => DataType::IntSize,
4✔
684
            Value::UIntSize(_) => DataType::UIntSize,
3✔
685
            Value::Duration(_) => DataType::Duration,
4✔
686
            Value::Url(_) => DataType::Url,
4✔
687
            Value::StringMap(_) => DataType::StringMap,
5✔
688
            Value::Json(_) => DataType::Json,
6✔
689
        }
690
    }
120✔
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 {
64✔
712
        matches!(self, Value::Empty(_))
64✔
713
    }
64✔
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) {
8✔
732
        let dt = self.data_type();
8✔
733
        *self = Value::Empty(dt);
8✔
734
    }
8✔
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) {
4✔
758
        if self.data_type() != data_type {
4✔
759
            *self = Value::Empty(data_type);
3✔
760
        }
3✔
761
    }
4✔
762
}
763

764
impl Default for Value {
765
    #[inline]
766
    fn default() -> Self {
2✔
767
        Value::Empty(DataType::String)
2✔
768
    }
2✔
769
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc