1mod decode;
19pub mod types;
20
21use alloc::string::String;
22use core::marker::PhantomData;
23use scale_type_resolver::TypeResolver;
24use types::*;
25
26pub use decode::decode_with_visitor;
27pub(crate) use decode::decode_with_visitor_maybe_compact;
28
29pub type TypeIdFor<V> = <<V as Visitor>::TypeResolver as TypeResolver>::TypeId;
31
32pub trait Visitor: Sized {
36 type Value<'scale, 'resolver>;
38 type Error: From<DecodeError>;
41 type TypeResolver: TypeResolver;
43
44 fn unchecked_decode_as_type<'scale, 'resolver>(
55 self,
56 _input: &mut &'scale [u8],
57 _type_id: TypeIdFor<Self>,
58 _types: &'resolver Self::TypeResolver,
59 ) -> DecodeAsTypeResult<Self, Result<Self::Value<'scale, 'resolver>, Self::Error>> {
60 DecodeAsTypeResult::Skipped(self)
61 }
62
63 fn visit_unexpected<'scale, 'resolver>(
67 self,
68 unexpected: Unexpected,
69 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
70 Err(DecodeError::Unexpected(unexpected).into())
71 }
72
73 fn visit_bool<'scale, 'resolver>(
75 self,
76 _value: bool,
77 _type_id: TypeIdFor<Self>,
78 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
79 self.visit_unexpected(Unexpected::Bool)
80 }
81 fn visit_char<'scale, 'resolver>(
83 self,
84 _value: char,
85 _type_id: TypeIdFor<Self>,
86 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
87 self.visit_unexpected(Unexpected::Char)
88 }
89 fn visit_u8<'scale, 'resolver>(
91 self,
92 _value: u8,
93 _type_id: TypeIdFor<Self>,
94 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
95 self.visit_unexpected(Unexpected::U8)
96 }
97 fn visit_u16<'scale, 'resolver>(
99 self,
100 _value: u16,
101 _type_id: TypeIdFor<Self>,
102 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
103 self.visit_unexpected(Unexpected::U16)
104 }
105 fn visit_u32<'scale, 'resolver>(
107 self,
108 _value: u32,
109 _type_id: TypeIdFor<Self>,
110 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
111 self.visit_unexpected(Unexpected::U32)
112 }
113 fn visit_u64<'scale, 'resolver>(
115 self,
116 _value: u64,
117 _type_id: TypeIdFor<Self>,
118 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
119 self.visit_unexpected(Unexpected::U64)
120 }
121 fn visit_u128<'scale, 'resolver>(
123 self,
124 _value: u128,
125 _type_id: TypeIdFor<Self>,
126 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
127 self.visit_unexpected(Unexpected::U128)
128 }
129 fn visit_u256<'resolver>(
131 self,
132 _value: &[u8; 32],
133 _type_id: TypeIdFor<Self>,
134 ) -> Result<Self::Value<'_, 'resolver>, Self::Error> {
135 self.visit_unexpected(Unexpected::U256)
136 }
137 fn visit_i8<'scale, 'resolver>(
139 self,
140 _value: i8,
141 _type_id: TypeIdFor<Self>,
142 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
143 self.visit_unexpected(Unexpected::I8)
144 }
145 fn visit_i16<'scale, 'resolver>(
147 self,
148 _value: i16,
149 _type_id: TypeIdFor<Self>,
150 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
151 self.visit_unexpected(Unexpected::I16)
152 }
153 fn visit_i32<'scale, 'resolver>(
155 self,
156 _value: i32,
157 _type_id: TypeIdFor<Self>,
158 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
159 self.visit_unexpected(Unexpected::I32)
160 }
161 fn visit_i64<'scale, 'resolver>(
163 self,
164 _value: i64,
165 _type_id: TypeIdFor<Self>,
166 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
167 self.visit_unexpected(Unexpected::I64)
168 }
169 fn visit_i128<'scale, 'resolver>(
171 self,
172 _value: i128,
173 _type_id: TypeIdFor<Self>,
174 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
175 self.visit_unexpected(Unexpected::I128)
176 }
177 fn visit_i256<'resolver>(
179 self,
180 _value: &[u8; 32],
181 _type_id: TypeIdFor<Self>,
182 ) -> Result<Self::Value<'_, 'resolver>, Self::Error> {
183 self.visit_unexpected(Unexpected::I256)
184 }
185 fn visit_sequence<'scale, 'resolver>(
187 self,
188 _value: &mut Sequence<'scale, 'resolver, Self::TypeResolver>,
189 _type_id: TypeIdFor<Self>,
190 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
191 self.visit_unexpected(Unexpected::Sequence)
192 }
193 fn visit_composite<'scale, 'resolver>(
195 self,
196 _value: &mut Composite<'scale, 'resolver, Self::TypeResolver>,
197 _type_id: TypeIdFor<Self>,
198 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
199 self.visit_unexpected(Unexpected::Composite)
200 }
201 fn visit_tuple<'scale, 'resolver>(
203 self,
204 _value: &mut Tuple<'scale, 'resolver, Self::TypeResolver>,
205 _type_id: TypeIdFor<Self>,
206 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
207 self.visit_unexpected(Unexpected::Tuple)
208 }
209 fn visit_str<'scale, 'resolver>(
211 self,
212 _value: &mut Str<'scale>,
213 _type_id: TypeIdFor<Self>,
214 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
215 self.visit_unexpected(Unexpected::Str)
216 }
217 fn visit_variant<'scale, 'resolver>(
219 self,
220 _value: &mut Variant<'scale, 'resolver, Self::TypeResolver>,
221 _type_id: TypeIdFor<Self>,
222 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
223 self.visit_unexpected(Unexpected::Variant)
224 }
225 fn visit_array<'scale, 'resolver>(
227 self,
228 _value: &mut Array<'scale, 'resolver, Self::TypeResolver>,
229 _type_id: TypeIdFor<Self>,
230 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
231 self.visit_unexpected(Unexpected::Array)
232 }
233 fn visit_bitsequence<'scale, 'resolver>(
235 self,
236 _value: &mut BitSequence<'scale>,
237 _type_id: TypeIdFor<Self>,
238 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
239 self.visit_unexpected(Unexpected::Bitsequence)
240 }
241}
242
243#[derive(Debug, Clone, PartialEq, Eq, thiserror::Error)]
245pub enum DecodeError {
246 #[error("Could not find type with ID '{0}'")]
248 TypeIdNotFound(String),
249 #[error("Failed to resolve type: {0}")]
251 TypeResolvingError(String),
252 #[error("Could not decode compact encoded type: compact types can only have 1 field")]
254 CannotDecodeCompactIntoType,
255 #[error("Could not decode string: {0}")]
257 InvalidStr(alloc::str::Utf8Error),
258 #[error("{_0} is expected to be a valid char, but is not")]
260 InvalidChar(u32),
261 #[error("Ran out of data during decoding")]
263 NotEnoughInput,
264 #[error("Could not find variant with index {_0}")]
266 VariantNotFound(u8),
267 #[error("Decode error: {0}")]
269 CodecError(codec::Error),
270 #[error("Unexpected type {_0}")]
272 Unexpected(#[from] Unexpected),
273}
274
275impl From<codec::Error> for DecodeError {
278 fn from(e: codec::Error) -> Self {
279 DecodeError::CodecError(e)
280 }
281}
282
283#[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)]
285#[allow(missing_docs)]
286pub enum Unexpected {
287 #[error("bool")]
288 Bool,
289 #[error("char")]
290 Char,
291 #[error("u8")]
292 U8,
293 #[error("u16")]
294 U16,
295 #[error("u32")]
296 U32,
297 #[error("u64")]
298 U64,
299 #[error("u128")]
300 U128,
301 #[error("u256")]
302 U256,
303 #[error("i8")]
304 I8,
305 #[error("i16")]
306 I16,
307 #[error("i32")]
308 I32,
309 #[error("i64")]
310 I64,
311 #[error("i128")]
312 I128,
313 #[error("i256")]
314 I256,
315 #[error("sequence")]
316 Sequence,
317 #[error("composite")]
318 Composite,
319 #[error("tuple")]
320 Tuple,
321 #[error("str")]
322 Str,
323 #[error("variant")]
324 Variant,
325 #[error("array")]
326 Array,
327 #[error("bitsequence")]
328 Bitsequence,
329}
330
331pub enum DecodeAsTypeResult<V, R> {
333 Skipped(V),
335 Decoded(R),
337}
338
339impl<V, R> DecodeAsTypeResult<V, R> {
340 pub fn map_decoded<T, F: FnOnce(R) -> T>(self, f: F) -> DecodeAsTypeResult<V, T> {
343 match self {
344 DecodeAsTypeResult::Skipped(s) => DecodeAsTypeResult::Skipped(s),
345 DecodeAsTypeResult::Decoded(r) => DecodeAsTypeResult::Decoded(f(r)),
346 }
347 }
348
349 pub fn map_skipped<T, F: FnOnce(V) -> T>(self, f: F) -> DecodeAsTypeResult<T, R> {
352 match self {
353 DecodeAsTypeResult::Skipped(s) => DecodeAsTypeResult::Skipped(f(s)),
354 DecodeAsTypeResult::Decoded(r) => DecodeAsTypeResult::Decoded(r),
355 }
356 }
357}
358
359pub trait DecodeItemIterator<'scale, 'resolver, R: TypeResolver> {
362 fn decode_item<V: Visitor<TypeResolver = R>>(
364 &mut self,
365 visitor: V,
366 ) -> Option<Result<V::Value<'scale, 'resolver>, V::Error>>;
367}
368
369pub struct IgnoreVisitor<R>(PhantomData<R>);
371
372impl<R> Default for IgnoreVisitor<R> {
373 fn default() -> Self {
374 Self::new()
375 }
376}
377
378impl<R> IgnoreVisitor<R> {
379 pub fn new() -> Self {
381 IgnoreVisitor(PhantomData)
382 }
383}
384
385impl<R: TypeResolver> Visitor for IgnoreVisitor<R> {
386 type Value<'scale, 'resolver> = ();
387 type Error = DecodeError;
388 type TypeResolver = R;
389
390 fn visit_unexpected<'scale, 'resolver>(
392 self,
393 _unexpected: Unexpected,
394 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
395 Ok(())
396 }
397}
398
399#[derive(Copy, Clone, Debug, PartialEq, Eq)]
407pub struct VisitorWithCrateError<V>(pub V);
408
409impl<V: Visitor> Visitor for VisitorWithCrateError<V>
410where
411 V::Error: Into<crate::Error>,
412{
413 type Value<'scale, 'resolver> = V::Value<'scale, 'resolver>;
414 type Error = crate::Error;
415 type TypeResolver = V::TypeResolver;
416
417 fn unchecked_decode_as_type<'scale, 'resolver>(
418 self,
419 input: &mut &'scale [u8],
420 type_id: TypeIdFor<Self>,
421 types: &'resolver Self::TypeResolver,
422 ) -> DecodeAsTypeResult<Self, Result<Self::Value<'scale, 'resolver>, Self::Error>> {
423 let res = decode_with_visitor(input, type_id, types, self.0).map_err(Into::into);
424 DecodeAsTypeResult::Decoded(res)
425 }
426}
427
428#[cfg(test)]
429mod test {
430 use super::*;
431 use alloc::borrow::ToOwned;
432 use alloc::string::{String, ToString};
433 use alloc::vec;
434 use alloc::vec::Vec;
435 use codec::{self, CompactAs, Encode};
436 use scale_info::PortableRegistry;
437
438 #[derive(Debug, PartialEq)]
441 enum Value {
442 Bool(bool),
443 Char(char),
444 U8(u8),
445 U16(u16),
446 U32(u32),
447 U64(u64),
448 U128(u128),
449 U256([u8; 32]),
450 I8(i8),
451 I16(i16),
452 I32(i32),
453 I64(i64),
454 I128(i128),
455 I256([u8; 32]),
456 Sequence(Vec<Value>),
457 Composite(Vec<(String, Value)>),
458 Tuple(Vec<Value>),
459 Str(String),
460 Array(Vec<Value>),
461 Variant(String, Vec<(String, Value)>),
462 BitSequence(scale_bits::Bits),
463 }
464
465 struct ValueVisitor<R>(PhantomData<R>);
466 impl<R> Clone for ValueVisitor<R> {
467 fn clone(&self) -> Self {
468 *self
469 }
470 }
471 impl<R> Copy for ValueVisitor<R> {}
472
473 impl<R> ValueVisitor<R> {
474 pub fn new() -> Self {
475 Self(PhantomData)
476 }
477 }
478
479 impl<R: TypeResolver> Visitor for ValueVisitor<R> {
480 type Value<'scale, 'resolver> = Value;
481 type Error = DecodeError;
482 type TypeResolver = R;
483
484 fn visit_bool<'scale, 'resolver>(
485 self,
486 value: bool,
487 _type_id: TypeIdFor<Self>,
488 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
489 Ok(Value::Bool(value))
490 }
491 fn visit_char<'scale, 'resolver>(
492 self,
493 value: char,
494 _type_id: TypeIdFor<Self>,
495 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
496 Ok(Value::Char(value))
497 }
498 fn visit_u8<'scale, 'resolver>(
499 self,
500 value: u8,
501 _type_id: TypeIdFor<Self>,
502 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
503 Ok(Value::U8(value))
504 }
505 fn visit_u16<'scale, 'resolver>(
506 self,
507 value: u16,
508 _type_id: TypeIdFor<Self>,
509 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
510 Ok(Value::U16(value))
511 }
512 fn visit_u32<'scale, 'resolver>(
513 self,
514 value: u32,
515 _type_id: TypeIdFor<Self>,
516 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
517 Ok(Value::U32(value))
518 }
519 fn visit_u64<'scale, 'resolver>(
520 self,
521 value: u64,
522 _type_id: TypeIdFor<Self>,
523 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
524 Ok(Value::U64(value))
525 }
526 fn visit_u128<'scale, 'resolver>(
527 self,
528 value: u128,
529 _type_id: TypeIdFor<Self>,
530 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
531 Ok(Value::U128(value))
532 }
533 fn visit_u256<'resolver>(
534 self,
535 value: &[u8; 32],
536 _type_id: TypeIdFor<Self>,
537 ) -> Result<Self::Value<'_, 'resolver>, Self::Error> {
538 Ok(Value::U256(*value))
539 }
540 fn visit_i8<'scale, 'resolver>(
541 self,
542 value: i8,
543 _type_id: TypeIdFor<Self>,
544 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
545 Ok(Value::I8(value))
546 }
547 fn visit_i16<'scale, 'resolver>(
548 self,
549 value: i16,
550 _type_id: TypeIdFor<Self>,
551 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
552 Ok(Value::I16(value))
553 }
554 fn visit_i32<'scale, 'resolver>(
555 self,
556 value: i32,
557 _type_id: TypeIdFor<Self>,
558 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
559 Ok(Value::I32(value))
560 }
561 fn visit_i64<'scale, 'resolver>(
562 self,
563 value: i64,
564 _type_id: TypeIdFor<Self>,
565 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
566 Ok(Value::I64(value))
567 }
568 fn visit_i128<'scale, 'resolver>(
569 self,
570 value: i128,
571 _type_id: TypeIdFor<Self>,
572 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
573 Ok(Value::I128(value))
574 }
575 fn visit_i256<'resolver>(
576 self,
577 value: &[u8; 32],
578 _type_id: TypeIdFor<Self>,
579 ) -> Result<Self::Value<'_, 'resolver>, Self::Error> {
580 Ok(Value::I256(*value))
581 }
582 fn visit_sequence<'scale, 'resolver>(
583 self,
584 value: &mut Sequence<'scale, 'resolver, Self::TypeResolver>,
585 _type_id: TypeIdFor<Self>,
586 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
587 let mut vals = vec![];
588 while let Some(val) = value.decode_item(ValueVisitor::new()) {
589 let val = val?;
590 vals.push(val);
591 }
592 Ok(Value::Sequence(vals))
593 }
594 fn visit_composite<'scale, 'resolver>(
595 self,
596 value: &mut Composite<'scale, 'resolver, Self::TypeResolver>,
597 _type_id: TypeIdFor<Self>,
598 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
599 let mut vals = vec![];
600 for item in value.by_ref() {
601 let item = item?;
602 let val = item.decode_with_visitor(ValueVisitor::new())?;
603 let name = item.name().unwrap_or("").to_owned();
604 vals.push((name, val));
605 }
606 Ok(Value::Composite(vals))
607 }
608 fn visit_tuple<'scale, 'resolver>(
609 self,
610 value: &mut Tuple<'scale, 'resolver, Self::TypeResolver>,
611 _type_id: TypeIdFor<Self>,
612 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
613 let mut vals = vec![];
614 while let Some(val) = value.decode_item(ValueVisitor::new()) {
615 let val = val?;
616 vals.push(val);
617 }
618 Ok(Value::Tuple(vals))
619 }
620 fn visit_str<'scale, 'resolver>(
621 self,
622 value: &mut Str<'scale>,
623 _type_id: TypeIdFor<Self>,
624 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
625 Ok(Value::Str(value.as_str()?.to_owned()))
626 }
627 fn visit_variant<'scale, 'resolver>(
628 self,
629 value: &mut Variant<'scale, 'resolver, Self::TypeResolver>,
630 _type_id: TypeIdFor<Self>,
631 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
632 let mut vals = vec![];
633 let fields = value.fields();
634 for item in fields.by_ref() {
635 let item = item?;
636 let val = item.decode_with_visitor(ValueVisitor::new())?;
637 let name = item.name().unwrap_or("").to_owned();
638 vals.push((name, val));
639 }
640 Ok(Value::Variant(value.name().to_owned(), vals))
641 }
642 fn visit_array<'scale, 'resolver>(
643 self,
644 value: &mut Array<'scale, 'resolver, Self::TypeResolver>,
645 _type_id: TypeIdFor<Self>,
646 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
647 let mut vals = vec![];
648 while let Some(val) = value.decode_item(ValueVisitor::new()) {
649 let val = val?;
650 vals.push(val);
651 }
652 Ok(Value::Array(vals))
653 }
654 fn visit_bitsequence<'scale, 'resolver>(
655 self,
656 value: &mut BitSequence<'scale>,
657 _type_id: TypeIdFor<Self>,
658 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
659 let bools: Result<scale_bits::Bits, _> = value.decode()?.collect();
660 Ok(Value::BitSequence(bools?))
661 }
662 }
663
664 fn make_type<T: scale_info::TypeInfo + 'static>() -> (u32, PortableRegistry) {
667 let m = scale_info::MetaType::new::<T>();
668 let mut types = scale_info::Registry::new();
669 let id = types.register_type(&m);
670 let portable_registry: PortableRegistry = types.into();
671
672 (id.id, portable_registry)
673 }
674
675 fn encode_decode_check_explicit_info<
678 Ty: scale_info::TypeInfo + 'static,
679 T: Encode,
680 V: for<'s, 'i> Visitor<Value<'s, 'i> = Value, Error = E, TypeResolver = PortableRegistry>,
681 E: core::fmt::Debug,
682 >(
683 val: T,
684 expected: Value,
685 visitor: V,
686 ) {
687 let encoded = val.encode();
688 let (id, types) = make_type::<Ty>();
689 let bytes = &mut &*encoded;
690 let val =
691 decode_with_visitor(bytes, id, &types, visitor).expect("decoding should not error");
692
693 assert_eq!(bytes.len(), 0, "Decoding should consume all bytes");
694 assert_eq!(val, expected);
695 }
696
697 fn encode_decode_check_with_visitor<
698 T: Encode + scale_info::TypeInfo + 'static,
699 V: for<'s, 'i> Visitor<Value<'s, 'i> = Value, Error = E, TypeResolver = PortableRegistry>,
700 E: core::fmt::Debug,
701 >(
702 val: T,
703 expected: Value,
704 visitor: V,
705 ) {
706 encode_decode_check_explicit_info::<T, T, _, _>(val, expected, visitor);
707 }
708
709 fn encode_decode_check<T: Encode + scale_info::TypeInfo + 'static>(val: T, expected: Value) {
710 encode_decode_check_explicit_info::<T, T, _, _>(val, expected, ValueVisitor::new());
711 }
712
713 #[test]
714 fn decode_with_root_error_wrapper_works() {
715 use crate::visitor::VisitorWithCrateError;
716 let visitor = VisitorWithCrateError(ValueVisitor::new());
717
718 encode_decode_check_with_visitor(123u8, Value::U8(123), visitor);
719 encode_decode_check_with_visitor(123u16, Value::U16(123), visitor);
720 encode_decode_check_with_visitor(123u32, Value::U32(123), visitor);
721 encode_decode_check_with_visitor(123u64, Value::U64(123), visitor);
722 encode_decode_check_with_visitor(123u128, Value::U128(123), visitor);
723 encode_decode_check_with_visitor(
724 "Hello there",
725 Value::Str("Hello there".to_owned()),
726 visitor,
727 );
728
729 #[derive(Encode, scale_info::TypeInfo)]
730 struct Unnamed(bool, String, Vec<u8>);
731 encode_decode_check_with_visitor(
732 Unnamed(true, "James".into(), vec![1, 2, 3]),
733 Value::Composite(vec![
734 (String::new(), Value::Bool(true)),
735 (String::new(), Value::Str("James".to_string())),
736 (String::new(), Value::Sequence(vec![Value::U8(1), Value::U8(2), Value::U8(3)])),
737 ]),
738 visitor,
739 );
740 }
741
742 #[test]
743 fn encode_decode_primitives() {
744 encode_decode_check(123u8, Value::U8(123));
745 encode_decode_check(123u16, Value::U16(123));
746 encode_decode_check(123u32, Value::U32(123));
747 encode_decode_check(123u64, Value::U64(123));
748 encode_decode_check(123u128, Value::U128(123));
749 encode_decode_check(codec::Compact(123u8), Value::U8(123));
750 encode_decode_check(codec::Compact(123u16), Value::U16(123));
751 encode_decode_check(codec::Compact(123u32), Value::U32(123));
752 encode_decode_check(codec::Compact(123u64), Value::U64(123));
753 encode_decode_check(codec::Compact(123u128), Value::U128(123));
754 encode_decode_check(true, Value::Bool(true));
755 encode_decode_check(false, Value::Bool(false));
756 encode_decode_check_explicit_info::<char, _, _, _>(
757 'c' as u32,
758 Value::Char('c'),
759 ValueVisitor::new(),
760 );
761 encode_decode_check("Hello there", Value::Str("Hello there".to_owned()));
762 encode_decode_check("Hello there".to_string(), Value::Str("Hello there".to_owned()));
763 }
764
765 #[test]
766 fn decode_compact_named_wrapper_struct() {
767 #[derive(Encode, scale_info::TypeInfo, CompactAs)]
769 struct MyWrapper {
770 inner: u32,
771 }
772
773 encode_decode_check(
774 codec::Compact(MyWrapper { inner: 123 }),
775 Value::Composite(vec![("inner".into(), Value::U32(123))]),
776 );
777 }
778
779 #[test]
780 fn decode_compact_unnamed_wrapper_struct() {
781 #[derive(Encode, scale_info::TypeInfo, CompactAs)]
783 struct MyWrapper(u32);
784
785 encode_decode_check(
786 codec::Compact(MyWrapper(123)),
787 Value::Composite(vec![("".into(), Value::U32(123))]),
788 );
789 }
790
791 #[test]
792 fn decode_nested_compact_structs() {
793 #[derive(Encode, scale_info::TypeInfo)]
795 struct Outer {
796 #[codec(compact)]
797 inner1: Inner1,
798 other: u16,
799 }
800
801 #[derive(Encode, scale_info::TypeInfo, CompactAs)]
802 struct Inner1 {
803 inner2: Inner2,
804 }
805
806 #[derive(Encode, scale_info::TypeInfo, CompactAs)]
807 struct Inner2(u64);
808
809 let struct_to_check = Outer { inner1: Inner1 { inner2: Inner2(123) }, other: 42 };
810 let expacted_value = Value::Composite(vec![
811 (
812 "inner1".into(),
813 Value::Composite(vec![(
814 "inner2".into(),
815 Value::Composite(vec![("".into(), Value::U64(123))]),
816 )]),
817 ),
818 ("other".into(), Value::U16(42)),
819 ]);
820 encode_decode_check(struct_to_check, expacted_value);
821 }
822
823 #[test]
824 fn decode_compact_single_item_tuple_field() {
825 #[derive(Encode, scale_info::TypeInfo, CompactAs)]
827 struct Struct {
828 a: (u32,),
829 }
830
831 encode_decode_check(
832 Struct { a: (123,) },
833 Value::Composite(vec![("a".into(), Value::Tuple(vec![Value::U32(123)]))]),
834 );
835 }
836
837 #[test]
838 fn decode_sequence_array_tuple_types() {
839 encode_decode_check(
840 vec![1i32, 2, 3],
841 Value::Sequence(vec![Value::I32(1), Value::I32(2), Value::I32(3)]),
842 );
843 encode_decode_check(
844 [1i32, 2, 3], Value::Array(vec![Value::I32(1), Value::I32(2), Value::I32(3)]),
846 );
847 encode_decode_check(
848 (1i32, true, 123456u128),
849 Value::Tuple(vec![Value::I32(1), Value::Bool(true), Value::U128(123456)]),
850 );
851 }
852
853 #[test]
854 fn decode_variant_types() {
855 #[derive(Encode, scale_info::TypeInfo)]
856 enum MyEnum {
857 Foo(bool),
858 Bar { hi: String, other: u128 },
859 }
860
861 encode_decode_check(
862 MyEnum::Foo(true),
863 Value::Variant("Foo".to_owned(), vec![(String::new(), Value::Bool(true))]),
864 );
865 encode_decode_check(
866 MyEnum::Bar { hi: "hello".to_string(), other: 123 },
867 Value::Variant(
868 "Bar".to_owned(),
869 vec![
870 ("hi".to_string(), Value::Str("hello".to_string())),
871 ("other".to_string(), Value::U128(123)),
872 ],
873 ),
874 );
875 }
876
877 #[test]
878 fn decode_composite_types() {
879 #[derive(Encode, scale_info::TypeInfo)]
880 struct Unnamed(bool, String, Vec<u8>);
881
882 #[derive(Encode, scale_info::TypeInfo)]
883 struct Named {
884 is_valid: bool,
885 name: String,
886 bytes: Vec<u8>,
887 }
888
889 encode_decode_check(
890 Unnamed(true, "James".into(), vec![1, 2, 3]),
891 Value::Composite(vec![
892 (String::new(), Value::Bool(true)),
893 (String::new(), Value::Str("James".to_string())),
894 (String::new(), Value::Sequence(vec![Value::U8(1), Value::U8(2), Value::U8(3)])),
895 ]),
896 );
897 encode_decode_check(
898 Named { is_valid: true, name: "James".into(), bytes: vec![1, 2, 3] },
899 Value::Composite(vec![
900 ("is_valid".to_string(), Value::Bool(true)),
901 ("name".to_string(), Value::Str("James".to_string())),
902 (
903 "bytes".to_string(),
904 Value::Sequence(vec![Value::U8(1), Value::U8(2), Value::U8(3)]),
905 ),
906 ]),
907 );
908 }
909
910 #[test]
911 fn decode_arrays() {
912 encode_decode_check(
913 [1u8, 2, 3],
914 Value::Array(vec![Value::U8(1), Value::U8(2), Value::U8(3)]),
915 )
916 }
917
918 #[test]
919 fn decode_bit_sequence() {
920 use bitvec::{
921 bitvec,
922 order::{Lsb0, Msb0},
923 };
924 use scale_bits::bits;
925
926 encode_decode_check(bits![0, 1, 1, 0, 1, 0], Value::BitSequence(bits![0, 1, 1, 0, 1, 0]));
928 encode_decode_check(
929 bitvec![u8, Lsb0; 0, 1, 1, 0, 1, 0],
930 Value::BitSequence(bits![0, 1, 1, 0, 1, 0]),
931 );
932 encode_decode_check(
933 bitvec![u16, Lsb0; 0, 1, 1, 0, 1, 0],
934 Value::BitSequence(bits![0, 1, 1, 0, 1, 0]),
935 );
936 encode_decode_check(
937 bitvec![u32, Lsb0; 0, 1, 1, 0, 1, 0],
938 Value::BitSequence(bits![0, 1, 1, 0, 1, 0]),
939 );
940 encode_decode_check(
941 bitvec![u64, Lsb0; 0, 1, 1, 0, 1, 0],
942 Value::BitSequence(bits![0, 1, 1, 0, 1, 0]),
943 );
944 encode_decode_check(
945 bitvec![u8, Msb0; 0, 1, 1, 0, 1, 0],
946 Value::BitSequence(bits![0, 1, 1, 0, 1, 0]),
947 );
948 encode_decode_check(
949 bitvec![u16, Msb0; 0, 1, 1, 0, 1, 0],
950 Value::BitSequence(bits![0, 1, 1, 0, 1, 0]),
951 );
952 encode_decode_check(
953 bitvec![u32, Msb0; 0, 1, 1, 0, 1, 0],
954 Value::BitSequence(bits![0, 1, 1, 0, 1, 0]),
955 );
956 encode_decode_check(
957 bitvec![u64, Msb0; 0, 1, 1, 0, 1, 0],
958 Value::BitSequence(bits![0, 1, 1, 0, 1, 0]),
959 );
960 }
961
962 macro_rules! decoding_returns_error_first {
970 ($name:ident $expr:expr) => {
971 #[test]
972 fn $name() {
973 fn visitor_err() -> DecodeError {
974 DecodeError::TypeResolvingError("Whoops".to_string())
975 }
976
977 #[derive(codec::Encode)]
978 struct HasBadTypeInfo;
979 impl scale_info::TypeInfo for HasBadTypeInfo {
980 type Identity = Self;
981 fn type_info() -> scale_info::Type {
982 scale_info::meta_type::<u8>().type_info()
985 }
986 }
987
988 struct VisitorImpl;
989 impl Visitor for VisitorImpl {
990 type Value<'scale, 'resolver> = ();
991 type Error = DecodeError;
992 type TypeResolver = PortableRegistry;
993
994 fn visit_unexpected<'scale, 'resolver>(
995 self,
996 _unexpected: Unexpected,
997 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
998 Err(visitor_err())
1001 }
1002 }
1003
1004 fn assert_visitor_err<E: codec::Encode + scale_info::TypeInfo + 'static>(input: E) {
1005 let input_encoded = input.encode();
1006 let (ty_id, types) = make_type::<E>();
1007 let err = decode_with_visitor(&mut &*input_encoded, ty_id, &types, VisitorImpl)
1008 .unwrap_err();
1009 assert_eq!(err, visitor_err());
1010 }
1011
1012 assert_visitor_err($expr);
1013 }
1014 };
1015 }
1016
1017 decoding_returns_error_first!(decode_composite_returns_error_first {
1018 #[derive(codec::Encode, scale_info::TypeInfo)]
1019 struct SomeComposite {
1020 a: bool,
1021 b: HasBadTypeInfo,
1022 c: Vec<u8>
1023 }
1024
1025 SomeComposite { a: true, b: HasBadTypeInfo, c: vec![1,2,3] }
1026 });
1027
1028 decoding_returns_error_first!(decode_variant_returns_error_first {
1029 #[derive(codec::Encode, scale_info::TypeInfo)]
1030 enum SomeVariant {
1031 Foo(u32, HasBadTypeInfo, String)
1032 }
1033
1034 SomeVariant::Foo(32, HasBadTypeInfo, "hi".to_owned())
1035 });
1036
1037 decoding_returns_error_first!(decode_array_returns_error_first {
1038 [HasBadTypeInfo, HasBadTypeInfo]
1039 });
1040
1041 decoding_returns_error_first!(decode_sequence_returns_error_first {
1042 vec![HasBadTypeInfo, HasBadTypeInfo]
1043 });
1044
1045 decoding_returns_error_first!(decode_tuple_returns_error_first {
1046 (32u64, HasBadTypeInfo, true)
1047 });
1048
1049 #[test]
1050 fn zero_copy_string_decoding() {
1051 let input = ("hello", "world");
1052
1053 let input_encoded = input.encode();
1055
1056 struct ZeroCopyStrVisitor;
1058 impl Visitor for ZeroCopyStrVisitor {
1059 type Value<'scale, 'resolver> = &'scale str;
1060 type Error = DecodeError;
1061 type TypeResolver = PortableRegistry;
1062
1063 fn visit_str<'scale, 'resolver>(
1064 self,
1065 value: &mut Str<'scale>,
1066 _type_id: TypeIdFor<Self>,
1067 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
1068 value.as_str()
1069 }
1070 }
1071
1072 struct ZeroCopyPairVisitor;
1074 impl Visitor for ZeroCopyPairVisitor {
1075 type Value<'scale, 'resolver> = (&'scale str, &'scale str);
1076 type Error = DecodeError;
1077 type TypeResolver = PortableRegistry;
1078
1079 fn visit_tuple<'scale, 'resolver>(
1080 self,
1081 value: &mut Tuple<'scale, 'resolver, Self::TypeResolver>,
1082 _type_id: TypeIdFor<Self>,
1083 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
1084 let fst = value.decode_item(ZeroCopyStrVisitor).unwrap()?;
1085 let snd = value.decode_item(ZeroCopyStrVisitor).unwrap()?;
1086 Ok((fst, snd))
1087 }
1088 }
1089
1090 let (ty_id, types) = make_type::<(&str, &str)>();
1091 let decoded =
1092 decode_with_visitor(&mut &*input_encoded, ty_id, &types, ZeroCopyPairVisitor).unwrap();
1093 assert_eq!(decoded, ("hello", "world"));
1094 }
1095
1096 #[test]
1097 fn zero_copy_using_info_and_scale_lifetimes() {
1098 use alloc::collections::BTreeMap;
1099
1100 #[derive(codec::Encode, scale_info::TypeInfo)]
1101 struct Foo {
1102 hello: String,
1103 world: String,
1104 }
1105
1106 let input_encoded = Foo { hello: "hi".to_string(), world: "planet".to_string() }.encode();
1108
1109 struct ZeroCopyStrVisitor;
1111 impl Visitor for ZeroCopyStrVisitor {
1112 type Value<'scale, 'resolver> = &'scale str;
1113 type Error = DecodeError;
1114 type TypeResolver = PortableRegistry;
1115
1116 fn visit_str<'scale, 'resolver>(
1117 self,
1118 value: &mut Str<'scale>,
1119 _type_id: TypeIdFor<Self>,
1120 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
1121 value.as_str()
1122 }
1123 }
1124
1125 struct ZeroCopyMapVisitor;
1127 impl Visitor for ZeroCopyMapVisitor {
1128 type Value<'scale, 'resolver> =
1129 alloc::collections::BTreeMap<&'resolver str, &'scale str>;
1130 type Error = DecodeError;
1131 type TypeResolver = PortableRegistry;
1132
1133 fn visit_composite<'scale, 'resolver>(
1134 self,
1135 value: &mut Composite<'scale, 'resolver, Self::TypeResolver>,
1136 _type_id: TypeIdFor<Self>,
1137 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
1138 let mut vals = alloc::collections::BTreeMap::<&'resolver str, &'scale str>::new();
1139 for item in value {
1140 let item = item?;
1141 let Some(key) = item.name() else { continue };
1142 let val = item.decode_with_visitor(ZeroCopyStrVisitor)?;
1143 vals.insert(key, val);
1144 }
1145 Ok(vals)
1146 }
1147 }
1148
1149 let (ty_id, types) = make_type::<Foo>();
1151 let decoded =
1152 decode_with_visitor(&mut &*input_encoded, ty_id, &types, ZeroCopyMapVisitor).unwrap();
1153 assert_eq!(decoded, BTreeMap::from_iter([("hello", "hi"), ("world", "planet")]));
1154 }
1155
1156 #[test]
1157 fn bailout_works() {
1158 let input = ("hello", "world");
1159 let (ty_id, types) = make_type::<(&str, &str)>();
1160 let input_encoded = input.encode();
1161
1162 struct BailOutVisitor;
1165 impl Visitor for BailOutVisitor {
1166 type Value<'scale, 'resolver> = (&'scale [u8], u32);
1167 type Error = DecodeError;
1168 type TypeResolver = PortableRegistry;
1169
1170 fn unchecked_decode_as_type<'scale, 'resolver>(
1171 self,
1172 input: &mut &'scale [u8],
1173 type_id: u32,
1174 _types: &'resolver scale_info::PortableRegistry,
1175 ) -> DecodeAsTypeResult<Self, Result<Self::Value<'scale, 'resolver>, Self::Error>>
1176 {
1177 DecodeAsTypeResult::Decoded(Ok((*input, type_id)))
1178 }
1179 }
1180
1181 let decoded =
1182 decode_with_visitor(&mut &*input_encoded, ty_id, &types, BailOutVisitor).unwrap();
1183 assert_eq!(decoded, (&*input_encoded, ty_id));
1184
1185 struct CodecDecodeVisitor<T>(core::marker::PhantomData<T>);
1188 impl<T: codec::Decode> Visitor for CodecDecodeVisitor<T> {
1189 type Value<'scale, 'resolver> = T;
1190 type Error = DecodeError;
1191 type TypeResolver = PortableRegistry;
1192
1193 fn unchecked_decode_as_type<'scale, 'resolver>(
1194 self,
1195 input: &mut &'scale [u8],
1196 _type_id: TypeIdFor<Self>,
1197 _types: &'resolver scale_info::PortableRegistry,
1198 ) -> DecodeAsTypeResult<Self, Result<Self::Value<'scale, 'resolver>, Self::Error>>
1199 {
1200 DecodeAsTypeResult::Decoded(T::decode(input).map_err(|e| e.into()))
1201 }
1202 }
1203
1204 let decoded: (String, String) = decode_with_visitor(
1205 &mut &*input_encoded,
1206 ty_id,
1207 &types,
1208 CodecDecodeVisitor(core::marker::PhantomData),
1209 )
1210 .unwrap();
1211 assert_eq!(decoded, ("hello".to_string(), "world".to_string()));
1212 }
1213
1214 mod proptests {
1217 use super::*;
1218 use proptest::prelude::*;
1219
1220 proptest! {
1221 #[test]
1222 fn invalid_strings_dont_panic(bytes in any::<Vec<u8>>()) {
1223 let (id, types) = make_type::<String>();
1224 let _ = decode_with_visitor(&mut &*bytes, id, &types, ValueVisitor::new());
1225 }
1226
1227 #[test]
1228 fn invalid_bitvecs_dont_panic(bytes in any::<Vec<u8>>()) {
1229 use bitvec::{
1230 vec::BitVec,
1231 order::{Lsb0, Msb0},
1232 };
1233
1234 let (id, types) = make_type::<BitVec<u8,Lsb0>>();
1235 let _ = decode_with_visitor(&mut &*bytes, id, &types, ValueVisitor::new());
1236
1237 let (id, types) = make_type::<BitVec<u8,Msb0>>();
1238 let _ = decode_with_visitor(&mut &*bytes, id, &types, ValueVisitor::new());
1239
1240 let (id, types) = make_type::<BitVec<u32,Lsb0>>();
1241 let _ = decode_with_visitor(&mut &*bytes, id, &types, ValueVisitor::new());
1242
1243 let (id, types) = make_type::<BitVec<u32,Msb0>>();
1244 let _ = decode_with_visitor(&mut &*bytes, id, &types, ValueVisitor::new());
1245 }
1246 }
1247 }
1248}