1use alloc::boxed::Box;
16use alloc::collections::BTreeMap;
17use alloc::string::String;
18use alloc::vec::Vec;
19
20use super::descriptor::{MemberId, TypeKind};
21use super::error::DynamicError;
22use super::type_::DynamicType;
23
24#[derive(Debug, Clone)]
32pub enum DynamicValue {
33 Bool(bool),
35 Byte(u8),
37 Int8(i8),
39 UInt8(u8),
41 Int16(i16),
43 UInt16(u16),
45 Int32(i32),
47 UInt32(u32),
49 Int64(i64),
51 UInt64(u64),
53 Float32(f32),
55 Float64(f64),
57 Char8(u8),
59 Char16(u16),
61 String(String),
63 WString(Vec<u16>),
65 Complex(Box<DynamicData>),
67 Sequence(Vec<DynamicData>),
70 Map(Vec<(DynamicData, DynamicData)>),
74 None,
76}
77
78impl PartialEq for DynamicValue {
79 fn eq(&self, other: &Self) -> bool {
80 match (self, other) {
81 (Self::Bool(a), Self::Bool(b)) => a == b,
82 (Self::Byte(a), Self::Byte(b)) => a == b,
83 (Self::Int8(a), Self::Int8(b)) => a == b,
84 (Self::UInt8(a), Self::UInt8(b)) => a == b,
85 (Self::Int16(a), Self::Int16(b)) => a == b,
86 (Self::UInt16(a), Self::UInt16(b)) => a == b,
87 (Self::Int32(a), Self::Int32(b)) => a == b,
88 (Self::UInt32(a), Self::UInt32(b)) => a == b,
89 (Self::Int64(a), Self::Int64(b)) => a == b,
90 (Self::UInt64(a), Self::UInt64(b)) => a == b,
91 (Self::Float32(a), Self::Float32(b)) => a.to_bits() == b.to_bits(),
92 (Self::Float64(a), Self::Float64(b)) => a.to_bits() == b.to_bits(),
93 (Self::Char8(a), Self::Char8(b)) => a == b,
94 (Self::Char16(a), Self::Char16(b)) => a == b,
95 (Self::String(a), Self::String(b)) => a == b,
96 (Self::WString(a), Self::WString(b)) => a == b,
97 (Self::Complex(a), Self::Complex(b)) => a.equals(b),
98 (Self::Sequence(a), Self::Sequence(b)) => {
99 a.len() == b.len() && a.iter().zip(b.iter()).all(|(x, y)| x.equals(y))
100 }
101 (Self::Map(a), Self::Map(b)) => {
102 a.len() == b.len()
103 && a.iter()
104 .zip(b.iter())
105 .all(|((ka, va), (kb, vb))| ka.equals(kb) && va.equals(vb))
106 }
107 (Self::None, Self::None) => true,
108 _ => false,
109 }
110 }
111}
112
113impl DynamicValue {
114 fn kind_str(&self) -> &'static str {
115 match self {
116 Self::Bool(_) => "bool",
117 Self::Byte(_) => "byte",
118 Self::Int8(_) => "int8",
119 Self::UInt8(_) => "uint8",
120 Self::Int16(_) => "int16",
121 Self::UInt16(_) => "uint16",
122 Self::Int32(_) => "int32",
123 Self::UInt32(_) => "uint32",
124 Self::Int64(_) => "int64",
125 Self::UInt64(_) => "uint64",
126 Self::Float32(_) => "float32",
127 Self::Float64(_) => "float64",
128 Self::Char8(_) => "char8",
129 Self::Char16(_) => "char16",
130 Self::String(_) => "string",
131 Self::WString(_) => "wstring",
132 Self::Complex(_) => "complex",
133 Self::Sequence(_) => "sequence",
134 Self::Map(_) => "map",
135 Self::None => "none",
136 }
137 }
138}
139
140#[derive(Debug)]
149pub struct DataLoan {
150 member_id: MemberId,
151 handle: u32,
153}
154
155impl DataLoan {
156 #[must_use]
158 pub fn member_id(&self) -> MemberId {
159 self.member_id
160 }
161}
162
163#[derive(Debug, Clone)]
174pub struct DynamicData {
175 type_: DynamicType,
176 values: BTreeMap<MemberId, DynamicValue>,
177 active_loans: Vec<u32>,
179 next_loan_handle: u32,
181}
182
183impl DynamicData {
184 pub(super) fn new(type_: DynamicType) -> Self {
185 Self {
186 type_,
187 values: BTreeMap::new(),
188 active_loans: Vec::new(),
189 next_loan_handle: 1,
190 }
191 }
192
193 #[must_use]
195 pub fn dynamic_type(&self) -> &DynamicType {
196 &self.type_
197 }
198
199 #[must_use]
201 pub fn equals(&self, other: &Self) -> bool {
202 self.type_.equals(&other.type_) && self.values == other.values
203 }
204
205 #[must_use]
207 pub fn item_count(&self) -> u32 {
208 u32::try_from(self.values.len()).unwrap_or(u32::MAX)
209 }
210
211 fn validate_member(&self, member_id: MemberId) -> Result<(), DynamicError> {
213 if self.type_.member_by_id(member_id).is_none() {
214 return Err(DynamicError::bad_parameter(alloc::format!(
215 "no member with id {member_id} in type {}",
216 self.type_.name()
217 )));
218 }
219 Ok(())
220 }
221
222 fn set(&mut self, member_id: MemberId, value: DynamicValue) -> Result<(), DynamicError> {
230 self.validate_member(member_id)?;
231 let member = self.type_.member_by_id(member_id).cloned();
232 if let Some(ref m) = member {
233 check_value_kind_matches_type(&value, m.dynamic_type().kind())?;
234 }
235 if let Some(m) = member {
238 match crate::dynamic::try_construct::apply_try_construct(&m, value) {
239 crate::dynamic::TryConstructOutcome::Accept(v)
240 | crate::dynamic::TryConstructOutcome::UseDefault(v)
241 | crate::dynamic::TryConstructOutcome::Trim(v) => {
242 self.values.insert(member_id, v);
243 }
244 crate::dynamic::TryConstructOutcome::Discard => {
245 self.values.remove(&member_id);
247 }
248 }
249 } else {
250 self.values.insert(member_id, value);
251 }
252 Ok(())
253 }
254
255 fn get(&self, member_id: MemberId) -> Result<&DynamicValue, DynamicError> {
257 self.values.get(&member_id).ok_or_else(|| {
258 DynamicError::PreconditionNotMet(alloc::format!(
259 "member {member_id} not set in {}",
260 self.type_.name()
261 ))
262 })
263 }
264
265 #[must_use]
270 pub fn get_value(&self, member_id: MemberId) -> Option<&DynamicValue> {
271 self.values.get(&member_id)
272 }
273
274 pub fn set_value_raw(&mut self, member_id: MemberId, value: DynamicValue) {
279 self.values.insert(member_id, value);
280 }
281
282 #[must_use]
285 pub fn set_member_ids(&self) -> alloc::vec::Vec<MemberId> {
286 let mut ids: alloc::vec::Vec<MemberId> = self.values.keys().copied().collect();
287 ids.sort_by_key(|id| self.type_.member_by_id(*id).map_or(u32::MAX, |m| m.index()));
289 ids
290 }
291}
292
293macro_rules! primitive_accessor {
298 ($get_name:ident, $set_name:ident, $rust_ty:ty, $variant:ident) => {
299 impl DynamicData {
300 #[doc = concat!("Spec §7.5.6.3 `get_", stringify!($variant), "_value`.")]
301 pub fn $get_name(&self, member_id: MemberId) -> Result<$rust_ty, DynamicError> {
306 let v = self.get(member_id)?;
307 if let DynamicValue::$variant(x) = v {
308 Ok(x.clone())
309 } else {
310 Err(DynamicError::bad_parameter(alloc::format!(
311 "type mismatch: expected {} got {}",
312 stringify!($variant),
313 v.kind_str()
314 )))
315 }
316 }
317
318 #[doc = concat!("Spec §7.5.6.3 `set_", stringify!($variant), "_value`.")]
319 pub fn $set_name(
323 &mut self,
324 member_id: MemberId,
325 value: $rust_ty,
326 ) -> Result<(), DynamicError> {
327 self.set(member_id, DynamicValue::$variant(value))
328 }
329 }
330 };
331}
332
333primitive_accessor!(get_boolean_value, set_boolean_value, bool, Bool);
334primitive_accessor!(get_byte_value, set_byte_value, u8, Byte);
335primitive_accessor!(get_int8_value, set_int8_value, i8, Int8);
336primitive_accessor!(get_uint8_value, set_uint8_value, u8, UInt8);
337primitive_accessor!(get_int16_value, set_int16_value, i16, Int16);
338primitive_accessor!(get_uint16_value, set_uint16_value, u16, UInt16);
339primitive_accessor!(get_int32_value, set_int32_value, i32, Int32);
340primitive_accessor!(get_uint32_value, set_uint32_value, u32, UInt32);
341primitive_accessor!(get_int64_value, set_int64_value, i64, Int64);
342primitive_accessor!(get_uint64_value, set_uint64_value, u64, UInt64);
343primitive_accessor!(get_float32_value, set_float32_value, f32, Float32);
344primitive_accessor!(get_float64_value, set_float64_value, f64, Float64);
345primitive_accessor!(get_char8_value, set_char8_value, u8, Char8);
346primitive_accessor!(get_char16_value, set_char16_value, u16, Char16);
347
348impl DynamicData {
350 pub fn get_string_value(&self, member_id: MemberId) -> Result<String, DynamicError> {
355 let v = self.get(member_id)?;
356 if let DynamicValue::String(s) = v {
357 Ok(s.clone())
358 } else {
359 Err(DynamicError::bad_parameter(alloc::format!(
360 "type mismatch: expected string got {}",
361 v.kind_str()
362 )))
363 }
364 }
365
366 pub fn set_string_value(
371 &mut self,
372 member_id: MemberId,
373 value: impl Into<String>,
374 ) -> Result<(), DynamicError> {
375 self.set(member_id, DynamicValue::String(value.into()))
376 }
377
378 pub fn get_wstring_value(&self, member_id: MemberId) -> Result<Vec<u16>, DynamicError> {
383 let v = self.get(member_id)?;
384 if let DynamicValue::WString(s) = v {
385 Ok(s.clone())
386 } else {
387 Err(DynamicError::bad_parameter(alloc::format!(
388 "type mismatch: expected wstring got {}",
389 v.kind_str()
390 )))
391 }
392 }
393
394 pub fn set_wstring_value(
399 &mut self,
400 member_id: MemberId,
401 value: Vec<u16>,
402 ) -> Result<(), DynamicError> {
403 self.set(member_id, DynamicValue::WString(value))
404 }
405}
406
407impl DynamicData {
412 pub fn get_complex_value(&self, member_id: MemberId) -> Result<&DynamicData, DynamicError> {
419 let v = self.get(member_id)?;
420 if let DynamicValue::Complex(d) = v {
421 Ok(d)
422 } else {
423 Err(DynamicError::bad_parameter(alloc::format!(
424 "type mismatch: expected complex got {}",
425 v.kind_str()
426 )))
427 }
428 }
429
430 pub fn set_complex_value(
435 &mut self,
436 member_id: MemberId,
437 value: DynamicData,
438 ) -> Result<(), DynamicError> {
439 self.set(member_id, DynamicValue::Complex(Box::new(value)))
440 }
441
442 pub fn get_sequence_length(&self, member_id: MemberId) -> Result<u32, DynamicError> {
447 let v = self.get(member_id)?;
448 if let DynamicValue::Sequence(seq) = v {
449 Ok(u32::try_from(seq.len()).unwrap_or(u32::MAX))
450 } else {
451 Err(DynamicError::bad_parameter(alloc::format!(
452 "type mismatch: expected sequence got {}",
453 v.kind_str()
454 )))
455 }
456 }
457
458 pub fn set_sequence_value(
463 &mut self,
464 member_id: MemberId,
465 value: Vec<DynamicData>,
466 ) -> Result<(), DynamicError> {
467 self.set(member_id, DynamicValue::Sequence(value))
468 }
469
470 pub fn set_map_value(
475 &mut self,
476 member_id: MemberId,
477 entries: Vec<(DynamicData, DynamicData)>,
478 ) -> Result<(), DynamicError> {
479 self.set(member_id, DynamicValue::Map(entries))
480 }
481
482 pub fn get_sequence_element(
487 &self,
488 member_id: MemberId,
489 index: u32,
490 ) -> Result<&DynamicData, DynamicError> {
491 let v = self.get(member_id)?;
492 if let DynamicValue::Sequence(seq) = v {
493 seq.get(index as usize).ok_or_else(|| {
494 DynamicError::bad_parameter(alloc::format!(
495 "sequence index {index} out of range (len={})",
496 seq.len()
497 ))
498 })
499 } else {
500 Err(DynamicError::bad_parameter(alloc::format!(
501 "type mismatch: expected sequence got {}",
502 v.kind_str()
503 )))
504 }
505 }
506}
507
508impl DynamicData {
513 pub fn loan_value(&mut self, member_id: MemberId) -> Result<DataLoan, DynamicError> {
522 self.validate_member(member_id)?;
523 if self.active_loans.contains(&member_id) {
524 return Err(DynamicError::loan(alloc::format!(
525 "member {member_id} is already on loan"
526 )));
527 }
528 self.active_loans.push(member_id);
529 let handle = self.next_loan_handle;
530 self.next_loan_handle = self.next_loan_handle.saturating_add(1);
531 Ok(DataLoan { member_id, handle })
532 }
533
534 pub fn return_loaned_value(&mut self, loan: DataLoan) -> Result<(), DynamicError> {
539 let pos = self
540 .active_loans
541 .iter()
542 .position(|m| *m == loan.member_id)
543 .ok_or_else(|| {
544 DynamicError::loan(alloc::format!(
545 "no active loan for member {}",
546 loan.member_id
547 ))
548 })?;
549 self.active_loans.swap_remove(pos);
550 let _ = loan.handle;
553 Ok(())
554 }
555}
556
557fn check_value_kind_matches_type(value: &DynamicValue, kind: TypeKind) -> Result<(), DynamicError> {
559 let ok = match (value, kind) {
560 (DynamicValue::Bool(_), TypeKind::Boolean) => true,
561 (DynamicValue::Byte(_), TypeKind::Byte) => true,
562 (DynamicValue::Int8(_), TypeKind::Int8) => true,
563 (DynamicValue::UInt8(_), TypeKind::UInt8) => true,
564 (DynamicValue::Int16(_), TypeKind::Int16) => true,
565 (DynamicValue::UInt16(_), TypeKind::UInt16) => true,
566 (DynamicValue::Int32(_), TypeKind::Int32 | TypeKind::Enumeration) => true,
567 (DynamicValue::UInt32(_), TypeKind::UInt32) => true,
568 (DynamicValue::Int64(_), TypeKind::Int64) => true,
569 (DynamicValue::UInt64(_), TypeKind::UInt64) => true,
570 (DynamicValue::Float32(_), TypeKind::Float32) => true,
571 (DynamicValue::Float64(_), TypeKind::Float64) => true,
572 (DynamicValue::Char8(_), TypeKind::Char8) => true,
573 (DynamicValue::Char16(_), TypeKind::Char16) => true,
574 (DynamicValue::String(_), TypeKind::String8) => true,
575 (DynamicValue::WString(_), TypeKind::String16) => true,
576 (DynamicValue::Complex(_), k) if k.is_aggregable() => true,
577 (DynamicValue::Sequence(_), TypeKind::Sequence | TypeKind::Array) => true,
578 (DynamicValue::Map(_), TypeKind::Map) => true,
579 (DynamicValue::None, _) => true,
580 _ => false,
581 };
582 if !ok {
583 return Err(DynamicError::bad_parameter(alloc::format!(
584 "value kind {} cannot be assigned to member kind {kind:?}",
585 value.kind_str()
586 )));
587 }
588 Ok(())
589}
590
591#[cfg(test)]
592#[allow(clippy::unwrap_used)]
593mod tests {
594 use super::*;
595 use crate::dynamic::DynamicTypeBuilderFactory;
596 use crate::dynamic::descriptor::{MemberDescriptor, TypeDescriptor};
597
598 fn struct_with_int32_member() -> DynamicType {
599 let mut b = DynamicTypeBuilderFactory::create_struct("::S");
600 b.add_struct_member("x", 1, TypeDescriptor::primitive(TypeKind::Int32, "int32"))
601 .unwrap();
602 b.build().unwrap()
603 }
604
605 #[test]
606 fn set_get_int32_roundtrips() {
607 let t = struct_with_int32_member();
608 let mut d = DynamicData::new(t);
609 d.set_int32_value(1, 42).unwrap();
610 assert_eq!(d.get_int32_value(1).unwrap(), 42);
611 }
612
613 #[test]
614 fn set_int32_into_int64_member_rejected() {
615 let mut b = DynamicTypeBuilderFactory::create_struct("::S");
616 b.add_struct_member("x", 1, TypeDescriptor::primitive(TypeKind::Int64, "int64"))
617 .unwrap();
618 let t = b.build().unwrap();
619 let mut d = DynamicData::new(t);
620 let err = d.set_int32_value(1, 5).unwrap_err();
621 assert!(matches!(err, DynamicError::BadParameter(_)));
622 }
623
624 #[test]
625 fn unknown_member_id_rejected() {
626 let t = struct_with_int32_member();
627 let mut d = DynamicData::new(t);
628 let err = d.set_int32_value(999, 0).unwrap_err();
629 assert!(matches!(err, DynamicError::BadParameter(_)));
630 }
631
632 #[test]
633 fn loan_double_rejected() {
634 let t = struct_with_int32_member();
635 let mut d = DynamicData::new(t);
636 let _l = d.loan_value(1).unwrap();
637 let err = d.loan_value(1).unwrap_err();
638 assert!(matches!(err, DynamicError::LoanError(_)));
639 }
640
641 #[test]
642 fn loan_return_then_loan_again_works() {
643 let t = struct_with_int32_member();
644 let mut d = DynamicData::new(t);
645 let l = d.loan_value(1).unwrap();
646 d.return_loaned_value(l).unwrap();
647 let _l2 = d.loan_value(1).unwrap();
648 }
649
650 #[test]
651 fn return_unknown_loan_rejected() {
652 let t = struct_with_int32_member();
653 let mut d = DynamicData::new(t);
654 let fake = DataLoan {
655 member_id: 1,
656 handle: 99,
657 };
658 let err = d.return_loaned_value(fake).unwrap_err();
659 assert!(matches!(err, DynamicError::LoanError(_)));
660 }
661
662 #[test]
663 fn item_count_grows_with_sets() {
664 let mut b = DynamicTypeBuilderFactory::create_struct("::S");
665 b.add_struct_member("a", 1, TypeDescriptor::primitive(TypeKind::Int32, "int32"))
666 .unwrap();
667 b.add_struct_member("b", 2, TypeDescriptor::primitive(TypeKind::Int64, "int64"))
668 .unwrap();
669 let t = b.build().unwrap();
670 let mut d = DynamicData::new(t);
671 assert_eq!(d.item_count(), 0);
672 d.set_int32_value(1, 10).unwrap();
673 assert_eq!(d.item_count(), 1);
674 d.set_int64_value(2, 20).unwrap();
675 assert_eq!(d.item_count(), 2);
676 }
677
678 #[test]
679 fn equals_distinguishes_value_diffs() {
680 let t = struct_with_int32_member();
681 let mut a = DynamicData::new(t.clone());
682 let mut b = DynamicData::new(t);
683 a.set_int32_value(1, 5).unwrap();
684 b.set_int32_value(1, 6).unwrap();
685 assert!(!a.equals(&b));
686 b.set_int32_value(1, 5).unwrap();
687 assert!(a.equals(&b));
688 }
689
690 #[test]
691 fn complex_value_set_get() {
692 let mut inner = DynamicTypeBuilderFactory::create_struct("::Inner");
694 inner
695 .add_struct_member("v", 1, TypeDescriptor::primitive(TypeKind::Int32, "int32"))
696 .unwrap();
697 let inner_t = inner.build().unwrap();
698
699 let mut outer = DynamicTypeBuilderFactory::create_struct("::Outer");
700 outer
701 .add_member(MemberDescriptor::new(
702 "nested",
703 10,
704 TypeDescriptor::structure("::Inner"),
705 ))
706 .unwrap();
707 let outer_t = outer.build().unwrap();
708
709 let mut inner_data = DynamicData::new(inner_t);
710 inner_data.set_int32_value(1, 99).unwrap();
711
712 let mut outer_data = DynamicData::new(outer_t);
713 outer_data.set_complex_value(10, inner_data).unwrap();
714
715 let got = outer_data.get_complex_value(10).unwrap();
716 assert_eq!(got.get_int32_value(1).unwrap(), 99);
717 }
718
719 #[test]
720 fn sequence_length_and_element_access() {
721 let mut b = DynamicTypeBuilderFactory::create_struct("::S");
722 b.add_struct_member(
723 "items",
724 1,
725 TypeDescriptor::sequence(
726 "items",
727 TypeDescriptor::primitive(TypeKind::Int32, "int32"),
728 100,
729 ),
730 )
731 .unwrap();
732 let t = b.build().unwrap();
733
734 let elem_t = DynamicTypeBuilderFactory::get_primitive_type(TypeKind::Int32).unwrap();
735 let mut e0 = DynamicData::new(elem_t.clone());
736 e0.values.insert(0, DynamicValue::Int32(7));
737 let mut e1 = DynamicData::new(elem_t);
738 e1.values.insert(0, DynamicValue::Int32(8));
739 let mut d = DynamicData::new(t);
740 d.set_sequence_value(1, alloc::vec![e0, e1]).unwrap();
741 assert_eq!(d.get_sequence_length(1).unwrap(), 2);
742 let _ = d.get_sequence_element(1, 0).unwrap();
743 assert!(d.get_sequence_element(1, 9).is_err());
744 }
745
746 #[test]
747 fn all_twelve_primitive_setters_work() {
748 let cases: alloc::vec::Vec<(&str, MemberId, TypeKind)> = alloc::vec![
750 ("b", 1, TypeKind::Boolean),
751 ("by", 2, TypeKind::Byte),
752 ("i8", 3, TypeKind::Int8),
753 ("u8", 4, TypeKind::UInt8),
754 ("i16", 5, TypeKind::Int16),
755 ("u16", 6, TypeKind::UInt16),
756 ("i32", 7, TypeKind::Int32),
757 ("u32", 8, TypeKind::UInt32),
758 ("i64", 9, TypeKind::Int64),
759 ("u64", 10, TypeKind::UInt64),
760 ("f32", 11, TypeKind::Float32),
761 ("f64", 12, TypeKind::Float64),
762 ("c8", 13, TypeKind::Char8),
763 ("c16", 14, TypeKind::Char16),
764 ];
765 let mut b = DynamicTypeBuilderFactory::create_struct("::S");
766 for (n, id, k) in &cases {
767 b.add_struct_member(
768 *n,
769 *id,
770 TypeDescriptor::primitive(*k, super::super::type_::primitive_name(*k)),
771 )
772 .unwrap();
773 }
774 b.add_struct_member("s", 100, TypeDescriptor::string8(64))
776 .unwrap();
777 b.add_struct_member("w", 101, TypeDescriptor::string16(64))
778 .unwrap();
779 let t = b.build().unwrap();
780 let mut d = DynamicData::new(t);
781 d.set_boolean_value(1, true).unwrap();
782 d.set_byte_value(2, 0xFF).unwrap();
783 d.set_int8_value(3, -1).unwrap();
784 d.set_uint8_value(4, 255).unwrap();
785 d.set_int16_value(5, -2).unwrap();
786 d.set_uint16_value(6, 2).unwrap();
787 d.set_int32_value(7, -3).unwrap();
788 d.set_uint32_value(8, 3).unwrap();
789 d.set_int64_value(9, -4).unwrap();
790 d.set_uint64_value(10, 4).unwrap();
791 d.set_float32_value(11, 1.5).unwrap();
792 d.set_float64_value(12, 2.5).unwrap();
793 d.set_char8_value(13, b'A').unwrap();
794 d.set_char16_value(14, 0x42).unwrap();
795 d.set_string_value(100, "abc").unwrap();
796 d.set_wstring_value(101, alloc::vec![0x41, 0x42]).unwrap();
797
798 assert!(d.get_boolean_value(1).unwrap());
799 assert_eq!(d.get_byte_value(2).unwrap(), 0xFF);
800 assert_eq!(d.get_int8_value(3).unwrap(), -1);
801 assert_eq!(d.get_uint8_value(4).unwrap(), 255);
802 assert_eq!(d.get_int16_value(5).unwrap(), -2);
803 assert_eq!(d.get_uint16_value(6).unwrap(), 2);
804 assert_eq!(d.get_int32_value(7).unwrap(), -3);
805 assert_eq!(d.get_uint32_value(8).unwrap(), 3);
806 assert_eq!(d.get_int64_value(9).unwrap(), -4);
807 assert_eq!(d.get_uint64_value(10).unwrap(), 4);
808 assert!((d.get_float32_value(11).unwrap() - 1.5).abs() < 1e-6);
809 assert!((d.get_float64_value(12).unwrap() - 2.5).abs() < 1e-9);
810 assert_eq!(d.get_char8_value(13).unwrap(), b'A');
811 assert_eq!(d.get_char16_value(14).unwrap(), 0x42);
812 assert_eq!(d.get_string_value(100).unwrap(), "abc");
813 assert_eq!(d.get_wstring_value(101).unwrap(), alloc::vec![0x41, 0x42]);
814 }
815}