Skip to main content

qubit_value/value/
value_accessors.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
11use std::collections::HashMap;
12use std::time::Duration;
13
14use bigdecimal::BigDecimal;
15use chrono::{
16    DateTime,
17    NaiveDate,
18    NaiveDateTime,
19    NaiveTime,
20    Utc,
21};
22use num_bigint::BigInt;
23use serde::Serialize;
24use serde::de::DeserializeOwned;
25use url::Url;
26
27use qubit_datatype::{
28    DataConversionError,
29    DataType,
30};
31
32use super::value::Value;
33use crate::value_error::{
34    ValueError,
35    ValueResult,
36    map_data_conversion_error,
37};
38
39macro_rules! impl_get_value {
40    // Copy type: directly dereference and return
41    ($(#[$attr:meta])* copy: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
42        $(#[$attr])*
43        #[doc = ""]
44        #[doc = "# Errors"]
45        #[doc = ""]
46        #[doc = "Returns [`ValueError::NoValue`] when the value is empty with"]
47        #[doc = "the requested type, or [`ValueError::TypeMismatch`] when the"]
48        #[doc = "stored data type differs."]
49        #[inline]
50        pub fn $method(&self) -> ValueResult<$type> {
51            match self {
52                Value::$variant(v) => Ok(*v),
53                Value::Empty(dt) if *dt == $data_type => Err(ValueError::NoValue),
54                Value::Empty(dt) => Err(ValueError::TypeMismatch {
55                    expected: $data_type,
56                    actual: *dt,
57                }),
58                _ => Err(ValueError::TypeMismatch {
59                    expected: $data_type,
60                    actual: self.data_type(),
61                }),
62            }
63        }
64    };
65
66    // Reference type: use conversion function to return reference,
67    // fixing lifetime issues
68    ($(#[$attr:meta])* ref: $method:ident, $variant:ident, $ret_type:ty, $data_type:expr, $conversion:expr) => {
69        $(#[$attr])*
70        #[doc = ""]
71        #[doc = "# Errors"]
72        #[doc = ""]
73        #[doc = "Returns [`ValueError::NoValue`] when the value is empty with"]
74        #[doc = "the requested type, or [`ValueError::TypeMismatch`] when the"]
75        #[doc = "stored data type differs."]
76        #[inline]
77        pub fn $method(&self) -> ValueResult<$ret_type> {
78            match self {
79                Value::$variant(v) => {
80                    let conv_fn: fn(&_) -> $ret_type = $conversion;
81                    Ok(conv_fn(v))
82                },
83                Value::Empty(dt) if *dt == $data_type => Err(ValueError::NoValue),
84                Value::Empty(dt) => Err(ValueError::TypeMismatch {
85                    expected: $data_type,
86                    actual: *dt,
87                }),
88                _ => Err(ValueError::TypeMismatch {
89                    expected: $data_type,
90                    actual: self.data_type(),
91                }),
92            }
93        }
94    };
95}
96
97/// Unified setter generation macro
98///
99/// Supports two modes:
100/// 1. `copy:` - For types implementing the Copy trait, directly sets the value
101/// 2. `owned:` - For non-Copy types, requires owning the value
102///
103/// # Documentation Comment Support
104///
105/// The macro automatically extracts preceding documentation comments, so
106/// you can add `///` comments before macro invocations.
107///
108///
109macro_rules! impl_set_value {
110    // Copy type: directly set the value
111    ($(#[$attr:meta])* copy: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
112        $(#[$attr])*
113        #[inline]
114        pub fn $method(&mut self, value: $type) -> ValueResult<()> {
115            *self = Value::$variant(value);
116            Ok(())
117        }
118    };
119
120    // Owned type: set the owned value
121    ($(#[$attr:meta])* owned: $method:ident, $variant:ident, $type:ty, $data_type:expr) => {
122        $(#[$attr])*
123        #[inline]
124        pub fn $method(&mut self, value: $type) -> ValueResult<()> {
125            *self = Value::$variant(value);
126            Ok(())
127        }
128    };
129}
130
131impl Value {
132    // ========================================================================
133    // Type-checking getters (strict type matching)
134    // ========================================================================
135
136    impl_get_value! {
137        /// Get boolean value
138        ///
139        /// # Returns
140        ///
141        /// If types match, returns the boolean value; see `# Errors`.
142        ///
143        /// # Example
144        ///
145        /// ```rust
146        /// use qubit_value::Value;
147        ///
148        /// let value = Value::Bool(true);
149        /// assert_eq!(value.get_bool().unwrap(), true);
150        /// ```
151        copy: get_bool, Bool, bool, DataType::Bool
152    }
153
154    impl_get_value! {
155        /// Get character value
156        ///
157        /// # Returns
158        ///
159        /// If types match, returns the character value; see `# Errors`.
160        ///
161        /// # Example
162        ///
163        /// ```rust
164        /// use qubit_value::Value;
165        ///
166        /// let value = Value::Char('A');
167        /// assert_eq!(value.get_char().unwrap(), 'A');
168        /// ```
169        copy: get_char, Char, char, DataType::Char
170    }
171
172    impl_get_value! {
173        /// Get int8 value
174        ///
175        /// # Returns
176        ///
177        /// If types match, returns the int8 value; see `# Errors`.
178        copy: get_int8, Int8, i8, DataType::Int8
179    }
180
181    impl_get_value! {
182        /// Get int16 value
183        ///
184        /// # Returns
185        ///
186        /// If types match, returns the int16 value; see `# Errors`.
187        copy: get_int16, Int16, i16, DataType::Int16
188    }
189
190    impl_get_value! {
191        /// Get int32 value
192        ///
193        /// # Returns
194        ///
195        /// If types match, returns the int32 value; see `# Errors`.
196        copy: get_int32, Int32, i32, DataType::Int32
197    }
198
199    impl_get_value! {
200        /// Get int64 value
201        ///
202        /// # Returns
203        ///
204        /// If types match, returns the int64 value; see `# Errors`.
205        copy: get_int64, Int64, i64, DataType::Int64
206    }
207
208    impl_get_value! {
209        /// Get int128 value
210        ///
211        /// # Returns
212        ///
213        /// If types match, returns the int128 value; see `# Errors`.
214        copy: get_int128, Int128, i128, DataType::Int128
215    }
216
217    impl_get_value! {
218        /// Get uint8 value
219        ///
220        /// # Returns
221        ///
222        /// If types match, returns the uint8 value; see `# Errors`.
223        copy: get_uint8, UInt8, u8, DataType::UInt8
224    }
225
226    impl_get_value! {
227        /// Get uint16 value
228        ///
229        /// # Returns
230        ///
231        /// If types match, returns the uint16 value; see `# Errors`.
232        copy: get_uint16, UInt16, u16, DataType::UInt16
233    }
234
235    impl_get_value! {
236        /// Get uint32 value
237        ///
238        /// # Returns
239        ///
240        /// If types match, returns the uint32 value; see `# Errors`.
241        copy: get_uint32, UInt32, u32, DataType::UInt32
242    }
243
244    impl_get_value! {
245        /// Get uint64 value
246        ///
247        /// # Returns
248        ///
249        /// If types match, returns the uint64 value; see `# Errors`.
250        copy: get_uint64, UInt64, u64, DataType::UInt64
251    }
252
253    impl_get_value! {
254        /// Get uint128 value
255        ///
256        /// # Returns
257        ///
258        /// If types match, returns the uint128 value; see `# Errors`.
259        copy: get_uint128, UInt128, u128, DataType::UInt128
260    }
261
262    impl_get_value! {
263        /// Get float32 value
264        ///
265        /// # Returns
266        ///
267        /// If types match, returns the float32 value; see `# Errors`.
268        copy: get_float32, Float32, f32, DataType::Float32
269    }
270
271    impl_get_value! {
272        /// Get float64 value
273        ///
274        /// # Returns
275        ///
276        /// If types match, returns the float64 value; see `# Errors`.
277        copy: get_float64, Float64, f64, DataType::Float64
278    }
279
280    impl_get_value! {
281        /// Get string reference
282        ///
283        /// # Returns
284        ///
285        /// If types match, returns a reference to the string; see `# Errors`.
286        ///
287        /// # Example
288        ///
289        /// ```rust
290        /// use qubit_value::Value;
291        ///
292        /// let value = Value::String("hello".to_string());
293        /// assert_eq!(value.get_string().unwrap(), "hello");
294        /// ```
295        ref: get_string, String, &str, DataType::String, |s: &String| s.as_str()
296    }
297
298    impl_get_value! {
299        /// Get date value
300        ///
301        /// # Returns
302        ///
303        /// If types match, returns the date value; see `# Errors`.
304        copy: get_date, Date, NaiveDate, DataType::Date
305    }
306
307    impl_get_value! {
308        /// Get time value
309        ///
310        /// # Returns
311        ///
312        /// If types match, returns the time value; see `# Errors`.
313        copy: get_time, Time, NaiveTime, DataType::Time
314    }
315
316    impl_get_value! {
317        /// Get datetime value
318        ///
319        /// # Returns
320        ///
321        /// If types match, returns the datetime value; see `# Errors`.
322        copy: get_datetime, DateTime, NaiveDateTime, DataType::DateTime
323    }
324
325    impl_get_value! {
326        /// Get UTC instant value
327        ///
328        /// # Returns
329        ///
330        /// If types match, returns the UTC instant value; see `# Errors`.
331        copy: get_instant, Instant, DateTime<Utc>, DataType::Instant
332    }
333
334    impl_get_value! {
335        /// Get big integer value.
336        ///
337        /// This method returns a cloned [`BigInt`]. Use
338        /// [`Value::get_biginteger_ref`] to borrow the stored value without
339        /// cloning.
340        ///
341        /// # Returns
342        ///
343        /// If types match, returns the big integer value; see `# Errors`.
344        ///
345        /// # Example
346        ///
347        /// ```rust
348        /// use qubit_value::Value;
349        /// use num_bigint::BigInt;
350        ///
351        /// let value = Value::BigInteger(BigInt::from(123456789));
352        /// assert_eq!(value.get_biginteger().unwrap(), BigInt::from(123456789));
353        /// ```
354        ref: get_biginteger, BigInteger, BigInt, DataType::BigInteger, |v: &BigInt| v.clone()
355    }
356
357    impl_get_value! {
358        /// Get big decimal value.
359        ///
360        /// This method returns a cloned [`BigDecimal`]. Use
361        /// [`Value::get_bigdecimal_ref`] to borrow the stored value without
362        /// cloning.
363        ///
364        /// # Returns
365        ///
366        /// If types match, returns the big decimal value; see `# Errors`.
367        ///
368        /// # Example
369        ///
370        /// ```rust
371        /// use std::str::FromStr;
372        ///
373        /// use bigdecimal::BigDecimal;
374        /// use qubit_value::Value;
375        ///
376        /// let bd = BigDecimal::from_str("123.456").unwrap();
377        /// let value = Value::BigDecimal(bd.clone());
378        /// assert_eq!(value.get_bigdecimal().unwrap(), bd);
379        /// ```
380        ref: get_bigdecimal, BigDecimal, BigDecimal, DataType::BigDecimal, |v: &BigDecimal| v.clone()
381    }
382
383    // ========================================================================
384    // Type-setting setters (strict type matching)
385    // ========================================================================
386
387    impl_set_value! {
388        /// Set boolean value
389        ///
390        /// # Parameters
391        ///
392        /// * `value` - The boolean value to set
393        ///
394        /// # Returns
395        ///
396        /// Always returns `Ok(())` for this supported setter.
397        ///
398        /// # Example
399        ///
400        /// ```rust
401        /// use qubit_datatype::DataType;
402        /// use qubit_value::Value;
403        ///
404        /// let mut value = Value::Empty(DataType::Bool);
405        /// value.set_bool(true).unwrap();
406        /// assert_eq!(value.get_bool().unwrap(), true);
407        /// ```
408        copy: set_bool, Bool, bool, DataType::Bool
409    }
410
411    impl_set_value! {
412        /// Set character value
413        ///
414        /// # Parameters
415        ///
416        /// * `value` - The character value to set
417        ///
418        /// # Returns
419        ///
420        /// Always returns `Ok(())` for this supported setter.
421        copy: set_char, Char, char, DataType::Char
422    }
423
424    impl_set_value! {
425        /// Set int8 value
426        ///
427        /// # Parameters
428        ///
429        /// * `value` - The int8 value to set
430        ///
431        /// # Returns
432        ///
433        /// Always returns `Ok(())` for this supported setter.
434        copy: set_int8, Int8, i8, DataType::Int8
435    }
436
437    impl_set_value! {
438        /// Set int16 value
439        ///
440        /// # Parameters
441        ///
442        /// * `value` - The int16 value to set
443        ///
444        /// # Returns
445        ///
446        /// Always returns `Ok(())` for this supported setter.
447        copy: set_int16, Int16, i16, DataType::Int16
448    }
449
450    impl_set_value! {
451        /// Set int32 value
452        ///
453        /// # Parameters
454        ///
455        /// * `value` - The int32 value to set
456        ///
457        /// # Returns
458        ///
459        /// Always returns `Ok(())` for this supported setter.
460        copy: set_int32, Int32, i32, DataType::Int32
461    }
462
463    impl_set_value! {
464        /// Set int64 value
465        ///
466        /// # Parameters
467        ///
468        /// * `value` - The int64 value to set
469        ///
470        /// # Returns
471        ///
472        /// Always returns `Ok(())` for this supported setter.
473        copy: set_int64, Int64, i64, DataType::Int64
474    }
475
476    impl_set_value! {
477        /// Set int128 value
478        ///
479        /// # Parameters
480        ///
481        /// * `value` - The int128 value to set
482        ///
483        /// # Returns
484        ///
485        /// Always returns `Ok(())` for this supported setter.
486        copy: set_int128, Int128, i128, DataType::Int128
487    }
488
489    impl_set_value! {
490        /// Set uint8 value
491        ///
492        /// # Parameters
493        ///
494        /// * `value` - The uint8 value to set
495        ///
496        /// # Returns
497        ///
498        /// Always returns `Ok(())` for this supported setter.
499        copy: set_uint8, UInt8, u8, DataType::UInt8
500    }
501
502    impl_set_value! {
503        /// Set uint16 value
504        ///
505        /// # Parameters
506        ///
507        /// * `value` - The uint16 value to set
508        ///
509        /// # Returns
510        ///
511        /// Always returns `Ok(())` for this supported setter.
512        copy: set_uint16, UInt16, u16, DataType::UInt16
513    }
514
515    impl_set_value! {
516        /// Set uint32 value
517        ///
518        /// # Parameters
519        ///
520        /// * `value` - The uint32 value to set
521        ///
522        /// # Returns
523        ///
524        /// Always returns `Ok(())` for this supported setter.
525        copy: set_uint32, UInt32, u32, DataType::UInt32
526    }
527
528    impl_set_value! {
529        /// Set uint64 value
530        ///
531        /// # Parameters
532        ///
533        /// * `value` - The uint64 value to set
534        ///
535        /// # Returns
536        ///
537        /// Always returns `Ok(())` for this supported setter.
538        copy: set_uint64, UInt64, u64, DataType::UInt64
539    }
540
541    impl_set_value! {
542        /// Set uint128 value
543        ///
544        /// # Parameters
545        ///
546        /// * `value` - The uint128 value to set
547        ///
548        /// # Returns
549        ///
550        /// Always returns `Ok(())` for this supported setter.
551        copy: set_uint128, UInt128, u128, DataType::UInt128
552    }
553
554    impl_set_value! {
555        /// Set float32 value
556        ///
557        /// # Parameters
558        ///
559        /// * `value` - The float32 value to set
560        ///
561        /// # Returns
562        ///
563        /// Always returns `Ok(())` for this supported setter.
564        copy: set_float32, Float32, f32, DataType::Float32
565    }
566
567    impl_set_value! {
568        /// Set float64 value
569        ///
570        /// # Parameters
571        ///
572        /// * `value` - The float64 value to set
573        ///
574        /// # Returns
575        ///
576        /// Always returns `Ok(())` for this supported setter.
577        copy: set_float64, Float64, f64, DataType::Float64
578    }
579
580    impl_set_value! {
581        /// Set string value
582        ///
583        /// # Parameters
584        ///
585        /// * `value` - The string value to set
586        ///
587        /// # Returns
588        ///
589        /// Always returns `Ok(())` for this supported setter.
590        ///
591        /// # Example
592        ///
593        /// ```rust
594        /// use qubit_datatype::DataType;
595        /// use qubit_value::Value;
596        ///
597        /// let mut value = Value::Empty(DataType::String);
598        /// value.set_string("hello".to_string()).unwrap();
599        /// assert_eq!(value.get_string().unwrap(), "hello");
600        /// ```
601        owned: set_string, String, String, DataType::String
602    }
603
604    impl_set_value! {
605        /// Set date value
606        ///
607        /// # Parameters
608        ///
609        /// * `value` - The date value to set
610        ///
611        /// # Returns
612        ///
613        /// Always returns `Ok(())` for this supported setter.
614        copy: set_date, Date, NaiveDate, DataType::Date
615    }
616
617    impl_set_value! {
618        /// Set time value
619        ///
620        /// # Parameters
621        ///
622        /// * `value` - The time value to set
623        ///
624        /// # Returns
625        ///
626        /// Always returns `Ok(())` for this supported setter.
627        copy: set_time, Time, NaiveTime, DataType::Time
628    }
629
630    impl_set_value! {
631        /// Set datetime value
632        ///
633        /// # Parameters
634        ///
635        /// * `value` - The datetime value to set
636        ///
637        /// # Returns
638        ///
639        /// Always returns `Ok(())` for this supported setter.
640        copy: set_datetime, DateTime, NaiveDateTime, DataType::DateTime
641    }
642
643    impl_set_value! {
644        /// Set UTC instant value
645        ///
646        /// # Parameters
647        ///
648        /// * `value` - The UTC instant value to set
649        ///
650        /// # Returns
651        ///
652        /// Always returns `Ok(())` for this supported setter.
653        copy: set_instant, Instant, DateTime<Utc>, DataType::Instant
654    }
655
656    impl_set_value! {
657        /// Set big integer value
658        ///
659        /// # Parameters
660        ///
661        /// * `value` - The big integer value to set
662        ///
663        /// # Returns
664        ///
665        /// Always returns `Ok(())` for this supported setter.
666        ///
667        /// # Example
668        ///
669        /// ```rust
670        /// use num_bigint::BigInt;
671        /// use qubit_datatype::DataType;
672        /// use qubit_value::Value;
673        ///
674        /// let mut value = Value::Empty(DataType::BigInteger);
675        /// value.set_biginteger(BigInt::from(123456789)).unwrap();
676        /// assert_eq!(value.get_biginteger().unwrap(), BigInt::from(123456789));
677        /// ```
678        owned: set_biginteger, BigInteger, BigInt, DataType::BigInteger
679    }
680
681    impl_set_value! {
682        /// Set big decimal value
683        ///
684        /// # Parameters
685        ///
686        /// * `value` - The big decimal value to set
687        ///
688        /// # Returns
689        ///
690        /// Always returns `Ok(())` for this supported setter.
691        ///
692        /// # Example
693        ///
694        /// ```rust
695        /// use std::str::FromStr;
696        ///
697        /// use bigdecimal::BigDecimal;
698        /// use qubit_datatype::DataType;
699        /// use qubit_value::Value;
700        ///
701        /// let mut value = Value::Empty(DataType::BigDecimal);
702        /// let bd = BigDecimal::from_str("123.456").unwrap();
703        /// value.set_bigdecimal(bd.clone()).unwrap();
704        /// assert_eq!(value.get_bigdecimal().unwrap(), bd);
705        /// ```
706        owned: set_bigdecimal, BigDecimal, BigDecimal, DataType::BigDecimal
707    }
708
709    impl_get_value! {
710        /// Get isize value
711        ///
712        /// # Returns
713        ///
714        /// If types match, returns the isize value; see `# Errors`.
715        copy: get_intsize, IntSize, isize, DataType::IntSize
716    }
717
718    impl_get_value! {
719        /// Get usize value
720        ///
721        /// # Returns
722        ///
723        /// If types match, returns the usize value; see `# Errors`.
724        copy: get_uintsize, UIntSize, usize, DataType::UIntSize
725    }
726
727    impl_get_value! {
728        /// Get Duration value
729        ///
730        /// # Returns
731        ///
732        /// If types match, returns the Duration value; see `# Errors`.
733        copy: get_duration, Duration, Duration, DataType::Duration
734    }
735
736    impl_get_value! {
737        /// Get URL value.
738        ///
739        /// This method returns a cloned [`Url`]. Use [`Value::get_url_ref`] to
740        /// borrow the stored value without cloning.
741        ///
742        /// # Returns
743        ///
744        /// If types match, returns the URL value; see `# Errors`.
745        ref: get_url, Url, Url, DataType::Url, |v: &Url| v.clone()
746    }
747
748    impl_get_value! {
749        /// Get string map value.
750        ///
751        /// This method returns a cloned `HashMap<String, String>`. Use
752        /// [`Value::get_string_map_ref`] to borrow the stored value without
753        /// cloning.
754        ///
755        /// # Returns
756        ///
757        /// If types match, returns the string map value; see `# Errors`.
758        ref: get_string_map, StringMap, HashMap<String, String>, DataType::StringMap,
759            |v: &HashMap<String, String>| v.clone()
760    }
761
762    impl_get_value! {
763        /// Get JSON value.
764        ///
765        /// This method returns a cloned [`serde_json::Value`]. Use
766        /// [`Value::get_json_ref`] to borrow the stored value without cloning.
767        ///
768        /// # Returns
769        ///
770        /// If types match, returns the JSON value; see `# Errors`.
771        ref: get_json, Json, serde_json::Value, DataType::Json,
772            |v: &serde_json::Value| v.clone()
773    }
774
775    /// Borrow the inner `BigInt` without cloning.
776    ///
777    /// # Errors
778    ///
779    /// Returns [`ValueError::NoValue`] when the value is empty with
780    /// `DataType::BigInteger`, or [`ValueError::TypeMismatch`] when the stored
781    /// data type differs.
782    pub fn get_biginteger_ref(&self) -> ValueResult<&BigInt> {
783        match self {
784            Value::BigInteger(v) => Ok(v),
785            Value::Empty(dt) if *dt == DataType::BigInteger => Err(ValueError::NoValue),
786            Value::Empty(dt) => Err(ValueError::TypeMismatch {
787                expected: DataType::BigInteger,
788                actual: *dt,
789            }),
790            _ => Err(ValueError::TypeMismatch {
791                expected: DataType::BigInteger,
792                actual: self.data_type(),
793            }),
794        }
795    }
796
797    /// Borrow the inner `BigDecimal` without cloning.
798    ///
799    /// # Errors
800    ///
801    /// Returns [`ValueError::NoValue`] when the value is empty with
802    /// `DataType::BigDecimal`, or [`ValueError::TypeMismatch`] when the stored
803    /// data type differs.
804    pub fn get_bigdecimal_ref(&self) -> ValueResult<&BigDecimal> {
805        match self {
806            Value::BigDecimal(v) => Ok(v),
807            Value::Empty(dt) if *dt == DataType::BigDecimal => Err(ValueError::NoValue),
808            Value::Empty(dt) => Err(ValueError::TypeMismatch {
809                expected: DataType::BigDecimal,
810                actual: *dt,
811            }),
812            _ => Err(ValueError::TypeMismatch {
813                expected: DataType::BigDecimal,
814                actual: self.data_type(),
815            }),
816        }
817    }
818
819    /// Borrow the inner `Url` without cloning.
820    ///
821    /// # Errors
822    ///
823    /// Returns [`ValueError::NoValue`] when the value is empty with
824    /// `DataType::Url`, or [`ValueError::TypeMismatch`] when the stored data
825    /// type differs.
826    pub fn get_url_ref(&self) -> ValueResult<&Url> {
827        match self {
828            Value::Url(v) => Ok(v),
829            Value::Empty(dt) if *dt == DataType::Url => Err(ValueError::NoValue),
830            Value::Empty(dt) => Err(ValueError::TypeMismatch {
831                expected: DataType::Url,
832                actual: *dt,
833            }),
834            _ => Err(ValueError::TypeMismatch {
835                expected: DataType::Url,
836                actual: self.data_type(),
837            }),
838        }
839    }
840
841    /// Borrow the inner `HashMap<String, String>` without cloning.
842    ///
843    /// # Errors
844    ///
845    /// Returns [`ValueError::NoValue`] when the value is empty with
846    /// `DataType::StringMap`, or [`ValueError::TypeMismatch`] when the stored
847    /// data type differs.
848    pub fn get_string_map_ref(&self) -> ValueResult<&HashMap<String, String>> {
849        match self {
850            Value::StringMap(v) => Ok(v),
851            Value::Empty(dt) if *dt == DataType::StringMap => Err(ValueError::NoValue),
852            Value::Empty(dt) => Err(ValueError::TypeMismatch {
853                expected: DataType::StringMap,
854                actual: *dt,
855            }),
856            _ => Err(ValueError::TypeMismatch {
857                expected: DataType::StringMap,
858                actual: self.data_type(),
859            }),
860        }
861    }
862
863    /// Borrow the inner JSON value without cloning.
864    ///
865    /// # Errors
866    ///
867    /// Returns [`ValueError::NoValue`] when the value is empty with
868    /// `DataType::Json`, or [`ValueError::TypeMismatch`] when the stored data
869    /// type differs.
870    pub fn get_json_ref(&self) -> ValueResult<&serde_json::Value> {
871        match self {
872            Value::Json(v) => Ok(v),
873            Value::Empty(dt) if *dt == DataType::Json => Err(ValueError::NoValue),
874            Value::Empty(dt) => Err(ValueError::TypeMismatch {
875                expected: DataType::Json,
876                actual: *dt,
877            }),
878            _ => Err(ValueError::TypeMismatch {
879                expected: DataType::Json,
880                actual: self.data_type(),
881            }),
882        }
883    }
884
885    impl_set_value! {
886        /// Set isize value
887        copy: set_intsize, IntSize, isize, DataType::IntSize
888    }
889
890    impl_set_value! {
891        /// Set usize value
892        copy: set_uintsize, UIntSize, usize, DataType::UIntSize
893    }
894
895    impl_set_value! {
896        /// Set Duration value
897        copy: set_duration, Duration, Duration, DataType::Duration
898    }
899
900    impl_set_value! {
901        /// Set Url value
902        owned: set_url, Url, Url, DataType::Url
903    }
904
905    impl_set_value! {
906        /// Set StringMap value
907        owned: set_string_map, StringMap, HashMap<String, String>, DataType::StringMap
908    }
909
910    impl_set_value! {
911        /// Set Json value
912        owned: set_json, Json, serde_json::Value, DataType::Json
913    }
914
915    /// Create a `Value` from a `serde_json::Value`.
916    ///
917    /// # Parameters
918    ///
919    /// * `json` - The JSON value to wrap.
920    ///
921    /// # Returns
922    ///
923    /// Returns a `Value::Json` wrapping the given JSON value.
924    #[inline]
925    pub fn from_json_value(json: serde_json::Value) -> Self {
926        Value::Json(json)
927    }
928
929    /// Create a `Value` from any serializable value by converting it to JSON.
930    ///
931    /// # Type Parameters
932    ///
933    /// * `T` - Any type implementing `Serialize`.
934    ///
935    /// # Parameters
936    ///
937    /// * `value` - The value to serialize into JSON.
938    ///
939    /// # Returns
940    ///
941    /// Returns `Ok(Value::Json(...))` on success, or an error if
942    /// serialization fails.
943    pub fn from_serializable<T: Serialize>(value: &T) -> ValueResult<Self> {
944        let json = serde_json::to_value(value).map_err(|error| {
945            map_data_conversion_error(DataConversionError::JsonSerializationError(
946                error.to_string(),
947            ))
948        })?;
949        Ok(Value::Json(json))
950    }
951
952    /// Deserialize the inner JSON value into a target type.
953    ///
954    /// Only works when `self` is `Value::Json(...)`.
955    ///
956    /// # Type Parameters
957    ///
958    /// * `T` - The target type implementing `DeserializeOwned`.
959    ///
960    /// # Returns
961    ///
962    /// Returns `Ok(T)` on success.
963    ///
964    /// # Errors
965    ///
966    /// Returns [`ValueError::NoValue`] when this value is `Empty(Json)`,
967    /// [`ValueError::TypeMismatch`] when this value has a non-JSON data type,
968    /// or [`ValueError::JsonDeserializationError`] when JSON deserialization
969    /// fails.
970    pub fn deserialize_json<T: DeserializeOwned>(&self) -> ValueResult<T> {
971        match self {
972            Value::Json(v) => serde_json::from_value(v.clone()).map_err(|error| {
973                map_data_conversion_error(DataConversionError::JsonDeserializationError(
974                    error.to_string(),
975                ))
976            }),
977            Value::Empty(dt) if *dt == DataType::Json => Err(ValueError::NoValue),
978            Value::Empty(dt) => Err(ValueError::TypeMismatch {
979                expected: DataType::Json,
980                actual: *dt,
981            }),
982            _ => Err(ValueError::TypeMismatch {
983                expected: DataType::Json,
984                actual: self.data_type(),
985            }),
986        }
987    }
988}