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}