1use super::{
18 decode::Decoder,
19 encode::Encoder,
20 env_types::{
21 self,
22 CustomTypeDecoder,
23 CustomTypeEncoder,
24 EnvTypesTranscoder,
25 PathKey,
26 TypesByPath,
27 },
28 scon::Value,
29 AccountId32,
30};
31
32use anyhow::Result;
33use scale::Output;
34use scale_info::{
35 PortableRegistry,
36 TypeInfo,
37};
38use std::{
39 collections::HashMap,
40 fmt::Debug,
41};
42
43pub struct Transcoder {
46 env_types: EnvTypesTranscoder,
47}
48
49impl Transcoder {
50 pub fn new(env_types: EnvTypesTranscoder) -> Self {
51 Self { env_types }
52 }
53
54 pub fn encode<O>(
55 &self,
56 registry: &PortableRegistry,
57 type_id: u32,
58 value: &Value,
59 output: &mut O,
60 ) -> Result<()>
61 where
62 O: Output + Debug,
63 {
64 let encoder = Encoder::new(registry, &self.env_types);
65 encoder.encode(type_id, value, output)
66 }
67
68 pub fn decode(
69 &self,
70 registry: &PortableRegistry,
71 type_id: u32,
72 input: &mut &[u8],
73 ) -> Result<Value> {
74 let decoder = Decoder::new(registry, &self.env_types);
75 decoder.decode(type_id, input)
76 }
77}
78
79pub struct TranscoderBuilder {
81 types_by_path: TypesByPath,
82 encoders: HashMap<u32, Box<dyn CustomTypeEncoder>>,
83 decoders: HashMap<u32, Box<dyn CustomTypeDecoder>>,
84}
85
86impl TranscoderBuilder {
87 pub fn new(registry: &PortableRegistry) -> Self {
88 let types_by_path = registry
89 .types
90 .iter()
91 .map(|ty| (PathKey::from(&ty.ty.path), ty.id))
92 .collect::<TypesByPath>();
93 Self {
94 types_by_path,
95 encoders: HashMap::new(),
96 decoders: HashMap::new(),
97 }
98 }
99
100 pub fn with_default_custom_type_transcoders(self) -> Self {
101 self.register_custom_type_transcoder::<AccountId32, _>(env_types::AccountId)
102 .register_custom_type_decoder::<primitive_types::H256, _>(env_types::Hash)
103 }
104
105 pub fn register_custom_type_transcoder<T, U>(self, transcoder: U) -> Self
106 where
107 T: TypeInfo + 'static,
108 U: CustomTypeEncoder + CustomTypeDecoder + Clone + 'static,
109 {
110 self.register_custom_type_encoder::<T, U>(transcoder.clone())
111 .register_custom_type_decoder::<T, U>(transcoder)
112 }
113
114 pub fn register_custom_type_encoder<T, U>(self, encoder: U) -> Self
115 where
116 T: TypeInfo + 'static,
117 U: CustomTypeEncoder + 'static,
118 {
119 let mut this = self;
120
121 let path_key = PathKey::from_type::<T>();
122 let type_id = this.types_by_path.get(&path_key);
123
124 match type_id {
125 Some(type_id) => {
126 let existing = this.encoders.insert(*type_id, Box::new(encoder));
127 tracing::debug!("Registered custom encoder for type `{:?}`", type_id);
128 if existing.is_some() {
129 panic!(
130 "Attempted to register encoder with existing type id {type_id:?}"
131 );
132 }
133 }
134 None => {
135 tracing::debug!("No matching type in registry for path {:?}.", path_key);
138 }
139 }
140 this
141 }
142
143 pub fn register_custom_type_decoder<T, U>(self, encoder: U) -> Self
144 where
145 T: TypeInfo + 'static,
146 U: CustomTypeDecoder + 'static,
147 {
148 let mut this = self;
149
150 let path_key = PathKey::from_type::<T>();
151 let type_id = this.types_by_path.get(&path_key);
152
153 match type_id {
154 Some(type_id) => {
155 let existing = this.decoders.insert(*type_id, Box::new(encoder));
156 tracing::debug!("Registered custom decoder for type `{:?}`", type_id);
157 if existing.is_some() {
158 panic!(
159 "Attempted to register decoder with existing type id {type_id:?}"
160 );
161 }
162 }
163 None => {
164 tracing::debug!("No matching type in registry for path {:?}.", path_key);
167 }
168 }
169 this
170 }
171
172 pub fn done(self) -> Transcoder {
173 let env_types_transcoder = EnvTypesTranscoder::new(self.encoders, self.decoders);
174 Transcoder::new(env_types_transcoder)
175 }
176}
177
178#[cfg(test)]
179mod tests {
180 use super::{
181 super::scon::{
182 self,
183 Hex,
184 Map,
185 Seq,
186 Tuple,
187 Value,
188 },
189 *,
190 };
191 use scale::Encode;
192 use scale_info::{
193 MetaType,
194 Registry,
195 TypeInfo,
196 };
197 use std::str::FromStr;
198
199 fn registry_with_type<T>() -> Result<(PortableRegistry, u32)>
200 where
201 T: scale_info::TypeInfo + 'static,
202 {
203 let mut registry = Registry::new();
204 let type_id = registry.register_type(&MetaType::new::<T>());
205 let registry: PortableRegistry = registry.into();
206
207 Ok((registry, type_id.id))
208 }
209
210 fn transcode_roundtrip<T>(input: &str, expected_output: Value) -> Result<()>
211 where
212 T: scale_info::TypeInfo + 'static,
213 {
214 let (registry, ty) = registry_with_type::<T>()?;
215 let transcoder = TranscoderBuilder::new(®istry)
216 .with_default_custom_type_transcoders()
217 .done();
218
219 let value = scon::parse_value(input)?;
220
221 let mut output = Vec::new();
222 transcoder.encode(®istry, ty, &value, &mut output)?;
223 let decoded = transcoder.decode(®istry, ty, &mut &output[..])?;
224 assert_eq!(expected_output, decoded, "decoding");
225 Ok(())
226 }
227
228 #[test]
229 fn transcode_bool() -> Result<()> {
230 transcode_roundtrip::<bool>("true", Value::Bool(true))?;
231 transcode_roundtrip::<bool>("false", Value::Bool(false))
232 }
233
234 #[test]
235 fn transcode_char_unsupported() -> Result<()> {
236 let (registry, ty) = registry_with_type::<char>()?;
237 let transcoder = Transcoder::new(Default::default());
238 let encoded = u32::from('c').encode();
239
240 assert!(transcoder
241 .encode(®istry, ty, &Value::Char('c'), &mut Vec::new())
242 .is_err());
243 assert!(transcoder.decode(®istry, ty, &mut &encoded[..]).is_err());
244 Ok(())
245 }
246
247 #[test]
248 fn transcode_str() -> Result<()> {
249 transcode_roundtrip::<String>("\"ink!\"", Value::String("ink!".to_string()))
250 }
251
252 #[test]
253 fn transcode_unsigned_integers() -> Result<()> {
254 transcode_roundtrip::<u8>("0", Value::UInt(0))?;
255 transcode_roundtrip::<u8>("255", Value::UInt(255))?;
256
257 transcode_roundtrip::<u16>("0", Value::UInt(0))?;
258 transcode_roundtrip::<u16>("65535", Value::UInt(65535))?;
259
260 transcode_roundtrip::<u32>("0", Value::UInt(0))?;
261 transcode_roundtrip::<u32>("4294967295", Value::UInt(4294967295))?;
262
263 transcode_roundtrip::<u64>("0", Value::UInt(0))?;
264 transcode_roundtrip::<u64>(
265 "\"18_446_744_073_709_551_615\"",
266 Value::UInt(18446744073709551615),
267 )?;
268
269 transcode_roundtrip::<u128>("0", Value::UInt(0))?;
270 transcode_roundtrip::<u128>(
271 "\"340_282_366_920_938_463_463_374_607_431_768_211_455\"",
272 Value::UInt(340282366920938463463374607431768211455),
273 )
274 }
275
276 #[test]
277 fn transcode_integers() -> Result<()> {
278 transcode_roundtrip::<i8>("-128", Value::Int(i8::MIN.into()))?;
279 transcode_roundtrip::<i8>("127", Value::Int(i8::MAX.into()))?;
280
281 transcode_roundtrip::<i16>("-32768", Value::Int(i16::MIN.into()))?;
282 transcode_roundtrip::<i16>("32767", Value::Int(i16::MAX.into()))?;
283
284 transcode_roundtrip::<i32>("-2147483648", Value::Int(i32::MIN.into()))?;
285 transcode_roundtrip::<i32>("2147483647", Value::Int(i32::MAX.into()))?;
286
287 transcode_roundtrip::<i64>("-9223372036854775808", Value::Int(i64::MIN.into()))?;
288 transcode_roundtrip::<i64>(
289 "\"9_223_372_036_854_775_807\"",
290 Value::Int(i64::MAX.into()),
291 )?;
292
293 transcode_roundtrip::<i128>(
294 "-170141183460469231731687303715884105728",
295 Value::Int(i128::MIN),
296 )?;
297 transcode_roundtrip::<i128>(
298 "\"170141183460469231731687303715884105727\"",
299 Value::Int(i128::MAX),
300 )
301 }
302
303 #[test]
304 fn transcode_byte_array() -> Result<()> {
305 transcode_roundtrip::<[u8; 2]>(
306 r#"0x0000"#,
307 Value::Seq(vec![Value::UInt(0x00), Value::UInt(0x00)].into()),
308 )?;
309 transcode_roundtrip::<[u8; 4]>(
310 r#"0xDEADBEEF"#,
311 Value::Seq(
312 vec![
313 Value::UInt(0xDE),
314 Value::UInt(0xAD),
315 Value::UInt(0xBE),
316 Value::UInt(0xEF),
317 ]
318 .into(),
319 ),
320 )?;
321 transcode_roundtrip::<[u8; 4]>(
322 r#"0xdeadbeef"#,
323 Value::Seq(
324 vec![
325 Value::UInt(0xDE),
326 Value::UInt(0xAD),
327 Value::UInt(0xBE),
328 Value::UInt(0xEF),
329 ]
330 .into(),
331 ),
332 )
333 }
334
335 #[test]
336 fn transcode_array() -> Result<()> {
337 transcode_roundtrip::<[u32; 3]>(
338 "[1, 2, 3]",
339 Value::Seq(vec![Value::UInt(1), Value::UInt(2), Value::UInt(3)].into()),
340 )?;
341 transcode_roundtrip::<[String; 2]>(
342 "[\"hello\", \"world\"]",
343 Value::Seq(
344 vec![
345 Value::String("hello".to_string()),
346 Value::String("world".to_string()),
347 ]
348 .into(),
349 ),
350 )
351 }
352
353 #[test]
354 fn transcode_seq() -> Result<()> {
355 transcode_roundtrip::<Vec<u32>>(
356 "[1, 2, 3]",
357 Value::Seq(vec![Value::UInt(1), Value::UInt(2), Value::UInt(3)].into()),
358 )?;
359 transcode_roundtrip::<Vec<String>>(
360 "[\"hello\", \"world\"]",
361 Value::Seq(
362 vec![
363 Value::String("hello".to_string()),
364 Value::String("world".to_string()),
365 ]
366 .into(),
367 ),
368 )
369 }
370
371 #[test]
372 fn transcode_tuple() -> Result<()> {
373 transcode_roundtrip::<(u32, String, [u8; 4])>(
374 r#"(1, "ink!", 0xDEADBEEF)"#,
375 Value::Tuple(Tuple::new(
376 None,
377 vec![
378 Value::UInt(1),
379 Value::String("ink!".to_string()),
380 Value::Seq(
381 vec![
382 Value::UInt(0xDE),
383 Value::UInt(0xAD),
384 Value::UInt(0xBE),
385 Value::UInt(0xEF),
386 ]
387 .into(),
388 ),
389 ],
390 )),
391 )
392 }
393
394 #[test]
395 fn transcode_composite_struct() -> Result<()> {
396 #[allow(dead_code)]
397 #[derive(TypeInfo)]
398 struct S {
399 a: u32,
400 b: String,
401 c: [u8; 4],
402 d: Vec<S>,
404 }
405
406 transcode_roundtrip::<S>(
407 r#"S(a: 1, b: "ink!", c: 0xDEADBEEF, d: [S(a: 2, b: "ink!", c: 0xDEADBEEF, d: [])])"#,
408 Value::Map(
409 vec![
410 (Value::String("a".to_string()), Value::UInt(1)),
411 (
412 Value::String("b".to_string()),
413 Value::String("ink!".to_string()),
414 ),
415 (
416 Value::String("c".to_string()),
417 Value::Seq(
418 vec![
419 Value::UInt(0xDE),
420 Value::UInt(0xAD),
421 Value::UInt(0xBE),
422 Value::UInt(0xEF),
423 ]
424 .into(),
425 ),
426 ),
427 (
428 Value::String("d".to_string()),
429 Value::Seq(
430 vec![Value::Map(
431 vec![
432 (Value::String("a".to_string()), Value::UInt(2)),
433 (
434 Value::String("b".to_string()),
435 Value::String("ink!".to_string()),
436 ),
437 (
438 Value::String("c".to_string()),
439 Value::Seq(
440 vec![
441 Value::UInt(0xDE),
442 Value::UInt(0xAD),
443 Value::UInt(0xBE),
444 Value::UInt(0xEF),
445 ]
446 .into(),
447 ),
448 ),
449 (
450 Value::String("d".to_string()),
451 Value::Seq(
452 Vec::new()
453 .into_iter()
454 .collect::<Vec<_>>()
455 .into(),
456 ),
457 ),
458 ]
459 .into_iter()
460 .collect(),
461 )]
462 .into(),
463 ),
464 ),
465 ]
466 .into_iter()
467 .collect(),
468 ),
469 )
470 }
471
472 #[test]
473 fn transcode_composite_struct_nested() -> Result<()> {
474 #[allow(dead_code)]
475 #[derive(TypeInfo)]
476 struct S {
477 nested: Nested,
478 }
479
480 #[allow(dead_code)]
481 #[derive(TypeInfo)]
482 struct Nested(u32);
483
484 transcode_roundtrip::<S>(
485 r#"S { nested: Nested(33) }"#,
486 Value::Map(Map::new(
487 Some("S"),
488 vec![(
489 Value::String("nested".to_string()),
490 Value::Tuple(Tuple::new(
491 Some("Nested"),
492 vec![Value::UInt(33)].into_iter().collect(),
493 )),
494 )]
495 .into_iter()
496 .collect(),
497 )),
498 )
499 }
500
501 #[test]
502 fn transcode_composite_struct_out_of_order_fields() -> Result<()> {
503 #[allow(dead_code)]
504 #[derive(TypeInfo)]
505 struct S {
506 a: u32,
507 b: String,
508 c: [u8; 4],
509 }
510
511 transcode_roundtrip::<S>(
512 r#"S(b: "ink!", a: 1, c: 0xDEADBEEF)"#,
513 Value::Map(
514 vec![
515 (Value::String("a".to_string()), Value::UInt(1)),
516 (
517 Value::String("b".to_string()),
518 Value::String("ink!".to_string()),
519 ),
520 (
521 Value::String("c".to_string()),
522 Value::Seq(
523 vec![
524 Value::UInt(0xDE),
525 Value::UInt(0xAD),
526 Value::UInt(0xBE),
527 Value::UInt(0xEF),
528 ]
529 .into(),
530 ),
531 ),
532 ]
533 .into_iter()
534 .collect(),
535 ),
536 )
537 }
538
539 #[test]
540 fn transcode_composite_tuple_struct() -> Result<()> {
541 #[allow(dead_code)]
542 #[derive(TypeInfo)]
543 struct S(u32, String, [u8; 4]);
544
545 transcode_roundtrip::<S>(
546 r#"S(1, "ink!", 0xDEADBEEF)"#,
547 Value::Tuple(Tuple::new(
548 Some("S"),
549 vec![
550 Value::UInt(1),
551 Value::String("ink!".to_string()),
552 Value::Seq(
553 vec![
554 Value::UInt(0xDE),
555 Value::UInt(0xAD),
556 Value::UInt(0xBE),
557 Value::UInt(0xEF),
558 ]
559 .into(),
560 ),
561 ],
562 )),
563 )
564 }
565
566 #[test]
567 fn transcode_composite_single_field_struct() -> Result<()> {
568 #[allow(dead_code)]
569 #[derive(TypeInfo)]
570 struct S([u8; 4]);
571
572 transcode_roundtrip::<S>(
573 r#"0xDEADBEEF"#,
574 Value::Tuple(Tuple::new(
575 Some("S"),
576 vec![Value::Seq(
577 vec![
578 Value::UInt(0xDE),
579 Value::UInt(0xAD),
580 Value::UInt(0xBE),
581 Value::UInt(0xEF),
582 ]
583 .into(),
584 )],
585 )),
586 )
587 }
588
589 #[test]
590 fn transcode_composite_single_field_tuple() -> Result<()> {
591 transcode_roundtrip::<([u8; 4],)>(
592 r#"0xDEADBEEF"#,
593 Value::Tuple(Tuple::new(
594 None,
595 vec![Value::Seq(
596 vec![
597 Value::UInt(0xDE),
598 Value::UInt(0xAD),
599 Value::UInt(0xBE),
600 Value::UInt(0xEF),
601 ]
602 .into(),
603 )],
604 )),
605 )
606 }
607
608 #[test]
609 fn transcode_enum_variant_tuple() -> Result<()> {
610 #[derive(TypeInfo)]
611 #[allow(dead_code)]
612 enum E {
613 A(u32, String),
614 B { a: [u8; 4], b: Vec<E> },
615 C,
616 }
617
618 transcode_roundtrip::<E>(
619 r#"A(1, "2")"#,
620 Value::Tuple(Tuple::new(
621 Some("A"),
622 vec![Value::UInt(1), Value::String("2".into())],
623 )),
624 )
625 }
626
627 #[test]
628 fn transcode_enum_variant_map() -> Result<()> {
629 #[derive(TypeInfo)]
630 #[allow(dead_code)]
631 enum E {
632 A { a: u32, b: bool },
633 }
634
635 transcode_roundtrip::<E>(
636 r#"A { a: 33, b: false }"#,
637 Value::Map(Map::new(
638 Some("A"),
639 vec![
640 (Value::String("a".to_string()), Value::UInt(33)),
641 (Value::String("b".to_string()), Value::Bool(false)),
642 ]
643 .into_iter()
644 .collect(),
645 )),
646 )
647 }
648
649 #[test]
650 fn transcode_enum_variant_map_out_of_order_fields() -> Result<()> {
651 #[derive(TypeInfo)]
652 #[allow(dead_code)]
653 enum E {
654 A { a: u32, b: bool },
655 }
656
657 transcode_roundtrip::<E>(
658 r#"A { a: 33, b: false }"#,
659 Value::Map(Map::new(
660 Some("A"),
661 vec![
662 (Value::String("a".to_string()), Value::UInt(33)),
663 (Value::String("b".to_string()), Value::Bool(false)),
664 ]
665 .into_iter()
666 .collect(),
667 )),
668 )
669 }
670
671 #[test]
672 fn transcode_option() -> Result<()> {
673 transcode_roundtrip::<Option<u32>>(
674 r#"Some(32)"#,
675 Value::Tuple(Tuple::new(Some("Some"), vec![Value::UInt(32)])),
676 )?;
677
678 transcode_roundtrip::<Option<u32>>(
679 r#"None"#,
680 Value::Tuple(Tuple::new(Some("None"), Vec::new())),
681 )
682 }
683
684 #[test]
685 fn transcode_account_id_custom_ss58_encoding() -> Result<()> {
686 type AccountId = AccountId32;
687
688 #[allow(dead_code)]
689 #[derive(TypeInfo)]
690 struct S {
691 no_alias: AccountId32,
692 aliased: AccountId,
693 }
694
695 transcode_roundtrip::<S>(
696 r#"S(
697 no_alias: 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,
698 aliased: 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty,
699 )"#,
700 Value::Map(Map::new(
701 Some("S"),
702 vec![
703 (
704 Value::String("no_alias".into()),
705 Value::Literal(
706 "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY".into(),
707 ),
708 ),
709 (
710 Value::String("aliased".into()),
711 Value::Literal(
712 "5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty".into(),
713 ),
714 ),
715 ]
716 .into_iter()
717 .collect(),
718 )),
719 )
720 }
721
722 #[test]
723 fn transcode_account_id_custom_ss58_encoding_seq() -> Result<()> {
724 let hex_to_bytes = |hex: &str| -> Result<Value> {
725 let hex = Hex::from_str(hex)?;
726 let values = hex.bytes().iter().map(|b| Value::UInt((*b).into()));
727 Ok(Value::Seq(Seq::new(values.collect())))
728 };
729
730 transcode_roundtrip::<Vec<AccountId32>>(
731 r#"[
732 5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY,
733 5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty,
734 ]"#,
735 Value::Seq(Seq::new(
736 vec![
737 Value::Tuple(
738 Tuple::new(
739 Some("AccountId32"),
740 vec![hex_to_bytes("0xd43593c715fdd31c61141abd04a99fd6822c8558854ccde39a5684e7a56da27d")?]
741 )
742 ),
743 Value::Tuple(
744 Tuple::new(
745 Some("AccountId32"),
746 vec![hex_to_bytes("0x8eaf04151687736326c9fea17e25fc5287613693c912909cb226aa4794f26a48")?]
747 )
748 )
749 ]
750 .into_iter()
751 .collect(),
752 )),
753 )
754 }
755
756 #[test]
757 fn decode_h256_as_hex_string() -> Result<()> {
758 #[allow(dead_code)]
759 #[derive(TypeInfo)]
760 struct S {
761 hash: primitive_types::H256,
762 }
763
764 transcode_roundtrip::<S>(
765 r#"S(
766 hash: 0x3428ebe146f5b82415da82724bcf75f053768738dcac5f83ab7d82a70a0ff2de,
767 )"#,
768 Value::Map(Map::new(
769 Some("S"),
770 vec![
771 (
772 Value::String("hash".into()),
773 Value::Hex(
774 Hex::from_str("0x3428ebe146f5b82415da82724bcf75f053768738dcac5f83ab7d82a70a0ff2de")?,
775 ),
776 ),
777 ]
778 .into_iter()
779 .collect(),
780 )),
781 )
782 }
783
784 #[test]
785 fn transcode_compact_primitives() -> Result<()> {
786 transcode_roundtrip::<scale::Compact<u8>>(r#"33"#, Value::UInt(33))?;
787
788 transcode_roundtrip::<scale::Compact<u16>>(r#"33"#, Value::UInt(33))?;
789
790 transcode_roundtrip::<scale::Compact<u32>>(r#"33"#, Value::UInt(33))?;
791
792 transcode_roundtrip::<scale::Compact<u64>>(r#"33"#, Value::UInt(33))?;
793
794 transcode_roundtrip::<scale::Compact<u128>>(r#"33"#, Value::UInt(33))
795 }
796
797 #[test]
798 fn transcode_compact_struct() -> Result<()> {
799 #[derive(scale::Encode, scale::CompactAs, TypeInfo)]
800 struct CompactStruct(u32);
801
802 #[allow(dead_code)]
803 #[derive(scale::Encode, TypeInfo)]
804 struct S {
805 #[codec(compact)]
806 a: CompactStruct,
807 }
808
809 transcode_roundtrip::<S>(
810 r#"S { a: CompactStruct(33) }"#,
811 Value::Map(Map::new(
812 Some("S"),
813 vec![(
814 Value::String("a".to_string()),
815 Value::Tuple(Tuple::new(
816 Some("CompactStruct"),
817 vec![Value::UInt(33)],
818 )),
819 )]
820 .into_iter()
821 .collect(),
822 )),
823 )
824 }
825
826 #[test]
827 fn transcode_hex_literal_uints() -> Result<()> {
828 #[derive(scale::Encode, TypeInfo)]
829 struct S(u8, u16, u32, u64, u128);
830
831 transcode_roundtrip::<S>(
832 r#"S (0xDE, 0xDEAD, 0xDEADBEEF, 0xDEADBEEF12345678, 0xDEADBEEF0123456789ABCDEF01234567)"#,
833 Value::Tuple(Tuple::new(
834 Some("S"),
835 vec![
836 Value::UInt(0xDE),
837 Value::UInt(0xDEAD),
838 Value::UInt(0xDEADBEEF),
839 Value::UInt(0xDEADBEEF12345678),
840 Value::UInt(0xDEADBEEF0123456789ABCDEF01234567),
841 ]
842 .into_iter()
843 .collect(),
844 )),
845 )
846 }
847}