1#[cfg(feature = "primitive-types")]
17mod primitive_types;
18
19use crate::{
20 error::{Error, ErrorKind},
21 visitor::{
22 self, decode_with_visitor, types::*, DecodeAsTypeResult, DecodeItemIterator, Visitor,
23 },
24 DecodeAsFields, FieldIter, IntoVisitor,
25};
26use alloc::{
27 borrow::{Cow, ToOwned},
28 boxed::Box,
29 collections::{BTreeMap, BTreeSet, BinaryHeap, LinkedList, VecDeque},
30 rc::Rc,
31 string::{String, ToString},
32 sync::Arc,
33 vec,
34 vec::Vec,
35};
36use codec::Compact;
37use core::num::{
38 NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroU128, NonZeroU16,
39 NonZeroU32, NonZeroU64, NonZeroU8,
40};
41use core::{
42 marker::PhantomData,
43 ops::{Range, RangeInclusive},
44 time::Duration,
45};
46use scale_bits::Bits;
47use scale_type_resolver::TypeResolver;
48
49pub struct BasicVisitor<T, R> {
50 _marker: core::marker::PhantomData<(T, R)>,
51}
52
53macro_rules! impl_into_visitor {
55 ($ty:ident $(< $($param:ident),* >)? $(where $( $where:tt )* )?) => {
56 impl $(< $($param),* >)? crate::IntoVisitor for $ty $(< $($param),* >)?
57 where $( $($where)* )?
58 {
59 type AnyVisitor<R: TypeResolver> = BasicVisitor<$ty $(< $($param),* >)?, R>;
60 fn into_visitor<R: TypeResolver>() -> Self::AnyVisitor<R> {
61 BasicVisitor { _marker: core::marker::PhantomData }
62 }
63 }
64 };
65}
66
67macro_rules! visit_single_field_composite_tuple_impls {
69 ($type_resolver:ident) => {
70 fn visit_composite<'scale, 'resolver>(
71 self,
72 value: &mut $crate::visitor::types::Composite<'scale, 'resolver, $type_resolver>,
73 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
74 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
75 if value.remaining() != 1 {
76 return self.visit_unexpected($crate::visitor::Unexpected::Composite);
77 }
78 value.decode_item(self).unwrap()
79 }
80 fn visit_tuple<'scale, 'resolver>(
81 self,
82 value: &mut $crate::visitor::types::Tuple<'scale, 'resolver, $type_resolver>,
83 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
84 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
85 if value.remaining() != 1 {
86 return self.visit_unexpected($crate::visitor::Unexpected::Tuple);
87 }
88 value.decode_item(self).unwrap()
89 }
90 };
91}
92
93impl<R: TypeResolver> Visitor for BasicVisitor<char, R> {
94 type Error = Error;
95 type Value<'scale, 'resolver> = char;
96 type TypeResolver = R;
97
98 fn visit_char<'scale, 'resolver>(
99 self,
100 value: char,
101 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
102 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
103 Ok(value)
104 }
105 visit_single_field_composite_tuple_impls!(R);
106}
107impl_into_visitor!(char);
108
109impl<R: TypeResolver> Visitor for BasicVisitor<bool, R> {
110 type Error = Error;
111 type Value<'scale, 'resolver> = bool;
112 type TypeResolver = R;
113
114 fn visit_bool<'scale, 'resolver>(
115 self,
116 value: bool,
117 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
118 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
119 Ok(value)
120 }
121 visit_single_field_composite_tuple_impls!(R);
122}
123impl_into_visitor!(bool);
124
125impl<R: TypeResolver> Visitor for BasicVisitor<String, R> {
126 type Error = Error;
127 type Value<'scale, 'resolver> = String;
128 type TypeResolver = R;
129
130 fn visit_str<'scale, 'resolver>(
131 self,
132 value: &mut Str<'scale>,
133 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
134 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
135 let s = value.as_str()?.to_owned();
136 Ok(s)
137 }
138 visit_single_field_composite_tuple_impls!(R);
139}
140impl_into_visitor!(String);
141
142impl<R: TypeResolver> Visitor for BasicVisitor<Bits, R> {
143 type Error = Error;
144 type Value<'scale, 'resolver> = Bits;
145 type TypeResolver = R;
146
147 fn visit_bitsequence<'scale, 'resolver>(
148 self,
149 value: &mut BitSequence<'scale>,
150 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
151 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
152 value
153 .decode()?
154 .collect::<Result<Bits, _>>()
155 .map_err(|e| Error::new(ErrorKind::VisitorDecodeError(e.into())))
156 }
157 visit_single_field_composite_tuple_impls!(R);
158}
159impl_into_visitor!(Bits);
160
161impl<T, R: TypeResolver> Visitor for BasicVisitor<PhantomData<T>, R> {
162 type Error = Error;
163 type Value<'scale, 'resolver> = PhantomData<T>;
164 type TypeResolver = R;
165
166 fn visit_tuple<'scale, 'resolver>(
167 self,
168 value: &mut Tuple<'scale, 'resolver, R>,
169 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
170 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
171 if value.remaining() == 0 {
172 Ok(PhantomData)
173 } else {
174 self.visit_unexpected(visitor::Unexpected::Tuple)
175 }
176 }
177 fn visit_composite<'scale, 'resolver>(
178 self,
179 value: &mut Composite<'scale, 'resolver, R>,
180 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
181 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
182 if value.remaining() == 0 {
183 Ok(PhantomData)
184 } else {
185 self.visit_unexpected(visitor::Unexpected::Composite)
186 }
187 }
188}
189impl_into_visitor!(PhantomData<T>);
190
191macro_rules! impl_into_visitor_like {
194 ($target:ident $(< $($param:ident),* >)? as $source:ty $( [where $($where:tt)*] )?: $mapper:expr) => {
195 impl <$( $($param, )* )? Resolver> Visitor for BasicVisitor<$target $(< $($param),* >)?, Resolver>
196 where
197 $source: IntoVisitor,
198 Resolver: TypeResolver,
199 $( $($where)* )?
200 {
201 type Value<'scale, 'resolver> = $target $(< $($param),* >)?;
202 type Error = <<$source as IntoVisitor>::AnyVisitor<Resolver> as Visitor>::Error;
203 type TypeResolver = Resolver;
204
205 fn unchecked_decode_as_type<'scale, 'resolver>(
206 self,
207 input: &mut &'scale [u8],
208 type_id: <Self::TypeResolver as TypeResolver>::TypeId,
209 types: &'resolver Self::TypeResolver,
210 ) -> DecodeAsTypeResult<Self, Result<Self::Value<'scale, 'resolver>, Self::Error>> {
211 let inner_res = decode_with_visitor(input, type_id, types, <$source>::into_visitor());
213 let res = inner_res.map($mapper);
215 DecodeAsTypeResult::Decoded(res)
216 }
217 }
218 impl_into_visitor!($target $(< $($param),* >)? where $source: IntoVisitor);
219 }
220}
221
222impl_into_visitor_like!(Compact<T> as T: |res| Compact(res));
223impl_into_visitor_like!(Arc<T> as T: |res| Arc::new(res));
224impl_into_visitor_like!(Rc<T> as T: |res| Rc::new(res));
225impl_into_visitor_like!(Box<T> as T: |res| Box::new(res));
226impl_into_visitor_like!(Duration as (u64, u32): |res: (u64,u32)| Duration::from_secs(res.0) + Duration::from_nanos(res.1 as u64));
227impl_into_visitor_like!(Range<T> as (T, T): |res: (T,T)| res.0..res.1);
228impl_into_visitor_like!(RangeInclusive<T> as (T, T): |res: (T,T)| res.0..=res.1);
229
230impl<'a, T, R> Visitor for BasicVisitor<Cow<'a, T>, R>
233where
234 T: 'a + ToOwned + ?Sized,
235 <T as ToOwned>::Owned: IntoVisitor,
236 R: TypeResolver,
237{
238 type Value<'scale, 'resolver> = Cow<'a, T>;
239 type Error = <<<T as ToOwned>::Owned as IntoVisitor>::AnyVisitor<R> as Visitor>::Error;
240 type TypeResolver = R;
241
242 fn unchecked_decode_as_type<'scale, 'resolver>(
243 self,
244 input: &mut &'scale [u8],
245 type_id: <Self::TypeResolver as TypeResolver>::TypeId,
246 types: &'resolver Self::TypeResolver,
247 ) -> DecodeAsTypeResult<Self, Result<Self::Value<'scale, 'resolver>, Self::Error>> {
248 let inner_res =
250 decode_with_visitor(input, type_id, types, <<T as ToOwned>::Owned>::into_visitor());
251 let res = inner_res.map(Cow::Owned);
253 DecodeAsTypeResult::Decoded(res)
254 }
255}
256impl<'a, T> IntoVisitor for Cow<'a, T>
257where
258 T: 'a + ToOwned + ?Sized,
259 <T as ToOwned>::Owned: IntoVisitor,
260{
261 type AnyVisitor<R: TypeResolver> = BasicVisitor<Cow<'a, T>, R>;
262 fn into_visitor<R: TypeResolver>() -> Self::AnyVisitor<R> {
263 BasicVisitor { _marker: core::marker::PhantomData }
264 }
265}
266
267macro_rules! impl_decode_seq_via_collect {
268 ($ty:ident<$generic:ident> $(where $($where:tt)*)?) => {
269 impl <$generic, Resolver> Visitor for BasicVisitor<$ty<$generic>, Resolver>
270 where
271 $generic: IntoVisitor,
272 Resolver: TypeResolver,
273 $( $($where)* )?
274 {
275 type Value<'scale, 'resolver> = $ty<$generic>;
276 type Error = Error;
277 type TypeResolver = Resolver;
278
279 fn visit_sequence<'scale, 'resolver>(
280 self,
281 value: &mut Sequence<'scale, 'resolver, Resolver>,
282 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
283 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
284 decode_items_using::<_, _, $generic>(value).collect()
285 }
286 fn visit_array<'scale, 'resolver>(
287 self,
288 value: &mut Array<'scale, 'resolver, Resolver>,
289 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
290 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
291 decode_items_using::<_, _, $generic>(value).collect()
292 }
293
294 visit_single_field_composite_tuple_impls!(Resolver);
295 }
296 impl_into_visitor!($ty < $generic > where $generic: IntoVisitor, $( $($where)* )?);
297 }
298}
299impl_decode_seq_via_collect!(Vec<T>);
300impl_decode_seq_via_collect!(VecDeque<T>);
301impl_decode_seq_via_collect!(LinkedList<T>);
302impl_decode_seq_via_collect!(BinaryHeap<T> where T: Ord);
303impl_decode_seq_via_collect!(BTreeSet<T> where T: Ord);
304
305macro_rules! array_method_impl {
308 ($value:ident, [$t:ident; $n:ident]) => {{
309 let val = decode_items_using::<_, _, $t>($value).collect::<Result<Vec<$t>, _>>()?;
310 let actual_len = val.len();
311 let arr = val
312 .try_into()
313 .map_err(|_e| Error::new(ErrorKind::WrongLength { actual_len, expected_len: $n }))?;
314 Ok(arr)
315 }};
316}
317impl<const N: usize, T: IntoVisitor, R: TypeResolver> Visitor for BasicVisitor<[T; N], R> {
318 type Value<'scale, 'resolver> = [T; N];
319 type Error = Error;
320 type TypeResolver = R;
321
322 fn visit_sequence<'scale, 'resolver>(
323 self,
324 value: &mut Sequence<'scale, 'resolver, R>,
325 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
326 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
327 array_method_impl!(value, [T; N])
328 }
329 fn visit_array<'scale, 'resolver>(
330 self,
331 value: &mut Array<'scale, 'resolver, R>,
332 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
333 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
334 array_method_impl!(value, [T; N])
335 }
336
337 visit_single_field_composite_tuple_impls!(R);
338}
339impl<const N: usize, T: IntoVisitor> IntoVisitor for [T; N] {
340 type AnyVisitor<R: TypeResolver> = BasicVisitor<[T; N], R>;
341 fn into_visitor<R: TypeResolver>() -> Self::AnyVisitor<R> {
342 BasicVisitor { _marker: core::marker::PhantomData }
343 }
344}
345
346impl<T: IntoVisitor, R: TypeResolver> Visitor for BasicVisitor<BTreeMap<String, T>, R> {
347 type Error = Error;
348 type Value<'scale, 'resolver> = BTreeMap<String, T>;
349 type TypeResolver = R;
350
351 fn visit_composite<'scale, 'resolver>(
352 self,
353 value: &mut Composite<'scale, 'resolver, R>,
354 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
355 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
356 let mut map = BTreeMap::new();
357 while value.remaining() > 0 {
358 let Some(key) = value.peek_name() else {
360 value.decode_item(crate::visitor::IgnoreVisitor::<R>::new()).transpose()?;
361 continue;
362 };
363 let Some(val) = value.decode_item(T::into_visitor::<R>()) else { break };
365 let val = val.map_err(|e| e.at_field(key.to_owned()))?;
367 map.insert(key.to_owned(), val);
368 }
369 Ok(map)
370 }
371}
372impl<T: IntoVisitor> IntoVisitor for BTreeMap<String, T> {
373 type AnyVisitor<R: TypeResolver> = BasicVisitor<BTreeMap<String, T>, R>;
374 fn into_visitor<R: TypeResolver>() -> Self::AnyVisitor<R> {
375 BasicVisitor { _marker: core::marker::PhantomData }
376 }
377}
378
379impl<T: IntoVisitor, R: TypeResolver> Visitor for BasicVisitor<Option<T>, R> {
380 type Error = Error;
381 type Value<'scale, 'resolver> = Option<T>;
382 type TypeResolver = R;
383
384 fn visit_variant<'scale, 'resolver>(
385 self,
386 value: &mut Variant<'scale, 'resolver, R>,
387 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
388 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
389 if value.name() == "Some" && value.fields().remaining() == 1 {
390 let val = value
391 .fields()
392 .decode_item(T::into_visitor::<R>())
393 .transpose()
394 .map_err(|e| e.at_variant("Some"))?
395 .expect("checked for 1 field already so should be ok");
396 Ok(Some(val))
397 } else if value.name() == "None" && value.fields().remaining() == 0 {
398 Ok(None)
399 } else {
400 Err(Error::new(ErrorKind::CannotFindVariant {
401 got: value.name().to_string(),
402 expected: vec!["Some", "None"],
403 }))
404 }
405 }
406 visit_single_field_composite_tuple_impls!(R);
407}
408impl_into_visitor!(Option<T> where T: IntoVisitor);
409
410impl<T: IntoVisitor, E: IntoVisitor, R: TypeResolver> Visitor for BasicVisitor<Result<T, E>, R> {
411 type Error = Error;
412 type Value<'scale, 'resolver> = Result<T, E>;
413 type TypeResolver = R;
414
415 fn visit_variant<'scale, 'resolver>(
416 self,
417 value: &mut Variant<'scale, 'resolver, R>,
418 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
419 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
420 if value.name() == "Ok" && value.fields().remaining() == 1 {
421 let val = value
422 .fields()
423 .decode_item(T::into_visitor::<R>())
424 .transpose()
425 .map_err(|e| e.at_variant("Ok"))?
426 .expect("checked for 1 field already so should be ok");
427 Ok(Ok(val))
428 } else if value.name() == "Err" && value.fields().remaining() == 1 {
429 let val = value
430 .fields()
431 .decode_item(E::into_visitor::<R>())
432 .transpose()
433 .map_err(|e| e.at_variant("Err"))?
434 .expect("checked for 1 field already so should be ok");
435 Ok(Err(val))
436 } else {
437 Err(Error::new(ErrorKind::CannotFindVariant {
438 got: value.name().to_string(),
439 expected: vec!["Ok", "Err"],
440 }))
441 }
442 }
443 visit_single_field_composite_tuple_impls!(R);
444}
445impl_into_visitor!(Result<T, E> where T: IntoVisitor, E: IntoVisitor);
446
447macro_rules! visit_number_fn_impl {
449 ($name:ident : $ty:ty where |$res:ident| $expr:expr) => {
450 fn $name<'scale, 'resolver>(
451 self,
452 value: $ty,
453 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
454 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
455 let $res = value;
456 let n = $expr.ok_or_else(|| {
457 Error::new(ErrorKind::NumberOutOfRange { value: value.to_string() })
458 })?;
459 Ok(n)
460 }
461 };
462}
463macro_rules! visit_number_impl {
464 ($ty:ident where |$res:ident| $expr:expr) => {
465 #[allow(clippy::unnecessary_fallible_conversions, clippy::useless_conversion)]
466 impl <R: TypeResolver> Visitor for BasicVisitor<$ty, R> {
467 type Error = Error;
468 type Value<'scale, 'resolver> = $ty;
469 type TypeResolver = R;
470
471 visit_number_fn_impl!(visit_u8: u8 where |$res| $expr);
472 visit_number_fn_impl!(visit_u16: u16 where |$res| $expr);
473 visit_number_fn_impl!(visit_u32: u32 where |$res| $expr);
474 visit_number_fn_impl!(visit_u64: u64 where |$res| $expr);
475 visit_number_fn_impl!(visit_u128: u128 where |$res| $expr);
476 visit_number_fn_impl!(visit_i8: i8 where |$res| $expr);
477 visit_number_fn_impl!(visit_i16: i16 where |$res| $expr);
478 visit_number_fn_impl!(visit_i32: i32 where |$res| $expr);
479 visit_number_fn_impl!(visit_i64: i64 where |$res| $expr);
480 visit_number_fn_impl!(visit_i128: i128 where |$res| $expr);
481
482 visit_single_field_composite_tuple_impls!(R);
483 }
484 impl_into_visitor!($ty);
485 };
486}
487visit_number_impl!(u8 where |res| res.try_into().ok());
488visit_number_impl!(u16 where |res| res.try_into().ok());
489visit_number_impl!(u32 where |res| res.try_into().ok());
490visit_number_impl!(u64 where |res| res.try_into().ok());
491visit_number_impl!(u128 where |res| res.try_into().ok());
492visit_number_impl!(usize where |res| res.try_into().ok());
493visit_number_impl!(i8 where |res| res.try_into().ok());
494visit_number_impl!(i16 where |res| res.try_into().ok());
495visit_number_impl!(i32 where |res| res.try_into().ok());
496visit_number_impl!(i64 where |res| res.try_into().ok());
497visit_number_impl!(i128 where |res| res.try_into().ok());
498visit_number_impl!(isize where |res| res.try_into().ok());
499visit_number_impl!(NonZeroU8 where |res| res.try_into().ok().and_then(NonZeroU8::new));
500visit_number_impl!(NonZeroU16 where |res| res.try_into().ok().and_then(NonZeroU16::new));
501visit_number_impl!(NonZeroU32 where |res| res.try_into().ok().and_then(NonZeroU32::new));
502visit_number_impl!(NonZeroU64 where |res| res.try_into().ok().and_then(NonZeroU64::new));
503visit_number_impl!(NonZeroU128 where |res| res.try_into().ok().and_then(NonZeroU128::new));
504visit_number_impl!(NonZeroI8 where |res| res.try_into().ok().and_then(NonZeroI8::new));
505visit_number_impl!(NonZeroI16 where |res| res.try_into().ok().and_then(NonZeroI16::new));
506visit_number_impl!(NonZeroI32 where |res| res.try_into().ok().and_then(NonZeroI32::new));
507visit_number_impl!(NonZeroI64 where |res| res.try_into().ok().and_then(NonZeroI64::new));
508visit_number_impl!(NonZeroI128 where |res| res.try_into().ok().and_then(NonZeroI128::new));
509
510macro_rules! count_idents {
511 ($t:ident $($rest:ident)*) => {
512 1 + count_idents!( $($rest)* )
513 };
514 () => {
515 0
516 }
517}
518
519macro_rules! tuple_method_impl {
521 (($($t:ident,)*), $value:ident) => {{
522 const EXPECTED_LEN: usize = count_idents!($($t)*);
523 if $value.remaining() != EXPECTED_LEN {
524 return Err(Error::new(ErrorKind::WrongLength {
525 actual_len: $value.remaining(),
526 expected_len: EXPECTED_LEN
527 }))
528 }
529
530 #[allow(unused)]
531 let mut idx = 0;
532
533 Ok((
534 $(
535 #[allow(unused_assignments)]
536 {
537 let v = $value
538 .decode_item($t::into_visitor::<Resolver>())
539 .transpose()
540 .map_err(|e| e.at_idx(idx))?
541 .expect("length already checked via .remaining()");
542 idx += 1;
543 v
544 }
545 ,)*
546 ))
547 }}
548}
549
550macro_rules! decode_inner_type_when_one_tuple_entry {
551 ($t:ident) => {
552 fn unchecked_decode_as_type<'scale, 'resolver>(
553 self,
554 input: &mut &'scale [u8],
555 type_id: <Self::TypeResolver as TypeResolver>::TypeId,
556 types: &'resolver Self::TypeResolver,
557 ) -> DecodeAsTypeResult<Self, Result<Self::Value<'scale, 'resolver>, Self::Error>> {
558 use scale_type_resolver::{ResolvedTypeVisitor, UnhandledKind};
559
560 struct TryDecodeAsInner<TypeId>(PhantomData<TypeId>);
563 impl<'resolver, TypeId: scale_type_resolver::TypeId + 'static>
564 ResolvedTypeVisitor<'resolver> for TryDecodeAsInner<TypeId>
565 {
566 type TypeId = TypeId;
567 type Value = bool;
568 fn visit_unhandled(self, kind: UnhandledKind) -> Self::Value {
569 match kind {
570 UnhandledKind::Composite
571 | UnhandledKind::Tuple
572 | UnhandledKind::NotFound => false,
573 _ => true,
574 }
575 }
576 }
577
578 if let Err(_) | Ok(false) =
580 types.resolve_type(type_id.clone(), TryDecodeAsInner(PhantomData))
581 {
582 return DecodeAsTypeResult::Skipped(self);
583 }
584
585 let inner_res = decode_with_visitor(input, type_id, types, <$t>::into_visitor());
587 let res = inner_res.map(|val| (val,)).map_err(|e| e.into());
588 DecodeAsTypeResult::Decoded(res)
589 }
590 };
591 ($($tt:tt)*) => {
592 };
594}
595macro_rules! impl_decode_tuple {
596 ($($t:ident)*) => {
597 impl <Resolver, $($t),* > Visitor for BasicVisitor<($($t,)*), Resolver>
598 where
599 Resolver: TypeResolver,
600 $($t: IntoVisitor,)*
601 {
602 type Value<'scale, 'resolver> = ($($t,)*);
603 type Error = Error;
604 type TypeResolver = Resolver;
605
606 decode_inner_type_when_one_tuple_entry!($($t)*);
609
610 fn visit_composite<'scale, 'resolver>(
611 self,
612 value: &mut Composite<'scale, 'resolver, Resolver>,
613 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
614 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
615 tuple_method_impl!(($($t,)*), value)
616 }
617 fn visit_tuple<'scale, 'resolver>(
618 self,
619 value: &mut Tuple<'scale, 'resolver, Resolver>,
620 _type_id: <Self::TypeResolver as TypeResolver>::TypeId,
621 ) -> Result<Self::Value<'scale, 'resolver>, Self::Error> {
622 tuple_method_impl!(($($t,)*), value)
623 }
624 }
625
626 impl < $($t),* > IntoVisitor for ($($t,)*)
628 where $( $t: IntoVisitor, )*
629 {
630 type AnyVisitor<Resolver: TypeResolver> = BasicVisitor<($($t,)*), Resolver>;
631 fn into_visitor<Resolver: TypeResolver>() -> Self::AnyVisitor<Resolver> {
632 BasicVisitor { _marker: core::marker::PhantomData }
633 }
634 }
635
636 impl < $($t),* > DecodeAsFields for ($($t,)*)
638 where $( $t: IntoVisitor, )*
639 {
640 fn decode_as_fields<'resolver, Resolver: TypeResolver>(input: &mut &[u8], fields: &mut dyn FieldIter<'resolver, Resolver::TypeId>, types: &'resolver Resolver) -> Result<Self, Error> {
641 let mut composite = crate::visitor::types::Composite::new(core::iter::empty(), input, fields, types, false);
642
643 let val = <($($t,)*)>::into_visitor().visit_composite(&mut composite, Default::default());
646
647 composite.skip_decoding()?;
649 *input = composite.bytes_from_undecoded();
650
651 val
652 }
653 }
654 }
655}
656
657impl_decode_tuple!();
658impl_decode_tuple!(A);
659impl_decode_tuple!(A B);
660impl_decode_tuple!(A B C);
661impl_decode_tuple!(A B C D);
662impl_decode_tuple!(A B C D E);
663impl_decode_tuple!(A B C D E F);
664impl_decode_tuple!(A B C D E F G);
665impl_decode_tuple!(A B C D E F G H);
666impl_decode_tuple!(A B C D E F G H I);
667impl_decode_tuple!(A B C D E F G H I J);
668impl_decode_tuple!(A B C D E F G H I J K);
669impl_decode_tuple!(A B C D E F G H I J K L);
670impl_decode_tuple!(A B C D E F G H I J K L M);
671impl_decode_tuple!(A B C D E F G H I J K L M N);
672impl_decode_tuple!(A B C D E F G H I J K L M N O);
673impl_decode_tuple!(A B C D E F G H I J K L M N O P);
674impl_decode_tuple!(A B C D E F G H I J K L M N O P Q);
675impl_decode_tuple!(A B C D E F G H I J K L M N O P Q R);
676impl_decode_tuple!(A B C D E F G H I J K L M N O P Q R S);
677impl_decode_tuple!(A B C D E F G H I J K L M N O P Q R S T);
678fn decode_items_using<'a, 'scale, 'resolver, R, D, T>(
682 decoder: &'a mut D,
683) -> impl Iterator<Item = Result<T, Error>> + 'a
684where
685 T: IntoVisitor,
686 R: TypeResolver,
687 D: DecodeItemIterator<'scale, 'resolver, R>,
688{
689 let mut idx = 0;
690 core::iter::from_fn(move || {
691 let item = decoder.decode_item(T::into_visitor()).map(|res| res.map_err(|e| e.at_idx(idx)));
692 idx += 1;
693 item
694 })
695}
696
697#[cfg(all(feature = "derive", feature = "primitive-types"))]
698#[cfg(test)]
699mod test {
700 use super::*;
701 use crate::{DecodeAsType, Field};
702 use codec::Encode;
703
704 fn make_type<T: scale_info::TypeInfo + 'static>() -> (u32, scale_info::PortableRegistry) {
706 let m = scale_info::MetaType::new::<T>();
707 let mut types = scale_info::Registry::new();
708 let id = types.register_type(&m);
709 let portable_registry: scale_info::PortableRegistry = types.into();
710
711 (id.id, portable_registry)
712 }
713
714 fn assert_encode_decode_to_with<T, A, B>(a: &A, b: &B)
716 where
717 A: Encode,
718 B: DecodeAsType + PartialEq + core::fmt::Debug,
719 T: scale_info::TypeInfo + 'static,
720 {
721 let (type_id, types) = make_type::<T>();
722 let encoded = a.encode();
723 let decoded =
724 B::decode_as_type(&mut &*encoded, type_id, &types).expect("should be able to decode");
725 assert_eq!(&decoded, b);
726 }
727
728 fn assert_encode_decode_to<A, B>(a: &A, b: &B)
730 where
731 A: Encode + scale_info::TypeInfo + 'static,
732 B: DecodeAsType + PartialEq + core::fmt::Debug,
733 {
734 assert_encode_decode_to_with::<A, A, B>(a, b);
735 }
736
737 fn assert_encode_decode_with<T, A>(a: &A)
739 where
740 A: Encode + DecodeAsType + PartialEq + core::fmt::Debug,
741 T: scale_info::TypeInfo + 'static,
742 {
743 assert_encode_decode_to_with::<T, A, A>(a, a)
744 }
745
746 fn assert_encode_decode<A>(a: &A)
748 where
749 A: Encode + scale_info::TypeInfo + 'static + DecodeAsType + PartialEq + core::fmt::Debug,
750 {
751 assert_encode_decode_to(a, a)
752 }
753
754 fn assert_encode_decode_as_fields<Foo>(foo: Foo)
756 where
757 Foo: scale_info::TypeInfo
758 + DecodeAsFields
759 + PartialEq
760 + core::fmt::Debug
761 + codec::Encode
762 + 'static,
763 {
764 let foo_encoded = foo.encode();
765 let foo_encoded_cursor = &mut &*foo_encoded;
766
767 let (ty, types) = make_type::<Foo>();
768
769 let new_foo = match &types.resolve(ty).unwrap().type_def {
770 scale_info::TypeDef::Composite(c) => {
771 let mut field_iter = c.fields.iter().map(|f| Field::new(f.ty.id, f.name));
772 Foo::decode_as_fields(foo_encoded_cursor, &mut field_iter, &types).unwrap()
773 }
774 scale_info::TypeDef::Tuple(t) => {
775 let mut field_iter = t.fields.iter().map(|f| Field::unnamed(f.id));
776 Foo::decode_as_fields(foo_encoded_cursor, &mut field_iter, &types).unwrap()
777 }
778 _ => {
779 panic!("Expected composite or tuple type def")
780 }
781 };
782
783 assert_eq!(foo, new_foo);
784 assert_eq!(
785 foo_encoded_cursor.len(),
786 0,
787 "leftover len when total was {}",
788 foo_encoded.len()
789 );
790 }
791
792 #[test]
793 fn decode_primitives() {
794 assert_encode_decode(&true);
795 assert_encode_decode(&false);
796 assert_encode_decode(&"hello".to_string());
797 }
798
799 #[test]
800 fn decode_pointer_types() {
801 assert_encode_decode_to(&true, &Box::new(true));
802 assert_encode_decode_to(&true, &Arc::new(true));
803 assert_encode_decode_to(&true, &Rc::new(true));
804 assert_encode_decode_to(&true, &Cow::Borrowed(&true));
805 }
806
807 #[test]
808 fn decode_duration() {
809 assert_encode_decode_with::<(u64, u32), _>(&Duration::from_millis(12345));
810 }
811
812 #[test]
813 fn decode_ranges() {
814 assert_encode_decode(&(1..10));
815 assert_encode_decode(&(1..=10));
816 }
817
818 #[test]
819 fn decode_basic_numbers() {
820 fn decode_all_types(n: u128) {
821 assert_encode_decode_to(&n, &(n as u8));
822 assert_encode_decode_to(&n, &(n as u16));
823 assert_encode_decode_to(&n, &(n as u32));
824 assert_encode_decode_to(&n, &(n as u64));
825 assert_encode_decode_to(&n, &n);
826
827 assert_encode_decode_to(&n, &(n as i8));
828 assert_encode_decode_to(&n, &(n as i16));
829 assert_encode_decode_to(&n, &(n as i32));
830 assert_encode_decode_to(&n, &(n as i64));
831 assert_encode_decode_to(&n, &(n as i128));
832 }
833
834 decode_all_types(0);
835 decode_all_types(1);
836 decode_all_types(127);
837 }
838
839 #[test]
840 fn decode_cows() {
841 let a = "hello";
842 assert_encode_decode_to(&a, &Cow::<'_, str>::Borrowed(a));
843 assert_encode_decode(&Cow::<'_, str>::Borrowed(a));
846 }
847
848 #[test]
849 fn decode_sequences() {
850 assert_encode_decode_to(&vec![1u8, 2, 3], &[1u8, 2, 3]);
851 assert_encode_decode_to(&vec![1u8, 2, 3], &vec![1u8, 2, 3]);
852 assert_encode_decode_to(&vec![1u8, 2, 3], &LinkedList::from_iter([1u8, 2, 3]));
853 assert_encode_decode_to(&vec![1u8, 2, 3], &VecDeque::from_iter([1u8, 2, 3]));
854 assert_encode_decode_to(&vec![1u8, 2, 3, 2], &BTreeSet::from_iter([1u8, 2, 3, 2]));
855 }
857
858 #[test]
859 fn decode_types_via_tuples_or_composites() {
860 #[derive(DecodeAsType, codec::Encode, scale_info::TypeInfo)]
862 #[decode_as_type(crate_path = "crate")]
863 struct Foo<A> {
864 val: A,
865 }
866
867 #[derive(DecodeAsType, codec::Encode, scale_info::TypeInfo, Debug, PartialEq, Clone)]
869 #[decode_as_type(crate_path = "crate")]
870 enum Wibble {
871 Bar(u64),
872 }
873
874 fn check<A>(a: A)
875 where
876 A: Encode
877 + scale_info::TypeInfo
878 + 'static
879 + DecodeAsType
880 + PartialEq
881 + core::fmt::Debug
882 + Clone,
883 {
884 let tup = ((a.clone(),),);
885 let struc = Foo { val: Foo { val: a.clone() } };
886
887 assert_encode_decode_to(&tup, &a);
888 assert_encode_decode_to(&struc, &a);
889 }
890
891 check(123u8);
894 check(123u16);
895 check(123u32);
896 check(123u64);
897 check(123u128);
898 check(123i8);
899 check(123i16);
900 check(123i32);
901 check(123i64);
902 check(123i128);
903 check(true);
904 check("hello".to_string());
905 check(Bits::from_iter([true, false, true, true]));
906 check([1, 2, 3, 4, 5]);
907 check(vec![1, 2, 3, 4, 5]);
908 check(NonZeroU8::new(100).unwrap());
909 check(Some(123));
910 check(Ok::<_, bool>(123));
911 check(Wibble::Bar(12345));
912 }
913
914 #[test]
915 fn decode_tuples() {
916 #[derive(DecodeAsType, codec::Encode, scale_info::TypeInfo, Debug, PartialEq, Clone)]
918 #[decode_as_type(crate_path = "crate")]
919 struct Foo {
920 a: u8,
921 b: u16,
922 c: bool,
923 }
924
925 assert_encode_decode(&(1u8, 2u16, true));
927 assert_encode_decode_to(&(1u8, 2u8, true), &Foo { a: 1u8, b: 2u16, c: true });
929 assert_encode_decode_to(&Foo { a: 1u8, b: 2u16, c: true }, &(1u8, 2u8, true));
931 }
932
933 #[test]
934 fn decode_composites_to_tuples() {
935 #[derive(codec::Encode, scale_info::TypeInfo)]
936 struct Foo {
937 hello: bool,
938 other: (u8, u32),
939 }
940
941 let input = Foo { hello: true, other: (1, 3) };
942 assert_encode_decode_to(&input, &(true, (1u8, 3u32)));
944 assert_encode_decode_to(&input, &(true, (1u64, 3u64)));
946 }
947
948 #[test]
949 fn decode_compacts() {
950 assert_encode_decode(&Compact(126u64));
951 }
952
953 #[test]
954 fn decode_options_and_results() {
955 assert_encode_decode(&Some(123i128));
957 assert_encode_decode(&(None as Option<bool>));
958 assert_encode_decode(&Ok::<_, bool>(123i128));
959 assert_encode_decode(&Err::<bool, _>(123i128));
960 }
961
962 #[test]
963 fn decode_bits() {
964 assert_encode_decode(&Bits::new());
965 assert_encode_decode(&Bits::from_iter([true, false, false, true, false]));
966 }
967
968 #[test]
969 #[cfg(feature = "primitive-types")]
970 fn decode_hxxx() {
971 use ::primitive_types::{H128, H160, H256, H384, H512, H768};
972
973 fn try_decode_hxxx(input: impl IntoIterator<Item = u8>) {
974 let mut bytes: Vec<u8> = input.into_iter().collect();
975
976 macro_rules! check_ty {
977 ($bytes:expr, $bits:literal, $ty:ident) => {
978 while $bytes.len() < $bits / 8 {
979 $bytes.push(0)
980 }
981 assert_encode_decode(&$ty::from_slice(&$bytes));
982 assert_encode_decode_to(&$ty::from_slice(&$bytes), &$bytes);
983 assert_encode_decode_to(&$bytes, &$ty::from_slice(&$bytes));
984 };
985 }
986 check_ty!(bytes, 128, H128);
987 check_ty!(bytes, 160, H160);
988 check_ty!(bytes, 256, H256);
989 check_ty!(bytes, 384, H384);
990 check_ty!(bytes, 512, H512);
991 check_ty!(bytes, 768, H768);
992 }
993
994 try_decode_hxxx([0]);
995 try_decode_hxxx([1, 2, 3, 4]);
996 try_decode_hxxx([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]);
997 }
998
999 #[test]
1000 fn decoding_can_skip_named_struct_fields() {
1001 #[derive(DecodeAsType, PartialEq, Debug)]
1002 #[decode_as_type(crate_path = "crate")]
1003 struct Foo {
1004 some_field: u8,
1005 value: u16,
1006 #[decode_as_type(skip)]
1007 some_field_to_skip: bool,
1008 #[decode_as_type(skip)]
1009 other_field_to_skip: usize,
1010 }
1011
1012 #[derive(codec::Encode, scale_info::TypeInfo)]
1013 struct FooPartial {
1014 some_field: u8,
1015 value: u16,
1016 }
1017
1018 assert_encode_decode_to(
1019 &FooPartial { some_field: 123, value: 456 },
1020 &Foo {
1021 some_field: 123,
1022 value: 456,
1023 some_field_to_skip: false,
1025 other_field_to_skip: 0,
1026 },
1027 );
1028 }
1029
1030 #[test]
1031 fn decoding_can_skip_unnamed_struct_fields() {
1032 #[derive(DecodeAsType, PartialEq, Debug)]
1033 #[decode_as_type(crate_path = "crate")]
1034 struct Foo(u8, #[decode_as_type(skip)] bool, #[decode_as_type(skip)] usize);
1035
1036 #[derive(codec::Encode, scale_info::TypeInfo)]
1037 struct FooPartial {
1038 some_field: u8,
1039 }
1040
1041 assert_encode_decode_to(
1042 &FooPartial { some_field: 123 },
1043 &Foo(
1044 123, false, 0,
1046 ),
1047 );
1048 }
1049
1050 #[test]
1051 fn decoding_can_skip_enum_variant_fields() {
1052 #[derive(DecodeAsType, PartialEq, Debug)]
1053 #[decode_as_type(crate_path = "crate")]
1054 enum Foo {
1055 NamedField {
1056 some_field: u8,
1057 #[decode_as_type(skip)]
1058 some_field_to_skip: bool,
1059 #[codec(skip)]
1061 another_field_to_skip: String,
1062 value: u16,
1063 },
1064 UnnamedField(bool, #[decode_as_type(skip)] usize, String),
1065 }
1066
1067 #[derive(codec::Encode, scale_info::TypeInfo)]
1068 enum FooPartial {
1069 NamedField { some_field: u8, value: u16 },
1070 UnnamedField(bool, String),
1071 }
1072
1073 assert_encode_decode_to(
1074 &FooPartial::NamedField { some_field: 123, value: 456 },
1075 &Foo::NamedField {
1076 some_field: 123,
1077 some_field_to_skip: false,
1078 another_field_to_skip: String::new(),
1079 value: 456,
1080 },
1081 );
1082 assert_encode_decode_to(
1083 &FooPartial::UnnamedField(true, "hello".to_string()),
1084 &Foo::UnnamedField(true, 0, "hello".to_string()),
1085 );
1086 }
1087
1088 #[test]
1089 fn decode_as_fields_works() {
1090 use core::fmt::Debug;
1091
1092 #[derive(DecodeAsType, codec::Encode, PartialEq, Debug, scale_info::TypeInfo)]
1093 #[decode_as_type(crate_path = "crate")]
1094 struct Foo {
1095 some_field: u8,
1096 value: u16,
1097 }
1098
1099 assert_encode_decode_as_fields(Foo { some_field: 123, value: 456 });
1100
1101 #[derive(DecodeAsType, codec::Encode, PartialEq, Debug, scale_info::TypeInfo)]
1102 #[decode_as_type(crate_path = "crate")]
1103 struct Foo2(String, bool, u64);
1104
1105 assert_encode_decode_as_fields(Foo2("hello".to_string(), true, 12345));
1106
1107 #[derive(DecodeAsType, codec::Encode, PartialEq, Debug, scale_info::TypeInfo)]
1108 #[decode_as_type(crate_path = "crate")]
1109 struct Foo3;
1110
1111 assert_encode_decode_as_fields(Foo3);
1112
1113 assert_encode_decode_as_fields((true, 123u8, "hello".to_string()));
1115 }
1116}